diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml index f6c6122f..b7a5c41c 100644 --- a/.github/workflows/run_tests.yaml +++ b/.github/workflows/run_tests.yaml @@ -64,7 +64,7 @@ jobs: SHINKAI_STORE_ADDR: ${{ vars.SHINKAI_STORE_ADDR }} SHINKAI_STORE_TOKEN: ${{ secrets.SHINKAI_STORE_TOKEN }} USE_DOCKER: true - SHINKAI_NODE_IMAGE: "dcsparkdevops/shinkai-node:${{ inputs.node_version || 'debug-latest' }}" + SHINKAI_NODE_IMAGE: "dcsparkdevops/shinkai-node:${{ inputs.node_version || 'release-latest' }}" run: | ./scripts/run_node.sh & timeout 60 bash -c 'until curl -s --location "$SHINKAI_NODE_ADDR/v2/health_check" | jq -e ".status == \"ok\"" > /dev/null; do sleep 1; done' diff --git a/scripts/Lato-Bold.ttf b/scripts/Lato-Bold.ttf new file mode 100644 index 00000000..1d23c706 Binary files /dev/null and b/scripts/Lato-Bold.ttf differ diff --git a/scripts/add_text_to_image.ts b/scripts/add_text_to_image.ts new file mode 100644 index 00000000..7a3ca6eb --- /dev/null +++ b/scripts/add_text_to_image.ts @@ -0,0 +1,103 @@ +import { Image, TextLayout } from "https://deno.land/x/imagescript@1.2.15/mod.ts"; +import { join, dirname, fromFileUrl } from "https://deno.land/std@0.210.0/path/mod.ts"; +import { existsSync } from "https://deno.land/std@0.210.0/fs/mod.ts"; + +const __dirname = dirname(fromFileUrl(import.meta.url)); +const toolsDir = join(__dirname, '..', 'tools'); +const fontPath = join(__dirname, 'Lato-Bold.ttf'); + +async function addTextToImage(inputPath: string, outputPath: string, toolName: string): Promise { + try { + // Load the background image + const image = await Image.decode(await Deno.readFile(inputPath)); + const width = image.width; + const height = image.height; + + // Calculate font size (start with 15% of height) + const fontSize = Math.floor(height * 0.15); + console.log(`Image dimensions: ${width}x${height}, fontSize: ${fontSize}`); + + // Load font + const font = await Deno.readFile(fontPath); + + // Create text layout + const layout = new TextLayout({ + maxWidth: Math.floor(width * 0.9), + maxHeight: Math.floor(height * 0.9), + wrapStyle: "word", + align: "center" + }); + + // Create shadow text + const shadowText = Image.renderText(font, fontSize, toolName, 0x000000FF, layout); + + // Calculate bottom right position with padding + const padding = Math.floor(height * 0.05); // 5% of height as padding + let x = Math.floor(width - shadowText.width - padding); + let y = Math.floor(height - shadowText.height - padding); + console.log(`Text position: (${x},${y})`); + + // Ensure we don't go beyond image boundaries + if (x < 0) x = padding; + if (y < 0) y = padding; + + // Draw shadow with multiple offsets for thickness + for (let offsetX = 1; offsetX <= 4; offsetX++) { + for (let offsetY = 1; offsetY <= 4; offsetY++) { + await image.composite(shadowText, x + offsetX, y + offsetY); + } + } + + // Create and draw main text + const mainText = Image.renderText(font, fontSize, toolName, 0xFFFFFFFF, layout); + await image.composite(mainText, x, y); + + // Save the result + await Deno.writeFile(outputPath, await image.encode()); + } catch (error) { + console.error(`Error processing ${inputPath}:`, error); + throw error; + } +} + +async function readToolMetadata(toolPath: string) { + const metadataPath = join(toolPath, 'metadata.json'); + const metadata = JSON.parse(await Deno.readTextFile(metadataPath)); + return metadata; +} + +async function main() { + // Get all tool directories + const tools = Array.from(Deno.readDirSync(toolsDir)) + .filter(item => item.isDirectory) + .map(item => item.name); + + for (const tool of tools) { + const toolPath = join(toolsDir, tool); + const backgroundPath = join(toolPath, 'banner_background.png'); + const bannerPath = join(toolPath, 'banner.png'); + + // Skip if background doesn't exist + if (!existsSync(backgroundPath)) { + console.log(`Skipping ${tool}: no banner_background.png found`); + continue; + } + + try { + console.log(`Processing ${tool}...`); + const metadata = await readToolMetadata(toolPath); + await addTextToImage(backgroundPath, bannerPath, metadata.name); + console.log(`Successfully generated banner.png for ${tool}`); + } catch (error) { + console.error(`Error processing tool ${tool}:`, error); + } + } +} + +// Run if called directly +if (import.meta.main) { + main().catch(error => { + console.error('Fatal error:', error); + Deno.exit(1); + }); +} \ No newline at end of file diff --git a/scripts/generate_images.ts b/scripts/generate_images.ts new file mode 100644 index 00000000..8ab1246c --- /dev/null +++ b/scripts/generate_images.ts @@ -0,0 +1,222 @@ +import { config as dotenvConfig } from "https://deno.land/x/dotenv@v3.2.2/mod.ts"; +import { join, dirname, fromFileUrl } from "https://deno.land/std@0.210.0/path/mod.ts"; +import { existsSync } from "https://deno.land/std@0.210.0/fs/mod.ts"; +import { createCanvas, loadImage } from "https://deno.land/x/canvas/mod.ts"; +import axios from "npm:axios@1.6.2"; + +// Load environment variables +dotenvConfig(); + +const BANNER_WIDTH = 1280; +const BANNER_HEIGHT = 640; +const ICON_SIZE = 256; +const BFL_API_URL = 'https://api.us1.bfl.ai/v1'; +const BFL_API_KEY = Deno.env.get("BFL_API_KEY"); + +interface ToolMetadata { + name: string; + description: string; +} + +interface GenerateImageOptions { + prompt: string; + negative_prompt?: string; + width?: number; + height?: number; + num_outputs?: number; + guidance_scale?: number; + seed?: number; +} + +interface BFLResponse { + id: string; + status: string; + result?: { + sample: string; + }; +} + +async function readToolMetadata(toolPath: string): Promise { + const metadataPath = join(toolPath, 'metadata.json'); + const metadata = JSON.parse(await Deno.readTextFile(metadataPath)); + return metadata; +} + +async function waitForImageGeneration(requestId: string): Promise { + while (true) { + const response = await axios.get(`${BFL_API_URL}/get_result?id=${requestId}`, { + headers: { + 'accept': 'application/json', + 'x-key': BFL_API_KEY + } + }); + + if (response.data.status === 'Ready' && response.data.result) { + return response.data.result.sample; + } + + if (response.data.status === 'Failed') { + throw new Error('Image generation failed'); + } + + // Wait before polling again + await new Promise(resolve => setTimeout(resolve, 500)); + } +} + +async function generateImage(options: GenerateImageOptions): Promise { + const defaultOptions = { + width: 1024, + height: 1024, + // prompt_upsampling: true, + }; + + if (!options.prompt) { + throw new Error('Prompt is required'); + } + + const mergedOptions = { ...defaultOptions, ...options }; + + try { + // Initial request to start generation + const response = await axios.post( + `${BFL_API_URL}/flux-pro-1.1`, + { + prompt: mergedOptions.prompt, + width: mergedOptions.width, + height: mergedOptions.height + }, + { + headers: { + 'accept': 'application/json', + 'x-key': BFL_API_KEY, + 'Content-Type': 'application/json' + } + } + ); + + // Poll for results + return await waitForImageGeneration(response.data.id); + } catch (error) { + console.error('Error generating image:', error); + throw error; + } +} + +async function copyPlaceholderImages(scriptDir: string, toolPath: string, missingFiles: string[]): Promise { + console.log("Using placeholder images for:", missingFiles.join(", ")); + for (const file of missingFiles) { + const sourcePath = join(scriptDir, file); + const destPath = join(toolPath, file); + if (existsSync(sourcePath)) { + await Deno.copyFile(sourcePath, destPath); + } + } +} + +async function generateToolImages(toolPath: string, metadata: ToolMetadata): Promise { + const bannerPath = join(toolPath, 'banner_background.png'); + const iconPath = join(toolPath, 'icon.png'); + const missingFiles: string[] = []; + + if (!existsSync(bannerPath)) missingFiles.push('banner_background.png'); + if (!existsSync(iconPath)) missingFiles.push('icon.png'); + + if (!missingFiles.length) { + console.log("All images already exist, skipping generation"); + return; + } + + console.log(`Generating missing images: ${missingFiles.join(', ')}`); + + try { + if (missingFiles.includes('banner_background.png')) { + const bannerPrompt = + `Create a professional banner image for a software tool named '${metadata.name}'. ` + + `The tool description is: ${metadata.description}. Use a modern, minimalist style with subtle tech elements. ` + + "Make it suitable for a developer tool interface. Use a cohesive color scheme, dark colors, allowing for white text to be readable on the image. " + + "and include some abstract geometric elements that represent the tool's function." + + "Do not include any text, just create a beautiful image. And I repeat, do not include any text."; + + console.log(`Generating banner for ${metadata.name}...`); + const bannerUrl = await generateImage({ + prompt: bannerPrompt, + width: 1280, + height: 736, + num_outputs: 1 + }); + + const response = await axios.get(bannerUrl, { responseType: 'arraybuffer' }); + await Deno.writeFile(join(toolPath, 'banner_background.png'), new Uint8Array(response.data)); + } + + if (missingFiles.includes('icon.png')) { + const iconPrompt = + `Create a simple, memorable icon for '${metadata.name}'. The icon should represent ` + + `${metadata.description}. Use a minimal design with clear shapes and limited colors. ` + + "Make it recognizable at small sizes and suitable for a developer tool. " + + "The icon should work well as an app icon or menu item."; + + console.log(`Generating icon for ${metadata.name}...`); + const iconUrl = await generateImage({ + prompt: iconPrompt, + width: 256, + height: 256, + num_outputs: 1 + }); + + const response = await axios.get(iconUrl, { responseType: 'arraybuffer' }); + await Deno.writeFile(join(toolPath, 'icon.png'), new Uint8Array(response.data)); + } + + console.log("Successfully generated missing images"); + } catch (error) { + console.error('Error generating images:', error); + throw error; + } +} + +async function main() { + if (!BFL_API_KEY) { + console.error('Please set BFL_API_KEY environment variable'); + Deno.exit(1); + } + + const __dirname = dirname(fromFileUrl(import.meta.url)); + const toolsDir = join(__dirname, '..', 'tools'); + const scriptDir = __dirname; + + // Get all tool directories + const tools = Array.from(Deno.readDirSync(toolsDir)) + .filter(item => item.isDirectory) + .map(item => item.name); + + for (const tool of tools) { + const toolPath = join(toolsDir, tool); + console.log(`\nProcessing tool: ${tool}`); + + try { + const metadata = await readToolMetadata(toolPath); + await generateToolImages(toolPath, metadata); + } catch (error) { + console.error(`Error processing tool ${tool}:`, error); + // Copy placeholder images if available + const missingFiles = []; + if (!existsSync(join(toolPath, 'banner_background.png'))) missingFiles.push('banner_background.png'); + if (!existsSync(join(toolPath, 'icon.png'))) missingFiles.push('icon.png'); + if (missingFiles.length) { + await copyPlaceholderImages(scriptDir, toolPath, missingFiles); + } + } + } +} + +// Run if called directly +if (import.meta.main) { + main().catch(error => { + console.error('Fatal error:', error); + Deno.exit(1); + }); +} + +export { generateImage, GenerateImageOptions }; \ No newline at end of file diff --git a/tools/article-scraper/icon.png b/tools/article-scraper/icon.png index ccf27c93..b5748382 100644 Binary files a/tools/article-scraper/icon.png and b/tools/article-scraper/icon.png differ diff --git a/tools/arxiv-download/icon.png b/tools/arxiv-download/icon.png index 47d751e4..5ae947e1 100644 Binary files a/tools/arxiv-download/icon.png and b/tools/arxiv-download/icon.png differ diff --git a/tools/arxiv-search/icon.png b/tools/arxiv-search/icon.png index e8e1d363..62430f3d 100644 Binary files a/tools/arxiv-search/icon.png and b/tools/arxiv-search/icon.png differ diff --git a/tools/chess-evaluate/icon.png b/tools/chess-evaluate/icon.png index a9986e89..48ccf91f 100644 Binary files a/tools/chess-evaluate/icon.png and b/tools/chess-evaluate/icon.png differ diff --git a/tools/chess-generate-image/icon.png b/tools/chess-generate-image/icon.png index a9c9a992..2b85a7c2 100644 Binary files a/tools/chess-generate-image/icon.png and b/tools/chess-generate-image/icon.png differ diff --git a/tools/chess-move/icon.png b/tools/chess-move/icon.png index 7419b8b0..6917cd02 100644 Binary files a/tools/chess-move/icon.png and b/tools/chess-move/icon.png differ diff --git a/tools/coin-flip/icon.png b/tools/coin-flip/icon.png index e18e6ab9..c655d3bf 100644 Binary files a/tools/coin-flip/icon.png and b/tools/coin-flip/icon.png differ diff --git a/tools/coinbase-call-faucet/icon.png b/tools/coinbase-call-faucet/icon.png index 16e86d9b..75e927f3 100644 Binary files a/tools/coinbase-call-faucet/icon.png and b/tools/coinbase-call-faucet/icon.png differ diff --git a/tools/coinbase-create-wallet/icon.png b/tools/coinbase-create-wallet/icon.png index e8ca3dc2..5e6cf76d 100644 Binary files a/tools/coinbase-create-wallet/icon.png and b/tools/coinbase-create-wallet/icon.png differ diff --git a/tools/coinbase-get-balance/icon.png b/tools/coinbase-get-balance/icon.png index 915b6394..3f1bc934 100644 Binary files a/tools/coinbase-get-balance/icon.png and b/tools/coinbase-get-balance/icon.png differ diff --git a/tools/coinbase-get-my-address/icon.png b/tools/coinbase-get-my-address/icon.png index c93d6abd..76c241c9 100644 Binary files a/tools/coinbase-get-my-address/icon.png and b/tools/coinbase-get-my-address/icon.png differ diff --git a/tools/coinbase-get-transactions/icon.png b/tools/coinbase-get-transactions/icon.png index 4ee77cc7..c2ce28b7 100644 Binary files a/tools/coinbase-get-transactions/icon.png and b/tools/coinbase-get-transactions/icon.png differ diff --git a/tools/coinbase-send-tx/icon.png b/tools/coinbase-send-tx/icon.png index 03e5315f..41220947 100644 Binary files a/tools/coinbase-send-tx/icon.png and b/tools/coinbase-send-tx/icon.png differ diff --git a/tools/coingecko-get-coins/icon.png b/tools/coingecko-get-coins/icon.png index 3c73ae55..e5985f22 100644 Binary files a/tools/coingecko-get-coins/icon.png and b/tools/coingecko-get-coins/icon.png differ diff --git a/tools/coingecko-get-historical-data/icon.png b/tools/coingecko-get-historical-data/icon.png index 880d9faa..8b795be5 100644 Binary files a/tools/coingecko-get-historical-data/icon.png and b/tools/coingecko-get-historical-data/icon.png differ diff --git a/tools/dev-airtable/icon.png b/tools/dev-airtable/icon.png index 47f32777..4ec9212b 100644 Binary files a/tools/dev-airtable/icon.png and b/tools/dev-airtable/icon.png differ diff --git a/tools/dev-github/icon.png b/tools/dev-github/icon.png index 0fe11353..6a60d14f 100644 Binary files a/tools/dev-github/icon.png and b/tools/dev-github/icon.png differ diff --git a/tools/dev-gmail/icon.png b/tools/dev-gmail/icon.png index bf9dc656..c1abd8b9 100644 Binary files a/tools/dev-gmail/icon.png and b/tools/dev-gmail/icon.png differ diff --git a/tools/dev-google-drive/icon.png b/tools/dev-google-drive/icon.png index 0334552d..a53842e3 100644 Binary files a/tools/dev-google-drive/icon.png and b/tools/dev-google-drive/icon.png differ diff --git a/tools/dev-twitter/icon.png b/tools/dev-twitter/icon.png index 1a4a5c48..695a2419 100644 Binary files a/tools/dev-twitter/icon.png and b/tools/dev-twitter/icon.png differ diff --git a/tools/download-page/icon.png b/tools/download-page/icon.png index c452297a..0ec60629 100644 Binary files a/tools/download-page/icon.png and b/tools/download-page/icon.png differ diff --git a/tools/duckduckgo-search/icon.png b/tools/duckduckgo-search/icon.png index f3d3f6d4..0cc502a8 100644 Binary files a/tools/duckduckgo-search/icon.png and b/tools/duckduckgo-search/icon.png differ diff --git a/tools/elevenlabs-isolate-voice/icon.png b/tools/elevenlabs-isolate-voice/icon.png index d561910e..cbdf8db2 100644 Binary files a/tools/elevenlabs-isolate-voice/icon.png and b/tools/elevenlabs-isolate-voice/icon.png differ diff --git a/tools/elevenlabs-text-to-speech/icon.png b/tools/elevenlabs-text-to-speech/icon.png index eb7124a7..b090241b 100644 Binary files a/tools/elevenlabs-text-to-speech/icon.png and b/tools/elevenlabs-text-to-speech/icon.png differ diff --git a/tools/email-imap-fetcher/icon.png b/tools/email-imap-fetcher/icon.png index ae6b00e7..b5a000ec 100644 Binary files a/tools/email-imap-fetcher/icon.png and b/tools/email-imap-fetcher/icon.png differ diff --git a/tools/email-responder/icon.png b/tools/email-responder/icon.png index fab2880c..a7777ac5 100644 Binary files a/tools/email-responder/icon.png and b/tools/email-responder/icon.png differ diff --git a/tools/email-sender/icon.png b/tools/email-sender/icon.png index fb8c7c97..f3affaf3 100644 Binary files a/tools/email-sender/icon.png and b/tools/email-sender/icon.png differ diff --git a/tools/file-read/icon.png b/tools/file-read/icon.png index 6988fa3a..d8363213 100644 Binary files a/tools/file-read/icon.png and b/tools/file-read/icon.png differ diff --git a/tools/file-update/icon.png b/tools/file-update/icon.png index 3d02eef8..58cc557a 100644 Binary files a/tools/file-update/icon.png and b/tools/file-update/icon.png differ diff --git a/tools/file-write/icon.png b/tools/file-write/icon.png index 9682c59f..ec25e190 100644 Binary files a/tools/file-write/icon.png and b/tools/file-write/icon.png differ diff --git a/tools/game-crypto-2048/icon.png b/tools/game-crypto-2048/icon.png index 3e47dce6..43880b20 100644 Binary files a/tools/game-crypto-2048/icon.png and b/tools/game-crypto-2048/icon.png differ diff --git a/tools/google-news-search/icon.png b/tools/google-news-search/icon.png index f805a879..b4471f67 100644 Binary files a/tools/google-news-search/icon.png and b/tools/google-news-search/icon.png differ diff --git a/tools/google-search/icon.png b/tools/google-search/icon.png index e586e5da..8ce93c99 100644 Binary files a/tools/google-search/icon.png and b/tools/google-search/icon.png differ diff --git a/tools/hacker-news/icon.png b/tools/hacker-news/icon.png index bb14c9d5..e0bf6300 100644 Binary files a/tools/hacker-news/icon.png and b/tools/hacker-news/icon.png differ diff --git a/tools/iterm-control/icon.png b/tools/iterm-control/icon.png index dc10f635..e127a0d2 100644 Binary files a/tools/iterm-control/icon.png and b/tools/iterm-control/icon.png differ diff --git a/tools/iterm-read/icon.png b/tools/iterm-read/icon.png index 3ac57715..33dfcfea 100644 Binary files a/tools/iterm-read/icon.png and b/tools/iterm-read/icon.png differ diff --git a/tools/iterm-write/icon.png b/tools/iterm-write/icon.png index 5f646732..233a633a 100644 Binary files a/tools/iterm-write/icon.png and b/tools/iterm-write/icon.png differ diff --git a/tools/macos-calendar/icon.png b/tools/macos-calendar/icon.png index 7ffd0a7a..e701fb57 100644 Binary files a/tools/macos-calendar/icon.png and b/tools/macos-calendar/icon.png differ diff --git a/tools/macos-clipboard/icon.png b/tools/macos-clipboard/icon.png index 95772205..cdc52970 100644 Binary files a/tools/macos-clipboard/icon.png and b/tools/macos-clipboard/icon.png differ diff --git a/tools/macos-finder/icon.png b/tools/macos-finder/icon.png index 12811851..c3aab146 100644 Binary files a/tools/macos-finder/icon.png and b/tools/macos-finder/icon.png differ diff --git a/tools/macos-iterm/icon.png b/tools/macos-iterm/icon.png index 8246a847..074e5863 100644 Binary files a/tools/macos-iterm/icon.png and b/tools/macos-iterm/icon.png differ diff --git a/tools/macos-notifications/icon.png b/tools/macos-notifications/icon.png index fe935ba3..48bb044a 100644 Binary files a/tools/macos-notifications/icon.png and b/tools/macos-notifications/icon.png differ diff --git a/tools/macos-say-text-to-audio/icon.png b/tools/macos-say-text-to-audio/icon.png index e531a898..63583654 100644 Binary files a/tools/macos-say-text-to-audio/icon.png and b/tools/macos-say-text-to-audio/icon.png differ diff --git a/tools/macos-system/icon.png b/tools/macos-system/icon.png index b91f5808..082cda0d 100644 Binary files a/tools/macos-system/icon.png and b/tools/macos-system/icon.png differ diff --git a/tools/math-exp/icon.png b/tools/math-exp/icon.png index 35f4ba8b..958d0f77 100644 Binary files a/tools/math-exp/icon.png and b/tools/math-exp/icon.png differ diff --git a/tools/meme-generator/icon.png b/tools/meme-generator/icon.png index 53befef3..f677257d 100644 Binary files a/tools/meme-generator/icon.png and b/tools/meme-generator/icon.png differ diff --git a/tools/memory/icon.png b/tools/memory/icon.png index 8c84aab6..bdfde440 100644 Binary files a/tools/memory/icon.png and b/tools/memory/icon.png differ diff --git a/tools/mermaid/icon.png b/tools/mermaid/icon.png index a1690f59..1b41f05c 100644 Binary files a/tools/mermaid/icon.png and b/tools/mermaid/icon.png differ diff --git a/tools/news-aggregator/icon.png b/tools/news-aggregator/icon.png index fd28b5b7..9c2ff484 100644 Binary files a/tools/news-aggregator/icon.png and b/tools/news-aggregator/icon.png differ diff --git a/tools/ntfy-push/icon.png b/tools/ntfy-push/icon.png index 13cb4007..3483ff89 100644 Binary files a/tools/ntfy-push/icon.png and b/tools/ntfy-push/icon.png differ diff --git a/tools/pdf-summarize-to-audio/icon.png b/tools/pdf-summarize-to-audio/icon.png index a1e3480e..bc2541d8 100644 Binary files a/tools/pdf-summarize-to-audio/icon.png and b/tools/pdf-summarize-to-audio/icon.png differ diff --git a/tools/pdf-text-extractor/icon.png b/tools/pdf-text-extractor/icon.png index 8a2095bc..c56e399b 100644 Binary files a/tools/pdf-text-extractor/icon.png and b/tools/pdf-text-extractor/icon.png differ diff --git a/tools/pdf-whitepaper-analyzer/icon.png b/tools/pdf-whitepaper-analyzer/icon.png index 127ea0b9..d81eeb45 100644 Binary files a/tools/pdf-whitepaper-analyzer/icon.png and b/tools/pdf-whitepaper-analyzer/icon.png differ diff --git a/tools/perplexity-api/icon.png b/tools/perplexity-api/icon.png index 3a129565..7864fb0a 100644 Binary files a/tools/perplexity-api/icon.png and b/tools/perplexity-api/icon.png differ diff --git a/tools/perplexity/icon.png b/tools/perplexity/icon.png index 1c8038b4..e2771bf4 100644 Binary files a/tools/perplexity/icon.png and b/tools/perplexity/icon.png differ diff --git a/tools/podcast-to-podcast/icon.png b/tools/podcast-to-podcast/icon.png index a630844a..c62552a8 100644 Binary files a/tools/podcast-to-podcast/icon.png and b/tools/podcast-to-podcast/icon.png differ diff --git a/tools/pubmed-search/icon.png b/tools/pubmed-search/icon.png index fbcf976b..e65f4870 100644 Binary files a/tools/pubmed-search/icon.png and b/tools/pubmed-search/icon.png differ diff --git a/tools/shinkai-question-learner/icon.png b/tools/shinkai-question-learner/icon.png index 9ef99195..ef9aed09 100644 Binary files a/tools/shinkai-question-learner/icon.png and b/tools/shinkai-question-learner/icon.png differ diff --git a/tools/smart-search/icon.png b/tools/smart-search/icon.png index 55d06e27..7bfae72d 100644 Binary files a/tools/smart-search/icon.png and b/tools/smart-search/icon.png differ diff --git a/tools/stagehand-generic/icon.png b/tools/stagehand-generic/icon.png index 433c2149..5befd3f7 100644 Binary files a/tools/stagehand-generic/icon.png and b/tools/stagehand-generic/icon.png differ diff --git a/tools/stock-technical-analysis/icon.png b/tools/stock-technical-analysis/icon.png index fd5ed8b1..f64a9eaa 100644 Binary files a/tools/stock-technical-analysis/icon.png and b/tools/stock-technical-analysis/icon.png differ diff --git a/tools/system-hw-info/icon.png b/tools/system-hw-info/icon.png index 7b2974ca..1a9d4a7e 100644 Binary files a/tools/system-hw-info/icon.png and b/tools/system-hw-info/icon.png differ diff --git a/tools/text-to-audio-kokoro/icon.png b/tools/text-to-audio-kokoro/icon.png index 779d43ef..219f7277 100644 Binary files a/tools/text-to-audio-kokoro/icon.png and b/tools/text-to-audio-kokoro/icon.png differ diff --git a/tools/twitter-post/icon.png b/tools/twitter-post/icon.png index af9699ec..07bda6d7 100644 Binary files a/tools/twitter-post/icon.png and b/tools/twitter-post/icon.png differ diff --git a/tools/webcam-capture/icon.png b/tools/webcam-capture/icon.png index ae989262..a020e95a 100644 Binary files a/tools/webcam-capture/icon.png and b/tools/webcam-capture/icon.png differ diff --git a/tools/wikimedia-featured-content/icon.png b/tools/wikimedia-featured-content/icon.png index b496a9a4..46236351 100644 Binary files a/tools/wikimedia-featured-content/icon.png and b/tools/wikimedia-featured-content/icon.png differ diff --git a/tools/wikimedia-historical-events/icon.png b/tools/wikimedia-historical-events/icon.png index 3983af08..d701e9b0 100644 Binary files a/tools/wikimedia-historical-events/icon.png and b/tools/wikimedia-historical-events/icon.png differ diff --git a/tools/wikimedia-page-content/icon.png b/tools/wikimedia-page-content/icon.png index e7416b49..3213d516 100644 Binary files a/tools/wikimedia-page-content/icon.png and b/tools/wikimedia-page-content/icon.png differ diff --git a/tools/wikimedia-search-titles/icon.png b/tools/wikimedia-search-titles/icon.png index e589de59..ec8aa4b0 100644 Binary files a/tools/wikimedia-search-titles/icon.png and b/tools/wikimedia-search-titles/icon.png differ diff --git a/tools/wikimedia-search/icon.png b/tools/wikimedia-search/icon.png index 523cb675..3220e3a4 100644 Binary files a/tools/wikimedia-search/icon.png and b/tools/wikimedia-search/icon.png differ diff --git a/tools/x-twitter-search/icon.png b/tools/x-twitter-search/icon.png index 35eb686b..41f35b75 100644 Binary files a/tools/x-twitter-search/icon.png and b/tools/x-twitter-search/icon.png differ diff --git a/tools/youtube-download-mp3/icon.png b/tools/youtube-download-mp3/icon.png index 31e07d6f..b722ff2b 100644 Binary files a/tools/youtube-download-mp3/icon.png and b/tools/youtube-download-mp3/icon.png differ diff --git a/tools/youtube-search/icon.png b/tools/youtube-search/icon.png index 2ce57c87..e6d62f96 100644 Binary files a/tools/youtube-search/icon.png and b/tools/youtube-search/icon.png differ diff --git a/tools/youtube-summary/icon.png b/tools/youtube-summary/icon.png index 1114db32..c8e34d80 100644 Binary files a/tools/youtube-summary/icon.png and b/tools/youtube-summary/icon.png differ