companion-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/agents/example.json +9 -0
- package/agents/fontendengineer.json +9 -0
- package/dist/index.js +9975 -0
- package/dist/index.js.map +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/logger.ts","../src/smart-home/adapters/google-cast.ts","../src/native/win32.ts","../src/native/windows.ts","../src/native/mouse.ts","../src/native/keyboard.ts","../src/native/screenshot.ts","../src/native/process.ts","../src/native/index.ts","../src/tools/desktop.ts","../src/index.ts","../src/chat.ts","../src/providers/openai.ts","../src/providers/base.ts","../src/providers/anthropic.ts","../src/providers/google.ts","../src/providers/index.ts","../src/ui/renderer.ts","../src/commands/help.ts","../src/ui/wizard.ts","../src/commands/model.ts","../src/agents/manager.ts","../src/agents/runner.ts","../src/ui/spinner.ts","../src/commands/agent.ts","../src/commands/config.ts","../src/commands/clear.ts","../src/smart-home/registry.ts","../src/commands/devices.ts","../src/smart-home/adapters/alexa.ts","../src/commands/registry.ts","../src/ui/input.ts","../src/tools/filesystem.ts","../src/tools/security.ts","../src/tools/shell.ts","../src/tools/git.ts","../src/tools/web.ts","../src/tools/image.ts","../src/tools/video.ts","../src/tools/canvas.ts","../src/tools/system.ts","../src/smart-home/tools.ts","../src/smart-home/youtube.ts","../src/tools/middleware.ts","../src/tools/index.ts"],"sourcesContent":["import Conf from 'conf';\n\ninterface ConfigSchema {\n providers: {\n openai: { apiKey: string };\n anthropic: { apiKey: string };\n google: { apiKey: string };\n };\n defaultProvider: string;\n defaultModel: string;\n agentsDirectory: string;\n theme: {\n userColor: string;\n assistantColor: string;\n systemColor: string;\n };\n smartHome: {\n devices: Record<string, unknown>;\n };\n verbosity: 'quiet' | 'normal' | 'verbose' | 'debug';\n}\n\nconst schema = {\n providers: {\n type: 'object' as const,\n default: {\n openai: { apiKey: '' },\n anthropic: { apiKey: '' },\n google: { apiKey: '' },\n },\n },\n defaultProvider: {\n type: 'string' as const,\n default: 'openai',\n },\n defaultModel: {\n type: 'string' as const,\n default: 'gpt-4.1',\n },\n agentsDirectory: {\n type: 'string' as const,\n default: 'agents',\n },\n theme: {\n type: 'object' as const,\n default: {\n userColor: 'cyan',\n assistantColor: 'green',\n systemColor: 'yellow',\n },\n },\n smartHome: {\n type: 'object' as const,\n default: { devices: {} },\n },\n verbosity: {\n type: 'string' as const,\n default: 'normal',\n enum: ['quiet', 'normal', 'verbose', 'debug'],\n },\n};\n\nconst config = new Conf<ConfigSchema>({\n projectName: 'nm-cli',\n schema,\n});\n\nexport function get<K extends keyof ConfigSchema>(key: K): ConfigSchema[K] {\n return config.get(key);\n}\n\nexport function set<K extends keyof ConfigSchema>(key: K, value: ConfigSchema[K]): void {\n config.set(key, value);\n}\n\nexport function setNested(key: string, value: unknown): void {\n config.set(key, value);\n}\n\nexport function getNested(key: string): unknown {\n return config.get(key);\n}\n\nexport function getApiKey(provider: string): string {\n // Check environment variables first, then config\n const envVarMap: Record<string, string> = {\n openai: 'OPENAI_API_KEY',\n anthropic: 'ANTHROPIC_API_KEY',\n google: 'GOOGLE_API_KEY',\n };\n\n const envVar = envVarMap[provider];\n if (envVar && process.env[envVar]) {\n const val = process.env[envVar] as string;\n // Ignore placeholder values from .env.example copies\n if (!val.startsWith('your-') && val !== '') {\n return val;\n }\n }\n\n const providers = config.get('providers');\n const providerConfig = providers[provider as keyof typeof providers];\n if (providerConfig && 'apiKey' in providerConfig) {\n return providerConfig.apiKey;\n }\n\n return '';\n}\n\nexport function setApiKey(provider: string, apiKey: string): void {\n const key = `providers.${provider}.apiKey` as keyof ConfigSchema;\n config.set(key, apiKey);\n}\n\nexport function getDefaultModel(): { provider: string; model: string } {\n return {\n provider: config.get('defaultProvider'),\n model: config.get('defaultModel'),\n };\n}\n\nexport function setDefaultModel(provider: string, model: string): void {\n config.set('defaultProvider', provider);\n config.set('defaultModel', model);\n}\n\nexport function hasAnyApiKey(): boolean {\n return ['openai', 'anthropic', 'google'].some((p) => getApiKey(p) !== '');\n}\n\n/** Provider priority order used for fallback selection. */\nconst PROVIDER_PRIORITY = ['openai', 'anthropic', 'google'] as const;\n\n/**\n * Returns an array of provider names that have a configured API key\n * (via environment variable or persisted config).\n */\nexport function getConfiguredProviders(): string[] {\n return PROVIDER_PRIORITY.filter((p) => getApiKey(p) !== '');\n}\n\n/**\n * Returns the first configured provider in priority order, or null\n * if no providers are configured.\n *\n * Priority: openai > anthropic > google\n */\nexport function getFirstConfiguredProvider(): string | null {\n return getConfiguredProviders()[0] ?? null;\n}\n\nexport function listAll(): Record<string, unknown> {\n return config.store as unknown as Record<string, unknown>;\n}\n\nexport function getConfigPath(): string {\n return config.path;\n}\n","import chalk from 'chalk';\nimport { getNested } from './config.js';\n\ntype Verbosity = 'quiet' | 'normal' | 'verbose' | 'debug';\n\nconst LEVELS: Record<Verbosity, number> = { quiet: 0, normal: 1, verbose: 2, debug: 3 };\n\nlet override: Verbosity | null = null;\n\nfunction level(): number {\n if (override) return LEVELS[override];\n const configured = getNested('verbosity') as Verbosity | undefined;\n return LEVELS[configured ?? 'normal'];\n}\n\nexport function setOverride(v: Verbosity): void {\n override = v;\n}\n\n/** Always shown, stderr. */\nexport function error(msg: string, ...args: unknown[]): void {\n console.error(msg, ...args);\n}\n\n/** normal+, stderr. */\nexport function warn(msg: string, ...args: unknown[]): void {\n if (level() >= LEVELS.normal) console.error(msg, ...args);\n}\n\n/** normal+, stdout (user-facing). */\nexport function info(msg: string, ...args: unknown[]): void {\n if (level() >= LEVELS.normal) console.log(msg, ...args);\n}\n\n/** verbose+, stderr, dim text with [tag] prefix. */\nexport function verbose(tag: string, msg: string): void {\n if (level() >= LEVELS.verbose) {\n process.stderr.write(chalk.dim(`[${tag}] ${msg}`) + '\\n');\n }\n}\n\n/** debug only, stderr, dim [DEBUG] prefix. */\nexport function debug(msg: string, ...args: unknown[]): void {\n if (level() >= LEVELS.debug) {\n process.stderr.write(chalk.dim(`[DEBUG] ${msg}`) + '\\n');\n if (args.length) {\n for (const arg of args) {\n process.stderr.write(chalk.dim(` ${typeof arg === 'string' ? arg : JSON.stringify(arg)}`) + '\\n');\n }\n }\n }\n}\n","import type { SmartHomeAdapter, DeviceConfig, DeviceStatus, DiscoveredDevice } from '../types.js';\nimport * as appConfig from '../../config.js';\nimport { verbose } from '../../logger.js';\nimport { appendFileSync } from 'node:fs';\n\nconst DIAG_LOG = 'cast-diag.log';\nfunction castDiag(msg: string): void {\n const line = `${new Date().toISOString()} ${msg}\\n`;\n try { appendFileSync(DIAG_LOG, line); } catch { /* ignore */ }\n}\n\n// Lazy-loaded modules — dynamic import so the app doesn't crash if packages are missing.\nlet castv2Loaded: typeof import('castv2-client') | null = null;\nlet bonjourLoaded: typeof import('bonjour-service') | null = null;\nlet googleTTSLoaded: typeof import('google-tts-api') | null = null;\n\nasync function getCastv2(): Promise<typeof import('castv2-client')> {\n if (!castv2Loaded) {\n try {\n castv2Loaded = await import('castv2-client');\n } catch {\n throw new Error('castv2-client is not installed. Run: npm install castv2-client');\n }\n }\n return castv2Loaded;\n}\n\nasync function getBonjour(): Promise<typeof import('bonjour-service')> {\n if (!bonjourLoaded) {\n try {\n bonjourLoaded = await import('bonjour-service');\n } catch {\n throw new Error('bonjour-service is not installed. Run: npm install bonjour-service');\n }\n }\n return bonjourLoaded;\n}\n\nasync function getGoogleTTS(): Promise<typeof import('google-tts-api')> {\n if (!googleTTSLoaded) {\n try {\n googleTTSLoaded = await import('google-tts-api');\n } catch {\n throw new Error('google-tts-api is not installed. Run: npm install google-tts-api');\n }\n }\n return googleTTSLoaded;\n}\n\n// Track active client connections by device ID\nconst activeClients = new Map<string, InstanceType<(typeof import('castv2-client'))['Client']>>();\n// Track active media players by device ID\nconst activePlayers = new Map<string, InstanceType<(typeof import('castv2-client'))['DefaultMediaReceiver']>>();\n// Track active cast session cleanup functions by device ID (proxy server + client teardown)\nconst activeCastCleanups = new Map<string, () => void>();\n\nfunction getHostPort(config: DeviceConfig): { host: string; port: number } {\n if (!config.cast) {\n throw new Error(`Device \"${config.id}\" has no cast configuration.`);\n }\n return { host: config.cast.host, port: config.cast.port ?? 8009 };\n}\n\n/**\n * Connect to a Cast device and optionally launch the DefaultMediaReceiver.\n * Returns the client and player.\n */\nasync function connectAndLaunch(config: DeviceConfig): Promise<{\n client: InstanceType<(typeof import('castv2-client'))['Client']>;\n player: InstanceType<(typeof import('castv2-client'))['DefaultMediaReceiver']>;\n}> {\n const castv2 = await getCastv2();\n const { host, port } = getHostPort(config);\n\n const client = new castv2.Client();\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n client.close();\n reject(new Error(`Connection to ${host}:${port} timed out after 10 seconds`));\n }, 10_000);\n\n client.connect({ host, port }, () => {\n clearTimeout(timeout);\n resolve();\n });\n\n client.on('error', (err: Error) => {\n clearTimeout(timeout);\n reject(err);\n });\n });\n\n const player = await new Promise<InstanceType<(typeof import('castv2-client'))['DefaultMediaReceiver']>>(\n (resolve, reject) => {\n const timeout = setTimeout(() => {\n client.close();\n reject(new Error(`Launching media receiver on ${host}:${port} timed out after 15 seconds`));\n }, 15_000);\n\n client.launch(castv2.DefaultMediaReceiver, (err, p) => {\n clearTimeout(timeout);\n if (err) reject(err);\n else resolve(p);\n });\n },\n );\n\n activeClients.set(config.id, client);\n activePlayers.set(config.id, player);\n\n return { client, player };\n}\n\n/**\n * Get or create a client connection (without launching a media receiver).\n */\nasync function getClient(config: DeviceConfig): Promise<InstanceType<(typeof import('castv2-client'))['Client']>> {\n const existing = activeClients.get(config.id);\n if (existing) return existing;\n\n const castv2 = await getCastv2();\n const { host, port } = getHostPort(config);\n\n const client = new castv2.Client();\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n client.close();\n reject(new Error(`Connection to ${host}:${port} timed out after 10 seconds`));\n }, 10_000);\n\n client.connect({ host, port }, () => {\n clearTimeout(timeout);\n resolve();\n });\n\n client.on('error', (err: Error) => {\n clearTimeout(timeout);\n reject(err);\n });\n });\n\n activeClients.set(config.id, client);\n return client;\n}\n\n/**\n * Extract a direct audio stream URL from YouTube using youtube-dl-exec\n * (bundles yt-dlp binary in node_modules — no Python or global install needed),\n * then proxy-stream it to the Cast device via a local HTTP server.\n */\nasync function castYouTubeAudio(\n config: DeviceConfig,\n videoId: string,\n title?: string,\n): Promise<{ success: boolean; error?: string }> {\n const ytUrl = `https://www.youtube.com/watch?v=${videoId}`;\n const castTag = `cast:yt:${videoId}`;\n castDiag(`[cast-diag] ENTERED castYouTubeAudio: videoId=${videoId}, device=${config.id}`);\n\n // Stop any existing cast session for this device so the new track can play cleanly\n const existingCleanup = activeCastCleanups.get(config.id);\n if (existingCleanup) {\n verbose(castTag, `Cleaning up previous cast session for device \"${config.id}\"`);\n existingCleanup();\n activeCastCleanups.delete(config.id);\n }\n\n // Extract the direct audio CDN URL using the bundled yt-dlp binary\n let audioStreamUrl: string;\n try {\n const ytdlMod = await import('youtube-dl-exec');\n const youtubedl = (ytdlMod.default ?? ytdlMod) as (\n url: string,\n opts: Record<string, unknown>,\n ) => Promise<string>;\n\n const result = await youtubedl(ytUrl, {\n getUrl: true,\n format: 'bestaudio[ext=m4a]/bestaudio',\n noWarnings: true,\n noCheckCertificates: true,\n });\n\n audioStreamUrl = String(result).trim().split('\\n')[0];\n if (!audioStreamUrl || !audioStreamUrl.startsWith('http')) {\n return { success: false, error: `Could not extract audio URL for \"${videoId}\".` };\n }\n verbose(castTag, `Extracted audio CDN URL (length=${audioStreamUrl.length})`);\n castDiag(`[cast-diag] yt-dlp extracted URL OK (length=${audioStreamUrl.length})`);\n } catch (err) {\n castDiag(`[cast-diag] yt-dlp FAILED: ${err instanceof Error ? err.message : String(err)}`);\n return {\n success: false,\n error: `Failed to extract audio: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n // Proxy the YouTube CDN audio to the Cast device via a local HTTP server.\n // Cast devices need an accessible URL; the CDN URLs are signed and may\n // require specific headers, so we proxy to avoid issues.\n const http = await import('node:http');\n const https = await import('node:https');\n const { randomUUID } = await import('node:crypto');\n\n const audioPath = `/${randomUUID()}.m4a`;\n let serverClosed = false;\n let proxyRequestCount = 0;\n\n const server = http.createServer((req, res) => {\n // Strip query string for path matching (Cast devices may append query params)\n const reqPath = (req.url ?? '').split('?')[0];\n if (reqPath !== audioPath) {\n verbose(castTag, `Proxy 404: ${req.method} ${req.url}`);\n res.writeHead(404);\n res.end();\n return;\n }\n\n proxyRequestCount++;\n verbose(castTag, `Proxy request #${proxyRequestCount}: ${req.method} ${req.url} (range: ${req.headers.range ?? 'none'})`);\n castDiag(`[cast-diag] Proxy request #${proxyRequestCount}: ${req.method} (range: ${req.headers.range ?? 'none'})`);\n\n // Handle HEAD requests — Cast devices probe with HEAD before GET\n if (req.method === 'HEAD') {\n const fetchHead = (url: string, redirects = 0) => {\n if (redirects > 5) {\n res.writeHead(502);\n res.end();\n return;\n }\n const mod = url.startsWith('https') ? https : http;\n const headReq = mod.request(url, { method: 'HEAD' }, (upstream) => {\n if (upstream.statusCode && upstream.statusCode >= 300 && upstream.statusCode < 400 && upstream.headers.location) {\n upstream.resume();\n fetchHead(upstream.headers.location, redirects + 1);\n return;\n }\n const headers: Record<string, string> = {\n 'Content-Type': upstream.headers['content-type'] ?? 'audio/mp4',\n 'Accept-Ranges': 'bytes',\n };\n if (upstream.headers['content-length']) {\n headers['Content-Length'] = upstream.headers['content-length'];\n }\n res.writeHead(200, headers);\n res.end();\n upstream.resume();\n });\n headReq.on('error', () => {\n res.writeHead(502);\n res.end();\n });\n headReq.end();\n };\n fetchHead(audioStreamUrl);\n return;\n }\n\n // Follow redirects (YouTube CDN often returns 302) and support Range requests\n const fetchUpstream = (url: string, redirects = 0) => {\n if (redirects > 5) {\n res.writeHead(502);\n res.end();\n return;\n }\n\n const parsedUrl = new URL(url);\n const reqOptions: import('node:https').RequestOptions = {\n hostname: parsedUrl.hostname,\n port: parsedUrl.port,\n path: parsedUrl.pathname + parsedUrl.search,\n method: 'GET',\n headers: {},\n };\n\n // Forward Range header from Cast device to upstream CDN\n if (req.headers.range) {\n (reqOptions.headers as Record<string, string>)['Range'] = req.headers.range;\n }\n\n const mod = url.startsWith('https') ? https : http;\n const upstreamReq = mod.request(reqOptions, (upstream) => {\n if (upstream.statusCode && upstream.statusCode >= 300 && upstream.statusCode < 400 && upstream.headers.location) {\n upstream.resume();\n fetchUpstream(upstream.headers.location, redirects + 1);\n return;\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': upstream.headers['content-type'] ?? 'audio/mp4',\n 'Accept-Ranges': 'bytes',\n };\n if (upstream.headers['content-length']) {\n headers['Content-Length'] = upstream.headers['content-length'];\n }\n if (upstream.headers['content-range']) {\n headers['Content-Range'] = upstream.headers['content-range'];\n }\n\n const statusCode = upstream.statusCode ?? 200;\n verbose(castTag, `Upstream responded: ${statusCode} (content-length: ${upstream.headers['content-length'] ?? 'unknown'})`);\n castDiag(`[cast-diag] Upstream responded: ${statusCode} (content-length: ${upstream.headers['content-length'] ?? 'unknown'}, type: ${upstream.headers['content-type'] ?? 'unknown'})`);\n\n res.writeHead(statusCode, headers);\n upstream.pipe(res);\n upstream.on('error', (err) => {\n verbose(castTag, `Upstream stream error: ${err.message}`);\n res.end();\n });\n });\n\n upstreamReq.on('error', (err) => {\n verbose(castTag, `Upstream request error: ${err.message}`);\n res.writeHead(502);\n res.end();\n });\n upstreamReq.end();\n };\n\n fetchUpstream(audioStreamUrl);\n });\n\n await new Promise<void>((resolve, reject) => {\n server.on('error', (err) => {\n verbose(castTag, `Audio proxy server error: ${err.message}`);\n reject(err);\n });\n server.listen(0, '0.0.0.0', () => resolve());\n });\n\n const address = server.address();\n if (!address || typeof address === 'string') {\n server.close();\n return { success: false, error: 'Failed to start audio proxy server.' };\n }\n\n // Find our local IP that the Cast device can reach\n const localIp = await getLocalIpForDevice(config);\n const proxyUrl = `http://${localIp}:${address.port}${audioPath}`;\n verbose(castTag, `Audio proxy listening at ${proxyUrl}`);\n castDiag(`[cast-diag] Proxy: ${proxyUrl}`);\n\n // Verify the proxy is accessible before sending to Cast device\n try {\n const testResult = await new Promise<{ ok: boolean; error?: string }>((resolve) => {\n const testReq = http.request(proxyUrl, { method: 'HEAD', timeout: 5_000 }, (res) => {\n res.resume();\n if (res.statusCode === 200) {\n resolve({ ok: true });\n } else {\n resolve({ ok: false, error: `Proxy self-test returned HTTP ${res.statusCode}` });\n }\n });\n testReq.on('error', (err) => resolve({ ok: false, error: err.message }));\n testReq.on('timeout', () => {\n testReq.destroy();\n resolve({ ok: false, error: 'Self-test timed out — proxy may not be reachable' });\n });\n testReq.end();\n });\n\n if (!testResult.ok) {\n verbose(castTag, `Proxy self-test failed: ${testResult.error}`);\n server.close();\n return { success: false, error: `Audio proxy is not accessible: ${testResult.error}` };\n }\n verbose(castTag, `Proxy self-test passed`);\n castDiag(`[cast-diag] Proxy self-test PASSED`);\n } catch (err) {\n castDiag(`[cast-diag] Proxy self-test THREW: ${err instanceof Error ? err.message : String(err)}`);\n verbose(castTag, `Proxy self-test threw: ${err instanceof Error ? err.message : String(err)}`);\n server.close();\n return { success: false, error: `Audio proxy self-test failed: ${err instanceof Error ? err.message : String(err)}` };\n }\n\n // Cast the proxied URL\n try {\n castDiag(`[cast-diag] Connecting to Cast device...`);\n const { client, player } = await connectAndLaunch(config);\n castDiag(`[cast-diag] Connected to Cast device, loading media at ${proxyUrl}`);\n verbose(castTag, `Connected to Cast device, loading media...`);\n\n await new Promise<void>((resolve, reject) => {\n const loadTimeout = setTimeout(() => {\n reject(new Error('player.load() timed out after 15 seconds — Cast device did not respond'));\n }, 15_000);\n\n player.load(\n {\n contentId: proxyUrl,\n contentType: 'audio/mp4',\n streamType: 'BUFFERED',\n metadata: {\n type: 0,\n metadataType: 0,\n title: title ?? 'YouTube Audio',\n },\n },\n { autoplay: true },\n (err) => {\n clearTimeout(loadTimeout);\n if (err) reject(err);\n else resolve();\n },\n );\n });\n\n verbose(castTag, `player.load() callback fired (success). Waiting for playback to start...`);\n castDiag(`[cast-diag] player.load() SUCCESS. Waiting for playback...`);\n\n // Wait for the Cast device to actually start playing (or fail).\n // The load callback only means the device accepted the request, NOT that\n // it successfully fetched and decoded the media. We poll player status to\n // confirm playback actually started, with a timeout.\n const playbackConfirmed = await waitForPlayback(player, castTag, 15_000);\n castDiag(`[cast-diag] waitForPlayback result: playing=${playbackConfirmed.playing}, state=${playbackConfirmed.state}, idleReason=${playbackConfirmed.idleReason ?? 'none'}, proxyRequests=${proxyRequestCount}`);\n\n if (!playbackConfirmed.playing) {\n verbose(castTag, `Cast device did not start playing. State: ${playbackConfirmed.state}, idle reason: ${playbackConfirmed.idleReason ?? 'none'}`);\n\n // If the proxy never received a request, the device could not reach it\n if (proxyRequestCount === 0) {\n verbose(castTag, `Proxy received 0 requests — the Cast device likely cannot reach this machine. Check firewall settings.`);\n server.close();\n client.close();\n activeClients.delete(config.id);\n activePlayers.delete(config.id);\n return {\n success: false,\n error:\n `Cast device accepted the media URL but never fetched it (0 proxy requests). ` +\n `This usually means a firewall is blocking inbound connections on port ${address.port}. ` +\n `Proxy URL: ${proxyUrl}`,\n };\n }\n\n server.close();\n client.close();\n activeClients.delete(config.id);\n activePlayers.delete(config.id);\n return {\n success: false,\n error:\n `Cast device did not start playback. Player state: ${playbackConfirmed.state}` +\n (playbackConfirmed.idleReason ? `, idle reason: ${playbackConfirmed.idleReason}` : '') +\n `. The device may have rejected the audio format.`,\n };\n }\n\n verbose(castTag, `Playback confirmed (state: ${playbackConfirmed.state}). Proxy requests so far: ${proxyRequestCount}`);\n castDiag(`[cast-diag] Playback confirmed. proxyRequests=${proxyRequestCount}`);\n\n // Sanity check: if the Cast device reports PLAYING but the proxy never\n // received a request, the device may be \"playing\" a stale/empty session.\n if (proxyRequestCount === 0) {\n verbose(castTag, `WARNING: Cast device reports PLAYING but proxy received 0 requests — audio is likely not streaming`);\n server.close();\n client.close();\n activeClients.delete(config.id);\n activePlayers.delete(config.id);\n return {\n success: false,\n error:\n `Cast device reports PLAYING but the audio proxy received 0 requests. ` +\n `The device likely cannot reach this machine. Check firewall settings. ` +\n `Proxy URL was: ${proxyUrl}`,\n };\n }\n\n // Keep a reference to client so GC doesn't sever the CASTV2 TCP connection.\n // The auto-close timer handles cleanup.\n let autoCloseTimer: ReturnType<typeof setTimeout> | null = null;\n\n const closeProxyAndClient = () => {\n if (autoCloseTimer) {\n clearTimeout(autoCloseTimer);\n autoCloseTimer = null;\n }\n if (!serverClosed) {\n serverClosed = true;\n server.close();\n verbose(castTag, `Proxy server closed`);\n }\n // Close the Cast client/player so the device is free for a new session\n try { player.stop(() => { /* ignore */ }); } catch { /* ignore */ }\n try { client.close(); } catch { /* ignore */ }\n activeClients.delete(config.id);\n activePlayers.delete(config.id);\n activeCastCleanups.delete(config.id);\n };\n\n // Register cleanup so the next castYouTubeAudio call can tear this session down\n activeCastCleanups.set(config.id, closeProxyAndClient);\n\n // Listen for player stop/close to clean up the proxy early\n player.on('status', (status: { playerState?: string; idleReason?: string }) => {\n if (status.playerState === 'IDLE' && status.idleReason) {\n verbose(castTag, `Player went idle: ${status.idleReason}`);\n closeProxyAndClient();\n }\n });\n\n // Auto-close the proxy after 4 hours (safety net)\n autoCloseTimer = setTimeout(() => {\n closeProxyAndClient();\n }, 4 * 60 * 60 * 1000);\n autoCloseTimer.unref();\n\n return { success: true };\n } catch (err) {\n server.close();\n return { success: false, error: err instanceof Error ? err.message : String(err) };\n }\n}\n\n/**\n * Poll the Cast player status until playback starts or a timeout is reached.\n * Returns the final observed state so the caller can decide how to proceed.\n */\nasync function waitForPlayback(\n player: InstanceType<(typeof import('castv2-client'))['DefaultMediaReceiver']>,\n tag: string,\n timeoutMs: number,\n): Promise<{ playing: boolean; state: string; idleReason?: string }> {\n const startTime = Date.now();\n const pollInterval = 1_000;\n let sawBuffering = false;\n\n while (Date.now() - startTime < timeoutMs) {\n try {\n const status = await new Promise<{ playerState?: string; idleReason?: string } | null>(\n (resolve, reject) => {\n const t = setTimeout(() => resolve(null), 3_000);\n player.getStatus((err, s) => {\n clearTimeout(t);\n if (err) reject(err);\n else resolve(s);\n });\n },\n );\n\n const state = status?.playerState ?? 'UNKNOWN';\n\n if (state === 'PLAYING') {\n return { playing: true, state };\n }\n\n // BUFFERING means the device accepted the media and is fetching data.\n // Track it but keep polling — we need to see PLAYING to confirm audio\n // is actually being produced. If it stays BUFFERING until timeout,\n // something is wrong (e.g. firewall blocking the stream).\n if (state === 'BUFFERING') {\n sawBuffering = true;\n verbose(tag, `Device is buffering... waiting for PLAYING state`);\n }\n\n // If the device went IDLE with an error reason, it rejected the media\n if (state === 'IDLE' && status?.idleReason) {\n return { playing: false, state, idleReason: status.idleReason };\n }\n\n verbose(tag, `Waiting for playback... current state: ${state}`);\n } catch (err) {\n verbose(tag, `Error polling player status: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n await new Promise<void>((resolve) => setTimeout(resolve, pollInterval));\n }\n\n return {\n playing: false,\n state: sawBuffering ? 'BUFFERING_TIMEOUT' : 'TIMEOUT',\n idleReason: sawBuffering\n ? 'Device started buffering but never reached PLAYING state — the audio stream may be unreachable (check firewall) or the format was rejected'\n : undefined,\n };\n}\n\n/**\n * Determine the local IP address that a Cast device can reach.\n */\nasync function getLocalIpForDevice(config: DeviceConfig): Promise<string> {\n const os = await import('node:os');\n const dgram = await import('node:dgram');\n const { host: deviceHost } = getHostPort(config);\n\n try {\n const sock = dgram.createSocket('udp4');\n const ip = await new Promise<string>((resolve) => {\n sock.connect(1, deviceHost, () => {\n const addr = sock.address().address;\n sock.close();\n resolve(addr);\n });\n sock.on('error', () => {\n sock.close();\n resolve('');\n });\n setTimeout(() => {\n try { sock.close(); } catch { /* */ }\n resolve('');\n }, 2_000);\n });\n if (ip) return ip;\n } catch { /* fall through */ }\n\n // Fallback: prefer an IPv4 address on the same subnet as the device.\n // Machines with virtual adapters (VMware, WSL, Docker) may have many\n // non-internal IPs — picking the wrong one means the Cast device can't\n // reach the proxy.\n const interfaces = os.networkInterfaces();\n const deviceParts = deviceHost.split('.');\n let bestMatch: string | null = null;\n let firstNonInternal: string | null = null;\n\n for (const nets of Object.values(interfaces)) {\n if (!nets) continue;\n for (const net of nets) {\n if (net.family === 'IPv4' && !net.internal) {\n if (!firstNonInternal) firstNonInternal = net.address;\n // Prefer same /24 subnet as the Cast device\n const parts = net.address.split('.');\n if (parts[0] === deviceParts[0] && parts[1] === deviceParts[1] && parts[2] === deviceParts[2]) {\n bestMatch = net.address;\n }\n }\n }\n }\n\n if (bestMatch) return bestMatch;\n if (firstNonInternal) return firstNonInternal;\n return '127.0.0.1';\n}\n\n/**\n * Handle OAuth2 authentication for Google Assistant.\n *\n * We manage the OAuth flow ourselves instead of using the google-assistant\n * package's built-in auth because:\n * 1. Its readline \"Paste your code:\" prompt conflicts with our readline\n * 2. It redirects to http://localhost (port 80) with no server listening\n *\n * Flow:\n * - If saved tokens exist, load them and return an authed client\n * - Otherwise, spin up a local HTTP server on a random port, open the\n * browser for consent, catch the redirect with the auth code, exchange\n * it for tokens, save them, and return the authed client\n */\nexport async function getAuthenticatedOAuthClient(\n keyFilePath: string,\n savedTokensPath: string,\n): Promise<{ client: InstanceType<typeof import('google-auth-library').OAuth2Client> } | { error: string }> {\n const fs = await import('node:fs');\n const path = await import('node:path');\n const { OAuth2Client } = await import('google-auth-library');\n\n const keyFileContent = JSON.parse(fs.readFileSync(keyFilePath, 'utf-8'));\n const key = keyFileContent.installed ?? keyFileContent.web;\n\n // If we have saved tokens, use them directly\n try {\n const tokensRaw = fs.readFileSync(savedTokensPath, 'utf-8');\n const tokens = JSON.parse(tokensRaw);\n if (tokens && (tokens.refresh_token || tokens.access_token)) {\n const client = new OAuth2Client(key.client_id, key.client_secret);\n client.setCredentials(tokens);\n return { client };\n }\n } catch {\n // No saved tokens — need to do the OAuth flow\n }\n\n // Start a local HTTP server to catch the OAuth redirect\n const http = await import('node:http');\n\n const { code, redirectUri } = await new Promise<{ code: string | null; redirectUri: string }>(\n (resolve) => {\n let serverPort = 0;\n\n const server = http.createServer((req, res) => {\n const url = new URL(req.url ?? '/', `http://localhost:${serverPort}`);\n const authCode = url.searchParams.get('code');\n const error = url.searchParams.get('error');\n\n if (error) {\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end('<h2>Authorization denied.</h2><p>You can close this tab.</p>');\n server.close();\n resolve({ code: null, redirectUri: '' });\n return;\n }\n\n if (authCode) {\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(\n '<h2>Authorization successful!</h2>' +\n '<p>You can close this tab and return to the CLI.</p>',\n );\n server.close();\n resolve({ code: authCode, redirectUri: `http://localhost:${serverPort}` });\n return;\n }\n\n res.writeHead(404);\n res.end();\n });\n\n server.on('error', (err) => {\n verbose('google-assistant', `OAuth callback server error: ${err.message}`);\n resolve({ code: null, redirectUri: '' });\n });\n\n server.listen(0, '127.0.0.1', async () => {\n const addr = server.address();\n if (!addr || typeof addr === 'string') {\n server.close();\n resolve({ code: null, redirectUri: '' });\n return;\n }\n\n serverPort = addr.port;\n const redir = `http://localhost:${serverPort}`;\n const oauthClient = new OAuth2Client(key.client_id, key.client_secret, redir);\n const authUrl = oauthClient.generateAuthUrl({\n access_type: 'offline',\n scope: ['https://www.googleapis.com/auth/assistant-sdk-prototype'],\n });\n\n // Open browser for consent\n try {\n const openMod = await import('open');\n const openFn = (openMod.default ?? openMod) as (url: string) => Promise<unknown>;\n await openFn(authUrl);\n } catch {\n console.log(`\\nOpen this URL in your browser to authorize:\\n${authUrl}\\n`);\n }\n });\n\n // Timeout after 120 seconds\n const oauthTimeout = setTimeout(() => {\n server.close();\n resolve({ code: null, redirectUri: '' });\n }, 120_000);\n oauthTimeout.unref();\n },\n );\n\n if (!code) {\n return { error: 'OAuth authorization was not completed. Try again via /devices → Edit.' };\n }\n\n // Exchange the code for tokens using the same redirect URI\n const client = new OAuth2Client(key.client_id, key.client_secret, redirectUri);\n try {\n const { tokens } = await client.getToken(code);\n client.setCredentials(tokens!);\n\n // Save tokens for future use\n const dir = path.dirname(savedTokensPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(savedTokensPath, JSON.stringify(tokens), { mode: 0o600 });\n\n return { client };\n } catch (err) {\n return {\n error: `Failed to exchange OAuth code for tokens: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n}\n\nexport const googleCastAdapter: SmartHomeAdapter = {\n platform: 'google-cast',\n\n async connect(config: DeviceConfig): Promise<{ success: boolean; error?: string }> {\n try {\n await getClient(config);\n return { success: true };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n\n async disconnect(deviceId: string): Promise<void> {\n const client = activeClients.get(deviceId);\n if (client) {\n client.close();\n activeClients.delete(deviceId);\n activePlayers.delete(deviceId);\n }\n },\n\n async testConnection(config: DeviceConfig): Promise<{ success: boolean; message: string }> {\n try {\n const client = await getClient(config);\n const status = await new Promise<Record<string, unknown> | null>((resolve, reject) => {\n client.getStatus((err, s) => {\n if (err) reject(err);\n else resolve(s);\n });\n });\n\n // Clean up after test\n client.close();\n activeClients.delete(config.id);\n\n const appName = (status as Record<string, unknown> | null)?.applications\n ? 'running'\n : 'idle';\n\n return {\n success: true,\n message: `Connected to ${config.cast?.host}:${config.cast?.port ?? 8009} successfully. Device is ${appName}.`,\n };\n } catch (error) {\n return {\n success: false,\n message: error instanceof Error ? error.message : String(error),\n };\n }\n },\n\n async discover(onDeviceFound?: (device: DiscoveredDevice) => void): Promise<DiscoveredDevice[]> {\n const bonjourMod = await getBonjour();\n const BonjourClass = bonjourMod.Bonjour ?? bonjourMod.default;\n const instance = new BonjourClass();\n\n return new Promise((resolve) => {\n const devices: DiscoveredDevice[] = [];\n const seenHosts = new Set<string>();\n\n const browser = instance.find({ type: 'googlecast' }, (service) => {\n const host = service.referer?.address ?? service.addresses?.[0] ?? '';\n if (!host || seenHosts.has(host)) return;\n\n seenHosts.add(host);\n\n const device: DiscoveredDevice = {\n name: service.name ?? 'Unknown',\n host,\n port: service.port ?? 8009,\n model: (service.txt as Record<string, string> | undefined)?.md,\n };\n\n devices.push(device);\n onDeviceFound?.(device);\n });\n\n // Stop scanning after 60 seconds for thorough network discovery\n setTimeout(() => {\n browser.stop();\n instance.destroy();\n resolve(devices);\n }, 60_000);\n });\n },\n\n async getStatus(config: DeviceConfig): Promise<DeviceStatus> {\n try {\n const client = await getClient(config);\n\n const [receiverStatus, volume] = await Promise.all([\n new Promise<Record<string, unknown> | null>((resolve, reject) => {\n client.getStatus((err, s) => {\n if (err) reject(err);\n else resolve(s);\n });\n }),\n new Promise<{ level?: number; muted?: boolean }>((resolve, reject) => {\n client.getVolume((err, v) => {\n if (err) reject(err);\n else resolve(v);\n });\n }),\n ]);\n\n return {\n online: true,\n platform: 'google-cast',\n volume: volume.level !== undefined ? Math.round(volume.level * 100) : undefined,\n muted: volume.muted,\n mediaStatus: receiverStatus ? { playerState: 'available' } : undefined,\n };\n } catch {\n return { online: false, platform: 'google-cast' };\n }\n },\n\n async playMedia(\n config: DeviceConfig,\n mediaUrl: string,\n contentType?: string,\n title?: string,\n ): Promise<{ success: boolean; error?: string }> {\n try {\n const { client, player } = await connectAndLaunch(config);\n\n await new Promise<void>((resolve, reject) => {\n const loadTimeout = setTimeout(() => {\n reject(new Error('player.load() timed out after 15 seconds — Cast device did not respond'));\n }, 15_000);\n\n player.load(\n {\n contentId: mediaUrl,\n contentType: contentType ?? 'audio/mp3',\n streamType: 'BUFFERED',\n metadata: { title: title ?? 'Media' },\n },\n { autoplay: true },\n (err) => {\n clearTimeout(loadTimeout);\n if (err) reject(err);\n else resolve();\n },\n );\n });\n\n // Wait for the Cast device to actually start playing\n const playbackConfirmed = await waitForPlayback(player, 'playMedia', 15_000);\n if (!playbackConfirmed.playing) {\n client.close();\n activeClients.delete(config.id);\n activePlayers.delete(config.id);\n return {\n success: false,\n error:\n `Cast device did not start playback. Player state: ${playbackConfirmed.state}` +\n (playbackConfirmed.idleReason ? `, idle reason: ${playbackConfirmed.idleReason}` : ''),\n };\n }\n\n return { success: true };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n\n async controlPlayback(\n config: DeviceConfig,\n action: 'pause' | 'resume' | 'stop' | 'setVolume' | 'mute' | 'unmute' | 'seek',\n value?: number,\n ): Promise<{ success: boolean; error?: string }> {\n try {\n const client = await getClient(config);\n const player = activePlayers.get(config.id);\n\n switch (action) {\n case 'setVolume': {\n const level = (value ?? 50) / 100;\n await new Promise<void>((resolve, reject) => {\n client.setVolume({ level }, (err) => {\n if (err) reject(err);\n else resolve();\n });\n });\n break;\n }\n case 'mute':\n await new Promise<void>((resolve, reject) => {\n client.setVolume({ muted: true }, (err) => {\n if (err) reject(err);\n else resolve();\n });\n });\n break;\n case 'unmute':\n await new Promise<void>((resolve, reject) => {\n client.setVolume({ muted: false }, (err) => {\n if (err) reject(err);\n else resolve();\n });\n });\n break;\n case 'pause':\n if (!player) return { success: false, error: 'No active media session. Play something first.' };\n await new Promise<void>((resolve, reject) => {\n player.pause((err) => {\n if (err) reject(err);\n else resolve();\n });\n });\n break;\n case 'resume':\n if (!player) return { success: false, error: 'No active media session. Play something first.' };\n await new Promise<void>((resolve, reject) => {\n player.play((err) => {\n if (err) reject(err);\n else resolve();\n });\n });\n break;\n case 'stop':\n if (!player) return { success: false, error: 'No active media session.' };\n await new Promise<void>((resolve, reject) => {\n player.stop((err) => {\n if (err) reject(err);\n else resolve();\n });\n });\n break;\n case 'seek':\n if (!player) return { success: false, error: 'No active media session. Play something first.' };\n if (value === undefined) return { success: false, error: 'Seek requires a value in seconds.' };\n await new Promise<void>((resolve, reject) => {\n player.seek(value, (err) => {\n if (err) reject(err);\n else resolve();\n });\n });\n break;\n }\n\n return { success: true };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n\n async sendNotification(\n config: DeviceConfig,\n message: string,\n language?: string,\n ): Promise<{ success: boolean; error?: string }> {\n try {\n const tts = await getGoogleTTS();\n const audioUrl = tts.getAudioUrl(message, { lang: language ?? 'en' });\n\n return this.playMedia(config, audioUrl, 'audio/mp3', `TTS: ${message}`);\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n\n async castYouTube(\n config: DeviceConfig,\n videoId: string,\n title?: string,\n ): Promise<{ success: boolean; error?: string }> {\n try {\n return await castYouTubeAudio(config, videoId, title);\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n\n async askAssistant(\n config: DeviceConfig,\n command: string,\n language?: string,\n ): Promise<{ success: boolean; response?: string; error?: string }> {\n try {\n // Resolve credential paths: device config > env vars > global app config\n const keyFilePath =\n config.googleAssistant?.keyFilePath ??\n process.env.GOOGLE_ASSISTANT_KEY_FILE ??\n (appConfig.getNested('googleAssistant.keyFilePath') as string | undefined) ??\n '';\n\n const savedTokensPath =\n config.googleAssistant?.savedTokensPath ??\n process.env.GOOGLE_ASSISTANT_SAVED_TOKENS ??\n (appConfig.getNested('googleAssistant.savedTokensPath') as string | undefined) ??\n '';\n\n if (!keyFilePath) {\n return {\n success: false,\n error:\n 'Google Assistant credentials not configured for this device. ' +\n 'Run /devices → List devices → select your device → Edit → Google Assistant credentials. ' +\n 'Or set GOOGLE_ASSISTANT_KEY_FILE env var.',\n };\n }\n\n if (!savedTokensPath) {\n return {\n success: false,\n error:\n 'Google Assistant token path not configured for this device. ' +\n 'Run /devices → List devices → select your device → Edit → Google Assistant credentials. ' +\n 'Or set GOOGLE_ASSISTANT_SAVED_TOKENS env var.',\n };\n }\n\n // Validate the key file exists and has valid OAuth credentials\n const fs = await import('node:fs');\n if (!fs.existsSync(keyFilePath)) {\n return {\n success: false,\n error:\n `Google Assistant key file not found: \"${keyFilePath}\". ` +\n 'Run /devices → List devices → select your device → Edit → Google Assistant credentials to update the path.',\n };\n }\n\n try {\n const keyFileContent = JSON.parse(fs.readFileSync(keyFilePath, 'utf-8'));\n const creds = keyFileContent.installed ?? keyFileContent.web;\n if (!creds?.client_id || !creds?.client_secret) {\n return {\n success: false,\n error:\n `Key file \"${keyFilePath}\" is not a valid OAuth 2.0 client secret file. ` +\n 'Download the correct file from Google Cloud Console → APIs & Services → Credentials → OAuth 2.0 Client IDs → Download JSON.',\n };\n }\n } catch (parseErr) {\n return {\n success: false,\n error:\n `Failed to parse key file \"${keyFilePath}\": ${parseErr instanceof Error ? parseErr.message : String(parseErr)}. ` +\n 'Ensure it is a valid JSON file from Google Cloud Console.',\n };\n }\n\n // Get or create an authenticated OAuth2 client\n const oauthResult = await getAuthenticatedOAuthClient(keyFilePath, savedTokensPath);\n if ('error' in oauthResult) {\n return { success: false, error: oauthResult.error };\n }\n const oauth2Client = oauthResult.client;\n\n // Dynamically import the google-assistant package\n let GoogleAssistant: new (\n authConfig: { oauth2Client: unknown },\n callback?: (result: unknown) => void,\n ) => {\n start: (\n config: Record<string, unknown>,\n callback?: (conversation: unknown) => void,\n ) => void;\n on: (event: string, handler: (...args: unknown[]) => void) => void;\n };\n\n try {\n const mod = await import('google-assistant');\n GoogleAssistant = (mod.default ?? mod) as typeof GoogleAssistant;\n } catch {\n return {\n success: false,\n error: 'google-assistant package is not installed. Run: npm install google-assistant',\n };\n }\n\n // Initialize with pre-authed client (skips the package's broken auth flow)\n const result = await new Promise<{ success: boolean; response?: string; error?: string }>(\n (resolve) => {\n const timeout = setTimeout(() => {\n resolve({ success: false, error: 'Google Assistant request timed out after 30 seconds.' });\n }, 30_000);\n\n try {\n const assistant = new GoogleAssistant(\n { oauth2Client },\n (readyResult: unknown) => {\n if (readyResult instanceof Error) {\n clearTimeout(timeout);\n resolve({ success: false, error: `Assistant init failed: ${readyResult.message}` });\n return;\n }\n\n // Start a conversation with the text query\n assistant.start(\n {\n textQuery: command,\n lang: language ?? 'en-US',\n isNew: true,\n },\n (conversation: unknown) => {\n if (conversation instanceof Error) {\n clearTimeout(timeout);\n resolve({ success: false, error: `Conversation failed: ${conversation.message}` });\n return;\n }\n\n const conv = conversation as {\n on: (event: string, handler: (...args: unknown[]) => void) => void;\n end: () => void;\n };\n\n let responseText = '';\n const audioChunks: Buffer[] = [];\n\n conv.on('response', (text: unknown) => {\n if (typeof text === 'string' && text) {\n responseText = text;\n }\n });\n\n conv.on('audio-data', (data: unknown) => {\n if (Buffer.isBuffer(data)) {\n audioChunks.push(data);\n }\n });\n\n conv.on('error', (err: unknown) => {\n clearTimeout(timeout);\n resolve({\n success: false,\n error: err instanceof Error ? err.message : String(err),\n });\n });\n\n conv.on('ended', () => {\n clearTimeout(timeout);\n\n // If we got audio, cast it to the speaker\n if (audioChunks.length > 0) {\n const audioBuffer = Buffer.concat(audioChunks);\n castAssistantAudio(config, audioBuffer)\n .then(() => {\n resolve({\n success: true,\n response: responseText || 'Command executed (audio response sent to speaker).',\n });\n })\n .catch(() => {\n resolve({\n success: true,\n response:\n responseText ||\n 'Command executed (could not cast audio response to speaker).',\n });\n });\n } else {\n resolve({\n success: true,\n response: responseText || 'Command executed (no audio response).',\n });\n }\n });\n },\n );\n },\n );\n\n assistant.on('error', (err: unknown) => {\n clearTimeout(timeout);\n resolve({\n success: false,\n error: err instanceof Error ? err.message : String(err),\n });\n });\n } catch (err) {\n clearTimeout(timeout);\n resolve({\n success: false,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n },\n );\n\n return result;\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n};\n\n/**\n * Cast raw audio (LINEAR16 PCM from Google Assistant SDK) to a Cast device.\n * We write the buffer to a temporary WAV file served via a tiny HTTP server,\n * then cast that URL. The server auto-closes after the device fetches the audio.\n */\nasync function castAssistantAudio(config: DeviceConfig, audioBuffer: Buffer): Promise<void> {\n const http = await import('node:http');\n const { randomUUID } = await import('node:crypto');\n\n // Build a minimal WAV header for LINEAR16 PCM, 24000 Hz, mono\n const sampleRate = 24000;\n const bitsPerSample = 16;\n const numChannels = 1;\n const byteRate = sampleRate * numChannels * (bitsPerSample / 8);\n const blockAlign = numChannels * (bitsPerSample / 8);\n const dataSize = audioBuffer.length;\n const headerSize = 44;\n\n const wavHeader = Buffer.alloc(headerSize);\n wavHeader.write('RIFF', 0);\n wavHeader.writeUInt32LE(dataSize + headerSize - 8, 4);\n wavHeader.write('WAVE', 8);\n wavHeader.write('fmt ', 12);\n wavHeader.writeUInt32LE(16, 16); // PCM chunk size\n wavHeader.writeUInt16LE(1, 20); // PCM format\n wavHeader.writeUInt16LE(numChannels, 22);\n wavHeader.writeUInt32LE(sampleRate, 24);\n wavHeader.writeUInt32LE(byteRate, 28);\n wavHeader.writeUInt16LE(blockAlign, 32);\n wavHeader.writeUInt16LE(bitsPerSample, 34);\n wavHeader.write('data', 36);\n wavHeader.writeUInt32LE(dataSize, 40);\n\n const wavBuffer = Buffer.concat([wavHeader, audioBuffer]);\n\n // Spin up a one-shot HTTP server to serve the WAV file\n const audioId = randomUUID();\n const audioPath = `/${audioId}.wav`;\n\n const server = http.createServer((req, res) => {\n if (req.url === audioPath) {\n res.writeHead(200, {\n 'Content-Type': 'audio/wav',\n 'Content-Length': wavBuffer.length,\n });\n res.end(wavBuffer);\n\n // Auto-close after serving\n const closeTimer = setTimeout(() => {\n server.close();\n }, 5_000);\n closeTimer.unref();\n } else {\n res.writeHead(404);\n res.end();\n }\n });\n\n // Listen on a random port\n await new Promise<void>((resolve, reject) => {\n server.on('error', (err) => {\n verbose('google-assistant', `TTS audio server error: ${err.message}`);\n reject(err);\n });\n server.listen(0, '0.0.0.0', () => resolve());\n });\n\n const address = server.address();\n if (!address || typeof address === 'string') {\n server.close();\n throw new Error('Failed to start audio server');\n }\n\n // Determine our IP that the Cast device can reach.\n // Use the same network interface by connecting a UDP socket to the device's IP.\n const os = await import('node:os');\n const dgram = await import('node:dgram');\n const { host: deviceHost } = getHostPort(config);\n\n let localIp = '127.0.0.1';\n try {\n const sock = dgram.createSocket('udp4');\n sock.connect(1, deviceHost, () => {\n const addr = sock.address();\n localIp = addr.address;\n sock.close();\n });\n await new Promise<void>((resolve) => {\n sock.on('close', () => resolve());\n setTimeout(() => {\n try { sock.close(); } catch { /* already closed */ }\n resolve();\n }, 2_000);\n });\n } catch {\n // Fallback: pick the first non-internal IPv4 address\n const interfaces = os.networkInterfaces();\n for (const nets of Object.values(interfaces)) {\n if (!nets) continue;\n for (const net of nets) {\n if (net.family === 'IPv4' && !net.internal) {\n localIp = net.address;\n break;\n }\n }\n if (localIp !== '127.0.0.1') break;\n }\n }\n\n const audioUrl = `http://${localIp}:${address.port}${audioPath}`;\n\n // Cast the audio to the device\n try {\n const castv2 = await getCastv2();\n const { host, port } = getHostPort(config);\n\n const client = new castv2.Client();\n await new Promise<void>((resolve, reject) => {\n const t = setTimeout(() => {\n client.close();\n reject(new Error('Cast connection timed out'));\n }, 10_000);\n\n client.connect({ host, port }, () => {\n clearTimeout(t);\n resolve();\n });\n client.on('error', (err: Error) => {\n clearTimeout(t);\n reject(err);\n });\n });\n\n const player = await new Promise<InstanceType<(typeof import('castv2-client'))['DefaultMediaReceiver']>>(\n (resolve, reject) => {\n client.launch(castv2.DefaultMediaReceiver, (err, p) => {\n if (err) reject(err);\n else resolve(p);\n });\n },\n );\n\n await new Promise<void>((resolve, reject) => {\n player.load(\n {\n contentId: audioUrl,\n contentType: 'audio/wav',\n metadata: { title: 'Google Assistant' },\n },\n { autoplay: true },\n (err) => {\n if (err) reject(err);\n else resolve();\n },\n );\n });\n\n // Wait a moment for the device to start fetching, then let the server auto-close\n await new Promise<void>((resolve) => setTimeout(resolve, 2_000));\n\n // Don't close the client here — let the audio play through.\n // The server auto-closes 5s after serving the file.\n } catch (err) {\n server.close();\n throw err;\n }\n}\n","/**\n * Core Win32 FFI bindings via koffi.\n *\n * All DLL loads and function declarations live here.\n * Only loaded on Windows — callers must guard with `process.platform === 'win32'`.\n */\nimport koffi from 'koffi';\n\n// ── DLL handles ──────────────────────────────────────────────────────\n\nconst user32 = koffi.load('user32.dll');\nconst gdi32 = koffi.load('gdi32.dll');\n// kernel32 kept available for future use (e.g. GetLastError)\n// const kernel32 = koffi.load('kernel32.dll');\n\n// ── Struct types ─────────────────────────────────────────────────────\n\nexport const RECT = koffi.struct('RECT', {\n Left: 'int',\n Top: 'int',\n Right: 'int',\n Bottom: 'int',\n});\n\nexport const POINT = koffi.struct('POINT', {\n x: 'long',\n y: 'long',\n});\n\n// ── SendInput structs (mouse + keyboard) ─────────────────────────────\n\nexport const MOUSEINPUT = koffi.struct('MOUSEINPUT', {\n dx: 'long',\n dy: 'long',\n mouseData: 'uint32_t',\n dwFlags: 'uint32_t',\n time: 'uint32_t',\n dwExtraInfo: 'uintptr_t',\n});\n\nexport const KEYBDINPUT = koffi.struct('KEYBDINPUT', {\n wVk: 'uint16_t',\n wScan: 'uint16_t',\n dwFlags: 'uint32_t',\n time: 'uint32_t',\n dwExtraInfo: 'uintptr_t',\n});\n\nexport const HARDWAREINPUT = koffi.struct('HARDWAREINPUT', {\n uMsg: 'uint32_t',\n wParamL: 'uint16_t',\n wParamH: 'uint16_t',\n});\n\nexport const INPUT = koffi.struct('INPUT', {\n type: 'uint32_t',\n u: koffi.union({\n mi: MOUSEINPUT,\n ki: KEYBDINPUT,\n hi: HARDWAREINPUT,\n }),\n});\n\n// BITMAPINFOHEADER for GetDIBits\nexport const BITMAPINFOHEADER = koffi.struct('BITMAPINFOHEADER', {\n biSize: 'uint32_t',\n biWidth: 'int32_t',\n biHeight: 'int32_t',\n biPlanes: 'uint16_t',\n biBitCount: 'uint16_t',\n biCompression: 'uint32_t',\n biSizeImage: 'uint32_t',\n biXPelsPerMeter: 'int32_t',\n biYPelsPerMeter: 'int32_t',\n biClrUsed: 'uint32_t',\n biClrImportant: 'uint32_t',\n});\n\n// ── Callback prototype for EnumWindows ───────────────────────────────\n\nexport const EnumWindowsProc = koffi.proto(\n 'bool __stdcall EnumWindowsProc(intptr hWnd, intptr lParam)',\n);\n\n// ── user32 functions ─────────────────────────────────────────────────\n\nexport const EnumWindows = user32.func(\n 'bool __stdcall EnumWindows(EnumWindowsProc *cb, intptr lParam)',\n);\nexport const IsWindowVisible = user32.func(\n 'bool __stdcall IsWindowVisible(intptr hWnd)',\n);\nexport const GetWindowTextW = user32.func(\n 'int __stdcall GetWindowTextW(intptr hWnd, _Out_ uint16_t *buf, int maxCount)',\n);\nexport const GetWindowTextLengthW = user32.func(\n 'int __stdcall GetWindowTextLengthW(intptr hWnd)',\n);\nexport const GetWindowRect_ = user32.func(\n 'bool __stdcall GetWindowRect(intptr hWnd, _Out_ RECT *rect)',\n);\nexport const GetWindowThreadProcessId_ = user32.func(\n 'uint32_t __stdcall GetWindowThreadProcessId(intptr hWnd, _Out_ uint32_t *pid)',\n);\nexport const GetForegroundWindow = user32.func(\n 'intptr __stdcall GetForegroundWindow()',\n);\nexport const IsIconic = user32.func(\n 'bool __stdcall IsIconic(intptr hWnd)',\n);\nexport const MoveWindow_ = user32.func(\n 'bool __stdcall MoveWindow(intptr hWnd, int X, int Y, int W, int H, bool repaint)',\n);\nexport const ShowWindow_ = user32.func(\n 'bool __stdcall ShowWindow(intptr hWnd, int cmdShow)',\n);\nexport const SetForegroundWindow_ = user32.func(\n 'bool __stdcall SetForegroundWindow(intptr hWnd)',\n);\nexport const SetCursorPos_ = user32.func(\n 'bool __stdcall SetCursorPos(int X, int Y)',\n);\nexport const GetSystemMetrics = user32.func(\n 'int __stdcall GetSystemMetrics(int index)',\n);\nexport const SetProcessDPIAware = user32.func(\n 'bool __stdcall SetProcessDPIAware()',\n);\n\nexport const SendInput_ = user32.func(\n 'uint32_t __stdcall SendInput(uint32_t cInputs, INPUT *pInputs, int cbSize)',\n);\n\nexport const VkKeyScanW_ = user32.func(\n 'short __stdcall VkKeyScanW(uint16_t ch)',\n);\n\n// mouse_event — simpler alternative for click events\nexport const mouse_event_ = user32.func(\n 'void __stdcall mouse_event(uint32_t dwFlags, uint32_t dx, uint32_t dy, uint32_t dwData, uintptr_t dwExtraInfo)',\n);\n\n// ── GDI functions (for screenshots) ─────────────────────────────────\n\nexport const GetDC = user32.func(\n 'intptr __stdcall GetDC(intptr hWnd)',\n);\nexport const ReleaseDC = user32.func(\n 'int __stdcall ReleaseDC(intptr hWnd, intptr hDC)',\n);\nexport const CreateCompatibleDC = gdi32.func(\n 'intptr __stdcall CreateCompatibleDC(intptr hDC)',\n);\nexport const CreateCompatibleBitmap = gdi32.func(\n 'intptr __stdcall CreateCompatibleBitmap(intptr hDC, int w, int h)',\n);\nexport const SelectObject = gdi32.func(\n 'intptr __stdcall SelectObject(intptr hDC, intptr obj)',\n);\nexport const BitBlt = gdi32.func(\n 'bool __stdcall BitBlt(intptr hdcDest, int x, int y, int w, int h, intptr hdcSrc, int x2, int y2, uint32_t rop)',\n);\nexport const DeleteObject = gdi32.func(\n 'bool __stdcall DeleteObject(intptr obj)',\n);\nexport const DeleteDC = gdi32.func(\n 'bool __stdcall DeleteDC(intptr hDC)',\n);\nexport const GetDIBits_ = gdi32.func(\n 'int __stdcall GetDIBits(intptr hDC, intptr hBitmap, uint32_t start, uint32_t lines, void *bits, BITMAPINFOHEADER *bmi, uint32_t usage)',\n);\n\n// ── Constants ────────────────────────────────────────────────────────\n\n// SendInput type constants\nexport const INPUT_MOUSE = 0;\nexport const INPUT_KEYBOARD = 1;\n\n// Mouse event flags\nexport const MOUSEEVENTF_MOVE = 0x0001;\nexport const MOUSEEVENTF_LEFTDOWN = 0x0002;\nexport const MOUSEEVENTF_LEFTUP = 0x0004;\nexport const MOUSEEVENTF_RIGHTDOWN = 0x0008;\nexport const MOUSEEVENTF_RIGHTUP = 0x0010;\nexport const MOUSEEVENTF_MIDDLEDOWN = 0x0020;\nexport const MOUSEEVENTF_MIDDLEUP = 0x0040;\nexport const MOUSEEVENTF_ABSOLUTE = 0x8000;\n\n// Keyboard event flags\nexport const KEYEVENTF_EXTENDEDKEY = 0x0001;\nexport const KEYEVENTF_KEYUP = 0x0002;\nexport const KEYEVENTF_UNICODE = 0x0004;\n\n// GetSystemMetrics indices\nexport const SM_CXSCREEN = 0;\nexport const SM_CYSCREEN = 1;\n\n// ShowWindow commands\nexport const SW_NORMAL = 1;\nexport const SW_MAXIMIZE = 3;\nexport const SW_MINIMIZE = 6;\nexport const SW_RESTORE = 9;\n\n// BitBlt raster ops\nexport const SRCCOPY = 0x00CC0020;\n\n// ── DPI awareness ───────────────────────────────────────────────────\n\nSetProcessDPIAware();\n\n// ── INPUT struct size (for SendInput) ───────────────────────────────\n\nexport const INPUT_SIZE = koffi.sizeof(INPUT);\n","/**\n * Window management — enumerate, move, resize, focus windows.\n */\nimport koffi from 'koffi';\nimport {\n EnumWindows,\n EnumWindowsProc,\n IsWindowVisible,\n GetWindowTextW,\n GetWindowTextLengthW,\n GetWindowRect_,\n GetWindowThreadProcessId_,\n GetForegroundWindow,\n IsIconic,\n MoveWindow_,\n ShowWindow_,\n SetForegroundWindow_,\n SW_NORMAL,\n SW_MAXIMIZE,\n SW_MINIMIZE,\n SW_RESTORE,\n} from './win32.js';\n\n// ── Types ────────────────────────────────────────────────────────────\n\nexport interface WindowInfo {\n handle: string; // hex string like \"0x001A02B4\"\n title: string;\n pid: number;\n x: number;\n y: number;\n width: number;\n height: number;\n isMinimized: boolean;\n isForeground: boolean;\n}\n\n// ── Window enumeration ──────────────────────────────────────────────\n\nexport function listWindows(filter?: string): WindowInfo[] {\n const windows: WindowInfo[] = [];\n const fgHwnd = GetForegroundWindow();\n\n const cb = koffi.register(\n (hwnd: number, _lParam: number): boolean => {\n try {\n if (!IsWindowVisible(hwnd)) return true;\n\n const titleLen = GetWindowTextLengthW(hwnd);\n if (titleLen === 0) return true;\n\n // Read title (UTF-16)\n const buf = Buffer.alloc((titleLen + 1) * 2);\n GetWindowTextW(hwnd, buf, titleLen + 1);\n const title = buf.toString('utf16le', 0, titleLen * 2);\n\n // Apply filter\n if (filter && !title.toLowerCase().includes(filter.toLowerCase())) {\n return true;\n }\n\n // Window rect\n const rect = {} as { Left: number; Top: number; Right: number; Bottom: number };\n GetWindowRect_(hwnd, rect);\n\n // Process ID\n const pidArr = [0];\n GetWindowThreadProcessId_(hwnd, pidArr);\n\n windows.push({\n handle: '0x' + (hwnd >>> 0).toString(16).toUpperCase().padStart(8, '0'),\n title,\n pid: pidArr[0],\n x: rect.Left,\n y: rect.Top,\n width: rect.Right - rect.Left,\n height: rect.Bottom - rect.Top,\n isMinimized: IsIconic(hwnd),\n isForeground: hwnd === fgHwnd,\n });\n } catch {\n // Skip this window on error, continue enumeration\n }\n return true;\n },\n koffi.pointer(EnumWindowsProc),\n );\n\n try {\n EnumWindows(cb, 0);\n } finally {\n koffi.unregister(cb);\n }\n\n return windows;\n}\n\n// ── Window manipulation ─────────────────────────────────────────────\n\nconst SHOW_CMDS: Record<string, number> = {\n normal: SW_NORMAL,\n minimized: SW_MINIMIZE,\n maximized: SW_MAXIMIZE,\n restore: SW_RESTORE,\n};\n\nexport function moveWindow(\n hwnd: number,\n x: number,\n y: number,\n w: number,\n h: number,\n): boolean {\n return MoveWindow_(hwnd, x, y, w, h, true);\n}\n\nexport function showWindow(hwnd: number, state: string): boolean {\n const cmd = SHOW_CMDS[state] ?? SW_NORMAL;\n return ShowWindow_(hwnd, cmd);\n}\n\nexport function setForegroundWindow(hwnd: number): boolean {\n return SetForegroundWindow_(hwnd);\n}\n\nexport function getWindowRect(hwnd: number): {\n x: number;\n y: number;\n width: number;\n height: number;\n} {\n const rect = {} as { Left: number; Top: number; Right: number; Bottom: number };\n GetWindowRect_(hwnd, rect);\n return {\n x: rect.Left,\n y: rect.Top,\n width: rect.Right - rect.Left,\n height: rect.Bottom - rect.Top,\n };\n}\n\nexport function isMinimized(hwnd: number): boolean {\n return IsIconic(hwnd);\n}\n\n/**\n * Find a window by title substring. Returns the first match.\n */\nexport function findWindowByTitle(titleSubstring: string): WindowInfo | null {\n const windows = listWindows(titleSubstring);\n return windows.length > 0 ? windows[0]! : null;\n}\n\n/**\n * Parse a hex handle string like \"0x001A02B4\" to a numeric handle.\n */\nexport function parseHandle(handle: string): number {\n return parseInt(handle, 16);\n}\n\n/**\n * Resolve a window by title or handle string. Returns the numeric handle\n * and the current window info, or null if not found.\n */\nexport function resolveWindow(\n title?: string,\n handle?: string,\n): { hwnd: number; info: WindowInfo } | null {\n if (handle) {\n const hwnd = parseHandle(handle);\n // Verify it exists by trying to get its rect\n const rect = {} as { Left: number; Top: number; Right: number; Bottom: number };\n const ok = GetWindowRect_(hwnd, rect);\n if (!ok) return null;\n\n const titleLen = GetWindowTextLengthW(hwnd);\n let windowTitle = '';\n if (titleLen > 0) {\n const buf = Buffer.alloc((titleLen + 1) * 2);\n GetWindowTextW(hwnd, buf, titleLen + 1);\n windowTitle = buf.toString('utf16le', 0, titleLen * 2);\n }\n\n const pidArr = [0];\n GetWindowThreadProcessId_(hwnd, pidArr);\n\n return {\n hwnd,\n info: {\n handle: '0x' + (hwnd >>> 0).toString(16).toUpperCase().padStart(8, '0'),\n title: windowTitle,\n pid: pidArr[0],\n x: rect.Left,\n y: rect.Top,\n width: rect.Right - rect.Left,\n height: rect.Bottom - rect.Top,\n isMinimized: IsIconic(hwnd),\n isForeground: hwnd === GetForegroundWindow(),\n },\n };\n }\n\n if (title) {\n const win = findWindowByTitle(title);\n if (!win) return null;\n return { hwnd: parseHandle(win.handle), info: win };\n }\n\n return null;\n}\n","/**\n * Mouse control — move cursor, click, double-click.\n *\n * Uses SetCursorPos for positioning and mouse_event for click events.\n */\nimport {\n SetCursorPos_,\n mouse_event_,\n MOUSEEVENTF_LEFTDOWN,\n MOUSEEVENTF_LEFTUP,\n MOUSEEVENTF_RIGHTDOWN,\n MOUSEEVENTF_RIGHTUP,\n MOUSEEVENTF_MIDDLEDOWN,\n MOUSEEVENTF_MIDDLEUP,\n} from './win32.js';\n\n// ── Button flag map ─────────────────────────────────────────────────\n\nconst BUTTON_FLAGS = {\n left: { down: MOUSEEVENTF_LEFTDOWN, up: MOUSEEVENTF_LEFTUP },\n right: { down: MOUSEEVENTF_RIGHTDOWN, up: MOUSEEVENTF_RIGHTUP },\n middle: { down: MOUSEEVENTF_MIDDLEDOWN, up: MOUSEEVENTF_MIDDLEUP },\n} as const;\n\n// ── Public API ──────────────────────────────────────────────────────\n\n/**\n * Move the cursor to absolute screen coordinates.\n */\nexport function setCursorPos(x: number, y: number): boolean {\n return SetCursorPos_(x, y);\n}\n\n/**\n * Perform a mouse action at the given screen coordinates.\n */\nexport function mouseClick(\n x: number,\n y: number,\n button: 'left' | 'right' | 'middle' = 'left',\n action: 'click' | 'doubleclick' | 'down' | 'up' | 'move' = 'click',\n): boolean {\n // Move cursor to target\n SetCursorPos_(x, y);\n\n if (action === 'move') return true;\n\n const flags = BUTTON_FLAGS[button];\n\n switch (action) {\n case 'down':\n mouse_event_(flags.down, 0, 0, 0, 0);\n break;\n case 'up':\n mouse_event_(flags.up, 0, 0, 0, 0);\n break;\n case 'doubleclick':\n mouse_event_(flags.down, 0, 0, 0, 0);\n mouse_event_(flags.up, 0, 0, 0, 0);\n // Small delay between clicks for double-click detection\n mouse_event_(flags.down, 0, 0, 0, 0);\n mouse_event_(flags.up, 0, 0, 0, 0);\n break;\n case 'click':\n default:\n mouse_event_(flags.down, 0, 0, 0, 0);\n mouse_event_(flags.up, 0, 0, 0, 0);\n break;\n }\n\n return true;\n}\n","/**\n * Keyboard input — type text, press keys, send key combos.\n *\n * Uses SendInput with KEYBDINPUT for reliable input delivery.\n * For plain text, uses KEYEVENTF_UNICODE to send characters directly\n * without virtual-key mapping.\n */\nimport koffi from 'koffi';\nimport {\n SendInput_,\n INPUT,\n INPUT_KEYBOARD,\n INPUT_SIZE,\n KEYEVENTF_KEYUP,\n KEYEVENTF_UNICODE,\n KEYEVENTF_EXTENDEDKEY,\n} from './win32.js';\n\n// ── Virtual key code map ────────────────────────────────────────────\n\nconst VK_MAP: Record<string, { vk: number; extended?: boolean }> = {\n // Modifiers\n ctrl: { vk: 0x11 },\n control: { vk: 0x11 },\n alt: { vk: 0x12 },\n shift: { vk: 0x10 },\n win: { vk: 0x5b },\n lwin: { vk: 0x5b },\n rwin: { vk: 0x5c },\n\n // Navigation\n enter: { vk: 0x0d },\n return: { vk: 0x0d },\n tab: { vk: 0x09 },\n escape: { vk: 0x1b },\n esc: { vk: 0x1b },\n space: { vk: 0x20 },\n backspace: { vk: 0x08 },\n delete: { vk: 0x2e, extended: true },\n insert: { vk: 0x2d, extended: true },\n home: { vk: 0x24, extended: true },\n end: { vk: 0x23, extended: true },\n pageup: { vk: 0x21, extended: true },\n pagedown: { vk: 0x22, extended: true },\n\n // Arrow keys\n up: { vk: 0x26, extended: true },\n down: { vk: 0x28, extended: true },\n left: { vk: 0x25, extended: true },\n right: { vk: 0x27, extended: true },\n\n // Function keys\n f1: { vk: 0x70 },\n f2: { vk: 0x71 },\n f3: { vk: 0x72 },\n f4: { vk: 0x73 },\n f5: { vk: 0x74 },\n f6: { vk: 0x75 },\n f7: { vk: 0x76 },\n f8: { vk: 0x77 },\n f9: { vk: 0x78 },\n f10: { vk: 0x79 },\n f11: { vk: 0x7a },\n f12: { vk: 0x7b },\n\n // Other\n capslock: { vk: 0x14 },\n numlock: { vk: 0x90 },\n scrolllock: { vk: 0x91 },\n printscreen: { vk: 0x2c },\n pause: { vk: 0x13 },\n apps: { vk: 0x5d },\n menu: { vk: 0x5d },\n};\n\n// Add letter keys a-z => 0x41-0x5A\nfor (let i = 0; i < 26; i++) {\n const letter = String.fromCharCode(97 + i); // 'a' to 'z'\n VK_MAP[letter] = { vk: 0x41 + i };\n}\n\n// Add digit keys 0-9 => 0x30-0x39\nfor (let i = 0; i < 10; i++) {\n VK_MAP[String(i)] = { vk: 0x30 + i };\n}\n\n// ── Helpers ─────────────────────────────────────────────────────────\n\nfunction makeKeyDown(vk: number, extended: boolean = false) {\n return {\n type: INPUT_KEYBOARD,\n u: {\n ki: {\n wVk: vk,\n wScan: 0,\n dwFlags: extended ? KEYEVENTF_EXTENDEDKEY : 0,\n time: 0,\n dwExtraInfo: 0,\n },\n },\n };\n}\n\nfunction makeKeyUp(vk: number, extended: boolean = false) {\n return {\n type: INPUT_KEYBOARD,\n u: {\n ki: {\n wVk: vk,\n wScan: 0,\n dwFlags: KEYEVENTF_KEYUP | (extended ? KEYEVENTF_EXTENDEDKEY : 0),\n time: 0,\n dwExtraInfo: 0,\n },\n },\n };\n}\n\nfunction makeUnicodeDown(charCode: number) {\n return {\n type: INPUT_KEYBOARD,\n u: {\n ki: {\n wVk: 0,\n wScan: charCode,\n dwFlags: KEYEVENTF_UNICODE,\n time: 0,\n dwExtraInfo: 0,\n },\n },\n };\n}\n\nfunction makeUnicodeUp(charCode: number) {\n return {\n type: INPUT_KEYBOARD,\n u: {\n ki: {\n wVk: 0,\n wScan: charCode,\n dwFlags: KEYEVENTF_UNICODE | KEYEVENTF_KEYUP,\n time: 0,\n dwExtraInfo: 0,\n },\n },\n };\n}\n\nfunction sendInputEvents(events: unknown[]): number {\n return SendInput_(events.length, events, INPUT_SIZE);\n}\n\n// ── Public API ──────────────────────────────────────────────────────\n\n/**\n * Type literal text using Unicode input events.\n * Handles all characters including special/international ones.\n */\nexport function typeText(text: string): void {\n // Send all characters in one batch for speed\n const events: unknown[] = [];\n\n for (let i = 0; i < text.length; i++) {\n const charCode = text.charCodeAt(i);\n\n // Handle surrogate pairs (emoji etc.)\n if (charCode >= 0xd800 && charCode <= 0xdbff && i + 1 < text.length) {\n const lo = text.charCodeAt(i + 1);\n if (lo >= 0xdc00 && lo <= 0xdfff) {\n // Send both surrogate code units\n events.push(makeUnicodeDown(charCode));\n events.push(makeUnicodeDown(lo));\n events.push(makeUnicodeUp(lo));\n events.push(makeUnicodeUp(charCode));\n i++; // skip low surrogate\n continue;\n }\n }\n\n events.push(makeUnicodeDown(charCode));\n events.push(makeUnicodeUp(charCode));\n }\n\n if (events.length > 0) {\n sendInputEvents(events);\n }\n}\n\n/**\n * Press and release a single named key.\n * Supports special key names (see VK_MAP) and single characters.\n */\nexport function pressKey(key: string): void {\n const lower = key.toLowerCase();\n const entry = VK_MAP[lower];\n\n if (entry) {\n const events = [\n makeKeyDown(entry.vk, entry.extended),\n makeKeyUp(entry.vk, entry.extended),\n ];\n sendInputEvents(events);\n } else if (key.length === 1) {\n // Single character — use unicode input\n typeText(key);\n } else {\n throw new Error(`Unknown key: \"${key}\"`);\n }\n}\n\n/**\n * Send a key combination. Holds all modifier keys, presses the last key,\n * then releases in reverse order.\n *\n * Example: sendKeyCombo(['ctrl', 'shift', 's'])\n */\nexport function sendKeyCombo(keys: string[]): void {\n if (keys.length === 0) return;\n\n const events: unknown[] = [];\n\n // Press all keys down in order\n for (const key of keys) {\n const lower = key.toLowerCase();\n const entry = VK_MAP[lower];\n if (!entry) throw new Error(`Unknown key in combo: \"${key}\"`);\n events.push(makeKeyDown(entry.vk, entry.extended));\n }\n\n // Release all keys in reverse order\n for (let i = keys.length - 1; i >= 0; i--) {\n const lower = keys[i]!.toLowerCase();\n const entry = VK_MAP[lower]!;\n events.push(makeKeyUp(entry.vk, entry.extended));\n }\n\n sendInputEvents(events);\n}\n","/**\n * Screen capture via GDI — captures raw BGRA pixels and converts to PNG.\n *\n * Uses the `canvas` package for PNG encoding (already a project dependency).\n */\nimport koffi from 'koffi';\nimport { createCanvas } from 'canvas';\nimport {\n GetDC,\n ReleaseDC,\n CreateCompatibleDC,\n CreateCompatibleBitmap,\n SelectObject,\n BitBlt,\n DeleteObject,\n DeleteDC,\n GetDIBits_,\n GetSystemMetrics,\n BITMAPINFOHEADER,\n SM_CXSCREEN,\n SM_CYSCREEN,\n SRCCOPY,\n} from './win32.js';\n\n// ── Types ────────────────────────────────────────────────────────────\n\nexport interface CaptureResult {\n width: number;\n height: number;\n buffer: Buffer; // raw BGRA pixel data\n}\n\nexport interface ScreenRegion {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n// ── Core capture ────────────────────────────────────────────────────\n\n/**\n * Capture the screen (or a region) as raw BGRA pixels.\n */\nexport function captureScreen(region?: ScreenRegion): CaptureResult {\n const screenW = GetSystemMetrics(SM_CXSCREEN);\n const screenH = GetSystemMetrics(SM_CYSCREEN);\n\n const x = region?.x ?? 0;\n const y = region?.y ?? 0;\n const width = region?.width ?? screenW;\n const height = region?.height ?? screenH;\n\n // Get screen DC\n const hScreenDC = GetDC(0);\n if (!hScreenDC) throw new Error('Failed to get screen DC');\n\n let hMemDC = 0;\n let hBitmap = 0;\n\n try {\n // Create compatible DC and bitmap\n hMemDC = CreateCompatibleDC(hScreenDC);\n if (!hMemDC) throw new Error('Failed to create compatible DC');\n\n hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);\n if (!hBitmap) throw new Error('Failed to create compatible bitmap');\n\n // Select bitmap into memory DC\n const hOldBitmap = SelectObject(hMemDC, hBitmap);\n\n // Copy screen pixels to memory DC\n const bltOk = BitBlt(hMemDC, 0, 0, width, height, hScreenDC, x, y, SRCCOPY);\n if (!bltOk) throw new Error('BitBlt failed');\n\n // Restore old bitmap\n SelectObject(hMemDC, hOldBitmap);\n\n // Prepare BITMAPINFOHEADER for GetDIBits\n const bmi = {\n biSize: koffi.sizeof(BITMAPINFOHEADER),\n biWidth: width,\n biHeight: -height, // negative = top-down (row 0 at top)\n biPlanes: 1,\n biBitCount: 32,\n biCompression: 0, // BI_RGB\n biSizeImage: 0,\n biXPelsPerMeter: 0,\n biYPelsPerMeter: 0,\n biClrUsed: 0,\n biClrImportant: 0,\n };\n\n // Allocate buffer for pixel data (BGRA, 4 bytes per pixel)\n const pixelBuffer = Buffer.alloc(width * height * 4);\n\n // Extract pixel data\n const lines = GetDIBits_(hMemDC, hBitmap, 0, height, pixelBuffer, bmi, 0);\n if (lines === 0) throw new Error('GetDIBits returned 0 lines');\n\n return { width, height, buffer: pixelBuffer };\n } finally {\n // Clean up GDI resources\n if (hBitmap) DeleteObject(hBitmap);\n if (hMemDC) DeleteDC(hMemDC);\n ReleaseDC(0, hScreenDC);\n }\n}\n\n// ── PNG conversion ──────────────────────────────────────────────────\n\n/**\n * Convert raw BGRA pixel buffer to a PNG Buffer.\n */\nexport function bgraToPng(\n bgraBuffer: Buffer,\n width: number,\n height: number,\n): Buffer {\n const canvas = createCanvas(width, height);\n const ctx = canvas.getContext('2d');\n const imageData = ctx.createImageData(width, height);\n\n // Convert BGRA to RGBA\n const src = bgraBuffer;\n const dst = imageData.data;\n for (let i = 0; i < src.length; i += 4) {\n dst[i] = src[i + 2]!; // R <- B\n dst[i + 1] = src[i + 1]!; // G\n dst[i + 2] = src[i]!; // B <- R\n dst[i + 3] = 255; // A (fully opaque)\n }\n\n ctx.putImageData(imageData, 0, 0);\n return canvas.toBuffer('image/png');\n}\n\n/**\n * Capture the screen and return a PNG buffer directly.\n */\nexport function captureScreenPng(region?: ScreenRegion): {\n width: number;\n height: number;\n pngBuffer: Buffer;\n} {\n const { width, height, buffer } = captureScreen(region);\n const pngBuffer = bgraToPng(buffer, width, height);\n return { width, height, pngBuffer };\n}\n","/**\n * App launching and window detection.\n */\nimport { spawn } from 'node:child_process';\nimport { listWindows, type WindowInfo } from './windows.js';\n\n/**\n * Launch an application by name or path.\n * Returns the spawned process PID.\n */\nexport function launchApp(\n app: string,\n args?: string,\n): { pid: number } {\n // Detect URLs and files that need to be opened with the default handler.\n // On Windows, `start` opens URLs in the default browser and files in\n // their associated app. Without it, spawn treats URLs as executable names.\n const isUrl = /^https?:\\/\\//i.test(app);\n const isFile = /\\.[a-zA-Z0-9]+$/.test(app) && !/\\.(exe|cmd|bat|com|ps1)$/i.test(app);\n\n let command: string;\n if (isUrl) {\n // Use 'start \"\"' with the URL quoted — the empty \"\" is the window title\n // required by start when the argument contains special characters\n command = args ? `start \"\" \"${app}\" ${args}` : `start \"\" \"${app}\"`;\n } else if (isFile && !args) {\n // Open a file with its default application\n command = `start \"\" \"${app}\"`;\n } else {\n command = args ? `${app} ${args}` : app;\n }\n\n const child = spawn(command, [], {\n detached: true,\n stdio: 'ignore',\n shell: true,\n });\n child.unref();\n\n if (!child.pid) {\n throw new Error(`Failed to launch \"${app}\" — no PID returned`);\n }\n\n return { pid: child.pid };\n}\n\n/**\n * Wait for a window belonging to the launched process to appear.\n *\n * Polls every 500ms until a visible window with a meaningful title and\n * minimum size appears, or until the timeout expires.\n *\n * Matches by PID or by process base name.\n */\nexport async function waitForWindow(\n pid: number,\n processBaseName: string,\n timeoutMs: number = 10_000,\n): Promise<WindowInfo | null> {\n const start = Date.now();\n\n while (Date.now() - start < timeoutMs) {\n const windows = listWindows();\n\n const match = windows.find((w) => {\n // Match by PID\n if (w.pid === pid) return true;\n // Match by process name in the title is a heuristic fallback\n // For apps that spawn child processes (e.g. Office), we match by name\n if (\n processBaseName &&\n w.title.toLowerCase().includes(processBaseName.toLowerCase())\n ) {\n return true;\n }\n return false;\n });\n\n // Require a reasonable window size (skip splash screens, hidden helpers)\n if (match && match.width > 200 && match.height > 100 && match.title.length > 2) {\n return match;\n }\n\n await new Promise((r) => setTimeout(r, 500));\n }\n\n return null;\n}\n","/**\n * Native Win32 bindings — barrel export.\n *\n * All exports are guarded: on non-Windows platforms, importing this module\n * throws an error at the point of use rather than crashing on import.\n */\n\nexport { listWindows, findWindowByTitle, moveWindow, showWindow, setForegroundWindow, getWindowRect, isMinimized, resolveWindow, parseHandle } from './windows.js';\nexport type { WindowInfo } from './windows.js';\n\nexport { setCursorPos, mouseClick } from './mouse.js';\n\nexport { typeText, pressKey, sendKeyCombo } from './keyboard.js';\n\nexport { captureScreen, captureScreenPng, bgraToPng } from './screenshot.js';\nexport type { CaptureResult, ScreenRegion } from './screenshot.js';\n\nexport { launchApp, waitForWindow } from './process.js';\n","import { tool } from 'ai';\nimport { z } from 'zod';\nimport { writeFile as fsWriteFile, unlink, mkdir } from 'node:fs/promises';\nimport { resolve, dirname, join } from 'node:path';\nimport { tmpdir } from 'node:os';\n\nimport {\n listWindows,\n resolveWindow,\n moveWindow as nativeMoveWindow,\n showWindow as nativeShowWindow,\n setForegroundWindow,\n getWindowRect,\n isMinimized,\n mouseClick as nativeMouseClick,\n typeText,\n pressKey,\n sendKeyCombo,\n captureScreenPng,\n launchApp as nativeLaunchApp,\n waitForWindow,\n} from '../native/index.js';\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n\n// ── takeScreenshot ───────────────────────────────────────────────────\n\nexport const takeScreenshot = tool({\n description:\n 'Capture the current screen (or a region) as a PNG screenshot. ' +\n 'Returns image dimensions and base64 data so you can see the desktop. ' +\n 'Use this to observe what is on screen before acting.',\n inputSchema: z.object({\n savePath: z\n .string()\n .optional()\n .describe('Where to save the screenshot PNG. Default: temp file (auto-cleaned).'),\n region: z\n .object({\n x: z.number().describe('Left edge X coordinate.'),\n y: z.number().describe('Top edge Y coordinate.'),\n width: z.number().describe('Width of capture region.'),\n height: z.number().describe('Height of capture region.'),\n })\n .optional()\n .describe('Capture a specific screen region instead of the full screen.'),\n }),\n execute: async ({ savePath, region }) => {\n const isTemp = !savePath;\n const targetPath = resolve(savePath ?? join(tmpdir(), `screenshot-${Date.now()}.png`));\n\n try {\n await mkdir(dirname(targetPath), { recursive: true });\n\n const { width, height, pngBuffer } = captureScreenPng(region ?? undefined);\n\n await fsWriteFile(targetPath, pngBuffer);\n\n const base64 = pngBuffer.toString('base64');\n const base64DataUrl = `data:image/png;base64,${base64}`;\n\n // Clean up temp file after reading\n if (isTemp) {\n await unlink(targetPath).catch(() => { /* ignore */ });\n }\n\n return {\n success: true,\n path: isTemp ? '(temp)' : targetPath,\n width,\n height,\n base64DataUrl,\n };\n } catch (error) {\n if (isTemp) {\n await unlink(targetPath).catch(() => { /* ignore */ });\n }\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n },\n toModelOutput({ output }) {\n const obj = output as Record<string, unknown>;\n\n if (obj.success && typeof obj.base64DataUrl === 'string') {\n const base64 = (obj.base64DataUrl as string).replace(/^data:[^;]+;base64,/, '');\n const summary = `Screenshot: ${obj.width}x${obj.height}${obj.path !== '(temp)' ? ` saved to ${obj.path}` : ''}`;\n\n return {\n type: 'content' as const,\n value: [\n { type: 'text' as const, text: summary },\n { type: 'image-data' as const, data: base64, mediaType: 'image/png' },\n ],\n };\n }\n\n const { base64DataUrl: _, ...rest } = obj;\n return {\n type: 'json' as const,\n value: rest as import('@ai-sdk/provider').JSONValue,\n };\n },\n});\n\n// ── getOpenWindows ───────────────────────────────────────────────────\n\nexport const getOpenWindows = tool({\n description:\n 'List all open/visible windows with their titles, positions, sizes, and process info. ' +\n 'Use to find windows for moveWindow, focusWindow, or to understand the desktop layout.',\n inputSchema: z.object({\n filter: z\n .string()\n .optional()\n .describe('Filter windows by title substring (case-insensitive).'),\n }),\n execute: async ({ filter }) => {\n try {\n const windows = listWindows(filter ?? undefined);\n return {\n success: true,\n windows,\n count: windows.length,\n ...(filter ? { filter } : {}),\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n },\n});\n\n// ── moveWindow ───────────────────────────────────────────────────────\n\nexport const moveWindow = tool({\n description:\n 'Move, resize, or change the state of a window. ' +\n 'Identify the window by title (partial match) or handle from getOpenWindows.',\n inputSchema: z.object({\n title: z\n .string()\n .optional()\n .describe('Window title to match (partial, case-insensitive). Use this or handle.'),\n handle: z\n .string()\n .optional()\n .describe('Window handle hex string from getOpenWindows (e.g., \"0x001A02B4\"). Use this or title.'),\n x: z.number().optional().describe('New X position.'),\n y: z.number().optional().describe('New Y position.'),\n width: z.number().optional().describe('New width.'),\n height: z.number().optional().describe('New height.'),\n state: z\n .enum(['normal', 'minimized', 'maximized', 'restore'])\n .optional()\n .describe('Change window state.'),\n }),\n execute: async ({ title, handle, x, y, width, height, state }) => {\n if (!title && !handle) {\n return { success: false, error: 'Provide either title or handle to identify the window.' };\n }\n\n try {\n const resolved = resolveWindow(title, handle);\n if (!resolved) {\n return { success: false, error: 'Window not found' };\n }\n\n const { hwnd, info } = resolved;\n\n // Change window state if requested\n if (state) {\n nativeShowWindow(hwnd, state);\n }\n\n // Move/resize if any position or size parameter is specified\n if (x !== undefined || y !== undefined || width !== undefined || height !== undefined) {\n const curRect = getWindowRect(hwnd);\n nativeMoveWindow(\n hwnd,\n x ?? curRect.x,\n y ?? curRect.y,\n width ?? curRect.width,\n height ?? curRect.height,\n );\n }\n\n // Bring to foreground\n setForegroundWindow(hwnd);\n\n // Read final rect\n const finalRect = getWindowRect(hwnd);\n\n return {\n success: true,\n handle: info.handle,\n x: finalRect.x,\n y: finalRect.y,\n width: finalRect.width,\n height: finalRect.height,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n },\n});\n\n// ── mouseClick ───────────────────────────────────────────────────────\n\nexport const mouseClick = tool({\n description:\n 'Move the mouse to screen coordinates and perform a click action. ' +\n 'Use takeScreenshot first to see the screen and determine coordinates.',\n inputSchema: z.object({\n x: z.number().describe('Screen X coordinate.'),\n y: z.number().describe('Screen Y coordinate.'),\n button: z\n .enum(['left', 'right', 'middle'])\n .optional()\n .describe('Mouse button. Default \"left\".'),\n action: z\n .enum(['click', 'doubleclick', 'down', 'up', 'move'])\n .optional()\n .describe('Click action. Default \"click\".'),\n delay: z\n .number()\n .optional()\n .describe('Milliseconds to wait before performing the action (for UI to settle).'),\n }),\n execute: async ({ x, y, button, action, delay: delayMs }) => {\n try {\n if (delayMs && delayMs > 0) {\n await delay(Math.min(delayMs, 10_000));\n }\n\n const btn = button ?? 'left';\n const act = action ?? 'click';\n\n nativeMouseClick(x, y, btn, act);\n\n return {\n success: true,\n x,\n y,\n button: btn,\n action: act,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n },\n});\n\n// ── pressKeys ────────────────────────────────────────────────────────\n\nexport const pressKeys = tool({\n description:\n 'Simulate keyboard input: type literal text, press a single key, or send a key combination.\\n' +\n '- text: type each character exactly as given (handles all Unicode).\\n' +\n '- key: press a single named key (e.g., \"enter\", \"tab\", \"f5\", \"escape\").\\n' +\n '- combo: hold modifier keys and press a key (e.g., [\"ctrl\", \"c\"], [\"alt\", \"f4\"], [\"ctrl\", \"shift\", \"s\"]).\\n' +\n 'Provide exactly one of text, key, or combo.',\n inputSchema: z.object({\n text: z\n .string()\n .optional()\n .describe('Literal text to type. Each character is sent as a keystroke.'),\n key: z\n .string()\n .optional()\n .describe('Single special key to press: \"enter\", \"tab\", \"escape\", \"f1\"-\"f12\", \"up\", \"down\", \"left\", \"right\", \"backspace\", \"delete\", \"home\", \"end\", \"pageup\", \"pagedown\", \"space\", etc.'),\n combo: z\n .array(z.string())\n .optional()\n .describe('Key combination as array: [\"ctrl\", \"c\"], [\"alt\", \"f4\"], [\"ctrl\", \"shift\", \"s\"]. Keys are held in order, released in reverse.'),\n }),\n execute: async ({ text, key, combo }) => {\n if (!text && !key && !combo) {\n return { success: false, error: 'Provide one of: text, key, or combo.' };\n }\n\n try {\n if (text) {\n typeText(text);\n return { success: true, typed: text };\n }\n\n if (combo && combo.length > 0) {\n sendKeyCombo(combo);\n return { success: true, combo };\n }\n\n if (key) {\n pressKey(key);\n return { success: true, key };\n }\n\n return { success: false, error: 'No input provided.' };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n },\n});\n\n// ── launchApp ────────────────────────────────────────────────────────\n\nexport const launchApp = tool({\n description:\n 'Launch an application by name, path, or file. ' +\n 'Common names: \"notepad\", \"chrome\", \"code\", \"explorer\", \"calc\", \"mspaint\". ' +\n 'Can also open files with their default application.',\n inputSchema: z.object({\n app: z\n .string()\n .describe('App name (e.g., \"notepad\", \"chrome\"), executable path, or file to open.'),\n args: z\n .string()\n .optional()\n .describe('Command-line arguments for the app.'),\n waitForWindow: z\n .boolean()\n .optional()\n .describe('Wait for the app window to appear and return its info. Default true.'),\n waitTimeoutSeconds: z\n .number()\n .optional()\n .describe('Max seconds to wait for the window to appear. Default 10. Increase for slow apps like Office.'),\n }),\n execute: async ({ app, args, waitForWindow: shouldWait, waitTimeoutSeconds }) => {\n try {\n const doWait = shouldWait !== false;\n const timeoutSec = Math.min(Math.max(waitTimeoutSeconds ?? 10, 1), 30);\n\n const { pid } = nativeLaunchApp(app, args);\n\n if (!doWait) {\n return { success: true, app, pid };\n }\n\n // Extract base process name for matching\n const baseProcessName = app\n .replace(/^.*[\\\\/]/, '')\n .replace(/\\.exe$/i, '')\n .toLowerCase();\n\n const window = await waitForWindow(pid, baseProcessName, timeoutSec * 1000);\n\n if (window) {\n return { success: true, app, pid, window };\n }\n\n return {\n success: true,\n app,\n pid,\n window: null,\n note: `Process started but no window detected within ${timeoutSec} seconds`,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n },\n});\n\n// ── focusWindow ──────────────────────────────────────────────────────\n\nexport const focusWindow = tool({\n description:\n 'Bring a window to the foreground. Identify by title (partial match) or handle.',\n inputSchema: z.object({\n title: z\n .string()\n .optional()\n .describe('Window title to match (partial, case-insensitive). Use this or handle.'),\n handle: z\n .string()\n .optional()\n .describe('Window handle hex string from getOpenWindows (e.g., \"0x001A02B4\"). Use this or title.'),\n }),\n execute: async ({ title, handle }) => {\n if (!title && !handle) {\n return { success: false, error: 'Provide either title or handle to identify the window.' };\n }\n\n try {\n const resolved = resolveWindow(title, handle);\n if (!resolved) {\n return { success: false, error: 'Window not found' };\n }\n\n const { hwnd, info } = resolved;\n\n // Restore if minimized\n if (isMinimized(hwnd)) {\n nativeShowWindow(hwnd, 'restore');\n }\n\n setForegroundWindow(hwnd);\n\n return {\n success: true,\n handle: info.handle,\n title: info.title,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n },\n});\n","import dotenv from 'dotenv';\n// Load .env without overriding existing system env vars\ndotenv.config({ override: false });\nimport { createRequire } from 'node:module';\nimport { Command } from 'commander';\nimport { startChat } from './chat.js';\nimport * as config from './config.js';\nimport { listAgents, getAgent } from './agents/manager.js';\nimport { runAgent } from './agents/runner.js';\nimport { formatError, formatSuccess, formatAssistantLabel, formatHeader, formatDim, renderMarkdown } from './ui/renderer.js';\nimport { startSpinner, stopSpinner } from './ui/spinner.js';\nimport { setOverride } from './logger.js';\nimport chalk from 'chalk';\n\nconst require = createRequire(import.meta.url);\nconst { version } = require('../package.json') as { version: string };\n\nconst program = new Command();\n\nprogram\n .name('nm-cli')\n .description('A model-agnostic AI CLI assistant')\n .version(version);\n\n// Default: start interactive chat\nprogram\n .command('chat', { isDefault: true })\n .description('Start interactive chat (default)')\n .option('-v, --verbose', 'Enable verbose output')\n .option('--debug', 'Enable debug output')\n .option('-q, --quiet', 'Suppress informational output')\n .action(async (opts) => {\n if (opts.debug) setOverride('debug');\n else if (opts.verbose) setOverride('verbose');\n else if (opts.quiet) setOverride('quiet');\n await startChat();\n });\n\n// Config commands\nconst configCmd = program\n .command('config')\n .description('Manage configuration');\n\nconfigCmd\n .command('set <key> <value>')\n .description('Set a configuration value')\n .action((key: string, value: string) => {\n const isApiKey = key.toLowerCase().includes('apikey') || key.toLowerCase().includes('api_key');\n const displayValue = isApiKey && value.length > 8 ? value.slice(0, 8) + '...' : value;\n config.setNested(key, value);\n console.log(formatSuccess(`Set ${key} = ${displayValue}`));\n });\n\nconfigCmd\n .command('get <key>')\n .description('Get a configuration value')\n .action((key: string) => {\n const value = config.getNested(key);\n if (value === undefined) {\n console.log(formatError(`Key \"${key}\" not found.`));\n process.exit(1);\n }\n const isApiKey = key.toLowerCase().includes('apikey') || key.toLowerCase().includes('api_key');\n const displayValue = isApiKey && typeof value === 'string' && value.length > 8\n ? value.slice(0, 8) + '...'\n : String(value);\n console.log(displayValue);\n });\n\nconfigCmd\n .command('list')\n .description('List all configuration')\n .action(() => {\n const all = config.listAll();\n console.log(JSON.stringify(all, null, 2));\n });\n\nconfigCmd\n .command('path')\n .description('Show config file path')\n .action(() => {\n console.log(config.getConfigPath());\n });\n\n// Agent commands\nconst agentCmd = program\n .command('agent')\n .description('Manage agents');\n\nagentCmd\n .command('list')\n .description('List all agents')\n .action(() => {\n const agents = listAgents();\n if (agents.length === 0) {\n console.log('No agents found.');\n return;\n }\n console.log('');\n console.log(formatHeader('Agents'));\n for (const agent of agents) {\n console.log(` ${chalk.bold.cyan(agent.name)} - ${agent.description}`);\n console.log(` ${formatDim(`${agent.provider}:${agent.model} | temp: ${agent.temperature}`)}`);\n }\n console.log('');\n });\n\nagentCmd\n .command('view <name>')\n .description('View agent details')\n .action((name: string) => {\n const agent = getAgent(name);\n if (!agent) {\n console.log(formatError(`Agent \"${name}\" not found.`));\n process.exit(1);\n }\n console.log(JSON.stringify(agent, null, 2));\n });\n\nagentCmd\n .command('run <name> <prompt>')\n .description('Run an agent with a prompt')\n .action(async (name: string, prompt: string) => {\n const spinner = startSpinner(`Running agent \"${name}\"...`);\n let firstToken = true;\n\n try {\n const result = await runAgent(name, prompt, {\n onToken(token: string) {\n if (firstToken) {\n stopSpinner();\n firstToken = false;\n }\n process.stdout.write(token);\n },\n onComplete() {\n process.stdout.write('\\n');\n },\n onError(error: Error) {\n stopSpinner();\n console.error(formatError(error.message));\n },\n });\n\n if (result.error) {\n console.error(formatError(result.error));\n process.exit(1);\n }\n } catch (error) {\n stopSpinner();\n console.error(formatError(error instanceof Error ? error.message : String(error)));\n process.exit(1);\n }\n });\n\n// Handle unhandled rejections\nprocess.on('unhandledRejection', (reason) => {\n console.error(formatError(`Unhandled error: ${reason instanceof Error ? reason.message : String(reason)}`));\n process.exit(1);\n});\n\nprogram.parse();\n","import type { ModelMessage } from 'ai';\nimport type { ChatContext, CommandContext } from './types.js';\nimport { createRequire } from 'node:module';\nimport { getProvider } from './providers/index.js';\nimport { executeCommand } from './commands/registry.js';\nimport { createReadlineInterface, prompt } from './ui/input.js';\nimport { startSpinner, stopSpinner, getRandomThinkingText } from './ui/spinner.js';\nimport {\n formatAssistantLabel,\n formatError,\n formatSystemMessage,\n formatInfo,\n formatToolCall,\n formatToolResult,\n formatToolError,\n renderMarkdown,\n} from './ui/renderer.js';\nimport { allTools, toolMetadata, wrapToolsWithConfirmation } from './tools/index.js';\nimport { promptSimple } from './ui/input.js';\nimport * as config from './config.js';\nimport chalk from 'chalk';\n\nconst require = createRequire(import.meta.url);\nconst { version } = require('../package.json') as { version: string };\n\nconst SYSTEM_PROMPT = `You are an AI assistant running inside a terminal CLI application. You have access to the user's local filesystem and can execute shell commands.\n\nAvailable tools:\n- listFiles: List files and directories at a given path\n- readFile: Read the contents of a file (text, images, and binary files)\n- viewImage: View and analyze an image file (dimensions, dominant colors, visual content)\n- writeFile: Write content to a file (creates or overwrites)\n- runCommand: Execute a shell command and return output\n\nUse these tools proactively when the user asks about files, code, projects, or needs you to perform actions on their system. For example:\n- If asked \"what files are in this directory?\", use listFiles\n- If asked \"show me the contents of package.json\", use readFile\n- If asked about an image file, use readFile (for quick view) or viewImage (for detailed analysis with dominant colors)\n- If asked to create or modify a file, use writeFile\n- If asked to run a build, test, git command, etc., use runCommand\n\nWhen you read an image file with readFile or viewImage, you can see the image contents and describe what you see. Image data is sent as a vision input so you can analyze the visual content.\n\nYou can chain multiple tool calls in sequence to accomplish complex tasks. Always report what you did and the results clearly.\n\nDesktop automation tools (Windows):\n- takeScreenshot: Capture the screen to see what is displayed\n- getOpenWindows: List all open windows with positions and sizes\n- moveWindow: Move, resize, or change window state\n- mouseClick: Click the mouse at screen coordinates\n- pressKeys: Type text or send key combinations (SendKeys format)\n- launchApp: Launch an application\n- focusWindow: Bring a window to the foreground\n\nDesktop workflow: takeScreenshot (see) -> analyze -> act -> takeScreenshot (verify).\nFor window management, prefer getOpenWindows + moveWindow over mouse clicking — more reliable.\n\nSmart home tools (Google Cast + Alexa):\n- listSmartDevices: List all configured smart home devices with optional live status\n- getDeviceStatus: Get current status of a specific device (online, volume, media)\n- controlDevice: Control playback (pause/resume/stop), volume (0-100), mute/unmute\n- playMedia: Play an audio/video URL on a smart home speaker or display\n- searchMusic: Search YouTube for music/audio. Returns a list of candidates (title, artist, duration). Does NOT play anything.\n- playMusic: Play a specific video (by videoId from searchMusic) on a smart home device.\n- sendNotification: Send a text-to-speech message to a speaker\n- askAssistant: Send a Google Assistant command to a Google Home device. USE THIS for non-music commands — smart home control (\"turn off the lights\"), questions (\"what's the weather\"), timers, broadcasts, routines. Do NOT use askAssistant for playing music — it cannot play media on the device. Use playMusic instead.\n\nMusic flow:\n1. ALWAYS call searchMusic first to find candidates.\n2. If the user's intent is vague/generic (\"play some jazz\", \"play background music\"), pick the top result and call playMusic immediately.\n3. If the user names a specific artist or song that could match many tracks (\"play Beatles\", \"play Bohemian Rhapsody\"), present 3-5 options and let the user choose before calling playMusic.\n4. If the user says \"play the next one\" or \"try another\", use a different result from the last searchMusic call.\n\nIMPORTANT routing rules for smart home:\n- Music/audio requests → ALWAYS use searchMusic then playMusic (YouTube search + Cast)\n- Smart home control, questions, timers, broadcasts → use askAssistant\n- Direct URL playback → use playMedia\n- Never use askAssistant for \"play music\" commands — it will fail with \"I can't do that here\"\n\nDevices must be configured first via the /devices command.\nFor askAssistant, Google Assistant SDK credentials must be configured (see GOOGLE_ASSISTANT_KEY_FILE and GOOGLE_ASSISTANT_SAVED_TOKENS).`;\n\nexport async function startChat(): Promise<void> {\n const { provider: defaultProvider, model: defaultModel } = config.getDefaultModel();\n\n const chatContext: ChatContext = {\n messages: [],\n currentProvider: defaultProvider,\n currentModel: defaultModel,\n abortController: null,\n };\n\n let shouldExit = false;\n\n const rl = createReadlineInterface();\n\n const commandContext: CommandContext = {\n chat: chatContext,\n rl,\n setModel(provider: string, model: string) {\n chatContext.currentProvider = provider;\n chatContext.currentModel = model;\n },\n clearMessages() {\n chatContext.messages = [];\n },\n exit() {\n shouldExit = true;\n },\n };\n\n // Wrap mutating/destructive tools with a user confirmation prompt\n const confirmedTools = wrapToolsWithConfirmation(\n allTools,\n toolMetadata,\n async (message: string) => {\n stopSpinner();\n const answer = await promptSimple(rl, chalk.yellow(` ${message} [y/N] `));\n return answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes';\n },\n );\n\n // Print welcome (handles all scenarios: first run, returning, mismatch)\n printWelcome(chatContext);\n\n // Keep stdin alive — prevents the event loop from draining between\n // streaming responses and the next rl.question call (Windows issue).\n process.stdin.resume();\n\n // Handle Ctrl+C gracefully\n rl.on('SIGINT', () => {\n if (chatContext.abortController) {\n chatContext.abortController.abort();\n chatContext.abortController = null;\n process.stdout.write('\\n');\n console.log(formatSystemMessage('Response interrupted.'));\n } else {\n console.log(formatSystemMessage('\\nGoodbye!'));\n rl.close();\n process.exit(0);\n }\n });\n\n // When readline closes unexpectedly (e.g. stdin EOF), exit the loop\n // gracefully instead of calling process.exit() — a hard exit here\n // races with other async work and can mask the real cause of the close.\n rl.on('close', () => {\n shouldExit = true;\n });\n\n // Main loop\n while (!shouldExit) {\n const input = await prompt(rl, {\n provider: chatContext.currentProvider,\n model: chatContext.currentModel,\n });\n\n if (!input) {\n continue;\n }\n\n // Handle slash commands\n if (input.startsWith('/')) {\n const handled = await executeCommand(input, commandContext);\n if (!handled) {\n console.log(formatError(`Unknown command: \"${input}\". Type /help for available commands.`));\n }\n if (shouldExit) {\n break;\n }\n continue;\n }\n\n // Send message to AI\n await sendMessage(input, chatContext, confirmedTools);\n }\n\n console.log(formatSystemMessage('Goodbye!'));\n rl.close();\n process.exit(0);\n}\n\nasync function sendMessage(userInput: string, context: ChatContext, tools: import('ai').ToolSet): Promise<void> {\n const provider = getProvider(context.currentProvider);\n if (!provider) {\n console.log(formatError(`Provider \"${context.currentProvider}\" not found.`));\n return;\n }\n\n if (!provider.isConfigured()) {\n console.log(formatError(`Provider \"${context.currentProvider}\" is not configured.`));\n console.log(formatInfo(`Set API key: /config set providers.${context.currentProvider}.apiKey <your-key>`));\n return;\n }\n\n // Add user message to history\n context.messages.push({ role: 'user', content: userInput });\n\n const abortController = new AbortController();\n context.abortController = abortController;\n\n startSpinner(getRandomThinkingText());\n let firstToken = true;\n // Tracks whether we are actively streaming text tokens to stdout.\n // While true, the spinner must NOT be (re)started.\n let isStreamingText = false;\n // Tracks whether the most-recently-finished step was a tool call.\n // Used by onStepStart to decide if a \"Thinking...\" spinner is appropriate.\n let lastStepWasToolCall = false;\n\n // Buffer to collect streamed text for post-stream markdown rendering.\n // Each entry is the text from one contiguous streaming segment (segments\n // are separated by tool-call steps).\n let streamedTextBuffer = '';\n // Count the raw lines written so we can overwrite them with rendered output.\n let rawLineCount = 0;\n const isTTY = process.stdout.isTTY ?? false;\n\n try {\n const chatResult = await provider.chat(\n context.messages,\n context.currentModel,\n {\n signal: abortController.signal,\n systemPrompt: SYSTEM_PROMPT,\n tools,\n maxSteps: 25,\n },\n {\n onToken(token: string) {\n if (firstToken) {\n stopSpinner();\n process.stdout.write('\\n' + formatAssistantLabel());\n firstToken = false;\n } else if (!isStreamingText) {\n // Resumed text after a tool-call step — print label again\n stopSpinner();\n process.stdout.write('\\n' + formatAssistantLabel());\n }\n isStreamingText = true;\n streamedTextBuffer += token;\n // Track newlines so we know how many raw lines to overwrite later.\n const newlines = token.split('\\n').length - 1;\n rawLineCount += newlines;\n process.stdout.write(token);\n },\n onComplete() {\n stopSpinner();\n },\n onError(error: Error) {\n stopSpinner();\n console.log(formatError(error.message));\n },\n onToolCall(info) {\n stopSpinner();\n isStreamingText = false;\n // Reset the streaming buffer — previous text is already finalized;\n // we only markdown-render the final contiguous text segment.\n streamedTextBuffer = '';\n rawLineCount = 0;\n if (firstToken) {\n // First output is a tool call, not text\n process.stdout.write('\\n');\n firstToken = false;\n }\n console.log(formatToolCall(info.toolName, info.args));\n\n // Diagnostic logging for cast debugging\n try {\n const fs = require('node:fs');\n fs.appendFileSync('cast-diag.log', `${new Date().toISOString()} [chat] onToolCall: ${info.toolName} args=${JSON.stringify(info.args)}\\n`);\n } catch { /* ignore */ }\n\n // Show tool-specific spinner while the tool executes\n const spinnerText = getToolSpinnerText(info.toolName, info.args);\n startSpinner(spinnerText);\n },\n onToolResult(info) {\n stopSpinner();\n lastStepWasToolCall = true;\n\n // Diagnostic logging for cast debugging\n try {\n const fs = require('node:fs');\n fs.appendFileSync('cast-diag.log', `${new Date().toISOString()} [chat] onToolResult: ${info.toolName} result=${JSON.stringify(info.result).substring(0, 500)}\\n`);\n } catch { /* ignore */ }\n\n console.log(formatToolResult(info.toolName, info.result));\n },\n onToolError(info) {\n stopSpinner();\n lastStepWasToolCall = true;\n\n // Diagnostic logging for cast debugging\n try {\n const fs = require('node:fs');\n fs.appendFileSync('cast-diag.log', `${new Date().toISOString()} [chat] onToolError: ${info.toolName} error=${info.error instanceof Error ? info.error.message : String(info.error)}\\n`);\n } catch { /* ignore */ }\n\n console.log(formatToolError(info.toolName, info.error));\n },\n onStepStart() {\n // Only show a spinner between steps if the previous step involved\n // a tool call. If the previous step was pure text, a spinner here\n // would bleed into the streamed output.\n if (lastStepWasToolCall) {\n startSpinner(getRandomThinkingText());\n }\n lastStepWasToolCall = false;\n },\n onStepFinish() {\n // Mark text streaming as done for this step so the next\n // onStepStart can safely decide whether to show a spinner.\n isStreamingText = false;\n },\n },\n );\n\n // Safety net: always stop spinner after streaming completes\n stopSpinner();\n\n // Replace raw streamed output with markdown-rendered version (TTY only).\n // When piped, keep the raw output as-is to avoid ANSI escape sequences.\n if (isTTY && streamedTextBuffer.length > 0) {\n // Move cursor up to the beginning of the raw streamed text and clear it.\n // rawLineCount is the number of newlines in the streamed text; we also\n // need +1 for the \"AI: \" label line.\n const linesToClear = rawLineCount + 1;\n process.stdout.write(`\\x1b[${linesToClear}A\\r\\x1b[0J`);\n\n // Re-print the label followed by the markdown-rendered content\n const rendered = renderMarkdown(streamedTextBuffer).trimEnd();\n process.stdout.write(formatAssistantLabel() + rendered);\n }\n\n // Add newline after streaming\n process.stdout.write('\\n\\n');\n\n // Append all response messages (including tool calls and tool results)\n // to the conversation history so the model retains full context.\n if (chatResult.responseMessages.length > 0) {\n context.messages.push(...chatResult.responseMessages);\n }\n } catch (error) {\n stopSpinner();\n if (error instanceof Error && error.name !== 'AbortError') {\n console.log(formatError(error.message));\n }\n } finally {\n context.abortController = null;\n }\n}\n\n/**\n * Generate spinner text that describes what a specific tool is doing.\n */\nfunction getToolSpinnerText(toolName: string, args: Record<string, unknown>): string {\n switch (toolName) {\n case 'readFile':\n return `Reading ${args.path ?? 'file'}...`;\n case 'viewImage':\n return `Viewing ${args.path ?? 'image'}...`;\n case 'writeFile':\n return `Writing ${args.path ?? 'file'}...`;\n case 'listFiles':\n return `Listing ${args.path ?? '.'}...`;\n case 'runCommand':\n return `Running ${args.command ?? 'command'}...`;\n case 'searchFiles':\n case 'grep':\n return `Searching for \"${args.pattern ?? args.query ?? ''}\"...`;\n case 'editFile':\n return `Editing ${args.path ?? args.filePath ?? 'file'}...`;\n case 'takeScreenshot':\n return 'Capturing screen...';\n case 'getOpenWindows':\n return 'Listing windows...';\n case 'moveWindow':\n return `Moving window ${args.title ?? args.handle ?? ''}...`;\n case 'mouseClick':\n return `Clicking at (${args.x ?? '?'}, ${args.y ?? '?'})...`;\n case 'pressKeys':\n return 'Sending keystrokes...';\n case 'launchApp':\n return `Launching ${args.app ?? 'app'}...`;\n case 'focusWindow':\n return `Focusing ${args.title ?? args.handle ?? 'window'}...`;\n case 'listSmartDevices':\n return 'Listing smart home devices...';\n case 'getDeviceStatus':\n return `Getting status of ${args.deviceId ?? 'device'}...`;\n case 'controlDevice':\n return `Controlling ${args.deviceId ?? 'device'}: ${args.action ?? ''}...`;\n case 'playMedia':\n return `Playing media on ${args.deviceId ?? 'device'}...`;\n case 'searchMusic':\n return `Searching YouTube for \"${args.query ?? ''}\"...`;\n case 'playMusic':\n return `Playing on ${args.deviceId ?? 'device'}...`;\n case 'sendNotification':\n return `Sending notification to ${args.deviceId ?? 'device'}...`;\n case 'askAssistant':\n return `Asking Google Assistant on ${args.deviceId ?? 'device'}...`;\n default:\n return `Running ${toolName}...`;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Welcome / onboarding — three scenarios based on API key state\n// ---------------------------------------------------------------------------\n\ntype WelcomeScenario = 'first-run' | 'returning' | 'key-mismatch';\n\ninterface WelcomeState {\n scenario: WelcomeScenario;\n /** Provider to fall back to when the default has no key. */\n fallbackProvider: string | null;\n /** Default model for the fallback provider. */\n fallbackModel: string | null;\n}\n\n/**\n * Detect which welcome scenario applies based on the current config\n * and configured API keys.\n */\nfunction detectWelcomeScenario(context: ChatContext): WelcomeState {\n const configuredProviders = config.getConfiguredProviders();\n\n if (configuredProviders.length === 0) {\n return { scenario: 'first-run', fallbackProvider: null, fallbackModel: null };\n }\n\n const defaultHasKey = config.getApiKey(context.currentProvider) !== '';\n if (defaultHasKey) {\n return { scenario: 'returning', fallbackProvider: null, fallbackModel: null };\n }\n\n // Default model's provider has no key — find a fallback\n const fallbackProvider = config.getFirstConfiguredProvider();\n let fallbackModel: string | null = null;\n\n if (fallbackProvider) {\n const provider = getProvider(fallbackProvider);\n const models = provider?.listModels() ?? [];\n fallbackModel = models[0]?.id ?? null;\n }\n\n return { scenario: 'key-mismatch', fallbackProvider, fallbackModel };\n}\n\n/**\n * Print the welcome banner. Handles three scenarios:\n *\n * - **First run**: no API keys configured — show setup guide\n * - **Returning**: has keys, default model's provider is configured\n * - **Key mismatch**: has keys but default model's provider lacks a key\n */\nfunction printWelcome(context: ChatContext): void {\n const state = detectWelcomeScenario(context);\n\n switch (state.scenario) {\n case 'first-run':\n printFirstRunWelcome();\n break;\n case 'returning':\n printReturningWelcome(context);\n break;\n case 'key-mismatch':\n printMismatchWelcome(context, state);\n break;\n }\n}\n\nfunction printFirstRunWelcome(): void {\n console.log('');\n console.log(\n chalk.bold('nm-cli')\n + chalk.dim(` v${version} — AI assistant for your terminal`),\n );\n console.log('');\n console.log('To get started, configure at least one provider API key:');\n console.log('');\n console.log(\n chalk.dim(' ')\n + chalk.white('/config set providers.openai.apiKey')\n + chalk.dim(' sk-...'),\n );\n console.log(\n chalk.dim(' ')\n + chalk.white('/config set providers.anthropic.apiKey')\n + chalk.dim(' sk-ant-...'),\n );\n console.log(\n chalk.dim(' ')\n + chalk.white('/config set providers.google.apiKey')\n + chalk.dim(' AIza...'),\n );\n console.log('');\n console.log(chalk.dim(\n ' Or set environment variables: '\n + 'OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_API_KEY',\n ));\n console.log(chalk.dim(\n ' Or run /config to launch the setup wizard.',\n ));\n console.log('');\n console.log(chalk.dim('Type /help for all commands.'));\n console.log('');\n}\n\nfunction printReturningWelcome(context: ChatContext): void {\n const modelLabel = `${context.currentProvider}:${context.currentModel}`;\n\n console.log('');\n console.log(\n chalk.bold('nm-cli') + chalk.dim(` v${version}`),\n );\n console.log('');\n console.log(\n ' ' + chalk.white(modelLabel)\n + chalk.dim(' | /model to switch | /help for commands'),\n );\n console.log('');\n}\n\nfunction printMismatchWelcome(\n context: ChatContext,\n state: WelcomeState,\n): void {\n const oldModel = `${context.currentProvider}:${context.currentModel}`;\n\n console.log('');\n console.log(\n chalk.bold('nm-cli') + chalk.dim(` v${version}`),\n );\n console.log('');\n\n if (state.fallbackProvider && state.fallbackModel) {\n const newModel = `${state.fallbackProvider}:${state.fallbackModel}`;\n\n console.log(\n ' ' + chalk.yellow('Warning:')\n + ` Default model ${chalk.white(oldModel)} has no API key configured.`,\n );\n console.log(\n ' ' + chalk.green(`Switching to ${newModel}`),\n );\n\n // Actually update the context and persist the change\n context.currentProvider = state.fallbackProvider;\n context.currentModel = state.fallbackModel;\n config.setDefaultModel(state.fallbackProvider, state.fallbackModel);\n } else {\n // Defensive: configured providers exist but we couldn't resolve\n // a fallback model — should not happen, but handle gracefully.\n console.log(\n ' ' + chalk.yellow('Warning:')\n + ` Default model ${chalk.white(oldModel)} has no API key configured.`,\n );\n console.log(\n ' ' + chalk.dim('Run /config to add the missing key.'),\n );\n }\n\n console.log('');\n console.log(chalk.dim(\n ' /model to change | /config to add the missing key',\n ));\n console.log('');\n}\n","import { createOpenAI } from '@ai-sdk/openai';\nimport type { LanguageModel } from 'ai';\nimport type { ModelInfo } from '../types.js';\nimport { getApiKey } from '../config.js';\nimport { BaseProvider } from './base.js';\n\nconst MODELS: ModelInfo[] = [\n { id: 'gpt-5.4', name: 'GPT-5.4', description: 'Most capable GPT model', contextWindow: 1047576 },\n { id: 'gpt-4.1', name: 'GPT-4.1', description: 'Latest GPT-4.1 model', contextWindow: 1047576 },\n { id: 'gpt-4.1-mini', name: 'GPT-4.1 Mini', description: 'Fast GPT-4.1 variant', contextWindow: 1047576 },\n { id: 'gpt-4.1-nano', name: 'GPT-4.1 Nano', description: 'Fastest GPT-4.1 variant', contextWindow: 1047576 },\n { id: 'o3', name: 'o3', description: 'Most capable reasoning model', contextWindow: 200000 },\n { id: 'o3-mini', name: 'o3-mini', description: 'Fast reasoning model', contextWindow: 200000 },\n { id: 'o4-mini', name: 'o4-mini', description: 'Latest fast reasoning model', contextWindow: 200000 },\n { id: 'gpt-4o', name: 'GPT-4o', description: 'GPT-4 Omni model', contextWindow: 128000 },\n { id: 'gpt-4o-mini', name: 'GPT-4o Mini', description: 'Fast and affordable GPT-4o variant', contextWindow: 128000 },\n];\n\nexport class OpenAIProvider extends BaseProvider {\n readonly name = 'openai';\n readonly displayName = 'OpenAI';\n\n isConfigured(): boolean {\n return getApiKey('openai') !== '';\n }\n\n listModels(): ModelInfo[] {\n return MODELS;\n }\n\n protected createModel(modelId: string): LanguageModel {\n const apiKey = getApiKey('openai');\n if (!apiKey) {\n throw new Error('OpenAI API key not configured. Run: ai config set providers.openai.apiKey <key>');\n }\n const openai = createOpenAI({ apiKey });\n return openai(modelId) as LanguageModel;\n }\n}\n","import { streamText, stepCountIs } from 'ai';\nimport type { LanguageModel } from 'ai';\nimport type { ModelMessage } from 'ai';\nimport type { ModelInfo, StreamCallbacks } from '../types.js';\nimport type { ToolSet } from 'ai';\nimport { verbose } from '../logger.js';\n\nexport interface ChatOptions {\n temperature?: number;\n maxTokens?: number;\n systemPrompt?: string;\n signal?: AbortSignal;\n tools?: ToolSet;\n maxSteps?: number;\n}\n\nexport interface ChatResult {\n text: string;\n /** Response messages including tool calls and tool results from all steps. */\n responseMessages: ModelMessage[];\n}\n\nexport interface AIProvider {\n readonly name: string;\n readonly displayName: string;\n\n chat(\n messages: ModelMessage[],\n model: string,\n options: ChatOptions,\n callbacks: StreamCallbacks,\n ): Promise<ChatResult>;\n\n listModels(): ModelInfo[];\n\n isConfigured(): boolean;\n}\n\n/**\n * Abstract base class for AI providers that share identical streaming logic.\n * Subclasses provide only the SDK-specific model creation and configuration.\n */\nexport abstract class BaseProvider implements AIProvider {\n abstract readonly name: string;\n abstract readonly displayName: string;\n\n /** Create the SDK-specific language model instance for the given model ID. */\n protected abstract createModel(modelId: string): LanguageModel;\n\n /** Return the list of known models for this provider. */\n abstract listModels(): ModelInfo[];\n\n /** Return true if the provider has a valid API key configured. */\n abstract isConfigured(): boolean;\n\n /** Override to set a provider-specific default for maxOutputTokens. */\n protected getDefaultMaxTokens(): number | undefined {\n return undefined;\n }\n\n async chat(\n messages: ModelMessage[],\n model: string,\n options: ChatOptions,\n callbacks: StreamCallbacks,\n ): Promise<ChatResult> {\n const defaultMax = this.getDefaultMaxTokens();\n const maxOutputTokens = options.maxTokens ?? defaultMax;\n\n const result = streamText({\n model: this.createModel(model),\n system: options.systemPrompt,\n messages,\n temperature: options.temperature,\n maxOutputTokens,\n abortSignal: options.signal,\n ...(options.tools\n ? { tools: options.tools, stopWhen: stepCountIs(options.maxSteps ?? 10) }\n : {}),\n });\n\n let fullText = '';\n\n try {\n for await (const part of result.fullStream) {\n switch (part.type) {\n case 'text-delta':\n fullText += part.text;\n callbacks.onToken(part.text);\n break;\n\n case 'tool-call':\n callbacks.onToolCall?.({\n toolName: part.toolName,\n args: part.input as Record<string, unknown>,\n });\n break;\n\n case 'tool-result':\n callbacks.onToolResult?.({\n toolName: part.toolName,\n result: part.output as unknown,\n });\n break;\n\n case 'tool-error':\n callbacks.onToolError?.({\n toolName: part.toolName,\n error: part.error,\n });\n break;\n\n case 'start-step':\n callbacks.onStepStart?.({});\n break;\n\n case 'finish-step':\n callbacks.onStepFinish?.({\n finishReason: part.finishReason,\n });\n break;\n\n case 'error':\n callbacks.onError(\n part.error instanceof Error ? part.error : new Error(String(part.error)),\n );\n break;\n\n default:\n break;\n }\n }\n callbacks.onComplete(fullText);\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n callbacks.onComplete(fullText);\n } else {\n callbacks.onError(error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n // Await the response to get all messages including tool calls/results.\n // This can throw if the stream was aborted, so handle gracefully.\n let responseMessages: ModelMessage[] = [];\n try {\n const response = await result.response;\n responseMessages = response.messages;\n } catch (error) {\n // On abort or stream failure, return what we have so far\n verbose('provider', `Failed to await final response: ${error instanceof Error ? error.message : String(error)}`);\n }\n\n return { text: fullText, responseMessages };\n }\n}\n","import { createAnthropic } from '@ai-sdk/anthropic';\nimport type { LanguageModel } from 'ai';\nimport type { ModelInfo } from '../types.js';\nimport { getApiKey } from '../config.js';\nimport { BaseProvider } from './base.js';\n\nconst MODELS: ModelInfo[] = [\n { id: 'claude-opus-4-6', name: 'Claude Opus 4.6', description: 'Most capable Claude model', contextWindow: 200000 },\n { id: 'claude-sonnet-4-6', name: 'Claude Sonnet 4.6', description: 'Balanced performance Claude model', contextWindow: 200000 },\n { id: 'claude-opus-4-20250514', name: 'Claude Opus 4', description: 'Previous gen most capable model', contextWindow: 200000 },\n { id: 'claude-sonnet-4-20250514', name: 'Claude Sonnet 4', description: 'Previous gen balanced model', contextWindow: 200000 },\n { id: 'claude-haiku-4-5-20251001', name: 'Claude Haiku 4.5', description: 'Fast and affordable Claude model', contextWindow: 200000 },\n];\n\nexport class AnthropicProvider extends BaseProvider {\n readonly name = 'anthropic';\n readonly displayName = 'Anthropic';\n\n isConfigured(): boolean {\n return getApiKey('anthropic') !== '';\n }\n\n listModels(): ModelInfo[] {\n return MODELS;\n }\n\n protected getDefaultMaxTokens(): number {\n return 4096;\n }\n\n protected createModel(modelId: string): LanguageModel {\n const apiKey = getApiKey('anthropic');\n if (!apiKey) {\n throw new Error('Anthropic API key not configured. Run: ai config set providers.anthropic.apiKey <key>');\n }\n const anthropic = createAnthropic({ apiKey });\n return anthropic(modelId) as LanguageModel;\n }\n}\n","import { createGoogleGenerativeAI } from '@ai-sdk/google';\nimport type { LanguageModel } from 'ai';\nimport type { ModelInfo } from '../types.js';\nimport { getApiKey } from '../config.js';\nimport { BaseProvider } from './base.js';\n\nconst MODELS: ModelInfo[] = [\n { id: 'gemini-2.5-pro-preview-05-06', name: 'Gemini 2.5 Pro', description: 'Most capable Gemini model with thinking', contextWindow: 1048576 },\n { id: 'gemini-2.5-flash-preview-05-20', name: 'Gemini 2.5 Flash', description: 'Fast Gemini model with thinking', contextWindow: 1048576 },\n { id: 'gemini-2.0-flash', name: 'Gemini 2.0 Flash', description: 'Fast and efficient Gemini model', contextWindow: 1048576 },\n { id: 'gemini-2.0-flash-lite', name: 'Gemini 2.0 Flash Lite', description: 'Lightweight fast model', contextWindow: 1048576 },\n { id: 'gemini-1.5-pro', name: 'Gemini 1.5 Pro', description: 'Previous generation pro model', contextWindow: 2097152 },\n { id: 'gemini-1.5-flash', name: 'Gemini 1.5 Flash', description: 'Previous generation flash model', contextWindow: 1048576 },\n];\n\nexport class GoogleProvider extends BaseProvider {\n readonly name = 'google';\n readonly displayName = 'Google (Gemini)';\n\n isConfigured(): boolean {\n return getApiKey('google') !== '';\n }\n\n listModels(): ModelInfo[] {\n return MODELS;\n }\n\n protected createModel(modelId: string): LanguageModel {\n const apiKey = getApiKey('google');\n if (!apiKey) {\n throw new Error('Google API key not configured. Run: ai config set providers.google.apiKey <key>');\n }\n const google = createGoogleGenerativeAI({ apiKey });\n return google(modelId) as LanguageModel;\n }\n}\n","import type { AIProvider } from './base.js';\nimport { OpenAIProvider } from './openai.js';\nimport { AnthropicProvider } from './anthropic.js';\nimport { GoogleProvider } from './google.js';\n\nconst providers = new Map<string, AIProvider>();\n\nfunction register(provider: AIProvider): void {\n providers.set(provider.name, provider);\n}\n\nregister(new OpenAIProvider());\nregister(new AnthropicProvider());\nregister(new GoogleProvider());\n\nexport function getProvider(name: string): AIProvider | undefined {\n return providers.get(name);\n}\n\nexport function getAllProviders(): AIProvider[] {\n return Array.from(providers.values());\n}\n\nexport function getProviderForModel(modelId: string): { provider: AIProvider; model: string } | undefined {\n for (const provider of providers.values()) {\n const model = provider.listModels().find((m) => m.id === modelId);\n if (model) {\n return { provider, model: model.id };\n }\n }\n return undefined;\n}\n\nexport function resolveProviderAndModel(input: string): { provider: AIProvider; model: string } | undefined {\n // Handle \"provider:model\" format\n if (input.includes(':')) {\n const [providerName, modelId] = input.split(':', 2);\n const provider = providers.get(providerName);\n if (provider) {\n return { provider, model: modelId };\n }\n return undefined;\n }\n\n // Try to find model across all providers\n return getProviderForModel(input);\n}\n\nexport type { AIProvider, ChatOptions, ChatResult } from './base.js';\n","import chalk, { type ChalkInstance } from 'chalk';\nimport { Marked } from 'marked';\nimport { markedTerminal } from 'marked-terminal';\nimport * as config from '../config.js';\n\nconst marked = new Marked();\nmarked.use({ async: false });\nmarked.use(markedTerminal() as Parameters<typeof marked.use>[0]);\n\nexport function renderMarkdown(text: string): string {\n try {\n const rendered = marked.parse(text);\n if (typeof rendered === 'string') {\n return rendered;\n }\n return text;\n } catch {\n return text;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Theme-aware color resolution\n// ---------------------------------------------------------------------------\n\nconst CHALK_COLORS: Record<string, ChalkInstance> = {\n black: chalk.black,\n red: chalk.red,\n green: chalk.green,\n yellow: chalk.yellow,\n blue: chalk.blue,\n magenta: chalk.magenta,\n cyan: chalk.cyan,\n white: chalk.white,\n gray: chalk.gray,\n grey: chalk.grey,\n redBright: chalk.redBright,\n greenBright: chalk.greenBright,\n yellowBright: chalk.yellowBright,\n blueBright: chalk.blueBright,\n magentaBright: chalk.magentaBright,\n cyanBright: chalk.cyanBright,\n whiteBright: chalk.whiteBright,\n};\n\n/**\n * Resolve a chalk color name from the theme config to a ChalkInstance.\n * Returns the provided fallback if the color name is invalid or not set.\n */\nfunction resolveThemeColor(colorName: string | undefined, fallback: ChalkInstance): ChalkInstance {\n if (!colorName) return fallback;\n return CHALK_COLORS[colorName] ?? fallback;\n}\n\nfunction getThemeColors() {\n const theme = config.get('theme');\n return {\n user: resolveThemeColor(theme?.userColor, chalk.cyan),\n assistant: resolveThemeColor(theme?.assistantColor, chalk.green),\n system: resolveThemeColor(theme?.systemColor, chalk.yellow),\n };\n}\n\nexport function formatUserMessage(message: string): string {\n const color = getThemeColors().user;\n return color.bold('You: ') + color(message);\n}\n\nexport function formatAssistantLabel(): string {\n const color = getThemeColors().assistant;\n return color.bold('AI: ');\n}\n\nexport function formatSystemMessage(message: string): string {\n const color = getThemeColors().system;\n return color(message);\n}\n\nexport function formatError(message: string): string {\n return chalk.red.bold('Error: ') + chalk.red(message);\n}\n\nexport function formatSuccess(message: string): string {\n return chalk.green(message);\n}\n\nexport function formatInfo(message: string): string {\n return chalk.blue(message);\n}\n\nexport function formatDim(message: string): string {\n return chalk.dim(message);\n}\n\nexport function formatHeader(message: string): string {\n return chalk.bold.underline(message);\n}\n\nexport function formatModelPrompt(provider: string, model: string): string {\n return chalk.gray(`${provider}:${model}`) + chalk.white(' > ');\n}\n\n// ---------------------------------------------------------------------------\n// Tool classification — maps tool names to display categories.\n// Unknown tools are handled gracefully with a generic fallback.\n// ---------------------------------------------------------------------------\n\ninterface ToolDisplayMeta {\n verb: string;\n mutating: boolean;\n}\n\nconst TOOL_DISPLAY: Record<string, ToolDisplayMeta> = {\n readFile: { verb: 'Read', mutating: false },\n viewImage: { verb: 'View', mutating: false },\n listFiles: { verb: 'List', mutating: false },\n searchFiles: { verb: 'Search', mutating: false },\n grep: { verb: 'Search', mutating: false },\n writeFile: { verb: 'Write', mutating: true },\n editFile: { verb: 'Edit', mutating: true },\n runCommand: { verb: 'Run', mutating: true },\n git: { verb: 'Git', mutating: true },\n fetch: { verb: 'Fetch', mutating: false },\n generateImage: { verb: 'Image', mutating: true },\n generateVideo: { verb: 'Video', mutating: true },\n\n // Canvas tools\n createCanvas: { verb: 'Canvas', mutating: false },\n drawText: { verb: 'Draw', mutating: false },\n drawImage: { verb: 'Draw', mutating: false },\n setCanvasStyle: { verb: 'Style', mutating: false },\n clearCanvas: { verb: 'Clear', mutating: false },\n saveCanvas: { verb: 'Save', mutating: true },\n getCanvasInfo: { verb: 'Canvas', mutating: false },\n drawGradient: { verb: 'Draw', mutating: false },\n floodFill: { verb: 'Fill', mutating: false },\n\n // Desktop tools\n takeScreenshot: { verb: 'Screen', mutating: false },\n getOpenWindows: { verb: 'Windows', mutating: false },\n moveWindow: { verb: 'Move', mutating: true },\n mouseClick: { verb: 'Click', mutating: true },\n pressKeys: { verb: 'Keys', mutating: true },\n launchApp: { verb: 'Launch', mutating: true },\n focusWindow: { verb: 'Focus', mutating: true },\n\n // Brush tools\n setBrush: { verb: 'Brush', mutating: false },\n brushStroke: { verb: 'Paint', mutating: false },\n brushFill: { verb: 'Fill', mutating: false },\n brushSmudge: { verb: 'Smudge', mutating: false },\n brushBlur: { verb: 'Blur', mutating: false },\n\n // Smart Home tools\n listSmartDevices: { verb: 'Devices', mutating: false },\n getDeviceStatus: { verb: 'Status', mutating: false },\n controlDevice: { verb: 'Control', mutating: true },\n playMedia: { verb: 'Play', mutating: true },\n searchMusic: { verb: 'Search', mutating: false },\n playMusic: { verb: 'Play', mutating: true },\n sendNotification: { verb: 'Notify', mutating: true },\n};\n\nfunction getToolMeta(toolName: string): ToolDisplayMeta {\n if (TOOL_DISPLAY[toolName]) return TOOL_DISPLAY[toolName];\n\n // Heuristic for unknown tools: assume mutating unless the name starts with\n // a read-like prefix.\n const lower = toolName.toLowerCase();\n const readPrefixes = ['read', 'get', 'list', 'search', 'find', 'grep', 'fetch', 'query', 'check', 'show'];\n const isReadOnly = readPrefixes.some((p) => lower.startsWith(p));\n\n // Generate a short verb from the tool name (camelCase -> first word, capitalised)\n const verb = toolName.replace(/([A-Z])/g, ' $1').trim().split(' ')[0];\n const capitalized = verb.charAt(0).toUpperCase() + verb.slice(1);\n\n return { verb: capitalized, mutating: !isReadOnly };\n}\n\n// ---------------------------------------------------------------------------\n// Compact formatting for tool calls\n// ---------------------------------------------------------------------------\n\n/**\n * Format a tool call for terminal display.\n *\n * Output: ● Read src/ui/renderer.ts\n * ● Run $ npm test\n */\nexport function formatToolCall(toolName: string, args: Record<string, unknown>): string {\n const meta = getToolMeta(toolName);\n const color = meta.mutating ? chalk.yellow : chalk.cyan;\n const bullet = color('●');\n const verb = color.bold(meta.verb.padEnd(6));\n const detail = formatToolCallDetail(toolName, args);\n\n return ` ${bullet} ${verb} ${chalk.white(detail)}`;\n}\n\nfunction formatToolCallDetail(toolName: string, args: Record<string, unknown>): string {\n switch (toolName) {\n case 'listFiles':\n return String(args.path ?? '.');\n\n case 'readFile':\n return String(args.path ?? '');\n\n case 'viewImage': {\n const imgPath = String(args.path ?? '');\n const filename = imgPath.split(/[\\\\/]/).pop() ?? imgPath;\n return chalk.white(filename);\n }\n\n case 'writeFile': {\n const path = String(args.path ?? '');\n const len = typeof args.content === 'string' ? args.content.length : 0;\n return `${path} ${chalk.dim(`(${len.toLocaleString()} chars)`)}`;\n }\n\n case 'editFile': {\n const path = String(args.path ?? args.filePath ?? '');\n return path;\n }\n\n case 'runCommand':\n return `$ ${String(args.command ?? '')}`;\n\n case 'searchFiles':\n case 'grep': {\n const pattern = String(args.pattern ?? args.query ?? args.search ?? '');\n const searchPath = args.path ?? args.directory ?? '';\n return `${chalk.white(`\"${pattern}\"`)}${searchPath ? chalk.dim(` in ${searchPath}`) : ''}`;\n }\n\n case 'git':\n return String(args.subcommand ?? args.command ?? JSON.stringify(args));\n\n case 'fetch':\n return String(args.url ?? '');\n\n case 'generateImage': {\n const prompt = String(args.prompt ?? '');\n const imgSize = String(args.size ?? '1024x1024');\n return `${chalk.white(`\"${prompt}\"`)} ${chalk.dim(`(${imgSize})`)}`;\n }\n\n case 'generateVideo': {\n const prompt = String(args.prompt ?? '');\n const vidSize = String(args.size ?? '720x1280');\n const vidDur = Number(args.duration ?? 4);\n const clipCount = Math.ceil(vidDur / 12);\n const clipsLabel = clipCount > 1 ? `, ${clipCount} clips` : '';\n return `${chalk.white(`\"${prompt}\"`)} ${chalk.dim(`(${vidSize}, ${vidDur}s${clipsLabel})`)}`;\n }\n\n // Canvas tools\n case 'createCanvas': {\n const w = args.width ?? '?';\n const h = args.height ?? '?';\n const bg = args.backgroundColor ?? 'white';\n return `create ${w}x${h} ${chalk.dim(`(${bg})`)}`;\n }\n\n case 'drawText': {\n const txt = String(args.text ?? '');\n const display = txt.length > 40 ? txt.slice(0, 37) + '...' : txt;\n return `text \"${display}\" at (${args.x},${args.y})`;\n }\n\n case 'drawImage': {\n const imgPath = String(args.imagePath ?? '');\n const filename = imgPath.split(/[\\\\/]/).pop() ?? imgPath;\n return `image ${chalk.white(filename)} at (${args.x ?? 0},${args.y ?? 0})`;\n }\n\n case 'drawGradient': {\n const dir = String(args.direction ?? 'vertical');\n const colors = args.colors as string[] | undefined;\n return `gradient ${dir} ${chalk.dim(`(${colors?.length ?? '?'} stops)`)} at (${args.x},${args.y})`;\n }\n\n case 'floodFill':\n return `at (${args.x},${args.y}) ${chalk.dim(String(args.color ?? ''))}`;\n\n case 'saveCanvas': {\n const savePath = args.path ? String(args.path) : 'auto';\n const filename = savePath === 'auto' ? savePath : savePath.split(/[\\\\/]/).pop() ?? savePath;\n return `canvas ${chalk.dim('->')} ${chalk.white(filename)}`;\n }\n\n case 'clearCanvas':\n return String(args.canvasId ?? '');\n\n case 'setCanvasStyle':\n return String(args.canvasId ?? '');\n\n case 'getCanvasInfo':\n return args.canvasId ? String(args.canvasId) : 'list all';\n\n // Brush tools\n case 'setBrush': {\n const bType = String(args.type ?? 'round');\n const bSize = args.size !== undefined ? ` size=${args.size}` : '';\n const bOpacity = args.opacity !== undefined ? ` opacity=${args.opacity}` : '';\n const bColor = args.color ? ` ${chalk.dim(String(args.color))}` : '';\n return `${bType}${bSize}${bOpacity}${bColor}`;\n }\n\n case 'brushStroke': {\n const pts = args.points as unknown[] | undefined;\n const ptCount = pts?.length ?? '?';\n return `stroke ${ptCount} points`;\n }\n\n case 'brushSmudge': {\n const pts = args.points as unknown[] | undefined;\n const ptCount = pts?.length ?? '?';\n const str = args.strength !== undefined ? ` strength=${args.strength}` : '';\n return `${ptCount} points${str}`;\n }\n\n case 'brushBlur': {\n const bw = args.width ?? '?';\n const bh = args.height ?? '?';\n const br = args.radius ?? 5;\n return `region ${bw}x${bh} radius=${br}`;\n }\n\n case 'brushFill': {\n const fc = args.color ? chalk.dim(String(args.color)) : '';\n return `at (${args.x},${args.y})${fc ? ' ' + fc : ''}`;\n }\n\n // Desktop tools\n case 'takeScreenshot': {\n const r = args.region as { x: number; y: number; width: number; height: number } | undefined;\n if (r) return `region (${r.x},${r.y}) ${r.width}x${r.height}`;\n return 'full screen';\n }\n\n case 'getOpenWindows': {\n const f = args.filter as string | undefined;\n return f ? chalk.dim(`(filter: \"${f}\")`) : 'all';\n }\n\n case 'moveWindow': {\n const label = String(args.title ?? args.handle ?? '');\n const parts: string[] = [];\n if (args.x !== undefined || args.y !== undefined) parts.push(`to (${args.x ?? '?'},${args.y ?? '?'})`);\n if (args.width !== undefined || args.height !== undefined) parts.push(`${args.width ?? '?'}x${args.height ?? '?'}`);\n if (args.state) parts.push(String(args.state));\n return `${chalk.white(`\"${label}\"`)} ${parts.join(' ')}`;\n }\n\n case 'mouseClick': {\n const btn = String(args.button ?? 'left');\n const act = String(args.action ?? 'click');\n const label = act === 'click' ? btn : `${btn} ${act}`;\n return `${label} at (${args.x},${args.y})`;\n }\n\n case 'pressKeys': {\n if (args.text) {\n const txt = String(args.text);\n const display = txt.length > 40 ? txt.slice(0, 37) + '...' : txt;\n return `\"${display}\"`;\n }\n return String(args.keys ?? '');\n }\n\n case 'launchApp': {\n const appName = String(args.app ?? '');\n const appArgs = args.args ? ` ${chalk.dim(String(args.args))}` : '';\n return `${chalk.white(appName)}${appArgs}`;\n }\n\n case 'focusWindow':\n return chalk.white(`\"${String(args.title ?? args.handle ?? '')}\"`);\n\n // Smart Home tools\n case 'listSmartDevices':\n return args.includeStatus ? 'list all (with status)' : 'list all';\n\n case 'getDeviceStatus':\n return String(args.deviceId ?? '');\n\n case 'controlDevice': {\n const ctrlDevice = String(args.deviceId ?? '');\n const ctrlAction = String(args.action ?? '');\n const ctrlValue = args.value !== undefined ? ` (${args.value})` : '';\n return `${chalk.white(ctrlDevice)}: ${ctrlAction}${ctrlValue}`;\n }\n\n case 'playMedia': {\n const pmDevice = String(args.deviceId ?? '');\n const pmTitle = args.title ? `\"${String(args.title)}\"` : String(args.mediaUrl ?? '');\n return `${pmTitle} on ${chalk.white(pmDevice)}`;\n }\n\n case 'searchMusic': {\n const smQuery = String(args.query ?? '');\n const smMax = args.maxResults !== undefined ? ` (max ${args.maxResults})` : '';\n return `${chalk.white(`\"${smQuery}\"`)}${chalk.dim(smMax)}`;\n }\n\n case 'playMusic': {\n const pmDevice = String(args.deviceId ?? '');\n const pmLabel = args.title ? `\"${String(args.title)}\"` : String(args.videoId ?? '');\n return `${pmLabel} on ${chalk.white(pmDevice)}`;\n }\n\n case 'sendNotification': {\n const snDevice = String(args.deviceId ?? '');\n const snMsg = String(args.message ?? '');\n const snDisplay = snMsg.length > 40 ? snMsg.slice(0, 37) + '...' : snMsg;\n return `${chalk.white(snDevice)}: \"${snDisplay}\"`;\n }\n\n default:\n return formatGenericArgs(args);\n }\n}\n\n/**\n * Generic arg formatter for unknown tools: pick the first string argument,\n * fall back to compact JSON.\n */\nfunction formatGenericArgs(args: Record<string, unknown>): string {\n const entries = Object.entries(args);\n for (const [, value] of entries) {\n if (typeof value === 'string' && value.length > 0 && value.length < 200) {\n return value;\n }\n }\n if (entries.length === 0) return '';\n try {\n const json = JSON.stringify(args);\n if (json.length > 120) return json.slice(0, 117) + '...';\n return chalk.dim(json);\n } catch {\n return '';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Compact formatting for tool results\n// ---------------------------------------------------------------------------\n\n/**\n * Format a tool result for terminal display.\n *\n * Output: ✓ Read src/renderer.ts (134 lines, 3.2 KB)\n * ✗ Read /nonexistent ENOENT: no such file or directory\n */\nexport function formatToolResult(toolName: string, result: unknown): string {\n const meta = getToolMeta(toolName);\n const obj = (result != null && typeof result === 'object' ? result : {}) as Record<string, unknown>;\n const isError = typeof obj.error === 'string';\n const mark = isError ? chalk.red('✗') : chalk.green('✓');\n const verbColor = isError ? chalk.red : (meta.mutating ? chalk.yellow : chalk.cyan);\n const verb = verbColor.bold(meta.verb.padEnd(6));\n\n const detail = isError\n ? formatToolResultError(toolName, obj)\n : formatToolResultSuccess(toolName, obj);\n\n const lines = [\n ` ${mark} ${verb} ${detail}`,\n ];\n\n // For runCommand, show truncated output under a gutter\n if (toolName === 'runCommand' && !isError) {\n const outputLines = formatCommandOutput(obj);\n if (outputLines) {\n lines.push(outputLines);\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Format a tool error for terminal display.\n *\n * Output: ✗ Read /bad/path ENOENT: no such file or directory\n */\nexport function formatToolError(toolName: string, error: unknown): string {\n const meta = getToolMeta(toolName);\n const verb = chalk.red.bold(meta.verb.padEnd(6));\n const message = error instanceof Error ? error.message : String(error);\n return ` ${chalk.red('✗')} ${verb} ${chalk.red(message)}`;\n}\n\nfunction formatToolResultError(toolName: string, obj: Record<string, unknown>): string {\n const errorMsg = String(obj.error ?? 'unknown error');\n const path = obj.path ? `${chalk.white(String(obj.path))} ` : '';\n return `${path}${chalk.red(errorMsg)}`;\n}\n\nfunction formatToolResultSuccess(toolName: string, obj: Record<string, unknown>): string {\n switch (toolName) {\n case 'listFiles': {\n const path = String(obj.path ?? '.');\n const entries = obj.entries as Array<Record<string, unknown>> | undefined;\n const count = entries ? entries.length : '?';\n return `${chalk.white(path)} ${chalk.dim(`(${count} entries)`)}`;\n }\n\n case 'readFile': {\n const path = String(obj.path ?? '');\n const fileType = obj.type as string | undefined;\n\n if (fileType === 'image') {\n const w = obj.width ?? '?';\n const h = obj.height ?? '?';\n const fmt = obj.format ?? '?';\n const sizeStr = String(obj.sizeFormatted ?? formatByteSize(obj.size as number ?? 0));\n return `${chalk.white(path)} ${chalk.dim(`(image, ${w}x${h}, ${fmt}, ${sizeStr})`)}`;\n }\n\n if (fileType === 'binary') {\n const desc = String(obj.description ?? 'binary file');\n return `${chalk.white(path)} ${chalk.dim(`(${desc})`)}`;\n }\n\n const content = String(obj.content ?? '');\n const lineCount = content.split('\\n').length;\n const sizeStr = formatByteSize(obj.size as number | undefined ?? content.length);\n const truncLabel = obj.truncated ? ', truncated' : '';\n return `${chalk.white(path)} ${chalk.dim(`(${lineCount} lines, ${sizeStr}${truncLabel})`)}`;\n }\n\n case 'viewImage': {\n const path = String(obj.path ?? '');\n const filename = path.split(/[\\\\/]/).pop() ?? path;\n const w = obj.width ?? '?';\n const h = obj.height ?? '?';\n const fmt = obj.format ?? '?';\n const sizeStr = String(obj.sizeFormatted ?? formatByteSize(obj.size as number ?? 0));\n return `${chalk.white(filename)} ${chalk.dim(`${w}x${h} ${fmt} ${sizeStr}`)}`;\n }\n\n case 'writeFile': {\n const path = String(obj.path ?? '');\n const sizeStr = formatByteSize(obj.bytesWritten as number | undefined ?? 0);\n return `${chalk.white(path)} ${chalk.dim(`(${sizeStr})`)}`;\n }\n\n case 'editFile': {\n const path = String(obj.path ?? obj.filePath ?? '');\n return chalk.white(path);\n }\n\n case 'runCommand': {\n const cmd = obj.command ? `$ ${obj.command}` : '';\n const exitCode = obj.exitCode as number | undefined;\n const exitLabel = exitCode !== undefined\n ? (exitCode === 0 ? chalk.dim('exit 0') : chalk.red(`exit ${exitCode}`))\n : '';\n return `${chalk.white(cmd)} ${exitLabel}`;\n }\n\n case 'generateImage': {\n const path = String(obj.path ?? '');\n const filename = path.split(/[\\\\/]/).pop() ?? path;\n return `saved to ${chalk.white(filename)}`;\n }\n\n case 'generateVideo': {\n const path = String(obj.path ?? '');\n const filename = path.split(/[\\\\/]/).pop() ?? path;\n const sizeStr = formatByteSize(obj.bytesWritten as number | undefined ?? 0);\n const clips = obj.clips as number | undefined;\n const stitchLabel = clips && clips > 1 ? `, ${clips} clips stitched` : '';\n return `saved to ${chalk.white(filename)} ${chalk.dim(`(${sizeStr}${stitchLabel})`)}`;\n }\n\n // Canvas tools\n case 'createCanvas': {\n const id = String(obj.canvasId ?? '');\n const w = obj.width ?? '?';\n const h = obj.height ?? '?';\n return `${chalk.white(id)} ${chalk.dim(`(${w}x${h})`)}`;\n }\n\n case 'drawText': {\n const id = String(obj.canvasId ?? '');\n const txt = String(obj.text ?? '');\n const display = txt.length > 30 ? txt.slice(0, 27) + '...' : txt;\n return `\"${display}\" on ${chalk.dim(id)}`;\n }\n\n case 'drawImage': {\n const id = String(obj.canvasId ?? '');\n const imgPath = String(obj.imagePath ?? '');\n const filename = imgPath.split(/[\\\\/]/).pop() ?? imgPath;\n return `${chalk.white(filename)} on ${chalk.dim(id)}`;\n }\n\n case 'saveCanvas': {\n const savePath = String(obj.path ?? '');\n const filename = savePath.split(/[\\\\/]/).pop() ?? savePath;\n const sizeStr = formatByteSize(obj.bytesWritten as number | undefined ?? 0);\n return `saved to ${chalk.white(filename)} ${chalk.dim(`(${sizeStr})`)}`;\n }\n\n case 'drawGradient':\n case 'floodFill':\n case 'clearCanvas':\n case 'setCanvasStyle':\n case 'getCanvasInfo': {\n const id = obj.canvasId ? String(obj.canvasId) : '';\n return id ? chalk.dim(id) : chalk.dim('(done)');\n }\n\n // Brush tools\n case 'setBrush': {\n const br = obj.brush as Record<string, unknown> | undefined;\n const bType = br ? String(br.type ?? 'round') : 'round';\n const bSize = br ? br.size : '?';\n const bColor = br ? chalk.dim(String(br.color ?? '')) : '';\n return `${chalk.white(bType)} size=${bSize} ${bColor} on ${chalk.dim(String(obj.canvasId ?? ''))}`;\n }\n\n case 'brushStroke': {\n const stamps = obj.stampCount ?? '?';\n const bType = obj.brushType ? String(obj.brushType) : '';\n return `${chalk.white(bType)} ${stamps} stamps on ${chalk.dim(String(obj.canvasId ?? ''))}`;\n }\n\n case 'brushFill': {\n const pxFilled = obj.pixelsFilled ?? 0;\n const fc = obj.color ? chalk.dim(String(obj.color)) : '';\n return `${pxFilled} pixels ${fc} on ${chalk.dim(String(obj.canvasId ?? ''))}`;\n }\n\n case 'brushSmudge': {\n const pts = obj.pointCount ?? '?';\n const str = obj.strength ?? '?';\n return `${pts} points strength=${str} on ${chalk.dim(String(obj.canvasId ?? ''))}`;\n }\n\n case 'brushBlur': {\n const region = obj.region as Record<string, unknown> | undefined;\n const br = obj.blurRadius ?? '?';\n const rDesc = region ? `${region.width}x${region.height}` : '?';\n return `${rDesc} radius=${br} on ${chalk.dim(String(obj.canvasId ?? ''))}`;\n }\n\n // Desktop tools\n case 'takeScreenshot': {\n const w = obj.width ?? '?';\n const h = obj.height ?? '?';\n const p = obj.path !== '(temp)' ? ` ${chalk.dim(`-> ${String(obj.path)}`)}` : '';\n return `${chalk.white(`${w}x${h}`)}${p}`;\n }\n\n case 'getOpenWindows': {\n const count = obj.count ?? '?';\n const f = obj.filter ? ` filter: \"${obj.filter}\"` : '';\n return `${chalk.dim(`(${count} windows${f})`)}`;\n }\n\n case 'moveWindow': {\n const handle = String(obj.handle ?? '');\n const pos = `(${obj.x},${obj.y}) ${obj.width}x${obj.height}`;\n return `${chalk.white(handle)} ${chalk.dim(pos)}`;\n }\n\n case 'mouseClick': {\n const btn = String(obj.button ?? 'left');\n const act = String(obj.action ?? 'click');\n return `${btn} ${act} at (${obj.x},${obj.y})`;\n }\n\n case 'pressKeys': {\n if (obj.typed) {\n const txt = String(obj.typed);\n const display = txt.length > 30 ? txt.slice(0, 27) + '...' : txt;\n return `typed \"${display}\"`;\n }\n return `sent ${chalk.dim(String(obj.keys ?? ''))}`;\n }\n\n case 'launchApp': {\n const appName = String(obj.app ?? '');\n const pid = obj.pid ? chalk.dim(` (pid ${obj.pid})`) : '';\n const win = obj.window as Record<string, unknown> | null | undefined;\n const winTitle = win ? ` \"${String(win.title ?? '')}\"` : '';\n return `${chalk.white(appName)}${pid}${winTitle}`;\n }\n\n case 'focusWindow': {\n const fTitle = obj.title ? `\"${String(obj.title)}\"` : String(obj.handle ?? '');\n return chalk.white(fTitle);\n }\n\n // Smart Home tools\n case 'listSmartDevices': {\n const devCount = obj.count ?? (obj.devices as unknown[] | undefined)?.length ?? '?';\n return chalk.dim(`(${devCount} devices)`);\n }\n\n case 'getDeviceStatus': {\n const devId = String(obj.deviceId ?? '');\n const devOnline = obj.online ? chalk.green('online') : chalk.red('offline');\n const devVol = obj.volume !== undefined ? ` vol=${obj.volume}%` : '';\n return `${chalk.white(devId)} ${devOnline}${chalk.dim(devVol)}`;\n }\n\n case 'controlDevice': {\n const devId = String(obj.deviceId ?? '');\n const devAction = String(obj.action ?? '');\n return `${chalk.white(devId)} ${chalk.dim(devAction)}`;\n }\n\n case 'playMedia': {\n const devId = String(obj.deviceId ?? '');\n return `on ${chalk.white(devId)}`;\n }\n\n case 'searchMusic': {\n const results = obj.results as unknown[] | undefined;\n const count = results?.length ?? 0;\n return chalk.dim(`(${count} results)`);\n }\n\n case 'playMusic': {\n const devId = String(obj.deviceId ?? '');\n const np = obj.nowPlaying as Record<string, unknown> | undefined;\n const npTitle = np ? String(np.title ?? '') : '';\n return npTitle\n ? `${chalk.white(`\"${npTitle}\"`)} on ${chalk.white(devId)}`\n : `on ${chalk.white(devId)}`;\n }\n\n case 'sendNotification': {\n const devId = String(obj.deviceId ?? '');\n const devMsg = String(obj.message ?? '');\n const devDisplay = devMsg.length > 30 ? devMsg.slice(0, 27) + '...' : devMsg;\n return `${chalk.white(devId)} \"${devDisplay}\"`;\n }\n\n default: {\n // Generic: show first short string value, or compact JSON summary\n const firstStr = Object.values(obj).find(\n (v) => typeof v === 'string' && v.length > 0 && v.length < 100,\n );\n if (typeof firstStr === 'string') return chalk.dim(firstStr);\n return chalk.dim('(done)');\n }\n }\n}\n\nfunction formatCommandOutput(obj: Record<string, unknown>): string | null {\n const stdout = obj.stdout ? String(obj.stdout).trimEnd() : '';\n const stderr = obj.stderr ? String(obj.stderr).trimEnd() : '';\n const combined = [stdout, stderr].filter(Boolean).join('\\n');\n if (!combined) return null;\n\n const maxLines = 8;\n const allLines = combined.split('\\n');\n const shown = allLines.slice(0, maxLines);\n const remaining = allLines.length - shown.length;\n\n const gutter = chalk.dim(' │ ');\n let output = shown.map((line) => `${gutter}${chalk.dim(line)}`).join('\\n');\n\n if (remaining > 0) {\n output += `\\n${gutter}${chalk.dim(`... ${remaining} more lines`)}`;\n }\n\n return output;\n}\n\nfunction formatByteSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n","import type { SlashCommand } from '../types.js';\nimport { formatHeader, formatDim, formatInfo } from '../ui/renderer.js';\nimport chalk from 'chalk';\n\nexport const helpCommand: SlashCommand = {\n name: 'help',\n description: 'Show available commands',\n aliases: ['h', '?'],\n\n async execute() {\n const lines = [\n '',\n formatHeader('Available Commands'),\n '',\n ` ${chalk.bold('/help')}${formatDim(', /h, /?')} ${formatInfo('Show this help message')}`,\n '',\n chalk.dim(' Model'),\n ` ${chalk.bold('/model')} ${formatInfo('Interactive model selector')}`,\n ` ${chalk.bold('/model')} ${formatDim('<provider:model>')} ${formatInfo('Switch model directly')}`,\n '',\n chalk.dim(' Configuration'),\n ` ${chalk.bold('/config')} ${formatInfo('Interactive config wizard')}`,\n ` ${chalk.bold('/config set')} ${formatDim('<key> <value>')} ${formatInfo('Set a value directly')}`,\n ` ${chalk.bold('/config get')} ${formatDim('<key>')} ${formatInfo('Get a value directly')}`,\n ` ${chalk.bold('/config list')} ${formatInfo('List all settings')}`,\n '',\n chalk.dim(' Agents'),\n ` ${chalk.bold('/agent')} ${formatInfo('Interactive agent manager')}`,\n ` ${chalk.bold('/agent create')} ${formatDim('[name]')} ${formatInfo('Create a new agent')}`,\n ` ${chalk.bold('/agent list')} ${formatInfo('List all agents')}`,\n ` ${chalk.bold('/agent view')} ${formatDim('[name]')} ${formatInfo('View agent details')}`,\n ` ${chalk.bold('/agent run')} ${formatDim('[name] [prompt]')} ${formatInfo('Run an agent')}`,\n ` ${chalk.bold('/agent run-parallel')} ${formatDim('[names] [prompt]')} ${formatInfo('Run multiple agents in parallel')}`,\n ` ${chalk.bold('/agent delete')} ${formatDim('[name]')} ${formatInfo('Delete an agent')}`,\n '',\n chalk.dim(' Smart Home'),\n ` ${chalk.bold('/devices')}${formatDim(', /dev, /smarthome')} ${formatInfo('Manage smart home devices (discover, add, edit, test, remove)')}`,\n '',\n chalk.dim(' Session'),\n ` ${chalk.bold('/clear')} ${formatInfo('Clear screen and messages')}`,\n ` ${chalk.bold('/exit')}${formatDim(', /quit, /q')} ${formatInfo('Exit the application')}`,\n '',\n chalk.dim(' Tip: Commands with optional args launch interactive wizards when called bare.'),\n '',\n ];\n\n console.log(lines.join('\\n'));\n },\n};\n","import type { Interface as ReadlineInterface } from 'node:readline';\nimport chalk from 'chalk';\n\n// ── Drawing helpers ──────────────────────────────────────────────────\n\nconst BOX_WIDTH = 56;\nconst BOX_TOP = chalk.dim('\\u250c' + '\\u2500'.repeat(BOX_WIDTH) + '\\u2510');\nconst BOX_BOTTOM = chalk.dim('\\u2514' + '\\u2500'.repeat(BOX_WIDTH) + '\\u2518');\nconst DIVIDER = chalk.dim('\\u2500'.repeat(BOX_WIDTH + 2));\nconst PROMPT_CHAR = chalk.cyan('\\u203a ');\nconst CHECK = chalk.green('\\u2714');\n\nexport function wizardHeader(title: string): void {\n console.log('');\n console.log(BOX_TOP);\n console.log(chalk.dim('\\u2502') + chalk.bold.white(' ' + title.padEnd(BOX_WIDTH - 1)) + chalk.dim('\\u2502'));\n console.log(BOX_BOTTOM);\n}\n\nexport function wizardSection(title: string): void {\n console.log('');\n console.log(DIVIDER);\n console.log(chalk.bold.white(' ' + title));\n console.log(DIVIDER);\n}\n\nexport function wizardDivider(): void {\n console.log(DIVIDER);\n}\n\n/**\n * Display a key-value info block, or a simple dim message.\n * Overloaded: pass a string for a dim message, or an array of {label, value} pairs.\n */\nexport function wizardInfo(message: string): void;\nexport function wizardInfo(items: { label: string; value: string }[]): void;\nexport function wizardInfo(input: string | { label: string; value: string }[]): void {\n if (typeof input === 'string') {\n console.log(chalk.dim(' ' + input));\n return;\n }\n\n // Key-value block\n const maxLabelLen = Math.max(...input.map((i) => i.label.length));\n console.log('');\n for (const item of input) {\n const label = chalk.bold(item.label.padEnd(maxLabelLen));\n console.log(` ${label} ${item.value}`);\n }\n console.log('');\n}\n\nexport function wizardSuccess(message: string): void {\n console.log(chalk.green(' ' + CHECK + ' ' + message));\n}\n\nexport function wizardError(message: string): void {\n console.log(chalk.red(' ' + message));\n}\n\nexport function wizardBlank(): void {\n console.log('');\n}\n\n// ── Prompt: ask a readline question ──────────────────────────────────\n\nfunction ask(rl: ReadlineInterface, question: string): Promise<string> {\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n resolve(answer.trim());\n });\n });\n}\n\n/**\n * Like `ask`, but listens for ESC key during input.\n * Returns `undefined` if ESC is pressed, otherwise the trimmed answer.\n *\n * Implementation: briefly enters raw mode to intercept keystrokes,\n * collecting characters manually and watching for ESC.\n */\nfunction askWithEsc(rl: ReadlineInterface, prompt: string): Promise<string | undefined> {\n process.stdout.write(prompt);\n\n const releaseRaw = acquireRawMode(rl);\n const chars: string[] = [];\n\n return new Promise((resolve) => {\n const read = (): void => {\n const onData = (buf: Buffer): void => {\n process.stdin.removeListener('data', onData);\n const s = buf.toString('utf8');\n\n // Ctrl+C — exit\n if (s === '\\x03') {\n process.stdout.write('\\n');\n releaseRaw();\n process.exit(0);\n }\n\n // ESC (bare escape, not part of an escape sequence) — cancel\n if (s === '\\x1B') {\n process.stdout.write('\\n');\n releaseRaw();\n resolve(undefined);\n return;\n }\n\n // Enter — submit\n if (s === '\\r' || s === '\\n') {\n process.stdout.write('\\n');\n releaseRaw();\n resolve(chars.join('').trim());\n return;\n }\n\n // Backspace (0x7F) or Ctrl+H (0x08)\n if (s === '\\x7F' || s === '\\x08') {\n if (chars.length > 0) {\n chars.pop();\n process.stdout.write('\\b \\b');\n }\n read();\n return;\n }\n\n // Ignore escape sequences (arrows, etc.)\n if (s.startsWith('\\x1B')) {\n read();\n return;\n }\n\n // Regular printable character(s)\n for (const ch of s) {\n if (ch.charCodeAt(0) >= 32) {\n chars.push(ch);\n process.stdout.write(ch);\n }\n }\n read();\n };\n process.stdin.on('data', onData);\n };\n read();\n });\n}\n\n// ── Raw-mode keypress reader ─────────────────────────────────────────\n\nconst HIDE_CURSOR = '\\x1B[?25l';\nconst SHOW_CURSOR = '\\x1B[?25h';\n\n/**\n * Parsed keypress result from raw stdin data.\n */\ninterface KeyPress {\n name: 'up' | 'down' | 'left' | 'right' | 'enter' | 'escape' | 'ctrlc' | 'unknown';\n raw: Buffer;\n}\n\nfunction parseKey(buf: Buffer): KeyPress {\n const s = buf.toString('utf8');\n\n // Ctrl+C\n if (s === '\\x03') return { name: 'ctrlc', raw: buf };\n\n // Enter (CR or LF)\n if (s === '\\r' || s === '\\n') return { name: 'enter', raw: buf };\n\n // Escape sequences: \\x1B[A, \\x1B[B, etc.\n if (s.startsWith('\\x1B[')) {\n const code = s[2];\n if (code === 'A') return { name: 'up', raw: buf };\n if (code === 'B') return { name: 'down', raw: buf };\n if (code === 'C') return { name: 'right', raw: buf };\n if (code === 'D') return { name: 'left', raw: buf };\n return { name: 'unknown', raw: buf };\n }\n\n // Bare escape (not followed by [)\n if (s === '\\x1B') return { name: 'escape', raw: buf };\n\n // Vim-style keys\n if (s === 'j') return { name: 'down', raw: buf };\n if (s === 'k') return { name: 'up', raw: buf };\n if (s === 'q') return { name: 'escape', raw: buf };\n\n return { name: 'unknown', raw: buf };\n}\n\n/**\n * Wait for a single keypress in raw mode.\n * Assumes stdin is already in raw mode.\n */\nfunction readKey(): Promise<KeyPress> {\n return new Promise((resolve) => {\n const onData = (buf: Buffer): void => {\n process.stdin.removeListener('data', onData);\n resolve(parseKey(buf));\n };\n process.stdin.on('data', onData);\n });\n}\n\n/**\n * Acquire raw mode from readline, returning a cleanup function.\n * Pauses readline, enables raw mode, resumes stdin flow.\n */\nfunction acquireRawMode(rl: ReadlineInterface): () => void {\n rl.pause();\n if (typeof process.stdin.setRawMode === 'function') {\n process.stdin.setRawMode(true);\n }\n process.stdin.resume();\n\n return () => {\n // Restore raw mode to true (not false!) because readline expects raw mode\n // to stay on for the lifetime of the terminal interface. Setting it to\n // false would break keypress event delivery, which in turn breaks the\n // inline slash-command autocomplete.\n process.stdin.pause();\n rl.resume();\n };\n}\n\n// ── ANSI rendering helpers ───────────────────────────────────────────\n\n/**\n * Move cursor up N lines and clear each line, then re-render.\n */\nfunction clearLines(count: number): void {\n for (let i = 0; i < count; i++) {\n // Move up one line, clear it\n process.stdout.write('\\x1B[1A\\x1B[2K');\n }\n}\n\n// ── Select: arrow-key list ──────────────────────────────────────────\n\nexport interface SelectOption<T = string> {\n label: string;\n value: T;\n description?: string;\n hint?: string;\n disabled?: boolean;\n}\n\nexport interface SelectConfig<T = string> {\n title: string;\n items?: SelectOption<T>[];\n options?: SelectOption<T>[]; // alias — both work\n hint?: string;\n cancelLabel?: string; // e.g. \"Back\" or \"Cancel\" — added as last option\n activeIndex?: number; // highlight an existing selection\n}\n\ninterface FlatEntry<T> {\n kind: 'option';\n option: SelectOption<T>;\n flatIndex: number; // index into original option array\n}\n\ninterface CancelEntry {\n kind: 'cancel';\n label: string;\n}\n\ntype ListEntry<T> = FlatEntry<T> | CancelEntry;\n\n/**\n * Render the select list to stdout and return the number of lines written.\n */\nfunction renderSelectList<T>(\n entries: ListEntry<T>[],\n cursorIdx: number,\n activeIndex?: number,\n): number {\n let lines = 0;\n\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n const highlighted = i === cursorIdx;\n\n if (entry.kind === 'cancel') {\n const prefix = highlighted ? chalk.cyan(' \\u276f ') : ' ';\n const label = highlighted ? chalk.white(entry.label) : chalk.dim(entry.label);\n process.stdout.write(prefix + label + '\\n');\n lines++;\n } else {\n const opt = entry.option;\n const prefix = highlighted ? chalk.cyan(' \\u276f ') : ' ';\n const activeMark = entry.flatIndex === activeIndex ? chalk.green(' *') : '';\n\n if (opt.disabled) {\n const label = chalk.dim(opt.label);\n const desc = opt.description ? chalk.dim(` \\u2014 ${opt.description}`) : '';\n const hintStr = opt.hint ? chalk.dim(` ${opt.hint}`) : '';\n const tag = chalk.dim.red(' (unavailable)');\n process.stdout.write(prefix + label + desc + hintStr + tag + '\\n');\n } else if (highlighted) {\n const label = chalk.bold.white(opt.label);\n const desc = opt.description ? chalk.dim(` \\u2014 ${opt.description}`) : '';\n const hintStr = opt.hint ? chalk.dim(` ${opt.hint}`) : '';\n process.stdout.write(prefix + label + activeMark + desc + hintStr + '\\n');\n } else {\n const label = chalk.white(opt.label);\n const desc = opt.description ? chalk.dim(` \\u2014 ${opt.description}`) : '';\n const hintStr = opt.hint ? chalk.dim(` ${opt.hint}`) : '';\n process.stdout.write(prefix + label + activeMark + desc + hintStr + '\\n');\n }\n lines++;\n }\n }\n\n return lines;\n}\n\n/**\n * Find the next selectable index in the given direction.\n * Skips disabled items. Wraps around.\n */\nfunction findNextSelectable<T>(\n entries: ListEntry<T>[],\n current: number,\n direction: 1 | -1,\n): number {\n const len = entries.length;\n let next = current;\n\n for (let step = 0; step < len; step++) {\n next = (next + direction + len) % len;\n const entry = entries[next];\n if (entry.kind === 'cancel') return next;\n if (!entry.option.disabled) return next;\n }\n\n return current; // all disabled — stay put\n}\n\n/**\n * Shows a list with arrow-key navigation. ❯ cursor highlights the current item.\n * Returns the value of the chosen option, or `undefined` if cancelled/escaped.\n */\nexport async function wizardSelect<T = string>(\n rl: ReadlineInterface,\n config: SelectConfig<T>,\n): Promise<T | undefined> {\n const { title, cancelLabel = 'Cancel', activeIndex, hint } = config;\n const allOptions = config.items ?? config.options ?? [];\n\n wizardSection(title);\n if (hint) {\n console.log(chalk.dim(' ' + hint));\n }\n console.log('');\n\n // Build flat entry list\n const entries: ListEntry<T>[] = allOptions.map((opt, i) => ({\n kind: 'option' as const,\n option: opt,\n flatIndex: i,\n }));\n entries.push({ kind: 'cancel', label: cancelLabel });\n\n // Find initial cursor position\n let cursorIdx: number;\n if (activeIndex !== undefined && activeIndex >= 0 && activeIndex < allOptions.length && !allOptions[activeIndex].disabled) {\n cursorIdx = activeIndex;\n } else {\n // First selectable entry\n cursorIdx = findNextSelectable(entries, entries.length - 1, 1);\n }\n\n const releaseRaw = acquireRawMode(rl);\n process.stdout.write(HIDE_CURSOR);\n\n let renderedLines = renderSelectList(entries, cursorIdx, activeIndex);\n\n try {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const key = await readKey();\n\n if (key.name === 'ctrlc') {\n // Clean up and exit process\n process.stdout.write(SHOW_CURSOR);\n releaseRaw();\n process.exit(0);\n }\n\n if (key.name === 'escape') {\n clearLines(renderedLines);\n process.stdout.write(` ${chalk.dim(cancelLabel)}\\n`);\n process.stdout.write(SHOW_CURSOR);\n releaseRaw();\n return undefined;\n }\n\n if (key.name === 'enter') {\n const selected = entries[cursorIdx];\n clearLines(renderedLines);\n\n if (selected.kind === 'cancel') {\n process.stdout.write(` ${chalk.dim(cancelLabel)}\\n`);\n process.stdout.write(SHOW_CURSOR);\n releaseRaw();\n return undefined;\n }\n\n process.stdout.write(` ${CHECK} ${chalk.white(selected.option.label)}\\n`);\n process.stdout.write(SHOW_CURSOR);\n releaseRaw();\n return selected.option.value;\n }\n\n if (key.name === 'up') {\n cursorIdx = findNextSelectable(entries, cursorIdx, -1);\n clearLines(renderedLines);\n renderedLines = renderSelectList(entries, cursorIdx, activeIndex);\n } else if (key.name === 'down') {\n cursorIdx = findNextSelectable(entries, cursorIdx, 1);\n clearLines(renderedLines);\n renderedLines = renderSelectList(entries, cursorIdx, activeIndex);\n }\n }\n } catch {\n process.stdout.write(SHOW_CURSOR);\n releaseRaw();\n return undefined;\n }\n}\n\n// ── Grouped select: options organized under headings ─────────────────\n\nexport interface SelectGroup<T = string> {\n heading: string;\n badge?: string;\n options: SelectOption<T>[];\n}\n\nexport interface GroupedSelectConfig<T = string> {\n title: string;\n groups: SelectGroup<T>[];\n cancelLabel?: string;\n activeValue?: T;\n}\n\ninterface GroupHeadingEntry {\n kind: 'heading';\n heading: string;\n badge?: string;\n}\n\ntype GroupedListEntry<T> = FlatEntry<T> | CancelEntry | GroupHeadingEntry;\n\n/**\n * Render the grouped list to stdout and return the number of lines written.\n */\nfunction renderGroupedList<T>(\n entries: GroupedListEntry<T>[],\n cursorIdx: number,\n activeValue?: T,\n): number {\n let lines = 0;\n\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n const highlighted = i === cursorIdx;\n\n if (entry.kind === 'heading') {\n const badge = entry.badge ? ` ${entry.badge}` : '';\n process.stdout.write(chalk.bold(' ' + entry.heading + badge) + '\\n');\n lines++;\n } else if (entry.kind === 'cancel') {\n const prefix = highlighted ? chalk.cyan(' \\u276f ') : ' ';\n const label = highlighted ? chalk.white(entry.label) : chalk.dim(entry.label);\n process.stdout.write(prefix + label + '\\n');\n lines++;\n } else {\n const opt = entry.option;\n const prefix = highlighted ? chalk.cyan(' \\u276f ') : ' ';\n const isActive = activeValue !== undefined && opt.value === activeValue;\n const activeMark = isActive ? chalk.green(' *') : '';\n\n if (opt.disabled) {\n const label = chalk.dim(opt.label);\n const desc = opt.description ? chalk.dim(` \\u2014 ${opt.description}`) : '';\n const hintStr = opt.hint ? chalk.dim(` ${opt.hint}`) : '';\n const tag = chalk.dim.red(' (unavailable)');\n process.stdout.write(prefix + label + desc + hintStr + tag + '\\n');\n } else if (highlighted) {\n const label = chalk.bold.white(opt.label);\n const desc = opt.description ? chalk.dim(` \\u2014 ${opt.description}`) : '';\n const hintStr = opt.hint ? chalk.dim(` ${opt.hint}`) : '';\n process.stdout.write(prefix + label + activeMark + desc + hintStr + '\\n');\n } else {\n const label = chalk.white(opt.label);\n const desc = opt.description ? chalk.dim(` \\u2014 ${opt.description}`) : '';\n const hintStr = opt.hint ? chalk.dim(` ${opt.hint}`) : '';\n process.stdout.write(prefix + label + activeMark + desc + hintStr + '\\n');\n }\n lines++;\n }\n }\n\n return lines;\n}\n\n/**\n * Find next selectable index, skipping headings and disabled options.\n */\nfunction findNextGroupSelectable<T>(\n entries: GroupedListEntry<T>[],\n current: number,\n direction: 1 | -1,\n): number {\n const len = entries.length;\n let next = current;\n\n for (let step = 0; step < len; step++) {\n next = (next + direction + len) % len;\n const entry = entries[next];\n if (entry.kind === 'heading') continue;\n if (entry.kind === 'cancel') return next;\n if (!entry.option.disabled) return next;\n }\n\n return current;\n}\n\n/**\n * Shows options grouped under headings with arrow-key navigation.\n * Returns the value of the chosen option, or `undefined` if cancelled.\n */\nexport async function wizardGroupedSelect<T = string>(\n rl: ReadlineInterface,\n config: GroupedSelectConfig<T>,\n): Promise<T | undefined> {\n const { title, groups, cancelLabel = 'Cancel', activeValue } = config;\n\n wizardSection(title);\n\n // Build flat entry list with headings\n const entries: GroupedListEntry<T>[] = [];\n let flatIdx = 0;\n\n for (const group of groups) {\n entries.push({ kind: 'heading', heading: group.heading, badge: group.badge });\n for (const opt of group.options) {\n entries.push({ kind: 'option', option: opt, flatIndex: flatIdx++ });\n }\n }\n\n entries.push({ kind: 'cancel', label: cancelLabel });\n\n console.log('');\n\n // Find initial cursor: prefer activeValue, else first selectable\n let cursorIdx = -1;\n if (activeValue !== undefined) {\n for (let i = 0; i < entries.length; i++) {\n const e = entries[i];\n if (e.kind === 'option' && !e.option.disabled && e.option.value === activeValue) {\n cursorIdx = i;\n break;\n }\n }\n }\n if (cursorIdx < 0) {\n cursorIdx = findNextGroupSelectable(entries, entries.length - 1, 1);\n }\n\n const releaseRaw = acquireRawMode(rl);\n process.stdout.write(HIDE_CURSOR);\n\n let renderedLines = renderGroupedList(entries, cursorIdx, activeValue);\n\n try {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const key = await readKey();\n\n if (key.name === 'ctrlc') {\n process.stdout.write(SHOW_CURSOR);\n releaseRaw();\n process.exit(0);\n }\n\n if (key.name === 'escape') {\n clearLines(renderedLines);\n process.stdout.write(` ${chalk.dim(cancelLabel)}\\n`);\n process.stdout.write(SHOW_CURSOR);\n releaseRaw();\n return undefined;\n }\n\n if (key.name === 'enter') {\n const selected = entries[cursorIdx];\n clearLines(renderedLines);\n\n if (selected.kind === 'cancel') {\n process.stdout.write(` ${chalk.dim(cancelLabel)}\\n`);\n process.stdout.write(SHOW_CURSOR);\n releaseRaw();\n return undefined;\n }\n\n if (selected.kind === 'option') {\n process.stdout.write(` ${CHECK} ${chalk.white(selected.option.label)}\\n`);\n process.stdout.write(SHOW_CURSOR);\n releaseRaw();\n return selected.option.value;\n }\n }\n\n if (key.name === 'up') {\n cursorIdx = findNextGroupSelectable(entries, cursorIdx, -1);\n clearLines(renderedLines);\n renderedLines = renderGroupedList(entries, cursorIdx, activeValue);\n } else if (key.name === 'down') {\n cursorIdx = findNextGroupSelectable(entries, cursorIdx, 1);\n clearLines(renderedLines);\n renderedLines = renderGroupedList(entries, cursorIdx, activeValue);\n }\n }\n } catch {\n process.stdout.write(SHOW_CURSOR);\n releaseRaw();\n return undefined;\n }\n}\n\n// ── Confirm: yes/no prompt ───────────────────────────────────────────\n\nexport async function wizardConfirm(\n rl: ReadlineInterface,\n messageOrConfig: string | { message: string; default?: boolean },\n defaultValue?: boolean,\n): Promise<boolean | undefined> {\n let message: string;\n let defVal: boolean;\n\n if (typeof messageOrConfig === 'string') {\n message = messageOrConfig;\n defVal = defaultValue ?? false;\n } else {\n message = messageOrConfig.message;\n defVal = messageOrConfig.default ?? false;\n }\n\n const hint = defVal ? chalk.dim(' (Y/n)') : chalk.dim(' (y/N)');\n const answer = await askWithEsc(rl, ` ${PROMPT_CHAR}${message}${hint} `);\n\n // ESC pressed — return undefined to signal \"go back\"\n if (answer === undefined) {\n console.log(` ${chalk.dim('(cancelled)')}`);\n return undefined;\n }\n\n const result = !answer ? defVal : answer.toLowerCase().startsWith('y');\n\n // Show feedback\n console.log(` ${CHECK} ${chalk.white(result ? 'Yes' : 'No')}`);\n return result;\n}\n\n// ── Text input with label ────────────────────────────────────────────\n\nexport interface TextInputConfig {\n label: string;\n placeholder?: string;\n default?: string;\n defaultValue?: string; // alias\n required?: boolean;\n mask?: boolean; // mask display for API keys\n}\n\nexport async function wizardInput(\n rl: ReadlineInterface,\n config: TextInputConfig,\n): Promise<string | undefined> {\n const { label, placeholder, mask, required = false } = config;\n const defaultValue = config.default ?? config.defaultValue;\n\n const parts: string[] = [PROMPT_CHAR, label];\n if (placeholder) parts.push(chalk.dim(` (${placeholder})`));\n if (defaultValue && !mask) parts.push(chalk.dim(` [${defaultValue}]`));\n parts.push(': ');\n\n if (mask) {\n // Masked input: use raw mode to capture keystrokes and echo mask chars\n // instead of the actual characters, preventing plaintext key leakage.\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const value = await readMaskedInput(rl, ' ' + parts.join(''));\n\n // ESC pressed — return undefined to signal \"go back\"\n if (value === undefined) {\n console.log(` ${chalk.dim('(cancelled)')}`);\n return undefined;\n }\n\n if (required && !value) {\n console.log(chalk.dim(' This field is required.'));\n continue;\n }\n\n // Show masked confirmation\n if (value) {\n const masked = '\\u2022'.repeat(Math.min(value.length, 20));\n console.log(` ${CHECK} ${chalk.white(label)}: ${chalk.dim(masked)}`);\n }\n\n return value;\n }\n }\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const answer = await askWithEsc(rl, ' ' + parts.join(''));\n\n // ESC pressed — return undefined to signal \"go back\"\n if (answer === undefined) {\n console.log(` ${chalk.dim('(cancelled)')}`);\n return undefined;\n }\n\n const value = answer || defaultValue || '';\n\n if (required && !value) {\n console.log(chalk.dim(' This field is required.'));\n continue;\n }\n\n // Show feedback\n if (value) {\n console.log(` ${CHECK} ${chalk.white(value)}`);\n }\n\n return value;\n }\n}\n\n/**\n * Read a line of input in raw mode, echoing mask characters (\\u2022) instead\n * of the actual typed characters. Supports Backspace, Enter, and ESC.\n * Returns the entered string (empty string if user just presses Enter),\n * or `undefined` if ESC is pressed.\n */\nasync function readMaskedInput(\n rl: ReadlineInterface,\n prompt: string,\n): Promise<string | undefined> {\n process.stdout.write(prompt);\n\n const releaseRaw = acquireRawMode(rl);\n const chars: string[] = [];\n\n try {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const buf = await new Promise<Buffer>((resolve) => {\n const onData = (data: Buffer): void => {\n process.stdin.removeListener('data', onData);\n resolve(data);\n };\n process.stdin.on('data', onData);\n });\n\n const s = buf.toString('utf8');\n\n // Ctrl+C — exit\n if (s === '\\x03') {\n process.stdout.write('\\n');\n releaseRaw();\n process.exit(0);\n }\n\n // ESC (bare, not part of an escape sequence) — cancel\n if (s === '\\x1B') {\n process.stdout.write('\\n');\n releaseRaw();\n return undefined;\n }\n\n // Enter — submit\n if (s === '\\r' || s === '\\n') {\n process.stdout.write('\\n');\n releaseRaw();\n return chars.join('');\n }\n\n // Backspace (0x7F) or Ctrl+H (0x08)\n if (s === '\\x7F' || s === '\\x08') {\n if (chars.length > 0) {\n chars.pop();\n // Move cursor back, overwrite with space, move back again\n process.stdout.write('\\b \\b');\n }\n continue;\n }\n\n // Ignore escape sequences (arrows, etc.)\n if (s.startsWith('\\x1B')) {\n continue;\n }\n\n // Regular printable character(s) — accept each character\n for (const ch of s) {\n if (ch.charCodeAt(0) >= 32) {\n chars.push(ch);\n process.stdout.write('\\u2022');\n }\n }\n }\n } catch {\n releaseRaw();\n return chars.join('');\n }\n}\n\n/** @deprecated Use wizardInput instead */\nexport const wizardTextInput = wizardInput;\n\n// ── Key/value display ────────────────────────────────────────────────\n\nexport function wizardKeyValue(key: string, value: string, indent = 2): void {\n const pad = ' '.repeat(indent);\n console.log(`${pad}${chalk.bold(key)}: ${value}`);\n}\n\nexport function wizardBadge(label: string, color: 'green' | 'red' | 'yellow' | 'blue' | 'dim'): string {\n const fn = color === 'dim' ? chalk.dim : chalk[color];\n return fn(`[${label}]`);\n}\n","import type { SlashCommand, CommandContext } from '../types.js';\nimport { getAllProviders, resolveProviderAndModel } from '../providers/index.js';\nimport { formatError } from '../ui/renderer.js';\nimport {\n wizardGroupedSelect,\n wizardSuccess,\n wizardInfo,\n wizardBlank,\n wizardBadge,\n type SelectGroup,\n} from '../ui/wizard.js';\nimport * as config from '../config.js';\nimport chalk from 'chalk';\n\nexport const modelCommand: SlashCommand = {\n name: 'model',\n description: 'Show or switch the current model',\n aliases: ['m'],\n\n async execute(args: string, context: CommandContext) {\n const trimmed = args.trim();\n\n // Power-user shortcut: /model openai:gpt-4o\n if (trimmed && trimmed !== 'list') {\n switchModelDirect(trimmed, context);\n return;\n }\n\n // Interactive wizard\n await wizardModelSelect(context);\n },\n};\n\n// ── Direct switch (power-user) ───────────────────────────────────────\n\nfunction switchModelDirect(input: string, context: CommandContext): void {\n const resolved = resolveProviderAndModel(input);\n if (!resolved) {\n console.log(formatError(`Model \"${input}\" not found. Type /model to browse available models.`));\n return;\n }\n\n if (!resolved.provider.isConfigured()) {\n console.log(formatError(`Provider \"${resolved.provider.displayName}\" is not configured. Set an API key first.`));\n wizardInfo(` Run: /config set providers.${resolved.provider.name}.apiKey <your-key>`);\n return;\n }\n\n context.setModel(resolved.provider.name, resolved.model);\n config.setDefaultModel(resolved.provider.name, resolved.model);\n wizardSuccess(`Switched to ${resolved.provider.displayName} / ${resolved.model}`);\n}\n\n// ── Interactive model selection ──────────────────────────────────────\n\nasync function wizardModelSelect(context: CommandContext): Promise<void> {\n const { rl, chat } = context;\n const providers = getAllProviders();\n const currentId = `${chat.currentProvider}:${chat.currentModel}`;\n\n const groups: SelectGroup<string>[] = providers.map((provider) => {\n const configured = provider.isConfigured();\n const badge = configured\n ? wizardBadge('configured', 'green')\n : wizardBadge('no API key', 'red');\n\n return {\n heading: provider.displayName,\n badge,\n options: provider.listModels().map((model) => {\n const ctx = model.contextWindow\n ? `${(model.contextWindow / 1000).toFixed(0)}k ctx`\n : '';\n return {\n label: model.name,\n value: `${provider.name}:${model.id}`,\n hint: ctx ? `${model.description} (${ctx})` : model.description,\n disabled: !configured,\n };\n }),\n };\n });\n\n wizardBlank();\n wizardInfo(`Current: ${chalk.white(currentId)}`);\n\n const choice = await wizardGroupedSelect(rl, {\n title: 'Select a Model',\n groups,\n cancelLabel: 'Keep current model',\n activeValue: currentId,\n });\n\n if (!choice) {\n wizardInfo('No changes.');\n wizardBlank();\n return;\n }\n\n const [providerName, ...modelParts] = choice.split(':');\n const modelId = modelParts.join(':'); // handle model IDs that might contain colons\n\n context.setModel(providerName, modelId);\n config.setDefaultModel(providerName, modelId);\n wizardSuccess(`Switched to ${providerName}:${modelId}`);\n wizardBlank();\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { AgentDefinition } from './types.js';\n\n// ── Name validation ──────────────────────────────────────────────────\n\nconst AGENT_NAME_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/;\n\n/**\n * Validates an agent name. Returns an error message if invalid, or\n * `undefined` if the name is valid.\n *\n * Rules:\n * - 1-64 characters\n * - Letters, numbers, hyphens, underscores only\n * - Must start with a letter or number\n * - No path separators or special characters (prevents path traversal)\n */\nexport function validateAgentName(name: string): string | undefined {\n if (!name) {\n return 'Agent name cannot be empty.';\n }\n\n if (name.includes('/') || name.includes('\\\\') || name.includes('..')) {\n return 'Agent name contains illegal characters (path separators or \"..\" are not allowed).';\n }\n\n if (!AGENT_NAME_PATTERN.test(name)) {\n return 'Agent name must be 1-64 characters: letters, numbers, hyphens, underscores. Must start with a letter or number.';\n }\n\n return undefined;\n}\n\n// ── Directory helpers ────────────────────────────────────────────────\n\nfunction getAgentsDir(): string {\n const dir = path.resolve(process.cwd(), 'agents');\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n return dir;\n}\n\n/**\n * Returns the file path for an agent, with path traversal protection.\n * Throws if the resolved path escapes the agents directory.\n */\nfunction agentFilePath(name: string): string {\n const error = validateAgentName(name);\n if (error) {\n throw new Error(error);\n }\n\n const dir = getAgentsDir();\n const filePath = path.join(dir, `${name}.json`);\n\n // Belt-and-suspenders: verify the resolved path is inside the agents dir\n const resolved = path.resolve(filePath);\n const resolvedDir = path.resolve(dir);\n if (!resolved.startsWith(resolvedDir + path.sep) && resolved !== resolvedDir) {\n throw new Error('Invalid agent name: path traversal detected.');\n }\n\n return filePath;\n}\n\n// ── CRUD operations ──────────────────────────────────────────────────\n\nexport function createAgent(agent: AgentDefinition): void {\n const nameError = validateAgentName(agent.name);\n if (nameError) {\n throw new Error(nameError);\n }\n\n const filePath = agentFilePath(agent.name);\n if (fs.existsSync(filePath)) {\n throw new Error(`Agent \"${agent.name}\" already exists.`);\n }\n fs.writeFileSync(filePath, JSON.stringify(agent, null, 2), 'utf-8');\n}\n\nexport function getAgent(name: string): AgentDefinition | undefined {\n try {\n const filePath = agentFilePath(name);\n if (!fs.existsSync(filePath)) {\n return undefined;\n }\n const content = fs.readFileSync(filePath, 'utf-8');\n return JSON.parse(content) as AgentDefinition;\n } catch {\n return undefined;\n }\n}\n\nexport function updateAgent(name: string, updates: Partial<AgentDefinition>): void {\n const existing = getAgent(name);\n if (!existing) {\n throw new Error(`Agent \"${name}\" not found.`);\n }\n const updated = { ...existing, ...updates, name }; // name cannot change\n fs.writeFileSync(agentFilePath(name), JSON.stringify(updated, null, 2), 'utf-8');\n}\n\nexport function deleteAgent(name: string): boolean {\n try {\n const filePath = agentFilePath(name);\n if (!fs.existsSync(filePath)) {\n return false;\n }\n fs.unlinkSync(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function listAgents(): AgentDefinition[] {\n const dir = getAgentsDir();\n const files = fs.readdirSync(dir).filter((f) => f.endsWith('.json'));\n const agents: AgentDefinition[] = [];\n\n for (const file of files) {\n try {\n const content = fs.readFileSync(path.join(dir, file), 'utf-8');\n agents.push(JSON.parse(content) as AgentDefinition);\n } catch {\n // Skip malformed agent files\n }\n }\n\n return agents;\n}\n","import type { ModelMessage } from 'ai';\nimport type { AgentDefinition, AgentRunResult } from './types.js';\nimport type { StreamCallbacks } from '../types.js';\nimport { getProvider } from '../providers/index.js';\nimport { getAgent } from './manager.js';\n\nexport async function runAgent(\n agentName: string,\n prompt: string,\n callbacks: StreamCallbacks,\n): Promise<AgentRunResult> {\n const agent = getAgent(agentName);\n if (!agent) {\n throw new Error(`Agent \"${agentName}\" not found.`);\n }\n\n return executeAgent(agent, prompt, callbacks);\n}\n\nasync function executeAgent(\n agent: AgentDefinition,\n prompt: string,\n callbacks: StreamCallbacks,\n): Promise<AgentRunResult> {\n const provider = getProvider(agent.provider);\n if (!provider) {\n return {\n agentName: agent.name,\n response: '',\n provider: agent.provider,\n model: agent.model,\n error: `Provider \"${agent.provider}\" not found.`,\n };\n }\n\n if (!provider.isConfigured()) {\n return {\n agentName: agent.name,\n response: '',\n provider: agent.provider,\n model: agent.model,\n error: `Provider \"${agent.provider}\" is not configured. Set an API key first.`,\n };\n }\n\n const messages: ModelMessage[] = [{ role: 'user', content: prompt }];\n\n try {\n const chatResult = await provider.chat(messages, agent.model, {\n temperature: agent.temperature,\n systemPrompt: agent.systemPrompt,\n }, callbacks);\n\n return {\n agentName: agent.name,\n response: chatResult.text,\n provider: agent.provider,\n model: agent.model,\n };\n } catch (error) {\n return {\n agentName: agent.name,\n response: '',\n provider: agent.provider,\n model: agent.model,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nexport async function runAgentsParallel(\n agentNames: string[],\n prompt: string,\n): Promise<AgentRunResult[]> {\n const promises = agentNames.map(async (name) => {\n const agent = getAgent(name);\n if (!agent) {\n return {\n agentName: name,\n response: '',\n provider: 'unknown',\n model: 'unknown',\n error: `Agent \"${name}\" not found.`,\n } satisfies AgentRunResult;\n }\n\n // For parallel execution, collect output instead of streaming.\n // NOTE: We must NOT throw inside onError — the throw gets caught by\n // the provider's catch block which calls onError again, causing\n // infinite recursion. Instead, collect the error and surface it\n // after executeAgent returns.\n let collectedError: Error | null = null;\n const callbacks: StreamCallbacks = {\n onToken() {\n // no-op for parallel — response is captured in the result\n },\n onComplete() {\n // no-op — we rely on the returned AgentRunResult\n },\n onError(error: Error) {\n collectedError = error;\n },\n };\n\n const result = await executeAgent(agent, prompt, callbacks);\n\n // If the provider called onError, surface it in the result\n if (collectedError && !result.error) {\n result.error = (collectedError as Error).message;\n }\n\n return result;\n });\n\n const results = await Promise.allSettled(promises);\n\n return results.map((result, index) => {\n if (result.status === 'fulfilled') {\n return result.value;\n }\n return {\n agentName: agentNames[index],\n response: '',\n provider: 'unknown',\n model: 'unknown',\n error: result.reason instanceof Error ? result.reason.message : String(result.reason),\n };\n });\n}\n","import ora, { type Ora, type Spinner } from 'ora';\n\nlet activeSpinner: Ora | null = null;\n\n/**\n * Fun, personality-rich phrases that replace the generic \"Thinking...\" text.\n * A random one is picked each time the spinner starts with default text.\n */\nconst thinkingPhrases: string[] = [\n 'Pondering the universe...',\n 'Consulting the oracle...',\n 'Brewing ideas...',\n 'Warming up neurons...',\n 'Summoning creativity...',\n 'Crunching thoughts...',\n 'Channeling genius...',\n 'Loading brilliance...',\n 'Assembling wisdom...',\n 'Thinking really hard...',\n 'Asking the magic 8-ball...',\n 'Doing brain stuff...',\n 'Consulting my inner philosopher...',\n 'Untangling the cosmic web...',\n 'Spinning up the hamster wheel...',\n 'Rummaging through neurons...',\n 'Consulting ancient scrolls...',\n 'Dusting off the thinking cap...',\n 'Entering the thought dimension...',\n 'Percolating ideas...',\n 'Mining for insights...',\n 'Tickling the grey matter...',\n 'Firing up synapses...',\n 'Diving into the deep end...',\n 'Shaking the idea tree...',\n 'Summoning the muse...',\n 'Peering into the void...',\n 'Communing with electrons...',\n 'Wrangling stray thoughts...',\n 'Polishing the crystal ball...',\n 'Tuning the frequency...',\n 'Calibrating brain waves...',\n 'Consulting the hive mind...',\n 'Unfolding possibilities...',\n 'Sifting through dimensions...',\n 'Reticulating splines...',\n 'Gazing into the matrix...',\n 'Aligning the stars...',\n 'Decoding the cosmos...',\n 'Whispering to the algorithm...',\n 'Weaving a tapestry of thought...',\n 'Brewing a fresh batch of logic...',\n 'Contemplating existence...',\n 'Engaging turbo mode...',\n 'Asking the rubber duck...',\n 'Invoking deep thought...',\n 'Parsing the ether...',\n 'Consulting stack overflow...',\n 'Running on caffeine...',\n 'Flexing mental muscles...',\n 'Juggling possibilities...',\n 'Herding electric sheep...',\n 'Counting backwards from infinity...',\n 'Opening the third eye...',\n 'Vibing with the data...',\n 'Composing a symphony of bits...',\n 'Searching for the answer...',\n 'Warming up the flux capacitor...',\n 'Defragmenting thoughts...',\n 'Querying the universe...',\n 'Downloading inspiration...',\n 'Compiling brilliance...',\n 'Feeding the thought engine...',\n 'Stirring the imagination...',\n 'Pinging the mothership...',\n];\n\n/**\n * Curated set of visually appealing Unicode spinner frame sets.\n * A random one is picked each time the spinner starts.\n */\nconst spinnerSets: Spinner[] = [\n { interval: 120, frames: ['🌑', '🌒', '🌓', '🌔', '🌕', '🌖', '🌗', '🌘'] },\n { interval: 180, frames: ['🌍', '🌎', '🌏'] },\n { interval: 140, frames: ['🕐', '🕑', '🕒', '🕓', '🕔', '🕕', '🕖', '🕗', '🕘', '🕙', '🕚', '🕛'] },\n { interval: 100, frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'] },\n { interval: 120, frames: ['◐', '◓', '◑', '◒'] },\n { interval: 100, frames: ['▖', '▘', '▝', '▗'] },\n { interval: 150, frames: ['✦', '✧', '✦', '✧', '★', '☆'] },\n { interval: 120, frames: ['◰', '◳', '◲', '◱'] },\n { interval: 100, frames: ['⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷'] },\n { interval: 160, frames: ['☀️ ', '🌤️ ', '⛅ ', '🌥️ ', '☁️ ', '🌥️ ', '⛅ ', '🌤️ '] },\n { interval: 100, frames: ['∙∙∙', '●∙∙', '∙●∙', '∙∙●', '∙∙∙'] },\n { interval: 150, frames: ['🔸', '🔶', '🟠', '🔶', '🔸'] },\n { interval: 120, frames: ['⬡', '⬢', '⬡', '⬢'] },\n { interval: 100, frames: ['░', '▒', '▓', '█', '▓', '▒'] },\n];\n\n/**\n * Pick a random element from an array.\n */\nfunction pickRandom<T>(arr: T[]): T {\n return arr[Math.floor(Math.random() * arr.length)];\n}\n\n/**\n * Returns a random fun thinking phrase.\n */\nexport function getRandomThinkingText(): string {\n return pickRandom(thinkingPhrases);\n}\n\n/**\n * Returns a random spinner frame set.\n */\nexport function getRandomSpinner(): Spinner {\n return pickRandom(spinnerSets);\n}\n\nexport function startSpinner(text: string = 'Thinking...'): Ora {\n stopSpinner();\n activeSpinner = ora({ text, spinner: getRandomSpinner(), discardStdin: false }).start();\n return activeSpinner;\n}\n\nexport function stopSpinner(): void {\n if (activeSpinner) {\n activeSpinner.stop();\n activeSpinner = null;\n }\n}\n\nexport function updateSpinner(text: string): void {\n if (activeSpinner) {\n activeSpinner.text = text;\n }\n}\n","import type { SlashCommand, CommandContext } from '../types.js';\nimport { createAgent, getAgent, listAgents, deleteAgent, validateAgentName } from '../agents/manager.js';\nimport { runAgent, runAgentsParallel } from '../agents/runner.js';\nimport type { AgentDefinition } from '../agents/types.js';\nimport { formatError, formatAssistantLabel, renderMarkdown } from '../ui/renderer.js';\nimport { startSpinner, stopSpinner } from '../ui/spinner.js';\nimport {\n wizardHeader,\n wizardSelect,\n wizardInput,\n wizardConfirm,\n wizardSuccess,\n wizardError,\n wizardInfo,\n wizardBlank,\n wizardKeyValue,\n wizardDivider,\n wizardBadge,\n} from '../ui/wizard.js';\nimport { getAllProviders } from '../providers/index.js';\nimport chalk from 'chalk';\n\nexport const agentCommand: SlashCommand = {\n name: 'agent',\n description: 'Manage and run agents',\n aliases: ['a'],\n\n async execute(args: string, context: CommandContext) {\n const parts = args.trim().split(/\\s+/);\n const subcommand = parts[0] || '';\n const rest = parts.slice(1).join(' ');\n\n // Power-user direct commands\n switch (subcommand) {\n case 'create':\n if (rest) {\n await handleCreateDirect(rest, context);\n } else {\n await handleCreateWizard(context);\n }\n return;\n case 'list':\n case 'ls':\n handleList();\n return;\n case 'view':\n case 'show':\n if (rest) {\n handleView(rest);\n } else {\n await handleViewWizard(context);\n }\n return;\n case 'run':\n if (rest) {\n await handleRunDirect(rest);\n } else {\n await handleRunWizard(context);\n }\n return;\n case 'run-parallel':\n await handleRunParallel(rest);\n return;\n case 'delete':\n case 'rm':\n if (rest) {\n await handleDeleteDirect(rest, context);\n } else {\n await handleDeleteWizard(context);\n }\n return;\n }\n\n // No args → launch wizard menu\n await wizardMenu(context);\n },\n};\n\n// ── Wizard menu ──────────────────────────────────────────────────────\n\nasync function wizardMenu(context: CommandContext): Promise<void> {\n const { rl } = context;\n const agents = listAgents();\n const agentCount = agents.length;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n wizardHeader('Agent Manager');\n\n const choice = await wizardSelect(rl, {\n title: 'What would you like to do?',\n options: [\n { label: 'Create a new agent', value: 'create', hint: 'guided setup' },\n { label: 'List agents', value: 'list', hint: `${agentCount} agent${agentCount !== 1 ? 's' : ''}` },\n { label: 'View agent details', value: 'view', disabled: agentCount === 0 },\n { label: 'Run an agent', value: 'run', disabled: agentCount === 0 },\n { label: 'Delete an agent', value: 'delete', disabled: agentCount === 0 },\n ],\n cancelLabel: 'Back to chat',\n });\n\n if (!choice) return;\n\n switch (choice) {\n case 'create':\n await handleCreateWizard(context);\n break;\n case 'list':\n handleList();\n break;\n case 'view':\n await handleViewWizard(context);\n break;\n case 'run':\n await handleRunWizard(context);\n break;\n case 'delete':\n await handleDeleteWizard(context);\n break;\n }\n }\n}\n\n// ── Create wizard ────────────────────────────────────────────────────\n\nasync function handleCreateWizard(context: CommandContext): Promise<void> {\n const { rl } = context;\n\n wizardHeader('Create Agent');\n\n // Name\n const name = await wizardInput(rl, {\n label: 'Agent name',\n placeholder: 'letters, numbers, hyphens, underscores',\n required: true,\n });\n\n const nameError = validateAgentName(name);\n if (nameError) {\n wizardError(nameError);\n return;\n }\n\n const existing = getAgent(name);\n if (existing) {\n wizardError(`Agent \"${name}\" already exists.`);\n return;\n }\n\n // Description\n const description = await wizardInput(rl, {\n label: 'Description',\n placeholder: 'what does this agent do?',\n required: true,\n });\n\n // System prompt\n const systemPrompt = await wizardInput(rl, {\n label: 'System prompt',\n placeholder: 'instructions for the AI',\n required: true,\n });\n\n // Provider + Model selection (ESC on model goes back to provider)\n const providers = getAllProviders();\n let providerChoice: string | undefined;\n let modelChoice: string | undefined;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n providerChoice = await wizardSelect(rl, {\n title: 'Select Provider',\n options: providers.map((p) => {\n const configured = p.isConfigured();\n return {\n label: p.displayName,\n value: p.name,\n hint: configured ? wizardBadge('configured', 'green') : wizardBadge('no API key', 'red'),\n };\n }),\n cancelLabel: 'Cancel creation',\n });\n\n if (!providerChoice) {\n wizardInfo('Agent creation cancelled.');\n return;\n }\n\n const provider = providers.find((p) => p.name === providerChoice)!;\n const models = provider.listModels();\n\n modelChoice = await wizardSelect(rl, {\n title: `Select Model (${provider.displayName})`,\n options: models.map((m) => ({\n label: m.name,\n value: m.id,\n hint: m.description,\n })),\n cancelLabel: 'Back',\n });\n\n if (!modelChoice) continue; // ESC → back to provider select\n break;\n }\n\n // Temperature\n const tempStr = await wizardInput(rl, {\n label: 'Temperature',\n placeholder: '0-2',\n default: '0.7',\n });\n const temperature = parseFloat(tempStr) || 0.7;\n\n // Confirm\n wizardBlank();\n wizardDivider();\n console.log(chalk.bold.white(' Review'));\n wizardDivider();\n wizardKeyValue('Name', name);\n wizardKeyValue('Description', description);\n wizardKeyValue('Provider', providerChoice);\n wizardKeyValue('Model', modelChoice);\n wizardKeyValue('Temperature', String(temperature));\n wizardKeyValue('System Prompt', systemPrompt.length > 60 ? systemPrompt.slice(0, 60) + '...' : systemPrompt);\n wizardBlank();\n\n const confirmed = await wizardConfirm(rl, 'Create this agent?', true);\n if (!confirmed) {\n wizardInfo('Agent creation cancelled.');\n return;\n }\n\n const agent: AgentDefinition = {\n name,\n description,\n systemPrompt,\n provider: providerChoice,\n model: modelChoice,\n temperature,\n tools: [],\n };\n\n createAgent(agent);\n wizardSuccess(`Agent \"${name}\" created successfully.`);\n wizardBlank();\n}\n\nasync function handleCreateDirect(name: string, context: CommandContext): Promise<void> {\n const nameError = validateAgentName(name);\n if (nameError) {\n console.log(formatError(nameError));\n return;\n }\n\n const existing = getAgent(name);\n if (existing) {\n console.log(formatError(`Agent \"${name}\" already exists.`));\n return;\n }\n\n // Fall through to wizard with name pre-filled\n const { rl } = context;\n\n const description = await wizardInput(rl, { label: 'Description', required: true });\n const systemPrompt = await wizardInput(rl, { label: 'System prompt', required: true });\n\n // Provider + Model via interactive select (ESC on model → back to provider)\n const providers = getAllProviders();\n let providerChoice: string | undefined;\n let modelChoice: string | undefined;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n providerChoice = await wizardSelect(rl, {\n title: 'Select Provider',\n options: providers.map((p) => ({\n label: p.displayName,\n value: p.name,\n hint: p.isConfigured() ? wizardBadge('configured', 'green') : wizardBadge('no API key', 'red'),\n })),\n cancelLabel: 'Cancel creation',\n });\n\n if (!providerChoice) {\n wizardInfo('Agent creation cancelled.');\n return;\n }\n\n const provider = providers.find((p) => p.name === providerChoice)!;\n modelChoice = await wizardSelect(rl, {\n title: `Select Model (${provider.displayName})`,\n options: provider.listModels().map((m) => ({\n label: m.name,\n value: m.id,\n hint: m.description,\n })),\n cancelLabel: 'Back',\n });\n\n if (!modelChoice) continue; // ESC → back to provider\n break;\n }\n\n const tempStr = await wizardInput(rl, { label: 'Temperature', default: '0.7', placeholder: '0-2' });\n\n const agent: AgentDefinition = {\n name,\n description,\n systemPrompt,\n provider: providerChoice,\n model: modelChoice,\n temperature: parseFloat(tempStr) || 0.7,\n tools: [],\n };\n\n createAgent(agent);\n wizardSuccess(`Agent \"${name}\" created successfully.`);\n}\n\n// ── List ─────────────────────────────────────────────────────────────\n\nfunction handleList(): void {\n const agents = listAgents();\n\n if (agents.length === 0) {\n wizardBlank();\n wizardInfo('No agents found. Use /agent create or /agent to get started.');\n wizardBlank();\n return;\n }\n\n wizardBlank();\n wizardDivider();\n console.log(chalk.bold.white(` Agents (${agents.length})`));\n wizardDivider();\n wizardBlank();\n\n for (const agent of agents) {\n console.log(` ${chalk.bold.cyan(agent.name)} ${chalk.dim('\\u2014')} ${agent.description}`);\n console.log(` ${chalk.dim(`${agent.provider}:${agent.model} | temp: ${agent.temperature}`)}`);\n }\n wizardBlank();\n}\n\n// ── View wizard ──────────────────────────────────────────────────────\n\nasync function handleViewWizard(context: CommandContext): Promise<void> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const agents = listAgents();\n if (agents.length === 0) {\n wizardInfo('No agents found.');\n return;\n }\n\n const choice = await wizardSelect(context.rl, {\n title: 'View Agent Details',\n options: agents.map((a) => ({\n label: a.name,\n value: a.name,\n hint: a.description,\n })),\n cancelLabel: 'Back',\n });\n\n if (!choice) return; // ESC → back to main agent menu\n handleView(choice);\n }\n}\n\nfunction handleView(name: string): void {\n const agent = getAgent(name.trim());\n if (!agent) {\n console.log(formatError(`Agent \"${name}\" not found.`));\n return;\n }\n\n wizardBlank();\n wizardDivider();\n console.log(chalk.bold.white(` Agent: ${agent.name}`));\n wizardDivider();\n wizardKeyValue('Description', agent.description);\n wizardKeyValue('Provider', agent.provider);\n wizardKeyValue('Model', agent.model);\n wizardKeyValue('Temperature', String(agent.temperature));\n wizardKeyValue('System Prompt', '');\n console.log(chalk.dim(' ' + agent.systemPrompt));\n wizardBlank();\n}\n\n// ── Run wizard ───────────────────────────────────────────────────────\n\nasync function handleRunWizard(context: CommandContext): Promise<void> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const agents = listAgents();\n if (agents.length === 0) {\n wizardInfo('No agents found. Create one first with /agent create.');\n return;\n }\n\n const agentName = await wizardSelect(context.rl, {\n title: 'Run Agent',\n options: agents.map((a) => ({\n label: a.name,\n value: a.name,\n hint: `${a.provider}:${a.model}`,\n })),\n cancelLabel: 'Back',\n });\n\n if (!agentName) return; // ESC → back to main agent menu\n\n const prompt = await wizardInput(context.rl, {\n label: 'Prompt',\n placeholder: 'what should the agent do?',\n required: true,\n });\n\n await executeAgentRun(agentName, prompt);\n return; // After running an agent, return to main agent menu\n }\n}\n\nasync function handleRunDirect(args: string): Promise<void> {\n const match = args.match(/^(\\S+)\\s+(.+)$/);\n if (!match) {\n console.log(formatError('Usage: /agent run <name> <prompt>'));\n return;\n }\n\n const [, agentName, prompt] = match;\n await executeAgentRun(agentName, prompt);\n}\n\nasync function executeAgentRun(agentName: string, prompt: string): Promise<void> {\n const spinner = startSpinner(`Running agent \"${agentName}\"...`);\n let firstToken = true;\n\n try {\n const result = await runAgent(agentName, prompt, {\n onToken(token: string) {\n if (firstToken) {\n stopSpinner();\n process.stdout.write(formatAssistantLabel());\n firstToken = false;\n }\n process.stdout.write(token);\n },\n onComplete(_fullText: string) {\n if (firstToken) {\n stopSpinner();\n }\n process.stdout.write('\\n');\n },\n onError(error: Error) {\n stopSpinner();\n console.log(formatError(error.message));\n },\n });\n\n if (result.error) {\n console.log(formatError(result.error));\n }\n } catch (error) {\n stopSpinner();\n console.log(formatError(error instanceof Error ? error.message : String(error)));\n }\n}\n\n// ── Run parallel ─────────────────────────────────────────────────────\n\nasync function handleRunParallel(args: string): Promise<void> {\n const match = args.match(/^(\\S+)\\s+(.+)$/);\n if (!match) {\n console.log(formatError('Usage: /agent run-parallel <name1,name2,...> <prompt>'));\n return;\n }\n\n const [, namesStr, prompt] = match;\n const names = namesStr.split(',').map((n) => n.trim()).filter(Boolean);\n\n if (names.length < 2) {\n console.log(formatError('Provide at least 2 agent names separated by commas.'));\n return;\n }\n\n const spinner = startSpinner(`Running ${names.length} agents in parallel...`);\n\n try {\n const results = await runAgentsParallel(names, prompt);\n stopSpinner();\n\n wizardBlank();\n wizardDivider();\n console.log(chalk.bold.white(' Parallel Agent Results'));\n wizardDivider();\n\n for (const result of results) {\n wizardBlank();\n console.log(chalk.bold.cyan(` --- ${result.agentName} (${result.provider}:${result.model}) ---`));\n\n if (result.error) {\n console.log(formatError(result.error));\n } else {\n console.log(renderMarkdown(result.response));\n }\n }\n } catch (error) {\n stopSpinner();\n console.log(formatError(error instanceof Error ? error.message : String(error)));\n }\n}\n\n// ── Delete wizard ────────────────────────────────────────────────────\n\nasync function handleDeleteWizard(context: CommandContext): Promise<void> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const agents = listAgents();\n if (agents.length === 0) {\n wizardInfo('No agents found.');\n return;\n }\n\n const agentName = await wizardSelect(context.rl, {\n title: 'Delete Agent',\n hint: 'This action cannot be undone.',\n options: agents.map((a) => ({\n label: a.name,\n value: a.name,\n hint: a.description,\n })),\n cancelLabel: 'Back',\n });\n\n if (!agentName) return; // ESC → back to main agent menu\n\n const confirmed = await wizardConfirm(context.rl, `Delete agent \"${agentName}\"?`);\n if (!confirmed) {\n wizardInfo('Cancelled.');\n continue; // Back to agent selection list\n }\n\n const deleted = deleteAgent(agentName);\n if (deleted) {\n wizardSuccess(`Agent \"${agentName}\" deleted.`);\n } else {\n wizardError(`Agent \"${agentName}\" not found.`);\n }\n }\n}\n\nasync function handleDeleteDirect(name: string, context: CommandContext): Promise<void> {\n const agent = getAgent(name.trim());\n if (!agent) {\n console.log(formatError(`Agent \"${name.trim()}\" not found.`));\n return;\n }\n\n const confirmed = await wizardConfirm(context.rl, `Delete agent \"${name.trim()}\"?`);\n if (!confirmed) {\n wizardInfo('Cancelled.');\n return;\n }\n\n const deleted = deleteAgent(name.trim());\n if (deleted) {\n wizardSuccess(`Agent \"${name.trim()}\" deleted.`);\n } else {\n console.log(formatError(`Agent \"${name.trim()}\" not found.`));\n }\n}\n","import type { SlashCommand, CommandContext } from '../types.js';\nimport * as appConfig from '../config.js';\nimport { formatError, formatDim } from '../ui/renderer.js';\nimport {\n wizardHeader,\n wizardSelect,\n wizardInput,\n wizardKeyValue,\n wizardSuccess,\n wizardInfo,\n wizardBlank,\n wizardBadge,\n wizardDivider,\n} from '../ui/wizard.js';\nimport { getAllProviders } from '../providers/index.js';\nimport chalk from 'chalk';\n\nexport const configCommand: SlashCommand = {\n name: 'config',\n description: 'Manage configuration settings',\n aliases: ['cfg'],\n\n async execute(args: string, context: CommandContext) {\n const parts = args.trim().split(/\\s+/);\n const subcommand = parts[0] || '';\n const key = parts[1] || '';\n const value = parts.slice(2).join(' ');\n\n // Power-user direct commands still work\n switch (subcommand) {\n case 'set':\n handleSet(key, value);\n return;\n case 'get':\n handleGet(key);\n return;\n case 'list':\n case 'ls':\n handleList();\n return;\n case 'path':\n console.log(formatDim(`Config file: ${appConfig.getConfigPath()}`));\n return;\n }\n\n // No args or unrecognized subcommand → launch wizard\n await wizardMenu(context);\n },\n};\n\n// ── Wizard menu ──────────────────────────────────────────────────────\n\nasync function wizardMenu(context: CommandContext): Promise<void> {\n const { rl } = context;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n wizardHeader('Configuration');\n\n const choice = await wizardSelect(rl, {\n title: 'What would you like to configure?',\n options: [\n { label: 'Provider API Keys', value: 'apikeys', hint: 'OpenAI, Anthropic, Google' },\n { label: 'Default Model', value: 'model', hint: `currently ${context.chat.currentProvider}:${context.chat.currentModel}` },\n { label: 'Theme Colors', value: 'theme', hint: 'user, assistant, system colors' },\n { label: 'View All Settings', value: 'list' },\n { label: 'Config File Path', value: 'path' },\n ],\n cancelLabel: 'Back to chat',\n });\n\n if (!choice) return;\n\n switch (choice) {\n case 'apikeys':\n await wizardApiKeys(context);\n break;\n case 'model':\n await wizardDefaultModel(context);\n break;\n case 'theme':\n await wizardTheme(context);\n break;\n case 'list':\n handleList();\n break;\n case 'path':\n wizardBlank();\n wizardInfo(`Config file: ${appConfig.getConfigPath()}`);\n wizardBlank();\n break;\n }\n }\n}\n\n// ── API Keys wizard ──────────────────────────────────────────────────\n\nasync function wizardApiKeys(context: CommandContext): Promise<void> {\n const { rl } = context;\n\n const providers = [\n { name: 'openai', display: 'OpenAI', envVar: 'OPENAI_API_KEY' },\n { name: 'anthropic', display: 'Anthropic', envVar: 'ANTHROPIC_API_KEY' },\n { name: 'google', display: 'Google (Gemini)', envVar: 'GOOGLE_API_KEY' },\n ];\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const options = providers.map((p) => {\n const key = appConfig.getApiKey(p.name);\n const status = key\n ? wizardBadge('configured', 'green')\n : wizardBadge('not set', 'red');\n return {\n label: p.display,\n value: p.name,\n hint: status,\n };\n });\n\n const choice = await wizardSelect(rl, {\n title: 'Provider API Keys',\n options,\n cancelLabel: 'Back',\n });\n\n if (!choice) return; // ESC → back to config menu\n\n const provider = providers.find((p) => p.name === choice)!;\n const currentKey = appConfig.getApiKey(provider.name);\n\n if (currentKey) {\n wizardBlank();\n wizardKeyValue('Current key', maskKey(currentKey));\n wizardInfo(`Env var: ${provider.envVar}`);\n wizardBlank();\n }\n\n const newKey = await wizardInput(rl, {\n label: `${provider.display} API key`,\n placeholder: 'paste key or leave blank to skip',\n });\n\n if (newKey === undefined) {\n // ESC → back to provider list\n continue;\n }\n\n if (newKey) {\n appConfig.setApiKey(provider.name, newKey);\n wizardSuccess(`${provider.display} API key saved (${maskKey(newKey)})`);\n } else {\n wizardInfo('Skipped — no changes.');\n }\n wizardBlank();\n }\n}\n\n// ── Default model wizard ─────────────────────────────────────────────\n\nasync function wizardDefaultModel(context: CommandContext): Promise<void> {\n const { rl } = context;\n const allProviders = getAllProviders();\n\n // Outer loop: ESC on model select comes back to provider select\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const providerChoice = await wizardSelect(rl, {\n title: 'Default Model — Select Provider',\n options: allProviders.map((p) => ({\n label: p.displayName,\n value: p.name,\n hint: p.isConfigured() ? wizardBadge('configured', 'green') : wizardBadge('no API key', 'red'),\n })),\n cancelLabel: 'Back',\n });\n\n if (!providerChoice) return; // ESC → back to config menu\n\n const provider = allProviders.find((p) => p.name === providerChoice)!;\n const models = provider.listModels();\n const currentModel = context.chat.currentModel;\n\n const modelChoice = await wizardSelect(rl, {\n title: `Select Model (${provider.displayName})`,\n options: models.map((m) => ({\n label: m.name,\n value: m.id,\n description: m.description,\n hint: m.contextWindow ? `${(m.contextWindow / 1000).toFixed(0)}k ctx` : undefined,\n })),\n activeIndex: models.findIndex((m) => m.id === currentModel),\n cancelLabel: 'Back',\n });\n\n if (!modelChoice) continue; // ESC → back to provider select\n\n appConfig.setDefaultModel(providerChoice, modelChoice);\n context.setModel(providerChoice, modelChoice);\n wizardSuccess(`Default model set to ${providerChoice}:${modelChoice}`);\n wizardBlank();\n return;\n }\n}\n\n// ── Theme wizard ─────────────────────────────────────────────────────\n\nasync function wizardTheme(context: CommandContext): Promise<void> {\n const { rl } = context;\n const theme = appConfig.get('theme');\n const validColors = ['red', 'green', 'blue', 'cyan', 'magenta', 'yellow', 'white', 'gray'];\n\n const colorOptions = validColors.map((c) => {\n const colorFn = chalk[c as keyof typeof chalk] as (s: string) => string;\n return {\n label: c,\n value: c,\n hint: typeof colorFn === 'function' ? colorFn('\\u2588\\u2588\\u2588') : undefined,\n };\n });\n\n const fields = [\n { key: 'userColor', label: 'User message color', current: theme.userColor },\n { key: 'assistantColor', label: 'Assistant message color', current: theme.assistantColor },\n { key: 'systemColor', label: 'System message color', current: theme.systemColor },\n ];\n\n // Step-based navigation: ESC goes back to previous field, or config menu from the first field\n let step = 0;\n while (step < fields.length) {\n const field = fields[step];\n const choice = await wizardSelect(rl, {\n title: field.label,\n options: colorOptions,\n activeIndex: validColors.indexOf((theme as Record<string, string>)[field.key] ?? field.current),\n cancelLabel: step === 0 ? 'Back' : 'Back to previous',\n });\n\n if (!choice) {\n if (step === 0) return; // ESC on first field → back to config menu\n step--; // ESC → go back one field\n continue;\n }\n\n (theme as Record<string, string>)[field.key] = choice;\n step++;\n }\n\n appConfig.set('theme', theme);\n wizardSuccess('Theme updated.');\n wizardBlank();\n}\n\n// ── Direct subcommands (power-user) ──────────────────────────────────\n\nfunction handleSet(key: string, value: string): void {\n if (!key || !value) {\n console.log(formatError('Usage: /config set <key> <value>'));\n return;\n }\n\n const displayValue = isApiKeyField(key) ? maskKey(value) : value;\n appConfig.setNested(key, value);\n wizardSuccess(`Set ${key} = ${displayValue}`);\n}\n\nfunction handleGet(key: string): void {\n if (!key) {\n console.log(formatError('Usage: /config get <key>'));\n return;\n }\n\n const value = appConfig.getNested(key);\n\n if (value === undefined) {\n console.log(formatError(`Key \"${key}\" not found.`));\n return;\n }\n\n const displayValue = isApiKeyField(key) && typeof value === 'string' && value.length > 8\n ? maskKey(value)\n : String(value);\n\n console.log(`${chalk.bold(key)} = ${displayValue}`);\n}\n\nfunction handleList(): void {\n const all = appConfig.listAll();\n\n wizardBlank();\n wizardDivider();\n console.log(chalk.bold.white(' All Settings'));\n wizardDivider();\n wizardInfo(`Config file: ${appConfig.getConfigPath()}`);\n wizardBlank();\n\n printObject(all, ' ');\n wizardBlank();\n}\n\nfunction printObject(obj: Record<string, unknown>, indent: string): void {\n for (const [key, value] of Object.entries(obj)) {\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n console.log(`${indent}${chalk.bold(key)}:`);\n printObject(value as Record<string, unknown>, indent + ' ');\n } else {\n const isKey = key === 'apiKey' || isApiKeyField(key);\n const displayValue = isKey && typeof value === 'string' && value.length > 8\n ? maskKey(value)\n : String(value);\n console.log(`${indent}${chalk.bold(key)}: ${displayValue}`);\n }\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nfunction maskKey(key: string): string {\n if (key.length <= 8) return '***';\n return key.slice(0, 4) + '...' + key.slice(-4);\n}\n\nfunction isApiKeyField(key: string): boolean {\n const lower = key.toLowerCase();\n return lower.includes('apikey') || lower.includes('api_key') || lower.endsWith('.apikey');\n}\n","import type { SlashCommand } from '../types.js';\n\nexport const clearCommand: SlashCommand = {\n name: 'clear',\n description: 'Clear the screen',\n aliases: ['cls'],\n\n async execute(_args: string, context) {\n console.clear();\n context.clearMessages();\n },\n};\n","import type { DeviceConfig } from './types.js';\nimport * as appConfig from '../config.js';\n\ninterface SmartHomeStore {\n devices: Record<string, DeviceConfig>;\n}\n\nfunction getStore(): SmartHomeStore {\n const raw = appConfig.getNested('smartHome') as SmartHomeStore | undefined;\n return raw ?? { devices: {} };\n}\n\nfunction saveStore(store: SmartHomeStore): void {\n appConfig.setNested('smartHome', store);\n}\n\nexport function listDevices(): DeviceConfig[] {\n const store = getStore();\n return Object.values(store.devices);\n}\n\nexport function getDevice(id: string): DeviceConfig | undefined {\n const store = getStore();\n return store.devices[id];\n}\n\nexport function addDevice(config: DeviceConfig): void {\n const store = getStore();\n store.devices[config.id] = config;\n saveStore(store);\n}\n\nexport function removeDevice(id: string): boolean {\n const store = getStore();\n if (!store.devices[id]) return false;\n delete store.devices[id];\n saveStore(store);\n return true;\n}\n\nexport function updateDevice(id: string, updates: Partial<DeviceConfig>): void {\n const store = getStore();\n const existing = store.devices[id];\n if (!existing) return;\n store.devices[id] = { ...existing, ...updates };\n saveStore(store);\n}\n","import type { SlashCommand, CommandContext } from '../types.js';\nimport type { DeviceConfig, DevicePlatform, GoogleAssistantConfig } from '../smart-home/types.js';\nimport { listDevices, getDevice, addDevice, removeDevice, updateDevice } from '../smart-home/registry.js';\nimport { googleCastAdapter } from '../smart-home/adapters/google-cast.js';\nimport { alexaAdapter } from '../smart-home/adapters/alexa.js';\nimport { formatError } from '../ui/renderer.js';\nimport {\n wizardHeader,\n wizardSelect,\n wizardInput,\n wizardConfirm,\n wizardSuccess,\n wizardError,\n wizardInfo,\n wizardBlank,\n wizardKeyValue,\n wizardDivider,\n wizardBadge,\n} from '../ui/wizard.js';\nimport { startSpinner, stopSpinner, updateSpinner } from '../ui/spinner.js';\nimport chalk from 'chalk';\n\nexport const devicesCommand: SlashCommand = {\n name: 'devices',\n description: 'Manage smart home devices',\n aliases: ['dev', 'smarthome'],\n\n async execute(args: string, context: CommandContext) {\n const parts = args.trim().split(/\\s+/);\n const subcommand = parts[0] || '';\n const rest = parts.slice(1);\n\n // Power-user direct commands\n switch (subcommand) {\n case 'list':\n case 'ls':\n await handleListInteractive(context);\n return;\n case 'edit':\n if (rest[0]) {\n await handleEditDirect(rest[0], context);\n } else {\n await handleEditWizard(context);\n }\n return;\n case 'add': {\n const platform = rest[0] as DevicePlatform | undefined;\n if (platform === 'google-cast' && rest[1]) {\n await handleAddGoogleCastDirect(rest[1], rest[2], context);\n } else {\n await handleAddWizard(context);\n }\n return;\n }\n case 'rm':\n case 'remove':\n case 'delete':\n if (rest[0]) {\n await handleRemoveDirect(rest[0], context);\n } else {\n await handleRemoveWizard(context);\n }\n return;\n case 'test':\n if (rest[0]) {\n await handleTestDirect(rest[0]);\n } else {\n await handleTestWizard(context);\n }\n return;\n case 'discover':\n await handleDiscover();\n return;\n }\n\n // No args → wizard menu\n await wizardMenu(context);\n },\n};\n\n// ── Wizard menu ──────────────────────────────────────────────────────\n\nasync function wizardMenu(context: CommandContext): Promise<void> {\n const { rl } = context;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const devices = listDevices();\n const deviceCount = devices.length;\n\n wizardHeader('Smart Home Devices');\n\n const choice = await wizardSelect(rl, {\n title: 'What would you like to do?',\n options: [\n { label: 'Add a device', value: 'add', hint: 'Google Cast or Alexa' },\n { label: 'List devices', value: 'list', hint: `${deviceCount} device${deviceCount !== 1 ? 's' : ''}` },\n { label: 'Edit a device', value: 'edit', disabled: deviceCount === 0 },\n { label: 'Test connection', value: 'test', disabled: deviceCount === 0 },\n { label: 'Discover devices', value: 'discover', hint: 'mDNS scan for Google Cast' },\n { label: 'Remove a device', value: 'remove', disabled: deviceCount === 0 },\n ],\n cancelLabel: 'Back to chat',\n });\n\n if (!choice) return;\n\n switch (choice) {\n case 'add':\n await handleAddWizard(context);\n break;\n case 'list':\n await handleListInteractive(context);\n break;\n case 'edit':\n await handleEditWizard(context);\n break;\n case 'test':\n await handleTestWizard(context);\n break;\n case 'discover':\n await handleDiscover();\n break;\n case 'remove':\n await handleRemoveWizard(context);\n break;\n }\n }\n}\n\n// ── Add device wizard ────────────────────────────────────────────────\n\nasync function handleAddWizard(context: CommandContext): Promise<void> {\n const { rl } = context;\n\n const platformChoice = await wizardSelect(rl, {\n title: 'Select Platform',\n options: [\n { label: 'Google Cast', value: 'google-cast', hint: 'Chromecast, Google Home, Nest' },\n { label: 'Amazon Alexa', value: 'alexa', hint: 'Echo, Fire TV (unofficial API)' },\n ],\n cancelLabel: 'Back',\n });\n\n if (!platformChoice) return;\n\n if (platformChoice === 'google-cast') {\n await handleAddGoogleCast(context);\n } else {\n await handleAddAlexa(context);\n }\n}\n\nasync function handleAddGoogleCast(context: CommandContext): Promise<void> {\n const { rl } = context;\n\n const method = await wizardSelect(rl, {\n title: 'Add Google Cast Device',\n options: [\n { label: 'Discover on network', value: 'discover', hint: 'mDNS scan' },\n { label: 'Manual IP entry', value: 'manual' },\n ],\n cancelLabel: 'Back',\n });\n\n if (!method) return;\n\n let host = '';\n let port = 8009;\n let suggestedName = '';\n\n if (method === 'discover') {\n let secondsLeft = 60;\n let deviceCount = 0;\n\n startSpinner(`Scanning network... ${secondsLeft}s remaining (0 devices found)`);\n\n const interval = setInterval(() => {\n secondsLeft--;\n updateSpinner(`Scanning network... ${secondsLeft}s remaining (${deviceCount} device${deviceCount !== 1 ? 's' : ''} found)`);\n if (secondsLeft <= 0) clearInterval(interval);\n }, 1000);\n\n try {\n const found = await googleCastAdapter.discover!((device) => {\n deviceCount++;\n updateSpinner(`Scanning network... ${secondsLeft}s remaining (${deviceCount} device${deviceCount !== 1 ? 's' : ''} found) — ${device.name}`);\n });\n\n clearInterval(interval);\n stopSpinner();\n\n if (found.length === 0) {\n wizardBlank();\n wizardError('No Google Cast devices found on the network.');\n wizardBlank();\n wizardInfo('Troubleshooting tips:');\n wizardInfo(' - Ensure your devices are powered on and not in sleep mode');\n wizardInfo(' - Verify this machine and the devices are on the same network/VLAN');\n wizardInfo(' - Check that your firewall allows mDNS traffic (UDP port 5353)');\n wizardInfo(' - On Windows, ensure the \"Function Discovery Provider Host\" service is running');\n wizardInfo(' - Try restarting the Google Home device');\n wizardBlank();\n wizardInfo('You can also add a device manually with /devices add google-cast <ip-address>');\n wizardInfo('or choose \"Manual IP entry\" from the previous menu.');\n wizardBlank();\n return;\n }\n\n const selected = await wizardSelect(rl, {\n title: `Found ${found.length} device(s)`,\n options: found.map((d) => ({\n label: d.name,\n value: d.host,\n hint: `${d.host}:${d.port}${d.model ? ` (${d.model})` : ''}`,\n })),\n cancelLabel: 'Back',\n });\n\n if (!selected) return;\n\n const device = found.find((d) => d.host === selected)!;\n host = device.host;\n port = device.port;\n suggestedName = device.name;\n } catch (error) {\n clearInterval(interval);\n stopSpinner();\n wizardError(error instanceof Error ? error.message : String(error));\n return;\n }\n } else {\n const ipInput = await wizardInput(rl, {\n label: 'Device IP address',\n placeholder: '192.168.1.100',\n required: true,\n });\n host = ipInput;\n\n const portInput = await wizardInput(rl, {\n label: 'Port',\n default: '8009',\n });\n port = parseInt(portInput, 10) || 8009;\n }\n\n const deviceId = await wizardInput(rl, {\n label: 'Device ID',\n placeholder: 'living-room-speaker (letters, numbers, hyphens)',\n required: true,\n });\n\n if (getDevice(deviceId)) {\n wizardError(`Device \"${deviceId}\" already exists.`);\n return;\n }\n\n const deviceName = await wizardInput(rl, {\n label: 'Display name',\n default: suggestedName || deviceId,\n });\n\n // Test connection\n const shouldTest = await wizardConfirm(rl, 'Test connection before saving?', true);\n if (shouldTest) {\n const spinner = startSpinner(`Testing connection to ${host}:${port}...`);\n const result = await googleCastAdapter.testConnection({\n id: deviceId,\n name: deviceName,\n platform: 'google-cast',\n cast: { host, port },\n });\n stopSpinner();\n\n if (result.success) {\n wizardSuccess(result.message);\n } else {\n wizardError(result.message);\n const saveAnyway = await wizardConfirm(rl, 'Save device configuration anyway?');\n if (!saveAnyway) return;\n }\n }\n\n const config: DeviceConfig = {\n id: deviceId,\n name: deviceName,\n platform: 'google-cast',\n cast: { host, port },\n };\n\n // Optional Google Assistant integration\n const assistantConfig = await promptGoogleAssistant(rl);\n if (assistantConfig) {\n config.googleAssistant = assistantConfig;\n }\n\n addDevice(config);\n wizardSuccess(`Device \"${deviceId}\" saved.`);\n wizardBlank();\n}\n\nasync function handleAddGoogleCastDirect(\n ip: string,\n deviceId: string | undefined,\n context: CommandContext,\n): Promise<void> {\n const { rl } = context;\n const id = deviceId ?? ip.replace(/\\./g, '-');\n\n if (getDevice(id)) {\n console.log(formatError(`Device \"${id}\" already exists.`));\n return;\n }\n\n const name = await wizardInput(rl, {\n label: 'Display name',\n default: id,\n });\n\n const config: DeviceConfig = {\n id,\n name,\n platform: 'google-cast',\n cast: { host: ip, port: 8009 },\n };\n\n // Optional Google Assistant integration\n const assistantConfig = await promptGoogleAssistant(rl);\n if (assistantConfig) {\n config.googleAssistant = assistantConfig;\n }\n\n addDevice(config);\n wizardSuccess(`Device \"${id}\" saved (${ip}:8009).`);\n}\n\nasync function handleAddAlexa(context: CommandContext): Promise<void> {\n const { rl } = context;\n\n wizardBlank();\n wizardInfo('Amazon Alexa integration uses an unofficial API (alexa-remote2).');\n wizardInfo('You will need a cookie from your browser DevTools when logged into alexa.amazon.com.');\n wizardInfo('This cookie may expire and need to be refreshed periodically.');\n wizardBlank();\n\n const proceed = await wizardConfirm(rl, 'Continue with Alexa setup?');\n if (!proceed) return;\n\n const cookie = await wizardInput(rl, {\n label: 'Alexa cookie',\n placeholder: 'paste from browser DevTools (Network tab)',\n required: true,\n mask: true,\n });\n\n const domain = await wizardInput(rl, {\n label: 'Amazon domain',\n placeholder: 'amazon.com, amazon.co.uk, etc.',\n default: 'amazon.com',\n });\n\n // Try to connect and list devices\n const spinner = startSpinner('Connecting to Alexa...');\n try {\n const testConfig: DeviceConfig = {\n id: '__alexa_setup__',\n name: 'Setup',\n platform: 'alexa',\n alexa: { cookie, amazonDomain: domain },\n };\n\n const connectResult = await alexaAdapter.testConnection(testConfig);\n stopSpinner();\n\n if (!connectResult.success) {\n wizardError(connectResult.message);\n return;\n }\n\n wizardSuccess(connectResult.message);\n wizardBlank();\n\n // Let user enter device details manually\n // (Getting the device list requires a successful init, which we just tested)\n const deviceId = await wizardInput(rl, {\n label: 'Device ID',\n placeholder: 'echo-kitchen (letters, numbers, hyphens)',\n required: true,\n });\n\n if (getDevice(deviceId)) {\n wizardError(`Device \"${deviceId}\" already exists.`);\n return;\n }\n\n const deviceName = await wizardInput(rl, {\n label: 'Display name',\n default: deviceId,\n });\n\n const serialNumber = await wizardInput(rl, {\n label: 'Device serial number',\n placeholder: 'from Alexa app or browser DevTools',\n });\n\n const deviceType = await wizardInput(rl, {\n label: 'Device type',\n placeholder: 'optional, from Alexa API response',\n });\n\n const config: DeviceConfig = {\n id: deviceId,\n name: deviceName,\n platform: 'alexa',\n alexa: {\n cookie,\n amazonDomain: domain,\n deviceSerialNumber: serialNumber || undefined,\n deviceType: deviceType || undefined,\n },\n };\n\n addDevice(config);\n wizardSuccess(`Alexa device \"${deviceId}\" saved.`);\n wizardBlank();\n } catch (error) {\n stopSpinner();\n wizardError(error instanceof Error ? error.message : String(error));\n }\n}\n\n// ── Google Assistant credentials prompt ──────────────────────────────\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\n\n/**\n * Validate that a file is a valid OAuth 2.0 client secret JSON.\n * Returns null on success, or an error message on failure.\n */\nfunction validateOAuthKeyFile(filePath: string): string | null {\n if (!fs.existsSync(filePath)) {\n return `File not found: \"${filePath}\"`;\n }\n\n try {\n const content = JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n const creds = content.installed ?? content.web;\n\n if (!creds) {\n // Detect common wrong credential types\n if (content.type === 'service_account') {\n return 'This is a service account key (type: service_account). '\n + 'Google Assistant requires OAuth 2.0 Client ID credentials instead.\\n'\n + ' In the SAME Google Cloud project, go to:\\n'\n + ' Credentials → Create Credentials → OAuth Client ID → Desktop app → Download JSON';\n }\n return 'This file does not contain an \"installed\" or \"web\" section. '\n + 'It must be an OAuth 2.0 client secret JSON downloaded from '\n + 'Google Cloud Console → Credentials → OAuth 2.0 Client IDs.';\n }\n\n if (!creds.client_id || !creds.client_secret) {\n return 'The file is missing client_id or client_secret. '\n + 'Download a fresh OAuth 2.0 client secret from Google Cloud Console.';\n }\n\n return null; // Valid\n } catch (err) {\n return `Failed to parse JSON: ${err instanceof Error ? err.message : String(err)}`;\n }\n}\n\n/**\n * Attempt the OAuth consent flow by instantiating google-assistant with the\n * given credentials. The package will print a URL the user must visit in\n * their browser; once authorized it writes tokens to savedTokensPath.\n *\n * Returns true on success, false on failure (errors are displayed but never thrown).\n */\nasync function attemptOAuthFlow(keyFilePath: string, savedTokensPath: string): Promise<boolean> {\n wizardBlank();\n wizardInfo('Starting OAuth authorization flow...');\n wizardInfo('A browser window will open for Google sign-in.');\n wizardInfo('After authorizing, you will be redirected back automatically.');\n wizardBlank();\n\n try {\n // Import the shared OAuth helper from the google-cast adapter\n const { getAuthenticatedOAuthClient } = await import('../smart-home/adapters/google-cast.js');\n const result = await getAuthenticatedOAuthClient(keyFilePath, savedTokensPath);\n\n if ('error' in result) {\n wizardError(result.error);\n return false;\n }\n\n wizardSuccess('Google Assistant authorized successfully!');\n return true;\n } catch (err) {\n wizardError(`OAuth flow error: ${err instanceof Error ? err.message : String(err)}`);\n return false;\n }\n}\n\n/**\n * Get the secure directory for storing Google Assistant credentials.\n * Uses %APPDATA%/nm-cli on Windows, ~/.config/nm-cli elsewhere.\n */\nfunction getCredentialsDir(): string {\n const appData = process.env.APPDATA\n ?? path.join(os.homedir(), '.config');\n const dir = path.join(appData, 'nm-cli', 'credentials');\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n return dir;\n}\n\n/**\n * Create an OAuth client secret JSON file from a Client ID and Client Secret.\n * Saves to a secure app-data location and returns the file path.\n */\nfunction createKeyFileFromCredentials(clientId: string, clientSecret: string): string {\n const keyData = {\n installed: {\n client_id: clientId,\n client_secret: clientSecret,\n auth_uri: 'https://accounts.google.com/o/oauth2/auth',\n token_uri: 'https://oauth2.googleapis.com/token',\n redirect_uris: ['http://localhost', 'urn:ietf:wg:oauth:2.0:oob'],\n },\n };\n\n const credDir = getCredentialsDir();\n const filePath = path.join(credDir, 'google-assistant-client-secret.json');\n fs.writeFileSync(filePath, JSON.stringify(keyData, null, 2), { mode: 0o600 });\n return filePath;\n}\n\nasync function promptGoogleAssistantKeyFile(\n rl: import('readline').Interface,\n defaultPath?: string,\n): Promise<string | null> {\n // Loop until valid or user gives up\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const keyFilePath = await wizardInput(rl, {\n label: 'Path to OAuth client secret JSON file',\n placeholder: '/path/to/client_secret.json',\n default: defaultPath,\n required: true,\n });\n\n if (!keyFilePath) return null;\n\n const error = validateOAuthKeyFile(keyFilePath);\n if (!error) {\n wizardSuccess('Key file validated successfully.');\n return keyFilePath;\n }\n\n wizardBlank();\n wizardError(error);\n wizardBlank();\n\n const retry = await wizardConfirm(rl, 'Try a different file?');\n if (!retry) return null;\n }\n}\n\nasync function promptGoogleAssistant(\n rl: import('readline').Interface,\n): Promise<GoogleAssistantConfig | null> {\n const configure = await wizardConfirm(rl, 'Configure Google Assistant integration for this device?');\n if (!configure) return null;\n\n wizardBlank();\n wizardInfo('Google Assistant lets you send voice commands through this device.');\n wizardInfo('You need OAuth 2.0 credentials from Google Cloud Console.');\n wizardBlank();\n\n const method = await wizardSelect(rl, {\n title: 'How would you like to provide credentials?',\n options: [\n { label: 'Enter Client ID & Secret', value: 'manual', hint: 'paste from Google Cloud Console' },\n { label: 'Point to existing JSON file', value: 'file', hint: 'downloaded client_secret.json' },\n ],\n cancelLabel: 'Skip',\n });\n\n if (!method) return null;\n\n let keyFilePath: string | null = null;\n\n if (method === 'manual') {\n wizardBlank();\n wizardInfo('Paste the Client ID and Client Secret from Google Cloud Console.');\n wizardInfo('These will be saved securely in your app data folder.');\n wizardBlank();\n\n const clientId = await wizardInput(rl, {\n label: 'Client ID',\n placeholder: '123456789-abcdef.apps.googleusercontent.com',\n required: true,\n });\n if (!clientId) return null;\n\n const clientSecret = await wizardInput(rl, {\n label: 'Client Secret',\n required: true,\n mask: true,\n });\n if (!clientSecret) return null;\n\n keyFilePath = createKeyFileFromCredentials(clientId, clientSecret);\n wizardSuccess(`Credentials saved to ${keyFilePath}`);\n } else {\n wizardBlank();\n wizardInfo('Steps to get the JSON file:');\n wizardInfo(' 1. Go to console.cloud.google.com → APIs & Services → Credentials');\n wizardInfo(' 2. Create an OAuth 2.0 Client ID (Desktop app type)');\n wizardInfo(' 3. Download the JSON file');\n wizardInfo(' 4. Enable the Google Assistant API for your project');\n wizardBlank();\n\n keyFilePath = await promptGoogleAssistantKeyFile(rl);\n }\n\n if (!keyFilePath) return null;\n\n // Default tokens path next to the key file\n const defaultTokensPath = path.join(getCredentialsDir(), 'google-assistant-tokens.json');\n\n const savedTokensPath = await wizardInput(rl, {\n label: 'Path to save/load tokens',\n default: defaultTokensPath,\n });\n\n if (!savedTokensPath) return null;\n\n // Attempt OAuth consent flow so the user doesn't have to do it manually later\n await attemptOAuthFlow(keyFilePath, savedTokensPath);\n\n wizardSuccess('Google Assistant credentials configured for this device.');\n return { keyFilePath, savedTokensPath };\n}\n\n// ── List (interactive — select a device to view/edit) ────────────────\n\nfunction printDeviceDetails(device: DeviceConfig): void {\n const platformBadge = device.platform === 'google-cast'\n ? wizardBadge('Cast', 'green')\n : wizardBadge('Alexa', 'blue');\n\n wizardBlank();\n wizardDivider();\n console.log(` ${chalk.bold.cyan(device.id)} ${platformBadge}`);\n wizardDivider();\n wizardBlank();\n wizardKeyValue('Name', device.name);\n wizardKeyValue('Platform', device.platform);\n\n if (device.cast) {\n wizardKeyValue('Host', `${device.cast.host}:${device.cast.port ?? 8009}`);\n }\n if (device.alexa) {\n wizardKeyValue('Domain', `amazon.${device.alexa.amazonDomain ?? 'com'}`);\n if (device.alexa.deviceSerialNumber) {\n wizardKeyValue('Serial', device.alexa.deviceSerialNumber);\n }\n }\n if (device.googleAssistant) {\n wizardKeyValue('Assistant Key', device.googleAssistant.keyFilePath);\n wizardKeyValue('Assistant Tokens', device.googleAssistant.savedTokensPath);\n } else if (device.platform === 'google-cast') {\n wizardKeyValue('Assistant', chalk.dim('Not configured'));\n }\n wizardBlank();\n}\n\nasync function handleListInteractive(context: CommandContext): Promise<void> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const devices = listDevices();\n\n if (devices.length === 0) {\n wizardBlank();\n wizardInfo('No smart home devices configured. Use /devices to add one.');\n wizardBlank();\n return;\n }\n\n const deviceId = await wizardSelect(context.rl, {\n title: `Smart Home Devices (${devices.length})`,\n options: devices.map((d) => {\n const badge = d.platform === 'google-cast' ? 'Cast' : 'Alexa';\n const assistant = d.googleAssistant ? ' | Assistant' : '';\n return {\n label: d.id,\n value: d.id,\n hint: `${badge} \\u2014 ${d.name}${assistant}`,\n };\n }),\n cancelLabel: 'Back',\n });\n\n if (!deviceId) return; // ESC → back to main devices menu\n\n const device = getDevice(deviceId);\n if (!device) return;\n\n printDeviceDetails(device);\n\n const action = await wizardSelect(context.rl, {\n title: `Actions for \"${deviceId}\"`,\n options: [\n { label: 'Edit device', value: 'edit' },\n { label: 'Test connection', value: 'test' },\n { label: 'Remove device', value: 'remove' },\n ],\n cancelLabel: 'Back',\n });\n\n if (!action) continue; // ESC → back to device list\n\n switch (action) {\n case 'edit':\n await handleEditDirect(deviceId, context);\n break;\n case 'test':\n await handleTestDirect(deviceId);\n break;\n case 'remove':\n await handleRemoveDirect(deviceId, context);\n break;\n }\n }\n}\n\n// ── Edit device ──────────────────────────────────────────────────────\n\nasync function handleEditWizard(context: CommandContext): Promise<void> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const devices = listDevices();\n if (devices.length === 0) {\n wizardInfo('No devices configured.');\n return;\n }\n\n const deviceId = await wizardSelect(context.rl, {\n title: 'Edit Device',\n options: devices.map((d) => ({\n label: d.id,\n value: d.id,\n hint: `${d.platform} \\u2014 ${d.name}`,\n })),\n cancelLabel: 'Back',\n });\n\n if (!deviceId) return; // ESC → back to main devices menu\n await handleEditDirect(deviceId, context);\n }\n}\n\nasync function handleEditDirect(deviceId: string, context: CommandContext): Promise<void> {\n const { rl } = context;\n const device = getDevice(deviceId);\n if (!device) {\n console.log(formatError(`Device \"${deviceId}\" not found.`));\n return;\n }\n\n // Build edit options based on device platform\n const editOptions: { label: string; value: string; hint?: string }[] = [\n { label: 'Display name', value: 'name', hint: device.name },\n ];\n\n if (device.cast) {\n editOptions.push(\n { label: 'Host / IP', value: 'host', hint: device.cast.host },\n { label: 'Port', value: 'port', hint: String(device.cast.port ?? 8009) },\n );\n }\n\n if (device.alexa) {\n editOptions.push(\n { label: 'Cookie', value: 'cookie', hint: '(masked)' },\n { label: 'Amazon domain', value: 'domain', hint: device.alexa.amazonDomain ?? 'amazon.com' },\n );\n }\n\n if (device.platform === 'google-cast') {\n const assistantHint = device.googleAssistant\n ? device.googleAssistant.keyFilePath\n : 'Not configured';\n editOptions.push(\n { label: 'Google Assistant credentials', value: 'assistant', hint: assistantHint },\n );\n }\n\n const field = await wizardSelect(rl, {\n title: `Edit \"${deviceId}\"`,\n options: editOptions,\n cancelLabel: 'Back',\n });\n\n if (!field) return;\n\n switch (field) {\n case 'name': {\n const newName = await wizardInput(rl, {\n label: 'New display name',\n default: device.name,\n });\n if (newName && newName !== device.name) {\n updateDevice(deviceId, { name: newName });\n wizardSuccess(`Display name updated to \"${newName}\".`);\n }\n break;\n }\n case 'host': {\n const newHost = await wizardInput(rl, {\n label: 'New host / IP address',\n default: device.cast?.host ?? '',\n required: true,\n });\n if (newHost && newHost !== device.cast?.host) {\n updateDevice(deviceId, { cast: { ...device.cast!, host: newHost } });\n wizardSuccess(`Host updated to \"${newHost}\".`);\n }\n break;\n }\n case 'port': {\n const newPort = await wizardInput(rl, {\n label: 'New port',\n default: String(device.cast?.port ?? 8009),\n });\n const portNum = parseInt(newPort, 10) || 8009;\n updateDevice(deviceId, { cast: { ...device.cast!, port: portNum } });\n wizardSuccess(`Port updated to ${portNum}.`);\n break;\n }\n case 'cookie': {\n const newCookie = await wizardInput(rl, {\n label: 'New Alexa cookie',\n required: true,\n mask: true,\n });\n if (newCookie) {\n updateDevice(deviceId, { alexa: { ...device.alexa!, cookie: newCookie } });\n wizardSuccess('Alexa cookie updated.');\n }\n break;\n }\n case 'domain': {\n const newDomain = await wizardInput(rl, {\n label: 'New Amazon domain',\n default: device.alexa?.amazonDomain ?? 'amazon.com',\n });\n if (newDomain) {\n updateDevice(deviceId, { alexa: { ...device.alexa!, amazonDomain: newDomain } });\n wizardSuccess(`Amazon domain updated to \"${newDomain}\".`);\n }\n break;\n }\n case 'assistant': {\n await handleEditAssistant(rl, device);\n break;\n }\n }\n wizardBlank();\n}\n\nasync function handleEditAssistant(\n rl: import('readline').Interface,\n device: DeviceConfig,\n): Promise<void> {\n if (device.googleAssistant) {\n // Show current config and offer actions\n wizardBlank();\n wizardKeyValue('Current key file', device.googleAssistant.keyFilePath);\n wizardKeyValue('Current tokens path', device.googleAssistant.savedTokensPath);\n wizardBlank();\n\n const action = await wizardSelect(rl, {\n title: 'Google Assistant Credentials',\n options: [\n { label: 'Update credentials', value: 'update' },\n { label: 'Remove credentials', value: 'remove' },\n ],\n cancelLabel: 'Back',\n });\n\n if (!action) return;\n\n if (action === 'remove') {\n const confirmed = await wizardConfirm(rl, 'Remove Google Assistant credentials from this device?');\n if (confirmed) {\n updateDevice(device.id, { googleAssistant: undefined });\n wizardSuccess('Google Assistant credentials removed.');\n }\n return;\n }\n\n // Fall through to update\n const keyFilePath = await promptGoogleAssistantKeyFile(rl, device.googleAssistant.keyFilePath);\n if (!keyFilePath) return;\n\n const savedTokensPath = await wizardInput(rl, {\n label: 'Path to save/load tokens',\n default: device.googleAssistant.savedTokensPath,\n required: true,\n });\n\n if (!savedTokensPath) return;\n\n updateDevice(device.id, { googleAssistant: { keyFilePath, savedTokensPath } });\n wizardSuccess('Google Assistant credentials updated.');\n } else {\n // No credentials yet — offer to configure\n const assistantConfig = await promptGoogleAssistant(rl);\n if (assistantConfig) {\n updateDevice(device.id, { googleAssistant: assistantConfig });\n }\n }\n}\n\n// ── Test connection ──────────────────────────────────────────────────\n\nasync function handleTestWizard(context: CommandContext): Promise<void> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const devices = listDevices();\n if (devices.length === 0) {\n wizardInfo('No devices configured.');\n return;\n }\n\n const deviceId = await wizardSelect(context.rl, {\n title: 'Test Device Connection',\n options: devices.map((d) => ({\n label: d.id,\n value: d.id,\n hint: `${d.platform} \\u2014 ${d.name}`,\n })),\n cancelLabel: 'Back',\n });\n\n if (!deviceId) return; // ESC → back to main devices menu\n await handleTestDirect(deviceId);\n }\n}\n\nasync function handleTestDirect(deviceId: string): Promise<void> {\n const device = getDevice(deviceId);\n if (!device) {\n console.log(formatError(`Device \"${deviceId}\" not found.`));\n return;\n }\n\n const adapter = device.platform === 'google-cast' ? googleCastAdapter : alexaAdapter;\n const spinner = startSpinner(`Testing connection to \"${deviceId}\"...`);\n const result = await adapter.testConnection(device);\n stopSpinner();\n\n if (result.success) {\n wizardSuccess(result.message);\n } else {\n wizardError(result.message);\n }\n wizardBlank();\n}\n\n// ── Discover ─────────────────────────────────────────────────────────\n\nasync function handleDiscover(): Promise<void> {\n wizardBlank();\n let secondsLeft = 60;\n let deviceCount = 0;\n\n startSpinner(`Scanning network... ${secondsLeft}s remaining (0 devices found)`);\n\n const interval = setInterval(() => {\n secondsLeft--;\n updateSpinner(`Scanning network... ${secondsLeft}s remaining (${deviceCount} device${deviceCount !== 1 ? 's' : ''} found)`);\n if (secondsLeft <= 0) clearInterval(interval);\n }, 1000);\n\n try {\n const found = await googleCastAdapter.discover!((device) => {\n deviceCount++;\n updateSpinner(`Scanning network... ${secondsLeft}s remaining (${deviceCount} device${deviceCount !== 1 ? 's' : ''} found) — ${device.name}`);\n });\n\n clearInterval(interval);\n stopSpinner();\n\n if (found.length === 0) {\n wizardBlank();\n wizardError('No Google Cast devices found on the network.');\n wizardBlank();\n wizardInfo('Troubleshooting tips:');\n wizardInfo(' - Ensure your devices are powered on and not in sleep mode');\n wizardInfo(' - Verify this machine and the devices are on the same network/VLAN');\n wizardInfo(' - Check that your firewall allows mDNS traffic (UDP port 5353)');\n wizardInfo(' - On Windows, ensure the \"Function Discovery Provider Host\" service is running');\n wizardInfo(' - Try restarting the Google Home device');\n wizardBlank();\n wizardInfo('You can also add a device manually if you know its IP address:');\n wizardInfo(' /devices add google-cast <ip-address>');\n wizardBlank();\n return;\n }\n\n wizardDivider();\n console.log(chalk.bold.white(` Discovered Devices (${found.length})`));\n wizardDivider();\n wizardBlank();\n\n for (const device of found) {\n console.log(` ${chalk.bold.cyan(device.name)}`);\n console.log(` ${chalk.dim(`${device.host}:${device.port}`)}${device.model ? chalk.dim(` (${device.model})`) : ''}`);\n }\n wizardBlank();\n wizardInfo('Use /devices add to configure a discovered device.');\n wizardBlank();\n } catch (error) {\n clearInterval(interval);\n stopSpinner();\n wizardError(error instanceof Error ? error.message : String(error));\n wizardBlank();\n }\n}\n\n// ── Remove ───────────────────────────────────────────────────────────\n\nasync function handleRemoveWizard(context: CommandContext): Promise<void> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const devices = listDevices();\n if (devices.length === 0) {\n wizardInfo('No devices configured.');\n return;\n }\n\n const deviceId = await wizardSelect(context.rl, {\n title: 'Remove Device',\n hint: 'This action cannot be undone.',\n options: devices.map((d) => ({\n label: d.id,\n value: d.id,\n hint: `${d.platform} \\u2014 ${d.name}`,\n })),\n cancelLabel: 'Back',\n });\n\n if (!deviceId) return; // ESC → back to main devices menu\n await handleRemoveDirect(deviceId, context);\n }\n}\n\nasync function handleRemoveDirect(deviceId: string, context: CommandContext): Promise<void> {\n const device = getDevice(deviceId);\n if (!device) {\n console.log(formatError(`Device \"${deviceId}\" not found.`));\n return;\n }\n\n const confirmed = await wizardConfirm(context.rl, `Remove device \"${deviceId}\" (${device.name})?`);\n if (!confirmed) {\n wizardInfo('Cancelled.');\n return;\n }\n\n // Disconnect if active\n const adapter = device.platform === 'google-cast' ? googleCastAdapter : alexaAdapter;\n await adapter.disconnect(deviceId);\n\n const removed = removeDevice(deviceId);\n if (removed) {\n wizardSuccess(`Device \"${deviceId}\" removed.`);\n } else {\n wizardError(`Failed to remove device \"${deviceId}\".`);\n }\n wizardBlank();\n}\n","import type { SmartHomeAdapter, DeviceConfig, DeviceStatus } from '../types.js';\n\n/**\n * Local interface matching the subset of alexa-remote2 API we use.\n * This avoids complex InstanceType<typeof import(...)> gymnastics that\n * break under verbatimModuleSyntax + dynamic imports.\n */\ninterface AlexaInstance {\n init(options: { cookie: string; amazonPage?: string }, callback: (err: Error | null) => void): void;\n getDevices(callback: (err: Error | null, devices: Array<{ serialNumber?: string; accountName?: string }>) => void): void;\n sendSequenceCommand(serialNumber: string, command: string, value: string | Record<string, unknown>, callback?: (err: Error | null) => void): void;\n getPlayerInfo(serialNumber: string, callback: (err: Error | null, info: Record<string, unknown> | null) => void): void;\n setVolume(serialNumber: string, volume: number, callback?: (err: Error | null) => void): void;\n deviceStop(serialNumber: string, callback?: (err: Error | null) => void): void;\n pause(serialNumber: string, callback?: (err: Error | null) => void): void;\n play(serialNumber: string, callback?: (err: Error | null) => void): void;\n}\n\n// Cache initialized Alexa instances by device ID\nconst alexaInstances = new Map<string, AlexaInstance>();\n\nfunction getAlexaConfig(config: DeviceConfig): {\n cookie: string;\n amazonDomain: string;\n serialNumber: string;\n} {\n if (!config.alexa) {\n throw new Error(`Device \"${config.id}\" has no Alexa configuration.`);\n }\n if (!config.alexa.cookie) {\n throw new Error(`Device \"${config.id}\" has no Alexa cookie configured. Use /devices to set up authentication.`);\n }\n return {\n cookie: config.alexa.cookie,\n amazonDomain: config.alexa.amazonDomain ?? 'amazon.com',\n serialNumber: config.alexa.deviceSerialNumber ?? '',\n };\n}\n\nasync function getAlexaInstance(config: DeviceConfig): Promise<AlexaInstance> {\n const existing = alexaInstances.get(config.id);\n if (existing) return existing;\n\n let AlexaRemote: new () => AlexaInstance;\n try {\n const mod = await import('alexa-remote2');\n AlexaRemote = mod.default as unknown as new () => AlexaInstance;\n } catch {\n throw new Error(\n 'alexa-remote2 is not installed or failed to load. Run: npm install alexa-remote2. ' +\n 'Note: This is an unofficial API and may require specific Node.js versions.',\n );\n }\n\n const alexaConfig = getAlexaConfig(config);\n const alexa = new AlexaRemote();\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error('Alexa initialization timed out after 15 seconds'));\n }, 15_000);\n\n alexa.init(\n {\n cookie: alexaConfig.cookie,\n amazonPage: `amazon.${alexaConfig.amazonDomain}`,\n },\n (err) => {\n clearTimeout(timeout);\n if (err) reject(err);\n else resolve();\n },\n );\n });\n\n alexaInstances.set(config.id, alexa);\n return alexa;\n}\n\nexport const alexaAdapter: SmartHomeAdapter = {\n platform: 'alexa',\n\n async connect(config: DeviceConfig): Promise<{ success: boolean; error?: string }> {\n try {\n await getAlexaInstance(config);\n return { success: true };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n\n async disconnect(deviceId: string): Promise<void> {\n alexaInstances.delete(deviceId);\n },\n\n async testConnection(config: DeviceConfig): Promise<{ success: boolean; message: string }> {\n try {\n const alexa = await getAlexaInstance(config);\n\n const devices = await new Promise<Array<{ serialNumber?: string; accountName?: string }>>((resolve, reject) => {\n alexa.getDevices((err, devs) => {\n if (err) reject(err);\n else resolve(devs);\n });\n });\n\n // Clean up cached instance after test\n alexaInstances.delete(config.id);\n\n return {\n success: true,\n message: `Connected successfully. Found ${devices.length} Alexa device(s) on the account.`,\n };\n } catch (error) {\n alexaInstances.delete(config.id);\n return {\n success: false,\n message: error instanceof Error ? error.message : String(error),\n };\n }\n },\n\n // Alexa doesn't support mDNS discovery — devices are found via the API after authentication\n\n async getStatus(config: DeviceConfig): Promise<DeviceStatus> {\n try {\n const alexa = await getAlexaInstance(config);\n const alexaConfig = getAlexaConfig(config);\n\n if (!alexaConfig.serialNumber) {\n return { online: true, platform: 'alexa' };\n }\n\n const playerInfo = await new Promise<Record<string, unknown> | null>((resolve, reject) => {\n alexa.getPlayerInfo(alexaConfig.serialNumber, (err, info) => {\n if (err) reject(err);\n else resolve(info);\n });\n });\n\n return {\n online: true,\n platform: 'alexa',\n volume: playerInfo?.volume as number | undefined,\n mediaStatus: playerInfo\n ? {\n title: playerInfo.infoText as string | undefined,\n playerState: playerInfo.playerState as string | undefined,\n }\n : undefined,\n };\n } catch {\n return { online: false, platform: 'alexa' };\n }\n },\n\n async playMedia(\n config: DeviceConfig,\n mediaUrl: string,\n _contentType?: string,\n title?: string,\n ): Promise<{ success: boolean; error?: string }> {\n try {\n const alexa = await getAlexaInstance(config);\n const alexaConfig = getAlexaConfig(config);\n\n if (!alexaConfig.serialNumber) {\n return { success: false, error: 'No device serial number configured. Reconfigure this device.' };\n }\n\n await new Promise<void>((resolve, reject) => {\n alexa.sendSequenceCommand(\n alexaConfig.serialNumber,\n 'speak',\n title ?? `Playing media from ${mediaUrl}`,\n (err) => {\n if (err) reject(err);\n else resolve();\n },\n );\n });\n\n return { success: true };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n\n async controlPlayback(\n config: DeviceConfig,\n action: 'pause' | 'resume' | 'stop' | 'setVolume' | 'mute' | 'unmute' | 'seek',\n value?: number,\n ): Promise<{ success: boolean; error?: string }> {\n try {\n const alexa = await getAlexaInstance(config);\n const alexaConfig = getAlexaConfig(config);\n\n if (!alexaConfig.serialNumber) {\n return { success: false, error: 'No device serial number configured.' };\n }\n\n switch (action) {\n case 'setVolume':\n await new Promise<void>((resolve, reject) => {\n alexa.setVolume(alexaConfig.serialNumber, value ?? 50, (err) => {\n if (err) reject(err);\n else resolve();\n });\n });\n break;\n case 'pause':\n await new Promise<void>((resolve, reject) => {\n alexa.pause(alexaConfig.serialNumber, (err) => {\n if (err) reject(err);\n else resolve();\n });\n });\n break;\n case 'resume':\n await new Promise<void>((resolve, reject) => {\n alexa.play(alexaConfig.serialNumber, (err) => {\n if (err) reject(err);\n else resolve();\n });\n });\n break;\n case 'stop':\n await new Promise<void>((resolve, reject) => {\n alexa.deviceStop(alexaConfig.serialNumber, (err) => {\n if (err) reject(err);\n else resolve();\n });\n });\n break;\n case 'mute':\n await new Promise<void>((resolve, reject) => {\n alexa.setVolume(alexaConfig.serialNumber, 0, (err) => {\n if (err) reject(err);\n else resolve();\n });\n });\n break;\n case 'unmute':\n await new Promise<void>((resolve, reject) => {\n alexa.setVolume(alexaConfig.serialNumber, 50, (err) => {\n if (err) reject(err);\n else resolve();\n });\n });\n break;\n }\n\n return { success: true };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n\n async sendNotification(\n config: DeviceConfig,\n message: string,\n _language?: string,\n ): Promise<{ success: boolean; error?: string }> {\n try {\n const alexa = await getAlexaInstance(config);\n const alexaConfig = getAlexaConfig(config);\n\n if (!alexaConfig.serialNumber) {\n return { success: false, error: 'No device serial number configured.' };\n }\n\n await new Promise<void>((resolve, reject) => {\n alexa.sendSequenceCommand(\n alexaConfig.serialNumber,\n 'announcement',\n message,\n (err) => {\n if (err) reject(err);\n else resolve();\n },\n );\n });\n\n return { success: true };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n};\n","import type { SlashCommand, CommandContext } from '../types.js';\nimport { formatError } from '../ui/renderer.js';\nimport { helpCommand } from './help.js';\nimport { modelCommand } from './model.js';\nimport { agentCommand } from './agent.js';\nimport { configCommand } from './config.js';\nimport { clearCommand } from './clear.js';\nimport { devicesCommand } from './devices.js';\n\nconst commands = new Map<string, SlashCommand>();\nconst aliasMap = new Map<string, string>();\n\nfunction register(command: SlashCommand): void {\n commands.set(command.name, command);\n for (const alias of command.aliases) {\n aliasMap.set(alias, command.name);\n }\n}\n\nregister(helpCommand);\nregister(modelCommand);\nregister(agentCommand);\nregister(configCommand);\nregister(clearCommand);\nregister(devicesCommand);\n\nexport function getCommand(input: string): SlashCommand | undefined {\n const name = aliasMap.get(input) ?? input;\n return commands.get(name);\n}\n\nexport function getAllCommands(): SlashCommand[] {\n return Array.from(commands.values());\n}\n\n/**\n * Built-in commands that are handled inline in executeCommand\n * (not registered as SlashCommand objects).\n */\nconst builtinCommands: { name: string; description: string }[] = [\n { name: 'exit', description: 'Exit the chat' },\n { name: 'quit', description: 'Exit the chat' },\n { name: 'q', description: 'Exit the chat' },\n];\n\n/**\n * Return matching slash command completions for a partial input.\n * The `partial` should NOT include the leading `/`.\n * Returns { completions: string[], entries: { name, description }[] }.\n */\nexport function getCompletions(partial: string): {\n completions: string[];\n entries: { name: string; description: string }[];\n} {\n const lower = partial.toLowerCase();\n\n const entries: { name: string; description: string }[] = [];\n const seen = new Set<string>();\n\n // Registered commands (primary names)\n for (const cmd of commands.values()) {\n if (cmd.name.toLowerCase().startsWith(lower) && !seen.has(cmd.name)) {\n entries.push({ name: cmd.name, description: cmd.description });\n seen.add(cmd.name);\n }\n }\n\n // Registered aliases — only show an alias if its primary command\n // is NOT already in the results (avoids duplicate-looking entries\n // like \"/a\" and \"/agent\" both appearing for the same command).\n for (const [alias, primaryName] of aliasMap.entries()) {\n if (alias.toLowerCase().startsWith(lower) && !seen.has(alias) && !seen.has(primaryName)) {\n const primary = commands.get(primaryName);\n const desc = primary ? primary.description : '';\n entries.push({ name: alias, description: desc });\n seen.add(alias);\n }\n }\n\n // Built-in commands (exit, quit, q)\n for (const bc of builtinCommands) {\n if (bc.name.toLowerCase().startsWith(lower) && !seen.has(bc.name)) {\n entries.push(bc);\n seen.add(bc.name);\n }\n }\n\n // Sort alphabetically\n entries.sort((a, b) => a.name.localeCompare(b.name));\n\n const completions = entries.map((e) => '/' + e.name);\n\n return { completions, entries };\n}\n\n/**\n * Resolve an input string to a SlashCommand using exact match first,\n * then unambiguous prefix matching against command names, aliases, and builtins.\n *\n * Returns:\n * - `{ kind: 'exact' | 'prefix', command }` when a single match is found\n * - `{ kind: 'builtin', name }` for built-in commands (exit/quit/q)\n * - `{ kind: 'ambiguous', candidates }` when multiple commands match\n * - `{ kind: 'none' }` when nothing matches\n */\nfunction resolveCommand(input: string):\n | { kind: 'exact' | 'prefix'; command: SlashCommand }\n | { kind: 'builtin'; name: string }\n | { kind: 'ambiguous'; candidates: string[] }\n | { kind: 'none' } {\n // 1. Exact match against registered commands & aliases\n const exact = getCommand(input);\n if (exact) {\n return { kind: 'exact', command: exact };\n }\n\n // 2. Exact match against built-in commands\n const builtinExact = builtinCommands.find((bc) => bc.name === input);\n if (builtinExact) {\n return { kind: 'builtin', name: builtinExact.name };\n }\n\n // 3. Prefix match — collect all candidate names\n const lower = input.toLowerCase();\n const matchedNames = new Set<string>();\n\n for (const cmd of commands.values()) {\n if (cmd.name.toLowerCase().startsWith(lower)) {\n matchedNames.add(cmd.name);\n }\n }\n\n for (const [alias, primaryName] of aliasMap.entries()) {\n if (alias.toLowerCase().startsWith(lower)) {\n matchedNames.add(primaryName);\n }\n }\n\n for (const bc of builtinCommands) {\n if (bc.name.toLowerCase().startsWith(lower)) {\n matchedNames.add(bc.name);\n }\n }\n\n if (matchedNames.size === 1) {\n const name = matchedNames.values().next().value!;\n // Check if it's a built-in\n if (builtinCommands.some((bc) => bc.name === name)) {\n return { kind: 'builtin', name };\n }\n const cmd = commands.get(name);\n if (cmd) {\n return { kind: 'prefix', command: cmd };\n }\n }\n\n if (matchedNames.size > 1) {\n return { kind: 'ambiguous', candidates: Array.from(matchedNames).sort() };\n }\n\n return { kind: 'none' };\n}\n\nexport async function executeCommand(\n commandLine: string,\n context: CommandContext,\n): Promise<boolean> {\n // Remove leading slash\n const line = commandLine.startsWith('/') ? commandLine.slice(1) : commandLine;\n const parts = line.split(/\\s+/);\n const commandName = parts[0];\n const args = parts.slice(1).join(' ');\n\n const result = resolveCommand(commandName);\n\n switch (result.kind) {\n case 'builtin':\n context.exit();\n return true;\n\n case 'exact':\n case 'prefix':\n await result.command.execute(args, context);\n return true;\n\n case 'ambiguous':\n console.log(\n formatError(\n `Ambiguous command \"/${commandName}\". Did you mean: ${result.candidates.map((c) => '/' + c).join(', ')}?`,\n ),\n );\n return true;\n\n case 'none':\n return false;\n }\n}\n","import * as readline from 'node:readline';\nimport chalk from 'chalk';\nimport { formatModelPrompt } from './renderer.js';\nimport { getCompletions } from '../commands/registry.js';\n\nexport interface InputOptions {\n provider: string;\n model: string;\n}\n\n// ── Tab-completion via readline's completer ──────────────────────────\n\ntype CompleterResult = [string[], string];\n\nfunction slashCompleter(line: string): CompleterResult {\n if (!line.startsWith('/')) {\n return [[], line];\n }\n\n const partial = line.slice(1); // strip leading /\n const { completions } = getCompletions(partial);\n\n return [completions, line];\n}\n\n// ── Inline suggestion display ────────────────────────────────────────\n\nconst MAX_SUGGESTIONS = 5;\n\n/** Number of suggestion lines currently rendered below the prompt. */\nlet renderedSuggestionLines = 0;\n\n/** Strip ANSI escape codes to get visible string length. */\nfunction stripAnsi(str: string): string {\n return str.replace(/\\x1B\\[[0-9;]*[a-zA-Z]/g, '');\n}\n\n/** Get the column where readline's cursor currently sits (1-indexed). */\nfunction getCursorColumn(rl: readline.Interface): number {\n const prompt = (rl as unknown as { _prompt: string })._prompt || '';\n const promptWidth = stripAnsi(prompt).length;\n const cursor = (rl as unknown as { cursor: number }).cursor || 0;\n return promptWidth + cursor + 1; // ANSI columns are 1-indexed\n}\n\n/**\n * Clear any previously rendered suggestion lines below the cursor.\n * Uses relative cursor movement (not save/restore) for Windows reliability.\n */\nfunction clearSuggestions(rl: readline.Interface): void {\n if (renderedSuggestionLines === 0) return;\n\n const out = process.stdout;\n const col = getCursorColumn(rl);\n\n // Move to next line (handles scroll at bottom of terminal),\n // erase everything from there down, move back up, restore column.\n out.write(`\\n\\x1B[J\\x1B[A\\x1B[${col}G`);\n\n renderedSuggestionLines = 0;\n}\n\n/**\n * Render matching command suggestions below the current prompt line.\n * Uses relative cursor movement to return to the correct position.\n */\nfunction renderSuggestions(rl: readline.Interface, partial: string): void {\n clearSuggestions(rl);\n\n const { entries } = getCompletions(partial);\n if (entries.length === 0) return;\n\n const visible = entries.slice(0, MAX_SUGGESTIONS);\n const col = getCursorColumn(rl);\n\n // Build the entire output as a single string to avoid interleaving\n // with readline's own writes.\n let buf = '';\n\n for (const entry of visible) {\n const matchLen = partial.length;\n const matchedPart = chalk.cyan('/' + entry.name.slice(0, matchLen));\n const restPart = entry.name.slice(matchLen);\n const desc = chalk.dim(' \\u2014 ' + entry.description);\n\n buf += `\\n\\x1B[2K ${matchedPart}${restPart}${desc}`;\n }\n\n // Move cursor back up N lines and restore column position\n buf += `\\x1B[${visible.length}A\\x1B[${col}G`;\n\n process.stdout.write(buf);\n renderedSuggestionLines = visible.length;\n}\n\n/**\n * Attach a keypress listener that shows/hides inline suggestions\n * while the user types. Returns a cleanup function.\n */\nfunction attachSuggestionListener(rl: readline.Interface): () => void {\n // Reset rendered-line count so stale state from a prior prompt cycle\n // doesn't cause clearSuggestions() to emit bogus escape sequences.\n renderedSuggestionLines = 0;\n\n let active = true;\n\n const onKeypress = (_str: string | undefined, key: { name?: string } | undefined): void => {\n if (!active) return;\n\n // On Enter: clear suggestions IMMEDIATELY, before readline processes\n // the newline. This is critical — once readline prints the newline,\n // the cursor is on a suggestion line and relative clearing breaks.\n if (key?.name === 'return') {\n clearSuggestions(rl);\n return;\n }\n\n // On Tab: clear suggestions (readline's completer will handle display)\n if (key?.name === 'tab') {\n clearSuggestions(rl);\n return;\n }\n\n // For all other keys, update suggestions on nextTick so rl.line\n // reflects the keystroke that just occurred.\n process.nextTick(() => {\n if (!active) return;\n\n const line: string = (rl as unknown as { line: string }).line ?? '';\n\n if (line.startsWith('/') && line.length > 1) {\n renderSuggestions(rl, line.slice(1));\n } else if (line === '/') {\n // Show all commands when just \"/\" is typed\n renderSuggestions(rl, '');\n } else {\n clearSuggestions(rl);\n }\n });\n };\n\n process.stdin.on('keypress', onKeypress);\n\n return () => {\n active = false;\n process.stdin.removeListener('keypress', onKeypress);\n clearSuggestions(rl);\n };\n}\n\n// ── Public API ───────────────────────────────────────────────────────\n\nexport function createReadlineInterface(): readline.Interface {\n const isTTY = process.stdin.isTTY ?? false;\n\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: isTTY,\n completer: isTTY ? slashCompleter : undefined,\n });\n\n // Set up keypress event emission ONCE for the lifetime of this rl instance.\n // Calling this multiple times is problematic: Node internally guards against\n // re-attaching the data→keypress decoder, so subsequent calls silently become\n // no-ops while referencing stale rl state.\n // Only enable keypress events in terminal mode — they depend on raw mode\n // which is unavailable when stdin is not a TTY.\n if (isTTY) {\n readline.emitKeypressEvents(process.stdin, rl);\n }\n\n return rl;\n}\n\nexport function prompt(rl: readline.Interface, options: InputOptions): Promise<string> {\n const promptStr = formatModelPrompt(options.provider, options.model);\n\n return new Promise((resolve) => {\n const onClose = () => {\n cleanup();\n resolve('');\n };\n\n const isTTY = process.stdin.isTTY ?? false;\n const removeSuggestions = isTTY ? attachSuggestionListener(rl) : null;\n\n const cleanup = () => {\n removeSuggestions?.();\n rl.removeListener('close', onClose);\n };\n\n rl.once('close', onClose);\n\n try {\n rl.question(promptStr, (answer) => {\n cleanup();\n resolve(answer.trim());\n });\n } catch {\n cleanup();\n resolve('');\n }\n });\n}\n\nexport function promptSimple(rl: readline.Interface, question: string): Promise<string> {\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n resolve(answer.trim());\n });\n });\n}\n","import { tool } from 'ai';\nimport { z } from 'zod';\nimport {\n readdir,\n readFile as fsReadFile,\n writeFile as fsWriteFile,\n stat,\n mkdir,\n rm,\n lstat,\n} from 'node:fs/promises';\nimport { resolve, relative, join, basename, extname } from 'node:path';\nimport { validatePath } from './security.js';\n\n// Lazy-load canvas (optional native dependency)\nlet canvasModule: typeof import('canvas') | null = null;\nasync function getCanvasModule(): Promise<typeof import('canvas')> {\n if (!canvasModule) {\n try {\n canvasModule = await import('canvas');\n } catch {\n throw new Error('canvas is not installed. Run: npm install canvas');\n }\n }\n return canvasModule;\n}\n\n// ── Default ignore patterns for search/glob operations ──────────────\n\nconst IGNORE_DIRS = new Set([\n 'node_modules',\n '.git',\n '.hg',\n '.svn',\n 'dist',\n 'build',\n '.next',\n '.nuxt',\n 'coverage',\n '__pycache__',\n '.tox',\n '.mypy_cache',\n '.pytest_cache',\n 'vendor',\n '.DS_Store',\n 'Thumbs.db',\n]);\n\n/**\n * Detect binary files by checking for null bytes in the first 8KB.\n */\nfunction isBinaryBuffer(buffer: Buffer): boolean {\n const len = Math.min(buffer.length, 8192);\n for (let i = 0; i < len; i++) {\n if (buffer[i] === 0) return true;\n }\n return false;\n}\n\n// ── MIME type detection ──────────────────────────────────────────────\n\nconst IMAGE_EXTENSIONS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp', '.svg']);\n\nconst MIME_TYPES: Record<string, string> = {\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.webp': 'image/webp',\n '.bmp': 'image/bmp',\n '.svg': 'image/svg+xml',\n '.pdf': 'application/pdf',\n '.zip': 'application/zip',\n '.gz': 'application/gzip',\n '.tar': 'application/x-tar',\n '.7z': 'application/x-7z-compressed',\n '.rar': 'application/vnd.rar',\n '.exe': 'application/x-msdownload',\n '.dll': 'application/x-msdownload',\n '.so': 'application/x-sharedlib',\n '.wasm': 'application/wasm',\n '.json': 'application/json',\n '.xml': 'application/xml',\n '.csv': 'text/csv',\n '.md': 'text/markdown',\n '.html': 'text/html',\n '.htm': 'text/html',\n '.css': 'text/css',\n '.js': 'text/javascript',\n '.mjs': 'text/javascript',\n '.ts': 'text/typescript',\n '.tsx': 'text/typescript',\n '.jsx': 'text/javascript',\n '.yaml': 'text/yaml',\n '.yml': 'text/yaml',\n '.toml': 'text/plain',\n '.txt': 'text/plain',\n '.log': 'text/plain',\n '.sh': 'text/x-shellscript',\n '.py': 'text/x-python',\n '.rb': 'text/x-ruby',\n '.go': 'text/x-go',\n '.rs': 'text/x-rust',\n '.java': 'text/x-java',\n '.c': 'text/x-c',\n '.cpp': 'text/x-c++',\n '.h': 'text/x-c',\n '.mp3': 'audio/mpeg',\n '.wav': 'audio/wav',\n '.mp4': 'video/mp4',\n '.mov': 'video/quicktime',\n '.avi': 'video/x-msvideo',\n '.mkv': 'video/x-matroska',\n '.ico': 'image/x-icon',\n '.ttf': 'font/ttf',\n '.otf': 'font/otf',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n};\n\nexport function getMimeType(filePath: string): string {\n const ext = extname(filePath).toLowerCase();\n return MIME_TYPES[ext] || 'application/octet-stream';\n}\n\nfunction isImageExtension(filePath: string): boolean {\n return IMAGE_EXTENSIONS.has(extname(filePath).toLowerCase());\n}\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction getMimeDescription(mimeType: string): string {\n if (mimeType.startsWith('image/')) return 'image';\n if (mimeType.startsWith('video/')) return 'video';\n if (mimeType.startsWith('audio/')) return 'audio';\n if (mimeType.startsWith('font/')) return 'font';\n if (mimeType === 'application/pdf') return 'PDF document';\n if (mimeType.includes('zip') || mimeType.includes('compressed') || mimeType.includes('tar') || mimeType.includes('7z') || mimeType.includes('rar')) return 'archive';\n if (mimeType.includes('msdownload') || mimeType.includes('executable')) return 'executable';\n if (mimeType === 'application/wasm') return 'WebAssembly module';\n return 'binary';\n}\n\n/**\n * Simple glob matching (supports * and ** patterns).\n * Used when Node's fs.glob is unavailable.\n */\nfunction matchesGlob(filePath: string, pattern: string): boolean {\n // Normalize separators\n const normalized = filePath.replace(/\\\\/g, '/');\n const normalizedPattern = pattern.replace(/\\\\/g, '/');\n\n // Convert glob to regex\n let regexStr = '^';\n let i = 0;\n while (i < normalizedPattern.length) {\n const char = normalizedPattern[i];\n if (char === '*' && normalizedPattern[i + 1] === '*') {\n // ** matches any path segments\n if (normalizedPattern[i + 2] === '/') {\n regexStr += '(?:.*/)?';\n i += 3;\n } else {\n regexStr += '.*';\n i += 2;\n }\n } else if (char === '*') {\n regexStr += '[^/]*';\n i++;\n } else if (char === '?') {\n regexStr += '[^/]';\n i++;\n } else if (char === '.') {\n regexStr += '\\\\.';\n i++;\n } else {\n regexStr += char;\n i++;\n }\n }\n regexStr += '$';\n\n return new RegExp(regexStr, 'i').test(normalized);\n}\n\n// ── listFiles ───────────────────────────────────────────────────────\n\nexport const listFiles = tool({\n description:\n 'List files and directories at the given path. Returns names with a trailing \"/\" for directories. ' +\n 'Defaults to the current working directory if no path is provided.',\n inputSchema: z.object({\n path: z\n .string()\n .optional()\n .describe('Absolute or relative directory path. Defaults to cwd.'),\n recursive: z\n .boolean()\n .optional()\n .describe('If true, list files recursively up to maxDepth (default 3).'),\n maxDepth: z\n .number()\n .optional()\n .describe('Max recursion depth when recursive is true. Default 3.'),\n maxEntries: z\n .number()\n .optional()\n .describe('Maximum number of entries to return. Default 200.'),\n }),\n execute: async ({ path, recursive, maxDepth, maxEntries }) => {\n try {\n const target = resolve(path ?? '.');\n const pathCheck = validatePath(target);\n if (!pathCheck.allowed) {\n return { success: false, error: pathCheck.error };\n }\n const limit = maxEntries ?? 200;\n const depth = maxDepth ?? 3;\n\n if (!recursive) {\n const entries = await readdir(target, { withFileTypes: true });\n const items = entries.slice(0, limit).map((e) => ({\n name: e.name + (e.isDirectory() ? '/' : ''),\n type: e.isDirectory() ? ('directory' as const) : ('file' as const),\n }));\n return {\n success: true,\n path: target,\n entries: items,\n totalEntries: entries.length,\n truncated: entries.length > limit,\n };\n }\n\n // Recursive listing\n const items: Array<{ name: string; type: 'file' | 'directory' }> = [];\n\n async function walk(dir: string, currentDepth: number): Promise<void> {\n if (items.length >= limit || currentDepth > depth) return;\n\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return; // Skip unreadable directories\n }\n\n for (const entry of entries) {\n if (items.length >= limit) break;\n if (IGNORE_DIRS.has(entry.name)) continue;\n\n const relPath = relative(target, join(dir, entry.name));\n if (entry.isDirectory()) {\n items.push({ name: relPath + '/', type: 'directory' });\n await walk(join(dir, entry.name), currentDepth + 1);\n } else {\n items.push({ name: relPath, type: 'file' });\n }\n }\n }\n\n await walk(target, 1);\n return {\n success: true,\n path: target,\n entries: items,\n totalEntries: items.length,\n truncated: items.length >= limit,\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── readFile ────────────────────────────────────────────────────────\n\nexport const readFileContents = tool({\n description:\n 'Read a file. For text files, returns line-numbered output with offset/limit support. ' +\n 'For image files (.png, .jpg, .jpeg, .gif, .webp, .bmp, .svg), returns image metadata ' +\n '(dimensions, size, format) and base64 data so you can \"see\" the image. ' +\n 'For other binary files, returns metadata (size, MIME type) without content.',\n inputSchema: z.object({\n path: z.string().describe('Absolute or relative path to the file to read.'),\n offset: z\n .number()\n .optional()\n .describe('Line number to start reading from (1-based). Default 1. Text files only.'),\n limit: z\n .number()\n .optional()\n .describe('Maximum number of lines to return. Default: all lines. Text files only.'),\n }),\n execute: async ({ path, offset, limit }) => {\n try {\n const target = resolve(path);\n const pathCheck = validatePath(target);\n if (!pathCheck.allowed) {\n return { success: false, error: pathCheck.error };\n }\n\n const info = await stat(target);\n if (info.isDirectory()) {\n return { success: false, error: `\"${target}\" is a directory, not a file. Use listFiles instead.` };\n }\n\n const mimeType = getMimeType(target);\n const ext = extname(target).toLowerCase();\n\n // ── Image files ──────────────────────────────────────────\n if (isImageExtension(target)) {\n const buffer = await fsReadFile(target);\n const base64 = buffer.toString('base64');\n const base64DataUrl = `data:${mimeType};base64,${base64}`;\n\n // Get dimensions using canvas loadImage\n let width = 0;\n let height = 0;\n try {\n const { loadImage } = await getCanvasModule();\n const img = await loadImage(buffer);\n width = img.width;\n height = img.height;\n } catch {\n // SVGs or corrupt images may fail, or canvas not installed — dimensions will be 0\n }\n\n return {\n success: true,\n type: 'image' as const,\n path: target,\n mimeType,\n format: ext.replace('.', '').toUpperCase(),\n size: info.size,\n sizeFormatted: formatSize(info.size),\n width,\n height,\n base64DataUrl,\n ...(pathCheck.warning ? { warning: pathCheck.warning } : {}),\n };\n }\n\n // ── Read raw buffer to check for binary ──────────────────\n const buffer = await fsReadFile(target);\n if (isBinaryBuffer(buffer)) {\n const desc = getMimeDescription(mimeType);\n return {\n success: true,\n type: 'binary' as const,\n path: target,\n mimeType,\n size: info.size,\n sizeFormatted: formatSize(info.size),\n description: `Binary file: ${formatSize(info.size)} ${desc}`,\n ...(pathCheck.warning ? { warning: pathCheck.warning } : {}),\n };\n }\n\n // ── Text files ───────────────────────────────────────────\n const fullContent = buffer.toString('utf-8');\n const allLines = fullContent.split('\\n');\n const totalLines = allLines.length;\n\n const startLine = Math.max(1, offset ?? 1);\n const endLine = limit !== undefined ? startLine + limit - 1 : totalLines;\n\n const selectedLines = allLines.slice(startLine - 1, endLine);\n const numbered = selectedLines\n .map((line, i) => `${String(startLine + i).padStart(6)} ${line}`)\n .join('\\n');\n\n return {\n success: true,\n type: 'text' as const,\n path: target,\n mimeType,\n content: numbered,\n size: info.size,\n totalLines,\n fromLine: startLine,\n toLine: Math.min(endLine, totalLines),\n truncated: endLine < totalLines,\n ...(pathCheck.warning ? { warning: pathCheck.warning } : {}),\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n toModelOutput({ output }) {\n const obj = output as Record<string, unknown>;\n\n // For image files, send base64 data as an image content part so the model can see it\n if (obj.type === 'image' && typeof obj.base64DataUrl === 'string') {\n // Extract raw base64 (strip data URL prefix)\n const base64 = (obj.base64DataUrl as string).replace(/^data:[^;]+;base64,/, '');\n const mimeType = obj.mimeType as string;\n\n // Build a text summary alongside the image\n const summary = `Image: ${obj.path} | ${obj.width}x${obj.height} | ${obj.format} | ${obj.sizeFormatted}`;\n\n return {\n type: 'content',\n value: [\n { type: 'text', text: summary },\n { type: 'image-data', data: base64, mediaType: mimeType },\n ],\n };\n }\n\n // For non-image results, return as JSON (default behavior)\n // Strip base64DataUrl from the JSON to keep it compact\n const { base64DataUrl: _, ...rest } = obj;\n return {\n type: 'json',\n value: rest as import('@ai-sdk/provider').JSONValue,\n };\n },\n});\n\n// ── writeFile ───────────────────────────────────────────────────────\n\nexport const writeFileContents = tool({\n description:\n 'Write text content to a file, creating it if it does not exist or overwriting if it does. ' +\n 'Parent directories are created automatically.',\n inputSchema: z.object({\n path: z.string().describe('Absolute or relative path to the file to write.'),\n content: z.string().describe('The full text content to write to the file.'),\n }),\n execute: async ({ path, content }) => {\n try {\n const target = resolve(path);\n const pathCheck = validatePath(target);\n if (!pathCheck.allowed) {\n return { success: false, error: pathCheck.error };\n }\n\n // Ensure parent directory exists\n const parentDir = resolve(target, '..');\n await mkdir(parentDir, { recursive: true });\n\n await fsWriteFile(target, content, 'utf-8');\n return {\n success: true,\n path: target,\n bytesWritten: Buffer.byteLength(content, 'utf-8'),\n ...(pathCheck.warning ? { warning: pathCheck.warning } : {}),\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── editFile ────────────────────────────────────────────────────────\n\nexport const editFile = tool({\n description:\n 'Perform a surgical string replacement in a file (oldString → newString). ' +\n 'If oldString is not found, returns an error. If not unique and replaceAll is false, returns error with line numbers of all matches.',\n inputSchema: z.object({\n path: z.string().describe('Absolute or relative path to the file.'),\n oldString: z.string().describe('The exact text to find and replace.'),\n newString: z.string().describe('The replacement text.'),\n replaceAll: z\n .boolean()\n .optional()\n .describe('If true, replace all occurrences. Default false (unique match required).'),\n }),\n execute: async ({ path, oldString, newString, replaceAll }) => {\n try {\n const target = resolve(path);\n const pathCheck = validatePath(target);\n if (!pathCheck.allowed) {\n return { success: false, error: pathCheck.error };\n }\n\n const content = await fsReadFile(target, 'utf-8');\n\n if (!content.includes(oldString)) {\n return { success: false, error: 'oldString not found in file.' };\n }\n\n if (!replaceAll) {\n // Check uniqueness\n const lines = content.split('\\n');\n const matchLines: number[] = [];\n let searchFrom = 0;\n while (true) {\n const idx = content.indexOf(oldString, searchFrom);\n if (idx === -1) break;\n // Count which line this is on\n const lineNum = content.slice(0, idx).split('\\n').length;\n matchLines.push(lineNum);\n searchFrom = idx + 1;\n }\n\n if (matchLines.length > 1) {\n return {\n success: false,\n error: `oldString is not unique — found ${matchLines.length} occurrences at lines: ${matchLines.join(', ')}. Use replaceAll: true or provide a more specific oldString.`,\n };\n }\n\n // Single match — replace\n const newContent = content.replace(oldString, newString);\n await fsWriteFile(target, newContent, 'utf-8');\n return {\n success: true,\n path: target,\n replacements: 1,\n };\n }\n\n // Replace all occurrences\n const newContent = content.split(oldString).join(newString);\n const count = (content.split(oldString).length - 1);\n await fsWriteFile(target, newContent, 'utf-8');\n return {\n success: true,\n path: target,\n replacements: count,\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── createDirectory ─────────────────────────────────────────────────\n\nexport const createDirectory = tool({\n description: 'Create a directory, including any necessary parent directories.',\n inputSchema: z.object({\n path: z.string().describe('Absolute or relative path of the directory to create.'),\n }),\n execute: async ({ path }) => {\n try {\n const target = resolve(path);\n const pathCheck = validatePath(target);\n if (!pathCheck.allowed) {\n return { success: false, error: pathCheck.error };\n }\n\n await mkdir(target, { recursive: true });\n return { success: true, path: target };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── deleteFile ──────────────────────────────────────────────────────\n\nexport const deleteFile = tool({\n description:\n 'Delete a file or directory. For directories, set recursive to true.',\n inputSchema: z.object({\n path: z.string().describe('Absolute or relative path to delete.'),\n recursive: z\n .boolean()\n .optional()\n .describe('If true, recursively delete directory contents. Required for non-empty directories.'),\n }),\n execute: async ({ path, recursive }) => {\n try {\n const target = resolve(path);\n const pathCheck = validatePath(target);\n if (!pathCheck.allowed) {\n return { success: false, error: pathCheck.error };\n }\n\n const info = await lstat(target);\n const isDir = info.isDirectory();\n\n await rm(target, { recursive: recursive ?? false, force: false });\n return {\n success: true,\n path: target,\n type: isDir ? 'directory' : 'file',\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── searchFiles ─────────────────────────────────────────────────────\n\nexport const searchFiles = tool({\n description:\n 'Search for text/regex in files recursively. Similar to grep. ' +\n 'Skips binary files, node_modules, .git, and other common ignore directories.',\n inputSchema: z.object({\n pattern: z.string().describe('Regex pattern to search for.'),\n path: z\n .string()\n .optional()\n .describe('Directory to search in. Defaults to cwd.'),\n glob: z\n .string()\n .optional()\n .describe('Glob pattern to filter files (e.g., \"*.ts\", \"**/*.json\").'),\n contextLines: z\n .number()\n .optional()\n .describe('Number of context lines before and after each match. Default 0.'),\n maxResults: z\n .number()\n .optional()\n .describe('Maximum number of matches to return. Default 100.'),\n caseSensitive: z\n .boolean()\n .optional()\n .describe('Case-sensitive search. Default true.'),\n }),\n execute: async ({ pattern, path, glob, contextLines, maxResults, caseSensitive }) => {\n try {\n const target = resolve(path ?? '.');\n const limit = maxResults ?? 100;\n const ctx = contextLines ?? 0;\n const flags = (caseSensitive ?? true) ? '' : 'i';\n\n let regex: RegExp;\n try {\n regex = new RegExp(pattern, flags);\n } catch (e) {\n return { success: false, error: `Invalid regex: ${e instanceof Error ? e.message : String(e)}` };\n }\n\n const results: Array<{\n file: string;\n line: number;\n match: string;\n context?: string[];\n }> = [];\n\n async function searchDir(dir: string): Promise<void> {\n if (results.length >= limit) return;\n\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (results.length >= limit) break;\n if (IGNORE_DIRS.has(entry.name)) continue;\n\n const fullPath = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n await searchDir(fullPath);\n continue;\n }\n\n // Apply glob filter\n if (glob) {\n const relPath = relative(target, fullPath);\n if (!matchesGlob(relPath, glob) && !matchesGlob(basename(fullPath), glob)) {\n continue;\n }\n }\n\n try {\n const buf = await fsReadFile(fullPath);\n if (isBinaryBuffer(buf)) continue;\n\n const content = buf.toString('utf-8');\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n if (results.length >= limit) break;\n if (regex.test(lines[i])) {\n const result: (typeof results)[number] = {\n file: relative(target, fullPath),\n line: i + 1,\n match: lines[i],\n };\n\n if (ctx > 0) {\n const start = Math.max(0, i - ctx);\n const end = Math.min(lines.length - 1, i + ctx);\n result.context = lines.slice(start, end + 1);\n }\n\n results.push(result);\n }\n }\n } catch {\n // Skip unreadable files\n }\n }\n }\n\n await searchDir(target);\n\n return {\n success: true,\n searchPath: target,\n pattern,\n matches: results,\n totalMatches: results.length,\n truncated: results.length >= limit,\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── globFiles ───────────────────────────────────────────────────────\n\nexport const globFiles = tool({\n description:\n 'Find files matching a glob pattern. Skips node_modules, .git, and common ignore directories.',\n inputSchema: z.object({\n pattern: z.string().describe('Glob pattern (e.g., \"**/*.ts\", \"src/**/*.json\").'),\n path: z\n .string()\n .optional()\n .describe('Directory to search in. Defaults to cwd.'),\n maxResults: z\n .number()\n .optional()\n .describe('Maximum files to return. Default 200.'),\n }),\n execute: async ({ pattern, path, maxResults }) => {\n try {\n const target = resolve(path ?? '.');\n const limit = maxResults ?? 200;\n const files: string[] = [];\n\n async function walk(dir: string): Promise<void> {\n if (files.length >= limit) return;\n\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (files.length >= limit) break;\n if (IGNORE_DIRS.has(entry.name)) continue;\n\n const fullPath = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n await walk(fullPath);\n } else {\n const relPath = relative(target, fullPath);\n if (matchesGlob(relPath, pattern) || matchesGlob(basename(fullPath), pattern)) {\n files.push(relPath);\n }\n }\n }\n }\n\n await walk(target);\n\n return {\n success: true,\n searchPath: target,\n pattern,\n files,\n totalFiles: files.length,\n truncated: files.length >= limit,\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── fileStats ───────────────────────────────────────────────────────\n\n// ── viewImage ───────────────────────────────────────────────────────\n\nexport const viewImage = tool({\n description:\n 'View and analyze an image file. Returns dimensions, file size, format, dominant colors, ' +\n 'and optionally base64 data so you can \"see\" the image contents. ' +\n 'Use this for detailed image analysis — for quick metadata, use readFile instead.',\n inputSchema: z.object({\n path: z.string().describe('Absolute or relative path to the image file.'),\n describe: z\n .boolean()\n .optional()\n .describe('If true (default), include base64 data so you can see the image. Set false for metadata only.'),\n }),\n execute: async ({ path, describe }) => {\n try {\n const target = resolve(path);\n const pathCheck = validatePath(target);\n if (!pathCheck.allowed) {\n return { success: false, error: pathCheck.error };\n }\n\n if (!isImageExtension(target)) {\n return { success: false, error: `\"${target}\" is not a recognized image file. Supported: ${[...IMAGE_EXTENSIONS].join(', ')}` };\n }\n\n const info = await stat(target);\n const mimeType = getMimeType(target);\n const ext = extname(target).toLowerCase();\n const buffer = await fsReadFile(target);\n\n // Load image to get dimensions and sample colors\n let width = 0;\n let height = 0;\n let dominantColors: string[] = [];\n\n try {\n const canvasMod = await getCanvasModule();\n const img = await canvasMod.loadImage(buffer);\n width = img.width;\n height = img.height;\n\n // Sample dominant colors by reading pixels at regular intervals\n const { createCanvas: nodeCreateCanvas } = canvasMod;\n const sampleCanvas = nodeCreateCanvas(img.width, img.height);\n const ctx = sampleCanvas.getContext('2d');\n ctx.drawImage(img, 0, 0);\n\n // Sample pixels in a grid pattern\n const sampleSize = Math.max(1, Math.floor(Math.min(width, height) / 10));\n const colorCounts = new Map<string, number>();\n\n for (let sy = 0; sy < height; sy += sampleSize) {\n for (let sx = 0; sx < width; sx += sampleSize) {\n const pixel = ctx.getImageData(sx, sy, 1, 1).data;\n // Quantize to reduce noise: round each channel to nearest 32\n const r = Math.round(pixel[0] / 32) * 32;\n const g = Math.round(pixel[1] / 32) * 32;\n const b = Math.round(pixel[2] / 32) * 32;\n const key = `rgb(${r},${g},${b})`;\n colorCounts.set(key, (colorCounts.get(key) ?? 0) + 1);\n }\n }\n\n // Sort by frequency and take top 5\n dominantColors = [...colorCounts.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([color]) => color);\n } catch {\n // Dimension/color extraction failed — continue with zeros\n }\n\n const includeData = describe !== false;\n let base64DataUrl: string | undefined;\n if (includeData) {\n const base64 = buffer.toString('base64');\n base64DataUrl = `data:${mimeType};base64,${base64}`;\n }\n\n return {\n success: true,\n path: target,\n width,\n height,\n format: ext.replace('.', '').toUpperCase(),\n mimeType,\n size: info.size,\n sizeFormatted: formatSize(info.size),\n dominantColors,\n ...(base64DataUrl ? { base64DataUrl } : {}),\n ...(pathCheck.warning ? { warning: pathCheck.warning } : {}),\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n toModelOutput({ output }) {\n const obj = output as Record<string, unknown>;\n\n if (obj.success && typeof obj.base64DataUrl === 'string') {\n const base64 = (obj.base64DataUrl as string).replace(/^data:[^;]+;base64,/, '');\n const mimeType = obj.mimeType as string;\n const colors = (obj.dominantColors as string[]) ?? [];\n\n const summary = [\n `Image: ${obj.path}`,\n `Dimensions: ${obj.width}x${obj.height}`,\n `Format: ${obj.format} | Size: ${obj.sizeFormatted}`,\n colors.length > 0 ? `Dominant colors: ${colors.join(', ')}` : '',\n ].filter(Boolean).join('\\n');\n\n return {\n type: 'content' as const,\n value: [\n { type: 'text' as const, text: summary },\n { type: 'image-data' as const, data: base64, mediaType: mimeType },\n ],\n };\n }\n\n // Metadata-only or error — return as JSON\n const { base64DataUrl: _, ...rest } = obj;\n return {\n type: 'json' as const,\n value: rest as import('@ai-sdk/provider').JSONValue,\n };\n },\n});\n\n// ── fileStats ───────────────────────────────────────────────────────\n\nexport const fileStats = tool({\n description:\n 'Get file metadata: size, modification time, creation time, type, and permissions.',\n inputSchema: z.object({\n path: z.string().describe('Absolute or relative path to the file or directory.'),\n }),\n execute: async ({ path }) => {\n try {\n const target = resolve(path);\n const info = await stat(target);\n\n return {\n success: true,\n path: target,\n size: info.size,\n isFile: info.isFile(),\n isDirectory: info.isDirectory(),\n isSymlink: info.isSymbolicLink(),\n modified: info.mtime.toISOString(),\n created: info.birthtime.toISOString(),\n accessed: info.atime.toISOString(),\n mode: '0' + (info.mode & 0o777).toString(8),\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n","import { resolve, normalize } from 'node:path';\nimport { homedir } from 'node:os';\n\n/** Paths that should never be read or written by tools. */\nconst BLOCKED_PATH_PATTERNS = [\n /[\\\\/]\\.ssh[\\\\/]/i,\n /[\\\\/]\\.gnupg[\\\\/]/i,\n /[\\\\/]\\.aws[\\\\/]credentials/i,\n /[\\\\/]\\.docker[\\\\/]config\\.json/i,\n /[\\\\/]\\.kube[\\\\/]config/i,\n];\n\n/** Paths that trigger a warning but are not blocked. */\nconst WARN_PATH_PATTERNS = [\n /[\\\\/]\\.env$/i,\n /[\\\\/]\\.env\\..+$/i,\n];\n\nexport interface PathValidation {\n allowed: boolean;\n warning?: string;\n error?: string;\n}\n\n/**\n * Validate a file path for safety. Blocks access to sensitive directories\n * like ~/.ssh, ~/.gnupg, etc. Warns on .env files.\n */\nexport function validatePath(filePath: string): PathValidation {\n const resolved = resolve(filePath);\n const normalized = normalize(resolved);\n const home = homedir();\n\n // Ensure the resolved path doesn't escape via symlink tricks — we can only\n // do a string-level check here; real symlink resolution would need lstat.\n const fullPath = normalized.replace(/\\\\/g, '/');\n const homePath = home.replace(/\\\\/g, '/');\n\n for (const pattern of BLOCKED_PATH_PATTERNS) {\n if (pattern.test(fullPath)) {\n return {\n allowed: false,\n error: `Access denied: path \"${resolved}\" matches a blocked sensitive path pattern.`,\n };\n }\n }\n\n // Block the entire ~/.ssh and ~/.gnupg directories\n const sshDir = `${homePath}/.ssh`;\n const gnupgDir = `${homePath}/.gnupg`;\n if (\n fullPath.startsWith(sshDir + '/') ||\n fullPath === sshDir ||\n fullPath.startsWith(gnupgDir + '/') ||\n fullPath === gnupgDir\n ) {\n return {\n allowed: false,\n error: `Access denied: path \"${resolved}\" is inside a sensitive directory.`,\n };\n }\n\n for (const pattern of WARN_PATH_PATTERNS) {\n if (pattern.test(fullPath)) {\n return {\n allowed: true,\n warning: `Warning: accessing .env file at \"${resolved}\". Be careful not to expose secrets.`,\n };\n }\n }\n\n return { allowed: true };\n}\n\n/** Shell commands that should always be blocked. */\nconst BLOCKED_COMMAND_PATTERNS = [\n // Fork bombs\n /:\\(\\)\\{.*\\|.*&.*\\};:/,\n /fork\\s*bomb/i,\n // Destructive rm patterns\n /rm\\s+(-[a-zA-Z]*)?-[a-zA-Z]*r[a-zA-Z]*f[a-zA-Z]*\\s+\\//,\n /rm\\s+(-[a-zA-Z]*)?-[a-zA-Z]*f[a-zA-Z]*r[a-zA-Z]*\\s+\\//,\n /rm\\s+-rf\\s+\\/(?!\\S)/,\n /rm\\s+-rf\\s+~\\s*$/,\n /rm\\s+-rf\\s+\\$HOME\\b/,\n /rm\\s+-rf\\s+%USERPROFILE%/i,\n // Format / disk destruction\n /mkfs\\./,\n /dd\\s+if=.*of=\\/dev\\//,\n /format\\s+[a-zA-Z]:\\s*\\/y/i,\n // Chmod 777 on root\n /chmod\\s+-R\\s+777\\s+\\//,\n // Curl to shell (common malware pattern)\n /curl\\s+.*\\|\\s*(bash|sh|zsh)/,\n /wget\\s+.*\\|\\s*(bash|sh|zsh)/,\n];\n\n/**\n * Check if a command matches the blocklist of dangerous commands.\n * Returns an error message if blocked, or undefined if allowed.\n */\nexport function isBlockedCommand(command: string): string | undefined {\n const trimmed = command.trim();\n\n for (const pattern of BLOCKED_COMMAND_PATTERNS) {\n if (pattern.test(trimmed)) {\n return `Command blocked: matches dangerous pattern. Command: \"${trimmed.slice(0, 80)}...\"`;\n }\n }\n\n return undefined;\n}\n\n/**\n * Private/reserved IP ranges that should be blocked for SSRF protection.\n * Covers: loopback, link-local, private ranges (RFC 1918), and IPv6 equivalents.\n */\nconst PRIVATE_IP_PATTERNS = [\n /^127\\./, // 127.0.0.0/8\n /^10\\./, // 10.0.0.0/8\n /^172\\.(1[6-9]|2\\d|3[0-1])\\./, // 172.16.0.0/12\n /^192\\.168\\./, // 192.168.0.0/16\n /^169\\.254\\./, // 169.254.0.0/16 (link-local)\n /^0\\./, // 0.0.0.0/8\n /^::1$/, // IPv6 loopback\n /^fe80:/i, // IPv6 link-local\n /^fc00:/i, // IPv6 unique local\n /^fd[0-9a-f]{2}:/i, // IPv6 unique local\n];\n\n/**\n * Check if a hostname/IP is a private/reserved address.\n * Used for SSRF protection in web fetch tools.\n */\nexport function isPrivateIP(hostname: string): boolean {\n const h = hostname.toLowerCase().trim();\n\n if (h === 'localhost' || h === 'localhost.localdomain') {\n return true;\n }\n\n // Strip IPv6 brackets\n const stripped = h.startsWith('[') && h.endsWith(']') ? h.slice(1, -1) : h;\n\n for (const pattern of PRIVATE_IP_PATTERNS) {\n if (pattern.test(stripped)) {\n return true;\n }\n }\n\n return false;\n}\n","import { tool } from 'ai';\nimport { z } from 'zod';\nimport { exec } from 'node:child_process';\nimport { resolve } from 'node:path';\nimport { isBlockedCommand } from './security.js';\n\nconst MAX_OUTPUT_BYTES = 256 * 1024; // 256 KB cap on stdout/stderr\n\nexport const runCommand = tool({\n description:\n 'Execute a shell command and return its stdout, stderr, exit code, and duration. ' +\n 'Use this to run build tools, scripts, linters, etc. ' +\n 'Dangerous commands (rm -rf /, fork bombs, etc.) are blocked.',\n inputSchema: z.object({\n command: z.string().describe('The shell command to execute.'),\n cwd: z\n .string()\n .optional()\n .describe('Working directory for the command. Defaults to process cwd.'),\n timeoutMs: z\n .number()\n .optional()\n .describe('Timeout in milliseconds. Defaults to 30 000 (30 s).'),\n shell: z\n .string()\n .optional()\n .describe(\n 'Shell to use. Defaults to powershell.exe on Windows, bash on Unix.',\n ),\n }),\n execute: async ({ command, cwd, timeoutMs, shell }) => {\n try {\n // Check command blocklist\n const blocked = isBlockedCommand(command);\n if (blocked) {\n return { success: false, stdout: '', stderr: blocked, exitCode: 1 };\n }\n\n // Validate shell against allowlist to prevent arbitrary binary execution\n const ALLOWED_SHELLS = new Set([\n 'bash', 'sh', 'zsh', 'fish',\n 'powershell', 'pwsh', 'cmd', 'cmd.exe', 'powershell.exe', 'pwsh.exe',\n '/bin/bash', '/bin/sh', '/bin/zsh', '/usr/bin/fish',\n ]);\n if (shell !== undefined && !ALLOWED_SHELLS.has(shell)) {\n return {\n success: false,\n stdout: '',\n stderr: `Shell \"${shell}\" is not allowed. Allowed shells: ${[...ALLOWED_SHELLS].join(', ')}`,\n exitCode: 1,\n durationMs: 0,\n };\n }\n\n const timeout = timeoutMs ?? 30_000;\n const workDir = cwd ? resolve(cwd) : process.cwd();\n const defaultShell =\n process.platform === 'win32' ? 'powershell.exe' : '/bin/bash';\n const shellToUse = shell ?? defaultShell;\n const startTime = Date.now();\n\n return await new Promise<{\n success: boolean;\n stdout: string;\n stderr: string;\n exitCode: number;\n durationMs: number;\n timedOut?: boolean;\n }>((resolvePromise) => {\n const child = exec(\n command,\n {\n cwd: workDir,\n timeout,\n maxBuffer: MAX_OUTPUT_BYTES,\n shell: shellToUse,\n },\n (error, stdout, stderr) => {\n const durationMs = Date.now() - startTime;\n\n let exitCode = 0;\n if (error) {\n // error.code on exec errors is a string errno (e.g. 'ERR_CHILD_PROCESS_STDIO_MAXBUFFER'),\n // NOT a numeric exit code. Use the status property from the child process, or default to 1.\n const errorAny = error as unknown as Record<string, unknown>;\n if (typeof errorAny.status === 'number') {\n exitCode = errorAny.status;\n } else if (typeof errorAny.code === 'number') {\n exitCode = errorAny.code;\n } else {\n exitCode = 1;\n }\n }\n\n const timedOut =\n error &&\n 'killed' in error &&\n (error as { killed?: boolean }).killed;\n\n resolvePromise({\n success: exitCode === 0,\n stdout: stdout.slice(0, MAX_OUTPUT_BYTES),\n stderr: stderr.slice(0, MAX_OUTPUT_BYTES),\n exitCode,\n durationMs,\n ...(timedOut ? { timedOut: true } : {}),\n });\n },\n );\n\n if (!child) {\n resolvePromise({\n success: false,\n stdout: '',\n stderr: 'Failed to spawn process',\n exitCode: 1,\n durationMs: Date.now() - startTime,\n });\n }\n });\n } catch (error) {\n return {\n success: false,\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 1,\n durationMs: 0,\n };\n }\n },\n});\n","import { tool } from 'ai';\nimport { z } from 'zod';\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execFileAsync = promisify(execFile);\n\nconst MAX_OUTPUT = 100 * 1024; // 100 KB\n\n/**\n * Run a git command safely via execFile (no shell injection risk).\n */\nasync function runGit(\n args: string[],\n options?: { cwd?: string; maxBuffer?: number },\n): Promise<{ stdout: string; stderr: string }> {\n const result = await execFileAsync('git', args, {\n cwd: options?.cwd ?? process.cwd(),\n maxBuffer: options?.maxBuffer ?? MAX_OUTPUT,\n });\n return { stdout: result.stdout, stderr: result.stderr };\n}\n\n// ── gitStatus ───────────────────────────────────────────────────────\n\nexport const gitStatus = tool({\n description:\n 'Get the current git status including branch info, staged/unstaged changes, and untracked files.',\n inputSchema: z.object({\n cwd: z\n .string()\n .optional()\n .describe('Working directory. Defaults to process cwd.'),\n }),\n execute: async ({ cwd }) => {\n try {\n const { stdout } = await runGit(\n ['status', '--porcelain=v2', '--branch'],\n { cwd },\n );\n\n const lines = stdout.split('\\n').filter(Boolean);\n let branch = '';\n let upstream = '';\n let ahead = 0;\n let behind = 0;\n const staged: string[] = [];\n const modified: string[] = [];\n const untracked: string[] = [];\n const other: string[] = [];\n\n for (const line of lines) {\n if (line.startsWith('# branch.head ')) {\n branch = line.slice('# branch.head '.length);\n } else if (line.startsWith('# branch.upstream ')) {\n upstream = line.slice('# branch.upstream '.length);\n } else if (line.startsWith('# branch.ab ')) {\n const match = line.match(/\\+(\\d+) -(\\d+)/);\n if (match) {\n ahead = parseInt(match[1], 10);\n behind = parseInt(match[2], 10);\n }\n } else if (line.startsWith('1 ') || line.startsWith('2 ')) {\n // Changed entry\n const parts = line.split(' ');\n const xy = parts[1]; // XY status\n const filePath = line.startsWith('2 ')\n ? parts.slice(9).join(' ') // renamed files have path at end\n : parts.slice(8).join(' ');\n\n if (xy[0] !== '.') staged.push(filePath);\n if (xy[1] !== '.') modified.push(filePath);\n } else if (line.startsWith('? ')) {\n untracked.push(line.slice(2));\n } else if (line.startsWith('u ')) {\n // Unmerged entry\n const parts = line.split(' ');\n other.push(parts.slice(10).join(' '));\n }\n }\n\n return {\n success: true,\n branch,\n upstream: upstream || undefined,\n ahead,\n behind,\n staged,\n modified,\n untracked,\n unmerged: other.length > 0 ? other : undefined,\n clean: staged.length === 0 && modified.length === 0 && untracked.length === 0 && other.length === 0,\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── gitDiff ─────────────────────────────────────────────────────────\n\nexport const gitDiff = tool({\n description:\n 'Show git diff output. Can diff working tree, staged changes, or between references.',\n inputSchema: z.object({\n target: z\n .string()\n .optional()\n .describe(\n 'What to diff: \"staged\" for --cached, a ref like \"HEAD~1\", or a range like \"main..feature\". Defaults to working tree diff.',\n ),\n path: z\n .string()\n .optional()\n .describe('Limit diff to a specific file or directory path.'),\n cwd: z\n .string()\n .optional()\n .describe('Working directory. Defaults to process cwd.'),\n }),\n execute: async ({ target, path, cwd }) => {\n try {\n const args = ['diff'];\n\n if (target === 'staged') {\n args.push('--cached');\n } else if (target) {\n args.push(target);\n }\n\n if (path) {\n args.push('--', path);\n }\n\n const { stdout } = await runGit(args, { cwd, maxBuffer: MAX_OUTPUT });\n\n let output = stdout;\n let truncated = false;\n if (output.length > MAX_OUTPUT) {\n output = output.slice(0, MAX_OUTPUT);\n truncated = true;\n }\n\n return {\n success: true,\n diff: output,\n truncated,\n empty: output.trim().length === 0,\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── gitLog ──────────────────────────────────────────────────────────\n\nexport const gitLog = tool({\n description:\n 'Show git commit history. Returns structured commit objects.',\n inputSchema: z.object({\n maxCount: z\n .number()\n .optional()\n .describe('Maximum commits to return. Default 20.'),\n oneline: z\n .boolean()\n .optional()\n .describe('If true, return short one-line format.'),\n path: z\n .string()\n .optional()\n .describe('Limit log to a specific file or directory.'),\n author: z\n .string()\n .optional()\n .describe('Filter by author name/email.'),\n since: z\n .string()\n .optional()\n .describe('Show commits since date (e.g., \"2024-01-01\", \"1 week ago\").'),\n cwd: z\n .string()\n .optional()\n .describe('Working directory. Defaults to process cwd.'),\n }),\n execute: async ({ maxCount, oneline, path, author, since, cwd }) => {\n try {\n const limit = maxCount ?? 20;\n\n if (oneline) {\n const args = ['log', `--max-count=${limit}`, '--oneline'];\n if (author) args.push(`--author=${author}`);\n if (since) args.push(`--since=${since}`);\n if (path) args.push('--', path);\n\n const { stdout } = await runGit(args, { cwd });\n const entries = stdout\n .split('\\n')\n .filter(Boolean)\n .map((line) => {\n const spaceIdx = line.indexOf(' ');\n return {\n hash: line.slice(0, spaceIdx),\n message: line.slice(spaceIdx + 1),\n };\n });\n\n return { success: true, commits: entries };\n }\n\n // Structured output using format\n const sep = '---COMMIT_SEP---';\n const format = `${sep}%n%H%n%an%n%ae%n%ai%n%s`;\n const args = ['log', `--max-count=${limit}`, `--format=${format}`];\n if (author) args.push(`--author=${author}`);\n if (since) args.push(`--since=${since}`);\n if (path) args.push('--', path);\n\n const { stdout } = await runGit(args, { cwd });\n const commits = stdout\n .split(sep)\n .filter((s) => s.trim())\n .map((block) => {\n const lines = block.trim().split('\\n');\n return {\n hash: lines[0] ?? '',\n author: lines[1] ?? '',\n email: lines[2] ?? '',\n date: lines[3] ?? '',\n message: lines[4] ?? '',\n };\n });\n\n return { success: true, commits };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── gitCommit ───────────────────────────────────────────────────────\n\nexport const gitCommit = tool({\n description:\n 'Stage files and create a git commit. Can stage specific files or all changes.',\n inputSchema: z.object({\n message: z.string().describe('Commit message.'),\n files: z\n .array(z.string())\n .optional()\n .describe('Specific files to stage before committing. If omitted and all is false, commits only already-staged files.'),\n all: z\n .boolean()\n .optional()\n .describe('If true, stage all modified and deleted files (git add -A) before committing.'),\n cwd: z\n .string()\n .optional()\n .describe('Working directory. Defaults to process cwd.'),\n }),\n execute: async ({ message, files, all, cwd }) => {\n try {\n // Stage files\n if (all) {\n await runGit(['add', '-A'], { cwd });\n } else if (files && files.length > 0) {\n await runGit(['add', ...files], { cwd });\n }\n\n // Commit\n const { stdout } = await runGit(['commit', '-m', message], { cwd });\n\n return {\n success: true,\n output: stdout.trim(),\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── gitBranch ───────────────────────────────────────────────────────\n\nexport const gitBranch = tool({\n description:\n 'List, create, switch, or delete git branches.',\n inputSchema: z.object({\n action: z\n .enum(['list', 'create', 'switch', 'delete'])\n .describe('The branch operation to perform.'),\n name: z\n .string()\n .optional()\n .describe('Branch name (required for create, switch, delete).'),\n cwd: z\n .string()\n .optional()\n .describe('Working directory. Defaults to process cwd.'),\n }),\n execute: async ({ action, name, cwd }) => {\n try {\n switch (action) {\n case 'list': {\n const { stdout } = await runGit(['branch', '-a', '--no-color'], { cwd });\n const branches = stdout\n .split('\\n')\n .filter(Boolean)\n .map((line) => ({\n name: line.replace(/^\\*?\\s+/, '').trim(),\n current: line.startsWith('*'),\n }));\n return { success: true, branches };\n }\n\n case 'create': {\n if (!name) return { success: false, error: 'Branch name is required for create.' };\n const { stdout } = await runGit(['branch', name], { cwd });\n return { success: true, output: stdout.trim() || `Branch \"${name}\" created.` };\n }\n\n case 'switch': {\n if (!name) return { success: false, error: 'Branch name is required for switch.' };\n const { stdout } = await runGit(['checkout', name], { cwd });\n return { success: true, output: stdout.trim() || `Switched to branch \"${name}\".` };\n }\n\n case 'delete': {\n if (!name) return { success: false, error: 'Branch name is required for delete.' };\n const { stdout } = await runGit(['branch', '-d', name], { cwd });\n return { success: true, output: stdout.trim() || `Branch \"${name}\" deleted.` };\n }\n\n default:\n return { success: false, error: `Unknown action: ${action as string}` };\n }\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n","import { tool } from 'ai';\nimport { z } from 'zod';\nimport { isPrivateIP } from './security.js';\n\n/**\n * Strip HTML tags and decode common entities for readable text extraction.\n */\nfunction stripHtml(html: string): string {\n // Remove script and style blocks entirely\n let text = html.replace(/<script[\\s\\S]*?<\\/script>/gi, '');\n text = text.replace(/<style[\\s\\S]*?<\\/style>/gi, '');\n\n // Remove HTML tags\n text = text.replace(/<[^>]+>/g, ' ');\n\n // Decode common entities\n text = text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/ /g, ' ')\n .replace(/&#(\\d+);/g, (_match, code) => String.fromCharCode(parseInt(code, 10)));\n\n // Collapse whitespace\n text = text.replace(/\\s+/g, ' ').trim();\n\n return text;\n}\n\nexport const fetchUrl = tool({\n description:\n 'Fetch a URL and return its content. Can extract text from HTML pages. ' +\n 'Has SSRF protection (blocks private/internal IPs) and a 15-second timeout.',\n inputSchema: z.object({\n url: z.string().describe('The URL to fetch.'),\n maxBytes: z\n .number()\n .optional()\n .describe('Maximum response bytes to read. Default 512 KB.'),\n extractText: z\n .boolean()\n .optional()\n .describe('If true, strip HTML tags and return plain text. Default false.'),\n headers: z\n .record(z.string())\n .optional()\n .describe('Additional HTTP headers to send.'),\n }),\n execute: async ({ url, maxBytes, extractText, headers }) => {\n try {\n // Validate URL\n let parsedUrl: URL;\n try {\n parsedUrl = new URL(url);\n } catch {\n return { success: false, error: `Invalid URL: \"${url}\"` };\n }\n\n // Only allow http/https\n if (!['http:', 'https:'].includes(parsedUrl.protocol)) {\n return { success: false, error: `Unsupported protocol: ${parsedUrl.protocol}` };\n }\n\n // SSRF protection: block private IPs\n if (isPrivateIP(parsedUrl.hostname)) {\n return {\n success: false,\n error: `Blocked: \"${parsedUrl.hostname}\" resolves to a private/internal address. SSRF protection prevents fetching this URL.`,\n };\n }\n\n const limit = maxBytes ?? 512 * 1024;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 15_000);\n\n try {\n const response = await fetch(url, {\n signal: controller.signal,\n headers: {\n 'User-Agent': 'nm-cli/1.0',\n ...(headers ?? {}),\n },\n redirect: 'follow',\n });\n\n clearTimeout(timeout);\n\n if (!response.ok) {\n return {\n success: false,\n error: `HTTP ${response.status} ${response.statusText}`,\n status: response.status,\n };\n }\n\n // Read body with size limit\n const contentType = response.headers.get('content-type') ?? '';\n const reader = response.body?.getReader();\n if (!reader) {\n return { success: false, error: 'No response body.' };\n }\n\n const chunks: Uint8Array[] = [];\n let totalBytes = 0;\n let truncated = false;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n totalBytes += value.byteLength;\n if (totalBytes > limit) {\n // Take only what fits\n const overflow = totalBytes - limit;\n chunks.push(value.slice(0, value.byteLength - overflow));\n truncated = true;\n reader.cancel();\n break;\n }\n chunks.push(value);\n }\n\n // Combine chunks\n const combined = new Uint8Array(\n chunks.reduce((acc, c) => acc + c.byteLength, 0),\n );\n let offset = 0;\n for (const chunk of chunks) {\n combined.set(chunk, offset);\n offset += chunk.byteLength;\n }\n\n let content = new TextDecoder().decode(combined);\n\n if (extractText && contentType.includes('text/html')) {\n content = stripHtml(content);\n }\n\n return {\n success: true,\n url,\n status: response.status,\n contentType,\n content,\n bytesFetched: combined.byteLength,\n truncated,\n };\n } catch (fetchError) {\n clearTimeout(timeout);\n if (fetchError instanceof Error && fetchError.name === 'AbortError') {\n return { success: false, error: 'Request timed out after 15 seconds.' };\n }\n throw fetchError;\n }\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n","import { tool } from 'ai';\nimport { z } from 'zod';\nimport { resolve, join, dirname } from 'node:path';\nimport { writeFile as fsWriteFile, mkdir } from 'node:fs/promises';\nimport { getApiKey } from '../config.js';\nimport OpenAI from 'openai';\n\nexport const generateImage = tool({\n description:\n 'Generate an image using DALL-E 3 from a text prompt and save it to disk. ' +\n 'Returns the local file path and the (possibly revised) prompt that DALL-E used.',\n inputSchema: z.object({\n prompt: z.string().describe('A description of the image to generate.'),\n size: z\n .enum(['1024x1024', '1792x1024', '1024x1792'])\n .optional()\n .describe('Image dimensions. Default \"1024x1024\".'),\n quality: z\n .enum(['standard', 'hd'])\n .optional()\n .describe('Image quality. \"hd\" produces finer details. Default \"standard\".'),\n savePath: z\n .string()\n .optional()\n .describe(\n 'Absolute or relative path where the image should be saved. ' +\n 'If omitted, saves to cwd as generated-image-{timestamp}.png.',\n ),\n }),\n execute: async ({ prompt, size, quality, savePath }) => {\n try {\n const apiKey = getApiKey('openai');\n if (!apiKey) {\n return {\n success: false,\n error:\n 'OpenAI API key not configured. Set OPENAI_API_KEY or run: ai config set providers.openai.apiKey <key>',\n };\n }\n\n const openai = new OpenAI({ apiKey });\n\n const selectedSize = size ?? '1024x1024';\n const selectedQuality = quality ?? 'standard';\n\n const response = await openai.images.generate({\n model: 'dall-e-3',\n prompt,\n n: 1,\n size: selectedSize,\n quality: selectedQuality,\n response_format: 'url',\n });\n\n const imageData = response.data?.[0];\n if (!imageData?.url) {\n return { success: false, error: 'No image URL returned from OpenAI.' };\n }\n\n // Download the image\n const imageResponse = await fetch(imageData.url);\n if (!imageResponse.ok) {\n return {\n success: false,\n error: `Failed to download generated image: HTTP ${imageResponse.status}`,\n };\n }\n\n const imageBuffer = Buffer.from(await imageResponse.arrayBuffer());\n\n // Determine save path\n const timestamp = Date.now();\n const targetPath = resolve(savePath ?? `generated-image-${timestamp}.png`);\n\n // Ensure parent directory exists\n await mkdir(dirname(targetPath), { recursive: true });\n\n await fsWriteFile(targetPath, imageBuffer);\n\n return {\n success: true,\n path: targetPath,\n prompt,\n revisedPrompt: imageData.revised_prompt ?? prompt,\n size: selectedSize,\n quality: selectedQuality,\n bytesWritten: imageBuffer.byteLength,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n },\n});\n","import { tool } from 'ai';\nimport { z } from 'zod';\nimport { resolve, dirname, join } from 'node:path';\nimport { writeFile as fsWriteFile, mkdir, readdir, unlink, rmdir, writeFile } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { randomUUID } from 'node:crypto';\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { getApiKey } from '../config.js';\nimport OpenAI from 'openai';\nimport type { VideoSeconds, VideoSize, VideoModel } from 'openai/resources/videos';\n\nconst execFileAsync = promisify(execFile);\n\n/**\n * Default timeout per clip for video generation (10 minutes).\n * Sora video generation can take several minutes depending on duration and resolution.\n */\nconst PER_CLIP_TIMEOUT_MS = 10 * 60 * 1000;\n\n/**\n * Polling interval when waiting for video generation to complete.\n */\nconst POLL_INTERVAL_MS = 5_000;\n\n/**\n * Maximum duration for a single Sora API clip (seconds).\n */\nconst MAX_CLIP_SECONDS = 12;\n\n/**\n * Maximum total duration supported (5 minutes).\n */\nconst MAX_TOTAL_SECONDS = 300;\n\n/**\n * Valid per-clip durations accepted by the Sora API.\n */\nconst VALID_CLIP_DURATIONS: VideoSeconds[] = ['4', '8', '12'];\n\n/**\n * Map user-friendly aspect-ratio + resolution combos to Sora's WxH size values.\n */\nconst SIZE_MAP: Record<string, VideoSize> = {\n 'landscape': '1280x720',\n 'portrait': '720x1280',\n 'landscape-wide': '1792x1024',\n 'portrait-tall': '1024x1792',\n};\n\n/**\n * Poll the OpenAI Videos API until the generation job reaches a terminal state\n * or the timeout expires.\n */\nasync function pollForCompletion(\n openai: OpenAI,\n videoId: string,\n timeoutMs: number,\n): Promise<OpenAI.Videos.Video> {\n const deadline = Date.now() + timeoutMs;\n\n while (Date.now() < deadline) {\n const video = await openai.videos.retrieve(videoId);\n\n if (video.status === 'completed') {\n return video;\n }\n\n if (video.status === 'failed') {\n const msg = video.error?.message ?? 'Video generation failed with no error details.';\n throw new Error(msg);\n }\n\n // Still queued or in_progress -- wait before polling again\n await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));\n }\n\n throw new Error(`Video generation timed out after ${timeoutMs / 1000}s`);\n}\n\n/**\n * Choose the best per-clip duration for Sora given the remaining seconds.\n * Prefers the largest clip that fits, so we generate fewer clips overall.\n */\nfunction chooseBestClipDuration(remainingSeconds: number): VideoSeconds {\n if (remainingSeconds >= 12) return '12';\n if (remainingSeconds >= 8) return '8';\n return '4';\n}\n\n/**\n * Calculate the clip plan: an array of per-clip durations that sum to at least totalSeconds.\n */\nfunction planClips(totalSeconds: number): VideoSeconds[] {\n if (totalSeconds <= MAX_CLIP_SECONDS) {\n return [chooseBestClipDuration(totalSeconds)];\n }\n\n const clips: VideoSeconds[] = [];\n let remaining = totalSeconds;\n\n while (remaining > 0) {\n const clipDuration = chooseBestClipDuration(remaining);\n clips.push(clipDuration);\n remaining -= parseInt(clipDuration, 10);\n }\n\n return clips;\n}\n\n/**\n * Check if FFmpeg is available on the system PATH.\n */\nasync function isFFmpegAvailable(): Promise<boolean> {\n try {\n // 'where' on Windows, 'which' on Unix\n const command = process.platform === 'win32' ? 'where' : 'which';\n await execFileAsync(command, ['ffmpeg']);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Generate a single clip via the Sora API and return the downloaded buffer.\n */\nasync function generateSingleClip(\n openai: OpenAI,\n prompt: string,\n seconds: VideoSeconds,\n size: VideoSize,\n model: VideoModel,\n timeoutMs: number,\n): Promise<{ buffer: Buffer; videoId: string; resolvedPrompt: string }> {\n let video = await openai.videos.create({\n prompt,\n seconds,\n size,\n model,\n });\n\n if (video.status !== 'completed') {\n video = await pollForCompletion(openai, video.id, timeoutMs);\n }\n\n const contentResponse = await openai.videos.downloadContent(video.id, { variant: 'video' });\n const buffer = Buffer.from(await contentResponse.arrayBuffer());\n\n return {\n buffer,\n videoId: video.id,\n resolvedPrompt: video.prompt ?? prompt,\n };\n}\n\n/**\n * Concatenate multiple video clips using FFmpeg's concat demuxer.\n */\nasync function stitchClips(clipPaths: string[], outputPath: string): Promise<void> {\n const concatDir = dirname(clipPaths[0]);\n const fileListPath = join(concatDir, 'filelist.txt');\n\n // Build the concat file — each line: file 'path'\n const fileListContent = clipPaths\n .map((p) => `file '${p.replace(/'/g, \"'\\\\''\")}'`)\n .join('\\n');\n\n await writeFile(fileListPath, fileListContent, 'utf-8');\n\n try {\n await execFileAsync('ffmpeg', [\n '-f', 'concat',\n '-safe', '0',\n '-i', fileListPath,\n '-c', 'copy',\n '-y',\n outputPath,\n ]);\n } finally {\n // Clean up the file list (clip cleanup happens in the caller)\n await unlink(fileListPath).catch(() => {});\n }\n}\n\n/**\n * Remove a temporary directory and all files inside it.\n */\nasync function cleanupTempDir(dirPath: string): Promise<void> {\n try {\n const entries = await readdir(dirPath);\n await Promise.all(entries.map((entry) => unlink(join(dirPath, entry)).catch(() => {})));\n await rmdir(dirPath).catch(() => {});\n } catch {\n // Best-effort cleanup; don't throw\n }\n}\n\n/**\n * Build a continuation prompt for clip N (0-indexed).\n * The first clip uses the original prompt; subsequent clips add continuity context.\n */\nfunction buildClipPrompt(originalPrompt: string, clipIndex: number, totalClips: number): string {\n if (clipIndex === 0) {\n return originalPrompt;\n }\n return `${originalPrompt}. Continuation of the scene, seamless transition, maintaining visual consistency and style from the previous shot. This is part ${clipIndex + 1} of ${totalClips}.`;\n}\n\nexport const generateVideo = tool({\n description:\n 'Generate a video using OpenAI Sora from a text prompt and save it to disk. ' +\n 'Supports durations from 1 to 300 seconds (5 minutes). Videos longer than 12 seconds ' +\n 'are generated as multiple clips and stitched together using FFmpeg. ' +\n 'Video generation may take several minutes. Returns the local file path and metadata.',\n inputSchema: z.object({\n prompt: z.string().describe('A description of the video to generate.'),\n duration: z\n .number()\n .int()\n .min(1)\n .max(MAX_TOTAL_SECONDS)\n .optional()\n .describe(\n 'Video duration in seconds (1-300). Defaults to 4. ' +\n 'Durations over 12s require FFmpeg to stitch multiple clips together.',\n ),\n size: z\n .enum(['720x1280', '1280x720', '1024x1792', '1792x1024'])\n .optional()\n .describe(\n 'Output resolution as WxH. Allowed: \"1280x720\" (landscape), \"720x1280\" (portrait), ' +\n '\"1792x1024\" (wide landscape), \"1024x1792\" (tall portrait). Default \"720x1280\".',\n ),\n model: z\n .enum(['sora-2', 'sora-2-pro'])\n .optional()\n .describe('Sora model variant. \"sora-2-pro\" produces higher quality. Default \"sora-2\".'),\n savePath: z\n .string()\n .optional()\n .describe(\n 'Absolute or relative path where the video should be saved. ' +\n 'If omitted, saves to cwd as generated-video-{timestamp}.mp4.',\n ),\n }),\n execute: async ({ prompt, duration, size, model, savePath }) => {\n try {\n const apiKey = getApiKey('openai');\n if (!apiKey) {\n return {\n success: false,\n error:\n 'OpenAI API key not configured. Set OPENAI_API_KEY or run: ai config set providers.openai.apiKey <key>',\n };\n }\n\n const totalSeconds = duration ?? 4;\n const selectedSize: VideoSize = size ?? '720x1280';\n const selectedModel: VideoModel = model ?? 'sora-2';\n\n const clipPlan = planClips(totalSeconds);\n const clipCount = clipPlan.length;\n const needsStitching = clipCount > 1;\n\n // If stitching is needed, verify FFmpeg is available before we start generating\n if (needsStitching) {\n const ffmpegOk = await isFFmpegAvailable();\n if (!ffmpegOk) {\n return {\n success: false,\n error:\n `Video duration ${totalSeconds}s requires ${clipCount} clips to be stitched together, ` +\n 'but FFmpeg was not found on your system PATH. ' +\n 'Please install FFmpeg (https://ffmpeg.org/download.html) and try again.',\n };\n }\n }\n\n const openai = new OpenAI({ apiKey });\n\n // Determine final save path\n const timestamp = Date.now();\n const targetPath = resolve(savePath ?? `generated-video-${timestamp}.mp4`);\n await mkdir(dirname(targetPath), { recursive: true });\n\n // ── Single clip (short video, no FFmpeg needed) ──────────────────\n if (!needsStitching) {\n const clipDuration = clipPlan[0];\n const { buffer, videoId, resolvedPrompt } = await generateSingleClip(\n openai,\n prompt,\n clipDuration,\n selectedSize,\n selectedModel,\n PER_CLIP_TIMEOUT_MS,\n );\n\n await fsWriteFile(targetPath, buffer);\n\n return {\n success: true,\n path: targetPath,\n prompt: resolvedPrompt,\n duration: totalSeconds,\n clips: 1,\n size: selectedSize,\n model: selectedModel,\n videoId,\n bytesWritten: buffer.byteLength,\n };\n }\n\n // ── Multi-clip (long video, sequential generation + FFmpeg stitch) ──\n const tempDir = join(tmpdir(), `nm-cli-video-${randomUUID()}`);\n await mkdir(tempDir, { recursive: true });\n\n const clipPaths: string[] = [];\n const videoIds: string[] = [];\n let lastPrompt = prompt;\n\n try {\n // Generate clips sequentially for narrative continuity\n for (let i = 0; i < clipPlan.length; i++) {\n const clipDuration = clipPlan[i];\n const clipPrompt = buildClipPrompt(prompt, i, clipPlan.length);\n\n const { buffer, videoId, resolvedPrompt } = await generateSingleClip(\n openai,\n clipPrompt,\n clipDuration,\n selectedSize,\n selectedModel,\n PER_CLIP_TIMEOUT_MS,\n );\n\n const clipPath = join(tempDir, `clip-${String(i).padStart(3, '0')}.mp4`);\n await fsWriteFile(clipPath, buffer);\n\n clipPaths.push(clipPath);\n videoIds.push(videoId);\n lastPrompt = resolvedPrompt;\n }\n\n // Stitch all clips together\n await stitchClips(clipPaths, targetPath);\n\n // Calculate final file size\n const { stat } = await import('node:fs/promises');\n const finalStat = await stat(targetPath);\n\n return {\n success: true,\n path: targetPath,\n prompt: lastPrompt,\n duration: totalSeconds,\n clips: clipCount,\n size: selectedSize,\n model: selectedModel,\n videoIds,\n bytesWritten: finalStat.size,\n };\n } finally {\n // Always clean up temp files\n await cleanupTempDir(tempDir);\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n },\n});\n","import { tool } from 'ai';\nimport { z } from 'zod';\nimport type { Canvas, CanvasRenderingContext2D, CanvasGradient } from 'canvas';\nimport { resolve, dirname } from 'node:path';\nimport { writeFile, mkdir } from 'node:fs/promises';\n\n// Lazy-load canvas (optional native dependency)\nlet canvasModule: typeof import('canvas') | null = null;\nasync function getCanvasModule(): Promise<typeof import('canvas')> {\n if (!canvasModule) {\n try {\n canvasModule = await import('canvas');\n } catch {\n throw new Error('canvas is not installed. Run: npm install canvas');\n }\n }\n return canvasModule;\n}\n\n// Synchronous accessor — only valid after getCanvasModule() has been called at least once.\nfunction getCanvasModuleSync(): typeof import('canvas') {\n if (!canvasModule) {\n throw new Error('canvas is not installed. Run: npm install canvas');\n }\n return canvasModule;\n}\n\n// ---------------------------------------------------------------------------\n// Canvas store — in-memory map of canvas instances keyed by ID\n// ---------------------------------------------------------------------------\n\ninterface CanvasEntry {\n canvas: Canvas;\n ctx: CanvasRenderingContext2D;\n width: number;\n height: number;\n}\n\nconst canvasStore = new Map<string, CanvasEntry>();\nlet nextCanvasId = 1;\n\nfunction getCanvas(id: string): CanvasEntry | null {\n return canvasStore.get(id) ?? null;\n}\n\nfunction requireCanvas(id: string): CanvasEntry {\n const entry = getCanvas(id);\n if (!entry) throw new Error(`Canvas \"${id}\" not found. Create one first with createCanvas.`);\n return entry;\n}\n\n// ---------------------------------------------------------------------------\n// Shared Zod schemas\n// ---------------------------------------------------------------------------\n\nconst canvasIdSchema = z.string().describe('The canvas ID returned by createCanvas.');\n\nconst styleSchema = z.object({\n color: z.string().optional().describe('CSS color string: named, hex, rgb(), rgba(). Default \"black\".'),\n fill: z.boolean().optional().describe('Whether to fill the shape (true) or just stroke it (false). Default true.'),\n lineWidth: z.number().optional().describe('Stroke line width. Default 1.'),\n opacity: z.number().min(0).max(1).optional().describe('Opacity 0-1. Default 1.'),\n lineCap: z.enum(['butt', 'round', 'square']).optional().describe('Line cap style. Default \"butt\".'),\n lineJoin: z.enum(['miter', 'round', 'bevel']).optional().describe('Line join style. Default \"miter\".'),\n}).optional().describe('Style options for the shape.');\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction applyStyle(ctx: CanvasRenderingContext2D, style?: {\n color?: string;\n fill?: boolean;\n lineWidth?: number;\n opacity?: number;\n lineCap?: string;\n lineJoin?: string;\n}): { color: string; fill: boolean; lineWidth: number } {\n const color = style?.color ?? 'black';\n const fill = style?.fill ?? true;\n const lineWidth = style?.lineWidth ?? 1;\n\n if (style?.opacity !== undefined) ctx.globalAlpha = style.opacity;\n if (style?.lineCap) ctx.lineCap = style.lineCap as CanvasRenderingContext2D['lineCap'];\n if (style?.lineJoin) ctx.lineJoin = style.lineJoin as CanvasRenderingContext2D['lineJoin'];\n\n ctx.fillStyle = color;\n ctx.strokeStyle = color;\n ctx.lineWidth = lineWidth;\n\n return { color, fill, lineWidth };\n}\n\nfunction restoreAlpha(ctx: CanvasRenderingContext2D) {\n ctx.globalAlpha = 1;\n}\n\nfunction parseColor(color: string): { r: number; g: number; b: number; a: number } {\n // Create a tiny 1x1 canvas to parse any CSS color\n const { createCanvas: nodeCreateCanvas } = getCanvasModuleSync();\n const c = nodeCreateCanvas(1, 1);\n const ctx = c.getContext('2d');\n ctx.fillStyle = color;\n ctx.fillRect(0, 0, 1, 1);\n const data = ctx.getImageData(0, 0, 1, 1).data;\n return { r: data[0], g: data[1], b: data[2], a: data[3] };\n}\n\n// ---------------------------------------------------------------------------\n// 1. createCanvas\n// ---------------------------------------------------------------------------\n\nexport const createCanvas = tool({\n description:\n 'Create a new in-memory canvas for drawing. Returns a canvas ID to use with other drawing tools. ' +\n 'The coordinate system has origin at top-left, x increases right, y increases down.',\n inputSchema: z.object({\n width: z.number().int().min(1).max(8192).describe('Canvas width in pixels.'),\n height: z.number().int().min(1).max(8192).describe('Canvas height in pixels.'),\n backgroundColor: z\n .string()\n .optional()\n .describe('Background color (CSS format). Default \"white\". Use \"transparent\" for no background.'),\n }),\n execute: async ({ width, height, backgroundColor }) => {\n try {\n const { createCanvas: nodeCreateCanvas } = await getCanvasModule();\n const id = `canvas-${nextCanvasId++}`;\n const canvas = nodeCreateCanvas(width, height);\n const ctx = canvas.getContext('2d');\n\n const bg = backgroundColor ?? 'white';\n if (bg !== 'transparent') {\n ctx.fillStyle = bg;\n ctx.fillRect(0, 0, width, height);\n }\n\n canvasStore.set(id, { canvas, ctx, width, height });\n\n return {\n success: true,\n canvasId: id,\n width,\n height,\n backgroundColor: bg,\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ---------------------------------------------------------------------------\n// 2. drawText\n// ---------------------------------------------------------------------------\n\nexport const drawText = tool({\n description:\n 'Draw text on a canvas. Supports font size, family, color, alignment, baseline, bold, italic, rotation, and max width for wrapping.',\n inputSchema: z.object({\n canvasId: canvasIdSchema,\n x: z.number().describe('X position for the text.'),\n y: z.number().describe('Y position for the text.'),\n text: z.string().describe('The text string to draw.'),\n fontSize: z.number().optional().describe('Font size in pixels. Default 16.'),\n fontFamily: z.string().optional().describe('Font family. Default \"sans-serif\".'),\n color: z.string().optional().describe('Text color (CSS). Default \"black\".'),\n align: z.enum(['left', 'center', 'right']).optional().describe('Text alignment. Default \"left\".'),\n baseline: z.enum(['top', 'middle', 'alphabetic', 'bottom']).optional().describe('Text baseline. Default \"top\".'),\n bold: z.boolean().optional().describe('Bold text. Default false.'),\n italic: z.boolean().optional().describe('Italic text. Default false.'),\n maxWidth: z.number().optional().describe('Max width in pixels — text wraps to multiple lines if exceeded.'),\n rotation: z.number().optional().describe('Rotation in degrees around the (x, y) anchor point. Default 0.'),\n opacity: z.number().min(0).max(1).optional().describe('Opacity 0-1. Default 1.'),\n }),\n execute: async ({ canvasId, x, y, text, fontSize, fontFamily, color, align, baseline, bold, italic, maxWidth, rotation, opacity }) => {\n try {\n const { ctx } = requireCanvas(canvasId);\n\n const size = fontSize ?? 16;\n // Only allow generic font families that are reliably available in node-canvas.\n // If the caller specifies a named font, append \", sans-serif\" as a fallback.\n const safeFamilies = new Set(['sans-serif', 'serif', 'monospace']);\n const family = fontFamily\n ? (safeFamilies.has(fontFamily) ? fontFamily : `${fontFamily}, sans-serif`)\n : 'sans-serif';\n const weight = bold ? 'bold' : '';\n const style = italic ? 'italic' : '';\n const font = `${style} ${weight} ${size}px ${family}`.trim();\n\n ctx.save();\n\n ctx.font = font;\n ctx.fillStyle = color ?? 'black';\n ctx.textAlign = (align ?? 'left') as CanvasRenderingContext2D['textAlign'];\n ctx.textBaseline = (baseline ?? 'top') as CanvasRenderingContext2D['textBaseline'];\n if (opacity !== undefined) ctx.globalAlpha = opacity;\n\n if (rotation) {\n const rad = (rotation * Math.PI) / 180;\n ctx.translate(x, y);\n ctx.rotate(rad);\n if (maxWidth) {\n wrapText(ctx, text, 0, 0, maxWidth, size * 1.2);\n } else {\n ctx.fillText(text, 0, 0);\n }\n } else if (maxWidth) {\n wrapText(ctx, text, x, y, maxWidth, size * 1.2);\n } else {\n ctx.fillText(text, x, y);\n }\n\n ctx.restore();\n\n return { success: true, canvasId, text };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\nfunction wrapText(ctx: CanvasRenderingContext2D, text: string, x: number, y: number, maxWidth: number, lineHeight: number) {\n const words = text.split(' ');\n let line = '';\n let currentY = y;\n\n for (const word of words) {\n const testLine = line ? `${line} ${word}` : word;\n const metrics = ctx.measureText(testLine);\n if (metrics.width > maxWidth && line) {\n ctx.fillText(line, x, currentY);\n line = word;\n currentY += lineHeight;\n } else {\n line = testLine;\n }\n }\n if (line) ctx.fillText(line, x, currentY);\n}\n\n// ---------------------------------------------------------------------------\n// 4. drawImage — composite an existing image onto the canvas\n// ---------------------------------------------------------------------------\n\nexport const drawImage = tool({\n description:\n 'Load an image file from disk and draw it onto a canvas at a given position. Supports scaling and opacity.',\n inputSchema: z.object({\n canvasId: canvasIdSchema,\n imagePath: z.string().describe('Path to the image file (PNG, JPEG, etc).'),\n x: z.number().optional().describe('X position on canvas. Default 0.'),\n y: z.number().optional().describe('Y position on canvas. Default 0.'),\n width: z.number().optional().describe('Draw width (scales the image). Default: image natural width.'),\n height: z.number().optional().describe('Draw height (scales the image). Default: image natural height.'),\n opacity: z.number().min(0).max(1).optional().describe('Opacity 0-1. Default 1.'),\n }),\n execute: async ({ canvasId, imagePath, x, y, width, height, opacity }) => {\n try {\n const { ctx } = requireCanvas(canvasId);\n const { loadImage } = await getCanvasModule();\n const resolvedPath = resolve(imagePath);\n const img = await loadImage(resolvedPath);\n\n ctx.save();\n if (opacity !== undefined) ctx.globalAlpha = opacity;\n\n const dx = x ?? 0;\n const dy = y ?? 0;\n const dw = width ?? img.width;\n const dh = height ?? img.height;\n ctx.drawImage(img, dx, dy, dw, dh);\n\n ctx.restore();\n\n return {\n success: true,\n canvasId,\n imagePath: resolvedPath,\n drawnAt: { x: dx, y: dy, width: dw, height: dh },\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ---------------------------------------------------------------------------\n// 5. setCanvasStyle — set default styles for subsequent operations\n// ---------------------------------------------------------------------------\n\nexport const setCanvasStyle = tool({\n description:\n 'Set default drawing styles on a canvas: stroke/fill colors, line width, shadow, and global opacity. ' +\n 'These persist until changed or overridden by individual draw calls.',\n inputSchema: z.object({\n canvasId: canvasIdSchema,\n strokeStyle: z.string().optional().describe('Default stroke color.'),\n fillStyle: z.string().optional().describe('Default fill color.'),\n lineWidth: z.number().optional().describe('Default line width.'),\n globalAlpha: z.number().min(0).max(1).optional().describe('Global opacity 0-1.'),\n shadowOffsetX: z.number().optional().describe('Shadow X offset.'),\n shadowOffsetY: z.number().optional().describe('Shadow Y offset.'),\n shadowBlur: z.number().optional().describe('Shadow blur radius.'),\n shadowColor: z.string().optional().describe('Shadow color.'),\n lineDash: z.array(z.number()).optional().describe('Line dash pattern, e.g. [5, 3] for dashed lines.'),\n }),\n execute: async ({ canvasId, strokeStyle, fillStyle, lineWidth, globalAlpha, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, lineDash }) => {\n try {\n const { ctx } = requireCanvas(canvasId);\n\n if (strokeStyle !== undefined) ctx.strokeStyle = strokeStyle;\n if (fillStyle !== undefined) ctx.fillStyle = fillStyle;\n if (lineWidth !== undefined) ctx.lineWidth = lineWidth;\n if (globalAlpha !== undefined) ctx.globalAlpha = globalAlpha;\n if (shadowOffsetX !== undefined) ctx.shadowOffsetX = shadowOffsetX;\n if (shadowOffsetY !== undefined) ctx.shadowOffsetY = shadowOffsetY;\n if (shadowBlur !== undefined) ctx.shadowBlur = shadowBlur;\n if (shadowColor !== undefined) ctx.shadowColor = shadowColor;\n if (lineDash !== undefined) ctx.setLineDash(lineDash);\n\n return { success: true, canvasId };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ---------------------------------------------------------------------------\n// 6. clearCanvas\n// ---------------------------------------------------------------------------\n\nexport const clearCanvas = tool({\n description:\n 'Clear all or part of a canvas. Without region parameters, clears the entire canvas to transparent. ' +\n 'Optionally specify a rectangular region to clear.',\n inputSchema: z.object({\n canvasId: canvasIdSchema,\n x: z.number().optional().describe('Region X. Default 0.'),\n y: z.number().optional().describe('Region Y. Default 0.'),\n width: z.number().optional().describe('Region width. Default canvas width.'),\n height: z.number().optional().describe('Region height. Default canvas height.'),\n backgroundColor: z.string().optional().describe('If provided, fill the cleared region with this color instead of transparent.'),\n }),\n execute: async ({ canvasId, x, y, width, height, backgroundColor }) => {\n try {\n const entry = requireCanvas(canvasId);\n const { ctx } = entry;\n\n const cx = x ?? 0;\n const cy = y ?? 0;\n const cw = width ?? entry.width;\n const ch = height ?? entry.height;\n\n ctx.clearRect(cx, cy, cw, ch);\n\n if (backgroundColor) {\n ctx.fillStyle = backgroundColor;\n ctx.fillRect(cx, cy, cw, ch);\n }\n\n return { success: true, canvasId };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ---------------------------------------------------------------------------\n// 7. saveCanvas\n// ---------------------------------------------------------------------------\n\nexport const saveCanvas = tool({\n description:\n 'Save a canvas to a PNG file on disk. If no path is provided, saves to the current directory with an auto-generated name.',\n inputSchema: z.object({\n canvasId: canvasIdSchema,\n path: z.string().optional().describe('File path to save the PNG. Default: canvas-{id}-{timestamp}.png in cwd.'),\n }),\n execute: async ({ canvasId, path }) => {\n try {\n const { canvas } = requireCanvas(canvasId);\n\n const timestamp = Date.now();\n const targetPath = resolve(path ?? `${canvasId}-${timestamp}.png`);\n\n await mkdir(dirname(targetPath), { recursive: true });\n\n const buffer = canvas.toBuffer('image/png');\n await writeFile(targetPath, buffer);\n\n return {\n success: true,\n canvasId,\n path: targetPath,\n bytesWritten: buffer.byteLength,\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ---------------------------------------------------------------------------\n// 8. getCanvasInfo\n// ---------------------------------------------------------------------------\n\nexport const getCanvasInfo = tool({\n description: 'Get information about a canvas: dimensions, pixel count, and a list of all active canvas IDs.',\n inputSchema: z.object({\n canvasId: canvasIdSchema.optional().describe('Canvas ID. If omitted, returns a list of all active canvases.'),\n }),\n execute: async ({ canvasId }) => {\n try {\n if (!canvasId) {\n const ids = Array.from(canvasStore.keys());\n return {\n success: true,\n activeCanvases: ids,\n count: ids.length,\n };\n }\n\n const entry = requireCanvas(canvasId);\n return {\n success: true,\n canvasId,\n width: entry.width,\n height: entry.height,\n pixelCount: entry.width * entry.height,\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ---------------------------------------------------------------------------\n// 9. drawGradient\n// ---------------------------------------------------------------------------\n\nexport const drawGradient = tool({\n description:\n 'Fill a rectangular region with a gradient. Supports linear (horizontal, vertical, diagonal) and radial gradients.',\n inputSchema: z.object({\n canvasId: canvasIdSchema,\n x: z.number().describe('Region X.'),\n y: z.number().describe('Region Y.'),\n width: z.number().describe('Region width.'),\n height: z.number().describe('Region height.'),\n colors: z.array(z.string()).min(2).describe('Array of CSS color stops (at least 2). Evenly distributed.'),\n direction: z.enum(['horizontal', 'vertical', 'diagonal', 'radial']).optional().describe('Gradient direction. Default \"vertical\".'),\n }),\n execute: async ({ canvasId, x, y, width, height, colors, direction }) => {\n try {\n const { ctx } = requireCanvas(canvasId);\n const dir = direction ?? 'vertical';\n\n let gradient: CanvasGradient;\n if (dir === 'radial') {\n const cx = x + width / 2;\n const cy = y + height / 2;\n const r = Math.max(width, height) / 2;\n gradient = ctx.createRadialGradient(cx, cy, 0, cx, cy, r);\n } else if (dir === 'horizontal') {\n gradient = ctx.createLinearGradient(x, y, x + width, y);\n } else if (dir === 'diagonal') {\n gradient = ctx.createLinearGradient(x, y, x + width, y + height);\n } else {\n // vertical\n gradient = ctx.createLinearGradient(x, y, x, y + height);\n }\n\n for (let i = 0; i < colors.length; i++) {\n gradient.addColorStop(i / (colors.length - 1), colors[i]);\n }\n\n ctx.fillStyle = gradient;\n ctx.fillRect(x, y, width, height);\n\n return { success: true, canvasId, direction: dir, colorStops: colors.length };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ---------------------------------------------------------------------------\n// 10. floodFill — paint bucket tool\n// ---------------------------------------------------------------------------\n\nexport const floodFill = tool({\n description:\n 'Flood fill (paint bucket) — fill a contiguous area of similar color starting from (x, y) with the given color. ' +\n 'Tolerance controls how similar colors must be to be filled (0 = exact match, 255 = fill everything).',\n inputSchema: z.object({\n canvasId: canvasIdSchema,\n x: z.number().int().describe('Starting X coordinate.'),\n y: z.number().int().describe('Starting Y coordinate.'),\n color: z.string().describe('Fill color (CSS format).'),\n tolerance: z.number().int().min(0).max(255).optional().describe('Color match tolerance 0-255. Default 0 (exact match).'),\n }),\n execute: async ({ canvasId, x, y, color, tolerance }) => {\n try {\n await getCanvasModule(); // ensure canvas is loaded for parseColor\n const entry = requireCanvas(canvasId);\n const { ctx, width, height } = entry;\n const tol = tolerance ?? 0;\n\n if (x < 0 || x >= width || y < 0 || y >= height) {\n return { success: false, error: `Coordinates (${x}, ${y}) out of bounds (${width}x${height}).` };\n }\n\n const imageData = ctx.getImageData(0, 0, width, height);\n const data = imageData.data;\n\n const targetIdx = (y * width + x) * 4;\n const tr = data[targetIdx];\n const tg = data[targetIdx + 1];\n const tb = data[targetIdx + 2];\n const ta = data[targetIdx + 3];\n\n const fillColor = parseColor(color);\n\n // If the target is already the fill color, skip\n if (tr === fillColor.r && tg === fillColor.g && tb === fillColor.b && ta === fillColor.a) {\n return { success: true, canvasId, pixelsFilled: 0 };\n }\n\n const matches = (idx: number): boolean => {\n return (\n Math.abs(data[idx] - tr) <= tol &&\n Math.abs(data[idx + 1] - tg) <= tol &&\n Math.abs(data[idx + 2] - tb) <= tol &&\n Math.abs(data[idx + 3] - ta) <= tol\n );\n };\n\n const stack: number[] = [x, y];\n const visited = new Uint8Array(width * height);\n let filled = 0;\n\n while (stack.length > 0) {\n const py = stack.pop()!;\n const px = stack.pop()!;\n const pos = py * width + px;\n\n if (px < 0 || px >= width || py < 0 || py >= height) continue;\n if (visited[pos]) continue;\n visited[pos] = 1;\n\n const idx = pos * 4;\n if (!matches(idx)) continue;\n\n data[idx] = fillColor.r;\n data[idx + 1] = fillColor.g;\n data[idx + 2] = fillColor.b;\n data[idx + 3] = fillColor.a;\n filled++;\n\n stack.push(px + 1, py);\n stack.push(px - 1, py);\n stack.push(px, py + 1);\n stack.push(px, py - 1);\n }\n\n ctx.putImageData(imageData, 0, 0);\n\n return { success: true, canvasId, pixelsFilled: filled };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ---------------------------------------------------------------------------\n// Brush engine — Photoshop-like brush system\n// ---------------------------------------------------------------------------\n\ntype BrushType =\n | 'round' | 'flat' | 'fan' | 'filbert' | 'palette-knife'\n | 'airbrush' | 'splatter' | 'chalk' | 'watercolor' | 'ink'\n | 'pencil' | 'marker' | 'eraser';\n\ntype BlendMode = 'normal' | 'multiply' | 'screen' | 'overlay';\ntype TextureType = 'none' | 'canvas-weave' | 'paper-grain' | 'linen' | 'noise';\n\nexport interface JitterConfig {\n sizeJitter?: number;\n opacityJitter?: number;\n angleJitter?: number;\n colorJitter?: number;\n}\n\ninterface BrushConfig {\n type: BrushType;\n size: number;\n opacity: number;\n hardness: number;\n flow: number;\n spacing: number;\n angle: number;\n roundness: number;\n scatter: number;\n jitter: JitterConfig;\n color: string;\n secondaryColor?: string;\n blendMode: BlendMode;\n pressureSensitivity: boolean;\n texture: TextureType;\n}\n\n/** Per-canvas brush state. */\nconst brushStore = new Map<string, BrushConfig>();\n\nfunction getDefaultBrush(): BrushConfig {\n return {\n type: 'round',\n size: 10,\n opacity: 1,\n hardness: 0.8,\n flow: 1,\n spacing: 0.25,\n angle: 0,\n roundness: 1,\n scatter: 0,\n jitter: {},\n color: 'black',\n blendMode: 'normal',\n pressureSensitivity: false,\n texture: 'none',\n };\n}\n\nfunction getBrush(canvasId: string): BrushConfig {\n let brush = brushStore.get(canvasId);\n if (!brush) {\n brush = getDefaultBrush();\n brushStore.set(canvasId, brush);\n }\n return brush;\n}\n\nconst blendModeToComposite: Record<BlendMode, string> = {\n normal: 'source-over',\n multiply: 'multiply',\n screen: 'screen',\n overlay: 'overlay',\n};\n\n// ---------------------------------------------------------------------------\n// Brush tip generation\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a brush tip as an offscreen Canvas.\n * Returns a small canvas with the brush stamp rendered at the given size.\n */\nfunction generateBrushTip(\n type: BrushType,\n size: number,\n hardness: number,\n roundness: number,\n angle: number,\n texture: TextureType,\n flow: number,\n): Canvas {\n const { createCanvas: nodeCreateCanvas } = getCanvasModuleSync();\n const pad = Math.ceil(size * 0.1) + 2;\n const dim = Math.ceil(size) + pad * 2;\n const tip = nodeCreateCanvas(dim, dim);\n const tc = tip.getContext('2d');\n const cx = dim / 2;\n const cy = dim / 2;\n const r = size / 2;\n\n tc.save();\n tc.translate(cx, cy);\n tc.rotate((angle * Math.PI) / 180);\n tc.scale(1, roundness);\n\n switch (type) {\n case 'round': {\n if (hardness >= 0.99) {\n tc.beginPath();\n tc.arc(0, 0, r, 0, Math.PI * 2);\n tc.fillStyle = `rgba(0,0,0,${flow})`;\n tc.fill();\n } else {\n const grad = tc.createRadialGradient(0, 0, r * hardness, 0, 0, r);\n grad.addColorStop(0, `rgba(0,0,0,${flow})`);\n grad.addColorStop(1, 'rgba(0,0,0,0)');\n tc.beginPath();\n tc.arc(0, 0, r, 0, Math.PI * 2);\n tc.fillStyle = grad;\n tc.fill();\n }\n break;\n }\n\n case 'flat': {\n const hw = r;\n const hh = r * 0.3;\n const softZone = (1 - hardness) * hh;\n tc.fillStyle = `rgba(0,0,0,${flow})`;\n tc.fillRect(-hw, -hh + softZone, hw * 2, (hh - softZone) * 2);\n if (softZone > 0) {\n const grad1 = tc.createLinearGradient(0, -hh, 0, -hh + softZone);\n grad1.addColorStop(0, 'rgba(0,0,0,0)');\n grad1.addColorStop(1, `rgba(0,0,0,${flow})`);\n tc.fillStyle = grad1;\n tc.fillRect(-hw, -hh, hw * 2, softZone);\n const grad2 = tc.createLinearGradient(0, hh - softZone, 0, hh);\n grad2.addColorStop(0, `rgba(0,0,0,${flow})`);\n grad2.addColorStop(1, 'rgba(0,0,0,0)');\n tc.fillStyle = grad2;\n tc.fillRect(-hw, hh - softZone, hw * 2, softZone);\n }\n break;\n }\n\n case 'fan': {\n const numLines = 7;\n const spread = Math.PI * 0.6;\n const startAngle = -spread / 2;\n tc.strokeStyle = `rgba(0,0,0,${flow * 0.7})`;\n tc.lineWidth = Math.max(1, size * 0.04);\n for (let i = 0; i < numLines; i++) {\n const a = startAngle + (i / (numLines - 1)) * spread;\n tc.beginPath();\n tc.moveTo(0, 0);\n tc.lineTo(Math.cos(a) * r, Math.sin(a) * r);\n tc.stroke();\n }\n break;\n }\n\n case 'filbert': {\n const grad = tc.createRadialGradient(0, 0, r * hardness * 0.5, 0, 0, r);\n grad.addColorStop(0, `rgba(0,0,0,${flow})`);\n grad.addColorStop(1, 'rgba(0,0,0,0)');\n tc.beginPath();\n tc.ellipse(0, 0, r, r * 0.6, 0, 0, Math.PI * 2);\n tc.fillStyle = grad;\n tc.fill();\n break;\n }\n\n case 'palette-knife': {\n const hw = r;\n const hh = r * 0.15;\n // Draw streaky lines\n const streaks = Math.max(3, Math.floor(hh * 2));\n for (let s = 0; s < streaks; s++) {\n const yy = -hh + (s / streaks) * hh * 2;\n const alpha = (0.3 + Math.random() * 0.7) * flow;\n tc.strokeStyle = `rgba(0,0,0,${alpha})`;\n tc.lineWidth = 1;\n tc.beginPath();\n tc.moveTo(-hw, yy);\n tc.lineTo(hw, yy);\n tc.stroke();\n }\n break;\n }\n\n case 'airbrush': {\n const grad = tc.createRadialGradient(0, 0, 0, 0, 0, r);\n grad.addColorStop(0, `rgba(0,0,0,${flow * 0.3})`);\n grad.addColorStop(0.5, `rgba(0,0,0,${flow * 0.1})`);\n grad.addColorStop(1, 'rgba(0,0,0,0)');\n tc.beginPath();\n tc.arc(0, 0, r, 0, Math.PI * 2);\n tc.fillStyle = grad;\n tc.fill();\n break;\n }\n\n case 'splatter': {\n const numDots = Math.max(5, Math.floor(size * 0.8));\n tc.fillStyle = `rgba(0,0,0,${flow})`;\n for (let i = 0; i < numDots; i++) {\n const da = Math.random() * Math.PI * 2;\n const dd = Math.random() * r;\n const dr = Math.max(0.5, Math.random() * r * 0.15);\n tc.beginPath();\n tc.arc(Math.cos(da) * dd, Math.sin(da) * dd, dr, 0, Math.PI * 2);\n tc.fill();\n }\n break;\n }\n\n case 'chalk': {\n // Round with noisy edge\n const imgData = tc.getImageData(0, 0, dim, dim);\n const data = imgData.data;\n for (let py = 0; py < dim; py++) {\n for (let px = 0; px < dim; px++) {\n const dx = px - cx;\n const dy = py - cy;\n const dist = Math.sqrt(dx * dx + dy * dy);\n if (dist > r) continue;\n const edgeFactor = dist / r;\n // Random removal at edges for chalk texture\n if (edgeFactor > hardness && Math.random() > (1 - edgeFactor) * 2) continue;\n if (Math.random() < 0.15) continue; // general texture noise\n const alpha = Math.floor(flow * 255 * (1 - edgeFactor * 0.3));\n const idx = (py * dim + px) * 4;\n data[idx + 3] = alpha;\n }\n }\n tc.putImageData(imgData, 0, 0);\n break;\n }\n\n case 'watercolor': {\n // Soft edges with darker rim (wet edge effect), semi-transparent\n const imgData = tc.getImageData(0, 0, dim, dim);\n const data = imgData.data;\n for (let py = 0; py < dim; py++) {\n for (let px = 0; px < dim; px++) {\n const dx = px - cx;\n const dy = py - cy;\n const dist = Math.sqrt(dx * dx + dy * dy);\n if (dist > r) continue;\n const norm = dist / r;\n // Wet edge: darker ring near the edge\n let alpha: number;\n if (norm > 0.8) {\n alpha = flow * 0.6 * (1 - (norm - 0.8) / 0.2);\n alpha = Math.max(alpha, flow * 0.4 * (norm > 0.85 ? (1 - (norm - 0.85) / 0.15) : 1));\n } else {\n alpha = flow * 0.35;\n }\n const idx = (py * dim + px) * 4;\n data[idx + 3] = Math.floor(alpha * 255);\n }\n }\n tc.putImageData(imgData, 0, 0);\n break;\n }\n\n case 'ink': {\n // Hard edges, variable width handled via pressure\n tc.beginPath();\n tc.arc(0, 0, r, 0, Math.PI * 2);\n tc.fillStyle = `rgba(0,0,0,${flow})`;\n tc.fill();\n break;\n }\n\n case 'pencil': {\n // Small, slightly rough with subtle noise\n const imgData = tc.getImageData(0, 0, dim, dim);\n const data = imgData.data;\n for (let py = 0; py < dim; py++) {\n for (let px = 0; px < dim; px++) {\n const dx = px - cx;\n const dy = py - cy;\n const dist = Math.sqrt(dx * dx + dy * dy);\n if (dist > r) continue;\n if (Math.random() < 0.1) continue; // subtle texture\n const edgeFade = dist > r * hardness ? 1 - (dist - r * hardness) / (r * (1 - hardness)) : 1;\n const alpha = Math.floor(flow * 255 * edgeFade * (0.8 + Math.random() * 0.2));\n const idx = (py * dim + px) * 4;\n data[idx + 3] = alpha;\n }\n }\n tc.putImageData(imgData, 0, 0);\n break;\n }\n\n case 'marker': {\n // Flat-topped, consistent opacity, no falloff\n tc.beginPath();\n tc.arc(0, 0, r, 0, Math.PI * 2);\n tc.fillStyle = `rgba(0,0,0,${flow})`;\n tc.fill();\n break;\n }\n\n case 'eraser': {\n // Same as round — eraser composite is handled in the stroke function\n if (hardness >= 0.99) {\n tc.beginPath();\n tc.arc(0, 0, r, 0, Math.PI * 2);\n tc.fillStyle = `rgba(0,0,0,${flow})`;\n tc.fill();\n } else {\n const grad = tc.createRadialGradient(0, 0, r * hardness, 0, 0, r);\n grad.addColorStop(0, `rgba(0,0,0,${flow})`);\n grad.addColorStop(1, 'rgba(0,0,0,0)');\n tc.beginPath();\n tc.arc(0, 0, r, 0, Math.PI * 2);\n tc.fillStyle = grad;\n tc.fill();\n }\n break;\n }\n }\n\n tc.restore();\n\n // Apply texture overlay\n if (texture !== 'none') {\n applyTextureToTip(tc, dim, texture);\n }\n\n return tip;\n}\n\n/**\n * Apply a texture pattern to the brush tip by multiplying the alpha channel\n * with a generated texture pattern.\n */\nfunction applyTextureToTip(tc: CanvasRenderingContext2D, dim: number, texture: TextureType): void {\n const imgData = tc.getImageData(0, 0, dim, dim);\n const data = imgData.data;\n\n for (let py = 0; py < dim; py++) {\n for (let px = 0; px < dim; px++) {\n const idx = (py * dim + px) * 4;\n if (data[idx + 3] === 0) continue;\n\n let texAlpha = 1;\n switch (texture) {\n case 'canvas-weave':\n // Grid-like pattern\n texAlpha = ((px + py) % 3 === 0) ? 0.6 : 1;\n break;\n case 'paper-grain':\n texAlpha = 0.7 + Math.random() * 0.3;\n break;\n case 'linen':\n // Diagonal line pattern\n texAlpha = ((px + py) % 4 < 2) ? 0.7 : 1;\n break;\n case 'noise':\n texAlpha = 0.5 + Math.random() * 0.5;\n break;\n }\n\n data[idx + 3] = Math.floor(data[idx + 3] * texAlpha);\n }\n }\n\n tc.putImageData(imgData, 0, 0);\n}\n\n/**\n * Colorise a brush tip canvas: replace black pixels with the target color,\n * preserving alpha.\n */\nfunction coloriseTip(tip: Canvas, color: string): Canvas {\n const w = tip.width;\n const h = tip.height;\n const { createCanvas: nodeCreateCanvas } = getCanvasModuleSync();\n const coloured = nodeCreateCanvas(w, h);\n const cc = coloured.getContext('2d');\n\n // Draw a rectangle of the target color\n cc.fillStyle = color;\n cc.fillRect(0, 0, w, h);\n\n // Use the tip as an alpha mask\n cc.globalCompositeOperation = 'destination-in';\n cc.drawImage(tip, 0, 0);\n\n return coloured;\n}\n\n/**\n * Apply color jitter: slightly shift hue/saturation of a color string.\n */\nfunction applyColorJitter(color: string, jitterAmount: number, secondaryColor?: string): string {\n if (jitterAmount <= 0) return color;\n\n if (secondaryColor && Math.random() < jitterAmount) {\n // Blend towards secondary color\n const c1 = parseColor(color);\n const c2 = parseColor(secondaryColor);\n const t = Math.random() * jitterAmount;\n const r = Math.round(c1.r + (c2.r - c1.r) * t);\n const g = Math.round(c1.g + (c2.g - c1.g) * t);\n const b = Math.round(c1.b + (c2.b - c1.b) * t);\n return `rgb(${r},${g},${b})`;\n }\n\n // Simple hue shift\n const c = parseColor(color);\n const shift = (Math.random() - 0.5) * 2 * jitterAmount * 30;\n const r = Math.max(0, Math.min(255, c.r + shift));\n const g = Math.max(0, Math.min(255, c.g + shift * 0.5));\n const b = Math.max(0, Math.min(255, c.b - shift * 0.3));\n return `rgb(${Math.round(r)},${Math.round(g)},${Math.round(b)})`;\n}\n\n// ---------------------------------------------------------------------------\n// 11. setBrush — configure the active brush\n// ---------------------------------------------------------------------------\n\nconst brushTypeEnum = z.enum([\n 'round', 'flat', 'fan', 'filbert', 'palette-knife',\n 'airbrush', 'splatter', 'chalk', 'watercolor', 'ink',\n 'pencil', 'marker', 'eraser',\n]);\n\nconst blendModeEnum = z.enum(['normal', 'multiply', 'screen', 'overlay']);\n\nconst textureEnum = z.enum(['none', 'canvas-weave', 'paper-grain', 'linen', 'noise']);\n\nconst jitterSchema = z.object({\n sizeJitter: z.number().min(0).max(1).optional().describe('Random size variation 0-1.'),\n opacityJitter: z.number().min(0).max(1).optional().describe('Random opacity variation 0-1.'),\n angleJitter: z.number().min(0).max(1).optional().describe('Random angle variation 0-1.'),\n colorJitter: z.number().min(0).max(1).optional().describe('Random hue/saturation variation 0-1.'),\n}).optional().describe('Randomness settings for natural brush effects.');\n\nexport const setBrush = tool({\n description:\n 'Configure the active brush for a canvas (Photoshop-like brush settings). ' +\n 'All settings persist until changed. Affects all subsequent brushStroke calls on this canvas. ' +\n 'Available brush types: round, flat, fan, filbert, palette-knife, airbrush, splatter, chalk, watercolor, ink, pencil, marker, eraser.',\n inputSchema: z.object({\n canvasId: canvasIdSchema,\n type: brushTypeEnum.optional().describe('Brush type. Default \"round\".'),\n size: z.number().min(1).max(500).optional().describe('Brush diameter in pixels (1-500). Default 10.'),\n opacity: z.number().min(0).max(1).optional().describe('Brush opacity 0-1. Default 1.'),\n hardness: z.number().min(0).max(1).optional().describe('Edge hardness: 1=hard, 0=soft/feathered. Default 0.8.'),\n flow: z.number().min(0).max(1).optional().describe('Paint flow rate 0-1. Lower = more transparent buildup. Default 1.'),\n spacing: z.number().min(0.1).max(5).optional().describe('Distance between stamps as fraction of brush size (0.1-5). Default 0.25.'),\n angle: z.number().min(0).max(360).optional().describe('Brush rotation in degrees (0-360). Default 0.'),\n roundness: z.number().min(0).max(1).optional().describe('1=circular, lower=elliptical. Default 1.'),\n scatter: z.number().min(0).max(5).optional().describe('Random perpendicular offset (0-5). Default 0.'),\n jitter: jitterSchema,\n color: z.string().optional().describe('Primary brush color (CSS format). Default \"black\".'),\n secondaryColor: z.string().optional().describe('Secondary color for dual-color brushes (used with colorJitter).'),\n blendMode: blendModeEnum.optional().describe('Blend mode: normal, multiply, screen, overlay. Default \"normal\".'),\n pressureSensitivity: z.boolean().optional().describe('Simulate pressure variation along strokes. Default false.'),\n texture: textureEnum.optional().describe('Texture overlay: none, canvas-weave, paper-grain, linen, noise. Default \"none\".'),\n }),\n execute: async ({ canvasId, type, size, opacity, hardness, flow, spacing, angle, roundness, scatter, jitter, color, secondaryColor, blendMode, pressureSensitivity, texture }) => {\n try {\n requireCanvas(canvasId); // validate canvas exists\n const brush = getBrush(canvasId);\n\n if (type !== undefined) brush.type = type;\n if (size !== undefined) brush.size = size;\n if (opacity !== undefined) brush.opacity = opacity;\n if (hardness !== undefined) brush.hardness = hardness;\n if (flow !== undefined) brush.flow = flow;\n if (spacing !== undefined) brush.spacing = spacing;\n if (angle !== undefined) brush.angle = angle;\n if (roundness !== undefined) brush.roundness = roundness;\n if (scatter !== undefined) brush.scatter = scatter;\n if (jitter !== undefined) brush.jitter = jitter;\n if (color !== undefined) brush.color = color;\n if (secondaryColor !== undefined) brush.secondaryColor = secondaryColor;\n if (blendMode !== undefined) brush.blendMode = blendMode;\n if (pressureSensitivity !== undefined) brush.pressureSensitivity = pressureSensitivity;\n if (texture !== undefined) brush.texture = texture;\n\n brushStore.set(canvasId, brush);\n\n return {\n success: true,\n canvasId,\n brush: { ...brush },\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ---------------------------------------------------------------------------\n// 12. brushStroke — paint a brush stroke\n// ---------------------------------------------------------------------------\n\nconst strokePointSchema = z.object({\n x: z.number(),\n y: z.number(),\n pressure: z.number().min(0).max(1).optional().describe('Simulated pen pressure 0-1 at this point.'),\n});\n\nexport const brushStroke = tool({\n description:\n 'Paint a brush stroke along a path using the current brush settings (configured with setBrush). ' +\n 'Provide an array of points; the brush engine interpolates between them. More points = smoother strokes. ' +\n 'Optionally override color, size, or opacity for this stroke only.',\n inputSchema: z.object({\n canvasId: canvasIdSchema,\n points: z.array(strokePointSchema).min(2).describe('Stroke path: array of {x, y, pressure?}. Minimum 2 points.'),\n color: z.string().optional().describe('Override brush color for this stroke only.'),\n size: z.number().min(1).max(500).optional().describe('Override brush size for this stroke only.'),\n opacity: z.number().min(0).max(1).optional().describe('Override opacity for this stroke only.'),\n }),\n execute: async ({ canvasId, points, color, size, opacity }) => {\n try {\n const { createCanvas: nodeCreateCanvas } = await getCanvasModule();\n const entry = requireCanvas(canvasId);\n const { ctx } = entry;\n const brush = getBrush(canvasId);\n\n const strokeColor = color ?? brush.color;\n const strokeSize = size ?? brush.size;\n const strokeOpacity = opacity ?? brush.opacity;\n\n // Create an offscreen canvas for compositing the entire stroke\n const strokeCanvas = nodeCreateCanvas(entry.width, entry.height);\n const sc = strokeCanvas.getContext('2d');\n\n let stampCount = 0;\n\n // Walk the path, placing stamps at spacing intervals\n for (let seg = 0; seg < points.length - 1; seg++) {\n const p0 = points[seg];\n const p1 = points[seg + 1];\n const dx = p1.x - p0.x;\n const dy = p1.y - p0.y;\n const dist = Math.sqrt(dx * dx + dy * dy);\n const stepSize = Math.max(1, strokeSize * brush.spacing);\n const steps = Math.max(1, Math.ceil(dist / stepSize));\n\n for (let i = 0; i <= steps; i++) {\n const t = steps === 0 ? 0 : i / steps;\n let stampX = p0.x + dx * t;\n let stampY = p0.y + dy * t;\n const pressure = brush.pressureSensitivity\n ? (p0.pressure ?? 1) + ((p1.pressure ?? 1) - (p0.pressure ?? 1)) * t\n : 1;\n\n // Compute effective size and opacity with pressure\n let effSize = strokeSize;\n let effOpacity = strokeOpacity;\n if (brush.pressureSensitivity) {\n effSize = strokeSize * (0.3 + 0.7 * pressure);\n effOpacity = strokeOpacity * (0.2 + 0.8 * pressure);\n }\n\n // Apply jitter\n if (brush.jitter.sizeJitter) {\n effSize *= 1 + (Math.random() - 0.5) * 2 * brush.jitter.sizeJitter;\n effSize = Math.max(1, effSize);\n }\n if (brush.jitter.opacityJitter) {\n effOpacity *= 1 - Math.random() * brush.jitter.opacityJitter;\n effOpacity = Math.max(0, Math.min(1, effOpacity));\n }\n\n let effAngle = brush.angle;\n if (brush.jitter.angleJitter) {\n effAngle += (Math.random() - 0.5) * 360 * brush.jitter.angleJitter;\n }\n\n // Apply scatter\n if (brush.scatter > 0) {\n const perpAngle = Math.atan2(dy, dx) + Math.PI / 2;\n const scatterDist = (Math.random() - 0.5) * 2 * brush.scatter * effSize;\n stampX += Math.cos(perpAngle) * scatterDist;\n stampY += Math.sin(perpAngle) * scatterDist;\n }\n\n // Apply color jitter\n let stampColor = strokeColor;\n if (brush.jitter.colorJitter) {\n stampColor = applyColorJitter(strokeColor, brush.jitter.colorJitter, brush.secondaryColor);\n }\n\n // Generate and colourise the brush tip\n const tip = generateBrushTip(\n brush.type, effSize, brush.hardness, brush.roundness,\n effAngle, brush.texture, brush.flow,\n );\n const colouredTip = coloriseTip(tip, stampColor);\n\n // Stamp onto the stroke canvas\n sc.globalAlpha = effOpacity;\n sc.drawImage(\n colouredTip,\n Math.round(stampX - colouredTip.width / 2),\n Math.round(stampY - colouredTip.height / 2),\n );\n\n stampCount++;\n }\n }\n\n // Composite the stroke canvas onto the main canvas\n ctx.save();\n if (brush.type === 'eraser') {\n ctx.globalCompositeOperation = 'destination-out';\n } else {\n ctx.globalCompositeOperation = blendModeToComposite[brush.blendMode] as CanvasRenderingContext2D['globalCompositeOperation'];\n }\n ctx.drawImage(strokeCanvas, 0, 0);\n ctx.restore();\n\n return {\n success: true,\n canvasId,\n pointCount: points.length,\n stampCount,\n brushType: brush.type,\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ---------------------------------------------------------------------------\n// 13. brushFill — fill an area with brush texture\n// ---------------------------------------------------------------------------\n\nexport const brushFill = tool({\n description:\n 'Fill a contiguous area using the current brush texture and color (paint bucket with brush texture). ' +\n 'Uses flood fill from the starting point, applying the brush color.',\n inputSchema: z.object({\n canvasId: canvasIdSchema,\n x: z.number().int().describe('Starting X coordinate.'),\n y: z.number().int().describe('Starting Y coordinate.'),\n tolerance: z.number().int().min(0).max(255).optional().describe('Color match tolerance 0-255. Default 30.'),\n color: z.string().optional().describe('Override brush color for this fill.'),\n }),\n execute: async ({ canvasId, x, y, tolerance, color }) => {\n try {\n await getCanvasModule(); // ensure canvas is loaded for parseColor\n const entry = requireCanvas(canvasId);\n const { ctx, width, height } = entry;\n const brush = getBrush(canvasId);\n const fillColorStr = color ?? brush.color;\n const tol = tolerance ?? 30;\n\n if (x < 0 || x >= width || y < 0 || y >= height) {\n return { success: false, error: `Coordinates (${x}, ${y}) out of bounds (${width}x${height}).` };\n }\n\n const imageData = ctx.getImageData(0, 0, width, height);\n const data = imageData.data;\n\n const targetIdx = (y * width + x) * 4;\n const tr = data[targetIdx];\n const tg = data[targetIdx + 1];\n const tb = data[targetIdx + 2];\n const ta = data[targetIdx + 3];\n\n const fillColor = parseColor(fillColorStr);\n\n if (tr === fillColor.r && tg === fillColor.g && tb === fillColor.b && ta === fillColor.a) {\n return { success: true, canvasId, pixelsFilled: 0 };\n }\n\n const matches = (idx: number): boolean =>\n Math.abs(data[idx] - tr) <= tol &&\n Math.abs(data[idx + 1] - tg) <= tol &&\n Math.abs(data[idx + 2] - tb) <= tol &&\n Math.abs(data[idx + 3] - ta) <= tol;\n\n // Generate a texture pattern if brush has texture\n const hasTexture = brush.texture !== 'none';\n\n const stack: number[] = [x, y];\n const visited = new Uint8Array(width * height);\n let filled = 0;\n\n while (stack.length > 0) {\n const py = stack.pop()!;\n const px = stack.pop()!;\n const pos = py * width + px;\n\n if (px < 0 || px >= width || py < 0 || py >= height) continue;\n if (visited[pos]) continue;\n visited[pos] = 1;\n\n const idx = pos * 4;\n if (!matches(idx)) continue;\n\n let texAlpha = 1;\n if (hasTexture) {\n switch (brush.texture) {\n case 'canvas-weave': texAlpha = ((px + py) % 3 === 0) ? 0.6 : 1; break;\n case 'paper-grain': texAlpha = 0.7 + (((px * 17 + py * 31) % 100) / 100) * 0.3; break;\n case 'linen': texAlpha = ((px + py) % 4 < 2) ? 0.7 : 1; break;\n case 'noise': texAlpha = 0.5 + (((px * 13 + py * 29) % 100) / 100) * 0.5; break;\n }\n }\n\n const alpha = Math.floor(fillColor.a * brush.opacity * texAlpha);\n // Alpha-blend the fill color\n const srcA = alpha / 255;\n const dstA = data[idx + 3] / 255;\n const outA = srcA + dstA * (1 - srcA);\n if (outA > 0) {\n data[idx] = Math.round((fillColor.r * srcA + data[idx] * dstA * (1 - srcA)) / outA);\n data[idx + 1] = Math.round((fillColor.g * srcA + data[idx + 1] * dstA * (1 - srcA)) / outA);\n data[idx + 2] = Math.round((fillColor.b * srcA + data[idx + 2] * dstA * (1 - srcA)) / outA);\n data[idx + 3] = Math.floor(outA * 255);\n }\n filled++;\n\n stack.push(px + 1, py);\n stack.push(px - 1, py);\n stack.push(px, py + 1);\n stack.push(px, py - 1);\n }\n\n ctx.putImageData(imageData, 0, 0);\n\n return { success: true, canvasId, pixelsFilled: filled, color: fillColorStr };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ---------------------------------------------------------------------------\n// 14. brushSmudge — smudge/blend colors\n// ---------------------------------------------------------------------------\n\nexport const brushSmudge = tool({\n description:\n 'Smudge/blend colors along a path, simulating finger-smudging paint on canvas. ' +\n 'Picks up color from the starting point and drags it along the path.',\n inputSchema: z.object({\n canvasId: canvasIdSchema,\n points: z.array(z.object({ x: z.number(), y: z.number() })).min(2).describe('Smudge path: array of {x, y}. Minimum 2 points.'),\n strength: z.number().min(0).max(1).optional().describe('Smudge intensity 0-1. Default 0.5.'),\n size: z.number().min(1).max(500).optional().describe('Override brush size for smudge radius.'),\n }),\n execute: async ({ canvasId, points, strength, size }) => {\n try {\n const entry = requireCanvas(canvasId);\n const { ctx, width, height } = entry;\n const brush = getBrush(canvasId);\n const smudgeStrength = strength ?? 0.5;\n const smudgeSize = size ?? brush.size;\n const radius = Math.floor(smudgeSize / 2);\n\n const imageData = ctx.getImageData(0, 0, width, height);\n const data = imageData.data;\n\n // Sample the starting area\n const sampleRadius = radius;\n let avgR = 0, avgG = 0, avgB = 0, avgA = 0, sampleCount = 0;\n const sx = Math.round(points[0].x);\n const sy = Math.round(points[0].y);\n\n for (let dy = -sampleRadius; dy <= sampleRadius; dy++) {\n for (let dx = -sampleRadius; dx <= sampleRadius; dx++) {\n if (dx * dx + dy * dy > sampleRadius * sampleRadius) continue;\n const px = sx + dx;\n const py = sy + dy;\n if (px < 0 || px >= width || py < 0 || py >= height) continue;\n const idx = (py * width + px) * 4;\n avgR += data[idx];\n avgG += data[idx + 1];\n avgB += data[idx + 2];\n avgA += data[idx + 3];\n sampleCount++;\n }\n }\n\n if (sampleCount > 0) {\n avgR /= sampleCount;\n avgG /= sampleCount;\n avgB /= sampleCount;\n avgA /= sampleCount;\n }\n\n // Walk the path and smudge\n for (let seg = 0; seg < points.length - 1; seg++) {\n const p0 = points[seg];\n const p1 = points[seg + 1];\n const dx = p1.x - p0.x;\n const dy = p1.y - p0.y;\n const dist = Math.sqrt(dx * dx + dy * dy);\n const steps = Math.max(1, Math.ceil(dist / Math.max(1, radius * 0.5)));\n\n for (let i = 1; i <= steps; i++) {\n const t = i / steps;\n const cx = Math.round(p0.x + dx * t);\n const cy = Math.round(p0.y + dy * t);\n\n for (let oy = -radius; oy <= radius; oy++) {\n for (let ox = -radius; ox <= radius; ox++) {\n if (ox * ox + oy * oy > radius * radius) continue;\n const px = cx + ox;\n const py = cy + oy;\n if (px < 0 || px >= width || py < 0 || py >= height) continue;\n\n const idx = (py * width + px) * 4;\n const distFromCenter = Math.sqrt(ox * ox + oy * oy) / radius;\n const falloff = 1 - distFromCenter;\n const blendAmount = smudgeStrength * falloff;\n\n // Blend carried color with canvas color\n data[idx] = Math.round(data[idx] * (1 - blendAmount) + avgR * blendAmount);\n data[idx + 1] = Math.round(data[idx + 1] * (1 - blendAmount) + avgG * blendAmount);\n data[idx + 2] = Math.round(data[idx + 2] * (1 - blendAmount) + avgB * blendAmount);\n data[idx + 3] = Math.round(data[idx + 3] * (1 - blendAmount) + avgA * blendAmount);\n }\n }\n\n // Pick up color from current position for the next step\n let newR = 0, newG = 0, newB = 0, newA = 0;\n let cnt = 0;\n for (let oy = -radius; oy <= radius; oy++) {\n for (let ox = -radius; ox <= radius; ox++) {\n if (ox * ox + oy * oy > radius * radius) continue;\n const px = cx + ox;\n const py = cy + oy;\n if (px < 0 || px >= width || py < 0 || py >= height) continue;\n const idx = (py * width + px) * 4;\n newR += data[idx]; newG += data[idx + 1]; newB += data[idx + 2]; newA += data[idx + 3];\n cnt++;\n }\n }\n if (cnt > 0) {\n avgR = newR / cnt; avgG = newG / cnt; avgB = newB / cnt; avgA = newA / cnt;\n }\n }\n }\n\n ctx.putImageData(imageData, 0, 0);\n\n return {\n success: true,\n canvasId,\n pointCount: points.length,\n strength: smudgeStrength,\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ---------------------------------------------------------------------------\n// 15. brushBlur — blur a region\n// ---------------------------------------------------------------------------\n\nexport const brushBlur = tool({\n description: 'Apply a box blur to a rectangular region of the canvas.',\n inputSchema: z.object({\n canvasId: canvasIdSchema,\n x: z.number().int().describe('Region X.'),\n y: z.number().int().describe('Region Y.'),\n width: z.number().int().min(1).describe('Region width.'),\n height: z.number().int().min(1).describe('Region height.'),\n radius: z.number().int().min(1).max(50).optional().describe('Blur radius 1-50 pixels. Default 5.'),\n }),\n execute: async ({ canvasId, x, y, width: rw, height: rh, radius }) => {\n try {\n const entry = requireCanvas(canvasId);\n const { ctx, width: cw, height: ch } = entry;\n const blurRadius = radius ?? 5;\n\n // Clamp the region to canvas bounds\n const x0 = Math.max(0, x);\n const y0 = Math.max(0, y);\n const x1 = Math.min(cw, x + rw);\n const y1 = Math.min(ch, y + rh);\n const regionW = x1 - x0;\n const regionH = y1 - y0;\n\n if (regionW <= 0 || regionH <= 0) {\n return { success: false, error: 'Region is outside canvas bounds.' };\n }\n\n const imageData = ctx.getImageData(0, 0, cw, ch);\n const data = imageData.data;\n const copy = new Uint8ClampedArray(data);\n\n // Box blur — horizontal pass then vertical pass for efficiency\n const temp = new Uint8ClampedArray(data.length);\n\n // Horizontal pass\n for (let py = y0; py < y1; py++) {\n for (let px = x0; px < x1; px++) {\n let r = 0, g = 0, b = 0, a = 0, count = 0;\n for (let kx = -blurRadius; kx <= blurRadius; kx++) {\n const sx = Math.max(0, Math.min(cw - 1, px + kx));\n const idx = (py * cw + sx) * 4;\n r += copy[idx]; g += copy[idx + 1]; b += copy[idx + 2]; a += copy[idx + 3];\n count++;\n }\n const idx = (py * cw + px) * 4;\n temp[idx] = r / count;\n temp[idx + 1] = g / count;\n temp[idx + 2] = b / count;\n temp[idx + 3] = a / count;\n }\n }\n\n // Copy non-region pixels to temp\n for (let py = 0; py < ch; py++) {\n for (let px = 0; px < cw; px++) {\n if (py >= y0 && py < y1 && px >= x0 && px < x1) continue;\n const idx = (py * cw + px) * 4;\n temp[idx] = copy[idx];\n temp[idx + 1] = copy[idx + 1];\n temp[idx + 2] = copy[idx + 2];\n temp[idx + 3] = copy[idx + 3];\n }\n }\n\n // Vertical pass\n for (let py = y0; py < y1; py++) {\n for (let px = x0; px < x1; px++) {\n let r = 0, g = 0, b = 0, a = 0, count = 0;\n for (let ky = -blurRadius; ky <= blurRadius; ky++) {\n const sy = Math.max(0, Math.min(ch - 1, py + ky));\n const idx = (sy * cw + px) * 4;\n r += temp[idx]; g += temp[idx + 1]; b += temp[idx + 2]; a += temp[idx + 3];\n count++;\n }\n const idx = (py * cw + px) * 4;\n data[idx] = r / count;\n data[idx + 1] = g / count;\n data[idx + 2] = b / count;\n data[idx + 3] = a / count;\n }\n }\n\n ctx.putImageData(imageData, 0, 0);\n\n return {\n success: true,\n canvasId,\n region: { x: x0, y: y0, width: regionW, height: regionH },\n blurRadius,\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n","import { tool } from 'ai';\nimport { z } from 'zod';\nimport { platform, arch, hostname, homedir, cpus, totalmem, freemem } from 'node:os';\nimport { resolve } from 'node:path';\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { existsSync } from 'node:fs';\n\nconst execFileAsync = promisify(execFile);\n\nasync function getCommandVersion(cmd: string, args: string[]): Promise<string | null> {\n try {\n const { stdout } = await execFileAsync(cmd, args, { timeout: 5_000 });\n return stdout.trim().split('\\n')[0] ?? null;\n } catch {\n return null;\n }\n}\n\n// ── systemInfo ──────────────────────────────────────────────────────\n\nexport const systemInfo = tool({\n description:\n 'Get information about the system: OS, architecture, Node.js version, and detected tool versions (git, npm, etc.).',\n inputSchema: z.object({}),\n execute: async () => {\n try {\n const [gitVersion, npmVersion, nodeVersion] = await Promise.all([\n getCommandVersion('git', ['--version']),\n getCommandVersion('npm', ['--version']),\n getCommandVersion('node', ['--version']),\n ]);\n\n return {\n success: true,\n platform: platform(),\n arch: arch(),\n hostname: hostname(),\n homeDir: homedir(),\n nodeVersion: process.version,\n nodeVersionDetected: nodeVersion,\n gitVersion: gitVersion ?? 'not found',\n npmVersion: npmVersion ?? 'not found',\n cpuCount: cpus().length,\n totalMemoryMB: Math.round(totalmem() / 1024 / 1024),\n freeMemoryMB: Math.round(freemem() / 1024 / 1024),\n cwd: process.cwd(),\n env: {\n NODE_ENV: process.env.NODE_ENV ?? 'not set',\n SHELL: process.env.SHELL ?? process.env.ComSpec ?? 'not set',\n },\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── getCwd ──────────────────────────────────────────────────────────\n\nexport const getCwd = tool({\n description: 'Get the current working directory.',\n inputSchema: z.object({}),\n execute: async () => {\n try {\n return { success: true, cwd: process.cwd() };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── changeCwd ───────────────────────────────────────────────────────\n\nexport const changeCwd = tool({\n description: 'Change the current working directory.',\n inputSchema: z.object({\n path: z.string().describe('The directory to change to (absolute or relative).'),\n }),\n execute: async ({ path }) => {\n try {\n const target = resolve(path);\n\n if (!existsSync(target)) {\n return { success: false, error: `Directory does not exist: \"${target}\"` };\n }\n\n process.chdir(target);\n return { success: true, cwd: process.cwd() };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n","import { tool } from 'ai';\nimport { z } from 'zod';\nimport type { SmartHomeAdapter, DeviceConfig } from './types.js';\nimport { listDevices, getDevice } from './registry.js';\nimport { googleCastAdapter } from './adapters/google-cast.js';\nimport { alexaAdapter } from './adapters/alexa.js';\nimport { searchYouTube } from './youtube.js';\nimport { appendFileSync } from 'node:fs';\n\nconst DIAG_LOG = 'cast-diag.log';\nfunction toolDiag(msg: string): void {\n const line = `${new Date().toISOString()} ${msg}\\n`;\n try { appendFileSync(DIAG_LOG, line); } catch { /* ignore */ }\n}\n\nfunction getAdapter(config: DeviceConfig): SmartHomeAdapter {\n switch (config.platform) {\n case 'google-cast':\n return googleCastAdapter;\n case 'alexa':\n return alexaAdapter;\n default:\n throw new Error(`Unknown platform: ${config.platform}`);\n }\n}\n\n// ── Tool 1: List all smart devices ─────────────────────────────────\n\nexport const listSmartDevices = tool({\n description:\n 'List all configured smart home devices with their platform and connection info. ' +\n 'Optionally fetch live status for each device.',\n inputSchema: z.object({\n includeStatus: z\n .boolean()\n .optional()\n .describe('If true, fetch live status for each device. Default false (faster).'),\n }),\n execute: async ({ includeStatus }) => {\n try {\n const devices = listDevices();\n\n if (devices.length === 0) {\n return {\n success: true,\n devices: [],\n message: 'No smart home devices configured. Use /devices to add one.',\n };\n }\n\n const results = [];\n\n for (const device of devices) {\n const entry: Record<string, unknown> = {\n id: device.id,\n name: device.name,\n platform: device.platform,\n };\n\n if (device.cast) {\n entry.host = device.cast.host;\n entry.port = device.cast.port ?? 8009;\n }\n\n if (includeStatus) {\n try {\n const adapter = getAdapter(device);\n const status = await adapter.getStatus(device);\n entry.status = status;\n } catch (error) {\n entry.status = { online: false, error: error instanceof Error ? error.message : String(error) };\n }\n }\n\n results.push(entry);\n }\n\n return { success: true, devices: results, count: results.length };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── Tool 2: Get device status ──────────────────────────────────────\n\nexport const getDeviceStatus = tool({\n description: 'Get the current status of a specific smart home device (online, volume, media playing, etc.).',\n inputSchema: z.object({\n deviceId: z.string().describe('The device ID (e.g., \"living-room-speaker\").'),\n }),\n execute: async ({ deviceId }) => {\n try {\n const device = getDevice(deviceId);\n if (!device) {\n return { success: false, error: `Device \"${deviceId}\" not found. Use listSmartDevices to see available devices.` };\n }\n\n const adapter = getAdapter(device);\n const status = await adapter.getStatus(device);\n\n return { success: true, deviceId, name: device.name, ...status, platform: device.platform };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── Tool 3: Control device ─────────────────────────────────────────\n\nexport const controlDevice = tool({\n description:\n 'Control a smart home device: pause, resume, stop playback, seek to a position, set volume, mute, or unmute. ' +\n 'Volume is 0-100. Seek value is in seconds (e.g. 90 for 1:30).',\n inputSchema: z.object({\n deviceId: z.string().describe('The device ID.'),\n action: z.enum(['pause', 'resume', 'stop', 'setVolume', 'mute', 'unmute', 'seek']).describe('The control action.'),\n value: z.number().optional().describe('Value for setVolume (0-100) or seek (seconds, e.g. 90 for 1:30, 3600 for 1:00:00).'),\n }),\n execute: async ({ deviceId, action, value }) => {\n try {\n const device = getDevice(deviceId);\n if (!device) {\n return { success: false, error: `Device \"${deviceId}\" not found.` };\n }\n\n const adapter = getAdapter(device);\n const result = await adapter.controlPlayback(device, action, value);\n\n return { ...result, deviceId, action, value };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── Tool 4: Play media ─────────────────────────────────────────────\n\nexport const playMedia = tool({\n description:\n 'Play an audio or video URL on a smart home device. ' +\n 'For Google Cast, supports any URL the device can stream (MP3, MP4, etc.). ' +\n 'Alternatively, provide a search query to find and play a YouTube video.',\n inputSchema: z.object({\n deviceId: z.string().describe('The device ID.'),\n mediaUrl: z.string().optional().describe('The URL of the media to play. Required unless query is provided.'),\n query: z\n .string()\n .optional()\n .describe(\n 'Natural language search query for music/video. Searches YouTube and plays the top result. ' +\n 'Example: \"ambient jazz music\", \"lo-fi beats to relax to\". If both query and mediaUrl are given, mediaUrl takes precedence.',\n ),\n contentType: z.string().optional().describe('MIME type (e.g., \"audio/mp3\", \"video/mp4\"). Default \"audio/mp3\".'),\n title: z.string().optional().describe('Display title for the media.'),\n }),\n execute: async ({ deviceId, mediaUrl, query, contentType, title }) => {\n toolDiag(`[tool] playMedia CALLED: deviceId=${deviceId}, mediaUrl=${mediaUrl}, query=${query}, title=${title}`);\n try {\n const device = getDevice(deviceId);\n if (!device) {\n return { success: false, error: `Device \"${deviceId}\" not found.` };\n }\n\n const adapter = getAdapter(device);\n toolDiag(`[tool] playMedia adapter: platform=${device.platform}, hasCastYouTube=${!!adapter.castYouTube}`);\n\n // If a direct URL is provided, cast it directly\n if (mediaUrl) {\n const result = await adapter.playMedia(device, mediaUrl, contentType, title);\n return { ...result, deviceId, mediaUrl, title };\n }\n\n // If a search query is provided, search YouTube and cast the top result\n if (query) {\n const videos = await searchYouTube(query, 1);\n if (videos.length === 0) {\n return { success: false, error: `No YouTube results found for \"${query}\".` };\n }\n\n const video = videos[0];\n\n if (adapter.castYouTube) {\n const result = await adapter.castYouTube(device, video.videoId, video.title);\n return {\n ...result,\n deviceId,\n query,\n nowPlaying: { title: video.title, author: video.author, duration: video.duration, url: video.url },\n };\n }\n\n // Fallback: cast the YouTube URL as a regular media URL\n const result = await adapter.playMedia(device, video.url, 'video/mp4', video.title);\n return {\n ...result,\n deviceId,\n query,\n nowPlaying: { title: video.title, author: video.author, duration: video.duration, url: video.url },\n };\n }\n\n return { success: false, error: 'Either mediaUrl or query must be provided.' };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── Tool 5: Send notification ──────────────────────────────────────\n\nexport const sendNotification = tool({\n description:\n 'Send a text-to-speech notification to a smart home speaker. ' +\n 'For Google Cast, uses Google TTS to generate audio. For Alexa, uses the announcement API.',\n inputSchema: z.object({\n deviceId: z.string().describe('The device ID.'),\n message: z.string().describe('The message to speak.'),\n language: z.string().optional().describe('Language code (e.g., \"en\", \"es\", \"fr\"). Default \"en\".'),\n }),\n execute: async ({ deviceId, message, language }) => {\n try {\n const device = getDevice(deviceId);\n if (!device) {\n return { success: false, error: `Device \"${deviceId}\" not found.` };\n }\n\n const adapter = getAdapter(device);\n const result = await adapter.sendNotification(device, message, language);\n\n return { ...result, deviceId, message };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── Tool 6a: Search music ──────────────────────────────────────────\n\nexport const searchMusic = tool({\n description:\n 'Search YouTube for music or audio content. Returns a list of candidates with title, artist, duration, and videoId. ' +\n 'Does NOT play anything — use playMusic to play a specific result.',\n inputSchema: z.object({\n query: z\n .string()\n .describe(\n 'What to search for — a natural language description. Examples: \"ambient jazz music\", \"Beatles Abbey Road\", ' +\n '\"lo-fi beats to relax to\", \"white noise for sleeping\", \"90s hip hop playlist\".',\n ),\n maxResults: z\n .number()\n .optional()\n .describe('Number of YouTube search results to return (1-10). Default 5.'),\n }),\n execute: async ({ query, maxResults }) => {\n try {\n const count = Math.max(1, Math.min(maxResults ?? 5, 10));\n const videos = await searchYouTube(query, count);\n\n if (videos.length === 0) {\n return { success: false, error: `No YouTube results found for \"${query}\".` };\n }\n\n return {\n success: true,\n results: videos.map((v) => ({\n videoId: v.videoId,\n title: v.title,\n author: v.author,\n duration: v.duration,\n url: v.url,\n })),\n };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── Tool 6b: Play music by videoId ────────────────────────────────\n\nexport const playMusic = tool({\n description:\n 'Play a specific YouTube video (by videoId from searchMusic) on a smart home speaker. ' +\n 'Always call searchMusic first to get candidate videoIds, then call this tool with the chosen videoId.',\n inputSchema: z.object({\n deviceId: z.string().describe('The device ID (e.g., \"living-room-speaker\").'),\n videoId: z.string().describe('The YouTube video ID to play (from searchMusic results).'),\n title: z.string().optional().describe('Display title for the media (shown on device UI).'),\n }),\n execute: async ({ deviceId, videoId, title }) => {\n toolDiag(`[tool] playMusic CALLED: deviceId=${deviceId}, videoId=${videoId}, title=${title}`);\n try {\n const device = getDevice(deviceId);\n if (!device) {\n return { success: false, error: `Device \"${deviceId}\" not found. Use listSmartDevices to see available devices.` };\n }\n\n const adapter = getAdapter(device);\n const url = `https://www.youtube.com/watch?v=${videoId}`;\n toolDiag(`[tool] playMusic adapter: platform=${device.platform}, hasCastYouTube=${!!adapter.castYouTube}`);\n\n if (adapter.castYouTube) {\n toolDiag(`[tool] playMusic calling adapter.castYouTube(${videoId})...`);\n const result = await adapter.castYouTube(device, videoId, title);\n toolDiag(`[tool] playMusic castYouTube returned: success=${result.success}, error=${result.error ?? 'none'}`);\n if (result.success) {\n return {\n ...result,\n deviceId,\n nowPlaying: { title: title ?? videoId, url },\n };\n }\n return { success: false, error: result.error ?? `Failed to cast video ${videoId} to ${deviceId}.` };\n }\n\n // Fallback: cast the YouTube URL as a regular media URL\n const result = await adapter.playMedia(device, url, 'video/mp4', title);\n if (result.success) {\n return {\n ...result,\n deviceId,\n nowPlaying: { title: title ?? videoId, url },\n };\n }\n\n return { success: false, error: `Failed to play video ${videoId} on ${deviceId}.` };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n\n// ── Tool 7: Ask Google Assistant ──────────────────────────────────\n\nexport const askAssistant = tool({\n description:\n 'Send a Google Assistant command to a Google Home device for NON-MUSIC tasks. ' +\n 'Use this for: smart home control (\"turn off the lights\"), questions (\"what is the weather\"), ' +\n 'timers (\"set a timer for 10 minutes\"), broadcasts (\"broadcast dinner is ready\"), routines, ' +\n 'and general knowledge questions. ' +\n 'Do NOT use this for playing music or audio — the Assistant SDK cannot play media on the device. ' +\n 'For music requests, use playMusic instead (YouTube search + Cast). ' +\n 'Requires Google Assistant SDK credentials.',\n inputSchema: z.object({\n deviceId: z.string().describe('The device ID (e.g., \"living-room-speaker\").'),\n command: z\n .string()\n .describe(\n 'The command to send to Google Assistant, exactly as you would say it out loud. ' +\n 'Examples: \"set a timer for 10 minutes\", \"what is the weather today\", ' +\n '\"turn off the living room lights\", \"broadcast dinner is ready\", ' +\n '\"what time is it\", \"add milk to my shopping list\".',\n ),\n language: z\n .string()\n .optional()\n .describe('Language code (e.g., \"en-US\", \"es-ES\", \"fr-FR\"). Default \"en-US\".'),\n }),\n execute: async ({ deviceId, command, language }) => {\n try {\n const device = getDevice(deviceId);\n if (!device) {\n return {\n success: false,\n error: `Device \"${deviceId}\" not found. Use listSmartDevices to see available devices.`,\n };\n }\n\n const adapter = getAdapter(device);\n if (!adapter.askAssistant) {\n return {\n success: false,\n error: `The ${device.platform} platform does not support Google Assistant commands.`,\n };\n }\n\n const result = await adapter.askAssistant(device, command, language);\n\n return { ...result, deviceId, command };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n },\n});\n","/**\n * YouTube search helper — uses `yt-search` to find videos without an API key.\n */\n\nlet ytSearchLoaded: typeof import('yt-search').default | null = null;\n\nasync function getYtSearch(): Promise<typeof import('yt-search').default> {\n if (!ytSearchLoaded) {\n try {\n const mod = await import('yt-search');\n ytSearchLoaded = mod.default;\n } catch {\n throw new Error('yt-search is not installed. Run: npm install yt-search');\n }\n }\n return ytSearchLoaded;\n}\n\nexport interface YouTubeVideo {\n videoId: string;\n title: string;\n url: string;\n duration: string;\n author: string;\n}\n\n/**\n * Search YouTube for videos matching a query.\n * Returns a compact list of results suitable for casting.\n */\nexport async function searchYouTube(query: string, maxResults = 5): Promise<YouTubeVideo[]> {\n const ytSearch = await getYtSearch();\n const result = await ytSearch(query);\n\n return result.videos.slice(0, maxResults).map((v) => ({\n videoId: v.videoId,\n title: v.title,\n url: v.url,\n duration: v.timestamp,\n author: v.author.name,\n }));\n}\n","import type { ToolSet } from 'ai';\nimport type { ToolMetadata } from './types.js';\n\n/**\n * Wraps a set of AI SDK tools with a confirmation middleware.\n *\n * - Read-only tools execute immediately.\n * - Mutating tools prompt the user for confirmation before executing.\n * - Destructive tools always prompt (no bypass).\n *\n * If the user declines, the tool returns `{ success: false, error: 'User declined this action.' }`.\n */\nexport function wrapToolsWithConfirmation(\n tools: ToolSet,\n metadata: Map<string, ToolMetadata>,\n confirmFn: (message: string) => Promise<boolean>,\n): ToolSet {\n const wrapped: ToolSet = {};\n\n for (const [name, toolDef] of Object.entries(tools)) {\n const meta = metadata.get(name);\n\n // If no metadata, read-only, or auto-approved, pass through unchanged\n if (!meta || meta.mutability === 'read-only' || meta.autoApprove) {\n wrapped[name] = toolDef;\n continue;\n }\n\n // Clone the tool definition with a wrapped execute function\n wrapped[name] = {\n ...toolDef,\n execute: async (args: Record<string, unknown>, options: unknown) => {\n const message =\n meta.confirmationMessage?.(args) ??\n `Tool \"${name}\" wants to perform a ${meta.mutability} operation. Allow?`;\n\n const allowed = await confirmFn(message);\n if (!allowed) {\n return { success: false, error: 'User declined this action.' };\n }\n\n // Call the original execute\n return (toolDef as { execute: (args: Record<string, unknown>, options: unknown) => Promise<unknown> }).execute(args, options);\n },\n };\n }\n\n return wrapped;\n}\n","import type { ToolMetadata } from './types.js';\n\n// ── Filesystem tools ────────────────────────────────────────────────\nimport {\n listFiles,\n readFileContents,\n writeFileContents,\n editFile,\n createDirectory,\n deleteFile,\n searchFiles,\n globFiles,\n fileStats,\n viewImage,\n} from './filesystem.js';\n\n// ── Shell tools ─────────────────────────────────────────────────────\nimport { runCommand } from './shell.js';\n\n// ── Git tools ───────────────────────────────────────────────────────\nimport { gitStatus, gitDiff, gitLog, gitCommit, gitBranch } from './git.js';\n\n// ── Web tools ───────────────────────────────────────────────────────\nimport { fetchUrl } from './web.js';\n\n// ── Image tools ─────────────────────────────────────────────────────\nimport { generateImage } from './image.js';\n\n// ── Video tools ─────────────────────────────────────────────────────\nimport { generateVideo } from './video.js';\n\n// ── Canvas tools ────────────────────────────────────────────────────\nimport {\n createCanvas,\n drawText,\n drawImage,\n setCanvasStyle,\n clearCanvas,\n saveCanvas,\n getCanvasInfo,\n drawGradient,\n floodFill,\n setBrush,\n brushStroke,\n brushFill,\n brushSmudge,\n brushBlur,\n} from './canvas.js';\n\n// ── Desktop tools (Win32 only — requires native 'koffi' package) ──\n// Loaded dynamically to avoid crashing on non-Windows platforms.\nlet desktopTools: {\n takeScreenshot: typeof import('./desktop.js').takeScreenshot;\n getOpenWindows: typeof import('./desktop.js').getOpenWindows;\n moveWindow: typeof import('./desktop.js').moveWindow;\n mouseClick: typeof import('./desktop.js').mouseClick;\n pressKeys: typeof import('./desktop.js').pressKeys;\n launchApp: typeof import('./desktop.js').launchApp;\n focusWindow: typeof import('./desktop.js').focusWindow;\n} | null = null;\n\nif (process.platform === 'win32') {\n try {\n const mod = await import('./desktop.js');\n desktopTools = {\n takeScreenshot: mod.takeScreenshot,\n getOpenWindows: mod.getOpenWindows,\n moveWindow: mod.moveWindow,\n mouseClick: mod.mouseClick,\n pressKeys: mod.pressKeys,\n launchApp: mod.launchApp,\n focusWindow: mod.focusWindow,\n };\n } catch {\n // koffi not installed — desktop tools will be unavailable\n }\n}\n\n// ── System tools ────────────────────────────────────────────────────\nimport { systemInfo, getCwd, changeCwd } from './system.js';\n\n// ── Smart Home tools ────────────────────────────────────────────────\nimport {\n listSmartDevices,\n getDeviceStatus,\n controlDevice,\n playMedia,\n searchMusic,\n playMusic,\n sendNotification,\n askAssistant,\n} from '../smart-home/tools.js';\n\n// ── Re-exports ──────────────────────────────────────────────────────\nexport type { ToolMetadata, ToolCategory, ToolMutability } from './types.js';\nexport { wrapToolsWithConfirmation } from './middleware.js';\nexport { validatePath, isBlockedCommand, isPrivateIP } from './security.js';\n\n/**\n * All tools available to the AI, keyed by tool name.\n * Pass this object directly to the Vercel AI SDK `tools` parameter.\n */\nexport const allTools = {\n // Filesystem\n listFiles,\n readFile: readFileContents,\n viewImage,\n writeFile: writeFileContents,\n editFile,\n createDirectory,\n deleteFile,\n searchFiles,\n globFiles,\n fileStats,\n\n // Shell\n runCommand,\n\n // Git\n gitStatus,\n gitDiff,\n gitLog,\n gitCommit,\n gitBranch,\n\n // Web\n fetchUrl,\n\n // Image\n generateImage,\n\n // Video\n generateVideo,\n\n // Canvas\n createCanvas,\n drawText,\n drawImage,\n setCanvasStyle,\n clearCanvas,\n saveCanvas,\n getCanvasInfo,\n drawGradient,\n floodFill,\n\n // Canvas — Brush engine\n setBrush,\n brushStroke,\n brushFill,\n brushSmudge,\n brushBlur,\n\n // Desktop (Win32 only — conditionally included)\n ...(desktopTools ? {\n takeScreenshot: desktopTools.takeScreenshot,\n getOpenWindows: desktopTools.getOpenWindows,\n moveWindow: desktopTools.moveWindow,\n mouseClick: desktopTools.mouseClick,\n pressKeys: desktopTools.pressKeys,\n launchApp: desktopTools.launchApp,\n focusWindow: desktopTools.focusWindow,\n } : {}),\n\n // System\n systemInfo,\n getCwd,\n changeCwd,\n\n // Smart Home\n listSmartDevices,\n getDeviceStatus,\n controlDevice,\n playMedia,\n searchMusic,\n playMusic,\n sendNotification,\n askAssistant,\n} as const;\n\nexport type ToolName = keyof typeof allTools;\n\n/**\n * Metadata for each tool — category, mutability, description.\n * Used by the confirmation middleware and system prompt generator.\n */\nexport const toolMetadata = new Map<string, ToolMetadata>([\n // Filesystem — read-only\n ['listFiles', { name: 'listFiles', category: 'filesystem', mutability: 'read-only', description: 'List files and directories' }],\n ['readFile', { name: 'readFile', category: 'filesystem', mutability: 'read-only', description: 'Read file contents (text, images, and binary files)' }],\n ['viewImage', { name: 'viewImage', category: 'filesystem', mutability: 'read-only', description: 'View and analyze an image file (dimensions, colors, visual content)' }],\n ['searchFiles', { name: 'searchFiles', category: 'filesystem', mutability: 'read-only', description: 'Search for text in files (grep-like)' }],\n ['globFiles', { name: 'globFiles', category: 'filesystem', mutability: 'read-only', description: 'Find files matching a glob pattern' }],\n ['fileStats', { name: 'fileStats', category: 'filesystem', mutability: 'read-only', description: 'Get file metadata (size, dates, permissions)' }],\n\n // Filesystem — mutating\n ['writeFile', {\n name: 'writeFile',\n category: 'filesystem',\n mutability: 'mutating',\n description: 'Write content to a file',\n confirmationMessage: (args) => `Write to file: ${args.path as string}?`,\n }],\n ['editFile', {\n name: 'editFile',\n category: 'filesystem',\n mutability: 'mutating',\n description: 'Surgical string replacement in a file',\n confirmationMessage: (args) => `Edit file: ${args.path as string}?`,\n }],\n ['createDirectory', {\n name: 'createDirectory',\n category: 'filesystem',\n mutability: 'mutating',\n description: 'Create a directory',\n confirmationMessage: (args) => `Create directory: ${args.path as string}?`,\n }],\n\n // Filesystem — destructive\n ['deleteFile', {\n name: 'deleteFile',\n category: 'filesystem',\n mutability: 'destructive',\n description: 'Delete a file or directory',\n confirmationMessage: (args) => `DELETE ${args.recursive ? '(recursive) ' : ''}${args.path as string}? This cannot be undone.`,\n }],\n\n // Shell — mutating\n ['runCommand', {\n name: 'runCommand',\n category: 'shell',\n mutability: 'mutating',\n description: 'Execute a shell command',\n confirmationMessage: (args) => `Run command: ${args.command as string}`,\n }],\n\n // Git — read-only\n ['gitStatus', { name: 'gitStatus', category: 'git', mutability: 'read-only', description: 'Get git status (branch, changes)' }],\n ['gitDiff', { name: 'gitDiff', category: 'git', mutability: 'read-only', description: 'Show git diff' }],\n ['gitLog', { name: 'gitLog', category: 'git', mutability: 'read-only', description: 'Show git commit history' }],\n\n // Git — mutating\n ['gitCommit', {\n name: 'gitCommit',\n category: 'git',\n mutability: 'mutating',\n description: 'Stage files and create a git commit',\n confirmationMessage: (args) => `Git commit: \"${args.message as string}\"`,\n }],\n ['gitBranch', {\n name: 'gitBranch',\n category: 'git',\n mutability: 'mutating',\n description: 'List/create/switch/delete git branches',\n confirmationMessage: (args) => `Git branch ${args.action as string}${args.name ? `: ${args.name as string}` : ''}`,\n }],\n\n // Web — read-only\n ['fetchUrl', { name: 'fetchUrl', category: 'web', mutability: 'read-only', description: 'Fetch a URL (with SSRF protection)' }],\n\n // Image — mutating\n ['generateImage', {\n name: 'generateImage',\n category: 'image',\n mutability: 'mutating',\n description: 'Generate an image with DALL-E 3 and save to disk',\n confirmationMessage: (args) => `Generate image: \"${args.prompt as string}\"${args.savePath ? ` → ${args.savePath as string}` : ''}?`,\n }],\n\n // Video — mutating\n ['generateVideo', {\n name: 'generateVideo',\n category: 'video',\n mutability: 'mutating',\n description: 'Generate a video with OpenAI Sora (up to 5 minutes) and save to disk',\n confirmationMessage: (args) => `Generate video: \"${args.prompt as string}\"${args.savePath ? ` → ${args.savePath as string}` : ''}?`,\n }],\n\n // Canvas — read-only (in-memory drawing)\n ['createCanvas', { name: 'createCanvas', category: 'canvas', mutability: 'read-only', description: 'Create a new in-memory canvas for drawing' }],\n ['drawText', { name: 'drawText', category: 'canvas', mutability: 'read-only', description: 'Draw text on a canvas' }],\n ['drawImage', { name: 'drawImage', category: 'canvas', mutability: 'read-only', description: 'Composite an image file onto a canvas' }],\n ['setCanvasStyle', { name: 'setCanvasStyle', category: 'canvas', mutability: 'read-only', description: 'Set default drawing styles (colors, line width, shadow, opacity)' }],\n ['clearCanvas', { name: 'clearCanvas', category: 'canvas', mutability: 'read-only', description: 'Clear all or part of a canvas' }],\n ['getCanvasInfo', { name: 'getCanvasInfo', category: 'canvas', mutability: 'read-only', description: 'Get canvas dimensions or list active canvases' }],\n ['drawGradient', { name: 'drawGradient', category: 'canvas', mutability: 'read-only', description: 'Fill a region with a linear or radial gradient' }],\n ['floodFill', { name: 'floodFill', category: 'canvas', mutability: 'read-only', description: 'Paint bucket fill from a point' }],\n ['setBrush', { name: 'setBrush', category: 'canvas', mutability: 'read-only', description: 'Configure the active brush (type, size, opacity, hardness, texture, jitter, etc.)' }],\n ['brushStroke', { name: 'brushStroke', category: 'canvas', mutability: 'read-only', description: 'Paint a brush stroke along a path using current brush settings' }],\n ['brushFill', { name: 'brushFill', category: 'canvas', mutability: 'read-only', description: 'Fill an area with brush texture and color' }],\n ['brushSmudge', { name: 'brushSmudge', category: 'canvas', mutability: 'read-only', description: 'Smudge/blend colors along a path' }],\n ['brushBlur', { name: 'brushBlur', category: 'canvas', mutability: 'read-only', description: 'Apply blur to a rectangular region' }],\n\n // Canvas — mutating (writes to disk)\n ['saveCanvas', {\n name: 'saveCanvas',\n category: 'canvas',\n mutability: 'mutating',\n description: 'Save a canvas to a PNG file on disk',\n confirmationMessage: (args) => `Save canvas \"${args.canvasId as string}\" to ${(args.path as string) ?? 'auto-generated path'}?`,\n }],\n\n // Desktop — read-only\n ['takeScreenshot', { name: 'takeScreenshot', category: 'desktop', mutability: 'read-only', description: 'Capture the screen as a PNG screenshot' }],\n ['getOpenWindows', { name: 'getOpenWindows', category: 'desktop', mutability: 'read-only', description: 'List all open windows with positions and process info' }],\n\n // Desktop — mutating\n ['moveWindow', {\n name: 'moveWindow',\n category: 'desktop',\n mutability: 'mutating',\n description: 'Move, resize, or change the state of a window',\n confirmationMessage: (args) => `Move window ${(args.title ?? args.handle) as string}?`,\n }],\n ['mouseClick', {\n name: 'mouseClick',\n category: 'desktop',\n mutability: 'mutating',\n description: 'Click the mouse at screen coordinates',\n confirmationMessage: (args) => `Mouse ${(args.action ?? 'click') as string} at (${args.x as number}, ${args.y as number})?`,\n }],\n ['pressKeys', {\n name: 'pressKeys',\n category: 'desktop',\n mutability: 'mutating',\n description: 'Simulate keyboard input (type text, press a key, or send a key combo)',\n confirmationMessage: (args) => `Send keys: ${(args.text ?? args.key ?? (args.combo as string[] | undefined)?.join('+') ?? '') as string}?`,\n }],\n ['launchApp', {\n name: 'launchApp',\n category: 'desktop',\n mutability: 'mutating',\n description: 'Launch an application',\n confirmationMessage: (args) => `Launch: ${args.app as string}${args.args ? ` ${args.args as string}` : ''}?`,\n }],\n ['focusWindow', {\n name: 'focusWindow',\n category: 'desktop',\n mutability: 'mutating',\n description: 'Bring a window to the foreground',\n confirmationMessage: (args) => `Focus window: ${(args.title ?? args.handle) as string}?`,\n }],\n\n // System — read-only\n ['systemInfo', { name: 'systemInfo', category: 'system', mutability: 'read-only', description: 'Get system information' }],\n ['getCwd', { name: 'getCwd', category: 'system', mutability: 'read-only', description: 'Get current working directory' }],\n\n // System — mutating\n ['changeCwd', {\n name: 'changeCwd',\n category: 'system',\n mutability: 'mutating',\n description: 'Change the current working directory',\n confirmationMessage: (args) => `Change working directory to: ${args.path as string}?`,\n }],\n\n // Smart Home — read-only\n ['listSmartDevices', { name: 'listSmartDevices', category: 'smart-home', mutability: 'read-only', description: 'List all configured smart home devices' }],\n ['getDeviceStatus', { name: 'getDeviceStatus', category: 'smart-home', mutability: 'read-only', description: 'Get current status of a smart home device' }],\n\n // Smart Home — auto-approved mutating tools.\n // These are always triggered by explicit user intent (\"play some jazz\",\n // \"set volume to 50\", etc.) so a second [y/N] confirmation is redundant.\n // Additionally, readline prompts deadlock during AI SDK stream processing.\n ['controlDevice', {\n name: 'controlDevice',\n category: 'smart-home',\n mutability: 'mutating',\n autoApprove: true,\n description: 'Control playback, volume, mute on a smart home device',\n }],\n ['playMedia', {\n name: 'playMedia',\n category: 'smart-home',\n mutability: 'mutating',\n autoApprove: true,\n description: 'Play audio/video URL or search query on a smart home device',\n }],\n ['searchMusic', {\n name: 'searchMusic',\n category: 'smart-home',\n mutability: 'read-only',\n description: 'Search YouTube for music/audio — returns candidates without playing',\n }],\n ['playMusic', {\n name: 'playMusic',\n category: 'smart-home',\n mutability: 'mutating',\n autoApprove: true,\n description: 'Play a specific YouTube video (by videoId) on a smart home speaker',\n }],\n ['sendNotification', {\n name: 'sendNotification',\n category: 'smart-home',\n mutability: 'mutating',\n autoApprove: true,\n description: 'Send TTS notification to a smart home speaker',\n }],\n ['askAssistant', {\n name: 'askAssistant',\n category: 'smart-home',\n mutability: 'mutating',\n autoApprove: true,\n description: 'Send a Google Assistant command to a Google Home device',\n }],\n]);\n\n/** Read-only tools that need no user confirmation. */\nexport const readOnlyToolNames = new Set(\n Array.from(toolMetadata.entries())\n .filter(([, meta]) => meta.mutability === 'read-only')\n .map(([name]) => name),\n);\n\n/** Tools that mutate the filesystem or run arbitrary commands. */\nexport const mutatingToolNames = new Set(\n Array.from(toolMetadata.entries())\n .filter(([, meta]) => meta.mutability === 'mutating' || meta.mutability === 'destructive')\n .map(([name]) => name),\n);\n\n/**\n * Generate a system prompt section describing all available tools, grouped by category.\n */\nexport function generateToolSystemPrompt(): string {\n const categories = new Map<string, ToolMetadata[]>();\n\n for (const meta of toolMetadata.values()) {\n const existing = categories.get(meta.category) ?? [];\n existing.push(meta);\n categories.set(meta.category, existing);\n }\n\n const lines: string[] = ['Available tools:'];\n\n const categoryOrder = ['filesystem', 'shell', 'git', 'web', 'image', 'video', 'canvas', 'desktop', 'system', 'smart-home'];\n for (const category of categoryOrder) {\n const tools = categories.get(category);\n if (!tools) continue;\n\n lines.push('');\n lines.push(`## ${category.charAt(0).toUpperCase() + category.slice(1)} Tools`);\n for (const t of tools) {\n const mutLabel = t.mutability !== 'read-only' ? ` [${t.mutability}]` : '';\n lines.push(`- **${t.name}**: ${t.description}${mutLabel}`);\n }\n }\n\n lines.push('');\n lines.push(\n 'Use these tools proactively when the user asks about files, code, projects, or needs you to perform actions. ' +\n 'You can chain multiple tool calls in sequence to accomplish complex tasks. Always report what you did and the results clearly.',\n );\n\n // Canvas-specific guidance\n if (categories.has('canvas')) {\n lines.push('');\n lines.push('## Canvas Painting Guide');\n lines.push('You have a painting canvas with Photoshop-like brushes. Workflow:');\n lines.push('1. **createCanvas** — create a canvas with desired dimensions and background color.');\n lines.push('2. **setBrush** — configure brush type, size, opacity, hardness, color, and other properties.');\n lines.push('3. **brushStroke** — paint strokes along paths. More points = smoother strokes.');\n lines.push('4. Use **drawText**, **drawImage**, **drawGradient**, **floodFill** as needed.');\n lines.push('5. **saveCanvas** — **ALWAYS call this** to save the finished image to a PNG file on disk. The image is NOT saved until you call saveCanvas.');\n lines.push('');\n lines.push('Coordinate system: origin at top-left, x increases right, y increases down.');\n lines.push('Colors: any CSS format — named (\"red\"), hex (\"#ff0000\"), rgb(\"rgb(255,0,0)\"), rgba(\"rgba(255,0,0,0.5)\").');\n lines.push('Use `setCanvasStyle` to set persistent defaults (shadow, dash patterns, opacity) that apply to subsequent draw calls.');\n lines.push('');\n lines.push('### Brush System');\n lines.push('Available brush types: round, flat, fan, filbert, palette-knife, airbrush, splatter, chalk, watercolor, ink, pencil, marker, eraser.');\n lines.push('Layer multiple semi-transparent strokes for depth and richness.');\n lines.push('Use scatter and jitter settings for natural, organic effects.');\n lines.push('Use `brushSmudge` to blend/smear colors. Use `brushBlur` to soften regions. Use `brushFill` for textured flood fills.');\n lines.push('');\n lines.push('**Important**: Always call `saveCanvas` when you are done drawing. The user expects a saved PNG file.');\n }\n\n // Desktop automation guidance\n if (categories.has('desktop')) {\n lines.push('');\n lines.push('## Desktop Automation Guide');\n lines.push('You can see and control the Windows desktop. Workflow:');\n lines.push('1. **takeScreenshot** — capture the screen to see what is currently displayed.');\n lines.push('2. Analyze the screenshot to understand the UI layout and determine coordinates.');\n lines.push('3. Act — use **mouseClick**, **pressKeys**, **launchApp**, **moveWindow**, or **focusWindow**.');\n lines.push('4. **takeScreenshot** again to verify the result.');\n lines.push('');\n lines.push('Tips:');\n lines.push('- For window management, prefer **getOpenWindows** + **moveWindow** over mouse clicking — it is more reliable.');\n lines.push('- Use **focusWindow** to bring a window to the front before sending keystrokes with **pressKeys**.');\n lines.push('- Always screenshot after actions to verify they worked.');\n lines.push('- Use the `region` parameter on takeScreenshot to capture just the area of interest for faster results.');\n }\n\n return lines.join('\\n');\n}\n"],"mappings":"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","names":["providers","config","resolve","randomUUID","os","fs","path","client","level","koffi","koffi","createCanvas","launchApp","mouseClick","moveWindow","tool","z","fsWriteFile","unlink","mkdir","resolve","dirname","join","tmpdir","createRequire","MODELS","MODELS","chalk","chalk","path","prompt","sizeStr","chalk","chalk","prompt","resolve","chalk","config","chalk","chalk","providers","prompt","chalk","providers","prompt","chalk","handleList","wizardMenu","providers","config","config","resolve","chalk","fs","path","platform","wizardMenu","device","config","getAuthenticatedOAuthClient","register","chalk","prompt","chalk","resolve","resolve","join","resolve","homedir","hostname","path","resolve","items","join","buffer","newContent","tool","z","resolve","tool","z","resolve","tool","z","path","args","stdout","sep","tool","z","tool","z","tool","z","resolve","fsWriteFile","mkdir","prompt","tool","z","resolve","dirname","join","fsWriteFile","mkdir","readdir","execFile","promisify","OpenAI","execFileAsync","execFileAsync","prompt","dirname","join","readdir","tool","z","OpenAI","resolve","mkdir","fsWriteFile","stat","tool","z","resolve","dirname","writeFile","mkdir","canvasModule","getCanvasModule","tool","z","getCanvasModule","resolve","path","mkdir","dirname","writeFile","r","g","b","idx","tool","z","homedir","resolve","execFile","promisify","existsSync","execFileAsync","path","tool","z","appendFileSync","DIAG_LOG","config","tool","z","result","chalk","require","fs","chalk","require","createRequire","version","prompt"]}
|