@openacp/cli 2026.330.3 → 2026.331.2

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.
Files changed (173) hide show
  1. package/README.md +19 -1
  2. package/dist/cli.d.ts +11 -0
  3. package/dist/cli.js +25134 -278
  4. package/dist/cli.js.map +1 -1
  5. package/dist/data/registry-snapshot.json +1 -1
  6. package/dist/index.d.ts +259 -30
  7. package/dist/index.js +17632 -404
  8. package/dist/index.js.map +1 -1
  9. package/package.json +2 -2
  10. package/dist/adapter-AWSI4GML.js +0 -13
  11. package/dist/adapter-AWSI4GML.js.map +0 -1
  12. package/dist/agent-catalog-SZQQERV7.js +0 -10
  13. package/dist/agent-catalog-SZQQERV7.js.map +0 -1
  14. package/dist/agent-dependencies-ED2ZTUHG.js +0 -23
  15. package/dist/agent-dependencies-ED2ZTUHG.js.map +0 -1
  16. package/dist/agent-registry-YOGP656W.js +0 -8
  17. package/dist/agent-registry-YOGP656W.js.map +0 -1
  18. package/dist/agent-store-5UHZH2XI.js +0 -8
  19. package/dist/agent-store-5UHZH2XI.js.map +0 -1
  20. package/dist/api-client-XTLRRFPX.js +0 -13
  21. package/dist/api-client-XTLRRFPX.js.map +0 -1
  22. package/dist/api-server-5VNYFWJE.js +0 -7
  23. package/dist/api-server-5VNYFWJE.js.map +0 -1
  24. package/dist/api-server-JLBDKCU4.js +0 -10
  25. package/dist/api-server-JLBDKCU4.js.map +0 -1
  26. package/dist/autostart-CUPZMKKC.js +0 -22
  27. package/dist/autostart-CUPZMKKC.js.map +0 -1
  28. package/dist/chunk-237WYH6H.js +0 -235
  29. package/dist/chunk-237WYH6H.js.map +0 -1
  30. package/dist/chunk-2HEFALTZ.js +0 -44
  31. package/dist/chunk-2HEFALTZ.js.map +0 -1
  32. package/dist/chunk-2KT6TROD.js +0 -129
  33. package/dist/chunk-2KT6TROD.js.map +0 -1
  34. package/dist/chunk-2R5XM3ES.js +0 -154
  35. package/dist/chunk-2R5XM3ES.js.map +0 -1
  36. package/dist/chunk-3EWTPOF7.js +0 -51
  37. package/dist/chunk-3EWTPOF7.js.map +0 -1
  38. package/dist/chunk-3NAFXVQM.js +0 -67
  39. package/dist/chunk-3NAFXVQM.js.map +0 -1
  40. package/dist/chunk-4WXALZA3.js +0 -45
  41. package/dist/chunk-4WXALZA3.js.map +0 -1
  42. package/dist/chunk-566W6INH.js +0 -83
  43. package/dist/chunk-566W6INH.js.map +0 -1
  44. package/dist/chunk-5HKQCYOI.js +0 -145
  45. package/dist/chunk-5HKQCYOI.js.map +0 -1
  46. package/dist/chunk-5OCGO27U.js +0 -125
  47. package/dist/chunk-5OCGO27U.js.map +0 -1
  48. package/dist/chunk-5WGVYX3C.js +0 -55
  49. package/dist/chunk-5WGVYX3C.js.map +0 -1
  50. package/dist/chunk-7ZCQF6QM.js +0 -27
  51. package/dist/chunk-7ZCQF6QM.js.map +0 -1
  52. package/dist/chunk-AFKX424Q.js +0 -92
  53. package/dist/chunk-AFKX424Q.js.map +0 -1
  54. package/dist/chunk-APS6UEFU.js +0 -259
  55. package/dist/chunk-APS6UEFU.js.map +0 -1
  56. package/dist/chunk-BTJHGSLM.js +0 -1116
  57. package/dist/chunk-BTJHGSLM.js.map +0 -1
  58. package/dist/chunk-CDAUYTVP.js +0 -41
  59. package/dist/chunk-CDAUYTVP.js.map +0 -1
  60. package/dist/chunk-FCTC7KDT.js +0 -101
  61. package/dist/chunk-FCTC7KDT.js.map +0 -1
  62. package/dist/chunk-FNRSWA2K.js +0 -1
  63. package/dist/chunk-FNRSWA2K.js.map +0 -1
  64. package/dist/chunk-GEOXPGCO.js +0 -650
  65. package/dist/chunk-GEOXPGCO.js.map +0 -1
  66. package/dist/chunk-IZ5UEZF7.js +0 -138
  67. package/dist/chunk-IZ5UEZF7.js.map +0 -1
  68. package/dist/chunk-KDU3ZEWT.js +0 -97
  69. package/dist/chunk-KDU3ZEWT.js.map +0 -1
  70. package/dist/chunk-LGFWH3AE.js +0 -26
  71. package/dist/chunk-LGFWH3AE.js.map +0 -1
  72. package/dist/chunk-MITTQMGZ.js +0 -543
  73. package/dist/chunk-MITTQMGZ.js.map +0 -1
  74. package/dist/chunk-MLF4W5R6.js +0 -101
  75. package/dist/chunk-MLF4W5R6.js.map +0 -1
  76. package/dist/chunk-MPGEHTGE.js +0 -679
  77. package/dist/chunk-MPGEHTGE.js.map +0 -1
  78. package/dist/chunk-OYSAN7UX.js +0 -15
  79. package/dist/chunk-OYSAN7UX.js.map +0 -1
  80. package/dist/chunk-PA6MNBG4.js +0 -190
  81. package/dist/chunk-PA6MNBG4.js.map +0 -1
  82. package/dist/chunk-QWVHCTCA.js +0 -172
  83. package/dist/chunk-QWVHCTCA.js.map +0 -1
  84. package/dist/chunk-R6KZYF7D.js +0 -231
  85. package/dist/chunk-R6KZYF7D.js.map +0 -1
  86. package/dist/chunk-S64CB6J3.js +0 -98
  87. package/dist/chunk-S64CB6J3.js.map +0 -1
  88. package/dist/chunk-TMVTSWVH.js +0 -228
  89. package/dist/chunk-TMVTSWVH.js.map +0 -1
  90. package/dist/chunk-UCIZM5SW.js +0 -3917
  91. package/dist/chunk-UCIZM5SW.js.map +0 -1
  92. package/dist/chunk-UWH7KIAA.js +0 -701
  93. package/dist/chunk-UWH7KIAA.js.map +0 -1
  94. package/dist/chunk-V2YZWYXT.js +0 -484
  95. package/dist/chunk-V2YZWYXT.js.map +0 -1
  96. package/dist/chunk-W26AUH5B.js +0 -61
  97. package/dist/chunk-W26AUH5B.js.map +0 -1
  98. package/dist/chunk-W4LK6WJP.js +0 -446
  99. package/dist/chunk-W4LK6WJP.js.map +0 -1
  100. package/dist/chunk-WQCJTU2C.js +0 -84
  101. package/dist/chunk-WQCJTU2C.js.map +0 -1
  102. package/dist/chunk-XBZIHNKV.js +0 -6410
  103. package/dist/chunk-XBZIHNKV.js.map +0 -1
  104. package/dist/chunk-ZSLHHQPQ.js +0 -282
  105. package/dist/chunk-ZSLHHQPQ.js.map +0 -1
  106. package/dist/config-KN6NKKPF.js +0 -20
  107. package/dist/config-KN6NKKPF.js.map +0 -1
  108. package/dist/config-editor-76RVZS4B.js +0 -10
  109. package/dist/config-editor-76RVZS4B.js.map +0 -1
  110. package/dist/config-registry-ZXAIJNYB.js +0 -17
  111. package/dist/config-registry-ZXAIJNYB.js.map +0 -1
  112. package/dist/context-NXXW62NJ.js +0 -9
  113. package/dist/context-NXXW62NJ.js.map +0 -1
  114. package/dist/core-plugins-BPZY7SEB.js +0 -22
  115. package/dist/core-plugins-BPZY7SEB.js.map +0 -1
  116. package/dist/daemon-XFEMMJSZ.js +0 -29
  117. package/dist/daemon-XFEMMJSZ.js.map +0 -1
  118. package/dist/dev-loader-7P3HZCIA.js +0 -37
  119. package/dist/dev-loader-7P3HZCIA.js.map +0 -1
  120. package/dist/doctor-AV6AUO22.js +0 -9
  121. package/dist/doctor-AV6AUO22.js.map +0 -1
  122. package/dist/file-service-HHB3JQIO.js +0 -8
  123. package/dist/file-service-HHB3JQIO.js.map +0 -1
  124. package/dist/install-cloudflared-JRJ4BSOM.js +0 -32
  125. package/dist/install-cloudflared-JRJ4BSOM.js.map +0 -1
  126. package/dist/install-context-EHYV5WRY.js +0 -77
  127. package/dist/install-context-EHYV5WRY.js.map +0 -1
  128. package/dist/install-jq-ISTGT263.js +0 -31
  129. package/dist/install-jq-ISTGT263.js.map +0 -1
  130. package/dist/integrate-JIEZYDOR.js +0 -371
  131. package/dist/integrate-JIEZYDOR.js.map +0 -1
  132. package/dist/log-YZ243M5G.js +0 -25
  133. package/dist/log-YZ243M5G.js.map +0 -1
  134. package/dist/main-VEJCG5PY.js +0 -654
  135. package/dist/main-VEJCG5PY.js.map +0 -1
  136. package/dist/menu-ALFN37IR.js +0 -15
  137. package/dist/menu-ALFN37IR.js.map +0 -1
  138. package/dist/notifications-MO23S7S3.js +0 -8
  139. package/dist/notifications-MO23S7S3.js.map +0 -1
  140. package/dist/plugin-create-EHL76ZZG.js +0 -966
  141. package/dist/plugin-create-EHL76ZZG.js.map +0 -1
  142. package/dist/plugin-installer-VSTYZSXC.js +0 -9
  143. package/dist/plugin-installer-VSTYZSXC.js.map +0 -1
  144. package/dist/plugin-registry-6J3YSFHF.js +0 -7
  145. package/dist/plugin-registry-6J3YSFHF.js.map +0 -1
  146. package/dist/plugin-search-MGKAL5JM.js +0 -39
  147. package/dist/plugin-search-MGKAL5JM.js.map +0 -1
  148. package/dist/post-upgrade-Y26S2ZQ7.js +0 -79
  149. package/dist/post-upgrade-Y26S2ZQ7.js.map +0 -1
  150. package/dist/read-text-file-DJBTITIB.js +0 -7
  151. package/dist/read-text-file-DJBTITIB.js.map +0 -1
  152. package/dist/registry-client-GTBWLXYU.js +0 -7
  153. package/dist/registry-client-GTBWLXYU.js.map +0 -1
  154. package/dist/security-2BA265LN.js +0 -8
  155. package/dist/security-2BA265LN.js.map +0 -1
  156. package/dist/settings-manager-B4UN2LAC.js +0 -7
  157. package/dist/settings-manager-B4UN2LAC.js.map +0 -1
  158. package/dist/setup-DISPNDEK.js +0 -802
  159. package/dist/setup-DISPNDEK.js.map +0 -1
  160. package/dist/speech-SG62JYIF.js +0 -9
  161. package/dist/speech-SG62JYIF.js.map +0 -1
  162. package/dist/suggest-RST5VOHB.js +0 -36
  163. package/dist/suggest-RST5VOHB.js.map +0 -1
  164. package/dist/telegram-L3YM6SQJ.js +0 -7
  165. package/dist/telegram-L3YM6SQJ.js.map +0 -1
  166. package/dist/tunnel-HWJ27WDH.js +0 -7
  167. package/dist/tunnel-HWJ27WDH.js.map +0 -1
  168. package/dist/tunnel-service-ZMO4THKE.js +0 -1261
  169. package/dist/tunnel-service-ZMO4THKE.js.map +0 -1
  170. package/dist/validators-GITLOFXC.js +0 -11
  171. package/dist/validators-GITLOFXC.js.map +0 -1
  172. package/dist/version-AXXV6IV2.js +0 -15
  173. package/dist/version-AXXV6IV2.js.map +0 -1
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli.ts","../../src/cli/commands/help.ts","../../src/cli/commands/version.ts","../../src/cli/commands/install.ts","../../src/cli/commands/helpers.ts","../../src/cli/commands/uninstall.ts","../../src/cli/commands/plugins.ts","../../src/cli/commands/api.ts","../../src/cli/commands/start.ts","../../src/cli/commands/stop.ts","../../src/cli/commands/status.ts","../../src/cli/commands/logs.ts","../../src/cli/commands/config.ts","../../src/cli/commands/reset.ts","../../src/cli/commands/update.ts","../../src/cli/commands/adopt.ts","../../src/cli/commands/integrate.ts","../../src/cli/commands/doctor.ts","../../src/cli/commands/agents.ts","../../src/cli/commands/tunnel.ts","../../src/cli/commands/onboard.ts","../../src/cli/commands/default.ts","../../src/cli/commands/dev.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { setDefaultAutoSelectFamily } from \"node:net\";\nsetDefaultAutoSelectFamily(false);\n\nimport {\n printHelp,\n cmdVersion,\n cmdInstall,\n cmdUninstall,\n cmdPlugins,\n cmdPlugin,\n cmdApi,\n cmdStart,\n cmdStop,\n cmdStatus,\n cmdLogs,\n cmdConfig,\n cmdReset,\n cmdUpdate,\n cmdDefault,\n cmdAdopt,\n cmdIntegrate,\n cmdDoctor,\n cmdAgents,\n cmdTunnel,\n cmdOnboard,\n cmdDev,\n} from './cli/commands/index.js'\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\nconst commands: Record<string, () => Promise<void>> = {\n '--help': async () => printHelp(),\n '-h': async () => printHelp(),\n '--version': () => cmdVersion(),\n '-v': () => cmdVersion(),\n 'install': () => cmdInstall(args),\n 'uninstall': () => cmdUninstall(args),\n 'plugins': () => cmdPlugins(args),\n 'plugin': () => cmdPlugin(args),\n 'api': () => cmdApi(args),\n 'start': () => cmdStart(args),\n 'stop': () => cmdStop(args),\n 'status': () => cmdStatus(args),\n 'logs': () => cmdLogs(args),\n 'config': () => cmdConfig(args),\n 'reset': () => cmdReset(args),\n 'update': () => cmdUpdate(args),\n 'adopt': () => cmdAdopt(args),\n 'integrate': () => cmdIntegrate(args),\n 'doctor': () => cmdDoctor(args),\n 'agents': () => cmdAgents(args),\n 'tunnel': () => cmdTunnel(args),\n 'onboard': () => cmdOnboard(),\n 'dev': () => cmdDev(args),\n '--daemon-child': async () => {\n const { startServer } = await import('./main.js')\n await startServer()\n },\n}\n\nasync function main() {\n const handler = command ? commands[command] : undefined\n if (handler) {\n await handler()\n } else {\n await cmdDefault(command)\n }\n}\n\nmain().catch((err) => {\n console.error(\"Fatal:\", err);\n process.exit(1);\n});\n","export function printHelp(): void {\n console.log(`\n\\x1b[1mOpenACP\\x1b[0m — Self-hosted bridge for AI coding agents\nConnect messaging platforms (Telegram, Discord) to 28+ AI coding agents via ACP protocol.\n\n\\x1b[1mGetting Started:\\x1b[0m\n openacp First run launches setup wizard\n openacp After setup, starts the server\n\n\\x1b[1mServer:\\x1b[0m\n openacp Start (mode from config)\n openacp start Start as background daemon\n openacp stop Stop background daemon\n openacp status Show daemon status\n openacp logs Tail daemon log file\n openacp --foreground Force foreground mode\n\n\\x1b[1mAgent Management:\\x1b[0m\n openacp agents Browse all agents (installed + available)\n openacp agents install <name> Install an agent from the ACP Registry\n openacp agents uninstall <name> Remove an installed agent\n openacp agents info <name> Show details, dependencies & setup guide\n openacp agents run <name> [-- args] Run agent CLI directly (login, config...)\n openacp agents refresh Force-refresh agent list from registry\n\n \\x1b[2mExamples:\\x1b[0m\n openacp agents install gemini Install Gemini CLI\n openacp agents run gemini Login to Google (first run)\n openacp agents info cursor See setup instructions\n\n\\x1b[1mConfiguration:\\x1b[0m\n openacp config Interactive config editor\n openacp config set <key> <value> Set a config value\n openacp onboard Re-run onboarding setup wizard\n openacp reset Re-run setup wizard\n openacp update Update to latest version\n openacp doctor Run system diagnostics\n openacp doctor --dry-run Check only, don't fix\n\n\\x1b[1mPlugins:\\x1b[0m\n openacp install <package> Install adapter plugin\n openacp uninstall <package> Remove adapter\n openacp plugins List installed plugins\n openacp plugin create Scaffold a new plugin project\n\n\\x1b[1mDevelopment:\\x1b[0m\n openacp dev <plugin-path> Run with local plugin (hot-reload)\n openacp dev <path> --no-watch Run without file watching\n openacp dev <path> --verbose Run with verbose logging\n\n\\x1b[1mSession Transfer:\\x1b[0m\n openacp integrate <agent> Install handoff integration\n openacp integrate <agent> --uninstall\n openacp adopt <agent> <id> Adopt an external session\n\n\\x1b[1mTunnels:\\x1b[0m\n openacp tunnel add <port> [--label name] Create tunnel to local port\n openacp tunnel list List active tunnels\n openacp tunnel stop <port> Stop a tunnel\n openacp tunnel stop-all Stop all user tunnels\n\n\\x1b[1mDaemon API:\\x1b[0m \\x1b[2m(requires running daemon)\\x1b[0m\n openacp api status Active sessions\n openacp api session <id> Session details\n openacp api new [agent] [workspace] Create session\n openacp api send <id> <prompt> Send prompt\n openacp api cancel <id> Cancel session\n openacp api dangerous <id> on|off Toggle dangerous mode\n openacp api topics [--status ...] List topics\n openacp api cleanup [--status ...] Cleanup old topics\n openacp api health System health check\n openacp api restart Restart daemon\n\n\\x1b[2mMore info: https://github.com/Open-ACP/OpenACP\\x1b[0m\n`)\n}\n","export async function cmdVersion(): Promise<void> {\n const { getCurrentVersion } = await import(\"../version.js\")\n console.log(`openacp v${getCurrentVersion()}`)\n}\n","import { execSync } from 'node:child_process'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { PLUGINS_DIR } from '../../core/config/config.js'\nimport { wantsHelp } from './helpers.js'\n\nexport async function cmdInstall(args: string[]): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp install\\x1b[0m — Install a plugin adapter\n\n\\x1b[1mUsage:\\x1b[0m\n openacp install <package>\n\n\\x1b[1mArguments:\\x1b[0m\n <package> npm package name (e.g. @openacp/adapter-discord)\n\nInstalls the plugin to ~/.openacp/plugins/.\n\n\\x1b[1mExamples:\\x1b[0m\n openacp install @openacp/adapter-discord\n`)\n return\n }\n const pkg = args[1]\n if (!pkg) {\n console.error(\"Usage: openacp install <package>\")\n process.exit(1)\n }\n fs.mkdirSync(PLUGINS_DIR, { recursive: true })\n const pkgPath = path.join(PLUGINS_DIR, 'package.json')\n if (!fs.existsSync(pkgPath)) {\n fs.writeFileSync(pkgPath, JSON.stringify({ name: 'openacp-plugins', private: true, dependencies: {} }, null, 2))\n }\n console.log(`Installing ${pkg}...`)\n execSync(`npm install ${pkg} --prefix \"${PLUGINS_DIR}\"`, { stdio: 'inherit' })\n console.log(`Plugin ${pkg} installed successfully.`)\n}\n","export function wantsHelp(args: string[]): boolean {\n return args.includes('--help') || args.includes('-h')\n}\n\nexport function buildNestedUpdateFromPath(dotPath: string, value: unknown): Record<string, unknown> {\n const parts = dotPath.split('.')\n const result: Record<string, unknown> = {}\n let target = result\n for (let i = 0; i < parts.length - 1; i++) {\n target[parts[i]] = {}\n target = target[parts[i]] as Record<string, unknown>\n }\n target[parts[parts.length - 1]] = value\n return result\n}\n","import { execSync } from 'node:child_process'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { PLUGINS_DIR } from '../../core/config/config.js'\nimport { wantsHelp } from './helpers.js'\n\nexport async function cmdUninstall(args: string[]): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp uninstall\\x1b[0m — Remove a plugin adapter\n\n\\x1b[1mUsage:\\x1b[0m\n openacp uninstall <package>\n\n\\x1b[1mArguments:\\x1b[0m\n <package> npm package name to remove\n\n\\x1b[1mExamples:\\x1b[0m\n openacp uninstall @openacp/adapter-discord\n`)\n return\n }\n const pkg = args[1]\n if (!pkg) {\n console.error(\"Usage: openacp uninstall <package>\")\n process.exit(1)\n }\n fs.mkdirSync(PLUGINS_DIR, { recursive: true })\n const pkgPath = path.join(PLUGINS_DIR, 'package.json')\n if (!fs.existsSync(pkgPath)) {\n fs.writeFileSync(pkgPath, JSON.stringify({ name: 'openacp-plugins', private: true, dependencies: {} }, null, 2))\n }\n console.log(`Uninstalling ${pkg}...`)\n execSync(`npm uninstall ${pkg} --prefix \"${PLUGINS_DIR}\"`, { stdio: 'inherit' })\n console.log(`Plugin ${pkg} uninstalled.`)\n}\n","import { wantsHelp } from './helpers.js'\n\nexport async function cmdPlugins(args: string[] = []): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp plugins\\x1b[0m — List installed plugins\n\n\\x1b[1mUsage:\\x1b[0m\n openacp plugins\n\nShows all plugins registered in the plugin registry.\n`)\n return\n }\n\n const os = await import('node:os')\n const path = await import('node:path')\n const { PluginRegistry } = await import('../../core/plugin/plugin-registry.js')\n\n const registryPath = path.join(os.homedir(), '.openacp', 'plugins.json')\n const registry = new PluginRegistry(registryPath)\n await registry.load()\n\n const plugins = registry.list()\n if (plugins.size === 0) {\n console.log(\"No plugins installed.\")\n } else {\n console.log(\"Installed plugins:\")\n for (const [name, entry] of plugins) {\n const status = entry.enabled ? '' : ' (disabled)'\n console.log(` ${name}@${entry.version}${status}`)\n }\n }\n}\n\n/**\n * `openacp plugin <subcommand>` — Extended plugin management.\n *\n * Subcommands:\n * list — List all plugins with status (same as `openacp plugins`)\n * add|install <pkg> — Install a plugin package\n * remove|uninstall — Remove a plugin package (--purge to delete data)\n * enable <name> — Enable a plugin\n * disable <name> — Disable a plugin\n * configure <name> — Run interactive configuration for a plugin\n */\nexport async function cmdPlugin(args: string[] = []): Promise<void> {\n const subcommand = args[1] // args[0] is 'plugin'\n\n if (wantsHelp(args) || !subcommand) {\n console.log(`\n\\x1b[1mopenacp plugin\\x1b[0m — Plugin management\n\n\\x1b[1mUsage:\\x1b[0m\n openacp plugin list List all plugins with status\n openacp plugin search <query> Search the plugin registry\n openacp plugin add <package>[@version] Install a plugin package\n openacp plugin install <package> Alias for add\n openacp plugin remove <package> Remove a plugin package\n openacp plugin uninstall <package> Alias for remove (--purge to delete data)\n openacp plugin enable <name> Enable a plugin\n openacp plugin disable <name> Disable a plugin\n openacp plugin configure <name> Run interactive configuration\n openacp plugin create Scaffold a new plugin project\n\n\\x1b[1mExamples:\\x1b[0m\n openacp plugin list\n openacp plugin search telegram\n openacp plugin add @openacp/adapter-discord\n openacp plugin add translator@1.2.0\n openacp plugin enable @openacp/adapter-discord\n openacp plugin configure @openacp/adapter-discord\n openacp plugin remove @openacp/adapter-discord --purge\n`)\n return\n }\n\n switch (subcommand) {\n case 'list':\n return cmdPlugins(args.slice(1))\n\n case 'search': {\n const { cmdPluginSearch } = await import('./plugin-search.js')\n await cmdPluginSearch(args.slice(2))\n return\n }\n\n case 'add':\n case 'install': {\n const pkg = args[2]\n if (!pkg) {\n console.error('Error: missing package name. Usage: openacp plugin add <package>')\n process.exit(1)\n }\n await installPlugin(pkg)\n return\n }\n\n case 'remove':\n case 'uninstall': {\n const pkg = args[2]\n if (!pkg) {\n console.error('Error: missing package name. Usage: openacp plugin remove <package> [--purge]')\n process.exit(1)\n }\n const purge = args.includes('--purge')\n await uninstallPlugin(pkg, purge)\n return\n }\n\n case 'enable': {\n const name = args[2]\n if (!name) {\n console.error('Error: missing plugin name. Usage: openacp plugin enable <name>')\n process.exit(1)\n }\n await setPluginEnabled(name, true)\n return\n }\n\n case 'disable': {\n const name = args[2]\n if (!name) {\n console.error('Error: missing plugin name. Usage: openacp plugin disable <name>')\n process.exit(1)\n }\n await setPluginEnabled(name, false)\n return\n }\n\n case 'configure': {\n const name = args[2]\n if (!name) {\n console.error('Error: missing plugin name. Usage: openacp plugin configure <name>')\n process.exit(1)\n }\n await configurePlugin(name)\n return\n }\n\n case 'create': {\n const { cmdPluginCreate } = await import('./plugin-create.js')\n await cmdPluginCreate()\n return\n }\n\n default:\n console.error(`Unknown subcommand: ${subcommand}`)\n console.error('Run \"openacp plugin --help\" for usage.')\n process.exit(1)\n }\n}\n\nasync function setPluginEnabled(name: string, enabled: boolean): Promise<void> {\n const os = await import('node:os')\n const path = await import('node:path')\n const { PluginRegistry } = await import('../../core/plugin/plugin-registry.js')\n\n const registryPath = path.join(os.homedir(), '.openacp', 'plugins.json')\n const registry = new PluginRegistry(registryPath)\n await registry.load()\n\n const entry = registry.get(name)\n if (!entry) {\n console.error(`Plugin \"${name}\" not found. Run \"openacp plugin list\" to see installed plugins.`)\n process.exit(1)\n }\n\n registry.setEnabled(name, enabled)\n await registry.save()\n console.log(`Plugin ${name} ${enabled ? 'enabled' : 'disabled'}. Restart to apply.`)\n}\n\nasync function configurePlugin(name: string): Promise<void> {\n const os = await import('node:os')\n const path = await import('node:path')\n const { corePlugins } = await import('../../plugins/core-plugins.js')\n const { SettingsManager } = await import('../../core/plugin/settings-manager.js')\n const { createInstallContext } = await import('../../core/plugin/install-context.js')\n\n const plugin = corePlugins.find(p => p.name === name)\n if (!plugin) {\n console.error(`Plugin \"${name}\" not found.`)\n process.exit(1)\n }\n\n const basePath = path.join(os.homedir(), '.openacp', 'plugins', 'data')\n const settingsManager = new SettingsManager(basePath)\n const ctx = createInstallContext({ pluginName: name, settingsManager, basePath })\n\n if (plugin.configure) {\n await plugin.configure(ctx)\n } else if (plugin.install) {\n await plugin.install(ctx)\n } else {\n console.log(`Plugin ${name} has no configure or install hook.`)\n }\n}\n\nasync function installPlugin(input: string): Promise<void> {\n const os = await import('node:os')\n const path = await import('node:path')\n const { execFileSync } = await import('node:child_process')\n const { getCurrentVersion } = await import('../version.js')\n const { SettingsManager } = await import('../../core/plugin/settings-manager.js')\n const { createInstallContext } = await import('../../core/plugin/install-context.js')\n const { PluginRegistry } = await import('../../core/plugin/plugin-registry.js')\n\n // Parse input: \"translator\", \"translator@1.2.0\", \"@lucas/pkg@2.0.0\"\n let pkgName: string\n let pkgVersion: string | undefined\n\n // Handle scoped packages: @scope/name@version\n if (input.startsWith('@')) {\n const afterScope = input.indexOf('/', 1)\n if (afterScope === -1) {\n pkgName = input\n } else {\n const rest = input.slice(afterScope + 1)\n const atIdx = rest.indexOf('@')\n if (atIdx !== -1) {\n pkgName = input.slice(0, afterScope + 1 + atIdx)\n pkgVersion = rest.slice(atIdx + 1)\n } else {\n pkgName = input\n }\n }\n } else {\n const atIdx = input.lastIndexOf('@')\n if (atIdx > 0) {\n pkgName = input.slice(0, atIdx)\n pkgVersion = input.slice(atIdx + 1)\n } else {\n pkgName = input\n }\n }\n\n // Try resolve from registry\n const { RegistryClient } = await import('../../core/plugin/registry-client.js')\n const client = new RegistryClient()\n let registryPlugin: any = null\n try {\n const registry = await client.getRegistry()\n registryPlugin = registry.plugins.find(p => p.name === pkgName || p.npm === pkgName)\n if (registryPlugin) {\n console.log(`Resolved from registry: ${pkgName} → ${registryPlugin.npm}`)\n pkgName = registryPlugin.npm\n\n if (!registryPlugin.verified) {\n console.log('⚠️ This plugin is not verified by the OpenACP team.')\n }\n }\n } catch {\n // Registry unavailable\n }\n\n const installSpec = pkgVersion ? `${pkgName}@${pkgVersion}` : pkgName\n console.log(`Installing ${installSpec}...`)\n\n // Check if built-in plugin\n const { corePlugins } = await import('../../plugins/core-plugins.js')\n const builtinPlugin = corePlugins.find(p => p.name === pkgName)\n\n const basePath = path.join(os.homedir(), '.openacp', 'plugins', 'data')\n const settingsManager = new SettingsManager(basePath)\n const registryPath = path.join(os.homedir(), '.openacp', 'plugins.json')\n const pluginRegistry = new PluginRegistry(registryPath)\n await pluginRegistry.load()\n\n if (builtinPlugin) {\n // Built-in plugin — run install hook directly\n if (builtinPlugin.install) {\n const ctx = createInstallContext({ pluginName: builtinPlugin.name, settingsManager, basePath })\n await builtinPlugin.install(ctx)\n }\n\n pluginRegistry.register(builtinPlugin.name, {\n version: builtinPlugin.version,\n source: 'builtin',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(builtinPlugin.name),\n description: builtinPlugin.description,\n })\n await pluginRegistry.save()\n console.log(`✓ ${builtinPlugin.name} installed! Restart to activate.`)\n return\n }\n\n // Community plugin — npm install to ~/.openacp/plugins/\n const pluginsDir = path.join(os.homedir(), '.openacp', 'plugins')\n const nodeModulesDir = path.join(pluginsDir, 'node_modules')\n\n try {\n execFileSync('npm', ['install', installSpec, '--prefix', pluginsDir, '--save'], {\n stdio: 'inherit',\n timeout: 60000,\n })\n } catch {\n console.error(`Failed to install ${installSpec}. Check the package name and try again.`)\n process.exit(1)\n }\n\n // Read installed plugin's package.json for compatibility check\n const cliVersion = getCurrentVersion()\n const isLocalPath = pkgName.startsWith('/') || pkgName.startsWith('.')\n try {\n const pluginRoot = isLocalPath ? path.resolve(pkgName) : path.join(nodeModulesDir, pkgName)\n const installedPkgPath = path.join(pluginRoot, 'package.json')\n const { readFileSync } = await import('node:fs')\n const installedPkg = JSON.parse(readFileSync(installedPkgPath, 'utf-8'))\n\n // Check engines.openacp compatibility\n const minVersion = installedPkg.engines?.openacp?.replace(/[>=^~\\s]/g, '')\n if (minVersion) {\n const { compareVersions } = await import('../version.js')\n if (compareVersions(cliVersion, minVersion) < 0) {\n console.log(`\\n⚠️ This plugin requires OpenACP >= ${minVersion}. You have ${cliVersion}.`)\n console.log(` Run 'openacp update' to get the latest version.\\n`)\n }\n }\n\n // Try to load and run install hook\n const pluginModule = await import(path.join(pluginRoot, installedPkg.main ?? 'dist/index.js'))\n const plugin = pluginModule.default\n\n if (plugin?.install) {\n const ctx = createInstallContext({ pluginName: plugin.name ?? pkgName, settingsManager, basePath })\n await plugin.install(ctx)\n }\n\n pluginRegistry.register(plugin?.name ?? pkgName, {\n version: installedPkg.version,\n source: 'npm',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(plugin?.name ?? pkgName),\n description: plugin?.description ?? installedPkg.description,\n })\n await pluginRegistry.save()\n\n console.log(`✓ ${plugin?.name ?? pkgName} installed! Restart to activate.`)\n } catch (err) {\n // Plugin installed via npm but no install hook or failed to load — still register\n pluginRegistry.register(pkgName, {\n version: pkgVersion ?? 'unknown',\n source: 'npm',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(pkgName),\n })\n await pluginRegistry.save()\n console.log(`✓ ${pkgName} installed (npm only). Restart to activate.`)\n }\n}\n\nasync function uninstallPlugin(name: string, purge: boolean): Promise<void> {\n const os = await import('node:os')\n const path = await import('node:path')\n const fs = await import('node:fs')\n const { PluginRegistry } = await import('../../core/plugin/plugin-registry.js')\n\n const registryPath = path.join(os.homedir(), '.openacp', 'plugins.json')\n const registry = new PluginRegistry(registryPath)\n await registry.load()\n\n const entry = registry.get(name)\n if (!entry) {\n console.error(`Plugin \"${name}\" not installed.`)\n process.exit(1)\n }\n\n if (entry.source === 'builtin') {\n console.error(`Cannot uninstall built-in plugin. Use \"openacp plugin disable ${name}\" instead.`)\n process.exit(1)\n }\n\n // Try to call uninstall hook\n try {\n const { corePlugins } = await import('../../plugins/core-plugins.js')\n const plugin = corePlugins.find(p => p.name === name)\n if (plugin?.uninstall) {\n const { SettingsManager } = await import('../../core/plugin/settings-manager.js')\n const { createInstallContext } = await import('../../core/plugin/install-context.js')\n const basePath = path.join(os.homedir(), '.openacp', 'plugins', 'data')\n const settingsManager = new SettingsManager(basePath)\n const ctx = createInstallContext({ pluginName: name, settingsManager, basePath })\n await plugin.uninstall(ctx, { purge })\n }\n } catch {\n // Plugin module might not be loadable, continue\n }\n\n if (purge) {\n const pluginDir = path.join(os.homedir(), '.openacp', 'plugins', name)\n fs.rmSync(pluginDir, { recursive: true, force: true })\n }\n\n registry.remove(name)\n await registry.save()\n console.log(`Plugin ${name} uninstalled${purge ? ' (purged)' : ''}.`)\n}\n","import { readApiPort, removeStalePortFile, apiCall } from '../api-client.js'\nimport { wantsHelp } from './helpers.js'\n\nfunction printApiHelp(): void {\n console.log(`\n\\x1b[1mopenacp api\\x1b[0m — Interact with the running OpenACP daemon\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api <command> [options]\n\n\\x1b[1mRequires a running daemon.\\x1b[0m Start with: openacp start\n\n\\x1b[1mSession Commands:\\x1b[0m\n openacp api status Show active sessions\n openacp api session <id> Show session details\n openacp api new [agent] [workspace] Create a new session\n [--channel <id>]\n openacp api send <id> <prompt> Send prompt to session\n openacp api cancel <id> Cancel a session\n openacp api dangerous <id> on|off Toggle dangerous mode\n\n\\x1b[1mTopic Commands:\\x1b[0m\n openacp api topics [--status s1,s2] List topics\n openacp api delete-topic <id> [--force] Delete a topic\n openacp api cleanup [--status s1,s2] Cleanup finished topics\n\n\\x1b[1mSystem Commands:\\x1b[0m\n openacp api health Show system health\n openacp api agents List available agents\n openacp api adapters List registered adapters\n openacp api tunnel Show tunnel status\n openacp api config Show runtime config\n openacp api config set <key> <value> Update config value\n openacp api notify <message> Send notification to all channels\n openacp api restart Restart daemon\n openacp api version Show daemon version\n\n\\x1b[1mOptions:\\x1b[0m\n -h, --help Show this help message\n`)\n}\n\nexport async function cmdApi(args: string[]): Promise<void> {\n const subCmd = args[1]\n\n if (wantsHelp(args) && (!subCmd || subCmd === '--help' || subCmd === '-h')) {\n printApiHelp()\n return\n }\n\n // Handle --help for individual api subcommands (before port check)\n if (wantsHelp(args) && subCmd) {\n const apiSubHelp: Record<string, string> = {\n 'status': `\n\\x1b[1mopenacp api status\\x1b[0m — Show active sessions\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api status\n\nLists all active sessions with their ID, agent, status, and name.\n`,\n 'session': `\n\\x1b[1mopenacp api session\\x1b[0m — Show session details\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api session <id>\n\n\\x1b[1mArguments:\\x1b[0m\n <id> Session ID\n\nShows detailed info: agent, status, name, workspace, creation time,\ndangerous mode, queue depth, and channel/thread IDs.\n`,\n 'new': `\n\\x1b[1mopenacp api new\\x1b[0m — Create a new session\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api new [agent] [workspace]\n openacp api new [agent] --workspace <path> [--channel <id>]\n\n\\x1b[1mArguments:\\x1b[0m\n [agent] Agent name (uses default if omitted)\n [workspace] Working directory for the session\n\n\\x1b[1mOptions:\\x1b[0m\n --channel <id> Target adapter (e.g. telegram, discord). Defaults to first registered adapter.\n\n\\x1b[1mExamples:\\x1b[0m\n openacp api new\n openacp api new claude /path/to/project\n openacp api new claude /path/to/project --channel discord\n`,\n 'send': `\n\\x1b[1mopenacp api send\\x1b[0m — Send prompt to a session\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api send <id> <prompt>\n\n\\x1b[1mArguments:\\x1b[0m\n <id> Session ID\n <prompt> Prompt text (all remaining arguments are joined)\n\n\\x1b[1mExamples:\\x1b[0m\n openacp api send abc123 \"Fix the login bug\"\n openacp api send abc123 refactor the auth module\n`,\n 'cancel': `\n\\x1b[1mopenacp api cancel\\x1b[0m — Cancel a session\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api cancel <id>\n\n\\x1b[1mArguments:\\x1b[0m\n <id> Session ID to cancel\n`,\n 'dangerous': `\n\\x1b[1mopenacp api dangerous\\x1b[0m — Toggle dangerous mode for a session\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api dangerous <id> on|off\n\n\\x1b[1mArguments:\\x1b[0m\n <id> Session ID\n on|off Enable or disable dangerous mode\n\nDangerous mode allows the agent to run destructive commands\nwithout confirmation prompts.\n`,\n 'topics': `\n\\x1b[1mopenacp api topics\\x1b[0m — List topics\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api topics [--status <statuses>]\n\n\\x1b[1mOptions:\\x1b[0m\n --status <s1,s2> Filter by status (comma-separated)\n\n\\x1b[1mExamples:\\x1b[0m\n openacp api topics\n openacp api topics --status active,finished\n`,\n 'delete-topic': `\n\\x1b[1mopenacp api delete-topic\\x1b[0m — Delete a topic\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api delete-topic <id> [--force]\n\n\\x1b[1mArguments:\\x1b[0m\n <id> Session ID of the topic to delete\n\n\\x1b[1mOptions:\\x1b[0m\n --force Delete even if session is active\n`,\n 'cleanup': `\n\\x1b[1mopenacp api cleanup\\x1b[0m — Cleanup finished topics\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api cleanup [--status <statuses>]\n\n\\x1b[1mOptions:\\x1b[0m\n --status <s1,s2> Filter by status (comma-separated, default: finished topics)\n\n\\x1b[1mExamples:\\x1b[0m\n openacp api cleanup\n openacp api cleanup --status finished,error\n`,\n 'health': `\n\\x1b[1mopenacp api health\\x1b[0m — Show system health\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api health\n\nShows status, uptime, version, memory usage, session counts,\nregistered adapters, and tunnel status.\n`,\n 'agents': `\n\\x1b[1mopenacp api agents\\x1b[0m — List available agents from running daemon\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api agents\n\nLists agents configured in the running daemon with their names\nand which one is the default.\n`,\n 'adapters': `\n\\x1b[1mopenacp api adapters\\x1b[0m — List registered adapters\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api adapters\n\nShows all channel adapters registered with the running daemon.\n`,\n 'tunnel': `\n\\x1b[1mopenacp api tunnel\\x1b[0m — Show tunnel status\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api tunnel\n\nShows whether a tunnel is enabled, the provider, and the URL.\n`,\n 'config': `\n\\x1b[1mopenacp api config\\x1b[0m — Show or update runtime config\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api config Show current runtime config\n openacp api config set <key> <value> Update a config value\n\n\\x1b[2mNote: Prefer 'openacp config' instead — it works whether daemon is running or not.\\x1b[0m\n`,\n 'restart': `\n\\x1b[1mopenacp api restart\\x1b[0m — Restart the daemon\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api restart\n\nSends a restart signal to the running daemon.\n`,\n 'notify': `\n\\x1b[1mopenacp api notify\\x1b[0m — Send notification to all channels\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api notify <message>\n\n\\x1b[1mArguments:\\x1b[0m\n <message> Notification text (all remaining arguments are joined)\n\n\\x1b[1mExamples:\\x1b[0m\n openacp api notify \"Deployment complete\"\n`,\n 'version': `\n\\x1b[1mopenacp api version\\x1b[0m — Show daemon version\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api version\n\nShows the version of the currently running daemon process.\n`,\n }\n const help = apiSubHelp[subCmd]\n if (help) {\n console.log(help)\n return\n }\n // Unknown subcommand with --help, show general help\n printApiHelp()\n return\n }\n\n const port = readApiPort()\n if (port === null) {\n console.error('OpenACP is not running. Start with `openacp start`')\n process.exit(1)\n }\n\n try {\n if (subCmd === 'new') {\n const agent = args[2]\n const workspaceIdx = args.indexOf('--workspace')\n const workspace = workspaceIdx !== -1 ? args[workspaceIdx + 1] : args[3]\n const channelIdx = args.indexOf('--channel')\n const channel = channelIdx !== -1 ? args[channelIdx + 1] : undefined\n const body: Record<string, string> = {}\n if (agent) body.agent = agent\n if (workspace) body.workspace = workspace\n if (channel) body.channel = channel\n\n const res = await apiCall(port, '/api/sessions', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log('Session created')\n console.log(` ID : ${data.sessionId}`)\n console.log(` Agent : ${data.agent}`)\n console.log(` Workspace : ${data.workspace}`)\n console.log(` Status : ${data.status}`)\n\n } else if (subCmd === 'cancel') {\n const sessionId = args[2]\n if (!sessionId) {\n console.error('Usage: openacp api cancel <session-id>')\n process.exit(1)\n }\n const res = await apiCall(port, `/api/sessions/${encodeURIComponent(sessionId)}`, {\n method: 'DELETE',\n })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log(`Session ${sessionId} cancelled`)\n\n } else if (subCmd === 'status') {\n const res = await apiCall(port, '/api/sessions')\n const data = await res.json() as { sessions: Array<{ id: string; agent: string; status: string; name: string | null }> }\n if (data.sessions.length === 0) {\n console.log('No active sessions.')\n } else {\n console.log(`Active sessions: ${data.sessions.length}\\n`)\n for (const s of data.sessions) {\n const name = s.name ? ` \"${s.name}\"` : ''\n console.log(` ${s.id} ${s.agent} ${s.status}${name}`)\n }\n }\n\n } else if (subCmd === 'agents') {\n const res = await apiCall(port, '/api/agents')\n const data = await res.json() as { agents: Array<{ name: string; command: string; args: string[] }>; default: string }\n console.log('Available agents:')\n for (const a of data.agents) {\n const isDefault = a.name === data.default ? ' (default)' : ''\n console.log(` ${a.name}${isDefault}`)\n }\n\n } else if (subCmd === 'topics') {\n const statusIdx = args.indexOf('--status')\n const statusParam = statusIdx !== -1 ? args[statusIdx + 1] : undefined\n const query = statusParam ? `?status=${encodeURIComponent(statusParam)}` : ''\n const res = await apiCall(port, `/api/topics${query}`)\n const data = await res.json() as { topics: Array<{ sessionId: string; topicId: number | null; name: string | null; status: string; agentName: string; lastActiveAt: string }> }\n if (data.topics.length === 0) {\n console.log('No topics found.')\n } else {\n console.log(`Topics: ${data.topics.length}\\n`)\n for (const t of data.topics) {\n const name = t.name ? ` \"${t.name}\"` : ''\n const topic = t.topicId ? `Topic #${t.topicId}` : 'headless'\n console.log(` ${t.sessionId} ${t.agentName} ${t.status}${name} ${topic}`)\n }\n }\n\n } else if (subCmd === 'delete-topic') {\n const sessionId = args[2]\n if (!sessionId) {\n console.error('Usage: openacp api delete-topic <session-id> [--force]')\n process.exit(1)\n }\n const force = args.includes('--force')\n const query = force ? '?force=true' : ''\n const res = await apiCall(port, `/api/topics/${encodeURIComponent(sessionId)}${query}`, { method: 'DELETE' })\n const data = await res.json() as Record<string, unknown>\n if (res.status === 409) {\n const session = data.session as Record<string, unknown> | undefined\n console.error(`Session \"${sessionId}\" is active (${session?.status}). Use --force to delete.`)\n process.exit(1)\n }\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n const topicLabel = data.topicId ? `Topic #${data.topicId}` : 'headless session'\n console.log(`${topicLabel} deleted (session ${sessionId})`)\n\n } else if (subCmd === 'cleanup') {\n const statusIdx = args.indexOf('--status')\n const statusParam = statusIdx !== -1 ? args[statusIdx + 1] : undefined\n const body: Record<string, unknown> = {}\n if (statusParam) body.statuses = statusParam.split(',')\n const res = await apiCall(port, '/api/topics/cleanup', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n const data = await res.json() as { deleted: string[]; failed: Array<{ sessionId: string; error: string }> }\n if (data.deleted.length === 0 && data.failed.length === 0) {\n console.log('Nothing to clean up.')\n } else {\n console.log(`Cleaned up ${data.deleted.length} topics${data.deleted.length ? ': ' + data.deleted.join(', ') : ''} (${data.failed.length} failed)`)\n for (const f of data.failed) {\n console.error(` Failed: ${f.sessionId} — ${f.error}`)\n }\n }\n\n } else if (subCmd === 'send') {\n const sessionId = args[2]\n if (!sessionId) {\n console.error('Usage: openacp api send <session-id> <prompt>')\n process.exit(1)\n }\n const prompt = args.slice(3).join(' ')\n if (!prompt) {\n console.error('Usage: openacp api send <session-id> <prompt>')\n process.exit(1)\n }\n const res = await apiCall(port, `/api/sessions/${encodeURIComponent(sessionId)}/prompt`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ prompt }),\n })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log(`Prompt sent to session ${sessionId} (queue depth: ${data.queueDepth})`)\n\n } else if (subCmd === 'session') {\n const sessionId = args[2]\n if (!sessionId) {\n console.error('Usage: openacp api session <session-id>')\n process.exit(1)\n }\n const res = await apiCall(port, `/api/sessions/${encodeURIComponent(sessionId)}`)\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n const s = (data.session ?? data) as Record<string, unknown>\n console.log(`Session details:`)\n console.log(` ID : ${s.id}`)\n console.log(` Agent : ${s.agent}`)\n console.log(` Status : ${s.status}`)\n console.log(` Name : ${s.name ?? '(none)'}`)\n console.log(` Workspace : ${s.workspace}`)\n console.log(` Created : ${s.createdAt}`)\n console.log(` Dangerous : ${s.dangerousMode}`)\n console.log(` Queue depth : ${s.queueDepth}`)\n console.log(` Prompt active : ${s.promptRunning}`)\n console.log(` Channel : ${s.channelId ?? '(none)'}`)\n console.log(` Thread : ${s.threadId ?? '(none)'}`)\n\n } else if (subCmd === 'dangerous') {\n const sessionId = args[2]\n if (!sessionId) {\n console.error('Usage: openacp api dangerous <session-id> [on|off]')\n process.exit(1)\n }\n const toggle = args[3]\n if (!toggle || (toggle !== 'on' && toggle !== 'off')) {\n console.error('Usage: openacp api dangerous <session-id> [on|off]')\n process.exit(1)\n }\n const res = await apiCall(port, `/api/sessions/${encodeURIComponent(sessionId)}/dangerous`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ enabled: toggle === 'on' }),\n })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n const state = toggle === 'on' ? 'enabled' : 'disabled'\n console.log(`Dangerous mode ${state} for session ${sessionId}`)\n\n } else if (subCmd === 'health') {\n const res = await apiCall(port, '/api/health')\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n const uptimeMs = typeof data.uptime === 'number' ? data.uptime : 0\n const uptimeSeconds = Math.floor(uptimeMs / 1000)\n const hours = Math.floor(uptimeSeconds / 3600)\n const minutes = Math.floor((uptimeSeconds % 3600) / 60)\n const mem = data.memory as Record<string, number> | undefined\n const memoryMB = mem ? (mem.rss / 1024 / 1024).toFixed(1) : '0.0'\n const sessions = data.sessions as Record<string, unknown> ?? {}\n const tunnel = data.tunnel as Record<string, unknown> | undefined\n const tunnelStr = tunnel?.enabled ? `${tunnel.url}` : 'disabled'\n const adapters = Array.isArray(data.adapters) ? data.adapters.join(', ') : String(data.adapters ?? 'none')\n console.log(`Status : ${data.status}`)\n console.log(`Uptime : ${hours}h ${minutes}m`)\n console.log(`Version : ${data.version}`)\n console.log(`Memory : ${memoryMB} MB`)\n console.log(`Sessions : ${sessions.active ?? 0} active / ${sessions.total ?? 0} total`)\n console.log(`Adapters : ${adapters}`)\n console.log(`Tunnel : ${tunnelStr}`)\n\n } else if (subCmd === 'restart') {\n const res = await apiCall(port, '/api/restart', { method: 'POST' })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log('Restart signal sent. OpenACP is restarting...')\n\n } else if (subCmd === 'config') {\n console.warn('⚠️ Deprecated: use \"openacp config\" or \"openacp config set\" instead.')\n const subSubCmd = args[2]\n if (!subSubCmd) {\n const res = await apiCall(port, '/api/config')\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log(JSON.stringify(data.config, null, 2))\n } else if (subSubCmd === 'set') {\n const configPath = args[3]\n const configValue = args[4]\n if (!configPath || configValue === undefined) {\n console.error('Usage: openacp api config set <path> <value>')\n process.exit(1)\n }\n let value: unknown = configValue\n try {\n value = JSON.parse(configValue)\n } catch {\n // keep as string\n }\n const res = await apiCall(port, '/api/config', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: configPath, value }),\n })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log(`Config updated: ${configPath} = ${JSON.stringify(value)}`)\n if (data.needsRestart) {\n console.log('Note: restart required for this change to take effect.')\n }\n } else {\n console.error(`Unknown config subcommand: ${subSubCmd}`)\n console.log(' openacp api config Show runtime config')\n console.log(' openacp api config set <key> <value> Update config value')\n process.exit(1)\n }\n\n } else if (subCmd === 'adapters') {\n const res = await apiCall(port, '/api/adapters')\n const data = await res.json() as { adapters: Array<{ name: string; type: string }> }\n if (!res.ok) {\n console.error(`Error: ${(data as Record<string, unknown>).error}`)\n process.exit(1)\n }\n console.log('Registered adapters:')\n for (const a of data.adapters) {\n console.log(` ${a.name} (${a.type})`)\n }\n\n } else if (subCmd === 'tunnel') {\n const res = await apiCall(port, '/api/tunnel')\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n if (data.enabled) {\n console.log(`Tunnel provider : ${data.provider}`)\n console.log(`Tunnel URL : ${data.url}`)\n } else {\n console.log('Tunnel: not enabled')\n }\n\n } else if (subCmd === 'notify') {\n const message = args.slice(2).join(' ')\n if (!message) {\n console.error('Usage: openacp api notify <message>')\n process.exit(1)\n }\n const res = await apiCall(port, '/api/notify', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ message }),\n })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log('Notification sent to all channels.')\n\n } else if (subCmd === 'version') {\n const res = await apiCall(port, '/api/version')\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log(`Daemon version: ${data.version}`)\n\n } else {\n const { suggestMatch } = await import('../suggest.js')\n const apiSubcommands = [\n 'new', 'cancel', 'status', 'agents', 'topics', 'delete-topic',\n 'cleanup', 'send', 'session', 'dangerous', 'health', 'restart',\n 'config', 'adapters', 'tunnel', 'notify', 'version',\n ]\n const suggestion = suggestMatch(subCmd ?? '', apiSubcommands)\n console.error(`Unknown api command: ${subCmd || '(none)'}\\n`)\n if (suggestion) console.error(`Did you mean: ${suggestion}?\\n`)\n printApiHelp()\n process.exit(1)\n }\n } catch (err) {\n if (err instanceof TypeError && (err.cause as Record<string, unknown> | undefined)?.code === 'ECONNREFUSED') {\n console.error('OpenACP is not running (stale port file)')\n removeStalePortFile()\n process.exit(1)\n }\n throw err\n }\n}\n","import { checkAndPromptUpdate } from '../version.js'\nimport { wantsHelp } from './helpers.js'\n\nexport async function cmdStart(args: string[] = []): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp start\\x1b[0m — Start OpenACP as a background daemon\n\n\\x1b[1mUsage:\\x1b[0m\n openacp start\n\nStarts the server as a background process (daemon mode).\nRequires an existing config — run 'openacp' first to set up.\n\n\\x1b[1mSee also:\\x1b[0m\n openacp stop Stop the daemon\n openacp status Check if daemon is running\n openacp logs Tail daemon log file\n`)\n return\n }\n await checkAndPromptUpdate()\n const { startDaemon, getPidPath } = await import('../daemon.js')\n const { ConfigManager } = await import('../../core/config/config.js')\n const cm = new ConfigManager()\n if (await cm.exists()) {\n await cm.load()\n const config = cm.get()\n const result = startDaemon(getPidPath(), config.logging.logDir)\n if ('error' in result) {\n console.error(result.error)\n process.exit(1)\n }\n console.log(`OpenACP daemon started (PID ${result.pid})`)\n } else {\n console.error('No config found. Run \"openacp\" first to set up.')\n process.exit(1)\n }\n}\n","import { wantsHelp } from './helpers.js'\n\nexport async function cmdStop(args: string[] = []): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp stop\\x1b[0m — Stop the background daemon\n\n\\x1b[1mUsage:\\x1b[0m\n openacp stop\n\nSends a stop signal to the running OpenACP daemon process.\n`)\n return\n }\n const { stopDaemon } = await import('../daemon.js')\n const result = await stopDaemon()\n if (result.stopped) {\n console.log(`OpenACP daemon stopped (was PID ${result.pid})`)\n } else {\n console.error(result.error)\n process.exit(1)\n }\n}\n","import { wantsHelp } from './helpers.js'\n\nexport async function cmdStatus(args: string[] = []): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp status\\x1b[0m — Show daemon status\n\n\\x1b[1mUsage:\\x1b[0m\n openacp status\n\nShows whether the OpenACP daemon is running and its PID.\n`)\n return\n }\n const { getStatus } = await import('../daemon.js')\n const status = getStatus()\n if (status.running) {\n console.log(`OpenACP is running (PID ${status.pid})`)\n } else {\n console.log('OpenACP is not running')\n }\n}\n","import { wantsHelp } from './helpers.js'\n\nexport async function cmdLogs(args: string[] = []): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp logs\\x1b[0m — Tail daemon log file\n\n\\x1b[1mUsage:\\x1b[0m\n openacp logs\n\nStreams the last 50 lines of the OpenACP log file and\nfollows new output (like tail -f). Press Ctrl+C to stop.\n\nLog file location is configured in config (default: ~/.openacp/logs/).\n`)\n return\n }\n const { spawn } = await import('node:child_process')\n const { ConfigManager, expandHome } = await import('../../core/config/config.js')\n const pathMod = await import('node:path')\n const cm = new ConfigManager()\n let logDir = '~/.openacp/logs'\n if (await cm.exists()) {\n await cm.load()\n logDir = cm.get().logging.logDir\n }\n const logFile = pathMod.join(expandHome(logDir), 'openacp.log')\n const tail = spawn('tail', ['-f', '-n', '50', logFile], { stdio: 'inherit' })\n tail.on('error', (err: Error) => {\n console.error(`Cannot tail log file: ${err.message}`)\n process.exit(1)\n })\n}\n","import { readApiPort, apiCall } from '../api-client.js'\nimport { wantsHelp, buildNestedUpdateFromPath } from './helpers.js'\n\nexport async function cmdConfig(args: string[] = []): Promise<void> {\n const subCmd = args[1] // 'set' or undefined\n\n if (wantsHelp(args) && subCmd === 'set') {\n console.log(`\n\\x1b[1mopenacp config set\\x1b[0m — Set a config value directly\n\n\\x1b[1mUsage:\\x1b[0m\n openacp config set <key> <value>\n\n\\x1b[1mArguments:\\x1b[0m\n <key> Dot-notation config path (e.g. telegram.botToken)\n <value> New value (JSON-parsed if possible, otherwise string)\n\n\\x1b[1mOptions:\\x1b[0m\n -h, --help Show this help message\n\nWorks with both running and stopped daemon. When running, uses\nthe API for live updates. When stopped, edits config file directly.\n\n\\x1b[1mExamples:\\x1b[0m\n openacp config set defaultAgent claude\n openacp config set security.maxConcurrentSessions 5\n openacp config set telegram.botToken \"123:ABC\"\n`)\n return\n }\n\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp config\\x1b[0m — View and edit configuration\n\n\\x1b[1mUsage:\\x1b[0m\n openacp config Open interactive config editor\n openacp config set <key> <value> Set a config value directly\n\n\\x1b[1mOptions:\\x1b[0m\n -h, --help Show this help message\n\nWorks with both running and stopped daemon. When running, uses\nthe API for live updates. When stopped, edits config file directly.\n\n\\x1b[1mExamples:\\x1b[0m\n openacp config\n openacp config set defaultAgent claude\n\n\\x1b[2mRun 'openacp config set --help' for more info on the set subcommand.\\x1b[0m\n`)\n return\n }\n\n if (subCmd === 'set') {\n // Non-interactive: openacp config set <key> <value>\n const configPath = args[2]\n const configValue = args[3]\n if (!configPath || configValue === undefined) {\n console.error('Usage: openacp config set <path> <value>')\n process.exit(1)\n }\n\n // Validate top-level config key\n const { ConfigSchema } = await import('../../core/config/config.js')\n const topLevelKey = configPath.split('.')[0]\n const validConfigKeys = Object.keys(ConfigSchema.shape)\n if (!validConfigKeys.includes(topLevelKey)) {\n const { suggestMatch } = await import('../suggest.js')\n const suggestion = suggestMatch(topLevelKey, validConfigKeys)\n console.error(`Unknown config key: ${topLevelKey}`)\n if (suggestion) console.error(`Did you mean: ${suggestion}?`)\n process.exit(1)\n }\n\n let value: unknown = configValue\n try { value = JSON.parse(configValue) } catch { /* keep as string */ }\n\n const port = readApiPort()\n if (port !== null) {\n // Server running — use API\n const res = await apiCall(port, '/api/config', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: configPath, value }),\n })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log(`Config updated: ${configPath} = ${JSON.stringify(value)}`)\n if (data.needsRestart) {\n console.log('Note: restart required for this change to take effect.')\n }\n } else {\n // Server not running — update file directly\n const { ConfigManager } = await import('../../core/config/config.js')\n const cm = new ConfigManager()\n if (!(await cm.exists())) {\n console.error('No config found. Run \"openacp\" first to set up.')\n process.exit(1)\n }\n await cm.load()\n const updates = buildNestedUpdateFromPath(configPath, value)\n await cm.save(updates)\n console.log(`Config updated: ${configPath} = ${JSON.stringify(value)}`)\n }\n return\n }\n\n // Interactive editor\n const { runConfigEditor } = await import('../../core/config/config-editor.js')\n const { ConfigManager } = await import('../../core/config/config.js')\n const cm = new ConfigManager()\n if (!(await cm.exists())) {\n console.error('No config found. Run \"openacp\" first to set up.')\n process.exit(1)\n }\n\n const port = readApiPort()\n if (port !== null) {\n await runConfigEditor(cm, 'api', port)\n } else {\n await runConfigEditor(cm, 'file')\n }\n}\n","import { wantsHelp } from './helpers.js'\n\nexport async function cmdReset(args: string[] = []): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp reset\\x1b[0m — Re-run setup wizard\n\n\\x1b[1mUsage:\\x1b[0m\n openacp reset\n\nDeletes all OpenACP data (~/.openacp) and allows you to\nstart fresh with the setup wizard. The daemon must be stopped first.\n\n\\x1b[1m\\x1b[31mThis is destructive\\x1b[0m — config, plugins, agent data will be removed.\n`)\n return\n }\n const { getStatus } = await import('../daemon.js')\n const status = getStatus()\n if (status.running) {\n console.error('OpenACP is running. Stop it first: openacp stop')\n process.exit(1)\n }\n\n const clack = await import('@clack/prompts')\n const yes = await clack.confirm({\n message: 'This will delete all OpenACP data (~/.openacp). You will need to set up again. Continue?',\n initialValue: false,\n })\n if (clack.isCancel(yes) || !yes) {\n console.log('Aborted.')\n return\n }\n\n const { uninstallAutoStart } = await import('../autostart.js')\n uninstallAutoStart()\n\n const fs = await import('node:fs')\n const os = await import('node:os')\n const path = await import('node:path')\n const openacpDir = path.join(os.homedir(), '.openacp')\n fs.rmSync(openacpDir, { recursive: true, force: true })\n\n console.log('Reset complete. Run `openacp` to set up again.')\n}\n","import { getCurrentVersion, getLatestVersion, compareVersions, runUpdate } from '../version.js'\nimport { wantsHelp } from './helpers.js'\n\nexport async function cmdUpdate(args: string[] = []): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp update\\x1b[0m — Update to latest version\n\n\\x1b[1mUsage:\\x1b[0m\n openacp update\n\nChecks npm for the latest version of @openacp/cli and\ninstalls it globally if an update is available.\n`)\n return\n }\n const current = getCurrentVersion()\n const latest = await getLatestVersion()\n if (!latest) {\n console.error('Could not check for updates. Check your internet connection.')\n process.exit(1)\n }\n if (compareVersions(current, latest) >= 0) {\n console.log(`Already up to date (v${current})`)\n return\n }\n console.log(`Update available: v${current} → v${latest}`)\n const ok = await runUpdate()\n if (ok) {\n console.log(`\\x1b[32m✓ Updated to v${latest}\\x1b[0m`)\n } else {\n console.error('Update failed. Try manually: npm install -g @openacp/cli@latest')\n process.exit(1)\n }\n}\n","import { readApiPort } from '../api-client.js'\nimport { wantsHelp } from './helpers.js'\n\nexport async function cmdAdopt(args: string[]): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp adopt\\x1b[0m — Adopt an external agent session\n\n\\x1b[1mUsage:\\x1b[0m\n openacp adopt <agent> <session_id> [--cwd <path>] [--channel <name>]\n\n\\x1b[1mArguments:\\x1b[0m\n <agent> Agent name (e.g. claude)\n <session_id> External session ID to adopt\n\n\\x1b[1mOptions:\\x1b[0m\n --cwd <path> Working directory for the session (default: current dir)\n --channel <name> Target channel adapter (e.g. telegram, discord). Default: first registered\n -h, --help Show this help message\n\nTransfers an existing agent session into OpenACP so it appears\nas a messaging thread. Requires a running daemon.\n\n\\x1b[1mExamples:\\x1b[0m\n openacp adopt claude abc123-def456\n openacp adopt claude abc123 --cwd /path/to/project\n openacp adopt claude abc123 --channel discord\n`)\n return\n }\n\n const agent = args[1];\n const sessionId = args[2];\n\n if (!agent || !sessionId) {\n console.log(\"Usage: openacp adopt <agent> <session_id> [--cwd <path>] [--channel <name>]\");\n console.log(\"Example: openacp adopt claude abc123-def456 --cwd /path/to/project\");\n process.exit(1);\n }\n\n const cwdIdx = args.indexOf(\"--cwd\");\n const cwd = cwdIdx !== -1 && args[cwdIdx + 1] ? args[cwdIdx + 1] : process.cwd();\n const channelIdx = args.indexOf(\"--channel\");\n const channel = channelIdx !== -1 && args[channelIdx + 1] ? args[channelIdx + 1] : undefined;\n\n const port = readApiPort();\n if (!port) {\n console.log(\"OpenACP is not running. Start it with: openacp start\");\n process.exit(1);\n }\n\n try {\n const { apiCall } = await import('../api-client.js')\n const res = await apiCall(port, '/api/sessions/adopt', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ agent, agentSessionId: sessionId, cwd, channel }),\n })\n const data = await res.json() as Record<string, unknown>;\n\n if (data.ok) {\n if (data.status === \"existing\") {\n console.log(`Session already active. Topic pinged.`);\n } else {\n console.log(`Session transferred to messaging platform.`);\n }\n console.log(` Session ID: ${data.sessionId}`);\n console.log(` Thread ID: ${data.threadId}`);\n } else {\n console.log(`Error: ${(data.message as string) || (data.error as string)}`);\n process.exit(1);\n }\n } catch (err) {\n console.log(`Failed to connect to OpenACP: ${err instanceof Error ? err.message : err}`);\n process.exit(1);\n }\n}\n","import { wantsHelp } from './helpers.js'\n\nexport async function cmdIntegrate(args: string[]): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp integrate\\x1b[0m — Manage agent integrations\n\n\\x1b[1mUsage:\\x1b[0m\n openacp integrate <agent> Install integration for an agent\n openacp integrate <agent> --uninstall Remove integration\n\n\\x1b[1mArguments:\\x1b[0m\n <agent> Agent name (e.g. claude)\n\n\\x1b[1mOptions:\\x1b[0m\n --uninstall Remove the integration instead of installing\n -h, --help Show this help message\n\nIntegrations enable features like session handoff from an agent\nto OpenACP (Telegram/Discord). For example, the Claude integration adds\na \"Handoff\" slash command to Claude Code.\n\n\\x1b[1mExamples:\\x1b[0m\n openacp integrate claude\n openacp integrate claude --uninstall\n`)\n return\n }\n\n const { getIntegration, listIntegrations } = await import(\"../integrate.js\");\n\n const agent = args[1];\n const uninstall = args.includes(\"--uninstall\");\n\n if (!agent) {\n console.log(\"Usage: openacp integrate <agent> [--uninstall]\");\n console.log(`Available integrations: ${listIntegrations().join(\", \")}`);\n process.exit(1);\n }\n\n const integration = getIntegration(agent);\n if (!integration) {\n const { suggestMatch } = await import('../suggest.js');\n const available = listIntegrations();\n const suggestion = suggestMatch(agent, available);\n console.log(`No integration available for '${agent}'.`);\n if (suggestion) console.log(`Did you mean: ${suggestion}?`);\n console.log(`Available: ${available.join(\", \")}`);\n process.exit(1);\n }\n\n for (const item of integration.items) {\n if (uninstall) {\n console.log(`Removing ${agent}/${item.id}...`);\n const result = await item.uninstall();\n for (const log of result.logs) console.log(` ${log}`);\n if (result.success) {\n console.log(` ${item.name} removed.`);\n } else {\n console.log(` Failed to remove ${item.name}.`);\n process.exit(1);\n }\n } else {\n console.log(`Installing ${agent}/${item.id}...`);\n const result = await item.install();\n for (const log of result.logs) console.log(` ${log}`);\n if (result.success) {\n console.log(` ${item.name} installed.`);\n } else {\n console.log(` Failed to install ${item.name}.`);\n process.exit(1);\n }\n }\n }\n}\n","import { wantsHelp } from './helpers.js'\n\nexport async function cmdDoctor(args: string[]): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp doctor\\x1b[0m — Run system diagnostics\n\n\\x1b[1mUsage:\\x1b[0m\n openacp doctor [--dry-run]\n\n\\x1b[1mOptions:\\x1b[0m\n --dry-run Check only, don't apply any fixes\n -h, --help Show this help message\n\nChecks your OpenACP installation for common issues including\nconfig validity, agent availability, dependencies, and connectivity.\nFixable issues can be auto-repaired when not using --dry-run.\n`)\n return\n }\n\n const knownFlags = [\"--dry-run\"];\n const unknownFlags = args.slice(1).filter(\n (a) => a.startsWith(\"--\") && !knownFlags.includes(a),\n );\n if (unknownFlags.length > 0) {\n const { suggestMatch } = await import('../suggest.js');\n for (const flag of unknownFlags) {\n const suggestion = suggestMatch(flag, knownFlags);\n console.error(`Unknown flag: ${flag}`);\n if (suggestion) console.error(`Did you mean: ${suggestion}?`);\n }\n process.exit(1);\n }\n\n const dryRun = args.includes(\"--dry-run\");\n const { DoctorEngine } = await import(\"../../core/doctor/index.js\");\n const engine = new DoctorEngine({ dryRun });\n\n console.log(\"\\n🩺 OpenACP Doctor\\n\");\n\n const report = await engine.runAll();\n\n // Render results\n const icons = { pass: \"\\x1b[32m✅\\x1b[0m\", warn: \"\\x1b[33m⚠️\\x1b[0m\", fail: \"\\x1b[31m❌\\x1b[0m\" };\n\n for (const category of report.categories) {\n console.log(`\\x1b[1m\\x1b[36m${category.name}\\x1b[0m`);\n for (const result of category.results) {\n console.log(` ${icons[result.status]} ${result.message}`);\n }\n console.log();\n }\n\n // Handle risky fixes\n if (report.pendingFixes.length > 0) {\n console.log(\"\\x1b[1mFixable issues:\\x1b[0m\\n\");\n for (const pending of report.pendingFixes) {\n if (dryRun) {\n console.log(` 🔧 ${pending.message} (use without --dry-run to fix)`);\n } else {\n const clack = await import(\"@clack/prompts\");\n const shouldFix = await clack.confirm({\n message: `Fix: ${pending.message}?`,\n initialValue: false,\n });\n if (clack.isCancel(shouldFix) || !shouldFix) {\n continue;\n }\n const fixResult = await pending.fix();\n if (fixResult.success) {\n console.log(` \\x1b[32m✓ ${fixResult.message}\\x1b[0m`);\n } else {\n console.log(` \\x1b[31m✗ Fix failed: ${fixResult.message}\\x1b[0m`);\n }\n }\n }\n console.log();\n }\n\n // Summary\n const { passed, warnings, failed, fixed } = report.summary;\n const fixedStr = fixed > 0 ? `, ${fixed} fixed` : \"\";\n console.log(`Result: ${passed} passed, ${warnings} warnings, ${failed} failed${fixedStr}`);\n\n if (failed > 0) {\n process.exit(1);\n }\n}\n","import { wantsHelp } from './helpers.js'\n\nexport async function cmdAgents(args: string[]): Promise<void> {\n const subcommand = args[1];\n\n if (wantsHelp(args) && (!subcommand || subcommand === '--help' || subcommand === '-h')) {\n console.log(`\n\\x1b[1mopenacp agents\\x1b[0m — Manage AI coding agents\n\n\\x1b[1mUsage:\\x1b[0m\n openacp agents Browse all agents (installed + available)\n openacp agents install <name> Install an agent from the ACP Registry\n openacp agents uninstall <name> Remove an installed agent\n openacp agents info <name> Show details, dependencies & setup guide\n openacp agents run <name> [-- args] Run agent CLI directly (login, config...)\n openacp agents refresh Force-refresh agent list from registry\n\n\\x1b[1mOptions:\\x1b[0m\n -h, --help Show this help message\n\n\\x1b[1mExamples:\\x1b[0m\n openacp agents install gemini Install Gemini CLI\n openacp agents run gemini Login to Google (first run)\n openacp agents info cursor See setup instructions\n\n\\x1b[2mRun 'openacp agents <command> --help' for more info on a subcommand.\\x1b[0m\n`)\n return;\n }\n\n switch (subcommand) {\n case \"install\":\n return agentsInstall(args[2], args.includes(\"--force\"), wantsHelp(args));\n case \"uninstall\":\n return agentsUninstall(args[2], wantsHelp(args));\n case \"refresh\":\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp agents refresh\\x1b[0m — Force-refresh agent list from registry\n\n\\x1b[1mUsage:\\x1b[0m\n openacp agents refresh\n\nFetches the latest agent catalog from the ACP Registry,\nbypassing the normal staleness check.\n`)\n return;\n }\n return agentsRefresh();\n case \"info\":\n return agentsInfo(args[2], wantsHelp(args));\n case \"run\":\n return agentsRun(args[2], args.slice(3), wantsHelp(args));\n case \"list\":\n case undefined:\n return agentsList();\n default: {\n const { suggestMatch } = await import('../suggest.js');\n const agentSubcommands = [\"install\", \"uninstall\", \"refresh\", \"info\", \"run\", \"list\"];\n const suggestion = suggestMatch(subcommand, agentSubcommands);\n console.error(`Unknown agents command: ${subcommand}`);\n if (suggestion) console.error(`Did you mean: ${suggestion}?`);\n console.error(`\\nRun 'openacp agents' to see available agents.`);\n process.exit(1);\n }\n }\n}\n\nasync function agentsList(): Promise<void> {\n const { AgentCatalog } = await import(\"../../core/agents/agent-catalog.js\");\n const catalog = new AgentCatalog();\n catalog.load();\n await catalog.refreshRegistryIfStale();\n\n const items = catalog.getAvailable();\n const installed = items.filter((i) => i.installed);\n const available = items.filter((i) => !i.installed);\n\n console.log(\"\");\n if (installed.length > 0) {\n console.log(\" \\x1b[1mInstalled agents:\\x1b[0m\\n\");\n for (const item of installed) {\n const deps = item.missingDeps?.length\n ? ` \\x1b[33m(needs: ${item.missingDeps.join(\", \")})\\x1b[0m`\n : \"\";\n console.log(\n ` \\x1b[32m✓\\x1b[0m ${item.key.padEnd(18)} ${item.name.padEnd(22)} v${item.version.padEnd(10)} ${item.distribution}${deps}`,\n );\n if (item.description) {\n console.log(` \\x1b[2m${item.description}\\x1b[0m`);\n }\n }\n console.log(\"\");\n }\n\n if (available.length > 0) {\n console.log(\" \\x1b[1mAvailable to install:\\x1b[0m\\n\");\n for (const item of available) {\n const icon = item.available ? \"\\x1b[2m⬇\\x1b[0m\" : \"\\x1b[33m⚠\\x1b[0m\";\n const deps = item.missingDeps?.length\n ? ` \\x1b[33m(needs: ${item.missingDeps.join(\", \")})\\x1b[0m`\n : \"\";\n console.log(\n ` ${icon} ${item.key.padEnd(18)} ${item.name.padEnd(22)} v${item.version.padEnd(10)} ${item.distribution}${deps}`,\n );\n if (item.description) {\n console.log(` \\x1b[2m${item.description}\\x1b[0m`);\n }\n }\n console.log(\"\");\n }\n\n console.log(\n ` \\x1b[2mInstall an agent: openacp agents install <name>\\x1b[0m`,\n );\n console.log(\"\");\n}\n\nasync function agentsInstall(nameOrId: string | undefined, force: boolean, help = false): Promise<void> {\n if (help || !nameOrId) {\n console.log(`\n\\x1b[1mopenacp agents install\\x1b[0m — Install an agent from the ACP Registry\n\n\\x1b[1mUsage:\\x1b[0m\n openacp agents install <name> [--force]\n\n\\x1b[1mArguments:\\x1b[0m\n <name> Agent name or ID (e.g. claude, gemini, copilot)\n\n\\x1b[1mOptions:\\x1b[0m\n --force Reinstall even if already installed\n -h, --help Show this help message\n\n\\x1b[1mExamples:\\x1b[0m\n openacp agents install claude\n openacp agents install gemini --force\n\nRun 'openacp agents' to see available agents.\n`)\n return;\n }\n\n const { AgentCatalog } = await import(\"../../core/agents/agent-catalog.js\");\n const catalog = new AgentCatalog();\n catalog.load();\n await catalog.refreshRegistryIfStale();\n\n const progress: import(\"../../core/types.js\").InstallProgress = {\n onStart(_id, name) {\n process.stdout.write(`\\n ⏳ Installing ${name}...\\n`);\n },\n onStep(step) {\n process.stdout.write(` \\x1b[32m✓\\x1b[0m ${step}\\n`);\n },\n onDownloadProgress(percent) {\n const filled = Math.round(percent / 5);\n const empty = 20 - filled;\n const bar = \"█\".repeat(filled) + \"░\".repeat(empty);\n process.stdout.write(`\\r ${bar} ${String(percent).padStart(3)}%`);\n if (percent >= 100) process.stdout.write(\"\\n\");\n },\n onSuccess(name) {\n console.log(`\\n \\x1b[32m✓ ${name} installed successfully!\\x1b[0m\\n`);\n },\n onError(error) {\n console.log(`\\n \\x1b[31m✗ ${error}\\x1b[0m\\n`);\n },\n };\n\n const result = await catalog.install(nameOrId, progress, force);\n if (!result.ok) {\n if (result.error?.includes('not found')) {\n const { suggestMatch } = await import('../suggest.js');\n const allKeys = catalog.getAvailable().map((a) => a.key);\n const suggestion = suggestMatch(nameOrId, allKeys);\n if (suggestion) console.log(` Did you mean: ${suggestion}?`);\n }\n process.exit(1);\n }\n\n // Auto-integrate handoff if agent supports it\n const { getAgentCapabilities } = await import(\"../../core/agents/agent-dependencies.js\");\n const caps = getAgentCapabilities(result.agentKey);\n if (caps.integration) {\n const { installIntegration } = await import(\"../integrate.js\");\n const intResult = await installIntegration(result.agentKey, caps.integration);\n if (intResult.success) {\n console.log(` \\x1b[32m✓\\x1b[0m Handoff integration installed for ${result.agentKey}`);\n } else {\n console.log(` \\x1b[33m⚠ Handoff integration failed: ${intResult.logs[intResult.logs.length - 1] ?? \"unknown error\"}\\x1b[0m`);\n }\n }\n\n // Show setup steps if any\n if (result.setupSteps?.length) {\n console.log(\" \\x1b[1mNext steps to get started:\\x1b[0m\\n\");\n for (const step of result.setupSteps) {\n console.log(` → ${step}`);\n }\n console.log(`\\n \\x1b[2mRun 'openacp agents info ${result.agentKey}' for more details.\\x1b[0m\\n`);\n }\n}\n\nasync function agentsUninstall(name: string | undefined, help = false): Promise<void> {\n if (help || !name) {\n console.log(`\n\\x1b[1mopenacp agents uninstall\\x1b[0m — Remove an installed agent\n\n\\x1b[1mUsage:\\x1b[0m\n openacp agents uninstall <name>\n\n\\x1b[1mArguments:\\x1b[0m\n <name> Agent name to remove\n\n\\x1b[1mExamples:\\x1b[0m\n openacp agents uninstall gemini\n`)\n return;\n }\n\n const { AgentCatalog } = await import(\"../../core/agents/agent-catalog.js\");\n const catalog = new AgentCatalog();\n catalog.load();\n\n const result = await catalog.uninstall(name);\n if (result.ok) {\n // Auto-uninstall handoff integration if exists\n const { getAgentCapabilities } = await import(\"../../core/agents/agent-dependencies.js\");\n const caps = getAgentCapabilities(name);\n if (caps.integration) {\n const { uninstallIntegration } = await import(\"../integrate.js\");\n await uninstallIntegration(name, caps.integration);\n console.log(` \\x1b[32m✓\\x1b[0m Handoff integration removed for ${name}`);\n }\n console.log(`\\n \\x1b[32m✓ ${name} removed.\\x1b[0m\\n`);\n } else {\n console.log(`\\n \\x1b[31m✗ ${result.error}\\x1b[0m`);\n if (result.error?.includes('not installed')) {\n const { suggestMatch } = await import('../suggest.js');\n const installedKeys = Object.keys(catalog.getInstalledEntries());\n const suggestion = suggestMatch(name, installedKeys);\n if (suggestion) console.log(` Did you mean: ${suggestion}?`);\n }\n console.log();\n }\n}\n\nasync function agentsRefresh(): Promise<void> {\n const { AgentCatalog } = await import(\"../../core/agents/agent-catalog.js\");\n const catalog = new AgentCatalog();\n catalog.load();\n console.log(\"\\n Updating agent list...\");\n await catalog.fetchRegistry();\n console.log(\" \\x1b[32m✓ Agent list updated.\\x1b[0m\\n\");\n}\n\nasync function agentsInfo(nameOrId: string | undefined, help = false): Promise<void> {\n if (help || !nameOrId) {\n console.log(`\n\\x1b[1mopenacp agents info\\x1b[0m — Show agent details, dependencies & setup guide\n\n\\x1b[1mUsage:\\x1b[0m\n openacp agents info <name>\n\n\\x1b[1mArguments:\\x1b[0m\n <name> Agent name or ID\n\nShows version, distribution type, command, setup steps, and\nwhether the agent is installed or available from the registry.\n\n\\x1b[1mExamples:\\x1b[0m\n openacp agents info claude\n openacp agents info cursor\n`)\n return;\n }\n\n const { AgentCatalog } = await import(\"../../core/agents/agent-catalog.js\");\n const catalog = new AgentCatalog();\n catalog.load();\n\n const { getAgentSetup } = await import(\"../../core/agents/agent-dependencies.js\");\n\n const installed = catalog.getInstalledAgent(nameOrId);\n if (installed) {\n console.log(`\\n \\x1b[1m${installed.name}\\x1b[0m`);\n console.log(` Version: ${installed.version}`);\n console.log(` Type: ${installed.distribution}`);\n console.log(` Command: ${installed.command} ${installed.args.join(\" \")}`);\n console.log(` Installed: ${new Date(installed.installedAt).toLocaleDateString()}`);\n if (installed.binaryPath) console.log(` Binary path: ${installed.binaryPath}`);\n\n const setup = installed.registryId ? getAgentSetup(installed.registryId) : undefined;\n if (setup) {\n console.log(`\\n \\x1b[1mSetup:\\x1b[0m`);\n for (const step of setup.setupSteps) {\n console.log(` → ${step}`);\n }\n }\n\n console.log(`\\n Run agent CLI: openacp agents run ${nameOrId} -- <args>`);\n console.log(\"\");\n return;\n }\n\n const regAgent = catalog.findRegistryAgent(nameOrId);\n if (regAgent) {\n const availability = catalog.checkAvailability(nameOrId);\n console.log(`\\n \\x1b[1m${regAgent.name}\\x1b[0m \\x1b[2m(not installed)\\x1b[0m`);\n console.log(` ${regAgent.description}`);\n console.log(` Version: ${regAgent.version}`);\n console.log(` License: ${regAgent.license ?? \"unknown\"}`);\n if (regAgent.website) console.log(` Website: ${regAgent.website}`);\n if (regAgent.repository) console.log(` Source: ${regAgent.repository}`);\n console.log(` Available: ${availability.available ? \"\\x1b[32mYes\\x1b[0m\" : `\\x1b[33mNo\\x1b[0m — ${availability.reason}`}`);\n\n const setup = getAgentSetup(regAgent.id);\n if (setup) {\n console.log(`\\n \\x1b[1mSetup after install:\\x1b[0m`);\n for (const step of setup.setupSteps) {\n console.log(` → ${step}`);\n }\n }\n\n console.log(`\\n Install: openacp agents install ${nameOrId}\\n`);\n return;\n }\n\n const { suggestMatch } = await import('../suggest.js');\n const allKeys = catalog.getAvailable().map((a) => a.key);\n const suggestion = suggestMatch(nameOrId, allKeys);\n console.log(`\\n \\x1b[31m\"${nameOrId}\" not found.\\x1b[0m`);\n if (suggestion) console.log(` Did you mean: ${suggestion}?`);\n console.log(` Run 'openacp agents' to see available agents.\\n`);\n}\n\nasync function agentsRun(nameOrId: string | undefined, extraArgs: string[], help = false): Promise<void> {\n if (help || !nameOrId) {\n console.log(`\n\\x1b[1mopenacp agents run\\x1b[0m — Run agent CLI directly\n\n\\x1b[1mUsage:\\x1b[0m\n openacp agents run <name> [-- <args>]\n\n\\x1b[1mArguments:\\x1b[0m\n <name> Installed agent name\n <args> Arguments to pass to the agent CLI\n\nUse \\x1b[1m--\\x1b[0m to separate OpenACP flags from agent arguments.\nACP-specific flags are automatically stripped.\n\n\\x1b[1mExamples:\\x1b[0m\n openacp agents run gemini Login to Google (first run)\n openacp agents run copilot Login to GitHub Copilot (first run)\n openacp agents run cline Setup API keys (first run)\n`)\n return;\n }\n\n const { AgentCatalog } = await import(\"../../core/agents/agent-catalog.js\");\n const catalog = new AgentCatalog();\n catalog.load();\n\n const installed = catalog.getInstalledAgent(nameOrId);\n if (!installed) {\n const { suggestMatch } = await import('../suggest.js');\n const installedKeys = Object.keys(catalog.getInstalledEntries());\n const suggestion = suggestMatch(nameOrId, installedKeys);\n console.log(`\\n \\x1b[31m\"${nameOrId}\" is not installed.\\x1b[0m`);\n if (suggestion) {\n console.log(` Did you mean: ${suggestion}?`);\n console.log(` Install first: openacp agents install ${suggestion}\\n`);\n } else {\n console.log(` Install first: openacp agents install ${nameOrId}\\n`);\n }\n return;\n }\n\n // Strip leading \"--\" separator if present\n const userArgs = extraArgs[0] === \"--\" ? extraArgs.slice(1) : extraArgs;\n\n const { spawnSync } = await import(\"node:child_process\");\n const command = installed.command;\n\n // Include agent's base args (e.g., package name for npx) but strip ACP-specific flags\n const acpFlags = new Set([\"--acp\", \"acp\", \"--acp=true\", \"--experimental-skills\"]);\n const baseArgs: string[] = [];\n for (let i = 0; i < installed.args.length; i++) {\n const arg = installed.args[i]!;\n // Skip standalone ACP flags\n if (acpFlags.has(arg)) continue;\n // Skip \"--output-format acp\" pair (factory-droid pattern)\n if (arg === \"--output-format\" && installed.args[i + 1] === \"acp\") { i++; continue; }\n // Skip \"exec\" subcommand used only in ACP mode (factory-droid)\n if (arg === \"exec\" && installed.args[i + 1] === \"--output-format\") continue;\n baseArgs.push(arg);\n }\n const fullArgs = [...baseArgs, ...userArgs];\n\n console.log(`\\n Running: ${command} ${fullArgs.join(\" \")}\\n`);\n\n const result = spawnSync(command, fullArgs, {\n stdio: \"inherit\",\n env: { ...process.env, ...installed.env },\n cwd: process.cwd(),\n });\n\n if (result.status !== null && result.status !== 0) {\n process.exit(result.status);\n }\n}\n","import { readApiPort, apiCall } from '../api-client.js'\n\nexport async function cmdTunnel(args: string[]): Promise<void> {\n const subCmd = args[1]\n const port = readApiPort()\n if (port === null) {\n console.error('OpenACP is not running. Start with `openacp start`')\n process.exit(1)\n }\n\n try {\n if (subCmd === 'add') {\n const tunnelPort = args[2]\n if (!tunnelPort) {\n console.error('Usage: openacp tunnel add <port> [--label name] [--session id]')\n process.exit(1)\n }\n const labelIdx = args.indexOf('--label')\n const label = labelIdx !== -1 ? args[labelIdx + 1] : undefined\n const sessionIdx = args.indexOf('--session')\n const sessionId = sessionIdx !== -1 ? args[sessionIdx + 1] : undefined\n\n const body: Record<string, unknown> = { port: parseInt(tunnelPort, 10) }\n if (label) body.label = label\n if (sessionId) body.sessionId = sessionId\n\n const res = await apiCall(port, '/api/tunnel', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log(`Tunnel active: port ${data.port} → ${data.publicUrl}`)\n\n } else if (subCmd === 'list') {\n const res = await apiCall(port, '/api/tunnel/list')\n const data = await res.json() as Array<Record<string, unknown>>\n if (data.length === 0) {\n console.log('No active tunnels.')\n return\n }\n console.log('Active tunnels:\\n')\n for (const t of data) {\n const label = t.label ? ` (${t.label})` : ''\n const status = t.status === 'active' ? '✅' : t.status === 'starting' ? '⏳' : '❌'\n console.log(` ${status} Port ${t.port}${label}`)\n if (t.publicUrl) console.log(` → ${t.publicUrl}`)\n }\n\n } else if (subCmd === 'stop') {\n const tunnelPort = args[2]\n if (!tunnelPort) {\n console.error('Usage: openacp tunnel stop <port>')\n process.exit(1)\n }\n const res = await apiCall(port, `/api/tunnel/${tunnelPort}`, { method: 'DELETE' })\n if (!res.ok) {\n const data = await res.json() as Record<string, unknown>\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log(`Tunnel stopped: port ${tunnelPort}`)\n\n } else if (subCmd === 'stop-all') {\n const res = await apiCall(port, '/api/tunnel', { method: 'DELETE' })\n if (!res.ok) {\n const data = await res.json() as Record<string, unknown>\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log('All user tunnels stopped.')\n\n } else {\n console.log(`\nTunnel Management:\n openacp tunnel add <port> [--label name] [--session id]\n openacp tunnel list\n openacp tunnel stop <port>\n openacp tunnel stop-all\n`)\n }\n } catch (err) {\n console.error(`Failed to connect to daemon: ${(err as Error).message}`)\n process.exit(1)\n }\n}\n","export async function cmdOnboard(): Promise<void> {\n const { ConfigManager, PLUGINS_DATA_DIR, REGISTRY_PATH } = await import('../../core/config/config.js')\n const { SettingsManager } = await import('../../core/plugin/settings-manager.js')\n const { PluginRegistry } = await import('../../core/plugin/plugin-registry.js')\n\n const cm = new ConfigManager()\n const settingsManager = new SettingsManager(PLUGINS_DATA_DIR)\n const pluginRegistry = new PluginRegistry(REGISTRY_PATH)\n await pluginRegistry.load()\n\n if (await cm.exists()) {\n const { runReconfigure } = await import('../../core/setup/index.js')\n await runReconfigure(cm)\n } else {\n const { runSetup } = await import('../../core/setup/index.js')\n await runSetup(cm, { skipRunMode: true, settingsManager, pluginRegistry })\n }\n}\n","import { checkAndPromptUpdate } from '../version.js'\nimport { printHelp } from './help.js'\nimport path from 'node:path'\nimport os from 'node:os'\n\nconst OPENACP_DIR = path.join(os.homedir(), '.openacp')\nconst PLUGINS_DATA_DIR = path.join(OPENACP_DIR, 'plugins', 'data')\nconst REGISTRY_PATH = path.join(OPENACP_DIR, 'plugins.json')\n\nexport async function cmdDefault(command: string | undefined): Promise<void> {\n const forceForeground = command === '--foreground'\n\n // Reject unknown commands\n if (command && !command.startsWith('-')) {\n const { suggestMatch } = await import('../suggest.js')\n const topLevelCommands = [\n 'start', 'stop', 'status', 'logs', 'config', 'reset', 'update',\n 'install', 'uninstall', 'plugins', 'plugin', 'api', 'adopt', 'integrate', 'doctor', 'agents', 'onboard',\n ]\n const suggestion = suggestMatch(command, topLevelCommands)\n console.error(`Unknown command: ${command}`)\n if (suggestion) console.error(`Did you mean: ${suggestion}?`)\n printHelp()\n process.exit(1)\n }\n\n await checkAndPromptUpdate()\n\n const { ConfigManager } = await import('../../core/config/config.js')\n const cm = new ConfigManager()\n\n // If no config, run setup first\n if (!(await cm.exists())) {\n const { SettingsManager } = await import('../../core/plugin/settings-manager.js')\n const { PluginRegistry } = await import('../../core/plugin/plugin-registry.js')\n const settingsManager = new SettingsManager(PLUGINS_DATA_DIR)\n const pluginRegistry = new PluginRegistry(REGISTRY_PATH)\n await pluginRegistry.load()\n\n const { runSetup } = await import('../../core/setup/index.js')\n const shouldStart = await runSetup(cm, { settingsManager, pluginRegistry })\n if (!shouldStart) process.exit(0)\n }\n\n await cm.load()\n const config = cm.get()\n\n if (!forceForeground && config.runMode === 'daemon') {\n const { startDaemon, getPidPath } = await import('../daemon.js')\n const result = startDaemon(getPidPath(), config.logging.logDir)\n if ('error' in result) {\n console.error(result.error)\n process.exit(1)\n }\n console.log(`OpenACP daemon started (PID ${result.pid})`)\n return\n }\n\n const { markRunning } = await import('../daemon.js')\n markRunning()\n const { startServer } = await import('../../main.js')\n await startServer()\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport { wantsHelp } from './helpers.js'\n\nexport async function cmdDev(args: string[] = []): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp dev\\x1b[0m — Run OpenACP with a local plugin in development mode\n\n\\x1b[1mUsage:\\x1b[0m\n openacp dev <plugin-path> [options]\n\n\\x1b[1mOptions:\\x1b[0m\n --no-watch Disable file watching (no hot-reload)\n --verbose Enable verbose logging\n\n\\x1b[1mExamples:\\x1b[0m\n openacp dev ./my-plugin\n openacp dev ../adapter-matrix --no-watch\n openacp dev ./my-plugin --verbose\n`)\n return\n }\n\n // Parse args: first non-flag arg after 'dev' is plugin path\n const pluginPathArg = args.slice(1).find(a => !a.startsWith('--'))\n const noWatch = args.includes('--no-watch')\n const verbose = args.includes('--verbose')\n\n if (!pluginPathArg) {\n console.error('Error: missing plugin path. Usage: openacp dev <plugin-path>')\n process.exit(1)\n }\n\n const pluginPath = path.resolve(pluginPathArg)\n\n if (!fs.existsSync(pluginPath)) {\n console.error(`Error: plugin path does not exist: ${pluginPath}`)\n process.exit(1)\n }\n\n const tsconfigPath = path.join(pluginPath, 'tsconfig.json')\n const hasTsconfig = fs.existsSync(tsconfigPath)\n\n // Initial TypeScript compile if tsconfig exists\n if (hasTsconfig) {\n console.log('Compiling plugin TypeScript...')\n const { execSync } = await import('node:child_process')\n try {\n execSync('npx tsc', { cwd: pluginPath, stdio: 'inherit' })\n console.log('Compilation complete.')\n } catch {\n console.error('TypeScript compilation failed. Fix errors and try again.')\n process.exit(1)\n }\n\n // Start tsc --watch in background if watching is enabled\n if (!noWatch) {\n const { spawn } = await import('node:child_process')\n const tscWatch = spawn('npx', ['tsc', '--watch', '--preserveWatchOutput'], {\n cwd: pluginPath,\n stdio: verbose ? 'inherit' : 'ignore',\n })\n tscWatch.unref()\n\n process.on('exit', () => {\n try { tscWatch.kill() } catch { /* ignore */ }\n })\n\n if (verbose) {\n console.log('Started tsc --watch for plugin')\n }\n }\n }\n\n // Set dev environment variables\n process.env.OPENACP_DEV_PLUGIN_PATH = pluginPath\n process.env.OPENACP_DEV_NO_WATCH = noWatch ? '1' : ''\n if (verbose) {\n process.env.OPENACP_DEBUG = '1'\n }\n process.env.OPENACP_DEV_LOOP = '1'\n\n // Start the server with dev plugin support\n const { startServer } = await import('../../main.js')\n await startServer({ devPluginPath: pluginPath, noWatch })\n}\n"],"mappings":"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","names":["getCurrentVersion","args","args","execSync","fs","path","args","execSync","args","os","path","getCurrentVersion","compareVersions","fs","args","args","args","args","args","args","port","ConfigManager","cm","args","fs","os","path","args","args","apiCall","args","args","args","command","args","PLUGINS_DATA_DIR","REGISTRY_PATH","path","command","fs","path","args","path","fs","execSync"]}
1
+ {"version":3,"sources":["../../src/cli/version.ts","../../src/core/plugin/plugin-registry.ts","../../src/core/plugin/registry-client.ts","../../src/cli/commands/plugin-search.ts","../../src/cli/plugin-template/package-json.ts","../../src/cli/plugin-template/tsconfig.ts","../../src/cli/plugin-template/dotfiles.ts","../../src/cli/plugin-template/readme.ts","../../src/cli/plugin-template/plugin-source.ts","../../src/cli/plugin-template/plugin-test.ts","../../src/cli/plugin-template/claude-md.ts","../../src/cli/plugin-template/plugin-guide.ts","../../src/cli/plugin-template/index.ts","../../src/cli/commands/plugin-create.ts","../../src/plugins/security/security-guard.ts","../../src/plugins/security/index.ts","../../src/core/utils/read-text-file.ts","../../src/plugins/file-service/file-service.ts","../../src/plugins/file-service/index.ts","../../src/plugins/context/context-cache.ts","../../src/plugins/context/context-manager.ts","../../src/plugins/context/context-provider.ts","../../src/plugins/context/entire/checkpoint-reader.ts","../../src/plugins/context/entire/message-cleaner.ts","../../src/plugins/context/entire/conversation-builder.ts","../../src/plugins/context/entire/entire-provider.ts","../../src/plugins/context/history/history-context-builder.ts","../../src/plugins/context/history/history-provider.ts","../../src/plugins/context/history/history-recorder.ts","../../src/plugins/context/history/history-store.ts","../../src/plugins/context/index.ts","../../src/plugins/speech/speech-service.ts","../../src/plugins/speech/providers/groq.ts","../../src/plugins/speech/exports.ts","../../src/core/plugin/plugin-installer.ts","../../src/plugins/speech/index.ts","../../src/plugins/notifications/notification.ts","../../src/plugins/notifications/index.ts","../../src/core/utils/log.ts","../../src/core/agents/agent-dependencies.ts","../../src/core/utils/install-binary.ts","../../src/plugins/tunnel/providers/install-cloudflared.ts","../../src/plugins/tunnel/providers/cloudflare.ts","../../src/plugins/tunnel/providers/ngrok.ts","../../src/plugins/tunnel/providers/bore.ts","../../src/plugins/tunnel/providers/tailscale.ts","../../src/plugins/tunnel/tunnel-registry.ts","../../src/plugins/tunnel/viewer-store.ts","../../src/plugins/tunnel/templates/file-viewer.ts","../../src/plugins/tunnel/templates/diff-viewer.ts","../../src/plugins/tunnel/templates/output-viewer.ts","../../src/plugins/tunnel/server.ts","../../src/plugins/tunnel/tunnel-service.ts","../../src/plugins/tunnel/index.ts","../../src/plugins/api-server/sse-manager.ts","../../src/plugins/api-server/static-server.ts","../../src/plugins/api-server/router.ts","../../src/plugins/api-server/routes/health.ts","../../src/plugins/api-server/routes/sessions.ts","../../src/core/instance-context.ts","../../src/core/config/config-registry.ts","../../src/core/config/config-migrations.ts","../../src/core/config/config.ts","../../src/plugins/api-server/routes/config.ts","../../src/plugins/api-server/routes/topics.ts","../../src/plugins/api-server/routes/tunnel.ts","../../src/core/agents/agent-registry.ts","../../src/plugins/api-server/routes/agents.ts","../../src/plugins/api-server/routes/notify.ts","../../src/plugins/api-server/api-server.ts","../../src/plugins/api-server/index.ts","../../src/plugins/telegram/validators.ts","../../src/plugins/telegram/topics.ts","../../src/core/adapter-primitives/format-types.ts","../../src/core/adapter-primitives/format-utils.ts","../../src/core/adapter-primitives/message-formatter.ts","../../src/plugins/telegram/formatting.ts","../../src/plugins/telegram/commands/admin.ts","../../src/plugins/telegram/commands/new-session.ts","../../src/plugins/telegram/commands/session.ts","../../src/plugins/telegram/commands/menu.ts","../../src/cli/integrate.ts","../../src/plugins/telegram/commands/agents.ts","../../src/plugins/telegram/commands/integrate.ts","../../src/plugins/telegram/commands/resume.ts","../../src/plugins/telegram/commands/settings.ts","../../src/core/doctor/checks/config.ts","../../src/core/doctor/checks/agents.ts","../../src/core/doctor/checks/telegram.ts","../../src/core/doctor/checks/storage.ts","../../src/core/doctor/checks/workspace.ts","../../src/core/doctor/checks/plugins.ts","../../src/core/doctor/checks/daemon.ts","../../src/core/doctor/checks/tunnel.ts","../../src/core/doctor/index.ts","../../src/plugins/telegram/commands/doctor.ts","../../src/plugins/telegram/commands/tunnel.ts","../../src/plugins/telegram/commands/switch.ts","../../src/plugins/telegram/commands/index.ts","../../src/plugins/telegram/permissions.ts","../../src/data/product-guide.ts","../../src/plugins/telegram/assistant.ts","../../src/core/adapter-primitives/primitives/tool-card-state.ts","../../src/core/adapter-primitives/stream-accumulator.ts","../../src/core/adapter-primitives/display-spec-builder.ts","../../src/plugins/telegram/activity.ts","../../src/core/adapter-primitives/primitives/send-queue.ts","../../src/plugins/telegram/action-detect.ts","../../src/plugins/telegram/streaming.ts","../../src/plugins/telegram/draft-manager.ts","../../src/plugins/telegram/skill-command-manager.ts","../../src/core/adapter-primitives/messaging-adapter.ts","../../src/core/adapter-primitives/rendering/renderer.ts","../../src/plugins/telegram/renderer.ts","../../src/core/adapter-primitives/output-mode-resolver.ts","../../src/plugins/telegram/adapter.ts","../../src/plugins/telegram/index.ts","../../src/plugins/core-plugins.ts","../../src/core/plugin/settings-manager.ts","../../src/core/plugin/terminal-io.ts","../../src/core/plugin/install-context.ts","../../src/cli/api-client.ts","../../src/cli/suggest.ts","../../src/cli/daemon.ts","../../src/core/instance-registry.ts","../../src/cli/autostart.ts","../../src/core/config/config-editor.ts","../../src/core/agents/agent-store.ts","../../src/core/agents/agent-installer.ts","../../src/core/agents/agent-catalog.ts","../../src/core/setup/types.ts","../../src/core/setup/helpers.ts","../../src/core/setup/setup-agents.ts","../../src/core/setup/setup-workspace.ts","../../src/core/setup/setup-run-mode.ts","../../src/core/setup/setup-integrations.ts","../../src/core/setup/setup-channels.ts","../../src/core/instance-copy.ts","../../src/core/setup/wizard.ts","../../src/core/setup/index.ts","../../src/core/utils/streams.ts","../../src/core/utils/stderr-capture.ts","../../src/core/utils/typed-emitter.ts","../../src/core/sessions/terminal-manager.ts","../../src/core/agents/mcp-manager.ts","../../src/core/utils/debug-tracer.ts","../../src/core/agents/agent-instance.ts","../../src/core/agents/agent-manager.ts","../../src/core/sessions/prompt-queue.ts","../../src/core/sessions/permission-gate.ts","../../src/core/sessions/session.ts","../../src/core/sessions/session-manager.ts","../../src/core/sessions/session-bridge.ts","../../src/core/utils/extract-file-info.ts","../../src/core/message-transformer.ts","../../src/core/sessions/session-store.ts","../../src/core/sessions/session-factory.ts","../../src/core/event-bus.ts","../../src/core/plugin/plugin-loader.ts","../../src/core/plugin/service-registry.ts","../../src/core/plugin/middleware-chain.ts","../../src/core/plugin/error-tracker.ts","../../src/core/plugin/plugin-storage.ts","../../src/core/plugin/plugin-context.ts","../../src/core/plugin/lifecycle-manager.ts","../../src/core/core.ts","../../src/core/command-registry.ts","../../src/core/commands/session.ts","../../src/core/commands/agents.ts","../../src/core/commands/admin.ts","../../src/core/commands/help.ts","../../src/core/commands/menu.ts","../../src/core/commands/switch.ts","../../src/core/commands/index.ts","../../src/core/utils/install-jq.ts","../../src/cli/post-upgrade.ts","../../src/core/plugin/dev-loader.ts","../../src/main.ts","../../src/cli.ts","../../src/cli/commands/help.ts","../../src/cli/commands/version.ts","../../src/cli/commands/install.ts","../../src/cli/commands/helpers.ts","../../src/cli/commands/uninstall.ts","../../src/cli/commands/plugins.ts","../../src/cli/commands/api.ts","../../src/cli/commands/start.ts","../../src/cli/commands/stop.ts","../../src/cli/commands/restart.ts","../../src/cli/commands/status.ts","../../src/cli/commands/logs.ts","../../src/cli/commands/config.ts","../../src/cli/commands/reset.ts","../../src/cli/commands/update.ts","../../src/cli/commands/adopt.ts","../../src/cli/commands/integrate.ts","../../src/cli/commands/doctor.ts","../../src/cli/commands/agents.ts","../../src/cli/commands/tunnel.ts","../../src/cli/commands/onboard.ts","../../src/cli/commands/default.ts","../../src/cli/commands/dev.ts"],"sourcesContent":["import { fileURLToPath } from 'node:url'\nimport { dirname, join, resolve } from 'node:path'\nimport { existsSync, readFileSync } from 'node:fs'\n\nconst NPM_PACKAGE = '@openacp/cli'\n\nfunction findPackageJson(): string | null {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (let i = 0; i < 5; i++) {\n const candidate = join(dir, 'package.json')\n if (existsSync(candidate)) return candidate\n const parent = resolve(dir, '..')\n if (parent === dir) break\n dir = parent\n }\n return null\n}\n\nexport function getCurrentVersion(): string {\n try {\n const pkgPath = findPackageJson()\n if (!pkgPath) return '0.0.0-dev'\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'))\n return pkg.version as string\n } catch {\n return '0.0.0-dev'\n }\n}\n\nexport async function getLatestVersion(): Promise<string | null> {\n try {\n const res = await fetch(`https://registry.npmjs.org/${NPM_PACKAGE}/latest`, {\n signal: AbortSignal.timeout(5000),\n })\n if (!res.ok) return null\n const data = (await res.json()) as { version?: string }\n return data.version ?? null\n } catch {\n return null\n }\n}\n\nexport function compareVersions(current: string, latest: string): -1 | 0 | 1 {\n const a = current.split('.').map(Number)\n const b = latest.split('.').map(Number)\n for (let i = 0; i < 3; i++) {\n if ((a[i] ?? 0) < (b[i] ?? 0)) return -1\n if ((a[i] ?? 0) > (b[i] ?? 0)) return 1\n }\n return 0\n}\n\nexport async function runUpdate(): Promise<boolean> {\n const { spawn } = await import('node:child_process')\n return new Promise((resolve) => {\n const child = spawn('npm', ['install', '-g', `${NPM_PACKAGE}@latest`], {\n stdio: 'inherit',\n shell: true,\n })\n const onSignal = () => {\n child.kill('SIGTERM')\n resolve(false)\n }\n process.on('SIGINT', onSignal)\n process.on('SIGTERM', onSignal)\n child.on('close', (code) => {\n process.off('SIGINT', onSignal)\n process.off('SIGTERM', onSignal)\n resolve(code === 0)\n })\n })\n}\n\nexport async function checkAndPromptUpdate(): Promise<void> {\n if (process.env.OPENACP_DEV_LOOP || process.env.OPENACP_SKIP_UPDATE_CHECK) return\n\n const current = getCurrentVersion()\n if (current === '0.0.0-dev') return\n\n const latest = await getLatestVersion()\n if (!latest || compareVersions(current, latest) >= 0) return\n\n console.log(`\\x1b[33mUpdate available: v${current} → v${latest}\\x1b[0m`)\n const clack = await import('@clack/prompts')\n const yes = await clack.confirm({\n message: 'Update now before starting?',\n })\n if (clack.isCancel(yes) || !yes) {\n return\n }\n const ok = await runUpdate()\n if (ok) {\n console.log(`\\x1b[32m✓ Updated to v${latest}. Please re-run your command.\\x1b[0m`)\n process.exit(0)\n } else {\n console.error('\\x1b[31mUpdate failed. Continuing with current version.\\x1b[0m')\n }\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\n\nexport interface PluginEntry {\n version: string\n installedAt: string\n updatedAt: string\n source: 'builtin' | 'npm' | 'local'\n enabled: boolean\n settingsPath: string\n description?: string\n}\n\ntype RegisterInput = Omit<PluginEntry, 'installedAt' | 'updatedAt'>\n\ninterface RegistryData {\n installed: Record<string, PluginEntry>\n}\n\nexport class PluginRegistry {\n private data: RegistryData = { installed: {} }\n\n constructor(private registryPath: string) {}\n\n list(): Map<string, PluginEntry> {\n return new Map(Object.entries(this.data.installed))\n }\n\n get(name: string): PluginEntry | undefined {\n return this.data.installed[name]\n }\n\n register(name: string, entry: RegisterInput): void {\n const now = new Date().toISOString()\n this.data.installed[name] = { ...entry, installedAt: now, updatedAt: now }\n }\n\n remove(name: string): void {\n delete this.data.installed[name]\n }\n\n setEnabled(name: string, enabled: boolean): void {\n const entry = this.data.installed[name]\n if (!entry) return\n entry.enabled = enabled\n entry.updatedAt = new Date().toISOString()\n }\n\n updateVersion(name: string, version: string): void {\n const entry = this.data.installed[name]\n if (!entry) return\n entry.version = version\n entry.updatedAt = new Date().toISOString()\n }\n\n listEnabled(): Map<string, PluginEntry> {\n return new Map(Object.entries(this.data.installed).filter(([, e]) => e.enabled))\n }\n\n listBySource(source: PluginEntry['source']): Map<string, PluginEntry> {\n return new Map(Object.entries(this.data.installed).filter(([, e]) => e.source === source))\n }\n\n async load(): Promise<void> {\n try {\n const content = fs.readFileSync(this.registryPath, 'utf-8')\n const parsed = JSON.parse(content)\n if (parsed && typeof parsed.installed === 'object') {\n this.data = parsed\n }\n } catch {\n this.data = { installed: {} }\n }\n }\n\n async save(): Promise<void> {\n const dir = path.dirname(this.registryPath)\n fs.mkdirSync(dir, { recursive: true })\n fs.writeFileSync(this.registryPath, JSON.stringify(this.data, null, 2))\n }\n}\n","const REGISTRY_URL = 'https://raw.githubusercontent.com/Open-ACP/plugin-registry/main/registry.json'\nconst CACHE_TTL = 60 * 1000 // 1 minute\n\nexport interface RegistryPlugin {\n name: string\n displayName?: string\n description: string\n npm: string\n version: string\n minCliVersion: string\n category: string\n tags: string[]\n icon: string\n author: string\n repository: string\n license: string\n verified: boolean\n featured: boolean\n}\n\nexport interface Registry {\n version: number\n generatedAt: string\n pluginCount: number\n plugins: RegistryPlugin[]\n categories: Array<{ id: string; name: string; icon: string }>\n}\n\nexport class RegistryClient {\n private cache: { data: Registry; fetchedAt: number } | null = null\n private registryUrl: string\n\n constructor(registryUrl?: string) {\n this.registryUrl = registryUrl ?? REGISTRY_URL\n }\n\n async getRegistry(): Promise<Registry> {\n if (this.cache && Date.now() - this.cache.fetchedAt < CACHE_TTL) {\n return this.cache.data\n }\n const res = await fetch(this.registryUrl)\n if (!res.ok) throw new Error(`Failed to fetch registry: ${res.status}`)\n const data = await res.json() as Registry\n this.cache = { data, fetchedAt: Date.now() }\n return data\n }\n\n async search(query: string): Promise<RegistryPlugin[]> {\n const registry = await this.getRegistry()\n const q = query.toLowerCase()\n return registry.plugins.filter(p => {\n const text = `${p.name} ${p.displayName ?? ''} ${p.description} ${p.tags?.join(' ') ?? ''}`.toLowerCase()\n return text.includes(q)\n })\n }\n\n async resolve(name: string): Promise<string | null> {\n const registry = await this.getRegistry()\n const plugin = registry.plugins.find(p => p.name === name)\n return plugin?.npm ?? null\n }\n\n clearCache(): void {\n this.cache = null\n }\n}\n","import { RegistryClient } from '../../core/plugin/registry-client.js'\n\nexport async function cmdPluginSearch(args: string[]): Promise<void> {\n const query = args.join(' ').trim()\n if (!query) {\n console.error('Usage: openacp plugin search <query>')\n process.exit(1)\n }\n\n const client = new RegistryClient()\n\n try {\n const results = await client.search(query)\n\n if (results.length === 0) {\n console.log(`No plugins found matching \"${query}\"`)\n return\n }\n\n console.log(`\\nFound ${results.length} plugin${results.length > 1 ? 's' : ''} matching \"${query}\":\\n`)\n for (const p of results) {\n const verified = p.verified ? ' ✓' : ''\n const featured = p.featured ? ' ⭐' : ''\n console.log(` ${p.icon || '📦'} ${p.displayName ?? p.name}${verified}${featured}`)\n console.log(` ${p.description}`)\n console.log(` ${p.category} | v${p.version} | npm: ${p.npm}`)\n console.log(` Install: openacp plugin install ${p.name}`)\n console.log()\n }\n } catch (err) {\n console.error(`Failed to search registry: ${err}`)\n process.exit(1)\n }\n}\n","export interface TemplateParams {\n pluginName: string\n description: string\n author: string\n license: string\n cliVersion: string\n}\n\nexport function generatePackageJson(params: TemplateParams): string {\n const packageJson = {\n name: params.pluginName,\n version: '0.1.0',\n description: params.description || '',\n type: 'module',\n main: 'dist/index.js',\n types: 'dist/index.d.ts',\n scripts: {\n build: 'tsc',\n dev: 'tsc --watch',\n test: 'vitest',\n prepublishOnly: 'npm run build',\n },\n author: params.author || '',\n license: params.license,\n keywords: ['openacp', 'openacp-plugin'],\n engines: {\n openacp: `>=${params.cliVersion}`,\n },\n peerDependencies: {\n '@openacp/cli': `>=${params.cliVersion}`,\n },\n devDependencies: {\n '@openacp/plugin-sdk': params.cliVersion,\n typescript: '^5.4.0',\n vitest: '^3.0.0',\n },\n }\n return JSON.stringify(packageJson, null, 2) + '\\n'\n}\n","export function generateTsconfig(): string {\n const tsconfig = {\n compilerOptions: {\n target: 'ES2022',\n module: 'NodeNext',\n moduleResolution: 'NodeNext',\n declaration: true,\n outDir: 'dist',\n rootDir: 'src',\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n forceConsistentCasingInFileNames: true,\n },\n include: ['src'],\n exclude: ['node_modules', 'dist', 'src/**/__tests__'],\n }\n return JSON.stringify(tsconfig, null, 2) + '\\n'\n}\n","export function generateGitignore(): string {\n return ['node_modules/', 'dist/', '*.tsbuildinfo', '.DS_Store', ''].join('\\n')\n}\n\nexport function generateNpmignore(): string {\n return ['src/', 'tsconfig.json', '.editorconfig', '.gitignore', '*.test.ts', '__tests__/', ''].join('\\n')\n}\n\nexport function generateEditorconfig(): string {\n return [\n 'root = true',\n '',\n '[*]',\n 'indent_style = space',\n 'indent_size = 2',\n 'end_of_line = lf',\n 'charset = utf-8',\n 'trim_trailing_whitespace = true',\n 'insert_final_newline = true',\n '',\n ].join('\\n')\n}\n","import type { TemplateParams } from './package-json.js'\n\nexport function generateReadme(params: TemplateParams): string {\n return [\n `# ${params.pluginName}`,\n '',\n params.description || 'An OpenACP plugin.',\n '',\n '## Installation',\n '',\n '```bash',\n `openacp plugin add ${params.pluginName}`,\n '```',\n '',\n '## Development',\n '',\n '```bash',\n 'npm install',\n 'npm run build',\n 'npm test',\n '',\n '# Live development with hot-reload:',\n `openacp dev .`,\n '```',\n '',\n '## License',\n '',\n params.license,\n '',\n ].join('\\n')\n}\n","import type { TemplateParams } from './package-json.js'\n\nexport function generatePluginSource(params: TemplateParams): string {\n const dirName = params.pluginName.replace(/^@[^/]+\\//, '')\n const escapedDescription = (params.description || '').replace(/'/g, \"\\\\'\")\n\n return `import type { OpenACPPlugin, PluginContext, InstallContext, MigrateContext } from '@openacp/plugin-sdk'\n\nconst plugin: OpenACPPlugin = {\n name: '${params.pluginName}',\n version: '0.1.0',\n description: '${escapedDescription}',\n\n // Declare which permissions your plugin needs.\n // Available: events:read, events:emit, services:register, services:use,\n // middleware:register, commands:register, storage:read, storage:write, kernel:access\n permissions: ['events:read', 'services:register'],\n\n // Dependencies on other plugins (loaded before this one).\n // pluginDependencies: { '@openacp/security': '>=1.0.0' },\n\n // Optional dependencies (used if available, gracefully degrade if not).\n // optionalPluginDependencies: { '@openacp/usage': '>=1.0.0' },\n\n /**\n * Called during server startup in dependency order.\n * Register services, middleware, commands, and event listeners here.\n */\n async setup(ctx: PluginContext): Promise<void> {\n ctx.log.info('Plugin setup started')\n\n // Example: register a service\n // ctx.registerService('my-service', myServiceImpl)\n\n // Example: listen to events\n // ctx.on('session:created', (event) => { ... })\n\n // Example: register a slash command\n // ctx.registerCommand({\n // name: 'mycommand',\n // description: 'Does something useful',\n // category: 'plugin',\n // async handler(args) {\n // return { type: 'text', text: 'Hello from ${params.pluginName}!' }\n // },\n // })\n\n ctx.log.info('Plugin setup complete')\n },\n\n /**\n * Called during server shutdown in reverse dependency order.\n * Clean up resources, close connections, stop timers here.\n * Has a 10-second timeout.\n */\n async teardown(): Promise<void> {\n // Clean up resources here\n },\n\n /**\n * Called when user runs \\`openacp plugin add ${params.pluginName}\\`.\n * Use ctx.terminal for interactive prompts to gather configuration.\n */\n async install(ctx: InstallContext): Promise<void> {\n ctx.terminal.log.info('Installing ${params.pluginName}...')\n\n // Example: prompt for configuration\n // const apiKey = await ctx.terminal.text({\n // message: 'Enter your API key',\n // validate: (v) => v.length === 0 ? 'Required' : undefined,\n // })\n // await ctx.settings.set('apiKey', apiKey)\n\n ctx.terminal.log.success('Installation complete!')\n },\n\n /**\n * Called when user runs \\`openacp plugin configure ${params.pluginName}\\`.\n * Re-run configuration prompts to update settings.\n */\n async configure(ctx: InstallContext): Promise<void> {\n ctx.terminal.log.info('Configuring ${params.pluginName}...')\n\n // Re-run configuration prompts, pre-filling with current values\n // const current = await ctx.settings.getAll()\n // ...\n\n ctx.terminal.log.success('Configuration updated!')\n },\n\n /**\n * Called during boot when the plugin version has changed.\n * Migrate settings from the old format to the new format.\n */\n async migrate(ctx: MigrateContext, oldSettings: unknown, oldVersion: string): Promise<unknown> {\n ctx.log.info(\\`Migrating from v\\${oldVersion}\\`)\n // Return the migrated settings object\n return oldSettings\n },\n\n /**\n * Called when user runs \\`openacp plugin remove ${params.pluginName}\\`.\n * Clean up any external resources. If opts.purge is true, delete all data.\n */\n async uninstall(ctx: InstallContext, opts: { purge: boolean }): Promise<void> {\n ctx.terminal.log.info('Uninstalling ${params.pluginName}...')\n if (opts.purge) {\n await ctx.settings.clear()\n }\n ctx.terminal.log.success('Uninstalled!')\n },\n}\n\nexport default plugin\n`\n}\n","import type { TemplateParams } from './package-json.js'\n\nexport function generatePluginTest(params: TemplateParams): string {\n return `import { describe, it, expect } from 'vitest'\nimport { createTestContext, createTestInstallContext } from '@openacp/plugin-sdk/testing'\nimport plugin from '../index.js'\n\ndescribe('${params.pluginName}', () => {\n it('has correct metadata', () => {\n expect(plugin.name).toBe('${params.pluginName}')\n expect(plugin.version).toBeDefined()\n expect(plugin.setup).toBeInstanceOf(Function)\n })\n\n it('sets up without errors', async () => {\n const ctx = createTestContext({\n pluginName: '${params.pluginName}',\n pluginConfig: { enabled: true },\n permissions: plugin.permissions,\n })\n await expect(plugin.setup(ctx)).resolves.not.toThrow()\n })\n\n it('tears down without errors', async () => {\n if (plugin.teardown) {\n await expect(plugin.teardown()).resolves.not.toThrow()\n }\n })\n\n it('installs without errors', async () => {\n if (plugin.install) {\n const ctx = createTestInstallContext({\n pluginName: '${params.pluginName}',\n terminalResponses: { password: [''], confirm: [true], select: ['apiKey'] },\n })\n await expect(plugin.install(ctx)).resolves.not.toThrow()\n }\n })\n})\n`\n}\n","import type { TemplateParams } from './package-json.js'\n\nexport function generateClaudeMd(params: TemplateParams): string {\n return `# CLAUDE.md\n\nThis file provides context for AI coding agents (Claude, Cursor, etc.) working on this plugin.\n\n## What is OpenACP?\n\nOpenACP is an open-source platform that bridges AI coding agents (Claude Code, Codex, etc.) to messaging platforms (Telegram, Discord, Slack) and custom UIs via the Agent Client Protocol (ACP). It features a microkernel plugin architecture where all features — adapters, services, commands — are plugins.\n\n- **Website & Docs**: https://openacp.gitbook.io/docs\n- **GitHub**: https://github.com/Open-ACP/OpenACP\n- **Plugin Registry**: https://github.com/Open-ACP/plugin-registry\n\nKey documentation pages:\n- [Getting Started](https://openacp.gitbook.io/docs/getting-started) — What is OpenACP, quickstart\n- [Plugin Development](https://openacp.gitbook.io/docs/extending/building-plugins) — How to build plugins\n- [Architecture](https://openacp.gitbook.io/docs/extending/architecture) — System design, plugin lifecycle\n- [Dev Mode](https://openacp.gitbook.io/docs/extending/dev-mode) — Hot-reload development workflow\n- [CLI Commands](https://openacp.gitbook.io/docs/api-reference/cli-commands) — Full CLI reference\n- [Platform Setup](https://openacp.gitbook.io/docs/platform-setup) — Telegram, Discord, Slack guides\n- [Configuration](https://openacp.gitbook.io/docs/self-hosting/configuration) — Config and settings reference\n\n## Project Overview\n\nThis is an OpenACP plugin. Plugins extend OpenACP with new adapters, services, commands, and middleware.\n\n- **Package**: ${params.pluginName}\n- **SDK**: \\`@openacp/plugin-sdk\\` (types, base classes, testing utilities)\n- **Entry point**: \\`src/index.ts\\` (default export of \\`OpenACPPlugin\\` object)\n\n## Build & Run\n\n\\`\\`\\`bash\nnpm install # Install dependencies\nnpm run build # Compile TypeScript (tsc)\nnpm run dev # Watch mode (tsc --watch)\nnpm test # Run tests (vitest)\n\\`\\`\\`\n\n### Development with hot-reload\n\n\\`\\`\\`bash\nopenacp dev . # Compiles, watches, and reloads plugin on changes\n\\`\\`\\`\n\n## File Structure\n\n\\`\\`\\`\nsrc/\n index.ts — Plugin entry point (exports OpenACPPlugin)\n __tests__/\n index.test.ts — Tests using @openacp/plugin-sdk/testing\npackage.json — engines.openacp declares minimum CLI version\ntsconfig.json — ES2022, NodeNext, strict mode\nCLAUDE.md — This file (AI agent context)\nPLUGIN_GUIDE.md — Human-readable developer guide\n\\`\\`\\`\n\n## Architecture: How OpenACP Plugins Work\n\n### Plugin Lifecycle\n\n\\`\\`\\`\ninstall ──> [reboot] ──> migrate? ──> setup ──> [running] ──> teardown ──> uninstall\n\\`\\`\\`\n\n| Hook | Trigger | Interactive? | Has Services? |\n|------|---------|-------------|---------------|\n| \\`install(ctx)\\` | \\`openacp plugin add <name>\\` | Yes | No |\n| \\`migrate(ctx, oldSettings, oldVersion)\\` | Boot — stored version differs from plugin version | No | No |\n| \\`configure(ctx)\\` | \\`openacp plugin configure <name>\\` | Yes | No |\n| \\`setup(ctx)\\` | Every boot, after migrate | No | Yes |\n| \\`teardown()\\` | Shutdown (10s timeout) | No | Yes |\n| \\`uninstall(ctx, opts)\\` | \\`openacp plugin remove <name>\\` | Yes | No |\n\n### OpenACPPlugin Interface\n\n\\`\\`\\`typescript\ninterface OpenACPPlugin {\n name: string // unique identifier, e.g. '@myorg/my-plugin'\n version: string // semver\n description?: string\n permissions?: PluginPermission[]\n pluginDependencies?: Record<string, string> // name -> semver range\n optionalPluginDependencies?: Record<string, string> // used if available\n overrides?: string // replace a built-in plugin entirely\n settingsSchema?: ZodSchema // Zod validation for settings\n essential?: boolean // true = needs setup before system can run\n\n setup(ctx: PluginContext): Promise<void>\n teardown?(): Promise<void>\n install?(ctx: InstallContext): Promise<void>\n configure?(ctx: InstallContext): Promise<void>\n migrate?(ctx: MigrateContext, oldSettings: unknown, oldVersion: string): Promise<unknown>\n uninstall?(ctx: InstallContext, opts: { purge: boolean }): Promise<void>\n}\n\\`\\`\\`\n\n### PluginContext API (available in setup)\n\n\\`\\`\\`typescript\ninterface PluginContext {\n pluginName: string\n pluginConfig: Record<string, unknown> // from settings.json\n\n // Events (requires 'events:read' / 'events:emit')\n on(event: string, handler: (...args: unknown[]) => void): void\n off(event: string, handler: (...args: unknown[]) => void): void\n emit(event: string, payload: unknown): void\n\n // Services (requires 'services:register' / 'services:use')\n registerService<T>(name: string, implementation: T): void\n getService<T>(name: string): T | undefined\n\n // Middleware (requires 'middleware:register')\n registerMiddleware<H extends MiddlewareHook>(hook: H, opts: MiddlewareOptions<MiddlewarePayloadMap[H]>): void\n\n // Commands (requires 'commands:register')\n registerCommand(def: CommandDef): void\n\n // Storage (requires 'storage:read' / 'storage:write')\n storage: PluginStorage // get, set, delete, list, getDataDir\n\n // Messaging (requires 'services:use')\n sendMessage(sessionId: string, content: OutgoingMessage): Promise<void>\n\n // Kernel access (requires 'kernel:access')\n sessions: SessionManager\n config: ConfigManager\n eventBus: EventBus\n\n // Always available\n log: Logger // trace, debug, info, warn, error, fatal, child\n}\n\\`\\`\\`\n\n### CommandDef and CommandResponse\n\n\\`\\`\\`typescript\ninterface CommandDef {\n name: string // command name without slash\n description: string // shown in /help\n usage?: string // e.g. '<city>' or 'on|off'\n category: 'system' | 'plugin'\n handler(args: CommandArgs): Promise<CommandResponse | void>\n}\n\ninterface CommandArgs {\n raw: string // text after command name\n sessionId: string | null\n channelId: string // 'telegram', 'discord', 'slack'\n userId: string\n reply(content: string | CommandResponse): Promise<void>\n}\n\ntype CommandResponse =\n | { type: 'text'; text: string }\n | { type: 'menu'; title: string; options: MenuOption[] }\n | { type: 'list'; title: string; items: ListItem[] }\n | { type: 'confirm'; question: string; onYes: string; onNo: string }\n | { type: 'error'; message: string }\n | { type: 'silent' }\n\\`\\`\\`\n\n### Settings System\n\n- \\`settingsSchema\\`: Zod schema for validation\n- \\`SettingsAPI\\` (in InstallContext): get, set, getAll, setAll, delete, clear, has\n- Settings stored at \\`~/.openacp/plugins/@scope/name/settings.json\\`\n- \\`PluginStorage\\` (in PluginContext): key-value store at \\`~/.openacp/plugins/data/@scope/name/kv.json\\`\n- \\`storage.getDataDir()\\`: returns path for large files, databases, caches\n\n### InstallContext (for install/configure/uninstall)\n\n\\`\\`\\`typescript\ninterface InstallContext {\n pluginName: string\n terminal: TerminalIO // text, select, confirm, password, multiselect, log, spinner, note\n settings: SettingsAPI\n legacyConfig?: Record<string, unknown>\n dataDir: string\n log: Logger\n}\n\\`\\`\\`\n\n### Service Interfaces (available via ctx.getService)\n\n| Service name | Interface | Description |\n|---|---|---|\n| \\`security\\` | \\`SecurityService\\` | Access control, session limits, user roles |\n| \\`file-service\\` | \\`FileServiceInterface\\` | File saving, resolving, format conversion |\n| \\`notifications\\` | \\`NotificationService\\` | Send notifications to users |\n| \\`usage\\` | \\`UsageService\\` | Token/cost tracking and budget checking |\n| \\`speech\\` | \\`SpeechServiceInterface\\` | Text-to-speech and speech-to-text |\n| \\`tunnel\\` | \\`TunnelServiceInterface\\` | Port tunneling and public URL management |\n| \\`context\\` | \\`ContextService\\` | Context building for agent sessions |\n\n## Plugin Permissions\n\nDeclare in \\`permissions\\` array. Only request what you need.\n\n| Permission | Allows |\n|---|---|\n| \\`events:read\\` | \\`ctx.on()\\` — subscribe to events |\n| \\`events:emit\\` | \\`ctx.emit()\\` — emit custom events (must prefix with plugin name) |\n| \\`services:register\\` | \\`ctx.registerService()\\` — provide services to other plugins |\n| \\`services:use\\` | \\`ctx.getService()\\`, \\`ctx.sendMessage()\\` — consume services |\n| \\`middleware:register\\` | \\`ctx.registerMiddleware()\\` — intercept and modify flows |\n| \\`commands:register\\` | \\`ctx.registerCommand()\\` — add chat commands |\n| \\`storage:read\\` | \\`ctx.storage.get()\\`, \\`ctx.storage.list()\\` |\n| \\`storage:write\\` | \\`ctx.storage.set()\\`, \\`ctx.storage.delete()\\` |\n| \\`kernel:access\\` | \\`ctx.sessions\\`, \\`ctx.config\\`, \\`ctx.eventBus\\`, \\`ctx.core\\` |\n\nCalling a method without the required permission throws \\`PluginPermissionError\\`.\n\n## Middleware Hooks (20 total)\n\nRegister with \\`ctx.registerMiddleware(hook, { priority?, handler })\\`. Return \\`null\\` to block the flow, call \\`next()\\` to continue.\n\n### Message flow\n- \\`message:incoming\\` — incoming user message (channelId, threadId, userId, text, attachments)\n- \\`message:outgoing\\` — outgoing message to user (sessionId, message)\n\n### Agent flow\n- \\`agent:beforePrompt\\` — before prompt is sent to agent (sessionId, text, attachments)\n- \\`agent:beforeEvent\\` — before agent event is processed (sessionId, event)\n- \\`agent:afterEvent\\` — after agent event, before delivery (sessionId, event, outgoingMessage)\n\n### Turn lifecycle\n- \\`turn:start\\` — agent turn begins (sessionId, promptText, promptNumber)\n- \\`turn:end\\` — agent turn ends (sessionId, stopReason, durationMs)\n\n### File system\n- \\`fs:beforeRead\\` — before file read (sessionId, path, line, limit)\n- \\`fs:beforeWrite\\` — before file write (sessionId, path, content)\n\n### Terminal\n- \\`terminal:beforeCreate\\` — before terminal process spawned (sessionId, command, args, env, cwd)\n- \\`terminal:afterExit\\` — after terminal process exits (sessionId, terminalId, command, exitCode, durationMs)\n\n### Permission\n- \\`permission:beforeRequest\\` — before permission prompt (sessionId, request, autoResolve)\n- \\`permission:afterResolve\\` — after permission resolved (sessionId, requestId, decision, userId, durationMs)\n\n### Session\n- \\`session:beforeCreate\\` — before session creation (agentName, workingDir, userId, channelId, threadId)\n- \\`session:afterDestroy\\` — after session destroyed (sessionId, reason, durationMs, promptCount)\n\n### Control\n- \\`mode:beforeChange\\` — before mode change (sessionId, fromMode, toMode)\n- \\`config:beforeChange\\` — before config change (sessionId, configId, oldValue, newValue)\n- \\`model:beforeChange\\` — before model change (sessionId, fromModel, toModel)\n- \\`agent:beforeCancel\\` — before agent cancellation (sessionId, reason)\n- \\`agent:beforeSwitch\\` — **blocking** before agent switch (sessionId, fromAgent, toAgent). Return null/false to block.\n- \\`agent:afterSwitch\\` — **fire-and-forget** after agent switch (sessionId, fromAgent, toAgent, resumed). Observational only.\n\n## Plugin Events (subscribe with ctx.on)\n\n### System\n- \\`kernel:booted\\`, \\`system:ready\\`, \\`system:shutdown\\`, \\`system:commands-ready\\`\n\n### Plugin lifecycle\n- \\`plugin:loaded\\`, \\`plugin:failed\\`, \\`plugin:disabled\\`, \\`plugin:unloaded\\`\n\n### Session\n- \\`session:created\\`, \\`session:ended\\`, \\`session:named\\`, \\`session:updated\\`\n\n### Agent\n- \\`agent:event\\`, \\`agent:prompt\\`\n\n### Permission\n- \\`permission:request\\`, \\`permission:resolved\\`\n\n## Testing\n\nUse \\`@openacp/plugin-sdk/testing\\`:\n\n\\`\\`\\`typescript\nimport { createTestContext, createTestInstallContext, mockServices } from '@openacp/plugin-sdk/testing'\n\\`\\`\\`\n\n### createTestContext(opts)\n\nCreates a test \\`PluginContext\\`. All state is in-memory.\n\n\\`\\`\\`typescript\nconst ctx = createTestContext({\n pluginName: '${params.pluginName}',\n pluginConfig: { enabled: true },\n permissions: plugin.permissions,\n services: { security: mockServices.security() },\n})\nawait plugin.setup(ctx)\nexpect(ctx.registeredCommands.has('mycommand')).toBe(true)\nconst response = await ctx.executeCommand('mycommand', { raw: 'test' })\n\\`\\`\\`\n\nInspection properties: \\`registeredServices\\`, \\`registeredCommands\\`, \\`registeredMiddleware\\`, \\`emittedEvents\\`, \\`sentMessages\\`, \\`executeCommand()\\`.\n\n### createTestInstallContext(opts)\n\nCreates a test \\`InstallContext\\`. Terminal prompts auto-answered from \\`terminalResponses\\`.\n\n\\`\\`\\`typescript\nconst ctx = createTestInstallContext({\n pluginName: '${params.pluginName}',\n terminalResponses: { password: ['sk-test-key'], select: ['en'] },\n})\nawait plugin.install!(ctx)\nexpect(ctx.settingsData.get('apiKey')).toBe('sk-test-key')\n\\`\\`\\`\n\n### mockServices\n\nFactory functions for mock service implementations:\n\n\\`\\`\\`typescript\nmockServices.security(overrides?) // checkAccess, checkSessionLimit, getUserRole\nmockServices.fileService(overrides?) // saveFile, resolveFile, readTextFileWithRange\nmockServices.notifications(overrides?) // notify, notifyAll\nmockServices.usage(overrides?) // trackUsage, checkBudget, getSummary\nmockServices.speech(overrides?) // textToSpeech, speechToText, register*\nmockServices.tunnel(overrides?) // getPublicUrl, start, stop, getStore, fileUrl, diffUrl\nmockServices.context(overrides?) // buildContext, registerProvider\n\\`\\`\\`\n\n## Conventions\n\n- **ESM-only**: \\`\"type\": \"module\"\\` in package.json\n- **Import extensions**: All imports must use \\`.js\\` extension (e.g., \\`import x from './util.js'\\`)\n- **TypeScript strict mode**: \\`strict: true\\` in tsconfig.json\n- **Target**: ES2022, module NodeNext\n- **Test framework**: Vitest\n- **Test files**: \\`src/**/__tests__/*.test.ts\\`\n\n## How to Add a Command\n\n\\`\\`\\`typescript\n// In setup():\nctx.registerCommand({\n name: 'mycommand',\n description: 'Does something useful',\n usage: '<arg>',\n category: 'plugin',\n async handler(args) {\n const input = args.raw.trim()\n if (!input) return { type: 'error', message: 'Usage: /mycommand <arg>' }\n return { type: 'text', text: \\\\\\`Result: \\\\\\${input}\\\\\\` }\n },\n})\n\\`\\`\\`\n\nRequires \\`commands:register\\` permission. Available as \\`/mycommand\\` (if no conflict) and \\`/pluginscope:mycommand\\` (always).\n\n## How to Add a Service\n\n\\`\\`\\`typescript\n// In setup():\nconst myService = new MyService()\nctx.registerService('my-service', myService)\n\\`\\`\\`\n\nRequires \\`services:register\\` permission. Other plugins consume with \\`ctx.getService<MyService>('my-service')\\`.\n\n## How to Add Middleware\n\n\\`\\`\\`typescript\n// In setup():\nctx.registerMiddleware('message:outgoing', {\n priority: 50, // lower = earlier execution\n handler: async (payload, next) => {\n payload.message.text = modifyText(payload.message.text)\n return next() // continue chain; return null to block\n },\n})\n\\`\\`\\`\n\nRequires \\`middleware:register\\` permission.\n\n## How Settings Work\n\n1. Define \\`settingsSchema\\` (Zod) on the plugin object\n2. In \\`install()\\`: use \\`ctx.terminal\\` for interactive prompts, save with \\`ctx.settings.set()\\`\n3. In \\`configure()\\`: re-run prompts with current values pre-filled\n4. In \\`setup()\\`: read settings from \\`ctx.pluginConfig\\`\n5. In \\`migrate()\\`: transform old settings to new format on version change\n\n## Version Compatibility\n\nThe \\`engines.openacp\\` field in package.json declares the minimum CLI version. OpenACP checks this on install and warns if incompatible.\n`\n}\n","import type { TemplateParams } from './package-json.js'\n\nexport function generatePluginGuide(params: TemplateParams): string {\n return `# Plugin Developer Guide\n\n## Overview\n\n**${params.pluginName}** is an OpenACP plugin.\n\n> TODO: Describe what this plugin does.\n\n## Project Structure\n\n\\`\\`\\`\nsrc/\n index.ts — Plugin entry point (exports OpenACPPlugin object)\n __tests__/\n index.test.ts — Tests using Vitest + @openacp/plugin-sdk/testing\npackage.json — npm package config with engines.openacp constraint\ntsconfig.json — TypeScript strict mode, ES2022, NodeNext\nCLAUDE.md — Full technical reference for AI coding agents\nPLUGIN_GUIDE.md — This file\n\\`\\`\\`\n\n## Development Workflow\n\n1. **Edit** \\`src/index.ts\\` — implement your plugin logic\n2. **Dev mode**: \\`openacp dev .\\` — compiles, watches, and hot-reloads your plugin\n3. **Test**: \\`npm test\\` — runs Vitest with SDK testing utilities\n4. **Build**: \\`npm run build\\` — compiles TypeScript to \\`dist/\\`\n\n\\`\\`\\`bash\nnpm install\nopenacp dev . # start developing with hot-reload\nnpm test # run tests\nnpm run build # compile for publishing\n\\`\\`\\`\n\n## Adding a Command\n\nRegister commands in your \\`setup()\\` function. Requires \\`commands:register\\` permission.\n\n\\`\\`\\`typescript\nasync setup(ctx: PluginContext) {\n ctx.registerCommand({\n name: 'greet',\n description: 'Send a greeting',\n usage: '[name]',\n category: 'plugin',\n async handler(args) {\n const name = args.raw.trim() || 'World'\n return { type: 'text', text: \\\\\\`Hello, \\\\\\${name}!\\\\\\` }\n },\n })\n}\n\\`\\`\\`\n\nThe command will be available as \\`/greet\\` in all messaging platforms.\n\n## Adding a Service\n\nProvide a service that other plugins can consume. Requires \\`services:register\\` permission.\n\n\\`\\`\\`typescript\nasync setup(ctx: PluginContext) {\n const myService = {\n doSomething(input: string): string {\n return input.toUpperCase()\n },\n }\n ctx.registerService('my-service', myService)\n}\n\\`\\`\\`\n\nOther plugins access it with \\`ctx.getService<MyServiceType>('my-service')\\`.\n\n## Adding Middleware\n\nIntercept and modify message flows. Requires \\`middleware:register\\` permission.\n\n\\`\\`\\`typescript\nasync setup(ctx: PluginContext) {\n ctx.registerMiddleware('message:outgoing', {\n priority: 50,\n handler: async (payload, next) => {\n // Modify the message before delivery\n payload.message.text += '\\\\n-- sent via ${params.pluginName}'\n return next() // continue the chain\n // return null to block the message entirely\n },\n })\n}\n\\`\\`\\`\n\n## Handling Settings\n\n### Install flow (first-time setup)\n\n\\`\\`\\`typescript\nasync install(ctx: InstallContext) {\n const apiKey = await ctx.terminal.password({\n message: 'Enter your API key:',\n validate: (v) => v.length > 0 ? undefined : 'Required',\n })\n await ctx.settings.set('apiKey', apiKey)\n ctx.terminal.log.success('Configured!')\n}\n\\`\\`\\`\n\n### Configure flow (reconfiguration)\n\n\\`\\`\\`typescript\nasync configure(ctx: InstallContext) {\n const current = await ctx.settings.getAll()\n const apiKey = await ctx.terminal.password({\n message: \\\\\\`API key (current: \\\\\\${current.apiKey ? '***' : 'not set'}):\\\\\\`,\n })\n if (apiKey) await ctx.settings.set('apiKey', apiKey)\n ctx.terminal.log.success('Updated!')\n}\n\\`\\`\\`\n\n### Reading settings at runtime\n\n\\`\\`\\`typescript\nasync setup(ctx: PluginContext) {\n const apiKey = ctx.pluginConfig.apiKey as string\n if (!apiKey) {\n ctx.log.warn('Not configured — run: openacp plugin configure ${params.pluginName}')\n return\n }\n // Use apiKey...\n}\n\\`\\`\\`\n\n## Testing\n\nTests use Vitest and \\`@openacp/plugin-sdk/testing\\`.\n\n\\`\\`\\`typescript\nimport { describe, it, expect } from 'vitest'\nimport { createTestContext, createTestInstallContext, mockServices } from '@openacp/plugin-sdk/testing'\nimport plugin from '../index.js'\n\ndescribe('${params.pluginName}', () => {\n it('registers commands on setup', async () => {\n const ctx = createTestContext({ pluginName: '${params.pluginName}' })\n await plugin.setup(ctx)\n expect(ctx.registeredCommands.has('greet')).toBe(true)\n })\n\n it('command returns expected response', async () => {\n const ctx = createTestContext({ pluginName: '${params.pluginName}' })\n await plugin.setup(ctx)\n const res = await ctx.executeCommand('greet', { raw: 'Alice' })\n expect(res).toEqual({ type: 'text', text: 'Hello, Alice!' })\n })\n\n it('install saves settings', async () => {\n const ctx = createTestInstallContext({\n pluginName: '${params.pluginName}',\n terminalResponses: { password: ['sk-test-key'] },\n })\n await plugin.install!(ctx)\n expect(ctx.settingsData.get('apiKey')).toBe('sk-test-key')\n })\n})\n\\`\\`\\`\n\n### Available mock services\n\n\\`\\`\\`typescript\nconst ctx = createTestContext({\n pluginName: '${params.pluginName}',\n services: {\n security: mockServices.security(),\n usage: mockServices.usage({ async checkBudget() { return { ok: false, percent: 100 } } }),\n },\n})\n\\`\\`\\`\n\n## Publishing\n\n1. Update \\`version\\` in both \\`package.json\\` and \\`src/index.ts\\`\n2. Build and test:\n \\`\\`\\`bash\n npm run build\n npm test\n \\`\\`\\`\n3. Publish:\n \\`\\`\\`bash\n npm publish --access public\n \\`\\`\\`\n4. Users install with:\n \\`\\`\\`bash\n openacp plugin install ${params.pluginName}\n \\`\\`\\`\n5. Submit to the [OpenACP Plugin Registry](https://github.com/Open-ACP/plugin-registry) for discoverability.\n\n## Useful Links\n\n- [Architecture: Plugin System](https://docs.openacp.dev/architecture/plugin-system)\n- [Architecture: Writing Plugins](https://docs.openacp.dev/architecture/writing-plugins)\n- [Architecture: Command System](https://docs.openacp.dev/architecture/command-system)\n- [Plugin SDK Reference](https://docs.openacp.dev/extending/plugin-sdk-reference)\n- [Getting Started: Your First Plugin](https://docs.openacp.dev/extending/getting-started-plugin)\n- [Dev Mode](https://docs.openacp.dev/extending/dev-mode)\n- [Contributing](https://github.com/Open-ACP/OpenACP/blob/main/CONTRIBUTING.md)\n`\n}\n","export type { TemplateParams } from './package-json.js'\nexport { generatePackageJson } from './package-json.js'\nexport { generateTsconfig } from './tsconfig.js'\nexport { generateGitignore, generateNpmignore, generateEditorconfig } from './dotfiles.js'\nexport { generateReadme } from './readme.js'\nexport { generatePluginSource } from './plugin-source.js'\nexport { generatePluginTest } from './plugin-test.js'\nexport { generateClaudeMd } from './claude-md.js'\nexport { generatePluginGuide } from './plugin-guide.js'\n","import * as p from '@clack/prompts'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { getCurrentVersion } from '../version.js'\nimport {\n type TemplateParams,\n generatePackageJson,\n generateTsconfig,\n generateGitignore,\n generateNpmignore,\n generateEditorconfig,\n generateReadme,\n generatePluginSource,\n generatePluginTest,\n generateClaudeMd,\n generatePluginGuide,\n} from '../plugin-template/index.js'\n\nexport async function cmdPluginCreate(): Promise<void> {\n p.intro('Create a new OpenACP plugin')\n\n const result = await p.group(\n {\n name: () =>\n p.text({\n message: 'Plugin name (e.g., @myorg/adapter-matrix)',\n placeholder: '@myorg/my-plugin',\n validate: (value: string | undefined) => {\n if (!value || !value.trim()) return 'Plugin name is required'\n if (!/^(@[a-z0-9-]+\\/)?[a-z0-9-]+$/.test(value.trim())) {\n return 'Must be a valid npm package name (lowercase, hyphens, optional @scope/)'\n }\n return undefined\n },\n }),\n description: () =>\n p.text({\n message: 'Description',\n placeholder: 'A short description of your plugin',\n }),\n author: () =>\n p.text({\n message: 'Author',\n placeholder: 'Your Name <email@example.com>',\n }),\n license: () =>\n p.select({\n message: 'License',\n options: [\n { value: 'MIT', label: 'MIT' },\n { value: 'Apache-2.0', label: 'Apache 2.0' },\n { value: 'ISC', label: 'ISC' },\n { value: 'UNLICENSED', label: 'Unlicensed (private)' },\n ],\n }),\n },\n {\n onCancel: () => {\n p.cancel('Plugin creation cancelled.')\n process.exit(0)\n },\n },\n )\n\n const pluginName = result.name.trim()\n const dirName = pluginName.replace(/^@[^/]+\\//, '') // strip scope for directory name\n const targetDir = path.resolve(process.cwd(), dirName)\n\n if (fs.existsSync(targetDir)) {\n p.cancel(`Directory \"${dirName}\" already exists.`)\n process.exit(1)\n }\n\n const spinner = p.spinner()\n spinner.start('Scaffolding plugin...')\n\n // Create directory structure\n fs.mkdirSync(path.join(targetDir, 'src', '__tests__'), { recursive: true })\n\n // Collect template params\n const params: TemplateParams = {\n pluginName,\n description: (result.description as string) || '',\n author: (result.author as string) || '',\n license: result.license as string,\n cliVersion: getCurrentVersion(),\n }\n\n // Generate and write all files\n const files: Array<{ relativePath: string; content: string }> = [\n { relativePath: 'package.json', content: generatePackageJson(params) },\n { relativePath: 'tsconfig.json', content: generateTsconfig() },\n { relativePath: '.gitignore', content: generateGitignore() },\n { relativePath: '.npmignore', content: generateNpmignore() },\n { relativePath: '.editorconfig', content: generateEditorconfig() },\n { relativePath: 'README.md', content: generateReadme(params) },\n { relativePath: 'CLAUDE.md', content: generateClaudeMd(params) },\n { relativePath: 'PLUGIN_GUIDE.md', content: generatePluginGuide(params) },\n { relativePath: path.join('src', 'index.ts'), content: generatePluginSource(params) },\n { relativePath: path.join('src', '__tests__', 'index.test.ts'), content: generatePluginTest(params) },\n ]\n\n for (const file of files) {\n fs.writeFileSync(path.join(targetDir, file.relativePath), file.content)\n }\n\n spinner.stop('Plugin scaffolded!')\n\n p.note(\n [\n `cd ${dirName}`,\n 'npm install',\n 'npm run build',\n 'npm test',\n '',\n '# Start development with hot-reload:',\n `openacp dev .`,\n ].join('\\n'),\n 'Next steps',\n )\n\n p.outro(`Plugin ${pluginName} created in ./${dirName}`)\n}\n","import type { ConfigManager } from \"../../core/config/config.js\";\nimport type { SessionManager } from \"../../core/sessions/session-manager.js\";\nimport type { IncomingMessage } from \"../../core/types.js\";\n\nexport class SecurityGuard {\n constructor(\n private configManager: ConfigManager,\n private sessionManager: SessionManager,\n ) {}\n\n checkAccess(message: IncomingMessage):\n | { allowed: true }\n | { allowed: false; reason: string }\n {\n const config = this.configManager.get();\n if (config.security.allowedUserIds.length > 0) {\n const userId = String(message.userId);\n if (!config.security.allowedUserIds.includes(userId)) {\n return { allowed: false, reason: \"Unauthorized user\" };\n }\n }\n const active = this.sessionManager.listSessions()\n .filter(s => s.status === \"active\" || s.status === \"initializing\");\n if (active.length >= config.security.maxConcurrentSessions) {\n return { allowed: false, reason: `Session limit reached (${config.security.maxConcurrentSessions})` };\n }\n return { allowed: true };\n }\n}\n","import type { OpenACPPlugin, InstallContext, MiddlewarePayloadMap } from '../../core/plugin/types.js'\nimport { SecurityGuard } from './security-guard.js'\nimport type { IncomingMessage } from '../../core/types.js'\n\n// Structural type for the core fields SecurityGuard needs, avoiding\n// a direct dependency on OpenACPCore's full interface.\ninterface SecurityCoreAccess {\n configManager: ConstructorParameters<typeof SecurityGuard>[0]\n sessionManager: ConstructorParameters<typeof SecurityGuard>[1]\n}\n\n// Factory function pattern (closure for state)\nfunction createSecurityPlugin(): OpenACPPlugin {\n return {\n name: '@openacp/security',\n version: '1.0.0',\n description: 'User access control and session limits',\n essential: false,\n permissions: ['services:register', 'middleware:register', 'kernel:access', 'commands:register'],\n inheritableKeys: ['allowedUsers', 'maxSessionsPerUser', 'rateLimits'],\n\n async install(ctx: InstallContext) {\n const { settings, legacyConfig, terminal } = ctx\n\n // Migrate from legacy config if present\n if (legacyConfig) {\n const securityCfg = legacyConfig.security as Record<string, unknown> | undefined\n if (securityCfg) {\n await settings.setAll({\n allowedUserIds: securityCfg.allowedUserIds ?? [],\n maxConcurrentSessions: securityCfg.maxConcurrentSessions ?? 20,\n sessionTimeoutMinutes: securityCfg.sessionTimeoutMinutes ?? 60,\n })\n terminal.log.success('Security settings migrated from legacy config')\n return\n }\n }\n\n // Save defaults (no interactive prompts needed)\n await settings.setAll({\n allowedUserIds: [],\n maxConcurrentSessions: 20,\n sessionTimeoutMinutes: 60,\n })\n terminal.log.success('Security defaults saved')\n },\n\n async configure(ctx: InstallContext) {\n const { terminal, settings } = ctx\n const current = await settings.getAll()\n\n const choice = await terminal.select({\n message: 'What to configure?',\n options: [\n { value: 'allowedUsers', label: 'Edit allowed user IDs' },\n { value: 'maxSessions', label: `Max concurrent sessions (current: ${current.maxConcurrentSessions ?? 20})` },\n { value: 'timeout', label: `Session timeout minutes (current: ${current.sessionTimeoutMinutes ?? 60})` },\n { value: 'done', label: 'Done' },\n ],\n })\n\n if (choice === 'allowedUsers') {\n const currentIds = (current.allowedUserIds as string[]) ?? []\n const val = await terminal.text({\n message: 'Allowed user IDs (comma-separated, empty = allow all):',\n defaultValue: currentIds.join(', '),\n })\n const ids = val.split(',').map((s) => s.trim()).filter(Boolean)\n await settings.set('allowedUserIds', ids)\n terminal.log.success('Allowed user IDs updated')\n } else if (choice === 'maxSessions') {\n const val = await terminal.text({\n message: 'Max concurrent sessions:',\n defaultValue: String(current.maxConcurrentSessions ?? 20),\n validate: (v) => {\n const n = Number(v.trim())\n if (isNaN(n) || n < 1) return 'Must be a positive number'\n return undefined\n },\n })\n await settings.set('maxConcurrentSessions', Number(val.trim()))\n terminal.log.success('Max sessions updated')\n } else if (choice === 'timeout') {\n const val = await terminal.text({\n message: 'Session timeout (minutes):',\n defaultValue: String(current.sessionTimeoutMinutes ?? 60),\n validate: (v) => {\n const n = Number(v.trim())\n if (isNaN(n) || n < 1) return 'Must be a positive number'\n return undefined\n },\n })\n await settings.set('sessionTimeoutMinutes', Number(val.trim()))\n terminal.log.success('Session timeout updated')\n }\n },\n\n async uninstall(ctx: InstallContext, opts: { purge: boolean }) {\n if (opts.purge) {\n await ctx.settings.clear()\n ctx.terminal.log.success('Security settings cleared')\n }\n },\n\n async setup(ctx) {\n const core = ctx.core as SecurityCoreAccess\n const guard = new SecurityGuard(core.configManager, core.sessionManager)\n\n // Register middleware for message:incoming — block unauthorized users\n ctx.registerMiddleware('message:incoming', {\n handler: async (payload: MiddlewarePayloadMap['message:incoming'], next) => {\n const access = guard.checkAccess(payload as unknown as IncomingMessage)\n if (!access.allowed) {\n ctx.log.info(`Access denied: ${access.reason}`)\n return null // block\n }\n return next()\n }\n })\n\n // Register SecurityGuard as the service directly\n ctx.registerService('security', guard)\n\n ctx.registerCommand({\n name: 'dangerous',\n description: 'Toggle dangerous mode (auto-approve all permissions)',\n usage: 'on|off',\n category: 'plugin',\n handler: async (args) => {\n const mode = args.raw.trim().toLowerCase()\n if (mode === 'on') return { type: 'text', text: 'Dangerous mode enabled — all permissions will be auto-approved.' }\n if (mode === 'off') return { type: 'text', text: 'Dangerous mode disabled — permissions require manual approval.' }\n return { type: 'menu', title: 'Dangerous Mode', options: [\n { label: 'Enable', command: '/dangerous on' },\n { label: 'Disable', command: '/dangerous off' },\n ]}\n },\n })\n\n ctx.log.info('Security service ready')\n },\n }\n}\n\nexport default createSecurityPlugin()\n","import fs from \"node:fs\";\n\n/**\n * Read a text file, optionally returning only a range of lines.\n * Pure utility — no dependencies on plugin code.\n */\nexport async function readTextFileWithRange(\n filePath: string,\n options?: { line?: number; limit?: number },\n): Promise<string> {\n const content = await fs.promises.readFile(filePath, \"utf-8\");\n if (!options?.line && !options?.limit) return content;\n const lines = content.split(\"\\n\");\n const start = Math.max(0, (options.line ?? 1) - 1);\n const end = options.limit ? start + options.limit : lines.length;\n return lines.slice(start, end).join(\"\\n\");\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { OggOpusDecoder } from \"ogg-opus-decoder\";\nimport wav from \"node-wav\";\nimport type { Attachment } from \"../../core/types.js\";\n\nconst MIME_TO_EXT: Record<string, string> = {\n \"image/jpeg\": \".jpg\",\n \"image/png\": \".png\",\n \"image/gif\": \".gif\",\n \"image/webp\": \".webp\",\n \"image/svg+xml\": \".svg\",\n \"audio/ogg\": \".ogg\",\n \"audio/mpeg\": \".mp3\",\n \"audio/wav\": \".wav\",\n \"audio/webm\": \".webm\",\n \"audio/mp4\": \".m4a\",\n \"video/mp4\": \".mp4\",\n \"video/webm\": \".webm\",\n \"application/pdf\": \".pdf\",\n \"text/plain\": \".txt\",\n};\n\nconst EXT_TO_MIME: Record<string, string> = {\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".png\": \"image/png\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".ogg\": \"audio/ogg\",\n \".oga\": \"audio/ogg\",\n \".mp3\": \"audio/mpeg\",\n \".wav\": \"audio/wav\",\n \".m4a\": \"audio/mp4\",\n \".mp4\": \"video/mp4\",\n \".pdf\": \"application/pdf\",\n \".txt\": \"text/plain\",\n};\n\nfunction classifyMime(mimeType: string): Attachment[\"type\"] {\n if (mimeType.startsWith(\"image/\")) return \"image\";\n if (mimeType.startsWith(\"audio/\")) return \"audio\";\n return \"file\";\n}\n\nexport class FileService {\n constructor(private baseDir: string) {}\n\n /**\n * Remove session file directories older than maxAgeDays.\n * Called on startup to prevent unbounded disk growth.\n */\n async cleanupOldFiles(maxAgeDays: number): Promise<number> {\n const cutoff = Date.now() - maxAgeDays * 24 * 60 * 60 * 1000;\n let removed = 0;\n try {\n const entries = await fs.promises.readdir(this.baseDir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const dirPath = path.join(this.baseDir, entry.name);\n try {\n const stat = await fs.promises.stat(dirPath);\n if (stat.mtimeMs < cutoff) {\n await fs.promises.rm(dirPath, { recursive: true, force: true });\n removed++;\n }\n } catch {\n // Skip inaccessible directories\n }\n }\n } catch {\n // Base dir doesn't exist yet — nothing to clean\n }\n return removed;\n }\n\n async saveFile(\n sessionId: string,\n fileName: string,\n data: Buffer,\n mimeType: string,\n ): Promise<Attachment> {\n const sessionDir = path.join(this.baseDir, sessionId);\n await fs.promises.mkdir(sessionDir, { recursive: true });\n\n const safeName = `${Date.now()}-${fileName.replace(/[^a-zA-Z0-9._-]/g, \"_\")}`;\n const filePath = path.join(sessionDir, safeName);\n await fs.promises.writeFile(filePath, data);\n\n return {\n type: classifyMime(mimeType),\n filePath,\n fileName,\n mimeType,\n size: data.length,\n };\n }\n\n async resolveFile(filePath: string): Promise<Attachment | null> {\n try {\n const stat = await fs.promises.stat(filePath);\n if (!stat.isFile()) return null;\n\n const ext = path.extname(filePath).toLowerCase();\n const mimeType = EXT_TO_MIME[ext] || \"application/octet-stream\";\n\n return {\n type: classifyMime(mimeType),\n filePath,\n fileName: path.basename(filePath),\n mimeType,\n size: stat.size,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Convert OGG Opus audio to WAV format.\n * Telegram voice messages use OGG Opus which many AI agents can't read.\n */\n async convertOggToWav(oggData: Buffer): Promise<Buffer> {\n const decoder = new OggOpusDecoder();\n await decoder.ready;\n try {\n const { channelData, sampleRate } = await decoder.decode(new Uint8Array(oggData));\n const wavData = wav.encode(channelData, { sampleRate, float: true, bitDepth: 32 });\n return Buffer.from(wavData);\n } finally {\n decoder.free();\n }\n }\n\n /** Instance method — delegates to static for FileServiceInterface compliance */\n async readTextFileWithRange(\n filePath: string,\n options?: { line?: number; limit?: number },\n ): Promise<string> {\n return FileService.readTextFileWithRange(filePath, options);\n }\n\n static async readTextFileWithRange(\n filePath: string,\n options?: { line?: number; limit?: number },\n ): Promise<string> {\n // Delegate to core utility (canonical implementation)\n const { readTextFileWithRange } = await import(\"../../core/utils/read-text-file.js\");\n return readTextFileWithRange(filePath, options);\n }\n\n /** Instance method — delegates to static for FileServiceInterface compliance */\n extensionFromMime(mimeType: string): string {\n return FileService.extensionFromMime(mimeType);\n }\n\n static extensionFromMime(mimeType: string): string {\n return MIME_TO_EXT[mimeType] || \".bin\";\n }\n}\n","import type { OpenACPPlugin, InstallContext } from '../../core/plugin/types.js'\nimport { FileService } from './file-service.js'\nimport path from 'node:path'\nimport os from 'node:os'\n\nfunction createFileServicePlugin(): OpenACPPlugin {\n return {\n name: '@openacp/file-service',\n version: '1.0.0',\n description: 'File storage and management for session attachments',\n essential: false,\n permissions: ['services:register'],\n\n async install(ctx: InstallContext) {\n const { settings, legacyConfig, terminal } = ctx\n const defaultFilesDir = path.join(ctx.instanceRoot ?? path.join(os.homedir(), '.openacp'), 'files')\n\n // Migrate from legacy config if present\n if (legacyConfig) {\n const filesCfg = legacyConfig.files as Record<string, unknown> | undefined\n if (filesCfg) {\n await settings.setAll({\n baseDir: filesCfg.baseDir ?? defaultFilesDir,\n })\n terminal.log.success('File service settings migrated from legacy config')\n return\n }\n }\n\n // Save defaults\n await settings.setAll({\n baseDir: defaultFilesDir,\n })\n terminal.log.success('File service defaults saved')\n },\n\n async configure(ctx: InstallContext) {\n const { terminal, settings } = ctx\n const current = await settings.getAll()\n const defaultFilesDir = path.join(ctx.instanceRoot ?? path.join(os.homedir(), '.openacp'), 'files')\n\n const val = await terminal.text({\n message: 'File storage directory:',\n defaultValue: (current.baseDir as string) ?? defaultFilesDir,\n })\n await settings.set('baseDir', val.trim())\n terminal.log.success('File storage directory updated')\n },\n\n async uninstall(ctx: InstallContext, opts: { purge: boolean }) {\n if (opts.purge) {\n await ctx.settings.clear()\n ctx.terminal.log.success('File service settings cleared')\n }\n },\n\n async setup(ctx) {\n const config = ctx.pluginConfig as Record<string, unknown>\n const baseDir = (config.baseDir as string) ?? path.join(ctx.instanceRoot, 'files')\n const retentionDays = (config.retentionDays as number) ?? 30\n const service = new FileService(baseDir)\n ctx.registerService('file-service', service)\n // Cleanup old session files in background (fire-and-forget)\n service.cleanupOldFiles(retentionDays).then((count) => {\n if (count > 0) ctx.log.info(`Cleaned up ${count} old session files`)\n }).catch(() => {})\n ctx.log.info('File service ready')\n },\n }\n}\n\nexport default createFileServicePlugin()\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as crypto from \"node:crypto\";\nimport type { ContextResult } from \"./context-provider.js\";\n\nconst DEFAULT_TTL_MS = 60 * 60 * 1000;\n\nexport class ContextCache {\n constructor(private cacheDir: string, private ttlMs: number = DEFAULT_TTL_MS) {\n fs.mkdirSync(cacheDir, { recursive: true });\n }\n\n private keyHash(repoPath: string, queryKey: string): string {\n return crypto.createHash(\"sha256\").update(`${repoPath}:${queryKey}`).digest(\"hex\").slice(0, 16);\n }\n\n private filePath(repoPath: string, queryKey: string): string {\n return path.join(this.cacheDir, `${this.keyHash(repoPath, queryKey)}.json`);\n }\n\n get(repoPath: string, queryKey: string): ContextResult | null {\n const fp = this.filePath(repoPath, queryKey);\n try {\n const stat = fs.statSync(fp);\n if (Date.now() - stat.mtimeMs > this.ttlMs) { fs.unlinkSync(fp); return null; }\n return JSON.parse(fs.readFileSync(fp, \"utf-8\")) as ContextResult;\n } catch { return null; }\n }\n\n set(repoPath: string, queryKey: string, result: ContextResult): void {\n fs.writeFileSync(this.filePath(repoPath, queryKey), JSON.stringify(result));\n }\n}\n","import * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport type { ContextProvider, ContextQuery, ContextOptions, ContextResult, SessionListResult } from \"./context-provider.js\";\nimport { ContextCache } from \"./context-cache.js\";\n\nexport class ContextManager {\n private providers: ContextProvider[] = [];\n private cache: ContextCache;\n\n constructor(cachePath?: string) {\n this.cache = new ContextCache(cachePath ?? path.join(os.homedir(), \".openacp\", \"cache\", \"entire\"));\n }\n\n register(provider: ContextProvider): void {\n this.providers.push(provider);\n }\n\n async getProvider(repoPath: string): Promise<ContextProvider | null> {\n for (const provider of this.providers) {\n if (await provider.isAvailable(repoPath)) return provider;\n }\n return null;\n }\n\n async listSessions(query: ContextQuery): Promise<SessionListResult | null> {\n for (const provider of this.providers) {\n if (!(await provider.isAvailable(query.repoPath))) continue;\n const result = await provider.listSessions(query);\n if (result.sessions.length > 0) return result;\n }\n return null;\n }\n\n async buildContext(query: ContextQuery, options?: ContextOptions): Promise<ContextResult | null> {\n const queryKey = `${query.type}:${query.value}:${options?.limit ?? \"\"}:${options?.maxTokens ?? \"\"}:${options?.labelAgent ?? \"\"}`;\n const cached = this.cache.get(query.repoPath, queryKey);\n if (cached) return cached;\n\n for (const provider of this.providers) {\n if (!(await provider.isAvailable(query.repoPath))) continue;\n const result = await provider.buildContext(query, options);\n if (result && result.markdown) {\n this.cache.set(query.repoPath, queryKey, result);\n return result;\n }\n }\n return null;\n }\n}\n","// NOTE: This interface is designed around Entire as the first provider.\n// It may evolve when additional providers (Cursor history, Zed, etc.) are added.\n// Providers may only support a subset of query types and should return empty results\n// for unsupported types rather than throwing.\n\nexport interface ContextProvider {\n readonly name: string;\n isAvailable(repoPath: string): Promise<boolean>;\n listSessions(query: ContextQuery): Promise<SessionListResult>;\n buildContext(query: ContextQuery, options?: ContextOptions): Promise<ContextResult>;\n}\n\nexport interface ContextQuery {\n repoPath: string;\n type: \"branch\" | \"commit\" | \"pr\" | \"latest\" | \"checkpoint\" | \"session\";\n value: string;\n}\n\nexport interface ContextOptions {\n maxTokens?: number;\n limit?: number;\n /** When true, insert `## [agentName]` headers at agent boundaries in merged history */\n labelAgent?: boolean;\n}\n\nexport interface SessionInfo {\n checkpointId: string;\n sessionIndex: string;\n transcriptPath: string;\n createdAt: string;\n endedAt: string;\n branch: string;\n agent: string;\n turnCount: number;\n filesTouched: string[];\n sessionId: string;\n}\n\nexport interface SessionListResult {\n sessions: SessionInfo[];\n estimatedTokens: number;\n}\n\nexport type ContextMode = \"full\" | \"balanced\" | \"compact\";\n\nexport interface ContextResult {\n markdown: string;\n tokenEstimate: number;\n sessionCount: number;\n totalTurns: number;\n mode: ContextMode;\n truncated: boolean;\n timeRange: { start: string; end: string };\n}\n\nexport const DEFAULT_MAX_TOKENS = 30_000;\nexport const TOKENS_PER_TURN_ESTIMATE = 400;\n","import { execFileSync } from \"child_process\";\nimport type { SessionInfo } from \"../context-provider.js\";\n\n// ─── Internal types ────────────────────────────────────────────────────────────\n\ninterface CheckpointMeta {\n checkpoint_id?: string;\n branch?: string;\n files_touched?: string[];\n sessions: Array<{\n metadata: string;\n transcript: string;\n }>;\n}\n\ninterface SessionMeta {\n session_id?: string;\n created_at?: string;\n branch?: string;\n agent?: string;\n files_touched?: string[];\n session_metrics?: {\n turn_count?: number;\n };\n}\n\n// ─── CheckpointReader ─────────────────────────────────────────────────────────\n\nconst ENTIRE_BRANCH = \"origin/entire/checkpoints/v1\";\nconst CHECKPOINT_ID_RE = /^[0-9a-f]{12}$/;\nconst SESSION_ID_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;\n\nexport class CheckpointReader {\n constructor(private readonly repoPath: string) {}\n\n // ─── Git execution ───────────────────────────────────────────────────────────\n\n /**\n * Run a git command in the repo directory.\n * Returns trimmed stdout on success, empty string on failure.\n */\n private git(...args: string[]): string {\n try {\n return execFileSync(\"git\", [\"-C\", this.repoPath, ...args], {\n encoding: \"utf-8\",\n }).trim();\n } catch {\n return \"\";\n }\n }\n\n // ─── Static helpers ──────────────────────────────────────────────────────────\n\n /**\n * Convert a 12-char checkpoint ID to its shard path: \"f634acf05138\" → \"f6/34acf05138\"\n */\n static shardPath(cpId: string): string {\n return `${cpId.slice(0, 2)}/${cpId.slice(2)}`;\n }\n\n /**\n * Returns true when value looks like a 12-char lowercase hex checkpoint ID.\n */\n static isCheckpointId(value: string): boolean {\n return CHECKPOINT_ID_RE.test(value);\n }\n\n /**\n * Returns true when value looks like a UUID (session ID).\n */\n static isSessionId(value: string): boolean {\n return SESSION_ID_RE.test(value);\n }\n\n /**\n * Parse checkpoint-level metadata JSON. Returns null on error.\n */\n static parseCheckpointMeta(json: string): CheckpointMeta | null {\n try {\n const parsed = JSON.parse(json) as CheckpointMeta;\n if (!parsed || typeof parsed !== \"object\") return null;\n if (!Array.isArray(parsed.sessions)) return null;\n return parsed;\n } catch {\n return null;\n }\n }\n\n /**\n * Extract Entire-Checkpoint trailer IDs from `git log --format=\"%H|%(trailers:...)\"` output.\n * Each line is: `<hash>|<trailer_value_or_empty>`. Returns only non-empty trailer values.\n * Uses the last pipe on each line to locate the trailer value, to be robust against\n * subject lines that contain pipes.\n */\n static parseCheckpointTrailers(output: string): string[] {\n const ids: string[] = [];\n for (const line of output.split(\"\\n\")) {\n const pipe = line.lastIndexOf(\"|\");\n if (pipe === -1) continue;\n const trailerId = line.slice(pipe + 1).trim();\n if (trailerId) ids.push(trailerId);\n }\n return ids;\n }\n\n // ─── Branch check ────────────────────────────────────────────────────────────\n\n async hasEntireBranch(): Promise<boolean> {\n const out = this.git(\"branch\", \"-r\");\n return out.includes(\"entire/checkpoints/v1\");\n }\n\n // ─── Core session fetching ───────────────────────────────────────────────────\n\n private listAllCheckpointIds(): string[] {\n const out = this.git(\n \"ls-tree\",\n \"-r\",\n ENTIRE_BRANCH,\n \"--name-only\"\n );\n if (!out) return [];\n\n const ids = new Set<string>();\n for (const file of out.split(\"\\n\")) {\n const parts = file.split(\"/\");\n // Checkpoint-level metadata: XX/YYYYYYYYYY/metadata.json (3 parts)\n if (parts.length === 3 && parts[2] === \"metadata.json\") {\n ids.add(parts[0] + parts[1]);\n }\n }\n return [...ids];\n }\n\n private fetchCheckpointMeta(cpId: string): CheckpointMeta | null {\n const shard = CheckpointReader.shardPath(cpId);\n const raw = this.git(\"show\", `${ENTIRE_BRANCH}:${shard}/metadata.json`);\n if (!raw) return null;\n return CheckpointReader.parseCheckpointMeta(raw);\n }\n\n private fetchSessionMeta(metaPath: string): SessionMeta {\n const normalized = metaPath.startsWith(\"/\") ? metaPath.slice(1) : metaPath;\n const raw = this.git(\"show\", `${ENTIRE_BRANCH}:${normalized}`);\n if (!raw) return {};\n try {\n return JSON.parse(raw) as SessionMeta;\n } catch {\n return {};\n }\n }\n\n /**\n * Build SessionInfo[] from a single checkpoint's metadata.\n */\n private buildSessionsForCheckpoint(\n cpId: string,\n cpMeta: CheckpointMeta\n ): SessionInfo[] {\n const sessions: SessionInfo[] = [];\n\n for (let idx = 0; idx < cpMeta.sessions.length; idx++) {\n const sess = cpMeta.sessions[idx];\n const transcriptPath = (sess.transcript ?? \"\").replace(/^\\//, \"\");\n const metaPath = sess.metadata ?? \"\";\n\n const smeta = this.fetchSessionMeta(metaPath);\n const createdAt = smeta.created_at ?? \"\";\n\n sessions.push({\n checkpointId: cpId,\n sessionIndex: String(idx),\n transcriptPath,\n createdAt,\n endedAt: createdAt, // will be filled from JSONL by conversation builder\n branch: smeta.branch ?? cpMeta.branch ?? \"\",\n agent: smeta.agent ?? \"\",\n turnCount: smeta.session_metrics?.turn_count ?? 0,\n filesTouched: smeta.files_touched ?? cpMeta.files_touched ?? [],\n sessionId: smeta.session_id ?? \"\",\n });\n }\n\n return sessions;\n }\n\n private getSessionsForCheckpoint(cpId: string): SessionInfo[] {\n const meta = this.fetchCheckpointMeta(cpId);\n if (!meta) return [];\n return this.buildSessionsForCheckpoint(cpId, meta);\n }\n\n // ─── Public resolvers ────────────────────────────────────────────────────────\n\n /**\n * All sessions recorded on a given branch, sorted by createdAt ascending.\n */\n async resolveByBranch(branchName: string): Promise<SessionInfo[]> {\n const cpIds = this.listAllCheckpointIds();\n const sessions: SessionInfo[] = [];\n\n for (const cpId of cpIds) {\n const meta = this.fetchCheckpointMeta(cpId);\n if (!meta) continue;\n if (meta.branch !== branchName) continue;\n sessions.push(...this.buildSessionsForCheckpoint(cpId, meta));\n }\n\n sessions.sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n return sessions;\n }\n\n /**\n * Sessions linked to a specific commit via the Entire-Checkpoint git trailer.\n */\n async resolveByCommit(commitHash: string): Promise<SessionInfo[]> {\n const fullHash = this.git(\"rev-parse\", commitHash);\n if (!fullHash) return [];\n\n const cpId = this.git(\n \"log\",\n \"-1\",\n \"--format=%(trailers:key=Entire-Checkpoint,valueonly)\",\n fullHash\n );\n if (!cpId) return [];\n\n return this.getSessionsForCheckpoint(cpId.trim());\n }\n\n /**\n * All sessions from a merged PR (by number or GitHub URL).\n */\n async resolveByPr(prInput: string): Promise<SessionInfo[]> {\n let prNumber: string;\n\n if (/^\\d+$/.test(prInput)) {\n prNumber = prInput;\n } else {\n const m = /\\/pull\\/(\\d+)/.exec(prInput);\n if (!m) return [];\n prNumber = m[1];\n }\n\n const mergeOut = this.git(\n \"log\",\n \"--all\",\n \"--oneline\",\n \"--grep\",\n `Merge pull request #${prNumber}`\n );\n if (!mergeOut) return [];\n\n const mergeCommit = mergeOut.split(\"\\n\")[0].split(\" \")[0];\n\n const logOut = this.git(\n \"log\",\n \"--format=%H|%(trailers:key=Entire-Checkpoint,valueonly)\",\n `${mergeCommit}^2`,\n \"--not\",\n `${mergeCommit}^1`\n );\n if (!logOut) return [];\n\n const cpIds = CheckpointReader.parseCheckpointTrailers(logOut);\n const sessions: SessionInfo[] = [];\n\n for (const cpId of cpIds) {\n sessions.push(...this.getSessionsForCheckpoint(cpId));\n }\n\n sessions.sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n return sessions;\n }\n\n /**\n * Sessions matching a specific checkpoint ID.\n */\n async resolveByCheckpoint(checkpointId: string): Promise<SessionInfo[]> {\n return this.getSessionsForCheckpoint(checkpointId);\n }\n\n /**\n * Find a session by its UUID.\n */\n async resolveBySessionId(sessionId: string): Promise<SessionInfo[]> {\n const cpIds = this.listAllCheckpointIds();\n\n for (const cpId of cpIds) {\n const sessions = this.getSessionsForCheckpoint(cpId);\n const match = sessions.find((s) => s.sessionId === sessionId);\n if (match) return [match];\n }\n\n return [];\n }\n\n /**\n * Latest N sessions across all checkpoints, sorted by createdAt descending.\n */\n async resolveLatest(count: number): Promise<SessionInfo[]> {\n const cpIds = this.listAllCheckpointIds();\n const all: SessionInfo[] = [];\n\n for (const cpId of cpIds) {\n all.push(...this.getSessionsForCheckpoint(cpId));\n }\n\n all.sort((a, b) => b.createdAt.localeCompare(a.createdAt));\n return all.slice(0, count);\n }\n\n /**\n * Read the full JSONL transcript content from the entire branch.\n */\n getTranscript(transcriptPath: string): string {\n const normalized = transcriptPath.startsWith(\"/\")\n ? transcriptPath.slice(1)\n : transcriptPath;\n return this.git(\"show\", `${ENTIRE_BRANCH}:${normalized}`);\n }\n}\n","const SYSTEM_TAG_PATTERNS: RegExp[] = [\n /<system-reminder>[\\s\\S]*?<\\/system-reminder>/g,\n /<local-command-caveat>[\\s\\S]*?<\\/local-command-caveat>/g,\n /<local-command-stdout>[\\s\\S]*?<\\/local-command-stdout>/g,\n /<command-name>[\\s\\S]*?<\\/command-name>/g,\n /<command-message>[\\s\\S]*?<\\/command-message>/g,\n /<user-prompt-submit-hook>[\\s\\S]*?<\\/user-prompt-submit-hook>/g,\n /<ide_selection>[\\s\\S]*?<\\/ide_selection>/g,\n /<ide_context>[\\s\\S]*?<\\/ide_context>/g,\n /<ide_opened_file>[\\s\\S]*?<\\/ide_opened_file>/g,\n /<cursor_context>[\\s\\S]*?<\\/cursor_context>/g,\n /<attached_files>[\\s\\S]*?<\\/attached_files>/g,\n /<repo_context>[\\s\\S]*?<\\/repo_context>/g,\n /<task-notification>[\\s\\S]*?<\\/task-notification>/g,\n];\n\nconst COMMAND_ARGS_RE = /<command-args>([\\s\\S]*?)<\\/command-args>/;\n\nexport function cleanSystemTags(text: string): string {\n const argsMatch = COMMAND_ARGS_RE.exec(text);\n const userArgs = argsMatch?.[1]?.trim() ?? \"\";\n text = text.replace(/<command-args>[\\s\\S]*?<\\/command-args>/g, \"\");\n for (const pat of SYSTEM_TAG_PATTERNS) {\n text = text.replace(new RegExp(pat.source, pat.flags), \"\");\n }\n text = text.trim();\n if (!text && userArgs) return userArgs;\n if (text && userArgs && text !== userArgs) return `${text}\\n${userArgs}`;\n return text || userArgs;\n}\n\nconst SKILL_INDICATORS = [\n \"Base directory for this skill:\",\n \"<HARD-GATE>\",\n \"## Checklist\",\n \"## Process Flow\",\n \"## Key Principles\",\n \"digraph brainstorming\",\n \"You MUST create a task for each\",\n];\n\nexport function isSkillPrompt(text: string): boolean {\n for (const indicator of SKILL_INDICATORS) {\n if (text.includes(indicator)) return true;\n }\n if (text.length > 2000) {\n const headerCount = (text.match(/## /g) || []).length;\n if (headerCount >= 3) return true;\n }\n return false;\n}\n\nexport function isNoiseMessage(text: string): boolean {\n const cleaned = cleanSystemTags(text);\n if (!cleaned) return true;\n if (/^(ready|ready\\.)$/i.test(cleaned)) return true;\n if (cleaned.includes(\"Tell your human partner that this command is deprecated\")) return true;\n if (cleaned.startsWith(\"Read the output file to retrieve the result:\")) return true;\n if (/^(opus|sonnet|haiku|claude)(\\[.*\\])?$/i.test(cleaned)) return true;\n return false;\n}\n","import type { ContextMode } from \"../context-provider.js\";\nimport { cleanSystemTags, isSkillPrompt, isNoiseMessage } from \"./message-cleaner.js\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface AssistantPart {\n type: \"text\" | \"edit\" | \"write\";\n content?: string;\n file?: string;\n old?: string;\n new?: string;\n fileContent?: string;\n}\n\nexport interface Turn {\n userText: string;\n userTimestamp: string;\n assistantParts: AssistantPart[];\n}\n\nexport interface ParseResult {\n turns: Turn[];\n branch: string;\n firstTimestamp: string;\n lastTimestamp: string;\n}\n\nexport interface SessionMarkdownInput {\n markdown: string;\n startTime: string;\n endTime: string;\n agent: string;\n turns: number;\n branch: string;\n files: string[];\n}\n\n// ─── Mode selection ────────────────────────────────────────────────────────────\n\n/**\n * Select rendering mode based on total turn count.\n * ≤10 → full\n * 11-25 → balanced\n * >25 → compact\n */\nexport function selectMode(totalTurns: number): ContextMode {\n if (totalTurns <= 10) return \"full\";\n if (totalTurns <= 25) return \"balanced\";\n return \"compact\";\n}\n\n// ─── Token estimation ─────────────────────────────────────────────────────────\n\nexport function estimateTokens(text: string): number {\n return Math.floor(text.length / 4);\n}\n\n// ─── Path helpers ─────────────────────────────────────────────────────────────\n\nfunction shortenPath(fp: string): string {\n const parts = fp.split(\"/\");\n if (parts.length >= 2) return parts.slice(-2).join(\"/\");\n return fp;\n}\n\nfunction countLines(s: string): number {\n const trimmed = s.trim();\n if (!trimmed) return 0;\n return trimmed.split(\"\\n\").length;\n}\n\n// ─── Content extraction ───────────────────────────────────────────────────────\n\ntype ContentBlock = { type: string; [key: string]: unknown };\n\nfunction extractText(content: unknown): string {\n if (typeof content === \"string\") return content;\n if (Array.isArray(content)) {\n return content\n .filter((b): b is ContentBlock => typeof b === \"object\" && b !== null && (b as ContentBlock).type === \"text\")\n .map((b) => (b as unknown as { text: string }).text)\n .join(\"\\n\");\n }\n return \"\";\n}\n\nfunction extractContentBlocks(content: unknown): ContentBlock[] {\n if (typeof content === \"string\") return [{ type: \"text\", text: content }];\n if (Array.isArray(content)) {\n return content.filter((b): b is ContentBlock => typeof b === \"object\" && b !== null);\n }\n return [];\n}\n\nfunction isToolResultOnly(content: unknown): boolean {\n if (typeof content === \"string\") return false;\n if (!Array.isArray(content)) return true;\n for (const block of content) {\n if (typeof block === \"object\" && block !== null) {\n const b = block as ContentBlock;\n if (b.type === \"text\" && typeof b.text === \"string\" && (b.text as string).trim()) return false;\n if (b.type === \"image\") return false;\n }\n }\n return true;\n}\n\nfunction hasImage(content: unknown): boolean {\n if (!Array.isArray(content)) return false;\n return content.some((b) => typeof b === \"object\" && b !== null && (b as ContentBlock).type === \"image\");\n}\n\n// ─── Format functions ─────────────────────────────────────────────────────────\n\nfunction formatEditFull(filePath: string, oldStr: string, newStr: string): string {\n const lines: string[] = [];\n lines.push(`✏️ \\`${filePath}\\``);\n lines.push(\"```diff\");\n for (const line of oldStr.split(\"\\n\")) lines.push(`- ${line}`);\n for (const line of newStr.split(\"\\n\")) lines.push(`+ ${line}`);\n lines.push(\"```\");\n return lines.join(\"\\n\");\n}\n\nfunction formatEditBalanced(filePath: string, oldStr: string, newStr: string, maxDiffLines = 12): string {\n const oldLines = oldStr.split(\"\\n\");\n const newLines = newStr.split(\"\\n\");\n const total = oldLines.length + newLines.length;\n const lines: string[] = [];\n lines.push(`✏️ \\`${filePath}\\``);\n lines.push(\"```diff\");\n if (total <= maxDiffLines) {\n for (const line of oldLines) lines.push(`- ${line}`);\n for (const line of newLines) lines.push(`+ ${line}`);\n } else {\n const half = Math.floor(maxDiffLines / 2);\n for (const line of oldLines.slice(0, half)) lines.push(`- ${line}`);\n if (oldLines.length > half) lines.push(` ... (-${oldLines.length} lines total)`);\n for (const line of newLines.slice(0, half)) lines.push(`+ ${line}`);\n if (newLines.length > half) lines.push(` ... (+${newLines.length} lines total)`);\n }\n lines.push(\"```\");\n return lines.join(\"\\n\");\n}\n\nfunction formatEditCompact(filePath: string, oldStr: string, newStr: string): string {\n const oldLines = countLines(oldStr);\n const newLines = countLines(newStr);\n let firstNew = \"\";\n for (const line of newStr.split(\"\\n\")) {\n const stripped = line.trim();\n if (stripped && !stripped.startsWith(\"//\") && !stripped.startsWith(\"*\")) {\n firstNew = stripped.slice(0, 80);\n break;\n }\n }\n if (firstNew) {\n return `✏️ \\`${filePath}\\` (-${oldLines}/+${newLines} lines): \\`${firstNew}\\``;\n }\n return `✏️ \\`${filePath}\\` (-${oldLines}/+${newLines} lines)`;\n}\n\nfunction formatWriteFull(filePath: string, content: string): string {\n const lines: string[] = [];\n lines.push(`📝 \\`${filePath}\\``);\n lines.push(\"```\");\n lines.push(content);\n lines.push(\"```\");\n return lines.join(\"\\n\");\n}\n\nfunction formatWriteBalanced(filePath: string, content: string, maxLines = 15): string {\n const contentLines = content.split(\"\\n\");\n const lines: string[] = [];\n lines.push(`📝 \\`${filePath}\\` (${contentLines.length} lines)`);\n lines.push(\"```\");\n for (const line of contentLines.slice(0, maxLines)) lines.push(line);\n if (contentLines.length > maxLines) lines.push(`... (${contentLines.length - maxLines} more lines)`);\n lines.push(\"```\");\n return lines.join(\"\\n\");\n}\n\nfunction formatWriteCompact(filePath: string, content: string): string {\n const numLines = countLines(content);\n return `📝 \\`${filePath}\\` (${numLines} lines written)`;\n}\n\n// ─── Parser ───────────────────────────────────────────────────────────────────\n\ninterface RawEvent {\n type?: string;\n message?: { role?: string; content?: unknown };\n timestamp?: string;\n uuid?: string;\n parentUuid?: string | null;\n sessionId?: string;\n gitBranch?: string;\n}\n\nexport function parseJsonlToTurns(jsonl: string): ParseResult {\n const events: RawEvent[] = [];\n for (const rawLine of jsonl.split(\"\\n\")) {\n const line = rawLine.trim();\n if (!line) continue;\n try {\n events.push(JSON.parse(line) as RawEvent);\n } catch {\n // skip invalid JSON lines\n }\n }\n\n // Extract gitBranch from first event that has it\n let branch = \"unknown\";\n for (const e of events) {\n if (e.gitBranch) {\n branch = e.gitBranch;\n break;\n }\n }\n\n const convEvents = events.filter((e) => e.type === \"user\" || e.type === \"assistant\");\n\n const turns: Turn[] = [];\n let currentTurn: Turn | null = null;\n\n for (const e of convEvents) {\n const etype = e.type;\n const content = e.message?.content ?? [];\n const ts = e.timestamp ?? \"\";\n\n if (etype === \"user\") {\n if (isToolResultOnly(content)) continue;\n\n const text = extractText(content);\n\n if (isSkillPrompt(text)) continue;\n if (isNoiseMessage(text)) continue;\n\n const cleaned = cleanSystemTags(text);\n if (!cleaned) continue;\n\n // Push previous turn if any\n if (currentTurn) turns.push(currentTurn);\n\n const imgSuffix = hasImage(content) ? \" [image]\" : \"\";\n currentTurn = {\n userText: cleaned + imgSuffix,\n userTimestamp: ts,\n assistantParts: [],\n };\n } else if (etype === \"assistant\" && currentTurn) {\n const blocks = extractContentBlocks(content);\n let pendingText: string | null = null;\n\n for (const block of blocks) {\n const btype = block.type;\n\n if (btype === \"text\") {\n const text = typeof block.text === \"string\" ? (block.text as string).trim() : \"\";\n if (text) pendingText = text;\n } else if (btype === \"tool_use\") {\n const name = typeof block.name === \"string\" ? block.name : \"\";\n const inp = (typeof block.input === \"object\" && block.input !== null ? block.input : {}) as Record<string, string>;\n\n if (name === \"Edit\") {\n if (pendingText) {\n currentTurn.assistantParts.push({ type: \"text\", content: pendingText });\n pendingText = null;\n }\n currentTurn.assistantParts.push({\n type: \"edit\",\n file: shortenPath(inp.file_path ?? \"\"),\n old: inp.old_string ?? \"\",\n new: inp.new_string ?? \"\",\n });\n } else if (name === \"Write\") {\n if (pendingText) {\n currentTurn.assistantParts.push({ type: \"text\", content: pendingText });\n pendingText = null;\n }\n currentTurn.assistantParts.push({\n type: \"write\",\n file: shortenPath(inp.file_path ?? \"\"),\n fileContent: inp.content ?? \"\",\n });\n }\n // Skip Read, Bash, Grep, Glob, etc.\n }\n }\n\n if (pendingText) {\n currentTurn.assistantParts.push({ type: \"text\", content: pendingText });\n }\n }\n }\n\n if (currentTurn) turns.push(currentTurn);\n\n const firstTimestamp = turns[0]?.userTimestamp ?? \"\";\n const lastTimestamp = turns[turns.length - 1]?.userTimestamp ?? \"\";\n\n return { turns, branch, firstTimestamp, lastTimestamp };\n}\n\n// ─── Markdown builder ─────────────────────────────────────────────────────────\n\nexport function buildSessionMarkdown(turns: Turn[], mode: ContextMode): string {\n const out: string[] = [];\n\n for (let i = 0; i < turns.length; i++) {\n const turn = turns[i];\n const userText = turn.userText.trim();\n if (!userText) continue;\n\n out.push(`**User [${i + 1}]:**`);\n out.push(userText);\n out.push(\"\");\n\n let hasContent = false;\n\n for (const part of turn.assistantParts) {\n if (part.type === \"text\") {\n if (!hasContent) {\n out.push(\"**Assistant:**\");\n hasContent = true;\n }\n out.push(part.content ?? \"\");\n out.push(\"\");\n } else if (part.type === \"edit\") {\n if (!hasContent) {\n out.push(\"**Assistant:**\");\n hasContent = true;\n }\n const file = part.file ?? \"\";\n const oldStr = part.old ?? \"\";\n const newStr = part.new ?? \"\";\n if (mode === \"full\") {\n out.push(formatEditFull(file, oldStr, newStr));\n } else if (mode === \"balanced\") {\n out.push(formatEditBalanced(file, oldStr, newStr));\n } else {\n out.push(formatEditCompact(file, oldStr, newStr));\n }\n out.push(\"\");\n } else if (part.type === \"write\") {\n if (!hasContent) {\n out.push(\"**Assistant:**\");\n hasContent = true;\n }\n const file = part.file ?? \"\";\n const content = part.fileContent ?? \"\";\n if (mode === \"full\") {\n out.push(formatWriteFull(file, content));\n } else if (mode === \"balanced\") {\n out.push(formatWriteBalanced(file, content));\n } else {\n out.push(formatWriteCompact(file, content));\n }\n out.push(\"\");\n }\n }\n\n out.push(\"---\");\n out.push(\"\");\n }\n\n return out.join(\"\\n\");\n}\n\n// ─── Session merger ───────────────────────────────────────────────────────────\n\nconst DISCLAIMER = `> **Note:** This conversation history may contain outdated information. File contents, code, and project state may have changed since these sessions were recorded. Use this as context only — always verify against current files before acting.`;\n\nexport function mergeSessionsMarkdown(\n sessions: SessionMarkdownInput[],\n mode: ContextMode,\n title: string\n): string {\n // Sort sessions chronologically (oldest first)\n const sorted = [...sessions].sort((a, b) => a.startTime.localeCompare(b.startTime));\n\n const totalTurns = sorted.reduce((sum, s) => sum + s.turns, 0);\n const overallStart = sorted[0]?.startTime.slice(0, 16) ?? \"?\";\n const overallEnd = sorted[sorted.length - 1]?.endTime.slice(0, 16) ?? \"?\";\n\n const out: string[] = [];\n out.push(`# Conversation History from ${title}`);\n out.push(`${sorted.length} sessions | ${totalTurns} turns | ${overallStart} → ${overallEnd} | mode: ${mode}`);\n out.push(\"\");\n\n for (let i = 0; i < sorted.length; i++) {\n const s = sorted[i];\n const start = s.startTime.slice(0, 16);\n const end = s.endTime.slice(0, 16);\n out.push(`## Session Conversation History ${i + 1} — ${start} → ${end} (${s.agent}, ${s.turns} turns, branch: ${s.branch})`);\n out.push(\"\");\n out.push(s.markdown);\n }\n\n out.push(DISCLAIMER);\n out.push(\"\");\n\n return out.join(\"\\n\");\n}\n","import type { ContextProvider, ContextQuery, ContextOptions, ContextResult, SessionListResult, SessionInfo } from \"../context-provider.js\";\nimport type { ContextMode } from \"../context-provider.js\";\nimport { DEFAULT_MAX_TOKENS, TOKENS_PER_TURN_ESTIMATE } from \"../context-provider.js\";\nimport { CheckpointReader } from \"./checkpoint-reader.js\";\nimport { parseJsonlToTurns, buildSessionMarkdown, mergeSessionsMarkdown, selectMode, estimateTokens, type SessionMarkdownInput } from \"./conversation-builder.js\";\n\nexport class EntireProvider implements ContextProvider {\n readonly name = \"entire\";\n\n async isAvailable(repoPath: string): Promise<boolean> {\n return new CheckpointReader(repoPath).hasEntireBranch();\n }\n\n async listSessions(query: ContextQuery): Promise<SessionListResult> {\n const reader = new CheckpointReader(query.repoPath);\n const sessions = await this.resolveSessions(reader, query);\n const estimatedTokens = sessions.reduce((sum, s) => sum + s.turnCount * TOKENS_PER_TURN_ESTIMATE, 0);\n return { sessions, estimatedTokens };\n }\n\n async buildContext(query: ContextQuery, options?: ContextOptions): Promise<ContextResult> {\n const maxTokens = options?.maxTokens ?? DEFAULT_MAX_TOKENS;\n const reader = new CheckpointReader(query.repoPath);\n let sessions = await this.resolveSessions(reader, query);\n\n if (options?.limit && sessions.length > options.limit) {\n sessions = sessions.slice(-options.limit);\n }\n\n if (sessions.length === 0) {\n return { markdown: \"\", tokenEstimate: 0, sessionCount: 0, totalTurns: 0, mode: \"full\", truncated: false, timeRange: { start: \"\", end: \"\" } };\n }\n\n // Rebuild each session, cache parsed turns for potential re-render\n const parsedSessions: { session: SessionInfo; jsonl: string; }[] = [];\n for (const sess of sessions) {\n const jsonl = reader.getTranscript(sess.transcriptPath);\n if (jsonl) parsedSessions.push({ session: sess, jsonl });\n }\n\n if (parsedSessions.length === 0) {\n return { markdown: \"\", tokenEstimate: 0, sessionCount: 0, totalTurns: 0, mode: \"full\", truncated: false, timeRange: { start: \"\", end: \"\" } };\n }\n\n const totalTurns = parsedSessions.reduce((sum, ps) => {\n const parsed = parseJsonlToTurns(ps.jsonl);\n return sum + parsed.turns.length;\n }, 0);\n\n let mode = selectMode(totalTurns);\n const title = this.buildTitle(query);\n\n // Build markdown for each session\n let sessionMarkdowns = this.buildSessionMarkdowns(parsedSessions, mode);\n let merged = mergeSessionsMarkdown(sessionMarkdowns, mode, title);\n let tokens = estimateTokens(merged);\n\n // Auto-downgrade to compact if over budget\n if (tokens > maxTokens && mode !== \"compact\") {\n mode = \"compact\";\n sessionMarkdowns = this.buildSessionMarkdowns(parsedSessions, \"compact\");\n merged = mergeSessionsMarkdown(sessionMarkdowns, \"compact\", title);\n tokens = estimateTokens(merged);\n }\n\n // Truncate oldest sessions if still over budget\n let truncated = false;\n while (tokens > maxTokens && sessionMarkdowns.length > 1) {\n sessionMarkdowns = sessionMarkdowns.slice(1);\n truncated = true;\n merged = mergeSessionsMarkdown(sessionMarkdowns, mode, title);\n tokens = estimateTokens(merged);\n }\n\n const allTimes = sessionMarkdowns.flatMap(s => [s.startTime, s.endTime]).filter(Boolean).sort();\n const finalTurns = sessionMarkdowns.reduce((sum, s) => sum + s.turns, 0);\n\n return {\n markdown: merged,\n tokenEstimate: tokens,\n sessionCount: sessionMarkdowns.length,\n totalTurns: finalTurns,\n mode,\n truncated,\n timeRange: { start: allTimes[0] ?? \"\", end: allTimes[allTimes.length - 1] ?? \"\" },\n };\n }\n\n private buildSessionMarkdowns(parsedSessions: { session: SessionInfo; jsonl: string }[], mode: ContextMode): SessionMarkdownInput[] {\n return parsedSessions.map(ps => {\n const parsed = parseJsonlToTurns(ps.jsonl);\n return {\n markdown: buildSessionMarkdown(parsed.turns, mode),\n startTime: parsed.firstTimestamp,\n endTime: parsed.lastTimestamp,\n agent: ps.session.agent,\n turns: parsed.turns.length,\n branch: ps.session.branch,\n files: ps.session.filesTouched.map(f => f.split(\"/\").pop() ?? f),\n };\n });\n }\n\n private async resolveSessions(reader: CheckpointReader, query: ContextQuery): Promise<SessionInfo[]> {\n switch (query.type) {\n case \"branch\": return reader.resolveByBranch(query.value);\n case \"commit\": return reader.resolveByCommit(query.value);\n case \"pr\": return reader.resolveByPr(query.value);\n case \"checkpoint\": return reader.resolveByCheckpoint(query.value);\n case \"session\": return reader.resolveBySessionId(query.value);\n case \"latest\": return reader.resolveLatest(parseInt(query.value) || 5);\n default: return [];\n }\n }\n\n private buildTitle(query: ContextQuery): string {\n switch (query.type) {\n case \"pr\": return `PR #${query.value.replace(/.*\\/pull\\//, \"\")}`;\n case \"branch\": return `branch \\`${query.value}\\``;\n case \"commit\": return `commit \\`${query.value.slice(0, 8)}\\``;\n case \"checkpoint\": return `checkpoint \\`${query.value}\\``;\n case \"session\": return `session \\`${query.value.slice(0, 8)}...\\``;\n case \"latest\": return `latest ${query.value} sessions`;\n default: return \"unknown\";\n }\n }\n}\n","import type { ContextMode } from \"../context-provider.js\";\nimport type { Turn, Step, ToolCallStep } from \"./types.js\";\n\nexport function selectLevel(turnCount: number): ContextMode {\n if (turnCount <= 10) return \"full\";\n if (turnCount <= 25) return \"balanced\";\n return \"compact\";\n}\n\nexport function estimateTokens(text: string): number {\n return Math.floor(text.length / 4);\n}\n\nexport function buildHistoryMarkdown(turns: Turn[], mode: ContextMode): string {\n if (turns.length === 0) return \"\";\n switch (mode) {\n case \"full\":\n return buildFull(turns);\n case \"balanced\":\n return buildBalanced(turns);\n case \"compact\":\n return buildCompact(turns);\n }\n}\n\n// ─── Full Mode ───────────────────────────────────────────────────────────────\n\nfunction buildFull(turns: Turn[]): string {\n const out: string[] = [];\n let userIndex = 0;\n\n for (const turn of turns) {\n if (turn.role === \"user\") {\n userIndex++;\n out.push(`**User [${userIndex}]:**`);\n out.push(turn.content ?? \"\");\n if (turn.attachments?.length) {\n out.push(turn.attachments.map((a) => `[${a.type}: ${a.fileName}]`).join(\" \"));\n }\n out.push(\"\");\n } else if (turn.role === \"assistant\" && turn.steps?.length) {\n out.push(\"**Assistant:**\");\n\n for (const step of turn.steps) {\n out.push(renderStepFull(step));\n }\n\n if (turn.usage) {\n const parts: string[] = [];\n if (turn.usage.tokensUsed) parts.push(`${turn.usage.tokensUsed.toLocaleString()} tokens`);\n if (turn.usage.cost) parts.push(`$${turn.usage.cost.amount.toFixed(4)}`);\n if (parts.length) out.push(`**Usage**: ${parts.join(\", \")}`);\n }\n\n out.push(\"\");\n out.push(\"---\");\n out.push(\"\");\n }\n }\n\n return out.join(\"\\n\");\n}\n\nfunction renderStepFull(step: Step): string {\n switch (step.type) {\n case \"thinking\":\n return `> **Thinking**: ${step.content}\\n`;\n case \"text\":\n return `${step.content}\\n`;\n case \"tool_call\":\n return renderToolCallFull(step);\n case \"plan\":\n return renderPlan(step.entries);\n case \"image\":\n return `[Image: ${step.mimeType}]\\n`;\n case \"audio\":\n return `[Audio: ${step.mimeType}]\\n`;\n case \"resource\":\n return `[Resource: ${step.name}] ${step.uri}\\n`;\n case \"resource_link\":\n return `[Resource Link: ${step.name}] ${step.uri}\\n`;\n case \"mode_change\":\n return `*Mode changed to: ${step.modeId}*\\n`;\n case \"config_change\":\n return `*Config ${step.configId} set to: ${step.value}*\\n`;\n }\n}\n\nfunction renderToolCallFull(step: ToolCallStep): string {\n const lines: string[] = [];\n const loc = step.locations?.[0];\n const locStr = loc ? (loc.line ? `${loc.path}:${loc.line}` : loc.path) : \"\";\n\n if (step.diff) {\n lines.push(`**[${step.name}]** \\`${locStr || step.diff.path}\\``);\n lines.push(\"```diff\");\n if (step.diff.oldText) {\n for (const line of step.diff.oldText.split(\"\\n\")) lines.push(`- ${line}`);\n }\n for (const line of step.diff.newText.split(\"\\n\")) lines.push(`+ ${line}`);\n lines.push(\"```\");\n } else {\n lines.push(`**[${step.name}]** \\`${locStr}\\``);\n }\n\n if (step.permission) {\n lines.push(`*Permission: ${step.permission.outcome}*`);\n }\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\nfunction renderPlan(entries: { content: string; priority: string; status: string }[]): string {\n const lines = [\"**Plan:**\"];\n for (const e of entries) {\n const icon = e.status === \"completed\" || e.status === \"done\" ? \"✅\" : e.status === \"in_progress\" ? \"🔄\" : \"⬜\";\n lines.push(`${icon} ${e.content} (${e.priority})`);\n }\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\n// ─── Balanced Mode ───────────────────────────────────────────────────────────\n\nfunction buildBalanced(turns: Turn[]): string {\n const out: string[] = [];\n let userIndex = 0;\n\n for (const turn of turns) {\n if (turn.role === \"user\") {\n userIndex++;\n out.push(`**User [${userIndex}]:**`);\n out.push(turn.content ?? \"\");\n out.push(\"\");\n } else if (turn.role === \"assistant\" && turn.steps?.length) {\n out.push(\"**Assistant:**\");\n\n for (const step of turn.steps) {\n if (step.type === \"thinking\") continue;\n\n if (step.type === \"text\") {\n out.push(step.content);\n } else if (step.type === \"tool_call\") {\n out.push(renderToolCallBalanced(step));\n } else if (step.type === \"plan\") {\n out.push(renderPlan(step.entries));\n } else {\n out.push(renderStepFull(step));\n }\n }\n\n out.push(\"\");\n out.push(\"---\");\n out.push(\"\");\n }\n }\n\n return out.join(\"\\n\");\n}\n\nfunction renderToolCallBalanced(step: ToolCallStep): string {\n const loc = step.locations?.[0];\n const locStr = loc ? (loc.line ? `${loc.path}:${loc.line}` : loc.path) : \"\";\n\n if (step.diff) {\n const oldLines = step.diff.oldText?.split(\"\\n\").length ?? 0;\n const newLines = step.diff.newText.split(\"\\n\").length;\n return `- ${step.name} \\`${locStr || step.diff.path}\\` (-${oldLines}/+${newLines} lines)`;\n }\n\n return `- ${step.name} \\`${locStr}\\``;\n}\n\n// ─── Compact Mode ────────────────────────────────────────────────────────────\n\nfunction buildCompact(turns: Turn[]): string {\n const out: string[] = [];\n let i = 0;\n\n while (i < turns.length) {\n const turn = turns[i];\n if (turn.role === \"user\") {\n const userText = (turn.content ?? \"\").slice(0, 100);\n const nextTurn = turns[i + 1];\n if (nextTurn?.role === \"assistant\" && nextTurn.steps?.length) {\n const tools = nextTurn.steps\n .filter((s) => s.type === \"tool_call\")\n .map((s) => (s as ToolCallStep).name);\n const texts = nextTurn.steps\n .filter((s) => s.type === \"text\")\n .map((s) => (s as { content: string }).content.slice(0, 80));\n const parts: string[] = [];\n if (tools.length) parts.push(tools.join(\", \"));\n if (texts.length) parts.push(texts.join(\" \"));\n out.push(`User: ${userText} → Assistant: ${parts.join(\" | \")}`);\n i += 2;\n } else {\n out.push(`User: ${userText}`);\n i++;\n }\n } else {\n i++;\n }\n }\n\n return out.join(\"\\n\");\n}\n","import type { SessionRecord } from \"../../../core/types.js\";\nimport type {\n ContextProvider,\n ContextQuery,\n ContextOptions,\n ContextResult,\n ContextMode,\n SessionInfo,\n SessionListResult,\n} from \"../context-provider.js\";\nimport { DEFAULT_MAX_TOKENS, TOKENS_PER_TURN_ESTIMATE } from \"../context-provider.js\";\nimport { HistoryStore } from \"./history-store.js\";\nimport {\n buildHistoryMarkdown,\n selectLevel,\n estimateTokens,\n} from \"./history-context-builder.js\";\n\nconst EMPTY_RESULT: ContextResult = {\n markdown: \"\",\n tokenEstimate: 0,\n sessionCount: 0,\n totalTurns: 0,\n mode: \"full\",\n truncated: false,\n timeRange: { start: \"\", end: \"\" },\n};\n\nexport class HistoryProvider implements ContextProvider {\n readonly name = \"local\";\n\n constructor(\n private readonly store: HistoryStore,\n private readonly getSessionRecords: () => SessionRecord[]\n ) {}\n\n async isAvailable(_repoPath: string): Promise<boolean> {\n return true;\n }\n\n async listSessions(query: ContextQuery): Promise<SessionListResult> {\n if (!this.isSupportedType(query.type)) {\n return { sessions: [], estimatedTokens: 0 };\n }\n\n const candidates = await this.resolveCandidates(query);\n const sessions: SessionInfo[] = [];\n let estimatedTokens = 0;\n\n for (const record of candidates) {\n const history = await this.store.read(record.sessionId);\n if (!history) continue;\n const turnCount = history.turns.length;\n const tokenEstimate = turnCount * TOKENS_PER_TURN_ESTIMATE;\n sessions.push(this.toSessionInfo(record, turnCount));\n estimatedTokens += tokenEstimate;\n }\n\n return { sessions, estimatedTokens };\n }\n\n async buildContext(query: ContextQuery, options?: ContextOptions): Promise<ContextResult> {\n if (!this.isSupportedType(query.type)) {\n return { ...EMPTY_RESULT };\n }\n\n const maxTokens = options?.maxTokens ?? DEFAULT_MAX_TOKENS;\n const candidates = await this.resolveCandidates(query, options?.limit);\n\n // Load histories for sessions that have files\n type LoadedSession = {\n record: SessionRecord;\n history: import(\"./types.js\").SessionHistory;\n };\n\n const loaded: LoadedSession[] = [];\n for (const record of candidates) {\n const history = await this.store.read(record.sessionId);\n if (history) {\n loaded.push({ record, history });\n }\n }\n\n if (loaded.length === 0) {\n return { ...EMPTY_RESULT };\n }\n\n const totalTurns = loaded.reduce((sum, s) => sum + s.history.turns.length, 0);\n const labelAgent = options?.labelAgent ?? false;\n\n // Auto-select mode based on total turn count\n let mode: ContextMode = selectLevel(totalTurns);\n\n // Build markdown with selected mode\n let markdown = this.buildMergedMarkdown(loaded, mode, query, labelAgent);\n let tokenEstimate = estimateTokens(markdown);\n\n // Downgrade to compact if over budget\n if (tokenEstimate > maxTokens && mode !== \"compact\") {\n mode = \"compact\";\n markdown = this.buildMergedMarkdown(loaded, mode, query, labelAgent);\n tokenEstimate = estimateTokens(markdown);\n }\n\n // Truncate oldest sessions if still over budget\n let truncated = false;\n let activeSessions = [...loaded];\n while (tokenEstimate > maxTokens && activeSessions.length > 1) {\n // Remove the oldest session (last in list, sorted newest-first)\n activeSessions = activeSessions.slice(0, activeSessions.length - 1);\n markdown = this.buildMergedMarkdown(activeSessions, mode, query, labelAgent);\n tokenEstimate = estimateTokens(markdown);\n truncated = true;\n }\n\n const timeRange = this.computeTimeRange(activeSessions.map((s) => s.record));\n\n return {\n markdown,\n tokenEstimate,\n sessionCount: activeSessions.length,\n totalTurns: activeSessions.reduce((sum, s) => sum + s.history.turns.length, 0),\n mode,\n truncated,\n timeRange,\n };\n }\n\n // ─── Private helpers ─────────────────────────────────────────────────────────\n\n private isSupportedType(type: ContextQuery[\"type\"]): boolean {\n return type === \"session\" || type === \"latest\";\n }\n\n private async resolveCandidates(query: ContextQuery, limit?: number): Promise<SessionRecord[]> {\n const all = this.getSessionRecords();\n\n if (query.type === \"session\") {\n const found = all.find((r) => r.sessionId === query.value);\n return found ? [found] : [];\n }\n\n // latest: sort by lastActiveAt descending, take N\n const n = limit ?? (parseInt(query.value, 10) || 5);\n const sorted = [...all].sort(\n (a, b) => new Date(b.lastActiveAt).getTime() - new Date(a.lastActiveAt).getTime()\n );\n return sorted.slice(0, n);\n }\n\n private toSessionInfo(record: SessionRecord, turnCount: number): SessionInfo {\n return {\n checkpointId: \"\",\n sessionIndex: \"\",\n transcriptPath: \"\",\n createdAt: record.createdAt,\n endedAt: record.lastActiveAt,\n branch: \"\",\n agent: record.agentName,\n turnCount,\n filesTouched: [],\n sessionId: record.sessionId,\n };\n }\n\n private buildMergedMarkdown(\n sessions: Array<{ record: SessionRecord; history: import(\"./types.js\").SessionHistory }>,\n mode: ContextMode,\n query: ContextQuery,\n labelAgent = false\n ): string {\n if (sessions.length === 0) return \"\";\n\n const totalTurns = sessions.reduce((sum, s) => sum + s.history.turns.length, 0);\n const title = query.type === \"session\" ? query.value : `latest ${sessions.length} sessions`;\n\n const parts: string[] = [];\n parts.push(`# Conversation History — ${title}`);\n parts.push(`${sessions.length} sessions | ${totalTurns} turns | mode: ${mode}`);\n parts.push(\"\");\n\n for (let i = 0; i < sessions.length; i++) {\n const { record, history } = sessions[i];\n\n parts.push(`## Session ${i + 1} — ${record.agentName} · ${record.sessionId} (${history.turns.length} turns)`);\n parts.push(\"\");\n\n if (labelAgent && history.turns.length > 0) {\n const agentTimeline = this.buildAgentTimeline(record);\n const labeledMd = this.buildLabeledHistoryMarkdown(history.turns, mode, agentTimeline);\n if (labeledMd) {\n parts.push(labeledMd);\n }\n } else {\n const sessionMd = buildHistoryMarkdown(history.turns, mode);\n if (sessionMd) {\n parts.push(sessionMd);\n }\n }\n }\n\n parts.push(\n \"> **Note:** This conversation history may contain outdated information. Verify current state before acting on past context.\"\n );\n\n return parts.join(\"\\n\");\n }\n\n /**\n * Build a timeline of agent boundaries from the session record.\n * Returns sorted entries: [{ agentName, startedAt }] where startedAt is the\n * ISO timestamp when that agent started handling the session.\n *\n * The first agent runs from session creation until the first switch.\n * Each agentSwitchHistory entry records when the *previous* agent was switched away,\n * so the next agent starts at that switchedAt timestamp.\n */\n private buildAgentTimeline(record: SessionRecord): Array<{ agentName: string; switchedAt: number }> {\n const timeline: Array<{ agentName: string; switchedAt: number }> = [];\n\n // The first agent starts at the beginning of time (0)\n const firstAgentName = record.firstAgent ?? record.agentName;\n timeline.push({ agentName: firstAgentName, switchedAt: 0 });\n\n if (record.agentSwitchHistory && record.agentSwitchHistory.length > 0) {\n // Each entry in agentSwitchHistory records a *completed* agent stint:\n // { agentName: \"claude\", switchedAt: \"...\", ... } means claude was active\n // and was switched away at switchedAt. The next agent in sequence starts at that time.\n //\n // To reconstruct: after the last switchHistory entry, the current record.agentName is active.\n // But we need to map turns to agents, so we build boundaries.\n\n for (let i = 0; i < record.agentSwitchHistory.length; i++) {\n const entry = record.agentSwitchHistory[i];\n const switchTime = new Date(entry.switchedAt).getTime();\n\n // Determine which agent comes after this switch\n const nextAgent = i < record.agentSwitchHistory.length - 1\n ? record.agentSwitchHistory[i + 1].agentName\n : record.agentName; // current agent is the last one\n\n timeline.push({ agentName: nextAgent, switchedAt: switchTime });\n }\n }\n\n return timeline;\n }\n\n /**\n * Determine which agent produced a turn based on its timestamp and the agent timeline.\n */\n private resolveAgentForTurn(\n turnTimestamp: string,\n timeline: Array<{ agentName: string; switchedAt: number }>\n ): string {\n const turnTime = new Date(turnTimestamp).getTime();\n\n // Walk backward through the timeline to find the last boundary before this turn\n for (let i = timeline.length - 1; i >= 0; i--) {\n if (turnTime >= timeline[i].switchedAt) {\n return timeline[i].agentName;\n }\n }\n\n // Fallback to first agent\n return timeline[0].agentName;\n }\n\n /**\n * Build history markdown with agent labels inserted at agent boundaries.\n */\n private buildLabeledHistoryMarkdown(\n turns: import(\"./types.js\").Turn[],\n mode: ContextMode,\n agentTimeline: Array<{ agentName: string; switchedAt: number }>\n ): string {\n // If there's only one agent (no switches), just add a single label\n if (agentTimeline.length <= 1) {\n const label = `### [${agentTimeline[0]?.agentName ?? \"unknown\"}]\\n`;\n const md = buildHistoryMarkdown(turns, mode);\n return md ? label + \"\\n\" + md : label;\n }\n\n // Group turns by agent segments, then render each segment with a label\n const segments: Array<{ agentName: string; turns: import(\"./types.js\").Turn[] }> = [];\n let currentAgent = \"\";\n\n for (const turn of turns) {\n const agent = this.resolveAgentForTurn(turn.timestamp, agentTimeline);\n if (agent !== currentAgent) {\n segments.push({ agentName: agent, turns: [] });\n currentAgent = agent;\n }\n segments[segments.length - 1].turns.push(turn);\n }\n\n const parts: string[] = [];\n for (const segment of segments) {\n parts.push(`### [${segment.agentName}]`);\n parts.push(\"\");\n const md = buildHistoryMarkdown(segment.turns, mode);\n if (md) {\n parts.push(md);\n }\n }\n\n return parts.join(\"\\n\");\n }\n\n private computeTimeRange(\n records: SessionRecord[]\n ): { start: string; end: string } {\n if (records.length === 0) return { start: \"\", end: \"\" };\n\n const dates = records.map((r) => r.createdAt).filter(Boolean);\n const ends = records.map((r) => r.lastActiveAt).filter(Boolean);\n\n const start = dates.sort()[0] ?? \"\";\n const end = ends.sort().reverse()[0] ?? \"\";\n\n return { start, end };\n }\n}\n","import type { AgentEvent, Attachment } from \"../../../core/types.js\";\nimport type { HistoryStore } from \"./history-store.js\";\nimport type {\n HistoryAttachment,\n ResourceLinkStep,\n ResourceStep,\n SessionHistory,\n Step,\n ToolCallStep,\n Turn,\n} from \"./types.js\";\n\nexport interface RecorderState {\n history: SessionHistory;\n currentAssistantTurn: Turn | null;\n}\n\nfunction toHistoryAttachment(att: Attachment): HistoryAttachment {\n return {\n type: att.type,\n fileName: att.fileName,\n mimeType: att.mimeType,\n size: att.size,\n };\n}\n\nfunction extractDiff(\n content: unknown,\n): { path: string; oldText?: string; newText: string } | null {\n if (!Array.isArray(content)) return null;\n for (const item of content) {\n if (\n item &&\n typeof item === \"object\" &&\n (item as Record<string, unknown>).type === \"diff\"\n ) {\n const d = item as Record<string, unknown>;\n if (typeof d.path === \"string\" && typeof d.newText === \"string\") {\n const result: { path: string; oldText?: string; newText: string } = {\n path: d.path,\n newText: d.newText,\n };\n if (typeof d.oldText === \"string\") result.oldText = d.oldText;\n return result;\n }\n }\n }\n return null;\n}\n\nfunction extractLocations(\n locations: unknown,\n): { path: string; line?: number }[] | undefined {\n if (!Array.isArray(locations)) return undefined;\n const result: { path: string; line?: number }[] = [];\n for (const loc of locations) {\n if (loc && typeof loc === \"object\" && typeof (loc as any).path === \"string\") {\n const entry: { path: string; line?: number } = { path: (loc as any).path };\n if (typeof (loc as any).line === \"number\") entry.line = (loc as any).line;\n result.push(entry);\n }\n }\n return result.length > 0 ? result : undefined;\n}\n\nconst IGNORED_TYPES = new Set([\n \"session_end\",\n \"error\",\n \"system_message\",\n \"commands_update\",\n \"session_info_update\",\n \"model_update\",\n \"user_message_chunk\",\n \"tts_strip\",\n]);\n\nexport class HistoryRecorder {\n private states = new Map<string, RecorderState>();\n\n constructor(private readonly store: HistoryStore) {}\n\n onBeforePrompt(\n sessionId: string,\n text: string,\n attachments: Attachment[] | undefined,\n ): void {\n let state = this.states.get(sessionId);\n if (!state) {\n state = {\n history: { version: 1, sessionId, turns: [] },\n currentAssistantTurn: null,\n };\n this.states.set(sessionId, state);\n }\n\n const userTurn: Turn = {\n index: state.history.turns.length,\n role: \"user\",\n timestamp: new Date().toISOString(),\n content: text,\n };\n if (attachments && attachments.length > 0) {\n userTurn.attachments = attachments.map(toHistoryAttachment);\n }\n state.history.turns.push(userTurn);\n\n const assistantTurn: Turn = {\n index: state.history.turns.length,\n role: \"assistant\",\n timestamp: new Date().toISOString(),\n steps: [],\n };\n state.history.turns.push(assistantTurn);\n state.currentAssistantTurn = assistantTurn;\n }\n\n onAfterEvent(sessionId: string, event: AgentEvent): void {\n const state = this.states.get(sessionId);\n if (!state || !state.currentAssistantTurn) return;\n\n const turn = state.currentAssistantTurn;\n const steps = turn.steps!;\n\n if (IGNORED_TYPES.has(event.type)) return;\n\n switch (event.type) {\n case \"text\": {\n const last = steps[steps.length - 1];\n if (last && last.type === \"text\") {\n last.content += event.content;\n } else {\n steps.push({ type: \"text\", content: event.content });\n }\n break;\n }\n\n case \"thought\": {\n const last = steps[steps.length - 1];\n if (last && last.type === \"thinking\") {\n last.content += event.content;\n } else {\n steps.push({ type: \"thinking\", content: event.content });\n }\n break;\n }\n\n case \"tool_call\": {\n const step: ToolCallStep = {\n type: \"tool_call\",\n id: event.id,\n name: event.name,\n status: event.status,\n };\n if (event.kind) step.kind = event.kind;\n steps.push(step);\n break;\n }\n\n case \"tool_update\": {\n const existing = this.findToolCall(steps, event.id);\n if (!existing) break;\n existing.status = event.status;\n if (event.rawInput !== undefined) existing.input = event.rawInput;\n if (event.rawOutput !== undefined) existing.output = event.rawOutput;\n if (event.content !== undefined) {\n const diff = extractDiff(event.content);\n if (diff) existing.diff = diff;\n }\n if (event.locations !== undefined) {\n const locs = extractLocations(event.locations);\n if (locs) existing.locations = locs;\n }\n break;\n }\n\n case \"plan\": {\n steps.push({\n type: \"plan\",\n entries: event.entries.map((e) => ({\n content: e.content,\n priority: e.priority,\n status: e.status,\n })),\n });\n break;\n }\n\n case \"usage\": {\n turn.usage = {};\n if (event.tokensUsed !== undefined) turn.usage.tokensUsed = event.tokensUsed;\n if (event.contextSize !== undefined) turn.usage.contextSize = event.contextSize;\n if (event.cost) turn.usage.cost = event.cost;\n break;\n }\n\n case \"image_content\": {\n steps.push({\n type: \"image\",\n mimeType: event.mimeType,\n filePath: \"\",\n });\n break;\n }\n\n case \"audio_content\": {\n steps.push({\n type: \"audio\",\n mimeType: event.mimeType,\n filePath: \"\",\n });\n break;\n }\n\n case \"resource_content\": {\n const step: ResourceStep = {\n type: \"resource\",\n uri: event.uri,\n name: event.name,\n };\n if (event.text !== undefined) step.text = event.text;\n steps.push(step);\n break;\n }\n\n case \"resource_link\": {\n const step: ResourceLinkStep = {\n type: \"resource_link\",\n uri: event.uri,\n name: event.name,\n };\n if (event.title !== undefined) step.title = event.title;\n if (event.description !== undefined)\n step.description = event.description;\n steps.push(step);\n break;\n }\n\n case \"current_mode_update\": {\n steps.push({ type: \"mode_change\", modeId: event.modeId });\n break;\n }\n\n case \"config_option_update\": {\n for (const opt of event.options) {\n steps.push({\n type: \"config_change\",\n configId: opt.id,\n value: String(opt.currentValue),\n });\n }\n break;\n }\n }\n }\n\n onPermissionResolved(\n sessionId: string,\n requestId: string,\n decision: string,\n ): void {\n const state = this.states.get(sessionId);\n if (!state || !state.currentAssistantTurn) return;\n const step = this.findToolCall(state.currentAssistantTurn.steps!, requestId);\n if (!step) return;\n step.permission = { requested: true, outcome: decision };\n }\n\n async onTurnEnd(sessionId: string, stopReason: string): Promise<void> {\n const state = this.states.get(sessionId);\n if (!state || !state.currentAssistantTurn) return;\n state.currentAssistantTurn.stopReason = stopReason;\n state.currentAssistantTurn = null;\n await this.store.write(state.history);\n }\n\n finalize(sessionId: string): void {\n this.states.delete(sessionId);\n }\n\n getState(sessionId: string): RecorderState | undefined {\n return this.states.get(sessionId);\n }\n\n private findToolCall(steps: Step[], id: string): ToolCallStep | undefined {\n for (let i = steps.length - 1; i >= 0; i--) {\n const s = steps[i];\n if (s.type === \"tool_call\" && s.id === id) return s;\n }\n return undefined;\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { SessionHistory } from \"./types.js\";\n\nexport class HistoryStore {\n constructor(private readonly dir: string) {}\n\n async write(history: SessionHistory): Promise<void> {\n await fs.promises.mkdir(this.dir, { recursive: true });\n const filePath = this.filePath(history.sessionId);\n await fs.promises.writeFile(filePath, JSON.stringify(history, null, 2));\n }\n\n async read(sessionId: string): Promise<SessionHistory | null> {\n const filePath = this.filePath(sessionId);\n try {\n const raw = await fs.promises.readFile(filePath, \"utf-8\");\n return JSON.parse(raw) as SessionHistory;\n } catch {\n return null;\n }\n }\n\n async exists(sessionId: string): Promise<boolean> {\n try {\n await fs.promises.access(this.filePath(sessionId));\n return true;\n } catch {\n return false;\n }\n }\n\n async list(): Promise<string[]> {\n try {\n const files = await fs.promises.readdir(this.dir);\n return files\n .filter((f) => f.endsWith(\".json\"))\n .map((f) => f.replace(/\\.json$/, \"\"));\n } catch {\n return [];\n }\n }\n\n async delete(sessionId: string): Promise<void> {\n try {\n await fs.promises.unlink(this.filePath(sessionId));\n } catch {\n // file may not exist — safe to ignore\n }\n }\n\n private filePath(sessionId: string): string {\n return path.join(this.dir, `${sessionId}.json`);\n }\n}\n","import * as path from 'node:path'\nimport type { OpenACPPlugin, InstallContext } from '../../core/plugin/types.js'\nimport type { SessionRecord } from '../../core/types.js'\nimport { ContextManager } from './context-manager.js'\nimport { EntireProvider } from './entire/entire-provider.js'\nimport { HistoryProvider } from './history/history-provider.js'\nimport { HistoryRecorder } from './history/history-recorder.js'\nimport { HistoryStore } from './history/history-store.js'\n\nconst contextPlugin: OpenACPPlugin = {\n name: '@openacp/context',\n version: '1.0.0',\n description: 'Conversation context management with pluggable providers',\n essential: false,\n permissions: ['services:register', 'middleware:register', 'kernel:access'],\n\n async install(ctx: InstallContext) {\n const { settings, terminal } = ctx\n\n // No interactive prompts needed — save defaults\n await settings.setAll({ enabled: true })\n terminal.log.success('Context defaults saved')\n },\n\n async configure(ctx: InstallContext) {\n const { terminal, settings } = ctx\n const current = await settings.getAll()\n\n const toggle = await terminal.confirm({\n message: `Context service is ${current.enabled !== false ? 'enabled' : 'disabled'}. Toggle?`,\n initialValue: false,\n })\n if (toggle) {\n const newState = current.enabled === false\n await settings.set('enabled', newState)\n terminal.log.success(`Context service ${newState ? 'enabled' : 'disabled'}`)\n }\n },\n\n async uninstall(ctx: InstallContext, opts: { purge: boolean }) {\n if (opts.purge) {\n await ctx.settings.clear()\n ctx.terminal.log.success('Context settings cleared')\n }\n },\n\n async setup(ctx) {\n // History recording and context\n const historyDir = path.join(ctx.instanceRoot, 'history')\n const store = new HistoryStore(historyDir)\n const recorder = new HistoryRecorder(store)\n\n // Access session records via SessionManager (kernel:access)\n const sessionManager = ctx.sessions as { listRecords(): SessionRecord[] }\n const getRecords = () => sessionManager.listRecords()\n\n // Register providers — local first (priority), entire as fallback\n const cachePath = path.join(ctx.instanceRoot, 'cache', 'entire')\n const manager = new ContextManager(cachePath)\n manager.register(new HistoryProvider(store, getRecords))\n manager.register(new EntireProvider())\n ctx.registerService('context', manager)\n\n // Middleware: capture user prompts\n ctx.registerMiddleware('agent:beforePrompt', {\n priority: 200,\n handler: async (payload, next) => {\n recorder.onBeforePrompt(payload.sessionId, payload.text, payload.attachments)\n return next()\n },\n })\n\n // Middleware: capture agent events\n ctx.registerMiddleware('agent:afterEvent', {\n priority: 200,\n handler: async (payload, next) => {\n recorder.onAfterEvent(payload.sessionId, payload.event)\n return next()\n },\n })\n\n // Middleware: finalize turn and write to disk\n ctx.registerMiddleware('turn:end', {\n priority: 200,\n handler: async (payload, next) => {\n await recorder.onTurnEnd(payload.sessionId, payload.stopReason)\n return next()\n },\n })\n\n // Middleware: capture permission resolutions\n ctx.registerMiddleware('permission:afterResolve', {\n priority: 200,\n handler: async (payload, next) => {\n recorder.onPermissionResolved(payload.sessionId, payload.requestId, payload.decision)\n return next()\n },\n })\n\n // Middleware: clean up recorder memory on session destroy\n ctx.registerMiddleware('session:afterDestroy', {\n priority: 200,\n handler: async (payload, next) => {\n recorder.finalize(payload.sessionId)\n return next()\n },\n })\n\n ctx.log.info('Context service ready (local history + entire providers)')\n },\n}\n\nexport default contextPlugin\n","import type { STTProvider, TTSProvider, STTOptions, STTResult, TTSOptions, TTSResult, SpeechServiceConfig } from './speech-types.js';\n\nexport type ProviderFactory = (config: SpeechServiceConfig) => { stt: Map<string, STTProvider>; tts: Map<string, TTSProvider> };\n\nexport class SpeechService {\n private sttProviders = new Map<string, STTProvider>();\n private ttsProviders = new Map<string, TTSProvider>();\n private providerFactory?: ProviderFactory;\n\n constructor(private config: SpeechServiceConfig) {}\n\n /** Set a factory function that can recreate providers from config (for hot-reload) */\n setProviderFactory(factory: ProviderFactory): void {\n this.providerFactory = factory;\n }\n\n registerSTTProvider(name: string, provider: STTProvider): void {\n this.sttProviders.set(name, provider);\n }\n\n registerTTSProvider(name: string, provider: TTSProvider): void {\n this.ttsProviders.set(name, provider);\n }\n\n unregisterTTSProvider(name: string): void {\n this.ttsProviders.delete(name);\n }\n\n isSTTAvailable(): boolean {\n const { provider, providers } = this.config.stt;\n return provider !== null && providers[provider]?.apiKey !== undefined;\n }\n\n isTTSAvailable(): boolean {\n const provider = this.config.tts.provider;\n return provider !== null && this.ttsProviders.has(provider);\n }\n\n async transcribe(audioBuffer: Buffer, mimeType: string, options?: STTOptions): Promise<STTResult> {\n const providerName = this.config.stt.provider;\n if (!providerName || !this.config.stt.providers[providerName]?.apiKey) {\n throw new Error(\"STT not configured. Set speech.stt.provider and API key in config.\");\n }\n const provider = this.sttProviders.get(providerName);\n if (!provider) {\n throw new Error(`STT provider \"${providerName}\" not registered. Available: ${[...this.sttProviders.keys()].join(\", \") || \"none\"}`);\n }\n return provider.transcribe(audioBuffer, mimeType, options);\n }\n\n async synthesize(text: string, options?: TTSOptions): Promise<TTSResult> {\n const providerName = this.config.tts.provider;\n if (!providerName) {\n throw new Error(\"TTS not configured. Set speech.tts.provider in config.\");\n }\n const provider = this.ttsProviders.get(providerName);\n if (!provider) {\n throw new Error(`TTS provider \"${providerName}\" not registered. Available: ${[...this.ttsProviders.keys()].join(\", \") || \"none\"}`);\n }\n return provider.synthesize(text, options);\n }\n\n updateConfig(config: SpeechServiceConfig): void {\n this.config = config;\n }\n\n /** Re-create factory-managed providers from config. Preserves externally-registered providers (e.g. from plugins). */\n refreshProviders(newConfig: SpeechServiceConfig): void {\n this.config = newConfig;\n if (this.providerFactory) {\n const { stt, tts } = this.providerFactory(newConfig);\n // Merge: factory providers overwrite, but externally-registered providers are preserved\n for (const [name, provider] of stt) {\n this.sttProviders.set(name, provider);\n }\n for (const [name, provider] of tts) {\n this.ttsProviders.set(name, provider);\n }\n }\n }\n}\n","import type { STTProvider, STTOptions, STTResult } from '../speech-types.js';\n\nconst GROQ_API_URL = \"https://api.groq.com/openai/v1/audio/transcriptions\";\n\nexport class GroqSTT implements STTProvider {\n readonly name = \"groq\";\n\n constructor(\n private apiKey: string,\n private defaultModel: string = \"whisper-large-v3-turbo\",\n ) {}\n\n async transcribe(audioBuffer: Buffer, mimeType: string, options?: STTOptions): Promise<STTResult> {\n const ext = mimeToExt(mimeType);\n const form = new FormData();\n form.append(\"file\", new Blob([new Uint8Array(audioBuffer)], { type: mimeType }), `audio${ext}`);\n form.append(\"model\", options?.model || this.defaultModel);\n form.append(\"response_format\", \"verbose_json\");\n if (options?.language) {\n form.append(\"language\", options.language);\n }\n\n const resp = await fetch(GROQ_API_URL, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${this.apiKey}` },\n body: form,\n });\n\n if (!resp.ok) {\n const body = await resp.text();\n if (resp.status === 401) {\n throw new Error(\"Invalid Groq API key. Check your key at console.groq.com.\");\n }\n if (resp.status === 413) {\n throw new Error(\"Audio file too large for Groq API (max 25MB).\");\n }\n if (resp.status === 429) {\n throw new Error(\"Groq rate limit exceeded. Free tier: 28,800 seconds/day. Try again later.\");\n }\n throw new Error(`Groq STT error (${resp.status}): ${body}`);\n }\n\n const data = await resp.json() as { text: string; language?: string; duration?: number };\n return {\n text: data.text,\n language: data.language,\n duration: data.duration,\n };\n }\n}\n\nfunction mimeToExt(mimeType: string): string {\n const map: Record<string, string> = {\n \"audio/ogg\": \".ogg\",\n \"audio/wav\": \".wav\",\n \"audio/mpeg\": \".mp3\",\n \"audio/mp4\": \".m4a\",\n \"audio/webm\": \".webm\",\n \"audio/flac\": \".flac\",\n };\n return map[mimeType] || \".bin\";\n}\n","export type { STTProvider, TTSProvider, STTOptions, STTResult, TTSOptions, TTSResult, SpeechServiceConfig, SpeechProviderConfig } from './speech-types.js';\nexport { SpeechService } from './speech-service.js';\nexport { GroqSTT } from './providers/groq.js';\n","import { exec } from 'node:child_process'\nimport { promisify } from 'node:util'\nimport * as fs from 'node:fs/promises'\nimport * as os from 'node:os'\nimport * as path from 'node:path'\nimport { pathToFileURL } from 'node:url'\n\nconst execAsync = promisify(exec)\n\n/**\n * Import a package resolved from a specific directory (not the project root).\n * Reads the package's package.json to find the ESM entry point, then imports by file path.\n */\nexport async function importFromDir(packageName: string, dir: string): Promise<any> {\n const pkgDir = path.join(dir, 'node_modules', ...packageName.split('/'))\n const pkgJsonPath = path.join(pkgDir, 'package.json')\n\n let pkgJson: Record<string, any>\n try {\n pkgJson = JSON.parse(await fs.readFile(pkgJsonPath, 'utf-8'))\n } catch (err) {\n throw new Error(`Cannot read package.json for \"${packageName}\" at ${pkgJsonPath}: ${(err as Error).message}`)\n }\n\n // Resolve entry: exports[\".\"].import > main > index.js\n let entry: string\n const exportsMain = pkgJson.exports?.['.']\n if (typeof exportsMain === 'string') {\n entry = exportsMain\n } else if (exportsMain?.import) {\n entry = exportsMain.import\n } else {\n entry = pkgJson.main ?? 'index.js'\n }\n\n const entryPath = path.join(pkgDir, entry)\n try {\n await fs.access(entryPath)\n } catch {\n throw new Error(`Entry point \"${entry}\" not found for \"${packageName}\" at ${entryPath}`)\n }\n\n return import(pathToFileURL(entryPath).href)\n}\n\n/** Valid npm package name: optional @scope/, alphanumeric/hyphens/dots, optional @version */\nconst VALID_NPM_NAME = /^(@[a-z0-9][\\w.-]*\\/)?[a-z0-9][\\w.-]*(@[\\w.^~>=<|-]+)?$/i;\n\n/**\n * Install an npm package to the plugins directory and return the loaded module.\n * Tries to import first; if not installed, runs npm install asynchronously.\n */\nexport async function installNpmPlugin(packageName: string, pluginsDir?: string): Promise<any> {\n if (!VALID_NPM_NAME.test(packageName)) {\n throw new Error(`Invalid package name: \"${packageName}\". Must be a valid npm package name.`);\n }\n\n const dir = pluginsDir ?? path.join(os.homedir(), '.openacp', 'plugins')\n\n // Try import from plugins dir first — already installed\n try {\n return await importFromDir(packageName, dir)\n } catch {\n // Not installed, proceed with install\n }\n\n await execAsync(`npm install ${packageName} --prefix \"${dir}\" --save`, {\n timeout: 60000,\n })\n\n return await importFromDir(packageName, dir)\n}\n","import type { OpenACPPlugin, InstallContext, PluginContext } from '../../core/plugin/types.js'\nimport type { OpenACPCore } from '../../core/core.js'\nimport type { Session } from '../../core/sessions/session.js'\nimport { SpeechService, GroqSTT } from './exports.js'\nimport type { SpeechServiceConfig } from './exports.js'\nimport { installNpmPlugin } from '../../core/plugin/plugin-installer.js'\n\nconst EDGE_TTS_PLUGIN = '@openacp/msedge-tts-plugin'\n\nconst speechPlugin: OpenACPPlugin = {\n name: '@openacp/speech',\n version: '1.0.0',\n description: 'Text-to-speech and speech-to-text with pluggable providers',\n essential: false,\n optionalPluginDependencies: { '@openacp/file-service': '^1.0.0' },\n permissions: ['services:register', 'commands:register', 'kernel:access'],\n inheritableKeys: ['tts'],\n\n async install(ctx: InstallContext) {\n const { terminal, settings, legacyConfig } = ctx\n\n // Migrate from legacy config if present\n if (legacyConfig) {\n const speechCfg = legacyConfig.speech as Record<string, unknown> | undefined\n if (speechCfg) {\n const stt = speechCfg.stt as Record<string, unknown> | undefined\n const tts = speechCfg.tts as Record<string, unknown> | undefined\n const groqProviders = stt?.providers as Record<string, unknown> | undefined\n const groqConfig = groqProviders?.groq as Record<string, unknown> | undefined\n await settings.setAll({\n sttProvider: stt?.provider ?? null,\n groqApiKey: groqConfig?.apiKey ?? '',\n ttsProvider: tts?.provider ?? 'edge-tts',\n ttsVoice: '',\n })\n terminal.log.success('Speech settings migrated from legacy config')\n return\n }\n }\n\n // Interactive setup\n const enableStt = await terminal.confirm({\n message: 'Enable speech-to-text (STT)?',\n initialValue: false,\n })\n\n let sttProvider: string | null = null\n let groqApiKey = ''\n\n if (enableStt) {\n sttProvider = await terminal.select({\n message: 'STT provider:',\n options: [{ value: 'groq', label: 'Groq (Whisper)', hint: 'Fast and affordable' }],\n })\n\n if (sttProvider === 'groq') {\n groqApiKey = await terminal.text({\n message: 'Groq API key:',\n validate: (v) => (!v.trim() ? 'API key cannot be empty' : undefined),\n })\n groqApiKey = groqApiKey.trim()\n }\n }\n\n const ttsProvider = await terminal.select({\n message: 'TTS provider:',\n options: [\n { value: 'edge-tts', label: 'Edge TTS', hint: 'Free, good quality' },\n { value: 'none', label: 'None (disable TTS)' },\n ],\n })\n\n let ttsVoice = ''\n if (ttsProvider === 'edge-tts') {\n terminal.log.info('Installing Edge TTS plugin...')\n try {\n await installNpmPlugin(EDGE_TTS_PLUGIN)\n terminal.log.success('Edge TTS plugin installed')\n } catch (err) {\n terminal.log.warning(`Failed to install Edge TTS plugin: ${err}. You can install it later with: openacp plugin install ${EDGE_TTS_PLUGIN}`)\n }\n\n ttsVoice = await terminal.text({\n message: 'TTS voice (leave blank for default):',\n placeholder: 'e.g. en-US-AriaNeural',\n })\n ttsVoice = ttsVoice.trim()\n }\n\n await settings.setAll({\n sttProvider,\n groqApiKey,\n ttsProvider: ttsProvider === 'none' ? null : ttsProvider,\n ttsVoice,\n })\n terminal.log.success('Speech settings saved')\n },\n\n async configure(ctx: InstallContext) {\n const { terminal, settings } = ctx\n const current = await settings.getAll()\n\n const choice = await terminal.select({\n message: 'What to configure?',\n options: [\n { value: 'stt', label: 'Change STT provider/key' },\n { value: 'tts', label: 'Change TTS provider/voice' },\n { value: 'done', label: 'Done' },\n ],\n })\n\n if (choice === 'stt') {\n const key = await terminal.text({\n message: 'Groq API key (leave blank to disable STT):',\n defaultValue: (current.groqApiKey as string) ?? '',\n })\n const trimmed = key.trim()\n await settings.set('sttProvider', trimmed ? 'groq' : null)\n await settings.set('groqApiKey', trimmed)\n terminal.log.success('STT settings updated')\n } else if (choice === 'tts') {\n const voice = await terminal.text({\n message: 'TTS voice (leave blank for default):',\n defaultValue: (current.ttsVoice as string) ?? '',\n })\n await settings.set('ttsVoice', voice.trim())\n terminal.log.success('TTS settings updated')\n }\n },\n\n async uninstall(ctx: InstallContext, opts: { purge: boolean }) {\n if (opts.purge) {\n await ctx.settings.clear()\n ctx.terminal.log.success('Speech settings cleared')\n }\n },\n\n async setup(ctx) {\n const config = ctx.pluginConfig as Record<string, unknown>\n const groqApiKey = config.groqApiKey as string | undefined\n\n const sttProvider = groqApiKey ? 'groq' : null\n const speechConfig: SpeechServiceConfig = {\n stt: {\n provider: sttProvider,\n providers: groqApiKey ? { groq: { apiKey: groqApiKey } } : {},\n },\n tts: {\n provider: (config.ttsProvider as string) ?? 'edge-tts',\n providers: {},\n },\n }\n\n const service = new SpeechService(speechConfig)\n\n if (groqApiKey) {\n service.registerSTTProvider('groq', new GroqSTT(groqApiKey))\n }\n\n // TTS provider is now registered by @openacp/msedge-tts-plugin (no EdgeTTS here)\n\n // Register provider factory for hot-reload (STT only — TTS providers are managed by external plugins)\n service.setProviderFactory((cfg) => {\n const sttMap = new Map()\n const ttsMap = new Map()\n const groqCfg = cfg.stt?.providers?.groq\n if (groqCfg?.apiKey) {\n sttMap.set('groq', new GroqSTT(groqCfg.apiKey, groqCfg.model))\n }\n return { stt: sttMap, tts: ttsMap }\n })\n\n ctx.registerService('speech', service)\n\n // Helper to look up the session and set voiceMode\n const setSessionVoiceMode = (pluginCtx: PluginContext, sessionId: string | null, voiceMode: 'off' | 'next' | 'on'): void => {\n if (!sessionId) return\n try {\n const sessionManager = pluginCtx.sessions as { getSession(id: string): Session | undefined }\n const session = sessionManager.getSession(sessionId)\n if (session) {\n session.setVoiceMode(voiceMode)\n }\n } catch {\n // Session lookup may fail if kernel:access is unavailable; silently ignore\n }\n }\n\n ctx.registerCommand({\n name: 'tts',\n description: 'Toggle text-to-speech',\n usage: 'on|off|next|install',\n category: 'plugin',\n handler: async (args) => {\n const mode = args.raw.trim().toLowerCase()\n\n // Check if TTS provider is available\n if ((mode === 'on' || mode === '' || mode === 'next') && !service.isTTSAvailable()) {\n return {\n type: 'menu' as const,\n title: 'TTS provider not installed. Install Edge TTS plugin?',\n options: [\n { label: 'Install Edge TTS', command: '/tts install' },\n { label: 'Cancel', command: '/tts off' },\n ],\n }\n }\n\n if (mode === 'install') {\n try {\n const mod = await installNpmPlugin(EDGE_TTS_PLUGIN)\n const plugin = mod.default\n if (plugin && ctx.core) {\n const lm = (ctx.core as OpenACPCore).lifecycleManager\n const registry = lm.registry\n if (registry) {\n registry.register(plugin.name, {\n version: plugin.version,\n source: 'npm',\n enabled: true,\n settingsPath: '',\n description: plugin.description,\n })\n await registry.save()\n }\n await lm.boot([plugin])\n }\n return { type: 'text' as const, text: 'Edge TTS plugin installed and ready! Use /tts on to enable.' }\n } catch (err) {\n return { type: 'error' as const, message: `Failed to install Edge TTS plugin: ${err}. Try manually: openacp plugin install ${EDGE_TTS_PLUGIN}` }\n }\n }\n\n if (mode === 'on') {\n setSessionVoiceMode(ctx, args.sessionId, 'on')\n return { type: 'text' as const, text: 'Text-to-speech enabled' }\n }\n if (mode === 'off') {\n setSessionVoiceMode(ctx, args.sessionId, 'off')\n return { type: 'text' as const, text: 'Text-to-speech disabled' }\n }\n if (mode === 'next') {\n setSessionVoiceMode(ctx, args.sessionId, 'next')\n return { type: 'text' as const, text: 'Text-to-speech enabled for next message' }\n }\n return { type: 'menu' as const, title: 'Text to Speech', options: [\n { label: 'Enable', command: '/tts on' },\n { label: 'Disable', command: '/tts off' },\n { label: 'Next message only', command: '/tts next' },\n ]}\n },\n })\n\n ctx.log.info('Speech service ready')\n },\n}\n\nexport default speechPlugin\n","import type { IChannelAdapter } from '../../core/channel.js'\nimport type { NotificationMessage } from '../../core/types.js'\n\nexport class NotificationManager {\n constructor(private adapters: Map<string, IChannelAdapter>) {}\n\n async notify(channelId: string, notification: NotificationMessage): Promise<void> {\n const adapter = this.adapters.get(channelId)\n if (!adapter) return\n try {\n await adapter.sendNotification(notification)\n } catch {\n // Don't let notification failures crash the caller\n }\n }\n\n async notifyAll(notification: NotificationMessage): Promise<void> {\n for (const adapter of this.adapters.values()) {\n try {\n await adapter.sendNotification(notification)\n } catch {\n // Continue to next adapter\n }\n }\n }\n}\n","import type { OpenACPPlugin, InstallContext, CoreAccess } from '../../core/plugin/types.js'\nimport { NotificationManager } from './notification.js'\n\nfunction createNotificationsPlugin(): OpenACPPlugin {\n return {\n name: '@openacp/notifications',\n version: '1.0.0',\n description: 'Cross-session notification routing',\n essential: false,\n pluginDependencies: { '@openacp/security': '^1.0.0' },\n permissions: ['services:register', 'kernel:access'],\n\n async install(ctx: InstallContext) {\n const { settings, terminal } = ctx\n\n // No interactive prompts needed — save defaults\n await settings.setAll({ enabled: true })\n terminal.log.success('Notifications defaults saved')\n },\n\n async configure(ctx: InstallContext) {\n const { terminal, settings } = ctx\n const current = await settings.getAll()\n\n const toggle = await terminal.confirm({\n message: `Notifications are ${current.enabled !== false ? 'enabled' : 'disabled'}. Toggle?`,\n initialValue: false,\n })\n if (toggle) {\n const newState = current.enabled === false\n await settings.set('enabled', newState)\n terminal.log.success(`Notifications ${newState ? 'enabled' : 'disabled'}`)\n }\n },\n\n async uninstall(ctx: InstallContext, opts: { purge: boolean }) {\n if (opts.purge) {\n await ctx.settings.clear()\n ctx.terminal.log.success('Notifications settings cleared')\n }\n },\n\n async setup(ctx) {\n // NotificationManager needs the live adapters Map from core\n const core = ctx.core as CoreAccess\n const manager = new NotificationManager(core.adapters)\n ctx.registerService('notifications', manager)\n ctx.log.info('Notifications service ready')\n },\n }\n}\n\nexport default createNotificationsPlugin()\n","import pino from 'pino'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\nimport type { LoggingConfig } from '../config/config.js'\n\nexport type Logger = pino.Logger\n\n// --- Default console-only logger (pre-init) ---\nlet rootLogger: pino.Logger = pino({\n level: 'debug',\n transport: { target: 'pino-pretty', options: { colorize: true, translateTime: 'SYS:standard' } },\n})\nlet initialized = false\nlet logDir: string | undefined\nlet currentTransport: ReturnType<typeof pino.transport> | undefined\n\nfunction expandHome(p: string): string {\n return p.startsWith('~') ? path.join(os.homedir(), p.slice(1)) : p\n}\n\n// --- Variadic wrapper for backward compatibility ---\nfunction wrapVariadic(logger: pino.Logger) {\n return {\n info: (...args: unknown[]) => {\n if (args.length === 0) return\n if (typeof args[0] === 'object' && args[0] !== null && !(args[0] instanceof Error)) {\n logger.info(args[0] as object, args.slice(1).join(' '))\n } else {\n logger.info(args.map(String).join(' '))\n }\n },\n warn: (...args: unknown[]) => {\n if (args.length === 0) return\n if (typeof args[0] === 'object' && args[0] !== null && !(args[0] instanceof Error)) {\n logger.warn(args[0] as object, args.slice(1).join(' '))\n } else {\n logger.warn(args.map(String).join(' '))\n }\n },\n error: (...args: unknown[]) => {\n if (args.length === 0) return\n if (typeof args[0] === 'object' && args[0] !== null && !(args[0] instanceof Error)) {\n logger.error(args[0] as object, args.slice(1).join(' '))\n } else {\n logger.error(args.map(String).join(' '))\n }\n },\n debug: (...args: unknown[]) => {\n if (args.length === 0) return\n if (typeof args[0] === 'object' && args[0] !== null && !(args[0] instanceof Error)) {\n logger.debug(args[0] as object, args.slice(1).join(' '))\n } else {\n logger.debug(args.map(String).join(' '))\n }\n },\n fatal: (...args: unknown[]) => {\n if (args.length === 0) return\n if (typeof args[0] === 'object' && args[0] !== null && !(args[0] instanceof Error)) {\n logger.fatal(args[0] as object, args.slice(1).join(' '))\n } else {\n logger.fatal(args.map(String).join(' '))\n }\n },\n child: (bindings: pino.Bindings) => logger.child(bindings),\n }\n}\n\nexport const log = wrapVariadic(rootLogger)\n\n// --- Mute/unmute (suppress pino output during interactive prompts) ---\n\nlet muteCount = 0\nlet savedLevel = 'info'\n\nexport function muteLogger(): void {\n if (muteCount === 0) {\n savedLevel = rootLogger.level\n rootLogger.level = 'silent'\n }\n muteCount++\n}\n\nexport function unmuteLogger(): void {\n muteCount--\n if (muteCount <= 0) {\n muteCount = 0\n rootLogger.level = savedLevel\n }\n}\n\n// --- Public API ---\n\nexport function initLogger(config: LoggingConfig): Logger {\n if (initialized) return rootLogger\n\n const resolvedLogDir = expandHome(config.logDir)\n logDir = resolvedLogDir\n\n try {\n fs.mkdirSync(resolvedLogDir, { recursive: true })\n fs.mkdirSync(path.join(resolvedLogDir, 'sessions'), { recursive: true })\n } catch (err) {\n console.error(`[WARN] Failed to create log directory ${resolvedLogDir}, falling back to console-only:`, err)\n return rootLogger\n }\n\n const transports = pino.transport({\n targets: [\n {\n target: 'pino-pretty',\n options: {\n colorize: true,\n translateTime: 'HH:mm:ss',\n ignore: 'pid,hostname',\n singleLine: true,\n },\n level: config.level,\n },\n {\n target: 'pino-roll',\n options: {\n file: path.join(resolvedLogDir, 'openacp.log'),\n size: config.maxFileSize,\n limit: { count: config.maxFiles },\n },\n level: config.level,\n },\n ],\n })\n\n currentTransport = transports\n rootLogger = pino({ level: config.level }, transports)\n initialized = true\n\n // Update the default log wrapper to use the new root logger\n Object.assign(log, wrapVariadic(rootLogger))\n\n return rootLogger\n}\n\n/** Change log level at runtime. Pino transport targets respect parent level changes automatically. */\nexport function setLogLevel(level: string): void {\n rootLogger.level = level\n}\n\nexport function createChildLogger(context: { module: string; [key: string]: unknown }): Logger {\n // Return a proxy that always delegates to the current rootLogger.\n // This ensures child loggers created at module-level (before initLogger)\n // pick up the initialized logger with pino-pretty transport.\n return new Proxy({} as Logger, {\n get(_target, prop, receiver) {\n const child = rootLogger.child(context)\n const value = Reflect.get(child, prop, receiver)\n return typeof value === 'function' ? value.bind(child) : value\n },\n })\n}\n\nexport function createSessionLogger(sessionId: string, parentLogger: Logger): Logger {\n const sessionLogDir = logDir ? path.join(logDir, 'sessions') : undefined\n if (!sessionLogDir) {\n return parentLogger.child({ sessionId })\n }\n\n try {\n const sessionLogPath = path.join(sessionLogDir, `${sessionId}.log`)\n const dest = pino.destination(sessionLogPath)\n const sessionFileLogger = pino({ level: parentLogger.level }, dest).child({ sessionId })\n\n // Create a logger that writes to both parent (combined) and session file\n const combinedChild = parentLogger.child({ sessionId })\n const originalInfo = combinedChild.info.bind(combinedChild)\n const originalWarn = combinedChild.warn.bind(combinedChild)\n const originalError = combinedChild.error.bind(combinedChild)\n const originalDebug = combinedChild.debug.bind(combinedChild)\n const originalFatal = combinedChild.fatal.bind(combinedChild)\n\n // Proxy log methods to write to both destinations\n combinedChild.info = ((objOrMsg: any, ...rest: any[]) => {\n sessionFileLogger.info(objOrMsg, ...rest)\n return originalInfo(objOrMsg, ...rest)\n }) as any\n combinedChild.warn = ((objOrMsg: any, ...rest: any[]) => {\n sessionFileLogger.warn(objOrMsg, ...rest)\n return originalWarn(objOrMsg, ...rest)\n }) as any\n combinedChild.error = ((objOrMsg: any, ...rest: any[]) => {\n sessionFileLogger.error(objOrMsg, ...rest)\n return originalError(objOrMsg, ...rest)\n }) as any\n combinedChild.debug = ((objOrMsg: any, ...rest: any[]) => {\n sessionFileLogger.debug(objOrMsg, ...rest)\n return originalDebug(objOrMsg, ...rest)\n }) as any\n combinedChild.fatal = ((objOrMsg: any, ...rest: any[]) => {\n sessionFileLogger.fatal(objOrMsg, ...rest)\n return originalFatal(objOrMsg, ...rest)\n }) as any\n\n // Store dest for cleanup\n ;(combinedChild as any).__sessionDest = dest\n\n return combinedChild\n } catch (err) {\n // Graceful degradation: session file failed, just use combined log\n parentLogger.warn({ sessionId, err }, 'Failed to create session log file, using combined log only')\n return parentLogger.child({ sessionId })\n }\n}\n\nexport function closeSessionLogger(logger: Logger): void {\n const dest = (logger as any).__sessionDest\n if (dest && typeof dest.destroy === 'function') {\n dest.destroy()\n }\n}\n\nexport async function shutdownLogger(): Promise<void> {\n if (!initialized) return\n\n const transport = currentTransport\n\n // Reset state immediately so re-init is possible\n rootLogger = pino({ level: 'debug' })\n Object.assign(log, wrapVariadic(rootLogger))\n currentTransport = undefined\n logDir = undefined\n initialized = false\n\n if (transport) {\n await new Promise<void>((resolve) => {\n const timeout = setTimeout(resolve, 3000)\n transport.on('close', () => {\n clearTimeout(timeout)\n resolve()\n })\n transport.end()\n })\n }\n}\n\nexport async function cleanupOldSessionLogs(retentionDays: number): Promise<void> {\n if (!logDir) return\n\n const sessionsDir = path.join(logDir, 'sessions')\n try {\n const files = await fs.promises.readdir(sessionsDir)\n const cutoff = Date.now() - retentionDays * 24 * 60 * 60 * 1000\n\n for (const file of files) {\n try {\n const filePath = path.join(sessionsDir, file)\n const stat = await fs.promises.stat(filePath)\n if (stat.mtimeMs < cutoff) {\n await fs.promises.unlink(filePath)\n rootLogger.debug({ file }, 'Deleted old session log')\n }\n } catch (err) {\n rootLogger.warn({ file, err }, 'Failed to delete old session log')\n }\n }\n } catch {\n // Sessions directory doesn't exist — no-op\n }\n}\n","import { execFileSync } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { AvailabilityResult } from \"../types.js\";\n\nexport interface AgentDependency {\n command: string;\n label: string;\n installHint: string;\n}\n\nexport interface AgentSetupInfo {\n setupSteps: string[];\n loginCommand?: string;\n}\n\nexport interface AgentIntegrationSpec {\n hookEvent: string;\n settingsPath: string;\n settingsFormat: \"settings_json\" | \"hooks_json\";\n hooksDirPath: string;\n outputFormat: \"plaintext\" | \"json\";\n sessionIdField: string;\n commandsPath?: string;\n handoffCommandName?: string;\n commandFormat?: \"markdown\" | \"skill\";\n sessionIdVar?: string;\n workingDirVar?: string;\n}\n\nexport interface AgentCapability {\n supportsResume: boolean;\n resumeCommand?: (sessionId: string) => string;\n integration?: AgentIntegrationSpec;\n}\n\nconst AGENT_DEPENDENCIES: Record<string, AgentDependency[]> = {\n \"claude-acp\": [\n {\n command: \"claude\",\n label: \"Claude CLI\",\n installHint: \"npm install -g @anthropic-ai/claude-code\",\n },\n ],\n \"codex-acp\": [\n {\n command: \"codex\",\n label: \"Codex CLI\",\n installHint: \"npm install -g @openai/codex\",\n },\n ],\n};\n\nconst AGENT_SETUP: Record<string, AgentSetupInfo> = {\n // --- Agents requiring their own CLI installed first ---\n \"claude-acp\": {\n setupSteps: [\n \"Install Claude CLI: npm install -g @anthropic-ai/claude-code\",\n \"Login: claude login (opens browser for Anthropic account)\",\n ],\n loginCommand: \"claude login\",\n },\n \"codex-acp\": {\n setupSteps: [\n \"Install Codex CLI: npm install -g @openai/codex\",\n \"Login: codex (select 'Sign in with ChatGPT')\",\n \"Or set API key: export OPENAI_API_KEY=<your-key>\",\n ],\n loginCommand: \"codex\",\n },\n\n // --- Agents with built-in auth (npx handles download) ---\n \"gemini\": {\n setupSteps: [\n \"Login with Google: openacp agents run gemini (select 'Sign in with Google')\",\n \"Or set API key: export GEMINI_API_KEY=<key> (get from aistudio.google.com/apikey)\",\n \"Free tier: 60 requests/min, 1000 requests/day\",\n ],\n loginCommand: \"openacp agents run gemini\",\n },\n \"github-copilot-cli\": {\n setupSteps: [\n \"Requires active GitHub Copilot subscription\",\n \"Login: openacp agents run copilot (use /login command inside CLI)\",\n \"Or set token: export GITHUB_TOKEN=<personal-access-token>\",\n ],\n loginCommand: \"openacp agents run copilot\",\n },\n \"cline\": {\n setupSteps: [\n \"Setup: openacp agents run cline (guided API key setup on first run)\",\n \"Supports: Anthropic, OpenAI, Gemini, AWS Bedrock, Azure, Ollama, and more\",\n \"Or set env: export ANTHROPIC_API_KEY=<key> (or OPENAI_API_KEY, etc.)\",\n ],\n loginCommand: \"openacp agents run cline\",\n },\n \"auggie\": {\n setupSteps: [\n \"Login: openacp agents run auggie (opens browser for Augment account on first run)\",\n ],\n loginCommand: \"openacp agents run auggie\",\n },\n \"qwen-code\": {\n setupSteps: [\n \"Login: openacp agents run qwen (use /auth command, select 'Qwen OAuth')\",\n \"Free: 1000 requests/day with Qwen OAuth\",\n \"Or set API key: export OPENAI_API_KEY=<key> in ~/.qwen/settings.json\",\n ],\n loginCommand: \"openacp agents run qwen\",\n },\n\n // --- Agents requiring API keys via env vars ---\n \"kimi\": {\n setupSteps: [\n \"Login: openacp agents run kimi (use /login command inside CLI)\",\n \"Recommended: select 'Kimi Code' for browser-based OAuth\",\n \"Or select another provider and enter API key manually\",\n ],\n loginCommand: \"openacp agents run kimi\",\n },\n \"cursor\": {\n setupSteps: [\n \"Requires active Cursor subscription\",\n \"Login: openacp agents run cursor (opens browser for Cursor account)\",\n ],\n loginCommand: \"openacp agents run cursor\",\n },\n\n // --- Agents with provider selection on first run ---\n \"goose\": {\n setupSteps: [\n \"First run auto-enters setup mode — choose your LLM provider\",\n \"Options: OpenAI, Anthropic, Google Gemini, OpenRouter, or local models\",\n \"Set provider API key: export OPENAI_API_KEY=<key> (or other provider)\",\n \"Reconfigure anytime: goose configure\",\n ],\n },\n \"junie\": {\n setupSteps: [\n \"Bring Your Own Key (BYOK) — provide API key from any supported provider\",\n \"Supports: OpenAI, Anthropic, Gemini, xAI, OpenRouter\",\n \"Free tier: up to $50 with Gemini 3 Flash included\",\n \"Set key via env or first-run setup prompt\",\n ],\n },\n \"kilo\": {\n setupSteps: [\n \"Options: bring your own API keys (Anthropic, OpenAI, Google) or use Kilo Gateway\",\n \"Kilo Gateway: pay-as-you-go, includes free models — no API key needed\",\n \"BYOK: set provider key, e.g. export ANTHROPIC_API_KEY=<key>\",\n ],\n },\n \"mistral-vibe\": {\n setupSteps: [\n \"Get API key from console.mistral.ai/codestral/cli\",\n \"Or sign up for Free/Pro/Team plan at mistral.ai\",\n \"Set key when prompted on first run\",\n ],\n },\n \"deepagents\": {\n setupSteps: [\n \"Powered by LangChain — set your LLM provider API key\",\n \"Example: export OPENAI_API_KEY=<key> or export ANTHROPIC_API_KEY=<key>\",\n ],\n },\n\n // --- Agents that work out of the box (no setup / minimal setup) ---\n \"crow-cli\": {\n setupSteps: [\n \"Requires uvx (Python package runner): pip install uv\",\n \"Bring your own API key for your chosen LLM provider\",\n ],\n },\n \"fast-agent\": {\n setupSteps: [\n \"Requires uvx (Python package runner): pip install uv\",\n \"Configure LLM provider in agent config file\",\n ],\n },\n};\n\nexport function getAgentSetup(registryId: string): AgentSetupInfo | undefined {\n return AGENT_SETUP[registryId];\n}\n\nconst AGENT_CAPABILITIES: Record<string, AgentCapability> = {\n claude: {\n supportsResume: true,\n resumeCommand: (sid) => `claude --resume ${sid}`,\n integration: {\n hookEvent: \"UserPromptSubmit\",\n settingsPath: \"~/.claude/settings.json\",\n settingsFormat: \"settings_json\",\n hooksDirPath: \"~/.claude/hooks/\",\n outputFormat: \"plaintext\",\n sessionIdField: \".session_id\",\n commandsPath: \"~/.claude/commands/\",\n handoffCommandName: \"openacp:handoff\",\n commandFormat: \"markdown\",\n sessionIdVar: \"CLAUDE_SESSION_ID\",\n workingDirVar: \"CLAUDE_WORKING_DIR\",\n },\n },\n cursor: {\n supportsResume: true,\n resumeCommand: (sid) => `cursor --resume ${sid}`,\n integration: {\n hookEvent: \"beforeSubmitPrompt\",\n settingsPath: \"~/.cursor/hooks.json\",\n settingsFormat: \"hooks_json\",\n hooksDirPath: \"~/.cursor/hooks/\",\n outputFormat: \"json\",\n sessionIdField: \".conversation_id\",\n commandsPath: \"~/.cursor/skills/\",\n handoffCommandName: \"openacp-handoff\",\n commandFormat: \"skill\",\n },\n },\n gemini: {\n supportsResume: true,\n resumeCommand: (sid) => `gemini --resume ${sid}`,\n integration: {\n hookEvent: \"BeforeAgent\",\n settingsPath: \"~/.gemini/settings.json\",\n settingsFormat: \"settings_json\",\n hooksDirPath: \"~/.gemini/hooks/\",\n outputFormat: \"json\",\n sessionIdField: \".session_id\",\n },\n },\n cline: {\n supportsResume: true,\n resumeCommand: () => `cline --continue`,\n integration: {\n hookEvent: \"TaskStart\",\n settingsPath: \"~/.cline/settings.json\",\n settingsFormat: \"settings_json\",\n hooksDirPath: \"~/.cline/hooks/\",\n outputFormat: \"json\",\n sessionIdField: \".session_id\",\n },\n },\n codex: {\n supportsResume: true,\n resumeCommand: (sid) => `codex resume ${sid}`,\n },\n kilo: {\n supportsResume: true,\n resumeCommand: () => `kilo --continue`,\n },\n amp: {\n supportsResume: true,\n resumeCommand: (sid) => `amp threads continue ${sid}`,\n },\n};\n\nexport const REGISTRY_AGENT_ALIASES: Record<string, string> = {\n \"claude-acp\": \"claude\",\n \"codex-acp\": \"codex\",\n \"gemini\": \"gemini\",\n \"cursor\": \"cursor\",\n \"github-copilot-cli\": \"copilot\",\n \"cline\": \"cline\",\n \"goose\": \"goose\",\n \"kilo\": \"kilo\",\n \"qwen-code\": \"qwen\",\n};\n\nexport function getAgentAlias(registryId: string): string {\n return REGISTRY_AGENT_ALIASES[registryId] ?? registryId;\n}\n\nexport function getAgentDependencies(registryId: string): AgentDependency[] {\n return AGENT_DEPENDENCIES[registryId] ?? [];\n}\n\nexport function getAgentCapabilities(agentName: string): AgentCapability {\n return AGENT_CAPABILITIES[agentName] ?? { supportsResume: false };\n}\n\nexport function listAgentsWithIntegration(): string[] {\n return Object.entries(AGENT_CAPABILITIES)\n .filter(([, cap]) => cap.integration != null)\n .map(([key]) => key);\n}\n\nexport function commandExists(cmd: string): boolean {\n try {\n execFileSync(\"which\", [cmd], { stdio: \"pipe\" });\n return true;\n } catch {\n // not in PATH\n }\n // Check node_modules/.bin (walks up from cwd)\n let dir = process.cwd();\n while (true) {\n const binPath = path.join(dir, \"node_modules\", \".bin\", cmd);\n if (fs.existsSync(binPath)) return true;\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return false;\n}\n\nexport function checkDependencies(registryId: string): AvailabilityResult {\n const deps = getAgentDependencies(registryId);\n if (deps.length === 0) return { available: true };\n\n const missing = deps.filter((d) => !commandExists(d.command));\n if (missing.length === 0) return { available: true };\n\n return {\n available: false,\n reason: `Requires: ${missing.map((m) => m.label).join(\", \")}`,\n missing: missing.map((m) => ({ label: m.label, installHint: m.installHint })),\n };\n}\n\nexport function checkRuntimeAvailable(runtime: \"npx\" | \"uvx\"): boolean {\n return commandExists(runtime);\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport https from 'node:https'\nimport os from 'node:os'\nimport { execSync } from 'node:child_process'\nimport { createChildLogger } from './log.js'\nimport { commandExists } from '../agents/agent-dependencies.js'\n\nconst log = createChildLogger({ module: 'binary-installer' })\n\nconst DEFAULT_BIN_DIR = path.join(os.homedir(), '.openacp', 'bin')\nconst IS_WINDOWS = os.platform() === 'win32'\n\nexport interface BinarySpec {\n name: string\n /** GitHub base URL for releases, e.g. \"https://github.com/jqlang/jq/releases/latest/download\" */\n githubBaseUrl: string\n /** Platform → arch → filename mapping */\n platforms: Record<string, Record<string, string>>\n /** If true, downloaded file is a .tgz archive that needs extraction */\n isArchive?: (url: string) => boolean\n}\n\nfunction downloadFile(url: string, dest: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const file = fs.createWriteStream(dest)\n\n const cleanup = () => {\n try { if (fs.existsSync(dest)) fs.unlinkSync(dest) } catch { /* ignore */ }\n }\n\n https.get(url, (response) => {\n if (response.statusCode === 301 || response.statusCode === 302) {\n file.close(() => {\n cleanup()\n downloadFile(response.headers.location!, dest).then(resolve).catch(reject)\n })\n return\n }\n\n if (response.statusCode !== 200) {\n file.close(() => {\n cleanup()\n reject(new Error(`Download failed with status ${response.statusCode}`))\n })\n return\n }\n\n response.pipe(file)\n file.on('finish', () => file.close(() => resolve(dest)))\n file.on('error', (err) => {\n file.close(() => {\n cleanup()\n reject(err)\n })\n })\n }).on('error', (err) => {\n file.close(() => {\n cleanup()\n reject(err)\n })\n })\n })\n}\n\nfunction getDownloadUrl(spec: BinarySpec): string {\n const platform = os.platform()\n const arch = os.arch()\n const mapping = spec.platforms[platform]\n if (!mapping) throw new Error(`${spec.name}: unsupported platform ${platform}`)\n const binary = mapping[arch]\n if (!binary) throw new Error(`${spec.name}: unsupported architecture ${arch} for ${platform}`)\n return `${spec.githubBaseUrl}/${binary}`\n}\n\n/**\n * Ensure a binary is available.\n * 1. Check PATH first (respects user's system install)\n * 2. Check ~/.openacp/bin/\n * 3. Download from GitHub releases\n */\nexport async function ensureBinary(spec: BinarySpec, binDir?: string): Promise<string> {\n const resolvedBinDir = binDir ?? DEFAULT_BIN_DIR\n const binName = IS_WINDOWS ? `${spec.name}.exe` : spec.name\n const binPath = path.join(resolvedBinDir, binName)\n\n // 1. Check PATH first\n if (commandExists(spec.name)) {\n log.debug({ name: spec.name }, 'Found in PATH')\n return spec.name\n }\n\n // 2. Check our bin directory\n if (fs.existsSync(binPath)) {\n if (!IS_WINDOWS) fs.chmodSync(binPath, '755')\n log.debug({ name: spec.name, path: binPath }, 'Found in ~/.openacp/bin')\n return binPath\n }\n\n // 3. Download\n log.info({ name: spec.name }, 'Not found, downloading from GitHub...')\n fs.mkdirSync(resolvedBinDir, { recursive: true })\n\n const url = getDownloadUrl(spec)\n const isArchive = spec.isArchive?.(url) ?? false\n const downloadDest = isArchive ? path.join(resolvedBinDir, `${spec.name}.tgz`) : binPath\n\n await downloadFile(url, downloadDest)\n\n if (isArchive) {\n execSync(`tar -xzf \"${downloadDest}\" -C \"${resolvedBinDir}\"`, { stdio: 'pipe' })\n try { fs.unlinkSync(downloadDest) } catch { /* ignore */ }\n }\n\n // Validate the binary was actually produced\n if (!fs.existsSync(binPath)) {\n throw new Error(`${spec.name}: binary not found at ${binPath} after download/extraction. The archive structure may have changed.`)\n }\n\n if (!IS_WINDOWS) {\n fs.chmodSync(binPath, '755')\n }\n\n log.info({ name: spec.name, path: binPath }, 'Installed successfully')\n return binPath\n}\n","import { ensureBinary, type BinarySpec } from '../../../core/utils/install-binary.js'\n\nexport const CLOUDFLARED_SPEC: BinarySpec = {\n name: 'cloudflared',\n githubBaseUrl: 'https://github.com/cloudflare/cloudflared/releases/latest/download',\n platforms: {\n darwin: {\n x64: 'cloudflared-darwin-amd64.tgz',\n arm64: 'cloudflared-darwin-arm64.tgz',\n },\n win32: {\n x64: 'cloudflared-windows-amd64.exe',\n },\n linux: {\n x64: 'cloudflared-linux-amd64',\n arm64: 'cloudflared-linux-arm64',\n },\n },\n isArchive: (url) => url.endsWith('.tgz'),\n}\n\nexport async function ensureCloudflared(): Promise<string> {\n return ensureBinary(CLOUDFLARED_SPEC)\n}\n","import { spawn, type ChildProcess } from 'node:child_process'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\nimport { createChildLogger } from '../../../core/utils/log.js'\nimport { commandExists } from '../../../core/agents/agent-dependencies.js'\nimport type { TunnelProvider } from '../provider.js'\n\nconst log = createChildLogger({ module: 'cloudflare-tunnel' })\n\nconst SIGKILL_TIMEOUT_MS = 5_000\n\nexport class CloudflareTunnelProvider implements TunnelProvider {\n private child: ChildProcess | null = null\n private publicUrl = ''\n private options: Record<string, unknown>\n private binDir: string\n private exitCallback: ((code: number | null) => void) | null = null\n\n constructor(options: Record<string, unknown> = {}, binDir?: string) {\n this.options = options\n this.binDir = binDir ?? path.join(os.homedir(), '.openacp', 'bin')\n }\n\n onExit(callback: (code: number | null) => void): void {\n this.exitCallback = callback\n }\n\n async start(localPort: number): Promise<string> {\n // Find binary — post-upgrade should have installed it, but fallback to ensureCloudflared() as safety net\n let binaryPath = this.findBinary()\n if (!binaryPath) {\n log.warn('cloudflared not found locally, attempting auto-install as fallback...')\n try {\n const { ensureCloudflared } = await import('./install-cloudflared.js')\n binaryPath = await ensureCloudflared()\n } catch (err) {\n throw new Error(`cloudflared is not installed and auto-install failed: ${(err as Error).message}`)\n }\n }\n\n const args = ['tunnel', '--url', `http://localhost:${localPort}`]\n if (this.options.domain) {\n args.push('--hostname', String(this.options.domain))\n }\n\n return new Promise<string>((resolve, reject) => {\n let settled = false\n const settle = (fn: () => void) => { if (!settled) { settled = true; fn() } }\n\n const timeout = setTimeout(() => {\n this.stop()\n settle(() => reject(new Error('Cloudflare tunnel timed out after 30s')))\n }, 30_000)\n\n try {\n this.child = spawn(binaryPath, args, { stdio: ['ignore', 'pipe', 'pipe'] })\n } catch {\n clearTimeout(timeout)\n settle(() => reject(new Error(`Failed to start cloudflared at ${binaryPath}`)))\n return\n }\n\n const urlPattern = /https:\\/\\/[a-zA-Z0-9-]+\\.trycloudflare\\.com/\n\n const onData = (data: Buffer) => {\n const line = data.toString()\n log.debug(line.trim())\n const match = line.match(urlPattern)\n if (match) {\n clearTimeout(timeout)\n this.publicUrl = match[0]\n log.info({ url: this.publicUrl }, 'Cloudflare tunnel ready')\n settle(() => resolve(this.publicUrl))\n }\n }\n\n this.child.stdout?.on('data', onData)\n this.child.stderr?.on('data', onData)\n\n this.child.on('error', (err) => {\n clearTimeout(timeout)\n settle(() => reject(new Error(`cloudflared failed to start: ${err.message}`)))\n })\n\n this.child.on('exit', (code) => {\n if (!this.publicUrl) {\n clearTimeout(timeout)\n settle(() => reject(new Error(`cloudflared exited with code ${code} before establishing tunnel`)))\n } else {\n // Post-establishment crash\n log.error({ code }, 'cloudflared exited unexpectedly after establishment')\n this.child = null\n this.exitCallback?.(code)\n }\n })\n })\n }\n\n async stop(): Promise<void> {\n const child = this.child\n if (!child) return\n this.child = null\n\n child.kill('SIGTERM')\n\n // Wait for graceful exit, then SIGKILL if still alive\n const exited = await Promise.race([\n new Promise<boolean>((resolve) => child.on('exit', () => resolve(true))),\n new Promise<boolean>((resolve) => setTimeout(() => resolve(false), SIGKILL_TIMEOUT_MS)),\n ])\n\n if (!exited) {\n log.warn('cloudflared did not exit after SIGTERM, sending SIGKILL')\n child.kill('SIGKILL')\n }\n\n log.info('Cloudflare tunnel stopped')\n }\n\n getPublicUrl(): string {\n return this.publicUrl\n }\n\n private findBinary(): string | null {\n // 1. Check PATH first (respects user's system install)\n if (commandExists('cloudflared')) return 'cloudflared'\n\n // 2. Check binDir (installed by post-upgrade)\n const binPath = path.join(this.binDir, 'cloudflared')\n if (fs.existsSync(binPath)) return binPath\n\n // 3. Not found\n return null\n }\n}\n","import { spawn, type ChildProcess } from 'node:child_process'\nimport { createChildLogger } from '../../../core/utils/log.js'\nimport type { TunnelProvider } from '../provider.js'\n\nconst log = createChildLogger({ module: 'ngrok-tunnel' })\n\nconst SIGKILL_TIMEOUT_MS = 5_000\n\nexport class NgrokTunnelProvider implements TunnelProvider {\n private child: ChildProcess | null = null\n private publicUrl = ''\n private options: Record<string, unknown>\n private exitCallback: ((code: number | null) => void) | null = null\n\n constructor(options: Record<string, unknown> = {}) {\n this.options = options\n }\n\n onExit(callback: (code: number | null) => void): void {\n this.exitCallback = callback\n }\n\n async start(localPort: number): Promise<string> {\n const args = ['http', String(localPort), '--log', 'stdout', '--log-format', 'json']\n if (this.options.authtoken) {\n args.push('--authtoken', String(this.options.authtoken))\n }\n if (this.options.domain) {\n args.push('--domain', String(this.options.domain))\n }\n if (this.options.region) {\n args.push('--region', String(this.options.region))\n }\n\n return new Promise<string>((resolve, reject) => {\n let settled = false\n const settle = (fn: () => void) => { if (!settled) { settled = true; fn() } }\n\n const timeout = setTimeout(() => {\n this.stop()\n settle(() => reject(new Error('ngrok tunnel timed out after 30s. Is ngrok installed?')))\n }, 30_000)\n\n try {\n this.child = spawn('ngrok', args, { stdio: ['ignore', 'pipe', 'pipe'] })\n } catch {\n clearTimeout(timeout)\n settle(() => reject(new Error(\n 'Failed to start ngrok. Install it from https://ngrok.com/download'\n )))\n return\n }\n\n // Match both v2 (*.ngrok.io) and v3 (*.ngrok-free.app, *.ngrok.app) domains\n const urlPattern = /https:\\/\\/[a-zA-Z0-9-]+\\.(?:ngrok(?:-free)?\\.app|ngrok\\.io)/\n\n const onData = (data: Buffer) => {\n const line = data.toString()\n log.debug(line.trim())\n const match = line.match(urlPattern)\n if (match) {\n clearTimeout(timeout)\n this.publicUrl = match[0]\n log.info({ url: this.publicUrl }, 'ngrok tunnel ready')\n settle(() => resolve(this.publicUrl))\n }\n }\n\n this.child.stdout?.on('data', onData)\n this.child.stderr?.on('data', onData)\n\n this.child.on('error', (err) => {\n clearTimeout(timeout)\n settle(() => reject(new Error(\n `ngrok failed to start: ${err.message}. Install it from https://ngrok.com/download`\n )))\n })\n\n this.child.on('exit', (code) => {\n if (!this.publicUrl) {\n clearTimeout(timeout)\n settle(() => reject(new Error(`ngrok exited with code ${code} before establishing tunnel`)))\n } else {\n log.error({ code }, 'ngrok exited unexpectedly after establishment')\n this.child = null\n this.exitCallback?.(code)\n }\n })\n })\n }\n\n async stop(): Promise<void> {\n const child = this.child\n if (!child) return\n this.child = null\n\n child.kill('SIGTERM')\n\n const exited = await Promise.race([\n new Promise<boolean>((resolve) => child.on('exit', () => resolve(true))),\n new Promise<boolean>((resolve) => setTimeout(() => resolve(false), SIGKILL_TIMEOUT_MS)),\n ])\n\n if (!exited) {\n log.warn('ngrok did not exit after SIGTERM, sending SIGKILL')\n child.kill('SIGKILL')\n }\n\n log.info('ngrok tunnel stopped')\n }\n\n getPublicUrl(): string {\n return this.publicUrl\n }\n}\n","import { spawn, type ChildProcess } from 'node:child_process'\nimport { createChildLogger } from '../../../core/utils/log.js'\nimport type { TunnelProvider } from '../provider.js'\n\nconst log = createChildLogger({ module: 'bore-tunnel' })\n\nconst SIGKILL_TIMEOUT_MS = 5_000\n\nexport class BoreTunnelProvider implements TunnelProvider {\n private child: ChildProcess | null = null\n private publicUrl = ''\n private options: Record<string, unknown>\n private exitCallback: ((code: number | null) => void) | null = null\n\n constructor(options: Record<string, unknown> = {}) {\n this.options = options\n }\n\n onExit(callback: (code: number | null) => void): void {\n this.exitCallback = callback\n }\n\n async start(localPort: number): Promise<string> {\n const server = String(this.options.server || 'bore.pub')\n const args = ['local', String(localPort), '--to', server]\n if (this.options.port) {\n args.push('--port', String(this.options.port))\n }\n if (this.options.secret) {\n args.push('--secret', String(this.options.secret))\n }\n\n return new Promise<string>((resolve, reject) => {\n let settled = false\n const settle = (fn: () => void) => { if (!settled) { settled = true; fn() } }\n\n const timeout = setTimeout(() => {\n this.stop()\n settle(() => reject(new Error('Bore tunnel timed out after 30s. Is bore installed?')))\n }, 30_000)\n\n try {\n this.child = spawn('bore', args, { stdio: ['ignore', 'pipe', 'pipe'] })\n } catch {\n clearTimeout(timeout)\n settle(() => reject(new Error(\n 'Failed to start bore. Install it from https://github.com/ekzhang/bore'\n )))\n return\n }\n\n const urlPattern = /listening at ([^\\s]+):(\\d+)/\n\n const onData = (data: Buffer) => {\n const line = data.toString()\n log.debug(line.trim())\n const match = line.match(urlPattern)\n if (match) {\n clearTimeout(timeout)\n this.publicUrl = `http://${match[1]}:${match[2]}`\n log.info({ url: this.publicUrl }, 'Bore tunnel ready')\n settle(() => resolve(this.publicUrl))\n }\n }\n\n this.child.stdout?.on('data', onData)\n this.child.stderr?.on('data', onData)\n\n this.child.on('error', (err) => {\n clearTimeout(timeout)\n settle(() => reject(new Error(\n `bore failed to start: ${err.message}. Install it from https://github.com/ekzhang/bore`\n )))\n })\n\n this.child.on('exit', (code) => {\n if (!this.publicUrl) {\n clearTimeout(timeout)\n settle(() => reject(new Error(`bore exited with code ${code} before establishing tunnel`)))\n } else {\n log.error({ code }, 'bore exited unexpectedly after establishment')\n this.child = null\n this.exitCallback?.(code)\n }\n })\n })\n }\n\n async stop(): Promise<void> {\n const child = this.child\n if (!child) return\n this.child = null\n\n child.kill('SIGTERM')\n\n const exited = await Promise.race([\n new Promise<boolean>((resolve) => child.on('exit', () => resolve(true))),\n new Promise<boolean>((resolve) => setTimeout(() => resolve(false), SIGKILL_TIMEOUT_MS)),\n ])\n\n if (!exited) {\n log.warn('bore did not exit after SIGTERM, sending SIGKILL')\n child.kill('SIGKILL')\n }\n\n log.info('Bore tunnel stopped')\n }\n\n getPublicUrl(): string {\n return this.publicUrl\n }\n}\n","import { spawn, execSync, type ChildProcess } from 'node:child_process'\nimport { createChildLogger } from '../../../core/utils/log.js'\nimport type { TunnelProvider } from '../provider.js'\n\nconst log = createChildLogger({ module: 'tailscale-tunnel' })\n\nconst SIGKILL_TIMEOUT_MS = 5_000\n\nexport class TailscaleTunnelProvider implements TunnelProvider {\n private child: ChildProcess | null = null\n private publicUrl = ''\n private options: Record<string, unknown>\n private exitCallback: ((code: number | null) => void) | null = null\n\n constructor(options: Record<string, unknown> = {}) {\n this.options = options\n }\n\n onExit(callback: (code: number | null) => void): void {\n this.exitCallback = callback\n }\n\n async start(localPort: number): Promise<string> {\n let hostname = ''\n try {\n const statusJson = execSync('tailscale status --json', { encoding: 'utf-8', timeout: 10_000 })\n const status = JSON.parse(statusJson)\n hostname = String(status.Self.DNSName).replace(/\\.$/, '')\n log.debug({ hostname }, 'Resolved Tailscale hostname')\n } catch (err) {\n log.warn('Failed to resolve Tailscale hostname via status --json')\n }\n\n const args = ['funnel', String(localPort)]\n if (this.options.bg) {\n args.push('--bg')\n }\n\n return new Promise<string>((resolve, reject) => {\n let settled = false\n const settle = (fn: () => void) => { if (!settled) { settled = true; fn() } }\n\n const timeout = setTimeout(() => {\n this.stop()\n settle(() => reject(new Error('Tailscale funnel timed out after 30s. Is tailscale installed?')))\n }, 30_000)\n\n try {\n this.child = spawn('tailscale', args, { stdio: ['ignore', 'pipe', 'pipe'] })\n } catch {\n clearTimeout(timeout)\n settle(() => reject(new Error(\n 'Failed to start tailscale. Install it from https://tailscale.com/download'\n )))\n return\n }\n\n // Match only Tailscale funnel URLs (*.ts.net pattern)\n const urlPattern = /https:\\/\\/[a-zA-Z0-9-]+\\.[a-zA-Z0-9-]+\\.ts\\.net/\n\n const onData = (data: Buffer) => {\n const line = data.toString()\n log.debug(line.trim())\n const match = line.match(urlPattern)\n if (match) {\n clearTimeout(timeout)\n this.publicUrl = match[0]\n log.info({ url: this.publicUrl }, 'Tailscale funnel ready')\n settle(() => resolve(this.publicUrl))\n }\n }\n\n this.child.stdout?.on('data', onData)\n this.child.stderr?.on('data', onData)\n\n this.child.on('error', (err) => {\n clearTimeout(timeout)\n settle(() => reject(new Error(\n `tailscale failed to start: ${err.message}. Install it from https://tailscale.com/download`\n )))\n })\n\n this.child.on('exit', (code) => {\n if (!this.publicUrl) {\n clearTimeout(timeout)\n if (hostname) {\n // Tailscale funnel may exit immediately after configuring — construct URL with port\n this.publicUrl = `https://${hostname}:${localPort}`\n this.child = null // process is done; prevent stop() from sending SIGTERM to dead process\n log.info({ url: this.publicUrl }, 'Tailscale funnel ready (constructed from hostname)')\n settle(() => resolve(this.publicUrl))\n } else {\n settle(() => reject(new Error(`tailscale exited with code ${code} before establishing funnel`)))\n }\n } else {\n log.error({ code }, 'tailscale exited unexpectedly after establishment')\n this.child = null\n this.exitCallback?.(code)\n }\n })\n })\n }\n\n async stop(): Promise<void> {\n const child = this.child\n if (!child) return\n this.child = null\n\n child.kill('SIGTERM')\n\n const exited = await Promise.race([\n new Promise<boolean>((resolve) => child.on('exit', () => resolve(true))),\n new Promise<boolean>((resolve) => setTimeout(() => resolve(false), SIGKILL_TIMEOUT_MS)),\n ])\n\n if (!exited) {\n log.warn('tailscale did not exit after SIGTERM, sending SIGKILL')\n child.kill('SIGKILL')\n }\n\n log.info('Tailscale funnel stopped')\n }\n\n getPublicUrl(): string {\n return this.publicUrl\n }\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\nimport { createChildLogger } from '../../core/utils/log.js'\nimport type { TunnelProvider } from './provider.js'\nimport { CloudflareTunnelProvider } from './providers/cloudflare.js'\nimport { NgrokTunnelProvider } from './providers/ngrok.js'\nimport { BoreTunnelProvider } from './providers/bore.js'\nimport { TailscaleTunnelProvider } from './providers/tailscale.js'\n\nconst log = createChildLogger({ module: 'tunnel-registry' })\n\nexport const MAX_RETRIES = 5\nconst BASE_RETRY_DELAY_MS = 2_000\n\nexport interface TunnelEntry {\n port: number\n type: 'system' | 'user'\n provider: string\n label?: string\n publicUrl?: string\n sessionId?: string\n status: 'stopped' | 'starting' | 'active' | 'failed'\n retryCount: number\n createdAt: string\n}\n\ninterface PersistedEntry {\n port: number\n type: 'system' | 'user'\n provider: string\n label?: string\n sessionId?: string\n createdAt: string\n}\n\ninterface LiveEntry {\n entry: TunnelEntry\n process: TunnelProvider | null\n spawnPromise: Promise<string> | null\n retryTimer: ReturnType<typeof setTimeout> | null\n}\n\nexport class TunnelRegistry {\n private entries: Map<number, LiveEntry> = new Map()\n private saveTimeout: ReturnType<typeof setTimeout> | null = null\n private maxUserTunnels: number\n private providerOptions: Record<string, unknown>\n private registryPath: string\n private shuttingDown = false\n\n constructor(opts: { maxUserTunnels?: number; providerOptions?: Record<string, unknown>; registryPath?: string } = {}) {\n this.maxUserTunnels = opts.maxUserTunnels ?? 5\n this.providerOptions = opts.providerOptions ?? {}\n this.registryPath = opts.registryPath ?? path.join(os.homedir(), '.openacp', 'tunnels.json')\n }\n\n async add(port: number, opts: {\n type: 'system' | 'user'\n provider: string\n label?: string\n sessionId?: string\n }): Promise<TunnelEntry> {\n // Check if port already registered\n if (this.entries.has(port)) {\n const existing = this.entries.get(port)!\n if (existing.entry.status === 'active' || existing.entry.status === 'starting') {\n throw new Error(`Port ${port} is already tunneled → ${existing.entry.publicUrl || 'starting...'}`)\n }\n // Stopped/failed entry — clean up retry timer and re-add\n if (existing.retryTimer) clearTimeout(existing.retryTimer)\n this.entries.delete(port)\n }\n\n // Check max user tunnels\n if (opts.type === 'user') {\n const userCount = this.list(false).filter(e => e.status === 'active' || e.status === 'starting').length\n if (userCount >= this.maxUserTunnels) {\n throw new Error(`Max user tunnels (${this.maxUserTunnels}) reached. Stop a tunnel first.`)\n }\n }\n\n const entry: TunnelEntry = {\n port,\n type: opts.type,\n provider: opts.provider,\n label: opts.label,\n sessionId: opts.sessionId,\n status: 'starting',\n retryCount: 0,\n createdAt: new Date().toISOString(),\n }\n\n const provider = this.createProvider(opts.provider)\n\n // Wire up post-establishment crash detection with auto-retry\n provider.onExit((code) => {\n if (this.shuttingDown) return\n const live = this.entries.get(port)\n if (!live) return\n\n live.entry.status = 'failed'\n live.process = null\n this.scheduleSave()\n\n if (live.entry.retryCount < MAX_RETRIES) {\n const delay = BASE_RETRY_DELAY_MS * Math.pow(2, live.entry.retryCount)\n log.warn({ port, code, retry: live.entry.retryCount + 1, maxRetries: MAX_RETRIES, delayMs: delay },\n 'Tunnel crashed, scheduling retry')\n live.retryTimer = setTimeout(() => this.retry(port, opts), delay)\n } else {\n log.error({ port, code }, `Tunnel crashed and exhausted all ${MAX_RETRIES} retries`)\n }\n })\n\n const spawnPromise = provider.start(port).then(url => {\n entry.publicUrl = url\n entry.status = 'active'\n log.info({ port, url, label: opts.label }, 'Tunnel active')\n this.scheduleSave()\n return url\n }).catch(err => {\n entry.status = 'failed'\n log.error({ port, err: (err as Error).message }, 'Tunnel failed to start')\n this.scheduleSave()\n throw err\n })\n\n this.entries.set(port, { entry, process: provider, spawnPromise, retryTimer: null })\n this.scheduleSave()\n\n // Await spawn — caller gets the URL or error\n await spawnPromise\n return entry\n }\n\n private async retry(port: number, opts: {\n type: 'system' | 'user'\n provider: string\n label?: string\n sessionId?: string\n }): Promise<void> {\n if (this.shuttingDown) return\n const live = this.entries.get(port)\n if (!live) return\n\n const retryCount = live.entry.retryCount + 1\n log.info({ port, retry: retryCount, maxRetries: MAX_RETRIES }, 'Retrying tunnel')\n\n // Remove old entry so add() doesn't reject\n if (live.retryTimer) clearTimeout(live.retryTimer)\n this.entries.delete(port)\n\n try {\n const entry = await this.add(port, opts)\n entry.retryCount = retryCount\n } catch (err) {\n log.error({ port, err: (err as Error).message, retry: retryCount }, 'Tunnel retry failed')\n\n // Re-insert as failed with incremented retry count for next onExit cycle\n const failedEntry: TunnelEntry = {\n port,\n type: opts.type,\n provider: opts.provider,\n label: opts.label,\n sessionId: opts.sessionId,\n status: 'failed',\n retryCount,\n createdAt: live.entry.createdAt,\n }\n\n if (retryCount < MAX_RETRIES) {\n const delay = BASE_RETRY_DELAY_MS * Math.pow(2, retryCount)\n const retryTimer = setTimeout(() => this.retry(port, opts), delay)\n this.entries.set(port, { entry: failedEntry, process: null, spawnPromise: null, retryTimer })\n log.warn({ port, retry: retryCount + 1, delayMs: delay }, 'Scheduling next retry')\n } else {\n this.entries.set(port, { entry: failedEntry, process: null, spawnPromise: null, retryTimer: null })\n log.error({ port }, `Tunnel exhausted all ${MAX_RETRIES} retries`)\n }\n this.scheduleSave()\n }\n }\n\n async stop(port: number): Promise<void> {\n const live = this.entries.get(port)\n if (!live) return\n\n if (live.entry.type === 'system') {\n throw new Error('Cannot stop system tunnel')\n }\n\n // Cancel any pending retry\n if (live.retryTimer) clearTimeout(live.retryTimer)\n\n // Wait for spawn to finish if still starting\n if (live.spawnPromise) {\n try { await live.spawnPromise } catch { /* ignore spawn error */ }\n }\n\n if (live.process) {\n await live.process.stop()\n }\n\n this.entries.delete(port)\n this.scheduleSave()\n log.info({ port, label: live.entry.label }, 'Tunnel stopped')\n }\n\n async stopBySession(sessionId: string): Promise<TunnelEntry[]> {\n const stopped: TunnelEntry[] = []\n const toStop = this.getBySession(sessionId)\n for (const entry of toStop) {\n try {\n await this.stop(entry.port)\n stopped.push(entry)\n } catch { /* ignore */ }\n }\n return stopped\n }\n\n async stopAllUser(): Promise<void> {\n const userEntries = this.list(false)\n for (const entry of userEntries) {\n try { await this.stop(entry.port) } catch { /* ignore */ }\n }\n }\n\n async shutdown(): Promise<void> {\n this.shuttingDown = true\n\n for (const [, live] of this.entries) {\n if (live.retryTimer) clearTimeout(live.retryTimer)\n if (live.spawnPromise) {\n try { await live.spawnPromise } catch { /* ignore */ }\n }\n if (live.process) {\n await live.process.stop()\n }\n }\n this.entries.clear()\n this.scheduleSave()\n }\n\n list(includeSystem = false): TunnelEntry[] {\n const entries = Array.from(this.entries.values()).map(l => l.entry)\n if (includeSystem) return entries\n return entries.filter(e => e.type === 'user')\n }\n\n get(port: number): TunnelEntry | null {\n return this.entries.get(port)?.entry ?? null\n }\n\n getBySession(sessionId: string): TunnelEntry[] {\n return this.list(false).filter(e => e.sessionId === sessionId)\n }\n\n getSystemEntry(): TunnelEntry | null {\n for (const live of this.entries.values()) {\n if (live.entry.type === 'system') return live.entry\n }\n return null\n }\n\n async restore(): Promise<void> {\n if (!fs.existsSync(this.registryPath)) return\n\n try {\n const raw = JSON.parse(fs.readFileSync(this.registryPath, 'utf-8')) as PersistedEntry[]\n log.info({ count: raw.length }, 'Restoring tunnels')\n\n // Only restore user tunnels — system tunnel is registered separately by TunnelService.start()\n const userEntries = raw.filter(e => e.type === 'user')\n for (const persisted of userEntries) {\n try {\n await this.add(persisted.port, {\n type: persisted.type,\n provider: persisted.provider,\n label: persisted.label,\n sessionId: persisted.sessionId,\n })\n } catch (err) {\n log.warn({ port: persisted.port, err: (err as Error).message }, 'Failed to restore tunnel')\n }\n }\n } catch (err) {\n log.warn({ err: (err as Error).message }, 'Failed to read tunnels.json')\n }\n }\n\n private createProvider(name: string): TunnelProvider {\n switch (name) {\n case 'cloudflare':\n return new CloudflareTunnelProvider(this.providerOptions)\n case 'ngrok':\n return new NgrokTunnelProvider(this.providerOptions)\n case 'bore':\n return new BoreTunnelProvider(this.providerOptions)\n case 'tailscale':\n return new TailscaleTunnelProvider(this.providerOptions)\n default:\n log.warn({ provider: name }, 'Unknown provider, falling back to cloudflare')\n return new CloudflareTunnelProvider(this.providerOptions)\n }\n }\n\n private scheduleSave(): void {\n if (this.saveTimeout) clearTimeout(this.saveTimeout)\n this.saveTimeout = setTimeout(() => this.save(), 2000)\n }\n\n private save(): void {\n const data: PersistedEntry[] = Array.from(this.entries.values()).map(l => ({\n port: l.entry.port,\n type: l.entry.type,\n provider: l.entry.provider,\n label: l.entry.label,\n sessionId: l.entry.sessionId,\n createdAt: l.entry.createdAt,\n }))\n\n try {\n const dir = path.dirname(this.registryPath)\n fs.mkdirSync(dir, { recursive: true })\n fs.writeFileSync(this.registryPath, JSON.stringify(data, null, 2))\n } catch (err) {\n log.error({ err: (err as Error).message }, 'Failed to save tunnels.json')\n }\n }\n\n flush(): void {\n if (this.saveTimeout) {\n clearTimeout(this.saveTimeout)\n this.saveTimeout = null\n }\n this.save()\n }\n}\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { nanoid } from 'nanoid'\nimport { createChildLogger } from '../../core/utils/log.js'\n\nconst log = createChildLogger({ module: 'viewer-store' })\n\nconst MAX_CONTENT_SIZE = 1_000_000 // 1MB\n\nconst EXTENSION_LANGUAGE: Record<string, string> = {\n '.ts': 'typescript', '.tsx': 'typescript', '.js': 'javascript', '.jsx': 'javascript',\n '.py': 'python', '.rs': 'rust', '.go': 'go', '.java': 'java', '.kt': 'kotlin',\n '.rb': 'ruby', '.php': 'php', '.c': 'c', '.cpp': 'cpp', '.h': 'c', '.hpp': 'cpp',\n '.cs': 'csharp', '.swift': 'swift', '.sh': 'bash', '.zsh': 'bash', '.bash': 'bash',\n '.json': 'json', '.yaml': 'yaml', '.yml': 'yaml', '.toml': 'toml',\n '.xml': 'xml', '.html': 'html', '.css': 'css', '.scss': 'scss',\n '.sql': 'sql', '.md': 'markdown', '.dockerfile': 'dockerfile',\n '.tf': 'hcl', '.vue': 'xml', '.svelte': 'xml',\n}\n\nexport interface ViewerEntry {\n id: string\n type: 'file' | 'diff' | 'output'\n filePath?: string\n content: string\n oldContent?: string\n language?: string\n sessionId: string\n workingDirectory: string\n createdAt: number\n expiresAt: number\n}\n\nexport class ViewerStore {\n private entries = new Map<string, ViewerEntry>()\n private cleanupTimer: ReturnType<typeof setInterval>\n private ttlMs: number\n\n constructor(ttlMinutes: number = 60) {\n this.ttlMs = ttlMinutes * 60 * 1000\n this.cleanupTimer = setInterval(() => this.cleanup(), 5 * 60 * 1000)\n }\n\n storeFile(sessionId: string, filePath: string, content: string, workingDirectory: string): string | null {\n if (!this.isPathAllowed(filePath, workingDirectory)) {\n log.warn({ filePath, workingDirectory }, 'Path outside workspace, rejecting')\n return null\n }\n if (content.length > MAX_CONTENT_SIZE) {\n log.debug({ filePath, size: content.length }, 'File too large for viewer')\n return null\n }\n\n const id = nanoid(12)\n const now = Date.now()\n this.entries.set(id, {\n id,\n type: 'file',\n filePath,\n content,\n language: this.detectLanguage(filePath),\n sessionId,\n workingDirectory,\n createdAt: now,\n expiresAt: now + this.ttlMs,\n })\n log.debug({ id, filePath }, 'Stored file for viewing')\n return id\n }\n\n storeDiff(sessionId: string, filePath: string, oldContent: string, newContent: string, workingDirectory: string): string | null {\n if (!this.isPathAllowed(filePath, workingDirectory)) {\n log.warn({ filePath, workingDirectory }, 'Path outside workspace, rejecting')\n return null\n }\n const combined = oldContent.length + newContent.length\n if (combined > MAX_CONTENT_SIZE) {\n log.debug({ filePath, size: combined }, 'Diff content too large for viewer')\n return null\n }\n\n const id = nanoid(12)\n const now = Date.now()\n this.entries.set(id, {\n id,\n type: 'diff',\n filePath,\n content: newContent,\n oldContent,\n language: this.detectLanguage(filePath),\n sessionId,\n workingDirectory,\n createdAt: now,\n expiresAt: now + this.ttlMs,\n })\n log.debug({ id, filePath }, 'Stored diff for viewing')\n return id\n }\n\n storeOutput(sessionId: string, label: string, output: string): string | null {\n if (output.length > MAX_CONTENT_SIZE) {\n log.debug({ label, size: output.length }, 'Output too large for viewer')\n return null\n }\n const id = nanoid(12)\n const now = Date.now()\n this.entries.set(id, {\n id,\n type: 'output',\n filePath: label,\n content: output,\n language: 'text',\n sessionId,\n workingDirectory: '',\n createdAt: now,\n expiresAt: now + this.ttlMs,\n })\n log.debug({ id, label }, 'Stored output for viewing')\n return id\n }\n\n get(id: string): ViewerEntry | undefined {\n const entry = this.entries.get(id)\n if (!entry) return undefined\n if (Date.now() > entry.expiresAt) {\n this.entries.delete(id)\n return undefined\n }\n return entry\n }\n\n private cleanup(): void {\n const now = Date.now()\n let removed = 0\n for (const [id, entry] of this.entries) {\n if (now > entry.expiresAt) {\n this.entries.delete(id)\n removed++\n }\n }\n if (removed > 0) {\n log.debug({ removed, remaining: this.entries.size }, 'Cleaned up expired viewer entries')\n }\n }\n\n private isPathAllowed(filePath: string, workingDirectory: string): boolean {\n const caseInsensitive = process.platform === 'darwin' || process.platform === 'win32'\n\n // Resolve paths, using realpathSync when possible for symlink/case canonicalization\n let resolved: string\n let workspace: string\n try { resolved = fs.realpathSync(path.resolve(workingDirectory, filePath)) }\n catch { resolved = path.resolve(workingDirectory, filePath) }\n try { workspace = fs.realpathSync(path.resolve(workingDirectory)) }\n catch { workspace = path.resolve(workingDirectory) }\n\n // macOS/Windows have case-insensitive filesystems — always compare lowercase\n if (caseInsensitive) {\n const rLower = resolved.toLowerCase()\n const wLower = workspace.toLowerCase()\n return rLower.startsWith(wLower + path.sep) || rLower === wLower\n }\n return resolved.startsWith(workspace + path.sep) || resolved === workspace\n }\n\n private detectLanguage(filePath: string): string | undefined {\n const ext = path.extname(filePath).toLowerCase()\n return EXTENSION_LANGUAGE[ext]\n }\n\n destroy(): void {\n clearInterval(this.cleanupTimer)\n this.entries.clear()\n }\n}\n","import type { ViewerEntry } from '../viewer-store.js'\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n}\n\n// Map our language IDs to Monaco language IDs\nconst MONACO_LANGUAGE: Record<string, string> = {\n typescript: 'typescript', javascript: 'javascript', python: 'python',\n rust: 'rust', go: 'go', java: 'java', kotlin: 'kotlin', ruby: 'ruby',\n php: 'php', c: 'c', cpp: 'cpp', csharp: 'csharp', swift: 'swift',\n bash: 'shell', json: 'json', yaml: 'yaml', toml: 'ini', xml: 'xml',\n html: 'html', css: 'css', scss: 'scss', sql: 'sql', markdown: 'markdown',\n dockerfile: 'dockerfile', hcl: 'hcl', plaintext: 'plaintext',\n}\n\nfunction getMonacoLang(lang?: string): string {\n if (!lang) return 'plaintext'\n return MONACO_LANGUAGE[lang] || 'plaintext'\n}\n\nexport function renderFileViewer(entry: ViewerEntry): string {\n const fileName = entry.filePath || 'untitled'\n const lang = getMonacoLang(entry.language)\n // Escape </script> inside content to prevent premature tag closure\n const safeContent = JSON.stringify(entry.content).replace(/<\\//g, '<\\\\/')\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${escapeHtml(fileName)} - OpenACP</title>\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body { background: #1e1e1e; color: #d4d4d4; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; display: flex; flex-direction: column; height: 100vh; }\n .header { background: #252526; border-bottom: 1px solid #3c3c3c; padding: 8px 16px; display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; z-index: 10; }\n .file-info { display: flex; align-items: center; gap: 8px; font-size: 13px; min-width: 0; }\n .file-icon { font-size: 14px; flex-shrink: 0; }\n .file-path { color: #969696; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .file-name { color: #e0e0e0; font-weight: 500; flex-shrink: 0; }\n .actions { display: flex; gap: 6px; flex-shrink: 0; }\n .btn { background: #3c3c3c; color: #d4d4d4; border: 1px solid #505050; padding: 4px 10px; border-radius: 4px; cursor: pointer; font-size: 12px; transition: background 0.15s; }\n .btn:hover { background: #505050; }\n .btn.active { background: #0e639c; border-color: #1177bb; }\n #editor-container { flex: 1; overflow: hidden; }\n .status-bar { background: #007acc; color: #fff; padding: 2px 16px; font-size: 12px; display: flex; justify-content: space-between; flex-shrink: 0; }\n </style>\n</head>\n<body>\n <div class=\"header\">\n <div class=\"file-info\">\n <span class=\"file-icon\">📄</span>\n ${formatBreadcrumb(fileName)}\n </div>\n <div class=\"actions\">\n ${lang === 'markdown' ? '<button class=\"btn\" onclick=\"togglePreview()\" id=\"btn-preview\">Preview</button>' : ''}\n <button class=\"btn\" onclick=\"toggleWordWrap()\" id=\"btn-wrap\">Wrap</button>\n <button class=\"btn\" onclick=\"toggleMinimap()\" id=\"btn-minimap\">Minimap</button>\n <button class=\"btn\" onclick=\"toggleTheme()\" id=\"btn-theme\">Light</button>\n <button class=\"btn\" onclick=\"copyCode()\">Copy</button>\n </div>\n </div>\n <div id=\"editor-container\"></div>\n <div id=\"preview-wrapper\" style=\"display:none; flex:1; overflow-y:auto;\">\n <div id=\"preview-container\" style=\"padding:24px 48px; max-width:900px; margin:0 auto; width:100%;\"></div>\n </div>\n <div class=\"status-bar\">\n <span>${escapeHtml(entry.language || 'plaintext')} | ${entry.content.split('\\n').length} lines</span>\n <span>OpenACP Viewer (read-only)</span>\n </div>\n\n ${lang === 'markdown' ? '<script src=\"https://cdn.jsdelivr.net/npm/marked@15.0.0/marked.min.js\"></script>' : ''}\n <script src=\"https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs/loader.js\"></script>\n <script>\n const content = ${safeContent};\n const lang = ${JSON.stringify(lang)};\n let editor;\n let isDark = true;\n let wordWrap = false;\n let minimap = true;\n\n require.config({ paths: { vs: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs' } });\n require(['vs/editor/editor.main'], function () {\n editor = monaco.editor.create(document.getElementById('editor-container'), {\n value: content,\n language: lang,\n theme: 'vs-dark',\n readOnly: true,\n automaticLayout: true,\n minimap: { enabled: true },\n scrollBeyondLastLine: false,\n fontSize: 13,\n fontFamily: \"'SF Mono', SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace\",\n lineNumbers: 'on',\n renderLineHighlight: 'all',\n wordWrap: 'off',\n padding: { top: 8 },\n });\n\n // Handle line range from URL hash: #L42 or #L42-L55\n function highlightFromHash() {\n const hash = location.hash.slice(1);\n const match = hash.match(/^L(\\\\d+)(?:-L?(\\\\d+))?$/);\n if (!match) return;\n const startLine = parseInt(match[1], 10);\n const endLine = match[2] ? parseInt(match[2], 10) : startLine;\n editor.revealLineInCenter(startLine);\n editor.setSelection(new monaco.Selection(startLine, 1, endLine + 1, 1));\n }\n highlightFromHash();\n window.addEventListener('hashchange', highlightFromHash);\n });\n\n function toggleTheme() {\n isDark = !isDark;\n monaco.editor.setTheme(isDark ? 'vs-dark' : 'vs');\n document.body.style.background = isDark ? '#1e1e1e' : '#ffffff';\n document.querySelector('.header').style.background = isDark ? '#252526' : '#f3f3f3';\n document.querySelector('.header').style.borderColor = isDark ? '#3c3c3c' : '#e0e0e0';\n document.getElementById('btn-theme').textContent = isDark ? 'Light' : 'Dark';\n }\n\n function toggleWordWrap() {\n wordWrap = !wordWrap;\n editor.updateOptions({ wordWrap: wordWrap ? 'on' : 'off' });\n document.getElementById('btn-wrap').classList.toggle('active', wordWrap);\n }\n\n function toggleMinimap() {\n minimap = !minimap;\n editor.updateOptions({ minimap: { enabled: minimap } });\n document.getElementById('btn-minimap').classList.toggle('active', !minimap);\n }\n\n function copyCode() {\n navigator.clipboard.writeText(content).then(() => {\n const btn = event.target;\n btn.textContent = 'Copied!';\n setTimeout(() => btn.textContent = 'Copy', 2000);\n });\n }\n\n let previewMode = false;\n function togglePreview() {\n previewMode = !previewMode;\n const editorEl = document.getElementById('editor-container');\n const wrapperEl = document.getElementById('preview-wrapper');\n const previewEl = document.getElementById('preview-container');\n const btn = document.getElementById('btn-preview');\n if (previewMode) {\n editorEl.style.display = 'none';\n wrapperEl.style.display = 'block';\n previewEl.innerHTML = typeof marked !== 'undefined' ? marked.parse(content) : content.replace(/\\\\n/g, '<br>');\n previewEl.style.color = isDark ? '#d4d4d4' : '#1e1e1e';\n wrapperEl.style.background = isDark ? '#1e1e1e' : '#ffffff';\n btn.classList.add('active');\n btn.textContent = 'Editor';\n } else {\n editorEl.style.display = 'block';\n wrapperEl.style.display = 'none';\n btn.classList.remove('active');\n btn.textContent = 'Preview';\n }\n }\n </script>\n <style>\n #preview-container { font-size: 15px; line-height: 1.7; }\n #preview-container h1 { font-size: 2em; margin: 0.5em 0 0.3em; border-bottom: 1px solid #3c3c3c; padding-bottom: 0.3em; }\n #preview-container h2 { font-size: 1.5em; margin: 0.5em 0 0.3em; border-bottom: 1px solid #3c3c3c; padding-bottom: 0.2em; }\n #preview-container h3 { font-size: 1.25em; margin: 0.4em 0 0.2em; }\n #preview-container p { margin: 0.5em 0; }\n #preview-container code { background: rgba(128,128,128,0.2); padding: 2px 6px; border-radius: 3px; font-size: 0.9em; }\n #preview-container pre { background: rgba(0,0,0,0.3); padding: 16px; border-radius: 6px; overflow-x: auto; margin: 0.5em 0; }\n #preview-container pre code { background: none; padding: 0; }\n #preview-container blockquote { border-left: 3px solid #505050; padding-left: 16px; margin: 0.5em 0; color: #969696; }\n #preview-container ul, #preview-container ol { padding-left: 24px; margin: 0.5em 0; }\n #preview-container table { border-collapse: collapse; margin: 0.5em 0; width: 100%; }\n #preview-container th, #preview-container td { border: 1px solid #3c3c3c; padding: 6px 12px; text-align: left; }\n #preview-container th { background: rgba(128,128,128,0.15); }\n #preview-container a { color: #3794ff; }\n #preview-container img { max-width: 100%; }\n </style>\n</body>\n</html>`\n}\n\nfunction formatBreadcrumb(filePath: string): string {\n const parts = filePath.split('/')\n if (parts.length <= 1) return `<span class=\"file-name\">${escapeHtml(filePath)}</span>`\n const dir = parts.slice(0, -1).join(' / ')\n const name = parts[parts.length - 1]\n return `<span class=\"file-path\">${escapeHtml(dir)} /</span> <span class=\"file-name\">${escapeHtml(name)}</span>`\n}\n","import { createPatch } from 'diff'\nimport type { ViewerEntry } from '../viewer-store.js'\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n}\n\nconst MONACO_LANGUAGE: Record<string, string> = {\n typescript: 'typescript', javascript: 'javascript', python: 'python',\n rust: 'rust', go: 'go', java: 'java', kotlin: 'kotlin', ruby: 'ruby',\n php: 'php', c: 'c', cpp: 'cpp', csharp: 'csharp', swift: 'swift',\n bash: 'shell', json: 'json', yaml: 'yaml', toml: 'ini', xml: 'xml',\n html: 'html', css: 'css', scss: 'scss', sql: 'sql', markdown: 'markdown',\n dockerfile: 'dockerfile', hcl: 'hcl', plaintext: 'plaintext',\n}\n\nfunction getMonacoLang(lang?: string): string {\n if (!lang) return 'plaintext'\n return MONACO_LANGUAGE[lang] || 'plaintext'\n}\n\nexport function renderDiffViewer(entry: ViewerEntry): string {\n const fileName = entry.filePath || 'untitled'\n const lang = getMonacoLang(entry.language)\n const oldContent = entry.oldContent || ''\n const newContent = entry.content\n\n // Count changes for stats\n const patch = createPatch(fileName, oldContent, newContent, 'before', 'after')\n const adds = (patch.match(/^\\+[^+]/gm) || []).length\n const dels = (patch.match(/^-[^-]/gm) || []).length\n\n // Escape </script> in content\n const safeOld = JSON.stringify(oldContent).replace(/<\\//g, '<\\\\/')\n const safeNew = JSON.stringify(newContent).replace(/<\\//g, '<\\\\/')\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${escapeHtml(fileName)} (diff) - OpenACP</title>\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body { background: #1e1e1e; color: #d4d4d4; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; display: flex; flex-direction: column; height: 100vh; }\n .header { background: #252526; border-bottom: 1px solid #3c3c3c; padding: 8px 16px; display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; z-index: 10; }\n .file-info { display: flex; align-items: center; gap: 8px; font-size: 13px; }\n .file-icon { font-size: 14px; }\n .file-name { color: #e0e0e0; font-weight: 500; }\n .stats { font-size: 12px; margin-left: 12px; }\n .stats .add { color: #4ec9b0; }\n .stats .del { color: #f14c4c; }\n .actions { display: flex; gap: 6px; }\n .btn { background: #3c3c3c; color: #d4d4d4; border: 1px solid #505050; padding: 4px 10px; border-radius: 4px; cursor: pointer; font-size: 12px; transition: background 0.15s; }\n .btn:hover { background: #505050; }\n .btn.active { background: #0e639c; border-color: #1177bb; }\n #editor-container { flex: 1; overflow: hidden; }\n .status-bar { background: #007acc; color: #fff; padding: 2px 16px; font-size: 12px; display: flex; justify-content: space-between; flex-shrink: 0; }\n </style>\n</head>\n<body>\n <div class=\"header\">\n <div class=\"file-info\">\n <span class=\"file-icon\">📝</span>\n <span class=\"file-name\">${escapeHtml(fileName)}</span>\n <span class=\"stats\"><span class=\"add\">+${adds}</span> / <span class=\"del\">-${dels}</span></span>\n </div>\n <div class=\"actions\">\n <button class=\"btn active\" id=\"btn-side\" onclick=\"setView('side')\">Side by Side</button>\n <button class=\"btn\" id=\"btn-inline\" onclick=\"setView('inline')\">Inline</button>\n <button class=\"btn\" onclick=\"toggleTheme()\" id=\"btn-theme\">Light</button>\n </div>\n </div>\n <div id=\"editor-container\"></div>\n <div class=\"status-bar\">\n <span>${escapeHtml(entry.language || 'plaintext')} | <span class=\"add\">+${adds}</span> <span class=\"del\">-${dels}</span></span>\n <span>OpenACP Diff Viewer</span>\n </div>\n\n <script src=\"https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs/loader.js\"></script>\n <script>\n const oldContent = ${safeOld};\n const newContent = ${safeNew};\n const lang = ${JSON.stringify(lang)};\n let diffEditor;\n let isDark = true;\n let renderSideBySide = true;\n\n require.config({ paths: { vs: 'https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs' } });\n require(['vs/editor/editor.main'], function () {\n const originalModel = monaco.editor.createModel(oldContent, lang);\n const modifiedModel = monaco.editor.createModel(newContent, lang);\n\n diffEditor = monaco.editor.createDiffEditor(document.getElementById('editor-container'), {\n theme: 'vs-dark',\n readOnly: true,\n automaticLayout: true,\n renderSideBySide: true,\n scrollBeyondLastLine: false,\n fontSize: 13,\n fontFamily: \"'SF Mono', SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace\",\n padding: { top: 8 },\n enableSplitViewResizing: true,\n renderOverviewRuler: true,\n });\n\n diffEditor.setModel({ original: originalModel, modified: modifiedModel });\n });\n\n function setView(mode) {\n renderSideBySide = mode === 'side';\n diffEditor.updateOptions({ renderSideBySide });\n document.getElementById('btn-side').classList.toggle('active', renderSideBySide);\n document.getElementById('btn-inline').classList.toggle('active', !renderSideBySide);\n }\n\n function toggleTheme() {\n isDark = !isDark;\n monaco.editor.setTheme(isDark ? 'vs-dark' : 'vs');\n document.body.style.background = isDark ? '#1e1e1e' : '#ffffff';\n document.querySelector('.header').style.background = isDark ? '#252526' : '#f3f3f3';\n document.querySelector('.header').style.borderColor = isDark ? '#3c3c3c' : '#e0e0e0';\n document.getElementById('btn-theme').textContent = isDark ? 'Light' : 'Dark';\n }\n </script>\n</body>\n</html>`\n}\n","import type { ViewerEntry } from '../viewer-store.js'\n\nexport function renderOutputViewer(entry: ViewerEntry): string {\n const label = entry.filePath ?? 'Output'\n const lines = entry.content.split('\\n')\n const lineNumbers = lines\n .map((line, i) => {\n const num = String(i + 1).padStart(String(lines.length).length, ' ')\n return `<span class=\"line-num\">${num}</span><span class=\"line-content\">${escapeHtml(line)}</span>`\n })\n .join('\\n')\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>${escapeHtml(label)} — OpenACP</title>\n<style>\n body { background: #0d1117; color: #c9d1d9; font-family: 'JetBrains Mono', 'Fira Code', monospace; font-size: 13px; margin: 0; padding: 0; }\n header { background: #161b22; border-bottom: 1px solid #30363d; padding: 12px 20px; position: sticky; top: 0; z-index: 10; }\n header h1 { margin: 0; font-size: 14px; color: #e6edf3; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .content { padding: 16px 20px; }\n pre { margin: 0; line-height: 1.6; white-space: pre; overflow-x: auto; }\n .line-num { color: #484f58; user-select: none; margin-right: 16px; display: inline-block; min-width: 3ch; text-align: right; }\n .line-content { color: #c9d1d9; }\n</style>\n</head>\n<body>\n<header><h1>📋 ${escapeHtml(label)}</h1></header>\n<div class=\"content\"><pre>${lineNumbers}</pre></div>\n</body>\n</html>`\n}\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n}\n","import { Hono } from 'hono'\nimport type { ViewerStore } from './viewer-store.js'\nimport { renderFileViewer } from './templates/file-viewer.js'\nimport { renderDiffViewer } from './templates/diff-viewer.js'\nimport { renderOutputViewer } from './templates/output-viewer.js'\n\nfunction notFoundPage(): string {\n return `<!DOCTYPE html>\n<html><head><meta charset=\"UTF-8\"><title>Not Found - OpenACP</title>\n<style>body{background:#0d1117;color:#c9d1d9;font-family:sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0}\n.box{text-align:center;padding:40px}.code{font-size:72px;font-weight:bold;color:#484f58}p{margin-top:16px;color:#8b949e}</style>\n</head><body><div class=\"box\"><div class=\"code\">404</div><p>This viewer link has expired or does not exist.</p></div></body></html>`\n}\n\nexport function createTunnelServer(store: ViewerStore, authToken?: string): Hono {\n const app = new Hono()\n\n // Auth middleware\n if (authToken) {\n app.use('*', async (c, next) => {\n if (c.req.path === '/health') return next()\n const bearer = c.req.header('Authorization')?.replace('Bearer ', '')\n const query = c.req.query('token')\n if (bearer !== authToken && query !== authToken) {\n return c.text('Unauthorized', 401)\n }\n return next()\n })\n }\n\n app.get('/health', (c) => c.json({ status: 'ok' }))\n\n app.get('/view/:id', (c) => {\n const entry = store.get(c.req.param('id'))\n if (!entry || entry.type !== 'file') {\n return c.html(notFoundPage(), 404)\n }\n return c.html(renderFileViewer(entry))\n })\n\n app.get('/diff/:id', (c) => {\n const entry = store.get(c.req.param('id'))\n if (!entry || entry.type !== 'diff') {\n return c.html(notFoundPage(), 404)\n }\n return c.html(renderDiffViewer(entry))\n })\n\n app.get('/output/:id', (c) => {\n const entry = store.get(c.req.param('id'))\n if (!entry || entry.type !== 'output') {\n return c.html(notFoundPage(), 404)\n }\n return c.html(renderOutputViewer(entry))\n })\n\n app.get('/api/file/:id', (c) => {\n const entry = store.get(c.req.param('id'))\n if (!entry || entry.type !== 'file') {\n return c.json({ error: 'not found' }, 404)\n }\n return c.json({ filePath: entry.filePath, content: entry.content, language: entry.language })\n })\n\n app.get('/api/diff/:id', (c) => {\n const entry = store.get(c.req.param('id'))\n if (!entry || entry.type !== 'diff') {\n return c.json({ error: 'not found' }, 404)\n }\n return c.json({ filePath: entry.filePath, oldContent: entry.oldContent, newContent: entry.content, language: entry.language })\n })\n\n return app\n}\n","import { serve } from '@hono/node-server'\nimport type { TunnelConfig } from '../../core/config/config.js'\nimport { createChildLogger } from '../../core/utils/log.js'\nimport { TunnelRegistry, type TunnelEntry } from './tunnel-registry.js'\nimport { ViewerStore } from './viewer-store.js'\nimport { createTunnelServer } from './server.js'\n\nconst log = createChildLogger({ module: 'tunnel' })\n\nexport class TunnelService {\n private registry: TunnelRegistry\n private store: ViewerStore\n private server: ReturnType<typeof serve> | null = null\n private config: TunnelConfig\n private systemPort = 0\n private startError: string | undefined\n\n constructor(config: TunnelConfig, registryPath?: string) {\n this.config = config\n this.store = new ViewerStore(config.storeTtlMinutes)\n this.registry = new TunnelRegistry({\n maxUserTunnels: config.maxUserTunnels ?? 5,\n providerOptions: config.options,\n registryPath,\n })\n }\n\n async start(): Promise<string> {\n // 1. Start HTTP viewer server — try configured port, then auto-increment\n const authToken = this.config.auth.enabled ? this.config.auth.token : undefined\n const app = createTunnelServer(this.store, authToken)\n\n let actualPort = this.config.port\n const maxRetries = 10\n\n for (let i = 0; i < maxRetries; i++) {\n const port = this.config.port + i\n const server = serve({ fetch: app.fetch, port })\n\n const result = await new Promise<{ ok: boolean; code?: string }>((resolve) => {\n server.on('listening', () => resolve({ ok: true }))\n server.on('error', (err: NodeJS.ErrnoException) => resolve({ ok: false, code: err.code }))\n })\n\n if (result.ok) {\n this.server = server\n actualPort = port\n if (i > 0) {\n log.info({ configuredPort: this.config.port, actualPort }, 'Configured port in use, using next available')\n }\n log.info({ port: actualPort }, 'Tunnel HTTP server started')\n break\n }\n\n server.close()\n\n // EACCES = permission denied — retrying other ports won't help\n if (result.code === 'EACCES') {\n log.error({ port }, 'Permission denied binding to port (try a port > 1024)')\n break\n }\n }\n\n if (!this.server) {\n log.error({ port: this.config.port }, 'Failed to start tunnel HTTP server — no available port')\n this.startError = `HTTP server failed to bind (tried ports ${this.config.port}-${this.config.port + maxRetries - 1})`\n return `http://localhost:${this.config.port}`\n }\n\n this.systemPort = actualPort\n\n // 2. Register system tunnel (file viewer)\n try {\n await this.registry.add(actualPort, {\n type: 'system',\n provider: this.config.provider,\n label: 'File Viewer',\n })\n } catch (err) {\n this.startError = (err as Error).message\n log.warn({ err: this.startError }, 'System tunnel failed, running on localhost')\n }\n\n // 3. Restore persisted user tunnels\n await this.registry.restore()\n\n const systemEntry = this.registry.getSystemEntry()\n return systemEntry?.publicUrl || `http://localhost:${actualPort}`\n }\n\n async stop(): Promise<void> {\n await this.registry.shutdown()\n this.registry.flush()\n if (this.server) {\n this.server.close()\n this.server = null\n }\n this.store.destroy()\n log.info('Tunnel service stopped')\n }\n\n // --- User tunnel management ---\n\n async addTunnel(port: number, opts?: { label?: string; sessionId?: string }): Promise<TunnelEntry> {\n return this.registry.add(port, {\n type: 'user',\n provider: this.config.provider,\n label: opts?.label,\n sessionId: opts?.sessionId,\n })\n }\n\n async stopTunnel(port: number): Promise<void> {\n return this.registry.stop(port)\n }\n\n async stopAllUser(): Promise<void> {\n return this.registry.stopAllUser()\n }\n\n async stopBySession(sessionId: string): Promise<TunnelEntry[]> {\n return this.registry.stopBySession(sessionId)\n }\n\n listTunnels(): TunnelEntry[] {\n return this.registry.list(false) // user only\n }\n\n getTunnel(port: number): TunnelEntry | null {\n return this.registry.get(port)\n }\n\n // --- Viewer (system tunnel) ---\n\n getPublicUrl(): string {\n const system = this.registry.getSystemEntry()\n return system?.publicUrl || `http://localhost:${this.systemPort || this.config.port}`\n }\n\n getStartError(): string | undefined {\n return this.startError\n }\n\n getStore(): ViewerStore {\n return this.store\n }\n\n fileUrl(entryId: string): string {\n return `${this.getPublicUrl()}/view/${entryId}`\n }\n\n diffUrl(entryId: string): string {\n return `${this.getPublicUrl()}/diff/${entryId}`\n }\n\n outputUrl(entryId: string): string {\n return `${this.getPublicUrl()}/output/${entryId}`\n }\n}\n","import path from 'node:path'\nimport type { OpenACPPlugin, InstallContext } from '../../core/plugin/types.js'\nimport type { TunnelConfig } from '../../core/config/config.js'\nimport { MAX_RETRIES } from './tunnel-registry.js'\n\nfunction createTunnelPlugin(): OpenACPPlugin {\n let service: { stop(): Promise<void> } | null = null\n\n return {\n name: '@openacp/tunnel',\n version: '1.0.0',\n description: 'Expose local services to internet via tunnel providers',\n essential: false,\n permissions: ['services:register', 'kernel:access', 'commands:register'],\n\n async install(ctx: InstallContext) {\n const { terminal, settings, legacyConfig } = ctx\n\n // Migrate from legacy config if present\n if (legacyConfig) {\n const tunnelCfg = legacyConfig.tunnel as Record<string, unknown> | undefined\n if (tunnelCfg) {\n await settings.setAll({\n enabled: tunnelCfg.enabled ?? true,\n provider: tunnelCfg.provider ?? 'cloudflare',\n port: tunnelCfg.port ?? 3100,\n options: tunnelCfg.options ?? {},\n maxUserTunnels: tunnelCfg.maxUserTunnels ?? 5,\n storeTtlMinutes: tunnelCfg.storeTtlMinutes ?? 60,\n auth: tunnelCfg.auth ?? { enabled: false },\n })\n terminal.log.success('Tunnel settings migrated from legacy config')\n return\n }\n }\n\n // Interactive setup\n const provider = await terminal.select({\n message: 'Tunnel provider:',\n options: [\n { value: 'cloudflare', label: 'Cloudflare (cloudflared)', hint: 'Free, no account needed' },\n { value: 'ngrok', label: 'ngrok', hint: 'Requires auth token' },\n { value: 'bore', label: 'bore', hint: 'Self-hostable' },\n { value: 'tailscale', label: 'Tailscale Funnel' },\n ],\n })\n\n const portStr = await terminal.text({\n message: 'Local port to expose:',\n defaultValue: '3100',\n validate: (v) => {\n const n = Number(v.trim())\n if (isNaN(n) || n < 1 || n > 65535) return 'Port must be 1-65535'\n return undefined\n },\n })\n\n let authToken = ''\n if (provider === 'ngrok') {\n authToken = await terminal.text({\n message: 'ngrok auth token:',\n validate: (v) => (!v.trim() ? 'Auth token cannot be empty' : undefined),\n })\n authToken = authToken.trim()\n }\n\n await settings.setAll({\n enabled: true,\n provider,\n port: Number(portStr.trim()),\n options: authToken ? { authtoken: authToken } : {},\n maxUserTunnels: 5,\n storeTtlMinutes: 60,\n auth: { enabled: false },\n })\n terminal.log.success('Tunnel settings saved')\n },\n\n async configure(ctx: InstallContext) {\n const { terminal, settings } = ctx\n const current = await settings.getAll()\n\n const choice = await terminal.select({\n message: 'What to configure?',\n options: [\n { value: 'provider', label: `Change provider (current: ${current.provider ?? 'none'})` },\n { value: 'port', label: `Change port (current: ${current.port ?? 3100})` },\n { value: 'toggle', label: `${current.enabled ? 'Disable' : 'Enable'} tunnel` },\n { value: 'done', label: 'Done' },\n ],\n })\n\n if (choice === 'provider') {\n const provider = await terminal.select({\n message: 'Tunnel provider:',\n options: [\n { value: 'cloudflare', label: 'Cloudflare' },\n { value: 'ngrok', label: 'ngrok' },\n { value: 'bore', label: 'bore' },\n { value: 'tailscale', label: 'Tailscale' },\n ],\n })\n await settings.set('provider', provider)\n terminal.log.success('Provider updated')\n } else if (choice === 'port') {\n const val = await terminal.text({\n message: 'New port:',\n defaultValue: String(current.port ?? 3100),\n validate: (v) => {\n const n = Number(v.trim())\n if (isNaN(n) || n < 1 || n > 65535) return 'Port must be 1-65535'\n return undefined\n },\n })\n await settings.set('port', Number(val.trim()))\n terminal.log.success('Port updated')\n } else if (choice === 'toggle') {\n const newState = !current.enabled\n await settings.set('enabled', newState)\n terminal.log.success(`Tunnel ${newState ? 'enabled' : 'disabled'}`)\n }\n },\n\n async uninstall(ctx: InstallContext, opts: { purge: boolean }) {\n if (opts.purge) {\n await ctx.settings.clear()\n ctx.terminal.log.success('Tunnel settings cleared')\n }\n },\n\n inheritableKeys: ['provider', 'maxUserTunnels', 'auth'],\n\n async setup(ctx) {\n const config = ctx.pluginConfig as Record<string, unknown>\n if (!config.enabled) {\n ctx.log.info('Tunnel disabled')\n return\n }\n if (!config.provider) {\n ctx.log.info('Tunnel disabled (no provider configured)')\n return\n }\n\n const { TunnelService } = await import('./tunnel-service.js')\n const instanceRoot = ctx.instanceRoot\n const tunnelSvc = new TunnelService(\n config as unknown as TunnelConfig,\n path.join(instanceRoot, 'tunnels.json'),\n )\n const publicUrl = await tunnelSvc.start()\n service = tunnelSvc\n\n ctx.registerService('tunnel', tunnelSvc)\n\n ctx.registerCommand({\n name: 'tunnel',\n description: 'Manage tunnels: /tunnel <port> [label] | /tunnel stop <port>',\n category: 'plugin',\n handler: async (args) => {\n const parts = args.raw.trim().split(/\\s+/)\n\n // /tunnel stop <port>\n if (parts[0] === 'stop' && parts[1]) {\n const port = parseInt(parts[1], 10)\n if (isNaN(port)) return { type: 'error', message: 'Invalid port number' }\n try {\n await tunnelSvc.stopTunnel(port)\n return { type: 'text', text: `Tunnel on port ${port} stopped.` }\n } catch (err) {\n return { type: 'error', message: (err as Error).message }\n }\n }\n\n // /tunnel <port> [label]\n if (parts[0] && parts[0] !== '') {\n const port = parseInt(parts[0], 10)\n if (isNaN(port)) return { type: 'error', message: 'Invalid port number' }\n const label = parts.slice(1).join(' ') || undefined\n try {\n const entry = await tunnelSvc.addTunnel(port, { label })\n return { type: 'text', text: `Tunnel created: ${entry.publicUrl ?? 'starting...'}` }\n } catch (err) {\n return { type: 'error', message: (err as Error).message }\n }\n }\n\n // /tunnel (no args) — show current tunnel URL + health\n const url = tunnelSvc.getPublicUrl()\n const err = tunnelSvc.getStartError()\n let text = url ? `Tunnel: ${url}` : 'No tunnel active.'\n if (err) text += `\\n⚠️ System tunnel error: ${err}`\n return { type: 'text', text }\n },\n })\n\n ctx.registerCommand({\n name: 'tunnels',\n description: 'List active tunnels',\n category: 'plugin',\n handler: async () => {\n const userTunnels = tunnelSvc.listTunnels()\n const systemUrl = tunnelSvc.getPublicUrl()\n const sysError = tunnelSvc.getStartError()\n const systemDetail = sysError ? `${systemUrl} ⚠️ ${sysError}` : systemUrl\n const items = [\n { label: 'System', detail: systemDetail },\n ...userTunnels.map(t => {\n const statusInfo = t.status === 'failed' && t.retryCount > 0\n ? `${t.status} (retry ${t.retryCount}/${MAX_RETRIES})`\n : t.status\n return {\n label: t.label ?? `Port ${t.port}`,\n detail: `${t.publicUrl ?? statusInfo} (${t.provider})`,\n }\n }),\n ]\n return { type: 'list', title: 'Active Tunnels', items }\n },\n })\n\n ctx.log.info(`Tunnel ready: ${publicUrl}`)\n },\n\n async teardown() {\n if (service) {\n await service.stop()\n }\n },\n }\n}\n\nexport default createTunnelPlugin()\n","import * as http from \"node:http\";\nimport type { EventBus, EventBusEvents } from \"../../core/event-bus.js\";\n\ninterface SSEResponse extends http.ServerResponse {\n sessionFilter?: string;\n}\n\ninterface SessionStats {\n active: number;\n total: number;\n}\n\nexport class SSEManager {\n private sseConnections = new Set<http.ServerResponse>();\n private sseCleanupHandlers = new Map<http.ServerResponse, () => void>();\n private healthInterval?: ReturnType<typeof setInterval>;\n private boundHandlers: Array<{\n event: keyof EventBusEvents;\n handler: (data: unknown) => void;\n }> = [];\n\n constructor(\n private eventBus: EventBus | undefined,\n private getSessionStats: () => SessionStats,\n private startedAt: number,\n ) {}\n\n setup(): void {\n if (!this.eventBus) return;\n\n const events = [\n \"session:created\",\n \"session:updated\",\n \"session:deleted\",\n \"agent:event\",\n \"permission:request\",\n ] as const;\n\n for (const eventName of events) {\n const handler = (data: unknown) => {\n this.broadcast(eventName, data);\n };\n this.eventBus.on(eventName, handler);\n this.boundHandlers.push({ event: eventName, handler });\n }\n\n // Health heartbeat every 30s\n this.healthInterval = setInterval(() => {\n const mem = process.memoryUsage();\n const stats = this.getSessionStats();\n this.broadcast(\"health\", {\n uptime: Date.now() - this.startedAt,\n memory: {\n rss: mem.rss,\n heapUsed: mem.heapUsed,\n heapTotal: mem.heapTotal,\n },\n sessions: stats,\n });\n }, 30_000);\n }\n\n handleRequest(req: http.IncomingMessage, res: http.ServerResponse): void {\n const parsedUrl = new URL(req.url || \"\", \"http://localhost\");\n const sessionFilter = parsedUrl.searchParams.get(\"sessionId\");\n\n res.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n });\n res.flushHeaders();\n\n // Store filter metadata on the response for broadcast\n (res as SSEResponse).sessionFilter = sessionFilter ?? undefined;\n\n this.sseConnections.add(res);\n\n const cleanup = () => {\n this.sseConnections.delete(res);\n this.sseCleanupHandlers.delete(res);\n };\n this.sseCleanupHandlers.set(res, cleanup);\n req.on(\"close\", cleanup);\n }\n\n broadcast(event: string, data: unknown): void {\n const payload = `event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`;\n // Events that carry sessionId and should be filtered\n const sessionEvents = [\n \"agent:event\",\n \"permission:request\",\n \"session:updated\",\n ];\n for (const res of this.sseConnections) {\n const filter = (res as SSEResponse).sessionFilter;\n if (filter && sessionEvents.includes(event)) {\n const eventData = data as { sessionId: string };\n if (eventData.sessionId !== filter) continue;\n }\n try {\n if (res.writable) res.write(payload);\n } catch {\n /* connection closed */\n }\n }\n }\n\n stop(): void {\n if (this.healthInterval) clearInterval(this.healthInterval);\n\n // Remove only our own event bus listeners\n if (this.eventBus) {\n for (const { event, handler } of this.boundHandlers) {\n this.eventBus.off(event, handler);\n }\n }\n this.boundHandlers = [];\n\n // Copy to avoid modifying Map while iterating\n const entries = [...this.sseCleanupHandlers];\n for (const [res, cleanup] of entries) {\n res.end();\n cleanup();\n }\n }\n}\n\nexport type { SessionStats };\n","import * as http from \"node:http\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst MIME_TYPES: Record<string, string> = {\n \".html\": \"text/html; charset=utf-8\",\n \".js\": \"application/javascript; charset=utf-8\",\n \".css\": \"text/css; charset=utf-8\",\n \".json\": \"application/json; charset=utf-8\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".svg\": \"image/svg+xml\",\n \".ico\": \"image/x-icon\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n};\n\nexport class StaticServer {\n private uiDir: string | undefined;\n\n constructor(uiDir?: string) {\n this.uiDir = uiDir;\n\n if (!this.uiDir) {\n const __filename = fileURLToPath(import.meta.url);\n const candidate = path.resolve(path.dirname(__filename), \"../../ui/dist\");\n if (fs.existsSync(path.join(candidate, \"index.html\"))) {\n this.uiDir = candidate;\n }\n // Also check dist-publish layout\n if (!this.uiDir) {\n const publishCandidate = path.resolve(\n path.dirname(__filename),\n \"../ui\",\n );\n if (fs.existsSync(path.join(publishCandidate, \"index.html\"))) {\n this.uiDir = publishCandidate;\n }\n }\n }\n }\n\n isAvailable(): boolean {\n return this.uiDir !== undefined;\n }\n\n serve(req: http.IncomingMessage, res: http.ServerResponse): boolean {\n if (!this.uiDir) return false;\n\n const urlPath = (req.url || \"/\").split(\"?\")[0];\n const safePath = path.normalize(urlPath);\n\n // Try exact file match\n const filePath = path.join(this.uiDir, safePath);\n if (!filePath.startsWith(this.uiDir + path.sep) && filePath !== this.uiDir)\n return false; // path traversal guard\n\n if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) {\n const ext = path.extname(filePath);\n const contentType = MIME_TYPES[ext] ?? \"application/octet-stream\";\n // Vite-hashed assets get long cache, others get no-cache\n const isHashed = /\\.[a-zA-Z0-9]{8,}\\.(js|css)$/.test(filePath);\n const cacheControl = isHashed\n ? \"public, max-age=31536000, immutable\"\n : \"no-cache\";\n res.writeHead(200, {\n \"Content-Type\": contentType,\n \"Cache-Control\": cacheControl,\n });\n fs.createReadStream(filePath).pipe(res);\n return true;\n }\n\n // SPA fallback — serve index.html\n const indexPath = path.join(this.uiDir, \"index.html\");\n if (fs.existsSync(indexPath)) {\n res.writeHead(200, {\n \"Content-Type\": \"text/html; charset=utf-8\",\n \"Cache-Control\": \"no-cache\",\n });\n fs.createReadStream(indexPath).pipe(res);\n return true;\n }\n\n return false;\n }\n}\n","import type * as http from \"node:http\";\n\nexport type Handler = (\n req: http.IncomingMessage,\n res: http.ServerResponse,\n params: Record<string, string>,\n) => Promise<void>;\n\ninterface Route {\n method: string;\n pattern: RegExp;\n keys: string[];\n handler: Handler;\n}\n\nexport class Router {\n private routes: Route[] = [];\n\n get(path: string, handler: Handler): void {\n this.add(\"GET\", path, handler);\n }\n post(path: string, handler: Handler): void {\n this.add(\"POST\", path, handler);\n }\n put(path: string, handler: Handler): void {\n this.add(\"PUT\", path, handler);\n }\n patch(path: string, handler: Handler): void {\n this.add(\"PATCH\", path, handler);\n }\n delete(path: string, handler: Handler): void {\n this.add(\"DELETE\", path, handler);\n }\n\n match(\n method: string,\n url: string,\n ): { handler: Handler; params: Record<string, string> } | null {\n const pathname = url.split(\"?\")[0];\n for (const route of this.routes) {\n if (route.method !== method) continue;\n const m = pathname.match(route.pattern);\n if (!m) continue;\n const params: Record<string, string> = {};\n for (let i = 0; i < route.keys.length; i++) {\n params[route.keys[i]] = m[i + 1];\n }\n return { handler: route.handler, params };\n }\n return null;\n }\n\n private add(method: string, path: string, handler: Handler): void {\n const keys: string[] = [];\n const pattern = path.replace(/:(\\w+)/g, (_, key) => {\n keys.push(key);\n return \"([^/]+)\";\n });\n this.routes.push({\n method,\n pattern: new RegExp(`^${pattern}$`),\n keys,\n handler,\n });\n }\n}\n","import type { Router } from \"../router.js\";\nimport type { RouteDeps } from \"../api-server.js\";\n\nexport function registerHealthRoutes(router: Router, deps: RouteDeps): void {\n router.get(\"/api/health\", async (_req, res) => {\n const activeSessions = deps.core.sessionManager.listSessions();\n const allRecords = deps.core.sessionManager.listRecords();\n const mem = process.memoryUsage();\n const tunnel = deps.core.tunnelService;\n\n deps.sendJson(res, 200, {\n status: \"ok\",\n uptime: Date.now() - deps.startedAt,\n version: deps.getVersion(),\n memory: {\n rss: mem.rss,\n heapUsed: mem.heapUsed,\n heapTotal: mem.heapTotal,\n },\n sessions: {\n active: activeSessions.filter(\n (s) => s.status === \"active\" || s.status === \"initializing\",\n ).length,\n total: allRecords.length,\n },\n adapters: Array.from(deps.core.adapters.keys()),\n tunnel: tunnel\n ? { enabled: true, url: tunnel.getPublicUrl() }\n : { enabled: false },\n });\n });\n\n router.get(\"/api/version\", async (_req, res) => {\n deps.sendJson(res, 200, { version: deps.getVersion() });\n });\n\n router.post(\"/api/restart\", async (_req, res) => {\n if (!deps.core.requestRestart) {\n deps.sendJson(res, 501, { error: \"Restart not available\" });\n return;\n }\n\n deps.sendJson(res, 200, { ok: true, message: \"Restarting...\" });\n setImmediate(() => deps.core.requestRestart!());\n });\n\n router.get(\"/api/adapters\", async (_req, res) => {\n const adapters = Array.from(deps.core.adapters.entries()).map(([name]) => ({\n name,\n type: \"built-in\" as const,\n }));\n deps.sendJson(res, 200, { adapters });\n });\n}\n","import type { Router } from \"../router.js\";\nimport type { RouteDeps } from \"../api-server.js\";\nimport { createChildLogger } from \"../../../core/utils/log.js\";\n\nconst log = createChildLogger({ module: \"api-server\" });\n\nexport function registerSessionRoutes(router: Router, deps: RouteDeps): void {\n router.post(\"/api/sessions/adopt\", async (req, res) => {\n const body = await deps.readBody(req);\n if (body === null) {\n return deps.sendJson(res, 413, { error: \"Request body too large\" });\n }\n if (!body) {\n return deps.sendJson(res, 400, {\n error: \"bad_request\",\n message: \"Empty request body\",\n });\n }\n\n let parsed: { agent?: string; agentSessionId?: string; cwd?: string; channel?: string };\n try {\n parsed = JSON.parse(body);\n } catch {\n return deps.sendJson(res, 400, {\n error: \"bad_request\",\n message: \"Invalid JSON\",\n });\n }\n\n const { agent, agentSessionId, cwd, channel } = parsed;\n\n if (!agent || !agentSessionId) {\n return deps.sendJson(res, 400, {\n error: \"bad_request\",\n message: \"Missing required fields: agent, agentSessionId\",\n });\n }\n\n const result = await deps.core.adoptSession(\n agent,\n agentSessionId,\n cwd ?? process.cwd(),\n channel,\n );\n\n if (result.ok) {\n return deps.sendJson(res, 200, result);\n } else {\n const status =\n result.error === \"session_limit\"\n ? 429\n : result.error === \"agent_not_supported\"\n ? 400\n : 500;\n return deps.sendJson(res, status, result);\n }\n });\n\n router.post(\"/api/sessions\", async (req, res) => {\n const body = await deps.readBody(req);\n let agent: string | undefined;\n let workspace: string | undefined;\n let channel: string | undefined;\n\n if (body) {\n try {\n const parsed = JSON.parse(body);\n agent = parsed.agent;\n workspace = parsed.workspace;\n channel = parsed.channel;\n } catch {\n deps.sendJson(res, 400, { error: \"Invalid JSON body\" });\n return;\n }\n }\n\n // Check max concurrent sessions\n const config = deps.core.configManager.get();\n const activeSessions = deps.core.sessionManager\n .listSessions()\n .filter((s) => s.status === \"active\" || s.status === \"initializing\");\n if (activeSessions.length >= config.security.maxConcurrentSessions) {\n deps.sendJson(res, 429, {\n error: `Max concurrent sessions (${config.security.maxConcurrentSessions}) reached. Cancel a session first.`,\n });\n return;\n }\n\n // Resolve adapter: use explicit channel if provided, otherwise fall back to first registered adapter\n let adapterId: string | null = null;\n let adapter: InstanceType<any> | null = null;\n\n if (channel) {\n if (!deps.core.adapters.has(channel)) {\n const available = Array.from(deps.core.adapters.keys()).join(\", \") || \"none\";\n deps.sendJson(res, 400, {\n error: `Adapter '${channel}' is not connected. Available: ${available}`,\n });\n return;\n }\n adapterId = channel;\n adapter = deps.core.adapters.get(channel) ?? null;\n } else {\n const firstEntry = deps.core.adapters.entries().next().value;\n if (firstEntry) {\n [adapterId, adapter] = firstEntry;\n }\n }\n\n const channelId = adapterId ?? \"api\";\n\n const resolvedAgent = agent || config.defaultAgent;\n const agentDef = deps.core.agentCatalog.resolve(resolvedAgent);\n const resolvedWorkspace = deps.core.configManager.resolveWorkspace(\n workspace || agentDef?.workingDirectory,\n );\n\n const session = await deps.core.createSession({\n channelId,\n agentName: resolvedAgent,\n workingDirectory: resolvedWorkspace,\n createThread: !!adapter,\n initialName: `🔄 ${resolvedAgent} — New Session`,\n });\n\n // If no adapter wired events (headless), auto-approve permissions\n if (!adapter) {\n session.agentInstance.onPermissionRequest = async (request) => {\n const allowOption = request.options.find((o) => o.isAllow);\n log.debug(\n {\n sessionId: session.id,\n permissionId: request.id,\n option: allowOption?.id,\n },\n \"Auto-approving permission for API session\",\n );\n return allowOption?.id ?? request.options[0]?.id ?? \"\";\n };\n }\n\n // Warmup in background so session moves from 'initializing' to 'active'\n session\n .warmup()\n .catch((err) =>\n log.warn({ err, sessionId: session.id }, \"API session warmup failed\"),\n );\n\n deps.sendJson(res, 200, {\n sessionId: session.id,\n agent: session.agentName,\n status: session.status,\n workspace: session.workingDirectory,\n });\n });\n\n router.post(\"/api/sessions/:sessionId/prompt\", async (req, res, params) => {\n const sessionId = decodeURIComponent(params.sessionId);\n const session = deps.core.sessionManager.getSession(sessionId);\n if (!session) {\n deps.sendJson(res, 404, { error: `Session \"${sessionId}\" not found` });\n return;\n }\n\n if (\n session.status === \"cancelled\" ||\n session.status === \"finished\" ||\n session.status === \"error\"\n ) {\n deps.sendJson(res, 400, { error: `Session is ${session.status}` });\n return;\n }\n\n const body = await deps.readBody(req);\n let prompt: string | undefined;\n if (body) {\n try {\n const parsed = JSON.parse(body);\n prompt = parsed.prompt;\n } catch {\n deps.sendJson(res, 400, { error: \"Invalid JSON body\" });\n return;\n }\n }\n\n if (!prompt) {\n deps.sendJson(res, 400, { error: \"Missing prompt\" });\n return;\n }\n\n session.enqueuePrompt(prompt).catch(() => {});\n deps.sendJson(res, 200, {\n ok: true,\n sessionId,\n queueDepth: session.queueDepth,\n });\n });\n\n router.post(\n \"/api/sessions/:sessionId/permission\",\n async (req, res, params) => {\n const sessionId = decodeURIComponent(params.sessionId);\n const session = deps.core.sessionManager.getSession(sessionId);\n if (!session) {\n deps.sendJson(res, 404, { error: `Session \"${sessionId}\" not found` });\n return;\n }\n\n const body = await deps.readBody(req);\n let permissionId: string | undefined;\n let optionId: string | undefined;\n if (body) {\n try {\n const parsed = JSON.parse(body);\n permissionId = parsed.permissionId;\n optionId = parsed.optionId;\n } catch {\n deps.sendJson(res, 400, { error: \"Invalid JSON body\" });\n return;\n }\n }\n\n if (!permissionId || !optionId) {\n deps.sendJson(res, 400, {\n error: \"Missing permissionId or optionId\",\n });\n return;\n }\n\n if (\n !session.permissionGate.isPending ||\n session.permissionGate.requestId !== permissionId\n ) {\n deps.sendJson(res, 400, {\n error: \"No matching pending permission request\",\n });\n return;\n }\n\n session.permissionGate.resolve(optionId);\n deps.sendJson(res, 200, { ok: true });\n },\n );\n\n router.patch(\n \"/api/sessions/:sessionId/dangerous\",\n async (req, res, params) => {\n const sessionId = decodeURIComponent(params.sessionId);\n const session = deps.core.sessionManager.getSession(sessionId);\n if (!session) {\n deps.sendJson(res, 404, { error: `Session \"${sessionId}\" not found` });\n return;\n }\n\n const body = await deps.readBody(req);\n let enabled: boolean | undefined;\n if (body) {\n try {\n const parsed = JSON.parse(body);\n enabled = parsed.enabled;\n } catch {\n deps.sendJson(res, 400, { error: \"Invalid JSON body\" });\n return;\n }\n }\n\n if (typeof enabled !== \"boolean\") {\n deps.sendJson(res, 400, { error: \"Missing enabled boolean\" });\n return;\n }\n\n session.dangerousMode = enabled;\n await deps.core.sessionManager.patchRecord(sessionId, {\n dangerousMode: enabled,\n });\n deps.sendJson(res, 200, { ok: true, dangerousMode: enabled });\n },\n );\n\n router.get(\"/api/sessions/:sessionId\", async (_req, res, params) => {\n const sessionId = decodeURIComponent(params.sessionId);\n const session = deps.core.sessionManager.getSession(sessionId);\n if (!session) {\n deps.sendJson(res, 404, { error: `Session \"${sessionId}\" not found` });\n return;\n }\n\n deps.sendJson(res, 200, {\n session: {\n id: session.id,\n agent: session.agentName,\n status: session.status,\n name: session.name ?? null,\n workspace: session.workingDirectory,\n createdAt: session.createdAt.toISOString(),\n dangerousMode: session.dangerousMode,\n queueDepth: session.queueDepth,\n promptRunning: session.promptRunning,\n threadId: session.threadId,\n channelId: session.channelId,\n agentSessionId: session.agentSessionId,\n },\n });\n });\n\n router.post(\"/api/sessions/:sessionId/archive\", async (_req, res, params) => {\n const sessionId = decodeURIComponent(params.sessionId);\n const result = await deps.core.archiveSession(sessionId);\n if (result.ok) {\n deps.sendJson(res, 200, result);\n } else {\n deps.sendJson(res, 400, result);\n }\n });\n\n router.delete(\"/api/sessions/:sessionId\", async (_req, res, params) => {\n const sessionId = decodeURIComponent(params.sessionId);\n const session = deps.core.sessionManager.getSession(sessionId);\n if (!session) {\n deps.sendJson(res, 404, { error: `Session \"${sessionId}\" not found` });\n return;\n }\n await deps.core.sessionManager.cancelSession(sessionId);\n deps.sendJson(res, 200, { ok: true });\n });\n\n router.get(\"/api/sessions\", async (_req, res) => {\n const sessions = deps.core.sessionManager.listSessions();\n deps.sendJson(res, 200, {\n sessions: sessions.map((s) => ({\n id: s.id,\n agent: s.agentName,\n status: s.status,\n name: s.name ?? null,\n workspace: s.workingDirectory,\n createdAt: s.createdAt.toISOString(),\n dangerousMode: s.dangerousMode,\n queueDepth: s.queueDepth,\n promptRunning: s.promptRunning,\n lastActiveAt:\n deps.core.sessionManager.getSessionRecord(s.id)?.lastActiveAt ??\n null,\n })),\n });\n });\n}\n","import path from 'node:path'\nimport fs from 'node:fs'\nimport os from 'node:os'\n\nexport interface InstanceContext {\n id: string\n root: string\n isGlobal: boolean\n paths: {\n config: string\n sessions: string\n agents: string\n registryCache: string\n plugins: string\n pluginsData: string\n pluginRegistry: string\n logs: string\n pid: string\n running: string\n apiPort: string\n apiSecret: string\n bin: string\n cache: string\n tunnels: string\n agentsDir: string\n }\n}\n\nexport interface CreateInstanceContextOpts {\n id: string\n root: string\n isGlobal: boolean\n}\n\nexport function createInstanceContext(opts: CreateInstanceContextOpts): InstanceContext {\n const { id, root, isGlobal } = opts\n return {\n id, root, isGlobal,\n paths: {\n config: path.join(root, 'config.json'),\n sessions: path.join(root, 'sessions.json'),\n agents: path.join(root, 'agents.json'),\n registryCache: path.join(root, 'registry-cache.json'),\n plugins: path.join(root, 'plugins'),\n pluginsData: path.join(root, 'plugins', 'data'),\n pluginRegistry: path.join(root, 'plugins.json'),\n logs: path.join(root, 'logs'),\n pid: path.join(root, 'openacp.pid'),\n running: path.join(root, 'running'),\n apiPort: path.join(root, 'api.port'),\n apiSecret: path.join(root, 'api-secret'),\n bin: path.join(root, 'bin'),\n cache: path.join(root, 'cache'),\n tunnels: path.join(root, 'tunnels.json'),\n agentsDir: path.join(root, 'agents'),\n },\n }\n}\n\nexport function generateSlug(name: string): string {\n const slug = name.toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '')\n return slug || 'openacp'\n}\n\nfunction expandHome(p: string): string {\n if (p.startsWith('~')) return path.join(os.homedir(), p.slice(1))\n return p\n}\n\nexport interface ResolveOpts {\n dir?: string\n local?: boolean\n global?: boolean\n cwd?: string\n}\n\nexport function resolveInstanceRoot(opts: ResolveOpts): string | null {\n const cwd = opts.cwd ?? process.cwd()\n if (opts.dir) return path.join(expandHome(opts.dir), '.openacp')\n if (opts.local) return path.join(cwd, '.openacp')\n if (opts.global) return path.join(os.homedir(), '.openacp')\n const localRoot = path.join(cwd, '.openacp')\n if (fs.existsSync(localRoot)) return localRoot\n return null\n}\n\nexport function getGlobalRoot(): string {\n return path.join(os.homedir(), '.openacp')\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { Config } from \"./config.js\";\nimport { getGlobalRoot } from \"../instance-context.js\";\n\nexport interface ConfigFieldDef {\n path: string;\n displayName: string;\n group: string;\n type: \"toggle\" | \"select\" | \"number\" | \"string\";\n options?: string[] | ((config: Config) => string[]);\n scope: \"safe\" | \"sensitive\";\n hotReload: boolean;\n}\n\nexport const CONFIG_REGISTRY: ConfigFieldDef[] = [\n {\n path: \"defaultAgent\",\n displayName: \"Default Agent\",\n group: \"agent\",\n type: \"select\",\n options: (config) => {\n try {\n const agentsPath = path.join(getGlobalRoot(), \"agents.json\");\n if (fs.existsSync(agentsPath)) {\n const data = JSON.parse(fs.readFileSync(agentsPath, \"utf-8\"));\n return Object.keys(data.installed ?? {});\n }\n } catch {\n /* fallback */\n }\n return Object.keys(config.agents ?? {});\n },\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"channels.telegram.displayVerbosity\",\n displayName: \"Telegram Verbosity\",\n group: \"display\",\n type: \"select\",\n options: [\"low\", \"medium\", \"high\"],\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"channels.discord.displayVerbosity\",\n displayName: \"Discord Verbosity\",\n group: \"display\",\n type: \"select\",\n options: [\"low\", \"medium\", \"high\"],\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"logging.level\",\n displayName: \"Log Level\",\n group: \"logging\",\n type: \"select\",\n options: [\"silent\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\"],\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"tunnel.enabled\",\n displayName: \"Tunnel\",\n group: \"tunnel\",\n type: \"toggle\",\n scope: \"safe\",\n hotReload: false,\n },\n {\n path: \"security.maxConcurrentSessions\",\n displayName: \"Max Concurrent Sessions\",\n group: \"security\",\n type: \"number\",\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"security.sessionTimeoutMinutes\",\n displayName: \"Session Timeout (min)\",\n group: \"security\",\n type: \"number\",\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"workspace.baseDir\",\n displayName: \"Workspace Directory\",\n group: \"workspace\",\n type: \"string\",\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"sessionStore.ttlDays\",\n displayName: \"Session Store TTL (days)\",\n group: \"storage\",\n type: \"number\",\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"speech.stt.provider\",\n displayName: \"Speech to Text\",\n group: \"speech\",\n type: \"select\",\n options: [\"groq\"],\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"speech.stt.apiKey\",\n displayName: \"STT API Key\",\n group: \"speech\",\n type: \"string\",\n scope: \"sensitive\",\n hotReload: true,\n },\n {\n path: \"agentSwitch.labelHistory\",\n displayName: \"Label Agent in History\",\n group: \"agent\",\n type: \"toggle\",\n scope: \"safe\",\n hotReload: true,\n },\n];\n\nexport function getFieldDef(path: string): ConfigFieldDef | undefined {\n return CONFIG_REGISTRY.find((f) => f.path === path);\n}\n\nexport function getSafeFields(): ConfigFieldDef[] {\n return CONFIG_REGISTRY.filter((f) => f.scope === \"safe\");\n}\n\nexport function isHotReloadable(path: string): boolean {\n const def = getFieldDef(path);\n return def?.hotReload ?? false;\n}\n\nexport function resolveOptions(\n def: ConfigFieldDef,\n config: Config,\n): string[] | undefined {\n if (!def.options) return undefined;\n return typeof def.options === \"function\" ? def.options(config) : def.options;\n}\n\nexport function getConfigValue(config: Config, path: string): unknown {\n const parts = path.split(\".\");\n let current: unknown = config;\n for (const part of parts) {\n if (current && typeof current === \"object\" && part in current) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n return current;\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { createChildLogger } from \"../utils/log.js\";\nimport { getGlobalRoot } from \"../instance-context.js\";\nconst log = createChildLogger({ module: \"config-migrations\" });\n\ntype RawConfig = Record<string, unknown>;\n\nexport interface Migration {\n name: string;\n apply: (raw: RawConfig) => boolean; // returns true if config was modified\n}\n\nexport const migrations: Migration[] = [\n {\n name: \"add-tunnel-section\",\n apply(raw) {\n if (raw.tunnel) return false;\n raw.tunnel = {\n enabled: true,\n port: 3100,\n provider: \"cloudflare\",\n options: {},\n storeTtlMinutes: 60,\n auth: { enabled: false },\n };\n log.info(\"Added tunnel section to config (enabled by default with cloudflare)\");\n return true;\n },\n },\n {\n name: \"fix-agent-commands\",\n apply(raw) {\n const COMMAND_MIGRATIONS: Record<string, string[]> = {\n \"claude-agent-acp\": [\"claude\", \"claude-code\"],\n };\n\n const agents = raw.agents;\n if (!agents || typeof agents !== \"object\") return false;\n\n let changed = false;\n for (const [agentName, agentDef] of Object.entries(agents as Record<string, unknown>)) {\n if (!agentDef || typeof agentDef !== \"object\" || !(\"command\" in agentDef)) continue;\n const def = agentDef as Record<string, unknown>;\n if (typeof def.command !== \"string\") continue;\n for (const [correctCmd, legacyCmds] of Object.entries(COMMAND_MIGRATIONS)) {\n if (legacyCmds.includes(def.command as string)) {\n log.warn(\n { agent: agentName, oldCommand: def.command, newCommand: correctCmd },\n `Auto-migrating agent command: \"${def.command}\" → \"${correctCmd}\"`,\n );\n def.command = correctCmd;\n changed = true;\n }\n }\n }\n return changed;\n },\n },\n {\n name: \"migrate-agents-to-store\",\n apply(raw) {\n const agentsJsonPath = path.join(getGlobalRoot(), \"agents.json\");\n if (fs.existsSync(agentsJsonPath)) return false;\n\n const agents = raw.agents as Record<string, unknown> | undefined;\n if (!agents || Object.keys(agents).length === 0) return false;\n\n const COMMAND_TO_REGISTRY: Record<string, string> = {\n \"claude-agent-acp\": \"claude-acp\",\n \"codex\": \"codex-acp\",\n };\n\n const installed: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(agents)) {\n const cfg = val as Record<string, unknown>;\n const command = typeof cfg.command === \"string\" ? cfg.command : \"\";\n const registryId = COMMAND_TO_REGISTRY[command] ?? null;\n installed[key] = {\n registryId,\n name: key.charAt(0).toUpperCase() + key.slice(1),\n version: \"unknown\",\n distribution: \"custom\",\n command: cfg.command,\n args: cfg.args ?? [],\n env: cfg.env ?? {},\n workingDirectory: cfg.workingDirectory ?? undefined,\n installedAt: new Date().toISOString(),\n binaryPath: null,\n };\n }\n\n fs.mkdirSync(path.dirname(agentsJsonPath), { recursive: true });\n fs.writeFileSync(agentsJsonPath, JSON.stringify({ version: 1, installed }, null, 2));\n\n raw.agents = {};\n return true;\n },\n },\n {\n name: \"add-instance-name\",\n apply(raw) {\n if (raw.instanceName) return false;\n raw.instanceName = \"Main\";\n log.info(\"Added instanceName to config\");\n return true;\n },\n },\n {\n name: \"migrate-display-verbosity-to-output-mode\",\n apply(raw) {\n const channels = raw.channels as Record<string, unknown> | undefined;\n if (!channels) return false;\n let changed = false;\n for (const [, channelCfg] of Object.entries(channels)) {\n if (!channelCfg || typeof channelCfg !== \"object\") continue;\n const cfg = channelCfg as Record<string, unknown>;\n if (cfg.displayVerbosity && !cfg.outputMode) {\n cfg.outputMode = cfg.displayVerbosity;\n changed = true;\n }\n }\n return changed;\n },\n },\n];\n\n/**\n * Apply all migrations to raw config (mutates in place).\n * Returns whether any changes were made.\n */\nexport function applyMigrations(\n raw: RawConfig,\n migrationList: Migration[] = migrations,\n): { changed: boolean } {\n let changed = false;\n for (const migration of migrationList) {\n if (migration.apply(raw)) {\n changed = true;\n }\n }\n return { changed };\n}\n","import { z } from \"zod\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport { EventEmitter } from \"node:events\";\nimport { applyMigrations } from \"./config-migrations.js\";\nimport { createChildLogger } from \"../utils/log.js\";\nconst log = createChildLogger({ module: \"config\" });\n\nconst BaseChannelSchema = z\n .object({\n enabled: z.boolean().default(false),\n adapter: z.string().optional(), // package name for plugin adapters\n displayVerbosity: z\n .enum([\"low\", \"medium\", \"high\"])\n .optional(),\n outputMode: z.enum([\"low\", \"medium\", \"high\"]).optional(),\n })\n .passthrough();\n\nconst AgentSchema = z.object({\n command: z.string(),\n args: z.array(z.string()).default([]),\n workingDirectory: z.string().optional(),\n env: z.record(z.string(), z.string()).default({}),\n});\n\nconst LoggingSchema = z\n .object({\n level: z\n .enum([\"silent\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\"])\n .default(\"info\"),\n logDir: z.string().default(\"~/.openacp/logs\"),\n maxFileSize: z.union([z.string(), z.number()]).default(\"10m\"),\n maxFiles: z.number().default(7),\n sessionLogRetentionDays: z.number().default(30),\n })\n .default({});\n\nexport type LoggingConfig = z.infer<typeof LoggingSchema>;\n\nconst TunnelAuthSchema = z\n .object({\n enabled: z.boolean().default(false),\n token: z.string().optional(),\n })\n .default({});\n\nconst TunnelSchema = z\n .object({\n enabled: z.boolean().default(false),\n port: z.number().default(3100),\n provider: z\n .enum([\"cloudflare\", \"ngrok\", \"bore\", \"tailscale\"])\n .default(\"cloudflare\"),\n options: z.record(z.string(), z.unknown()).default({}),\n maxUserTunnels: z.number().default(5),\n storeTtlMinutes: z.number().default(60),\n auth: TunnelAuthSchema,\n })\n .default({});\n\nexport type TunnelConfig = z.infer<typeof TunnelSchema>;\n\n\nconst UsageSchema = z\n .object({\n enabled: z.boolean().default(true),\n monthlyBudget: z.number().optional(),\n warningThreshold: z.number().default(0.8),\n currency: z.string().default(\"USD\"),\n retentionDays: z.number().default(90),\n })\n .default({});\n\nexport type UsageConfig = z.infer<typeof UsageSchema>;\n\nconst SpeechProviderSchema = z\n .object({\n apiKey: z.string().min(1).optional(),\n model: z.string().optional(),\n })\n .passthrough();\n\nconst SpeechSchema = z\n .object({\n stt: z\n .object({\n provider: z.string().nullable().default(null),\n providers: z.record(SpeechProviderSchema).default({}),\n })\n .default({}),\n tts: z\n .object({\n provider: z.string().nullable().default(null),\n providers: z.record(SpeechProviderSchema).default({}),\n })\n .default({}),\n })\n .optional()\n .default({});\n\nexport const ConfigSchema = z.object({\n instanceName: z.string().optional(),\n channels: z\n .object({})\n .catchall(BaseChannelSchema),\n agents: z.record(z.string(), AgentSchema).optional().default({}),\n defaultAgent: z.string(),\n workspace: z\n .object({\n baseDir: z.string().default(\"~/openacp-workspace\"),\n })\n .default({}),\n security: z\n .object({\n allowedUserIds: z.array(z.string()).default([]),\n maxConcurrentSessions: z.number().default(20),\n sessionTimeoutMinutes: z.number().default(60),\n })\n .default({}),\n logging: LoggingSchema,\n runMode: z.enum([\"foreground\", \"daemon\"]).default(\"foreground\"),\n autoStart: z.boolean().default(false),\n api: z\n .object({\n port: z.number().default(21420),\n host: z.string().default(\"127.0.0.1\"),\n })\n .default({}),\n sessionStore: z\n .object({\n ttlDays: z.number().default(30),\n })\n .default({}),\n tunnel: TunnelSchema,\n usage: UsageSchema,\n integrations: z\n .record(\n z.string(),\n z.object({\n installed: z.boolean(),\n installedAt: z.string().optional(),\n }),\n )\n .default({}),\n speech: SpeechSchema,\n outputMode: z.enum([\"low\", \"medium\", \"high\"]).default(\"medium\").optional(),\n agentSwitch: z.object({\n labelHistory: z.boolean().default(true),\n }).default({}),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n\nexport function expandHome(p: string): string {\n if (p.startsWith(\"~\")) {\n return path.join(os.homedir(), p.slice(1));\n }\n return p;\n}\n\nconst DEFAULT_CONFIG = {\n channels: {\n telegram: {\n enabled: false,\n botToken: \"YOUR_BOT_TOKEN_HERE\",\n chatId: 0,\n notificationTopicId: null,\n assistantTopicId: null,\n },\n discord: {\n enabled: false,\n botToken: \"YOUR_DISCORD_BOT_TOKEN_HERE\",\n guildId: \"\",\n forumChannelId: null,\n notificationChannelId: null,\n assistantThreadId: null,\n },\n },\n agents: {\n claude: { command: \"claude-agent-acp\", args: [], env: {} },\n codex: { command: \"codex\", args: [\"--acp\"], env: {} },\n },\n defaultAgent: \"claude\",\n workspace: { baseDir: \"~/openacp-workspace\" },\n security: {\n allowedUserIds: [],\n maxConcurrentSessions: 20,\n sessionTimeoutMinutes: 60,\n },\n sessionStore: { ttlDays: 30 },\n tunnel: {\n enabled: true,\n port: 3100,\n provider: \"cloudflare\",\n options: {},\n storeTtlMinutes: 60,\n auth: { enabled: false },\n },\n usage: {},\n};\n\nexport class ConfigManager extends EventEmitter {\n private config!: Config;\n private configPath: string;\n\n constructor(configPath?: string) {\n super();\n this.configPath =\n process.env.OPENACP_CONFIG_PATH || configPath || expandHome(\"~/.openacp/config.json\");\n }\n\n async load(): Promise<void> {\n // 1. Ensure directory exists\n const dir = path.dirname(this.configPath);\n fs.mkdirSync(dir, { recursive: true });\n\n // 2. If config file doesn't exist, create default\n if (!fs.existsSync(this.configPath)) {\n fs.writeFileSync(\n this.configPath,\n JSON.stringify(DEFAULT_CONFIG, null, 2),\n );\n log.info({ configPath: this.configPath }, \"Config created\");\n log.info(\n \"Please edit it with your channel credentials (Telegram bot token, Discord bot token, etc.), then restart.\",\n );\n process.exit(1);\n }\n\n // 3. Read and parse\n const raw = JSON.parse(fs.readFileSync(this.configPath, \"utf-8\"));\n\n // 3.5. Auto-migrate config\n const { changed: configUpdated } = applyMigrations(raw);\n if (configUpdated) {\n fs.writeFileSync(this.configPath, JSON.stringify(raw, null, 2));\n }\n\n // 4. Apply env var overrides\n this.applyEnvOverrides(raw);\n\n // 5. Validate with Zod\n const result = ConfigSchema.safeParse(raw);\n if (!result.success) {\n log.error(\"Config validation failed\");\n for (const issue of result.error.issues) {\n log.error(\n { path: issue.path.join(\".\"), message: issue.message },\n \"Validation error\",\n );\n }\n process.exit(1);\n }\n this.config = result.data;\n }\n\n get(): Config {\n return structuredClone(this.config);\n }\n\n async save(\n updates: Record<string, unknown>,\n changePath?: string,\n ): Promise<void> {\n const oldConfig = this.config ? structuredClone(this.config) : undefined;\n // Read current file, merge updates\n const raw = JSON.parse(fs.readFileSync(this.configPath, \"utf-8\"));\n this.deepMerge(raw, updates);\n // Validate BEFORE writing to disk\n const result = ConfigSchema.safeParse(raw);\n if (!result.success) {\n log.error({ errors: result.error.issues }, \"Config validation failed, not saving\");\n return;\n }\n fs.writeFileSync(this.configPath, JSON.stringify(raw, null, 2));\n this.config = result.data;\n // Emit change event if path provided\n if (changePath) {\n const { getConfigValue } = await import(\"./config-registry.js\");\n const value = getConfigValue(this.config, changePath);\n const oldValue = oldConfig\n ? getConfigValue(oldConfig, changePath)\n : undefined;\n this.emit(\"config:changed\", { path: changePath, value, oldValue });\n }\n }\n\n resolveWorkspace(input?: string): string {\n if (!input) {\n const resolved = expandHome(this.config.workspace.baseDir);\n fs.mkdirSync(resolved, { recursive: true });\n return resolved;\n }\n if (input.startsWith(\"/\") || input.startsWith(\"~\")) {\n const resolved = expandHome(input);\n fs.mkdirSync(resolved, { recursive: true });\n return resolved;\n }\n // Named workspace → lowercase, under baseDir\n const name = input.toLowerCase();\n const resolved = path.join(expandHome(this.config.workspace.baseDir), name);\n fs.mkdirSync(resolved, { recursive: true });\n return resolved;\n }\n\n async exists(): Promise<boolean> {\n return fs.existsSync(this.configPath);\n }\n\n getConfigPath(): string {\n return this.configPath;\n }\n\n async writeNew(config: Config): Promise<void> {\n const dir = path.dirname(this.configPath);\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(this.configPath, JSON.stringify(config, null, 2));\n }\n\n private applyEnvOverrides(raw: Record<string, unknown>): void {\n const overrides: [string, string[]][] = [\n [\"OPENACP_TELEGRAM_BOT_TOKEN\", [\"channels\", \"telegram\", \"botToken\"]],\n [\"OPENACP_TELEGRAM_CHAT_ID\", [\"channels\", \"telegram\", \"chatId\"]],\n [\"OPENACP_DISCORD_BOT_TOKEN\", [\"channels\", \"discord\", \"botToken\"]],\n [\"OPENACP_DISCORD_GUILD_ID\", [\"channels\", \"discord\", \"guildId\"]],\n [\"OPENACP_SLACK_BOT_TOKEN\", [\"channels\", \"slack\", \"botToken\"]],\n [\"OPENACP_SLACK_APP_TOKEN\", [\"channels\", \"slack\", \"appToken\"]],\n [\"OPENACP_SLACK_SIGNING_SECRET\", [\"channels\", \"slack\", \"signingSecret\"]],\n [\"OPENACP_DEFAULT_AGENT\", [\"defaultAgent\"]],\n [\"OPENACP_RUN_MODE\", [\"runMode\"]],\n [\"OPENACP_API_PORT\", [\"api\", \"port\"]],\n ];\n for (const [envVar, configPath] of overrides) {\n const value = process.env[envVar];\n if (value !== undefined) {\n let target: Record<string, unknown> = raw;\n for (let i = 0; i < configPath.length - 1; i++) {\n if (!target[configPath[i]]) target[configPath[i]] = {};\n target = target[configPath[i]] as Record<string, unknown>;\n }\n const key = configPath[configPath.length - 1];\n // Convert numeric fields to number\n target[key] =\n key === \"chatId\" || key === \"port\" ? Number(value) : value;\n }\n }\n\n // Logging env var overrides\n if (process.env.OPENACP_LOG_LEVEL) {\n raw.logging = raw.logging || {};\n (raw.logging as Record<string, unknown>).level =\n process.env.OPENACP_LOG_LEVEL;\n }\n if (process.env.OPENACP_LOG_DIR) {\n raw.logging = raw.logging || {};\n (raw.logging as Record<string, unknown>).logDir =\n process.env.OPENACP_LOG_DIR;\n }\n if (process.env.OPENACP_DEBUG && !process.env.OPENACP_LOG_LEVEL) {\n raw.logging = raw.logging || {};\n (raw.logging as Record<string, unknown>).level = \"debug\";\n }\n\n // Tunnel env var overrides\n if (process.env.OPENACP_TUNNEL_ENABLED) {\n raw.tunnel = raw.tunnel || {};\n (raw.tunnel as Record<string, unknown>).enabled =\n process.env.OPENACP_TUNNEL_ENABLED === \"true\";\n }\n if (process.env.OPENACP_TUNNEL_PORT) {\n raw.tunnel = raw.tunnel || {};\n (raw.tunnel as Record<string, unknown>).port = Number(\n process.env.OPENACP_TUNNEL_PORT,\n );\n }\n if (process.env.OPENACP_TUNNEL_PROVIDER) {\n raw.tunnel = raw.tunnel || {};\n (raw.tunnel as Record<string, unknown>).provider =\n process.env.OPENACP_TUNNEL_PROVIDER;\n }\n\n // Speech env var overrides\n if (process.env.OPENACP_SPEECH_STT_PROVIDER) {\n raw.speech = raw.speech || {};\n const speech = raw.speech as Record<string, unknown>;\n speech.stt = speech.stt || {};\n (speech.stt as Record<string, unknown>).provider =\n process.env.OPENACP_SPEECH_STT_PROVIDER;\n }\n if (process.env.OPENACP_SPEECH_GROQ_API_KEY) {\n raw.speech = raw.speech || {};\n const speech = raw.speech as Record<string, unknown>;\n speech.stt = speech.stt || {};\n const stt = speech.stt as Record<string, unknown>;\n stt.providers = stt.providers || {};\n const providers = stt.providers as Record<string, unknown>;\n providers.groq = providers.groq || {};\n (providers.groq as Record<string, unknown>).apiKey =\n process.env.OPENACP_SPEECH_GROQ_API_KEY;\n }\n }\n\n private deepMerge(\n target: Record<string, unknown>,\n source: Record<string, unknown>,\n ): void {\n for (const key of Object.keys(source)) {\n const val = source[key];\n if (val && typeof val === \"object\" && !Array.isArray(val)) {\n if (!target[key]) target[key] = {};\n this.deepMerge(\n target[key] as Record<string, unknown>,\n val as Record<string, unknown>,\n );\n } else {\n target[key] = val;\n }\n }\n }\n}\n","import type { Router } from \"../router.js\";\nimport type { RouteDeps } from \"../api-server.js\";\n\nconst SENSITIVE_KEYS = [\n \"botToken\",\n \"token\",\n \"apiKey\",\n \"secret\",\n \"password\",\n \"webhookSecret\",\n];\n\nfunction redactConfig(config: unknown): unknown {\n const redacted = structuredClone(config);\n redactDeep(redacted as Record<string, unknown>);\n return redacted;\n}\n\nfunction redactDeep(obj: Record<string, unknown>): void {\n for (const [key, value] of Object.entries(obj)) {\n if (SENSITIVE_KEYS.includes(key) && typeof value === \"string\") {\n obj[key] = \"***\";\n } else if (Array.isArray(value)) {\n for (const item of value) {\n if (item && typeof item === \"object\")\n redactDeep(item as Record<string, unknown>);\n }\n } else if (value && typeof value === \"object\") {\n redactDeep(value as Record<string, unknown>);\n }\n }\n}\n\nexport function registerConfigRoutes(router: Router, deps: RouteDeps): void {\n router.get(\"/api/config/editable\", async (_req, res) => {\n const { getSafeFields, resolveOptions, getConfigValue } =\n await import(\"../../../core/config/config-registry.js\");\n const config = deps.core.configManager.get();\n const safeFields = getSafeFields();\n\n const fields = safeFields.map((def) => ({\n path: def.path,\n displayName: def.displayName,\n group: def.group,\n type: def.type,\n options: resolveOptions(def, config),\n value: getConfigValue(config, def.path),\n hotReload: def.hotReload,\n }));\n\n deps.sendJson(res, 200, { fields });\n });\n\n router.get(\"/api/config\", async (_req, res) => {\n const config = deps.core.configManager.get();\n deps.sendJson(res, 200, { config: redactConfig(config) });\n });\n\n router.patch(\"/api/config\", async (req, res) => {\n const body = await deps.readBody(req);\n let configPath: string | undefined;\n let value: unknown;\n\n if (body) {\n try {\n const parsed = JSON.parse(body);\n configPath = parsed.path;\n value = parsed.value;\n } catch {\n deps.sendJson(res, 400, { error: \"Invalid JSON body\" });\n return;\n }\n }\n\n if (!configPath) {\n deps.sendJson(res, 400, { error: \"Missing path\" });\n return;\n }\n\n // Block prototype pollution\n const BLOCKED_KEYS = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n const parts = configPath.split(\".\");\n if (parts.some((p) => BLOCKED_KEYS.has(p))) {\n deps.sendJson(res, 400, { error: \"Invalid config path\" });\n return;\n }\n\n // Enforce safe-fields scope — only fields marked 'safe' can be modified via API\n const { getFieldDef } = await import(\"../../../core/config/config-registry.js\");\n const fieldDef = getFieldDef(configPath);\n if (!fieldDef || fieldDef.scope !== \"safe\") {\n deps.sendJson(res, 403, {\n error: \"This config field cannot be modified via the API\",\n });\n return;\n }\n\n // Pre-validate by cloning config and applying the change\n const currentConfig = deps.core.configManager.get();\n const cloned = structuredClone(currentConfig) as Record<string, unknown>;\n let target: Record<string, unknown> = cloned;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n if (\n target[part] &&\n typeof target[part] === \"object\" &&\n !Array.isArray(target[part])\n ) {\n target = target[part] as Record<string, unknown>;\n } else if (target[part] === undefined || target[part] === null) {\n // Create intermediate objects for new paths (e.g. speech.stt.providers.groq.apiKey)\n target[part] = {};\n target = target[part] as Record<string, unknown>;\n } else {\n deps.sendJson(res, 400, { error: \"Invalid config path\" });\n return;\n }\n }\n\n const lastKey = parts[parts.length - 1];\n target[lastKey] = value;\n\n // Validate with Zod\n const { ConfigSchema } = await import(\"../../../core/config/config.js\");\n const result = ConfigSchema.safeParse(cloned);\n if (!result.success) {\n deps.sendJson(res, 400, {\n error: \"Validation failed\",\n details: result.error.issues.map((i) => ({\n path: i.path.join(\".\"),\n message: i.message,\n })),\n });\n return;\n }\n\n // Convert dot-path to nested object for save\n const updates: Record<string, unknown> = {};\n let updateTarget = updates;\n for (let i = 0; i < parts.length - 1; i++) {\n updateTarget[parts[i]] = {};\n updateTarget = updateTarget[parts[i]] as Record<string, unknown>;\n }\n updateTarget[lastKey] = value;\n\n await deps.core.configManager.save(updates, configPath);\n\n const { isHotReloadable } = await import(\"../../../core/config/config-registry.js\");\n const needsRestart = !isHotReloadable(configPath!);\n\n deps.sendJson(res, 200, {\n ok: true,\n needsRestart,\n config: redactConfig(deps.core.configManager.get()),\n });\n });\n}\n","import type { Router } from \"../router.js\";\nimport type { RouteDeps } from \"../api-server.js\";\n\nexport function registerTopicRoutes(router: Router, deps: RouteDeps): void {\n router.get(\"/api/topics\", async (req, res) => {\n if (!deps.topicManager) {\n deps.sendJson(res, 501, { error: \"Topic management not available\" });\n return;\n }\n const url = req.url || \"\";\n const params = new URL(url, \"http://localhost\").searchParams;\n const statusParam = params.get(\"status\");\n const filter = statusParam\n ? { statuses: statusParam.split(\",\") }\n : undefined;\n const topics = deps.topicManager.listTopics(filter);\n deps.sendJson(res, 200, { topics });\n });\n\n router.post(\"/api/topics/cleanup\", async (req, res) => {\n if (!deps.topicManager) {\n deps.sendJson(res, 501, { error: \"Topic management not available\" });\n return;\n }\n const body = await deps.readBody(req);\n let statuses: string[] | undefined;\n if (body) {\n try {\n statuses = JSON.parse(body).statuses;\n } catch {\n /* use defaults */\n }\n }\n const result = await deps.topicManager.cleanup(statuses);\n deps.sendJson(res, 200, result);\n });\n\n router.delete(\"/api/topics/:sessionId\", async (req, res, params) => {\n if (!deps.topicManager) {\n deps.sendJson(res, 501, { error: \"Topic management not available\" });\n return;\n }\n const sessionId = decodeURIComponent(params.sessionId);\n const url = req.url || \"\";\n const urlParams = new URL(url, \"http://localhost\").searchParams;\n const force = urlParams.get(\"force\") === \"true\";\n const result = await deps.topicManager.deleteTopic(\n sessionId,\n force ? { confirmed: true } : undefined,\n );\n if (result.ok) {\n deps.sendJson(res, 200, result);\n } else if (result.needsConfirmation) {\n deps.sendJson(res, 409, {\n error: \"Session is active\",\n needsConfirmation: true,\n session: result.session,\n });\n } else if (result.error === \"Cannot delete system topic\") {\n deps.sendJson(res, 403, { error: result.error });\n } else {\n deps.sendJson(res, 404, { error: result.error ?? \"Not found\" });\n }\n });\n}\n","import type { Router } from \"../router.js\";\nimport type { RouteDeps } from \"../api-server.js\";\n\nexport function registerTunnelRoutes(router: Router, deps: RouteDeps): void {\n router.get(\"/api/tunnel\", async (_req, res) => {\n const tunnel = deps.core.tunnelService;\n if (tunnel) {\n deps.sendJson(res, 200, {\n enabled: true,\n url: tunnel.getPublicUrl(),\n provider: deps.core.configManager.get().tunnel.provider,\n });\n } else {\n deps.sendJson(res, 200, { enabled: false });\n }\n });\n\n router.get(\"/api/tunnel/list\", async (_req, res) => {\n const tunnel = deps.core.tunnelService;\n if (!tunnel) {\n deps.sendJson(res, 200, []);\n return;\n }\n deps.sendJson(res, 200, tunnel.listTunnels());\n });\n\n router.post(\"/api/tunnel\", async (req, res) => {\n const tunnel = deps.core.tunnelService;\n if (!tunnel) {\n deps.sendJson(res, 400, { error: \"Tunnel service is not enabled\" });\n return;\n }\n const body = await deps.readBody(req);\n if (body === null) {\n deps.sendJson(res, 413, { error: \"Request body too large\" });\n return;\n }\n if (!body) {\n deps.sendJson(res, 400, { error: \"Missing request body\" });\n return;\n }\n try {\n const { port, label, sessionId } = JSON.parse(body);\n if (!port || typeof port !== \"number\") {\n deps.sendJson(res, 400, {\n error: \"port is required and must be a number\",\n });\n return;\n }\n const entry = await tunnel.addTunnel(port, { label, sessionId });\n deps.sendJson(res, 200, entry);\n } catch (err) {\n deps.sendJson(res, 400, { error: (err as Error).message });\n }\n });\n\n router.delete(\"/api/tunnel/:port\", async (_req, res, params) => {\n const tunnel = deps.core.tunnelService;\n if (!tunnel) {\n deps.sendJson(res, 400, { error: \"Tunnel service is not enabled\" });\n return;\n }\n const port = parseInt(params.port, 10);\n try {\n await tunnel.stopTunnel(port);\n deps.sendJson(res, 200, { ok: true });\n } catch (err) {\n deps.sendJson(res, 400, { error: (err as Error).message });\n }\n });\n\n router.delete(\"/api/tunnel\", async (_req, res) => {\n const tunnel = deps.core.tunnelService;\n if (!tunnel) {\n deps.sendJson(res, 400, { error: \"Tunnel service is not enabled\" });\n return;\n }\n const count = tunnel.listTunnels().length;\n await tunnel.stopAllUser();\n deps.sendJson(res, 200, { ok: true, stopped: count });\n });\n}\n","// Re-export from new consolidated module for backward compatibility\nexport { getAgentCapabilities } from \"./agent-dependencies.js\";\nexport type { AgentCapability } from \"./agent-dependencies.js\";\n","import type { Router } from \"../router.js\";\nimport type { RouteDeps } from \"../api-server.js\";\nimport { getAgentCapabilities } from \"../../../core/agents/agent-registry.js\";\n\nexport function registerAgentRoutes(router: Router, deps: RouteDeps): void {\n router.get(\"/api/agents\", async (_req, res) => {\n const agents = deps.core.agentManager.getAvailableAgents();\n const defaultAgent = deps.core.configManager.get().defaultAgent;\n const agentsWithCaps = agents.map((a) => ({\n ...a,\n capabilities: getAgentCapabilities(a.name),\n }));\n deps.sendJson(res, 200, { agents: agentsWithCaps, default: defaultAgent });\n });\n}\n","import type { Router } from \"../router.js\";\nimport type { RouteDeps } from \"../api-server.js\";\n\nexport function registerNotifyRoutes(router: Router, deps: RouteDeps): void {\n router.post(\"/api/notify\", async (req, res) => {\n const body = await deps.readBody(req);\n let message: string | undefined;\n if (body) {\n try {\n const parsed = JSON.parse(body);\n message = parsed.message;\n } catch {\n deps.sendJson(res, 400, { error: \"Invalid JSON body\" });\n return;\n }\n }\n\n if (!message) {\n deps.sendJson(res, 400, { error: \"Missing message\" });\n return;\n }\n\n await deps.core.notificationManager.notifyAll({\n sessionId: \"system\",\n type: \"completed\",\n summary: message,\n });\n deps.sendJson(res, 200, { ok: true });\n });\n}\n","import * as http from \"node:http\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport * as crypto from \"node:crypto\";\nimport { fileURLToPath } from \"node:url\";\nimport type { OpenACPCore } from \"../../core/core.js\";\nimport type { TopicManager } from \"../telegram/topic-manager.js\";\nimport { createChildLogger } from \"../../core/utils/log.js\";\nimport { SSEManager } from \"./sse-manager.js\";\nimport { StaticServer } from \"./static-server.js\";\nimport { Router } from \"./router.js\";\nimport { registerHealthRoutes } from \"./routes/health.js\";\nimport { registerSessionRoutes } from \"./routes/sessions.js\";\nimport { registerConfigRoutes } from \"./routes/config.js\";\nimport { registerTopicRoutes } from \"./routes/topics.js\";\nimport { registerTunnelRoutes } from \"./routes/tunnel.js\";\nimport { registerAgentRoutes } from \"./routes/agents.js\";\nimport { registerNotifyRoutes } from \"./routes/notify.js\";\n\nconst log = createChildLogger({ module: \"api-server\" });\n\nlet cachedVersion: string | undefined;\n\nfunction getVersion(): string {\n if (cachedVersion) return cachedVersion;\n try {\n const __filename = fileURLToPath(import.meta.url);\n const pkgPath = path.resolve(\n path.dirname(__filename),\n \"../../../package.json\",\n );\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n cachedVersion = pkg.version ?? \"0.0.0-dev\";\n } catch {\n cachedVersion = \"0.0.0-dev\";\n }\n return cachedVersion!;\n}\n\nexport interface ApiConfig {\n port: number;\n host: string;\n}\n\n/** Dependencies passed to route registration functions. */\nexport interface RouteDeps {\n core: OpenACPCore;\n topicManager?: TopicManager;\n startedAt: number;\n getVersion: () => string;\n sendJson: (res: http.ServerResponse, status: number, data: unknown) => void;\n readBody: (req: http.IncomingMessage) => Promise<string | null>;\n}\n\nexport class ApiServer {\n private server: http.Server | null = null;\n private actualPort: number = 0;\n private portFilePath: string;\n private startedAt = Date.now();\n private secret: string = \"\";\n private secretFilePath: string;\n private sseManager: SSEManager;\n private staticServer: StaticServer;\n private router: Router;\n\n constructor(\n private core: OpenACPCore,\n private config: ApiConfig,\n portFilePath?: string,\n private topicManager?: TopicManager,\n secretFilePath?: string,\n uiDir?: string,\n ) {\n this.portFilePath = portFilePath ?? path.join(os.homedir(), \".openacp\", \"api.port\");\n this.secretFilePath =\n secretFilePath ?? path.join(os.homedir(), \".openacp\", \"api-secret\");\n this.staticServer = new StaticServer(uiDir);\n this.sseManager = new SSEManager(\n core.eventBus,\n () => {\n const sessions = this.core.sessionManager.listSessions();\n return {\n active: sessions.filter(\n (s) => s.status === \"active\" || s.status === \"initializing\",\n ).length,\n total: sessions.length,\n };\n },\n this.startedAt,\n );\n\n this.router = new Router();\n const deps: RouteDeps = {\n core: this.core,\n topicManager: this.topicManager,\n startedAt: this.startedAt,\n getVersion,\n sendJson: this.sendJson.bind(this),\n readBody: this.readBody.bind(this),\n };\n\n registerHealthRoutes(this.router, deps);\n registerSessionRoutes(this.router, deps);\n registerConfigRoutes(this.router, deps);\n registerTopicRoutes(this.router, deps);\n registerTunnelRoutes(this.router, deps);\n registerAgentRoutes(this.router, deps);\n registerNotifyRoutes(this.router, deps);\n }\n\n async start(): Promise<void> {\n this.loadOrCreateSecret();\n this.server = http.createServer((req, res) => this.handleRequest(req, res));\n\n await new Promise<void>((resolve, reject) => {\n this.server!.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\") {\n log.warn(\n { port: this.config.port },\n \"API port in use, continuing without API server\",\n );\n this.server = null;\n // actualPort stays 0, port file not written\n resolve();\n } else {\n reject(err);\n }\n });\n\n this.server!.listen(this.config.port, this.config.host, () => {\n const addr = this.server!.address();\n if (addr && typeof addr === \"object\") {\n this.actualPort = addr.port;\n }\n this.writePortFile();\n log.info(\n { host: this.config.host, port: this.actualPort },\n \"API server listening\",\n );\n this.sseManager.setup();\n\n if (\n this.config.host !== \"127.0.0.1\" &&\n this.config.host !== \"localhost\"\n ) {\n log.warn(\n \"API server binding to non-localhost. Ensure api-secret file is secured.\",\n );\n }\n\n resolve();\n });\n });\n }\n\n async stop(): Promise<void> {\n this.sseManager.stop();\n this.removePortFile();\n if (this.server) {\n await new Promise<void>((resolve) => {\n this.server!.close(() => resolve());\n });\n this.server = null;\n }\n }\n\n getPort(): number {\n return this.actualPort;\n }\n\n getSecret(): string {\n return this.secret;\n }\n\n private writePortFile(): void {\n const dir = path.dirname(this.portFilePath);\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(this.portFilePath, String(this.actualPort));\n }\n\n private removePortFile(): void {\n try {\n fs.unlinkSync(this.portFilePath);\n } catch {\n /* ignore */\n }\n }\n\n private loadOrCreateSecret(): void {\n const dir = path.dirname(this.secretFilePath);\n fs.mkdirSync(dir, { recursive: true });\n\n try {\n this.secret = fs.readFileSync(this.secretFilePath, \"utf-8\").trim();\n if (this.secret) {\n // Warn if file permissions are too open (like SSH does for private keys)\n try {\n const stat = fs.statSync(this.secretFilePath);\n const mode = stat.mode & 0o777;\n if (mode & 0o077) {\n log.warn(\n { path: this.secretFilePath, mode: \"0\" + mode.toString(8) },\n \"API secret file has insecure permissions (should be 0600). Run: chmod 600 %s\",\n this.secretFilePath,\n );\n }\n } catch {\n /* stat failed, skip check */\n }\n return;\n }\n } catch {\n // File doesn't exist, create it\n }\n\n this.secret = crypto.randomBytes(32).toString(\"hex\");\n fs.writeFileSync(this.secretFilePath, this.secret, { mode: 0o600 });\n }\n\n private authenticate(\n req: http.IncomingMessage,\n allowQueryParam = false,\n ): boolean {\n // Check Authorization header\n const authHeader = req.headers.authorization;\n if (authHeader?.startsWith(\"Bearer \")) {\n const token = authHeader.slice(7);\n if (\n token.length === this.secret.length &&\n crypto.timingSafeEqual(\n Buffer.from(token, \"utf-8\"),\n Buffer.from(this.secret, \"utf-8\"),\n )\n ) {\n return true;\n }\n }\n // Query param auth only for SSE (EventSource can't set headers)\n if (allowQueryParam) {\n const parsedUrl = new URL(req.url || \"\", \"http://localhost\");\n const qToken = parsedUrl.searchParams.get(\"token\");\n if (\n qToken &&\n qToken.length === this.secret.length &&\n crypto.timingSafeEqual(\n Buffer.from(qToken, \"utf-8\"),\n Buffer.from(this.secret, \"utf-8\"),\n )\n ) {\n return true;\n }\n }\n return false;\n }\n\n private async handleRequest(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n ): Promise<void> {\n const method = req.method?.toUpperCase();\n const url = req.url || \"\";\n\n // Auth check: exempt health/version, SSE (has own auth), and non-/api/ routes (static files)\n if (url.startsWith(\"/api/\")) {\n const isExempt =\n method === \"GET\" &&\n (url === \"/api/health\" ||\n url === \"/api/version\" ||\n url.startsWith(\"/api/events\"));\n if (!isExempt && !this.authenticate(req)) {\n this.sendJson(res, 401, { error: \"Unauthorized\" });\n return;\n }\n }\n\n try {\n // SSE endpoint — handled separately (streaming connection)\n if (method === \"GET\" && url.startsWith(\"/api/events\")) {\n if (!this.authenticate(req, true)) {\n this.sendJson(res, 401, { error: \"Unauthorized\" });\n return;\n }\n this.sseManager.handleRequest(req, res);\n return; // Don't end the response — SSE keeps it open\n }\n\n // Try router for API routes\n if (url.startsWith(\"/api/\")) {\n const match = this.router.match(method!, url);\n if (match) {\n await match.handler(req, res, match.params);\n } else {\n this.sendJson(res, 404, { error: \"Not found\" });\n }\n return;\n }\n\n // Try static file serving (UI dashboard) for non-API routes\n if (!this.staticServer.serve(req, res)) {\n this.sendJson(res, 404, { error: \"Not found\" });\n }\n } catch (err) {\n log.error({ err }, \"API request error\");\n this.sendJson(res, 500, { error: \"Internal server error\" });\n }\n }\n\n private sendJson(\n res: http.ServerResponse,\n status: number,\n data: unknown,\n ): void {\n res.writeHead(status, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(data));\n }\n\n private readBody(req: http.IncomingMessage): Promise<string | null> {\n const MAX_BODY_SIZE = 1024 * 1024; // 1MB\n return new Promise((resolve) => {\n let data = \"\";\n let size = 0;\n let destroyed = false;\n req.on(\"data\", (chunk: Buffer) => {\n size += chunk.length;\n if (size > MAX_BODY_SIZE && !destroyed) {\n destroyed = true;\n req.destroy();\n resolve(null);\n return;\n }\n if (!destroyed) data += chunk;\n });\n req.on(\"end\", () => {\n if (!destroyed) resolve(data);\n });\n req.on(\"error\", () => {\n if (!destroyed) resolve(\"\");\n });\n });\n }\n}\n","import path from 'node:path'\nimport type { OpenACPPlugin, InstallContext } from '../../core/plugin/types.js'\nimport type { OpenACPCore } from '../../core/core.js'\nimport type { ApiConfig } from './api-server.js'\n\nfunction createApiServerPlugin(): OpenACPPlugin {\n let server: { start(): Promise<void>; stop?(): Promise<void> } | null = null\n\n return {\n name: '@openacp/api-server',\n version: '1.0.0',\n description: 'REST API + SSE streaming server',\n essential: false,\n permissions: ['services:register', 'kernel:access', 'events:read'],\n\n async install(ctx: InstallContext) {\n const { settings, legacyConfig, terminal } = ctx\n\n // Migrate from legacy config if present\n if (legacyConfig) {\n const apiCfg = legacyConfig.api as Record<string, unknown> | undefined\n if (apiCfg) {\n await settings.setAll({\n port: apiCfg.port ?? 21420,\n host: apiCfg.host ?? '127.0.0.1',\n })\n terminal.log.success('API server settings migrated from legacy config')\n return\n }\n }\n\n // Save defaults\n await settings.setAll({\n port: 21420,\n host: '127.0.0.1',\n })\n terminal.log.success('API server defaults saved')\n },\n\n async configure(ctx: InstallContext) {\n const { terminal, settings } = ctx\n const current = await settings.getAll()\n\n const choice = await terminal.select({\n message: 'What to configure?',\n options: [\n { value: 'port', label: `Change port (current: ${current.port ?? 21420})` },\n { value: 'host', label: `Change host (current: ${current.host ?? '127.0.0.1'})` },\n { value: 'done', label: 'Done' },\n ],\n })\n\n if (choice === 'port') {\n const val = await terminal.text({\n message: 'API port:',\n defaultValue: String(current.port ?? 21420),\n validate: (v) => {\n const n = Number(v.trim())\n if (isNaN(n) || n < 1 || n > 65535) return 'Port must be 1-65535'\n return undefined\n },\n })\n await settings.set('port', Number(val.trim()))\n terminal.log.success('Port updated')\n } else if (choice === 'host') {\n const val = await terminal.text({\n message: 'API host:',\n defaultValue: (current.host as string) ?? '127.0.0.1',\n })\n await settings.set('host', val.trim())\n terminal.log.success('Host updated')\n }\n },\n\n async uninstall(ctx: InstallContext, opts: { purge: boolean }) {\n if (opts.purge) {\n await ctx.settings.clear()\n ctx.terminal.log.success('API server settings cleared')\n }\n },\n\n inheritableKeys: ['host'],\n\n async setup(ctx) {\n const config = ctx.pluginConfig as Record<string, unknown>\n\n // Lazy import to avoid loading unless needed\n const { ApiServer } = await import('./api-server.js')\n\n const apiConfig: ApiConfig = {\n port: (config.port as number) ?? 0,\n host: (config.host as string) ?? '127.0.0.1',\n }\n\n const instanceRoot = ctx.instanceRoot\n server = new ApiServer(\n ctx.core as OpenACPCore,\n apiConfig,\n path.join(instanceRoot, 'api.port'),\n undefined,\n path.join(instanceRoot, 'api-secret'),\n )\n\n ctx.registerService('api-server', server)\n\n // Start on system:ready\n ctx.on('system:ready', async () => {\n try {\n await server!.start()\n ctx.log.info('API server started')\n } catch (err) {\n ctx.log.error(`API server failed to start: ${err}`)\n }\n })\n },\n\n async teardown() {\n if (server) {\n await server.stop?.()\n }\n },\n }\n}\n\nexport default createApiServerPlugin()\n","export async function validateBotToken(\n token: string,\n): Promise<\n | { ok: true; botName: string; botUsername: string }\n | { ok: false; error: string }\n> {\n try {\n const res = await fetch(`https://api.telegram.org/bot${token}/getMe`);\n const data = (await res.json()) as {\n ok: boolean;\n result?: { first_name: string; username: string };\n description?: string;\n };\n if (data.ok && data.result) {\n return {\n ok: true,\n botName: data.result.first_name,\n botUsername: data.result.username,\n };\n }\n return { ok: false, error: data.description || \"Invalid token\" };\n } catch (err) {\n return { ok: false, error: (err as Error).message };\n }\n}\n\nexport async function validateChatId(\n token: string,\n chatId: number,\n): Promise<\n { ok: true; title: string; isForum: boolean } | { ok: false; error: string }\n> {\n try {\n const res = await fetch(`https://api.telegram.org/bot${token}/getChat`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ chat_id: chatId }),\n });\n const data = (await res.json()) as {\n ok: boolean;\n result?: { title: string; type: string; is_forum?: boolean };\n description?: string;\n };\n if (!data.ok || !data.result) {\n return { ok: false, error: data.description || \"Invalid chat ID\" };\n }\n if (data.result.type !== \"supergroup\") {\n return {\n ok: false,\n error: `Chat is \"${data.result.type}\", must be a supergroup`,\n };\n }\n return {\n ok: true,\n title: data.result.title,\n isForum: data.result.is_forum === true,\n };\n } catch (err) {\n return { ok: false, error: (err as Error).message };\n }\n}\n\nexport async function validateBotAdmin(\n token: string,\n chatId: number,\n): Promise<{ ok: true } | { ok: false; error: string }> {\n try {\n // Get bot's own user ID\n const meRes = await fetch(`https://api.telegram.org/bot${token}/getMe`);\n const meData = (await meRes.json()) as {\n ok: boolean;\n result?: { id: number };\n };\n if (!meData.ok || !meData.result) {\n return { ok: false, error: \"Could not retrieve bot info\" };\n }\n\n const res = await fetch(\n `https://api.telegram.org/bot${token}/getChatMember`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ chat_id: chatId, user_id: meData.result.id }),\n },\n );\n const data = (await res.json()) as {\n ok: boolean;\n result?: { status: string };\n description?: string;\n };\n if (!data.ok || !data.result) {\n return {\n ok: false,\n error: data.description || \"Could not check bot membership\",\n };\n }\n\n const { status } = data.result;\n if (status === \"administrator\" || status === \"creator\") {\n return { ok: true };\n }\n return {\n ok: false,\n error: `Bot is \"${status}\" in this group. It must be an admin. Please promote the bot to admin in group settings.`,\n };\n } catch (err) {\n return { ok: false, error: (err as Error).message };\n }\n}\n","import type { Bot } from 'grammy'\n\n// Ensure notification and assistant topics exist, create if needed\n// Returns updated topic IDs\nexport async function ensureTopics(\n bot: Bot,\n chatId: number,\n config: { notificationTopicId: number | null; assistantTopicId: number | null },\n saveConfig: (updates: { notificationTopicId?: number; assistantTopicId?: number }) => Promise<void>,\n): Promise<{ notificationTopicId: number; assistantTopicId: number }> {\n let notificationTopicId = config.notificationTopicId\n let assistantTopicId = config.assistantTopicId\n\n if (notificationTopicId === null) {\n const topic = await bot.api.createForumTopic(chatId, '📋 Notifications')\n notificationTopicId = topic.message_thread_id\n await saveConfig({ notificationTopicId })\n }\n\n if (assistantTopicId === null) {\n const topic = await bot.api.createForumTopic(chatId, '🤖 Assistant')\n assistantTopicId = topic.message_thread_id\n await saveConfig({ assistantTopicId })\n }\n\n return { notificationTopicId, assistantTopicId }\n}\n\n// Create a new forum topic for a session\nexport async function createSessionTopic(\n bot: Bot,\n chatId: number,\n name: string,\n): Promise<number> {\n const topic = await bot.api.createForumTopic(chatId, name)\n return topic.message_thread_id\n}\n\n// Rename an existing forum topic\nexport async function renameSessionTopic(\n bot: Bot,\n chatId: number,\n threadId: number,\n name: string,\n): Promise<void> {\n try {\n await bot.api.editForumTopic(chatId, threadId, { name })\n } catch {\n // Ignore rename failures (topic may be closed/deleted)\n }\n}\n\n// Delete a forum topic and all its messages\nexport async function deleteSessionTopic(\n bot: Bot,\n chatId: number,\n threadId: number,\n): Promise<void> {\n await bot.api.deleteForumTopic(chatId, threadId);\n}\n\n// Build a Telegram deep link to a specific message in a forum topic\nexport function buildDeepLink(chatId: number, threadId: number, messageId?: number): string {\n // chatId for supergroups starts with -100, need to strip it for the link\n const cleanId = String(chatId).replace('-100', '')\n // For forum groups: c/{chatId}/{threadId}/{messageId} links to a specific message\n // Without messageId: c/{chatId}/{threadId} links to the topic itself\n if (messageId && messageId !== threadId) {\n return `https://t.me/c/${cleanId}/${threadId}/${messageId}`\n }\n return `https://t.me/c/${cleanId}/${threadId}`\n}\n","// src/adapters/shared/format-types.ts\n\nexport type OutputMode = \"low\" | \"medium\" | \"high\";\n/** @deprecated Use OutputMode instead */\nexport type DisplayVerbosity = OutputMode;\n\nexport type NoiseAction = \"hide\" | \"collapse\";\n\nexport interface NoiseRule {\n match: (name: string, kind: string, rawInput: unknown) => boolean;\n action: NoiseAction;\n}\n\nexport type MessageStyle =\n | \"text\"\n | \"thought\"\n | \"tool\"\n | \"plan\"\n | \"usage\"\n | \"system\"\n | \"error\"\n | \"attachment\";\n\nexport interface MessageMetadata {\n toolName?: string;\n toolStatus?: string;\n toolKind?: string;\n filePath?: string;\n command?: string;\n planEntries?: { content: string; status: string }[];\n tokens?: number;\n contextSize?: number;\n cost?: number;\n viewerLinks?: ViewerLinks;\n viewerFilePath?: string;\n}\n\n/** summary and detail are always plain text (never pre-escaped HTML/markdown) — renderers handle escaping */\nexport interface FormattedMessage {\n summary: string;\n detail?: string;\n viewerLinks?: ViewerLinks;\n icon: string;\n originalType: string;\n style: MessageStyle;\n metadata?: MessageMetadata;\n}\n\nexport const STATUS_ICONS: Record<string, string> = {\n pending: \"⏳\",\n in_progress: \"🔄\",\n completed: \"✅\",\n failed: \"❌\",\n cancelled: \"🚫\",\n running: \"🔄\",\n done: \"✅\",\n error: \"❌\",\n};\n\nexport const KIND_ICONS: Record<string, string> = {\n read: \"📖\",\n edit: \"✏️\",\n write: \"✏️\",\n delete: \"🗑️\",\n execute: \"▶️\",\n command: \"▶️\",\n bash: \"▶️\",\n terminal: \"▶️\",\n search: \"🔍\",\n web: \"🌐\",\n fetch: \"🌐\",\n agent: \"🧠\",\n think: \"🧠\",\n install: \"📦\",\n move: \"📦\",\n other: \"🛠️\",\n};\n\nexport const KIND_LABELS: Record<string, string> = {\n read: \"Read\",\n edit: \"Edit\",\n write: \"Write\",\n delete: \"Delete\",\n execute: \"Run\",\n bash: \"Bash\",\n command: \"Run\",\n terminal: \"Terminal\",\n search: \"Search\",\n web: \"Web\",\n fetch: \"Fetch\",\n agent: \"Agent\",\n think: \"Agent\",\n install: \"Install\",\n move: \"Move\",\n};\n\nexport interface ViewerLinks {\n file?: string;\n diff?: string;\n}\n\nexport interface ToolCallMeta {\n id: string;\n name: string;\n kind?: string;\n status?: string;\n content?: unknown;\n rawInput?: unknown;\n viewerLinks?: ViewerLinks;\n viewerFilePath?: string;\n displaySummary?: string;\n displayTitle?: string;\n displayKind?: string;\n}\n\nexport interface ToolUpdateMeta extends ToolCallMeta {\n status: string;\n}\n","export function progressBar(ratio: number, length = 10): string {\n const filled = Math.round(Math.min(ratio, 1) * length);\n return \"▓\".repeat(filled) + \"░\".repeat(length - filled);\n}\n\nexport function formatTokens(n: number): string {\n if (n >= 1_000_000) {\n const m = n / 1_000_000;\n return m % 1 === 0 ? `${m}M` : `${parseFloat(m.toFixed(1))}M`;\n }\n if (n >= 1000) {\n const k = n / 1000;\n return k % 1 === 0 ? `${k}k` : `${parseFloat(k.toFixed(1))}k`;\n }\n return String(n);\n}\n\nexport function stripCodeFences(text: string): string {\n return text\n .replace(/```\\w*\\n?/g, \"\")\n .replace(/```$/gm, \"\")\n .trim();\n}\n\nexport function truncateContent(text: string, maxLen: number): string {\n if (text.length <= maxLen) return text;\n return text.slice(0, maxLen) + \"\\n… (truncated)\";\n}\n\nexport function splitMessage(text: string, maxLength: number): string[] {\n if (text.length <= maxLength) return [text];\n const chunks: string[] = [];\n let remaining = text;\n while (remaining.length > 0) {\n if (remaining.length <= maxLength) {\n chunks.push(remaining);\n break;\n }\n\n const wouldLeaveSmall = remaining.length < maxLength * 1.3;\n const searchLimit = wouldLeaveSmall\n ? Math.floor(remaining.length / 2) + 300\n : maxLength;\n\n const threshold = maxLength * 0.2;\n let splitAt = remaining.lastIndexOf(\"\\n\\n\", searchLimit);\n if (splitAt === -1 || splitAt < threshold) {\n splitAt = remaining.lastIndexOf(\"\\n\", searchLimit);\n }\n if (splitAt === -1 || splitAt < threshold) {\n splitAt = searchLimit;\n }\n\n const candidate = remaining.slice(0, splitAt);\n const fences = candidate.match(/```/g);\n if (fences && fences.length % 2 !== 0) {\n const closingFence = remaining.indexOf(\"```\", splitAt);\n if (closingFence !== -1) {\n const afterFence = remaining.indexOf(\"\\n\", closingFence + 3);\n const fenceSplit =\n afterFence !== -1 ? afterFence + 1 : closingFence + 3;\n // Only extend to include the closing fence if it doesn't exceed 2x maxLength\n if (fenceSplit <= maxLength * 2) {\n splitAt = fenceSplit;\n }\n }\n }\n\n chunks.push(remaining.slice(0, splitAt));\n remaining = remaining.slice(splitAt).replace(/^\\n+/, \"\");\n }\n return chunks;\n}\n","import type { NoiseAction, NoiseRule } from \"./format-types.js\";\nimport { STATUS_ICONS, KIND_ICONS } from \"./format-types.js\";\n\nexport function extractContentText(content: unknown, depth = 0): string {\n if (!content || depth > 5) return \"\";\n if (typeof content === \"string\") return content;\n if (Array.isArray(content)) {\n return content\n .map((c) => extractContentText(c, depth + 1))\n .filter(Boolean)\n .join(\"\\n\");\n }\n if (typeof content !== \"object\") return String(content);\n\n const obj = content as Record<string, unknown>;\n if (obj.text && typeof obj.text === \"string\") return obj.text;\n if (obj.content) {\n if (typeof obj.content === \"string\") return obj.content;\n if (Array.isArray(obj.content)) {\n return obj.content\n .map((c) => extractContentText(c, depth + 1))\n .filter(Boolean)\n .join(\"\\n\");\n }\n return extractContentText(obj.content, depth + 1);\n }\n if (obj.input) return extractContentText(obj.input, depth + 1);\n if (obj.output) return extractContentText(obj.output, depth + 1);\n\n // Skip objects with only a 'type' key and no content fields\n const keys = Object.keys(obj).filter((k) => k !== \"type\");\n if (keys.length === 0) return \"\";\n\n // Fallback: serialize unrecognized objects so edge-case agent responses are not silently dropped\n try {\n return JSON.stringify(obj, null, 2);\n } catch {\n return \"\";\n }\n}\n\nfunction parseRawInput(rawInput: unknown): Record<string, unknown> {\n try {\n if (typeof rawInput === \"string\") {\n return JSON.parse(rawInput) as Record<string, unknown>;\n }\n if (typeof rawInput === \"object\" && rawInput !== null) {\n return rawInput as Record<string, unknown>;\n }\n } catch {\n // fall through\n }\n return {};\n}\n\n// --- Step 5: formatToolSummary with displaySummary override ---\n\nexport function formatToolSummary(\n name: string,\n rawInput: unknown,\n displaySummary?: string,\n): string {\n if (displaySummary && typeof displaySummary === \"string\") {\n return displaySummary;\n }\n\n const args = parseRawInput(rawInput);\n const lowerName = name.toLowerCase();\n\n if (lowerName === \"read\") {\n const fp = args.file_path ?? args.filePath ?? \"\";\n const limit = args.limit ? ` (${args.limit} lines)` : \"\";\n return fp ? `📖 Read ${fp}${limit}` : `🔧 ${name}`;\n }\n if (lowerName === \"edit\") {\n const fp = args.file_path ?? args.filePath ?? \"\";\n return fp ? `✏️ Edit ${fp}` : `🔧 ${name}`;\n }\n if (lowerName === \"write\") {\n const fp = args.file_path ?? args.filePath ?? \"\";\n return fp ? `📝 Write ${fp}` : `🔧 ${name}`;\n }\n if (lowerName === \"bash\" || lowerName === \"terminal\") {\n const cmd = String(args.command ?? args.cmd ?? \"\").slice(0, 60);\n return cmd ? `▶️ Run: ${cmd}` : `▶️ Terminal`;\n }\n if (lowerName === \"grep\") {\n const pattern = args.pattern ?? \"\";\n const path = args.path ?? \"\";\n return pattern\n ? `🔍 Grep \"${pattern}\"${path ? ` in ${path}` : \"\"}`\n : `🔧 ${name}`;\n }\n if (lowerName === \"glob\") {\n const pattern = args.pattern ?? \"\";\n return pattern ? `🔍 Glob ${pattern}` : `🔧 ${name}`;\n }\n if (lowerName === \"agent\") {\n const desc = String(args.description ?? \"\").slice(0, 60);\n return desc ? `🧠 Agent: ${desc}` : `🔧 ${name}`;\n }\n if (lowerName === \"webfetch\" || lowerName === \"web_fetch\") {\n const url = String(args.url ?? \"\").slice(0, 60);\n return url ? `🌐 Fetch ${url}` : `🔧 ${name}`;\n }\n if (lowerName === \"websearch\" || lowerName === \"web_search\") {\n const query = String(args.query ?? \"\").slice(0, 60);\n return query ? `🌐 Search \"${query}\"` : `🔧 ${name}`;\n }\n\n return `🔧 ${name}`;\n}\n\n// --- Step 6: formatToolTitle for low verbosity ---\n\nexport function formatToolTitle(\n name: string,\n rawInput: unknown,\n displayTitle?: string,\n): string {\n if (displayTitle && typeof displayTitle === \"string\") {\n return displayTitle;\n }\n\n const args = parseRawInput(rawInput);\n const lowerName = name.toLowerCase();\n\n if ([\"read\", \"edit\", \"write\"].includes(lowerName)) {\n return String(args.file_path ?? args.filePath ?? name);\n }\n if (lowerName === \"bash\" || lowerName === \"terminal\") {\n return String(args.command ?? args.cmd ?? name).slice(0, 60);\n }\n if (lowerName === \"grep\") {\n const pattern = args.pattern ?? \"\";\n const path = args.path ?? \"\";\n return pattern ? `\"${pattern}\"${path ? ` in ${path}` : \"\"}` : name;\n }\n if (lowerName === \"glob\") {\n return String(args.pattern ?? name);\n }\n if (lowerName === \"agent\") {\n return String(args.description ?? name).slice(0, 60);\n }\n if ([\"webfetch\", \"web_fetch\"].includes(lowerName)) {\n return String(args.url ?? name).slice(0, 60);\n }\n if ([\"websearch\", \"web_search\"].includes(lowerName)) {\n return String(args.query ?? name).slice(0, 60);\n }\n\n return name;\n}\n\n// --- Step 7: resolveToolIcon ---\n\nexport function resolveToolIcon(tool: {\n status?: string;\n displayKind?: string;\n kind?: string;\n}): string {\n const statusIcon = STATUS_ICONS[tool.status || \"\"];\n if (statusIcon) return statusIcon;\n const kind = tool.displayKind ?? tool.kind;\n if (kind && KIND_ICONS[kind]) return KIND_ICONS[kind];\n return \"🔧\";\n}\n\n// --- Step 8: Noise filtering ---\n\nconst NOISE_RULES: NoiseRule[] = [\n {\n match: (name) => name.toLowerCase() === \"ls\",\n action: \"hide\",\n },\n {\n match: (_name, kind, rawInput) => {\n if (kind !== \"read\") return false;\n const args = parseRawInput(rawInput);\n const p = String(args.file_path ?? args.filePath ?? args.path ?? \"\");\n return p.endsWith(\"/\");\n },\n action: \"hide\",\n },\n {\n match: (name) => name.toLowerCase() === \"glob\",\n action: \"hide\",\n },\n {\n match: (name) => name.toLowerCase() === \"grep\",\n action: \"hide\",\n },\n];\n\nexport function evaluateNoise(\n name: string,\n kind: string,\n rawInput: unknown,\n): NoiseAction | null {\n for (const rule of NOISE_RULES) {\n if (rule.match(name, kind, rawInput)) return rule.action;\n }\n return null;\n}\n","import type {\n ToolCallMeta,\n ToolUpdateMeta,\n ViewerLinks,\n} from \"../../core/adapter-primitives/format-types.js\";\nimport type { ToolCardSnapshot } from \"../../core/adapter-primitives/primitives/tool-card-state.js\";\nimport type { ToolDisplaySpec } from \"../../core/adapter-primitives/display-spec-builder.js\";\nimport {\n STATUS_ICONS,\n KIND_ICONS,\n KIND_LABELS,\n} from \"../../core/adapter-primitives/format-types.js\";\nimport {\n progressBar,\n formatTokens,\n truncateContent,\n stripCodeFences,\n splitMessage as sharedSplitMessage,\n} from \"../../core/adapter-primitives/format-utils.js\";\nimport {\n extractContentText,\n formatToolSummary,\n formatToolTitle,\n resolveToolIcon,\n} from \"../../core/adapter-primitives/message-formatter.js\";\nimport type { DisplayVerbosity } from \"../../core/adapter-primitives/format-types.js\";\n\nexport function escapeHtml(text: string | undefined | null): string {\n if (!text) return \"\";\n return text\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\");\n}\n\nexport function markdownToTelegramHtml(md: string): string {\n // Step 1: Extract code blocks and inline code into placeholders\n const codeBlocks: string[] = [];\n const inlineCodes: string[] = [];\n\n // Extract fenced code blocks (```lang\\n...\\n```)\n let text = md.replace(\n /```(\\w*)\\n?([\\s\\S]*?)```/g,\n (_match, lang: string, code: string) => {\n const index = codeBlocks.length;\n const escapedCode = escapeHtml(code);\n const langAttr = lang ? ` class=\"language-${escapeHtml(lang)}\"` : \"\";\n codeBlocks.push(`<pre><code${langAttr}>${escapedCode}</code></pre>`);\n return `\\x00CODE_BLOCK_${index}\\x00`;\n },\n );\n\n // Extract inline code (`...`)\n text = text.replace(/`([^`]+)`/g, (_match, code: string) => {\n const index = inlineCodes.length;\n inlineCodes.push(`<code>${escapeHtml(code)}</code>`);\n return `\\x00INLINE_CODE_${index}\\x00`;\n });\n\n // Step 2: Escape HTML in remaining text\n text = escapeHtml(text);\n\n // Step 3: Apply markdown transformations\n // Bold: **text** → <b>text</b>\n text = text.replace(/\\*\\*(.+?)\\*\\*/g, \"<b>$1</b>\");\n\n // Italic: *text* → <i>text</i> (but not the ** used for bold)\n text = text.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, \"<i>$1</i>\");\n\n // Links: [text](url) → <a href=\"url\">text</a>\n // Note: after escapeHtml, parentheses are not affected, but we need to handle\n // the escaped brackets properly. Since [ ] and ( ) are not escaped, this works directly.\n text = text.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<a href=\"$2\">$1</a>');\n\n // Step 4: Restore fenced code blocks\n text = text.replace(/\\x00CODE_BLOCK_(\\d+)\\x00/g, (_match, idx: string) => {\n return codeBlocks[parseInt(idx, 10)];\n });\n\n // Step 5: Restore inline code\n text = text.replace(/\\x00INLINE_CODE_(\\d+)\\x00/g, (_match, idx: string) => {\n return inlineCodes[parseInt(idx, 10)];\n });\n\n return text;\n}\n\nexport function formatToolCall(\n tool: ToolCallMeta,\n verbosity: DisplayVerbosity = \"medium\",\n): string {\n const si = resolveToolIcon(tool);\n const name = tool.name || \"Tool\";\n const label =\n verbosity === \"low\"\n ? formatToolTitle(name, tool.rawInput, tool.displayTitle)\n : formatToolSummary(name, tool.rawInput, tool.displaySummary);\n let text = `${si} <b>${escapeHtml(label)}</b>`;\n // viewer links always shown regardless of verbosity\n text += formatViewerLinks(tool.viewerLinks, tool.viewerFilePath);\n // high only: rawInput + content\n if (verbosity === \"high\") {\n text += formatHighDetails(tool.rawInput, tool.content, 3800);\n }\n return text;\n}\n\nexport function formatToolUpdate(\n update: ToolUpdateMeta,\n verbosity: DisplayVerbosity = \"medium\",\n): string {\n return formatToolCall(update, verbosity);\n}\n\nfunction formatHighDetails(\n rawInput: unknown,\n content: unknown,\n maxLen: number,\n): string {\n let text = \"\";\n if (rawInput) {\n const inputStr =\n typeof rawInput === \"string\"\n ? rawInput\n : JSON.stringify(rawInput, null, 2);\n if (inputStr && inputStr !== \"{}\") {\n text += `\\n<b>Input:</b>\\n<pre>${escapeHtml(truncateContent(inputStr, maxLen))}</pre>`;\n }\n }\n const details = stripCodeFences(extractContentText(content));\n if (details) {\n text += `\\n<b>Output:</b>\\n<pre>${escapeHtml(truncateContent(details, maxLen))}</pre>`;\n }\n return text;\n}\n\nfunction formatViewerLinks(links?: ViewerLinks, filePath?: string): string {\n if (!links) return \"\";\n const fileName = filePath ? filePath.split(\"/\").pop() || filePath : \"\";\n let text = \"\\n\";\n if (links.file)\n text += `\\n📄 <a href=\"${escapeHtml(links.file)}\">View ${escapeHtml(fileName || \"file\")}</a>`;\n if (links.diff)\n text += `\\n📝 <a href=\"${escapeHtml(links.diff)}\">View diff${fileName ? ` — ${escapeHtml(fileName)}` : \"\"}</a>`;\n return text;\n}\n\nexport function formatPlan(plan: {\n entries: Array<{ content: string; status: string }>;\n}): string {\n const { entries } = plan;\n const statusIcon: Record<string, string> = {\n pending: \"⬜\",\n in_progress: \"🔄\",\n completed: \"✅\",\n };\n const lines = entries.map(\n (e, i) =>\n `${statusIcon[e.status] || \"⬜\"} ${i + 1}. ${escapeHtml(e.content)}`,\n );\n return `<b>Plan:</b>\\n${lines.join(\"\\n\")}`;\n}\n\nexport function formatUsage(\n usage: { tokensUsed?: number; contextSize?: number; cost?: number },\n _verbosity: DisplayVerbosity = \"medium\",\n): string {\n const { tokensUsed, contextSize } = usage;\n if (tokensUsed == null) return \"📊 Usage data unavailable\";\n if (contextSize == null) return `📊 ${formatTokens(tokensUsed)} tokens`;\n\n const ratio = tokensUsed / contextSize;\n const pct = Math.round(ratio * 100);\n const bar = progressBar(ratio);\n const emoji = pct >= 85 ? \"⚠️\" : \"📊\";\n return `${emoji} ${formatTokens(tokensUsed)} / ${formatTokens(contextSize)} tokens\\n${bar} ${pct}%`;\n}\n\nexport function formatSummary(summary: string, sessionName?: string): string {\n const header = sessionName\n ? `📋 <b>Summary — ${escapeHtml(sessionName)}</b>`\n : \"📋 <b>Session Summary</b>\";\n return `${header}\\n\\n${escapeHtml(summary)}`;\n}\n\nexport function splitMessage(text: string, maxLength = 3800): string[] {\n return sharedSplitMessage(text, maxLength);\n}\n\nexport function renderToolCard(snap: ToolCardSnapshot): string {\n const sections: string[] = [];\n\n const { totalVisible, completedVisible, allComplete } = snap;\n const headerCheck = allComplete ? \" ✅\" : \"\";\n if (totalVisible > 0) {\n sections.push(`<b>📋 Tools (${completedVisible}/${totalVisible})</b>${headerCheck}`);\n }\n\n const DONE = new Set([\"completed\", \"done\", \"failed\", \"error\"]);\n const visible = snap.specs.filter((s) => !s.isHidden);\n const completed = visible.filter((s) => DONE.has(s.status));\n const running = visible.filter((s) => !DONE.has(s.status));\n\n for (const spec of completed) {\n sections.push(renderSpecSection(spec));\n }\n\n if (snap.planEntries && snap.planEntries.length > 0) {\n const planDone = snap.planEntries.filter((e) => e.status === \"completed\").length;\n const planTotal = snap.planEntries.length;\n sections.push(`── Plan: ${planDone}/${planTotal} ──`);\n const statusIcon: Record<string, string> = { completed: \"✅\", in_progress: \"🔄\", pending: \"⬜\" };\n for (let i = 0; i < snap.planEntries.length; i++) {\n const e = snap.planEntries[i];\n sections.push(`${statusIcon[e.status] ?? \"⬜\"} ${i + 1}. ${escapeHtml(e.content)}`);\n }\n sections.push(\"────\");\n }\n\n for (const spec of running) {\n sections.push(renderSpecSection(spec));\n }\n\n return sections.join(\"\\n\\n\");\n}\n\nconst FILE_KINDS = new Set([\"read\", \"edit\", \"write\", \"delete\"]);\n\n/** Shorten absolute file paths to just filename (+ line range if present) */\nfunction shortenTitle(title: string, kind: string): string {\n if (!FILE_KINDS.has(kind) || !title.includes(\"/\")) return title;\n // Separate optional parenthesized suffix (e.g. \" (lines 10–50)\" or \" (from line 10)\")\n const parenIdx = title.indexOf(\" (\");\n const pathPart = parenIdx > 0 ? title.slice(0, parenIdx) : title;\n const rangePart = parenIdx > 0 ? title.slice(parenIdx) : \"\";\n const fileName = pathPart.split(\"/\").pop() || pathPart;\n return fileName + rangePart;\n}\n\nfunction renderSpecSection(spec: ToolDisplaySpec): string {\n const lines: string[] = [];\n\n const DONE = new Set([\"completed\", \"done\", \"failed\", \"error\"]);\n // Status prefix at the start so text doesn't shift when status changes\n const statusPrefix =\n spec.status === \"error\" || spec.status === \"failed\"\n ? \"❌ \"\n : DONE.has(spec.status)\n ? \"✅ \"\n : \"🔄 \";\n\n // Build title line: \"✅ 📖 Read · filename.ts\"\n const kindLabel = KIND_LABELS[spec.kind];\n const displayTitle = shortenTitle(spec.title, spec.kind);\n // Suppress title when it duplicates the kind label (e.g. \"Edit · Edit\")\n const hasUniqueTitle = displayTitle && displayTitle.toLowerCase() !== kindLabel?.toLowerCase()\n && displayTitle.toLowerCase() !== spec.kind;\n let titleLine: string;\n if (kindLabel) {\n titleLine = hasUniqueTitle\n ? `${statusPrefix}${spec.icon} <b>${kindLabel}</b> · ${escapeHtml(displayTitle)}`\n : `${statusPrefix}${spec.icon} <b>${kindLabel}</b>`;\n } else {\n titleLine = `${statusPrefix}${spec.icon} ${escapeHtml(displayTitle)}`;\n }\n if (spec.diffStats) {\n const { added, removed } = spec.diffStats;\n if (added > 0 && removed > 0) titleLine += ` · <i>+${added}/-${removed} lines</i>`;\n else if (added > 0) titleLine += ` · <i>+${added} lines</i>`;\n else if (removed > 0) titleLine += ` · <i>-${removed} lines</i>`;\n }\n lines.push(titleLine);\n\n if (spec.description) lines.push(` <i>${escapeHtml(spec.description)}</i>`);\n if (spec.command) lines.push(` <code>${escapeHtml(spec.command)}</code>`);\n if (spec.inputContent) {\n const truncated = spec.inputContent.length > 800 ? spec.inputContent.slice(0, 797) + \"…\" : spec.inputContent;\n lines.push(` <pre><code>${escapeHtml(truncated)}</code></pre>`);\n }\n if (spec.outputSummary) lines.push(` · ${escapeHtml(spec.outputSummary)}`);\n if (spec.outputContent || spec.outputFallbackContent) {\n const raw = spec.outputContent ?? spec.outputFallbackContent!;\n const truncated =\n raw.length > 800\n ? raw.slice(0, 797) + \"…\"\n : raw;\n lines.push(` <pre><code>${escapeHtml(truncated)}</code></pre>`);\n }\n\n if (spec.viewerLinks?.file || spec.viewerLinks?.diff || spec.outputViewerLink) {\n const linkParts: string[] = [];\n const shortName = displayTitle || kindLabel || spec.kind;\n if (spec.viewerLinks?.file)\n linkParts.push(`<a href=\"${escapeHtml(spec.viewerLinks.file)}\">View ${escapeHtml(shortName)}</a>`);\n if (spec.viewerLinks?.diff)\n linkParts.push(`<a href=\"${escapeHtml(spec.viewerLinks.diff)}\">View diff</a>`);\n if (spec.outputViewerLink)\n linkParts.push(`<a href=\"${escapeHtml(spec.outputViewerLink)}\">View output</a>`);\n lines.push(` ${linkParts.join(\" · \")}`);\n }\n\n return lines.join(\"\\n\");\n}\n\nconst TELEGRAM_MAX_LENGTH = 4096;\n\n/**\n * Split a tool card into multiple chunks at entry boundaries.\n * Each chunk stays under the Telegram message length limit.\n */\nexport function splitToolCardText(text: string): string[] {\n if (text.length <= TELEGRAM_MAX_LENGTH) return [text];\n\n const sections = text.split(\"\\n\\n\");\n const chunks: string[] = [];\n let current = \"\";\n\n for (const section of sections) {\n // Handle single section > limit (truncate with ellipsis)\n const safeSection =\n section.length > TELEGRAM_MAX_LENGTH\n ? section.slice(0, TELEGRAM_MAX_LENGTH - 3) + \"...\"\n : section;\n\n const candidate = current ? `${current}\\n\\n${safeSection}` : safeSection;\n if (candidate.length > TELEGRAM_MAX_LENGTH && current) {\n chunks.push(current);\n current = safeSection;\n } else {\n current = candidate;\n }\n }\n if (current) chunks.push(current);\n return chunks;\n}\n","import type { Bot, Context } from \"grammy\";\nimport { InlineKeyboard } from \"grammy\";\nimport type { OpenACPCore } from \"../../../core/index.js\";\nimport { escapeHtml } from \"../formatting.js\";\nimport { createChildLogger } from \"../../../core/utils/log.js\";\nconst log = createChildLogger({ module: \"telegram-cmd-admin\" });\n\nexport function buildDangerousModeKeyboard(\n sessionId: string,\n enabled: boolean,\n): InlineKeyboard {\n return new InlineKeyboard().text(\n enabled ? \"🔐 Disable Dangerous Mode\" : \"☠️ Enable Dangerous Mode\",\n `d:${sessionId}`,\n );\n}\n\nexport function setupDangerousModeCallbacks(bot: Bot, core: OpenACPCore): void {\n bot.callbackQuery(/^d:/, async (ctx) => {\n const sessionId = ctx.callbackQuery.data.slice(2);\n const session = core.sessionManager.getSession(sessionId);\n\n // Session live in memory — toggle directly\n if (session) {\n session.dangerousMode = !session.dangerousMode;\n log.info(\n { sessionId, dangerousMode: session.dangerousMode },\n \"Dangerous mode toggled via button\",\n );\n core.sessionManager\n .patchRecord(sessionId, { dangerousMode: session.dangerousMode })\n .catch(() => {});\n\n const toastText = session.dangerousMode\n ? \"☠️ Dangerous mode enabled — permissions auto-approved\"\n : \"🔐 Dangerous mode disabled — permissions shown normally\";\n try {\n await ctx.answerCallbackQuery({ text: toastText });\n } catch {\n /* expired */\n }\n\n try {\n await ctx.editMessageReplyMarkup({\n reply_markup: buildSessionControlKeyboard(\n sessionId,\n session.dangerousMode,\n session.voiceMode === \"on\",\n ),\n });\n } catch {\n /* ignore */\n }\n return;\n }\n\n // Session not in memory (e.g. after restart) — toggle directly in store\n const record = core.sessionManager.getSessionRecord(sessionId);\n if (!record || record.status === \"cancelled\" || record.status === \"error\") {\n try {\n await ctx.answerCallbackQuery({\n text: \"⚠️ Session not found or already ended.\",\n });\n } catch {\n /* expired */\n }\n return;\n }\n\n const newDangerousMode = !(record.dangerousMode ?? false);\n core.sessionManager\n .patchRecord(sessionId, { dangerousMode: newDangerousMode })\n .catch(() => {});\n log.info(\n { sessionId, dangerousMode: newDangerousMode },\n \"Dangerous mode toggled via button (store-only, session not in memory)\",\n );\n\n const toastText = newDangerousMode\n ? \"☠️ Dangerous mode enabled — permissions auto-approved\"\n : \"🔐 Dangerous mode disabled — permissions shown normally\";\n try {\n await ctx.answerCallbackQuery({ text: toastText });\n } catch {\n /* expired */\n }\n\n try {\n await ctx.editMessageReplyMarkup({\n reply_markup: buildSessionControlKeyboard(\n sessionId,\n newDangerousMode,\n false,\n ),\n });\n } catch {\n /* ignore */\n }\n });\n}\n\nexport async function handleEnableDangerous(\n ctx: Context,\n core: OpenACPCore,\n): Promise<void> {\n const threadId = ctx.message?.message_thread_id;\n if (!threadId) {\n await ctx.reply(\"⚠️ This command only works inside a session topic.\", {\n parse_mode: \"HTML\",\n });\n return;\n }\n const session = core.sessionManager.getSessionByThread(\n \"telegram\",\n String(threadId),\n );\n if (session) {\n if (session.dangerousMode) {\n await ctx.reply(\"☠️ Dangerous mode is already enabled.\", {\n parse_mode: \"HTML\",\n });\n return;\n }\n session.dangerousMode = true;\n core.sessionManager\n .patchRecord(session.id, { dangerousMode: true })\n .catch(() => {});\n } else {\n // Session not in memory (e.g. after restart) — update store directly\n const record = core.sessionManager.getRecordByThread(\n \"telegram\",\n String(threadId),\n );\n if (!record || record.status === \"cancelled\" || record.status === \"error\") {\n await ctx.reply(\"⚠️ No active session in this topic.\", {\n parse_mode: \"HTML\",\n });\n return;\n }\n if (record.dangerousMode) {\n await ctx.reply(\"☠️ Dangerous mode is already enabled.\", {\n parse_mode: \"HTML\",\n });\n return;\n }\n core.sessionManager\n .patchRecord(record.sessionId, { dangerousMode: true })\n .catch(() => {});\n }\n await ctx.reply(\n `⚠️ <b>Dangerous mode enabled</b>\\n\\nAll permission requests will be auto-approved. Claude can run arbitrary commands without asking.\\n\\nUse /disable_dangerous to restore normal behaviour.`,\n { parse_mode: \"HTML\" },\n );\n}\n\nexport async function handleDisableDangerous(\n ctx: Context,\n core: OpenACPCore,\n): Promise<void> {\n const threadId = ctx.message?.message_thread_id;\n if (!threadId) {\n await ctx.reply(\"⚠️ This command only works inside a session topic.\", {\n parse_mode: \"HTML\",\n });\n return;\n }\n const session = core.sessionManager.getSessionByThread(\n \"telegram\",\n String(threadId),\n );\n if (session) {\n if (!session.dangerousMode) {\n await ctx.reply(\"🔐 Dangerous mode is already disabled.\", {\n parse_mode: \"HTML\",\n });\n return;\n }\n session.dangerousMode = false;\n core.sessionManager\n .patchRecord(session.id, { dangerousMode: false })\n .catch(() => {});\n } else {\n // Session not in memory (e.g. after restart) — update store directly\n const record = core.sessionManager.getRecordByThread(\n \"telegram\",\n String(threadId),\n );\n if (!record || record.status === \"cancelled\" || record.status === \"error\") {\n await ctx.reply(\"⚠️ No active session in this topic.\", {\n parse_mode: \"HTML\",\n });\n return;\n }\n if (!record.dangerousMode) {\n await ctx.reply(\"🔐 Dangerous mode is already disabled.\", {\n parse_mode: \"HTML\",\n });\n return;\n }\n core.sessionManager\n .patchRecord(record.sessionId, { dangerousMode: false })\n .catch(() => {});\n }\n await ctx.reply(\n \"🔐 <b>Dangerous mode disabled</b>\\n\\nPermission requests will be shown normally.\",\n { parse_mode: \"HTML\" },\n );\n}\n\nexport function buildTTSKeyboard(\n sessionId: string,\n enabled: boolean,\n): InlineKeyboard {\n return new InlineKeyboard().text(\n enabled ? \"🔊 Text to Speech\" : \"🔇 Text to Speech\",\n `v:${sessionId}`,\n );\n}\n\nexport function buildSessionControlKeyboard(\n sessionId: string,\n dangerousMode: boolean,\n voiceMode: boolean,\n): InlineKeyboard {\n return new InlineKeyboard()\n .text(\n dangerousMode ? \"🔐 Disable Dangerous Mode\" : \"☠️ Enable Dangerous Mode\",\n `d:${sessionId}`,\n )\n .row()\n .text(\n voiceMode ? \"🔊 Text to Speech\" : \"🔇 Text to Speech\",\n `v:${sessionId}`,\n );\n}\n\nexport function setupTTSCallbacks(bot: Bot, core: OpenACPCore): void {\n bot.callbackQuery(/^v:/, async (ctx) => {\n const sessionId = ctx.callbackQuery.data.slice(2);\n const session = core.sessionManager.getSession(sessionId);\n\n if (!session) {\n try {\n await ctx.answerCallbackQuery({\n text: \"⚠️ Session not found or not active.\",\n });\n } catch {}\n return;\n }\n\n // Check if TTS provider is available\n if (session.voiceMode !== \"on\" && !core.speechService?.isTTSAvailable()) {\n try {\n await ctx.answerCallbackQuery({\n text: \"⚠️ TTS provider not installed. Use /tts install to set up.\",\n });\n } catch {}\n return;\n }\n\n const newMode = session.voiceMode === \"on\" ? \"off\" : \"on\";\n session.setVoiceMode(newMode);\n\n const toastText =\n newMode === \"on\"\n ? \"🔊 Text to Speech enabled\"\n : \"🔇 Text to Speech disabled\";\n try {\n await ctx.answerCallbackQuery({ text: toastText });\n } catch {}\n\n try {\n await ctx.editMessageReplyMarkup({\n reply_markup: buildSessionControlKeyboard(\n sessionId,\n session.dangerousMode,\n newMode === \"on\",\n ),\n });\n } catch {\n /* ignore */\n }\n });\n}\n\nexport async function handleTTS(\n ctx: Context,\n core: OpenACPCore,\n): Promise<void> {\n const threadId = ctx.message?.message_thread_id;\n if (!threadId) {\n await ctx.reply(\"⚠️ This command only works inside a session topic.\", {\n parse_mode: \"HTML\",\n });\n return;\n }\n const session = await core.getOrResumeSession(\"telegram\", String(threadId));\n if (!session) {\n await ctx.reply(\"⚠️ No active session in this topic.\", {\n parse_mode: \"HTML\",\n });\n return;\n }\n\n const args = ctx.message?.text?.split(/\\s+/).slice(1) ?? [];\n const arg = args[0]?.toLowerCase();\n\n // Check if TTS provider is available before enabling\n if (arg === \"on\" || (!arg)) {\n if (!core.speechService?.isTTSAvailable()) {\n await ctx.reply(\n \"⚠️ TTS provider not installed.\\n\\nUse <code>/tts install</code> to install Edge TTS plugin.\",\n { parse_mode: \"HTML\" },\n );\n return;\n }\n }\n\n if (arg === \"on\") {\n session.setVoiceMode(\"on\");\n await ctx.reply(\"🔊 Text to Speech enabled for this session.\", {\n parse_mode: \"HTML\",\n });\n } else if (arg === \"off\") {\n session.setVoiceMode(\"off\");\n await ctx.reply(\"🔇 Text to Speech disabled.\", { parse_mode: \"HTML\" });\n } else {\n session.setVoiceMode(\"next\");\n await ctx.reply(\"🔊 Text to Speech enabled for the next message.\", {\n parse_mode: \"HTML\",\n });\n }\n}\n\n// ─── Verbosity (deprecated alias) ──────────────────────────────────────────\n\nexport async function handleVerbosity(\n ctx: Context,\n core: OpenACPCore,\n): Promise<void> {\n // Deprecated — alias for /outputmode\n await ctx.reply(\"⚠️ <code>/verbosity</code> is deprecated. Use <code>/outputmode</code> instead.\", { parse_mode: \"HTML\" });\n await handleOutputMode(ctx, core);\n}\n\n// ─── Output Mode ────────────────────────────────────────────────────────────\n\nconst OUTPUT_MODE_LABELS: Record<string, string> = {\n low: \"🔇 Low\",\n medium: \"📊 Medium\",\n high: \"🔍 High\",\n};\n\nexport async function handleOutputMode(\n ctx: Context,\n core: OpenACPCore,\n): Promise<void> {\n const args = ctx.message?.text?.split(/\\s+/).slice(1) ?? [];\n const arg0 = args[0]?.toLowerCase();\n const arg1 = args[1]?.toLowerCase();\n\n // /outputmode session [low|medium|high|reset]\n if (arg0 === \"session\") {\n const chatId = ctx.chat?.id;\n const threadId = ctx.message?.message_thread_id;\n if (!chatId || threadId === undefined) {\n await ctx.reply(\"⚠️ This command must be used in a session topic.\", { parse_mode: \"HTML\" });\n return;\n }\n\n const session = core.sessionManager.getSessionByThread(\n \"telegram\",\n String(threadId),\n );\n\n if (!session) {\n await ctx.reply(\"⚠️ No active session found for this topic.\", { parse_mode: \"HTML\" });\n return;\n }\n\n if (arg1 === \"reset\") {\n await core.sessionManager.patchRecord(session.id, { outputMode: undefined });\n await ctx.reply(\"🔄 Session output mode reset to adapter default.\", { parse_mode: \"HTML\" });\n } else if (arg1 === \"low\" || arg1 === \"medium\" || arg1 === \"high\") {\n await core.sessionManager.patchRecord(session.id, { outputMode: arg1 });\n await ctx.reply(\n `${OUTPUT_MODE_LABELS[arg1]} Session output mode set to <b>${arg1}</b>.`,\n { parse_mode: \"HTML\" },\n );\n } else {\n const record = core.sessionManager.getSessionRecord(session.id);\n const current = record?.outputMode ?? \"(adapter default)\";\n await ctx.reply(\n `📊 Session output mode: <b>${current}</b>\\n\\nUsage: <code>/outputmode session low|medium|high|reset</code>`,\n { parse_mode: \"HTML\" },\n );\n }\n return;\n }\n\n // /outputmode [low|medium|high] — adapter-level\n if (arg0 === \"low\" || arg0 === \"medium\" || arg0 === \"high\") {\n await core.configManager.save(\n { channels: { telegram: { outputMode: arg0 } } },\n \"channels.telegram.outputMode\",\n );\n await ctx.reply(\n `${OUTPUT_MODE_LABELS[arg0]} Output mode set to <b>${arg0}</b>.`,\n { parse_mode: \"HTML\" },\n );\n } else {\n const current =\n (core.configManager.get().channels?.telegram as Record<string, unknown> | undefined)\n ?.outputMode ?? \"medium\";\n await ctx.reply(\n `📊 Current output mode: <b>${current}</b>\\n\\n` +\n `Usage: <code>/outputmode low|medium|high</code>\\n` +\n `Session override: <code>/outputmode session low|medium|high|reset</code>\\n\\n` +\n `• <b>low</b> — minimal: title only\\n` +\n `• <b>medium</b> — balanced: description + output summary (default)\\n` +\n `• <b>high</b> — full detail: inline output, IN/OUT blocks`,\n { parse_mode: \"HTML\" },\n );\n }\n}\n\nexport function setupVerbosityCallbacks(bot: Bot, core: OpenACPCore): void {\n bot.callbackQuery(/^vb:/, async (ctx) => {\n const level = ctx.callbackQuery.data.slice(3);\n if (level !== \"low\" && level !== \"medium\" && level !== \"high\") return;\n\n await core.configManager.save(\n { channels: { telegram: { outputMode: level } } },\n \"channels.telegram.outputMode\",\n );\n\n try {\n await ctx.answerCallbackQuery({\n text: `${OUTPUT_MODE_LABELS[level]} Output mode: ${level}`,\n });\n } catch {}\n });\n}\n\nexport async function handleUpdate(\n ctx: Context,\n core: OpenACPCore,\n): Promise<void> {\n if (!core.requestRestart) {\n await ctx.reply(\n \"⚠️ Update is not available (no restart handler registered).\",\n { parse_mode: \"HTML\" },\n );\n return;\n }\n\n const { getCurrentVersion, getLatestVersion, compareVersions, runUpdate } =\n await import(\"../../../cli/version.js\");\n const current = getCurrentVersion();\n const statusMsg = await ctx.reply(\n `🔍 Checking for updates... (current: v${escapeHtml(current)})`,\n { parse_mode: \"HTML\" },\n );\n\n const latest = await getLatestVersion();\n if (!latest) {\n await ctx.api.editMessageText(\n ctx.chat!.id,\n statusMsg.message_id,\n \"❌ Could not check for updates.\",\n { parse_mode: \"HTML\" },\n );\n return;\n }\n\n if (compareVersions(current, latest) >= 0) {\n await ctx.api.editMessageText(\n ctx.chat!.id,\n statusMsg.message_id,\n `✅ Already up to date (v${escapeHtml(current)}).`,\n { parse_mode: \"HTML\" },\n );\n return;\n }\n\n await ctx.api.editMessageText(\n ctx.chat!.id,\n statusMsg.message_id,\n `⬇️ Updating v${escapeHtml(current)} → v${escapeHtml(latest)}...`,\n { parse_mode: \"HTML\" },\n );\n\n const ok = await runUpdate();\n if (!ok) {\n await ctx.api.editMessageText(\n ctx.chat!.id,\n statusMsg.message_id,\n \"❌ Update failed. Try manually: <code>npm install -g @openacp/cli@latest</code>\",\n { parse_mode: \"HTML\" },\n );\n return;\n }\n\n await ctx.api.editMessageText(\n ctx.chat!.id,\n statusMsg.message_id,\n `✅ Updated to v${escapeHtml(latest)}. Restarting...`,\n { parse_mode: \"HTML\" },\n );\n\n await new Promise((r) => setTimeout(r, 500));\n await core.requestRestart();\n}\n\nexport async function handleRestart(\n ctx: Context,\n core: OpenACPCore,\n): Promise<void> {\n if (!core.requestRestart) {\n await ctx.reply(\n \"⚠️ Restart is not available (no restart handler registered).\",\n { parse_mode: \"HTML\" },\n );\n return;\n }\n await ctx.reply(\n \"🔄 <b>Restarting OpenACP...</b>\\nRebuilding and restarting. Be back shortly.\",\n { parse_mode: \"HTML\" },\n );\n // Give Telegram a moment to deliver the message before shutting down\n await new Promise((r) => setTimeout(r, 500));\n await core.requestRestart();\n}\n","import type { Bot, Context } from \"grammy\";\nimport { InlineKeyboard } from \"grammy\";\nimport type { OpenACPCore } from \"../../../core/index.js\";\nimport type { Session } from \"../../../core/sessions/session.js\";\nimport { escapeHtml } from \"../formatting.js\";\nimport { createSessionTopic, renameSessionTopic, buildDeepLink } from \"../topics.js\";\nimport { createChildLogger } from \"../../../core/utils/log.js\";\nimport { buildSessionControlKeyboard } from \"./admin.js\";\nimport type { CommandsAssistantContext } from \"../types.js\";\nconst log = createChildLogger({ module: \"telegram-cmd-new-session\" });\n\ninterface PendingNewSession {\n agentName?: string;\n workspace?: string;\n step: \"agent\" | \"workspace\" | \"workspace_input\" | \"confirm\";\n messageId: number;\n threadId?: number;\n timer: ReturnType<typeof setTimeout>;\n}\n\nconst pendingNewSessions = new Map<number, PendingNewSession>();\n\nconst PENDING_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes\n\nfunction cleanupPending(userId: number): void {\n const pending = pendingNewSessions.get(userId);\n if (pending) {\n clearTimeout(pending.timer);\n pendingNewSessions.delete(userId);\n }\n}\n\nfunction botFromCtx(ctx: Context): Bot {\n // createSessionTopic only uses bot.api.createForumTopic\n return { api: ctx.api } as unknown as Bot;\n}\n\nexport async function handleNew(\n ctx: Context,\n core: OpenACPCore,\n chatId: number,\n assistant?: CommandsAssistantContext,\n): Promise<void> {\n const rawMatch = (ctx as Context & { match: unknown }).match;\n const matchStr = typeof rawMatch === \"string\" ? rawMatch : \"\";\n const args = matchStr.split(\" \").filter(Boolean);\n const agentName = args[0];\n const workspace = args[1];\n\n // Full args → create directly\n if (agentName && workspace) {\n await createSessionDirect(ctx, core, chatId, agentName, workspace);\n return;\n }\n\n // In assistant topic → forward to assistant for conversational handling\n const currentThreadId = ctx.message?.message_thread_id;\n if (assistant && currentThreadId === assistant.topicId) {\n const assistantSession = assistant.getSession();\n if (assistantSession) {\n const prompt = agentName\n ? `User wants to create a new session with agent \"${agentName}\" but didn't specify a workspace. Ask them which project directory to use as workspace.`\n : `User wants to create a new session. Guide them through choosing an agent and workspace (project directory).`;\n await assistantSession.enqueuePrompt(prompt);\n return;\n }\n }\n\n // Outside assistant topic → interactive agent picker flow\n await showAgentPicker(ctx, core, chatId, agentName);\n}\n\nasync function startWorkspaceStep(\n ctx: Context,\n core: OpenACPCore,\n chatId: number,\n userId: number,\n agentName: string,\n): Promise<void> {\n const config = core.configManager.get();\n const baseDir = config.workspace.baseDir;\n\n const keyboard = new InlineKeyboard()\n .text(`📁 Use ${baseDir}`, \"m:new:ws:default\")\n .row()\n .text(\"✏️ Enter project path\", \"m:new:ws:custom\");\n\n const text =\n `📁 <b>Where should ${escapeHtml(agentName)} work?</b>\\n\\n` +\n `Enter the path to your project folder — the agent will read, write, and run code there.\\n\\n` +\n `Or use the default directory below:`;\n\n let msg;\n try {\n const pending = pendingNewSessions.get(userId);\n if (pending?.messageId) {\n await ctx.api.editMessageText(chatId, pending.messageId, text, {\n parse_mode: \"HTML\",\n reply_markup: keyboard,\n });\n msg = { message_id: pending.messageId };\n } else {\n msg = await ctx.reply(text, { parse_mode: \"HTML\", reply_markup: keyboard });\n }\n } catch {\n msg = await ctx.reply(text, { parse_mode: \"HTML\", reply_markup: keyboard });\n }\n\n cleanupPending(userId);\n pendingNewSessions.set(userId, {\n agentName,\n step: \"workspace\",\n messageId: msg.message_id,\n threadId: ctx.message?.message_thread_id ?? (ctx.callbackQuery?.message as { message_thread_id?: number } | undefined)?.message_thread_id,\n timer: setTimeout(() => pendingNewSessions.delete(userId), PENDING_TIMEOUT_MS),\n });\n}\n\nasync function startConfirmStep(\n ctx: Context,\n chatId: number,\n userId: number,\n agentName: string,\n workspace: string,\n): Promise<void> {\n const keyboard = new InlineKeyboard()\n .text(\"✅ Create\", \"m:new:confirm\")\n .text(\"❌ Cancel\", \"m:new:cancel\");\n\n const text =\n `✅ <b>Ready to create session?</b>\\n\\n` +\n `<b>Agent:</b> ${escapeHtml(agentName)}\\n` +\n `<b>Project:</b> <code>${escapeHtml(workspace)}</code>`;\n\n let msg;\n try {\n const pending = pendingNewSessions.get(userId);\n if (pending?.messageId) {\n await ctx.api.editMessageText(chatId, pending.messageId, text, {\n parse_mode: \"HTML\",\n reply_markup: keyboard,\n });\n msg = { message_id: pending.messageId };\n } else {\n msg = await ctx.reply(text, { parse_mode: \"HTML\", reply_markup: keyboard });\n }\n } catch {\n msg = await ctx.reply(text, { parse_mode: \"HTML\", reply_markup: keyboard });\n }\n\n cleanupPending(userId);\n pendingNewSessions.set(userId, {\n agentName,\n workspace,\n step: \"confirm\",\n messageId: msg.message_id,\n threadId: ctx.message?.message_thread_id ?? (ctx.callbackQuery?.message as { message_thread_id?: number } | undefined)?.message_thread_id,\n timer: setTimeout(() => pendingNewSessions.delete(userId), PENDING_TIMEOUT_MS),\n });\n}\n\nexport async function createSessionDirect(\n ctx: Context,\n core: OpenACPCore,\n chatId: number,\n agentName: string,\n workspace: string,\n): Promise<number | null> {\n log.info({ userId: ctx.from?.id, agentName, workspace }, \"New session command (direct)\");\n\n let threadId: number | undefined;\n try {\n const topicName = `🔄 New Session`;\n threadId = await createSessionTopic(botFromCtx(ctx), chatId, topicName);\n\n await ctx.api.sendMessage(chatId, `⏳ Setting up session, please wait...`, {\n message_thread_id: threadId,\n parse_mode: \"HTML\",\n });\n\n const session = await core.handleNewSession(\"telegram\", agentName, workspace);\n session.threadId = String(threadId);\n\n await core.sessionManager.patchRecord(session.id, { platform: { topicId: threadId } });\n\n const finalName = `🔄 ${session.agentName} — New Session`;\n try {\n await ctx.api.editForumTopic(chatId, threadId, { name: finalName });\n } catch { /* ignore rename failures */ }\n\n await ctx.api.sendMessage(\n chatId,\n `✅ <b>Session started</b>\\n` +\n `<b>Agent:</b> ${escapeHtml(session.agentName)}\\n` +\n `<b>Workspace:</b> <code>${escapeHtml(session.workingDirectory)}</code>\\n\\n` +\n `This is your coding session — chat here to work with the agent.`,\n {\n message_thread_id: threadId,\n parse_mode: \"HTML\",\n reply_markup: buildSessionControlKeyboard(session.id, false, false),\n },\n );\n\n session.warmup().catch((err) => log.error({ err }, \"Warm-up error\"));\n return threadId ?? null;\n } catch (err) {\n log.error({ err }, \"Session creation failed\");\n if (threadId) {\n try { await ctx.api.deleteForumTopic(chatId, threadId); } catch { /* ignore */ }\n }\n const message = err instanceof Error ? err.message : (typeof err === 'object' ? JSON.stringify(err) : String(err));\n await ctx.reply(`❌ ${escapeHtml(message)}`, { parse_mode: \"HTML\" });\n return null;\n }\n}\n\nexport async function handleNewChat(\n ctx: Context,\n core: OpenACPCore,\n chatId: number,\n): Promise<void> {\n const threadId = ctx.message?.message_thread_id;\n if (!threadId) {\n await ctx.reply(\n \"Use /newchat inside a session topic to inherit its config.\",\n { parse_mode: \"HTML\" },\n );\n return;\n }\n\n // Resolve agent config from existing session/record BEFORE spawning\n const currentSession = core.sessionManager.getSessionByThread(\n \"telegram\",\n String(threadId),\n );\n let agentName: string | undefined;\n let workspace: string | undefined;\n\n if (currentSession) {\n agentName = currentSession.agentName;\n workspace = currentSession.workingDirectory;\n } else {\n const record = core.sessionManager.getRecordByThread(\"telegram\", String(threadId));\n if (!record || record.status === \"cancelled\" || record.status === \"error\") {\n await ctx.reply(\"No active session in this topic.\", {\n parse_mode: \"HTML\",\n });\n return;\n }\n agentName = record.agentName;\n workspace = record.workingDir;\n }\n\n let newThreadId: number | undefined;\n try {\n // Create topic FIRST so threadId is ready before session events fire\n const topicName = `🔄 ${agentName} — New Chat`;\n newThreadId = await createSessionTopic(\n botFromCtx(ctx),\n chatId,\n topicName,\n );\n\n // Notify in the original topic immediately with a deep link to the new one\n const topicLink = buildDeepLink(chatId, newThreadId);\n await ctx.reply(\n `✅ New chat created → <a href=\"${topicLink}\">Open topic</a>`,\n { parse_mode: \"HTML\" },\n );\n\n await ctx.api.sendMessage(chatId, `⏳ Setting up session, please wait...`, {\n message_thread_id: newThreadId,\n parse_mode: \"HTML\",\n });\n\n const session = await core.handleNewSession(\n \"telegram\",\n agentName,\n workspace,\n );\n session.threadId = String(newThreadId);\n\n // Persist platform mapping for new chat\n await core.sessionManager.patchRecord(session.id, { platform: {\n topicId: newThreadId,\n } });\n\n await ctx.api.sendMessage(\n chatId,\n `✅ New chat (same agent &amp; workspace)\\n` +\n `<b>Agent:</b> ${escapeHtml(session.agentName)}\\n` +\n `<b>Workspace:</b> <code>${escapeHtml(session.workingDirectory)}</code>`,\n {\n message_thread_id: newThreadId,\n parse_mode: \"HTML\",\n reply_markup: buildSessionControlKeyboard(session.id, false, false),\n },\n );\n\n // Warm up model cache in background while user types\n session.warmup().catch((err) => log.error({ err }, \"Warm-up error\"));\n } catch (err) {\n // Clean up orphaned topic if session creation failed\n if (newThreadId) {\n try {\n await ctx.api.deleteForumTopic(chatId, newThreadId);\n } catch {\n /* ignore cleanup failures */\n }\n }\n const message = err instanceof Error ? err.message : String(err);\n await ctx.reply(`❌ ${escapeHtml(message)}`, { parse_mode: \"HTML\" });\n }\n}\n\nexport async function executeNewSession(\n bot: Bot,\n core: OpenACPCore,\n chatId: number,\n agentName?: string,\n workspace?: string,\n): Promise<{ session: Session; threadId: number; firstMsgId: number }> {\n // Create topic with generic name first (same as original handleNew)\n const threadId = await createSessionTopic(bot, chatId, \"🔄 New Session\");\n\n const setupMsg = await bot.api.sendMessage(chatId, \"⏳ Setting up session, please wait...\", {\n message_thread_id: threadId,\n parse_mode: \"HTML\",\n });\n const firstMsgId = setupMsg.message_id;\n\n try {\n // core.handleNewSession() already wires events internally — do NOT call wireSessionEvents again\n const session = await core.handleNewSession(\n \"telegram\",\n agentName,\n workspace,\n );\n session.threadId = String(threadId);\n\n await core.sessionManager.patchRecord(session.id, { platform: {\n topicId: threadId,\n } });\n\n // Rename topic with agent name after session is created\n const finalName = `🔄 ${session.agentName} — New Session`;\n await renameSessionTopic(bot, chatId, threadId, finalName);\n\n // Warm up model cache in background while user types\n session.warmup().catch((err) => log.error({ err }, \"Warm-up error\"));\n\n return { session, threadId, firstMsgId };\n } catch (err) {\n // Clean up orphaned topic on failure\n try {\n await bot.api.deleteForumTopic(chatId, threadId);\n } catch {\n /* best effort */\n }\n throw err;\n }\n}\n\n/**\n * Check if a text message is a workspace path input for the interactive new session flow.\n * Returns true if the message was handled (caller should not process further).\n */\nexport async function handlePendingWorkspaceInput(\n ctx: Context,\n core: OpenACPCore,\n chatId: number,\n assistantTopicId?: number,\n): Promise<boolean> {\n const userId = ctx.from?.id;\n if (!userId) return false;\n const pending = pendingNewSessions.get(userId);\n if (!pending || !ctx.message?.text) return false;\n // Accept text input at both \"workspace\" step (user types directly instead of pressing buttons)\n // and \"workspace_input\" step (user pressed \"Custom path\" button)\n if (pending.step !== \"workspace_input\" && pending.step !== \"workspace\") return false;\n\n // Only intercept in assistant topic (or no-thread/general) — never in session topics\n const threadId = ctx.message.message_thread_id;\n if (threadId && threadId !== assistantTopicId) return false;\n\n let workspace = ctx.message.text.trim();\n if (!workspace || !pending.agentName) {\n await ctx.reply(\"⚠️ Please enter a valid directory path.\", { parse_mode: \"HTML\" });\n return true;\n }\n\n // Relative path (no / or ~ prefix) → resolve against baseDir\n if (!workspace.startsWith(\"/\") && !workspace.startsWith(\"~\")) {\n const baseDir = core.configManager.get().workspace.baseDir;\n workspace = `${baseDir.replace(/\\/$/, \"\")}/${workspace}`;\n }\n\n await startConfirmStep(ctx, chatId, userId, pending.agentName, workspace);\n return true;\n}\n\n/**\n * Start the interactive new session flow (agent → workspace → confirm).\n * Used by action-detect when workspace is not provided.\n */\nexport async function startInteractiveNewSession(\n ctx: Context,\n core: OpenACPCore,\n chatId: number,\n agentName?: string,\n): Promise<void> {\n await showAgentPicker(ctx, core, chatId, agentName);\n}\n\n/**\n * Shared agent picker logic used by both handleNew and startInteractiveNewSession.\n * Shows agent selection keyboard if multiple agents installed, otherwise skips to workspace step.\n */\nasync function showAgentPicker(\n ctx: Context,\n core: OpenACPCore,\n chatId: number,\n agentName?: string,\n): Promise<void> {\n const userId = ctx.from?.id;\n if (!userId) return;\n\n const installedEntries = core.agentCatalog.getInstalledEntries();\n const agentKeys = Object.keys(installedEntries);\n const config = core.configManager.get();\n\n // If agent provided or only 1 agent → skip to workspace step\n if (agentName || agentKeys.length === 1) {\n const selectedAgent = agentName || config.defaultAgent;\n await startWorkspaceStep(ctx, core, chatId, userId, selectedAgent);\n return;\n }\n\n // Multiple agents → show agent selection\n const keyboard = new InlineKeyboard();\n for (const key of agentKeys) {\n const agent = installedEntries[key]!;\n const label = key === config.defaultAgent\n ? `${agent.name} (default)`\n : agent.name;\n keyboard.text(label, `m:new:agent:${key}`).row();\n }\n\n const msg = await ctx.reply(\n `🤖 <b>Choose an agent:</b>`,\n { parse_mode: \"HTML\", reply_markup: keyboard },\n );\n\n cleanupPending(userId);\n const threadId = ctx.message?.message_thread_id\n ?? (ctx.callbackQuery?.message as { message_thread_id?: number } | undefined)?.message_thread_id;\n pendingNewSessions.set(userId, {\n step: \"agent\",\n messageId: msg.message_id,\n threadId,\n timer: setTimeout(() => pendingNewSessions.delete(userId), PENDING_TIMEOUT_MS),\n });\n}\n\nexport function setupNewSessionCallbacks(\n bot: Bot,\n core: OpenACPCore,\n chatId: number,\n): void {\n bot.callbackQuery(/^m:new:/, async (ctx) => {\n const data = ctx.callbackQuery.data;\n try {\n await ctx.answerCallbackQuery();\n } catch { /* expired or network — ignore */ }\n\n if (data.startsWith(\"m:new:agent:\")) {\n const agentName = data.replace(\"m:new:agent:\", \"\");\n const userId = ctx.from?.id;\n if (userId) await startWorkspaceStep(ctx, core, chatId, userId, agentName);\n return;\n }\n if (data === \"m:new:ws:default\") {\n const userId = ctx.from?.id;\n if (!userId) return;\n const pending = pendingNewSessions.get(userId);\n if (!pending?.agentName) return;\n const workspace = core.configManager.get().workspace.baseDir;\n await startConfirmStep(ctx, chatId, userId, pending.agentName, workspace);\n return;\n }\n if (data === \"m:new:ws:custom\") {\n const userId = ctx.from?.id;\n if (!userId) return;\n const pending = pendingNewSessions.get(userId);\n if (!pending?.agentName) return;\n try {\n await ctx.api.editMessageText(\n chatId,\n pending.messageId,\n `✏️ <b>Enter your project path:</b>\\n\\n` +\n `Full path like <code>~/code/my-project</code>\\n` +\n `Or just the folder name like <code>my-project</code> (will use ${core.configManager.get().workspace.baseDir}/)`,\n { parse_mode: \"HTML\" },\n );\n } catch {\n await ctx.reply(\n `✏️ <b>Enter your project path:</b>`,\n { parse_mode: \"HTML\" },\n );\n }\n clearTimeout(pending.timer);\n pending.step = \"workspace_input\";\n pending.timer = setTimeout(() => pendingNewSessions.delete(userId), PENDING_TIMEOUT_MS);\n return;\n }\n if (data === \"m:new:confirm\") {\n const userId = ctx.from?.id;\n if (!userId) return;\n const pending = pendingNewSessions.get(userId);\n if (!pending?.agentName || !pending?.workspace) return;\n cleanupPending(userId);\n const confirmMsgId = pending.messageId;\n try {\n await ctx.api.editMessageText(chatId, confirmMsgId, `⏳ Creating session...`, { parse_mode: \"HTML\" });\n } catch { /* ignore */ }\n const resultThreadId = await createSessionDirect(ctx, core, chatId, pending.agentName, pending.workspace);\n try {\n if (resultThreadId) {\n const link = buildDeepLink(chatId, resultThreadId);\n await ctx.api.editMessageText(chatId, confirmMsgId, `✅ Session created → <a href=\"${link}\">Open topic</a>`, { parse_mode: \"HTML\" });\n } else {\n await ctx.api.editMessageText(chatId, confirmMsgId, `❌ Session creation failed.`, { parse_mode: \"HTML\" });\n }\n } catch { /* ignore */ }\n return;\n }\n if (data === \"m:new:cancel\") {\n const userId = ctx.from?.id;\n if (userId) cleanupPending(userId);\n try {\n await ctx.editMessageText(\"❌ Session creation cancelled.\", { parse_mode: \"HTML\" });\n } catch { /* ignore */ }\n return;\n }\n });\n}\n","import type { Bot, Context } from \"grammy\";\nimport { InlineKeyboard } from \"grammy\";\nimport type { OpenACPCore } from \"../../../core/index.js\";\nimport type { Session } from \"../../../core/sessions/session.js\";\nimport { escapeHtml } from \"../formatting.js\";\nimport { createChildLogger } from \"../../../core/utils/log.js\";\nimport type { CommandsAssistantContext } from \"../types.js\";\nconst log = createChildLogger({ module: \"telegram-cmd-session\" });\n\nexport async function handleCancel(\n ctx: Context,\n core: OpenACPCore,\n assistant?: CommandsAssistantContext,\n): Promise<void> {\n const threadId = ctx.message?.message_thread_id;\n if (!threadId) return;\n\n // In assistant topic: forward to assistant for confirmation\n if (assistant && threadId === assistant.topicId) {\n const assistantSession = assistant.getSession();\n if (assistantSession) {\n await assistantSession.enqueuePrompt(\n \"User wants to cancel a session. Confirm which session to cancel.\",\n );\n return;\n }\n }\n\n const session = core.sessionManager.getSessionByThread(\n \"telegram\",\n String(threadId),\n );\n if (session) {\n log.info({ sessionId: session.id }, \"Abort prompt command\");\n await session.abortPrompt();\n await ctx.reply(\"⛔ Prompt aborted. Session is still active — send a new message to continue.\", { parse_mode: \"HTML\" });\n return;\n }\n\n // Fallback: session not in memory — nothing to abort, but session can\n // still be resumed when the user sends a new message.\n const record = core.sessionManager.getRecordByThread(\"telegram\", String(threadId));\n if (record && record.status !== \"error\") {\n log.info({ sessionId: record.sessionId, status: record.status }, \"Cancel command — no active prompt to abort\");\n await ctx.reply(\"ℹ️ No active prompt to cancel. Send a new message to resume the session.\", { parse_mode: \"HTML\" });\n }\n}\n\nexport async function handleStatus(ctx: Context, core: OpenACPCore): Promise<void> {\n const threadId = ctx.message?.message_thread_id;\n if (threadId) {\n const session = core.sessionManager.getSessionByThread(\n \"telegram\",\n String(threadId),\n );\n if (session) {\n await ctx.reply(\n `<b>Session:</b> ${escapeHtml(session.name || session.id)}\\n` +\n `<b>Agent:</b> ${escapeHtml(session.agentName)}\\n` +\n `<b>Status:</b> ${escapeHtml(session.status)}\\n` +\n `<b>Workspace:</b> <code>${escapeHtml(session.workingDirectory)}</code>\\n` +\n `<b>Queue:</b> ${session.queueDepth} pending`,\n { parse_mode: \"HTML\" },\n );\n } else {\n // Fallback: show stored session info when not loaded in memory (e.g. after restart)\n const record = core.sessionManager.getRecordByThread(\"telegram\", String(threadId));\n if (record) {\n await ctx.reply(\n `<b>Session:</b> ${escapeHtml(record.name || record.sessionId)}\\n` +\n `<b>Agent:</b> ${escapeHtml(record.agentName)}\\n` +\n `<b>Status:</b> ${escapeHtml(record.status)} (not loaded)\\n` +\n `<b>Workspace:</b> <code>${escapeHtml(record.workingDir)}</code>`,\n { parse_mode: \"HTML\" },\n );\n } else {\n await ctx.reply(\"No active session in this topic.\", {\n parse_mode: \"HTML\",\n });\n }\n }\n } else {\n const sessions = core.sessionManager.listSessions(\"telegram\");\n const active = sessions.filter(\n (s) => s.status === \"active\" || s.status === \"initializing\",\n );\n await ctx.reply(\n `<b>OpenACP Status</b>\\n` +\n `Active sessions: ${active.length}\\n` +\n `Total sessions: ${sessions.length}`,\n { parse_mode: \"HTML\" },\n );\n }\n}\n\nexport async function handleTopics(ctx: Context, core: OpenACPCore): Promise<void> {\n try {\n const allRecords = core.sessionManager.listRecords();\n\n // Only show sessions that have a Telegram topic (skip headless/CLI-only)\n const records = allRecords.filter((r) => {\n const platform = r.platform as { topicId?: number };\n return !!platform?.topicId;\n });\n\n const headlessCount = allRecords.length - records.length;\n\n if (records.length === 0) {\n const extra = headlessCount > 0 ? ` (${headlessCount} headless hidden)` : \"\";\n await ctx.reply(`No sessions with topics found.${extra}`, { parse_mode: \"HTML\" });\n return;\n }\n\n const statusEmoji: Record<string, string> = {\n active: \"🟢\",\n initializing: \"🟡\",\n finished: \"✅\",\n error: \"❌\",\n cancelled: \"⛔\",\n };\n\n // Sort: active/initializing first, then by lastActiveAt desc\n const statusOrder: Record<string, number> = { active: 0, initializing: 1, error: 2, finished: 3, cancelled: 4 };\n records.sort((a, b) => (statusOrder[a.status] ?? 5) - (statusOrder[b.status] ?? 5));\n\n const MAX_DISPLAY = 30;\n const displayed = records.slice(0, MAX_DISPLAY);\n\n const lines = displayed.map((r) => {\n const emoji = statusEmoji[r.status] || \"⚪\";\n const name = r.name?.trim();\n const label = name ? escapeHtml(name) : `<i>${escapeHtml(r.agentName)} session</i>`;\n return `${emoji} ${label} <code>[${r.status}]</code>`;\n });\n\n const header = `<b>Sessions: ${records.length}</b>` +\n (headlessCount > 0 ? ` (${headlessCount} headless hidden)` : \"\");\n const truncated = records.length > MAX_DISPLAY ? `\\n\\n<i>...and ${records.length - MAX_DISPLAY} more</i>` : \"\";\n\n // Count by status for cleanup buttons (include headless sessions)\n const finishedCount = allRecords.filter((r) => r.status === \"finished\").length;\n const errorCount = allRecords.filter((r) => r.status === \"error\" || r.status === \"cancelled\").length;\n\n const keyboard = new InlineKeyboard();\n if (finishedCount > 0) {\n keyboard.text(`Cleanup finished (${finishedCount})`, \"m:cleanup:finished\").row();\n }\n if (errorCount > 0) {\n keyboard.text(`Cleanup errors (${errorCount})`, \"m:cleanup:errors\").row();\n }\n if (finishedCount + errorCount > 0) {\n keyboard.text(`Cleanup all non-active (${finishedCount + errorCount})`, \"m:cleanup:all\").row();\n }\n keyboard.text(`⚠️ Cleanup ALL (${allRecords.length})`, \"m:cleanup:everything\").row();\n keyboard.text(\"Refresh\", \"m:topics\");\n\n await ctx.reply(\n `${header}\\n\\n${lines.join(\"\\n\")}${truncated}`,\n { parse_mode: \"HTML\", reply_markup: keyboard },\n );\n } catch (err) {\n log.error({ err }, \"handleTopics error\");\n await ctx.reply(\"❌ Failed to list sessions.\", { parse_mode: \"HTML\" }).catch(() => {});\n }\n}\n\nexport async function handleCleanup(ctx: Context, core: OpenACPCore, chatId: number, statuses: string[]): Promise<void> {\n const allRecords = core.sessionManager.listRecords();\n const cleanable = allRecords.filter((r) => statuses.includes(r.status));\n\n if (cleanable.length === 0) {\n await ctx.reply(\"Nothing to clean up.\", { parse_mode: \"HTML\" });\n return;\n }\n\n let deleted = 0;\n let failed = 0;\n\n for (const record of cleanable) {\n try {\n const topicId = (record.platform as { topicId?: number })?.topicId;\n if (topicId) {\n try {\n await ctx.api.deleteForumTopic(chatId, topicId);\n } catch (err) {\n log.warn({ err, sessionId: record.sessionId, topicId }, \"Failed to delete forum topic during cleanup\");\n }\n }\n await core.sessionManager.removeRecord(record.sessionId);\n deleted++;\n } catch (err) {\n log.error({ err, sessionId: record.sessionId }, \"Failed to cleanup session\");\n failed++;\n }\n }\n\n await ctx.reply(\n `🗑 Cleaned up <b>${deleted}</b> sessions${failed > 0 ? ` (${failed} failed)` : \"\"}.`,\n { parse_mode: \"HTML\" },\n );\n}\n\nexport async function handleCleanupEverything(\n ctx: Context,\n core: OpenACPCore,\n chatId: number,\n systemTopicIds?: { notificationTopicId: number; assistantTopicId: number },\n): Promise<void> {\n const allRecords = core.sessionManager.listRecords();\n const cleanable = allRecords.filter((r) => {\n const platform = r.platform as { topicId?: number };\n if (systemTopicIds && platform?.topicId && (platform.topicId === systemTopicIds.notificationTopicId || platform.topicId === systemTopicIds.assistantTopicId)) return false;\n return true;\n });\n\n if (cleanable.length === 0) {\n await ctx.reply(\"Nothing to clean up.\", { parse_mode: \"HTML\" });\n return;\n }\n\n // Group by status for breakdown\n const statusCounts = new Map<string, number>();\n for (const r of cleanable) {\n statusCounts.set(r.status, (statusCounts.get(r.status) ?? 0) + 1);\n }\n\n const statusEmoji: Record<string, string> = {\n active: \"🟢\", initializing: \"🟡\", finished: \"✅\", error: \"❌\", cancelled: \"⛔\",\n };\n\n const breakdown = Array.from(statusCounts.entries())\n .map(([status, count]) => `${statusEmoji[status] ?? \"⚪\"} ${status}: ${count}`)\n .join(\"\\n\");\n\n const activeCount = (statusCounts.get(\"active\") ?? 0) + (statusCounts.get(\"initializing\") ?? 0);\n const activeWarning = activeCount > 0\n ? `\\n\\n⚠️ <b>${activeCount} active session(s) will be cancelled and their agents stopped!</b>`\n : \"\";\n\n const keyboard = new InlineKeyboard()\n .text(\"Yes, delete all\", \"m:cleanup:everything:confirm\")\n .text(\"Cancel\", \"m:topics\");\n\n await ctx.reply(\n `<b>Delete ${cleanable.length} topics?</b>\\n\\n` +\n `This will:\\n` +\n `• Delete all session topics from this group\\n` +\n `• Cancel any running agent sessions\\n` +\n `• Remove all session records\\n\\n` +\n `<b>Breakdown:</b>\\n${breakdown}${activeWarning}\\n\\n` +\n `<i>Notifications and Assistant topics will NOT be deleted.</i>`,\n { parse_mode: \"HTML\", reply_markup: keyboard },\n );\n}\n\nexport async function handleCleanupEverythingConfirmed(\n ctx: Context,\n core: OpenACPCore,\n chatId: number,\n systemTopicIds?: { notificationTopicId: number; assistantTopicId: number },\n): Promise<void> {\n const allRecords = core.sessionManager.listRecords();\n const cleanable = allRecords.filter((r) => {\n const platform = r.platform as { topicId?: number };\n if (systemTopicIds && platform?.topicId && (platform.topicId === systemTopicIds.notificationTopicId || platform.topicId === systemTopicIds.assistantTopicId)) return false;\n return true;\n });\n\n if (cleanable.length === 0) {\n await ctx.reply(\"Nothing to clean up.\", { parse_mode: \"HTML\" });\n return;\n }\n\n let deleted = 0;\n let failed = 0;\n\n for (const record of cleanable) {\n try {\n // Cancel active sessions first\n if (record.status === \"active\" || record.status === \"initializing\") {\n try {\n await core.sessionManager.cancelSession(record.sessionId);\n } catch (err) {\n log.warn({ err, sessionId: record.sessionId }, \"Failed to cancel session during cleanup\");\n }\n }\n\n const topicId = (record.platform as { topicId?: number })?.topicId;\n if (topicId) {\n try {\n await ctx.api.deleteForumTopic(chatId, topicId);\n } catch (err) {\n log.warn({ err, sessionId: record.sessionId, topicId }, \"Failed to delete forum topic during cleanup\");\n }\n }\n await core.sessionManager.removeRecord(record.sessionId);\n deleted++;\n } catch (err) {\n log.error({ err, sessionId: record.sessionId }, \"Failed to cleanup session\");\n failed++;\n }\n }\n\n await ctx.reply(\n `🗑 Cleaned up <b>${deleted}</b> sessions${failed > 0 ? ` (${failed} failed)` : \"\"}.`,\n { parse_mode: \"HTML\" },\n );\n}\n\nexport async function executeCancelSession(\n core: OpenACPCore,\n excludeSessionId?: string,\n): Promise<Session | null> {\n const sessions = core.sessionManager\n .listSessions(\"telegram\")\n .filter((s) => s.status === \"active\" && s.id !== excludeSessionId)\n .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());\n\n const session = sessions[0];\n if (!session) return null;\n\n await session.abortPrompt();\n return session;\n}\n\nexport function setupSessionCallbacks(\n bot: Bot,\n core: OpenACPCore,\n chatId: number,\n systemTopicIds?: { notificationTopicId: number; assistantTopicId: number },\n): void {\n bot.callbackQuery(/^m:cleanup/, async (ctx) => {\n const data = ctx.callbackQuery.data;\n try {\n await ctx.answerCallbackQuery();\n } catch { /* expired */ }\n\n switch (data) {\n case \"m:cleanup:finished\":\n await handleCleanup(ctx, core, chatId, [\"finished\"]);\n break;\n case \"m:cleanup:errors\":\n await handleCleanup(ctx, core, chatId, [\"error\", \"cancelled\"]);\n break;\n case \"m:cleanup:all\":\n await handleCleanup(ctx, core, chatId, [\"finished\", \"error\", \"cancelled\"]);\n break;\n case \"m:cleanup:everything\":\n await handleCleanupEverything(ctx, core, chatId, systemTopicIds);\n break;\n case \"m:cleanup:everything:confirm\":\n await handleCleanupEverythingConfirmed(ctx, core, chatId, systemTopicIds);\n break;\n }\n });\n}\n\nexport async function handleArchive(\n ctx: Context,\n core: OpenACPCore,\n): Promise<void> {\n const threadId = ctx.message?.message_thread_id;\n if (!threadId) return;\n\n // Check in-memory session first, then fall back to stored record\n const session = core.sessionManager.getSessionByThread(\"telegram\", String(threadId));\n const record = !session ? core.sessionManager.getRecordByThread(\"telegram\", String(threadId)) : undefined;\n\n // Must be used in a session topic (not orphan or non-session)\n if (!session && !record) {\n await ctx.reply(\"This topic is not linked to a session.\", { parse_mode: \"HTML\" });\n return;\n }\n\n const identifier = session?.id ?? record?.sessionId;\n if (!identifier) {\n await ctx.reply(\"Could not determine session for this topic.\", { parse_mode: \"HTML\" });\n return;\n }\n\n // Session must be active (not initializing)\n const status = session?.status ?? record?.status;\n if (status === \"initializing\") {\n await ctx.reply(\"Cannot archive a session that is still initializing. Wait for it to become active.\", { parse_mode: \"HTML\" });\n return;\n }\n\n await ctx.reply(\n \"⚠️ <b>Archive this session?</b>\\n\\n\" +\n \"This will:\\n\" +\n \"• Delete this topic and recreate it (clearing chat history)\\n\" +\n \"• The agent session will keep running\\n\\n\" +\n \"<i>Chat history cannot be recovered.</i>\",\n {\n parse_mode: \"HTML\",\n reply_markup: new InlineKeyboard()\n .text(\"🗑 Yes, archive\", `ar:yes:${identifier}`)\n .text(\"❌ Cancel\", `ar:no:${identifier}`),\n },\n );\n}\n\nexport async function handleArchiveConfirm(\n ctx: Context,\n core: OpenACPCore,\n chatId: number,\n): Promise<void> {\n const data = ctx.callbackQuery?.data;\n if (!data) return;\n\n try {\n await ctx.answerCallbackQuery();\n } catch { /* expired */ }\n\n // Format: ar:<action>:<identifier> where identifier is sessionId\n const [, action, ...rest] = data.split(\":\");\n const identifier = rest.join(\":\");\n\n if (action === \"no\") {\n await ctx.editMessageText(\"Archive cancelled.\", { parse_mode: \"HTML\" });\n return;\n }\n\n // action === \"yes\"\n // Note: we don't editMessageText here because the topic is about to be deleted\n\n const result = await core.archiveSession(identifier);\n if (result.ok) {\n // Send confirmation in the new topic\n const adapter = core.adapters.get(\"telegram\");\n if (adapter) {\n try {\n await adapter.sendMessage(identifier, {\n type: \"text\",\n text: \"Chat history cleared. Session is still active — send a message to continue.\",\n });\n } catch {\n // Best effort — the new topic is already created\n }\n }\n } else {\n try {\n await ctx.editMessageText(`Failed to archive: <code>${escapeHtml(result.error)}</code>`, { parse_mode: \"HTML\" });\n } catch {\n core.notificationManager.notifyAll({\n sessionId: identifier,\n type: \"error\",\n summary: `Failed to archive session \"${identifier}\": ${result.error}`,\n });\n }\n }\n}\n\n","import type { Context } from \"grammy\";\nimport { InlineKeyboard } from \"grammy\";\nimport type { AgentCommand } from \"../../../core/index.js\";\nimport type { CommandsAssistantContext } from \"../types.js\";\n\nexport function buildMenuKeyboard(): InlineKeyboard {\n return new InlineKeyboard()\n .text(\"🆕 New Session\", \"m:new\")\n .text(\"📋 Sessions\", \"m:topics\")\n .row()\n .text(\"📊 Status\", \"m:status\")\n .text(\"🤖 Agents\", \"m:agents\")\n .row()\n .text(\"⚙️ Settings\", \"m:settings\")\n .text(\"🔗 Integrate\", \"m:integrate\")\n .row()\n .text(\"🔄 Restart\", \"m:restart\")\n .text(\"⬆️ Update\", \"m:update\")\n .row()\n .text(\"❓ Help\", \"m:help\")\n .text(\"🩺 Doctor\", \"m:doctor\");\n}\n\nexport async function handleMenu(ctx: Context): Promise<void> {\n await ctx.reply(`<b>OpenACP Menu</b>\\nChoose an action:`, {\n parse_mode: \"HTML\",\n reply_markup: buildMenuKeyboard(),\n });\n}\n\nexport async function handleHelp(ctx: Context): Promise<void> {\n await ctx.reply(\n `📖 <b>OpenACP Help</b>\\n\\n` +\n `🚀 <b>Getting Started</b>\\n` +\n `Tap 🆕 New Session to start coding with AI.\\n` +\n `Each session gets its own topic — chat there to work with the agent.\\n\\n` +\n `💡 <b>Common Tasks</b>\\n` +\n `/new [agent] [workspace] — Create new session\\n` +\n `/cancel — Cancel session (in session topic)\\n` +\n `/status — Show session or system status\\n` +\n `/sessions — List all sessions\\n` +\n `/agents — Browse & install agents\\n` +\n `/install <name> — Install an agent\\n\\n` +\n `⚙️ <b>System</b>\\n` +\n `/restart — Restart OpenACP\\n` +\n `/update — Update to latest version\\n` +\n `/integrate — Manage agent integrations\\n` +\n `/menu — Show action menu\\n\\n` +\n `🔒 <b>Session Options</b>\\n` +\n `/enable_dangerous — Auto-approve permissions\\n` +\n `/disable_dangerous — Restore permission prompts\\n` +\n `/handoff — Continue session in terminal\\n` +\n `/archive — Archive session topic\\n` +\n `/clear — Clear assistant history\\n\\n` +\n `💬 Need help? Just ask me in this topic!`,\n { parse_mode: \"HTML\" },\n );\n}\n\nexport async function handleClear(ctx: Context, assistant?: CommandsAssistantContext): Promise<void> {\n if (!assistant) {\n await ctx.reply(\"⚠️ Assistant is not available.\", { parse_mode: \"HTML\" });\n return;\n }\n\n const threadId = ctx.message?.message_thread_id;\n if (threadId !== assistant.topicId) {\n await ctx.reply(\"ℹ️ /clear only works in the Assistant topic.\", { parse_mode: \"HTML\" });\n return;\n }\n\n await ctx.reply(\"🔄 Clearing assistant history...\", { parse_mode: \"HTML\" });\n\n try {\n await assistant.respawn();\n await ctx.reply(\"✅ Assistant history cleared.\", { parse_mode: \"HTML\" });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await ctx.reply(`❌ Failed to clear: <code>${message}</code>`, { parse_mode: \"HTML\" });\n }\n}\n\nconst TELEGRAM_MSG_LIMIT = 4096;\n\n/**\n * Build plain-text skill command messages. Each command is on its own line\n * wrapped in <code> for tap-to-copy. If the list exceeds Telegram's message\n * limit, it is split into multiple messages (cut at line boundaries).\n */\nexport function buildSkillMessages(commands: AgentCommand[]): string[] {\n const sorted = [...commands].sort((a, b) => a.name.localeCompare(b.name));\n const header = \"🛠 <b>Available Skills</b>\\n\";\n const lines = sorted.map((c) => `<code>/${c.name}</code>`);\n\n const messages: string[] = [];\n let current = header;\n\n for (const line of lines) {\n const candidate = current + \"\\n\" + line;\n if (candidate.length > TELEGRAM_MSG_LIMIT) {\n messages.push(current);\n current = line;\n } else {\n current = candidate;\n }\n }\n if (current) messages.push(current);\n return messages;\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, chmodSync, rmdirSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { getAgentCapabilities, commandExists, listAgentsWithIntegration } from \"../core/agents/agent-dependencies.js\";\nimport type { AgentIntegrationSpec } from \"../core/agents/agent-dependencies.js\";\n\nexport interface IntegrationResult {\n success: boolean;\n logs: string[];\n}\n\nexport interface IntegrationItem {\n id: string;\n name: string;\n description: string;\n isInstalled(): boolean;\n install(): Promise<IntegrationResult>;\n uninstall(): Promise<IntegrationResult>;\n}\n\nexport interface AgentIntegration {\n items: IntegrationItem[];\n}\n\nconst HOOK_MARKER = \"openacp-inject-session.sh\";\n\nfunction expandPath(p: string): string {\n return p.replace(/^~/, homedir());\n}\n\n// --- Script generators ---\n\nfunction generateInjectScript(_agentKey: string, spec: AgentIntegrationSpec): string {\n const sidVar = spec.sessionIdVar ?? \"SESSION_ID\";\n const cwdVar = spec.workingDirVar ?? \"WORKING_DIR\";\n\n // Resolve jq: check ~/.openacp/bin first, then PATH\n const jqResolver = `JQ=$(command -v jq 2>/dev/null || echo \"$HOME/.openacp/bin/jq\")`;\n\n if (spec.outputFormat === \"plaintext\") {\n return `#!/bin/bash\n${jqResolver}\nINPUT=$(cat)\nSESSION_ID=$(echo \"$INPUT\" | \"$JQ\" -r '${spec.sessionIdField}')\nCWD=$(echo \"$INPUT\" | \"$JQ\" -r '.cwd')\n\necho \"${sidVar}: $SESSION_ID\"\necho \"${cwdVar}: $CWD\"\n\nexit 0\n`;\n }\n\n // JSON output (Gemini, Cline, Cursor)\n return `#!/bin/bash\n${jqResolver}\nINPUT=$(cat)\nSESSION_ID=$(echo \"$INPUT\" | \"$JQ\" -r '${spec.sessionIdField}')\nCWD=$(echo \"$INPUT\" | \"$JQ\" -r '.cwd')\n\n\"$JQ\" -n --arg sid \"$SESSION_ID\" --arg cwd \"$CWD\" \\\\\n '{\"additionalContext\":\"${sidVar}: \\\\($sid)\\\\n${cwdVar}: \\\\($cwd)\"}'\n\nexit 0\n`;\n}\n\nfunction generateHandoffScript(agentKey: string): string {\n return `#!/bin/bash\nSESSION_ID=$1\nCWD=$2\nCHANNEL=$3\n\nif [ -z \"$SESSION_ID\" ]; then\n echo \"Usage: openacp-handoff.sh <session_id> [cwd] [channel]\"\n exit 1\nfi\n\nopenacp adopt ${agentKey} \"$SESSION_ID\" \\${CWD:+--cwd \"$CWD\"} \\${CHANNEL:+--channel \"$CHANNEL\"}\n`;\n}\n\nfunction generateTunnelCommand(): string {\n return `---\ndescription: Expose local ports to the internet. Use when user wants to share, preview, or access their local dev server remotely. Triggers on phrases like \"expose port\", \"map port\", \"share my app\", \"make it public\", \"open tunnel\", \"public URL\", \"share localhost\", \"preview on phone\", \"access from outside\", \"forward port\", \"ngrok\", \"cloudflare tunnel\", etc.\n---\n\nYou have access to OpenACP tunnel management via CLI. This creates a public URL for any local port (dev servers, APIs, static sites, etc.) using Cloudflare tunnel.\n\n## Commands\n\n\\`\\`\\`bash\n# Create a tunnel — exposes local port to the internet\nopenacp tunnel add <port> --label <name>\n\n# List all active tunnels with their public URLs\nopenacp tunnel list\n\n# Stop a specific tunnel\nopenacp tunnel stop <port>\n\n# Stop all tunnels\nopenacp tunnel stop-all\n\\`\\`\\`\n\n## When to use\n\nUser wants to:\n- **Share their local app** — \"share this on my phone\", \"let my friend see this\", \"preview on mobile\"\n- **Expose a port** — \"expose port 3000\", \"map port 5173\", \"make port 8080 public\"\n- **Get a public URL** — \"give me a public URL\", \"I need an external link\", \"make localhost accessible\"\n- **Open a tunnel** — \"open tunnel\", \"start tunnel\", \"tunnel this\"\n- **Forward/proxy a port** — \"forward port 3000\", \"proxy my server\"\n- **Deploy preview** — \"deploy preview\", \"share a preview link\"\n- **Access remotely** — \"access from my phone\", \"access from outside\"\n- **Manage tunnels** — \"show tunnels\", \"list tunnels\", \"stop tunnel\", \"close tunnel\", \"kill tunnel\"\n\n## How to respond\n\n1. Run the CLI command\n2. Share the public URL with the user\n3. Mention the URL works on any device (phone, tablet, other computer)\n4. If the user hasn't started a dev server yet, remind them to start one first\n\n## Example flow\n\nUser: \"I want to see this React app on my phone\"\n→ Check if dev server is running (e.g. port 5173 for Vite)\n→ Run: \\`openacp tunnel add 5173 --label react-app\\`\n→ Share the public URL\n`;\n}\n\nfunction generateHandoffCommand(_agentKey: string, spec: AgentIntegrationSpec): string {\n const sidVar = spec.sessionIdVar ?? \"SESSION_ID\";\n const cwdVar = spec.workingDirVar ?? \"WORKING_DIR\";\n const hooksDir = expandPath(spec.hooksDirPath);\n\n return `---\ndescription: Transfer current session to OpenACP (Telegram/Discord)\n---\n\nLook at the context injected at the start of this message to find\n${sidVar} and ${cwdVar}, then run:\n\nbash ${hooksDir}openacp-handoff.sh <${sidVar}> <${cwdVar}> <args if any>\n\nUsage: /openacp:handoff [channel]\n channel: name of a registered adapter (e.g. telegram), or omit for default\n\nExamples:\n /openacp:handoff\n /openacp:handoff telegram\n`;\n}\n\n// --- Settings mergers ---\n\nfunction mergeSettingsJson(settingsPath: string, hookEvent: string, hookScriptPath: string): void {\n const fullPath = expandPath(settingsPath);\n let settings: Record<string, unknown> = {};\n\n if (existsSync(fullPath)) {\n const raw = readFileSync(fullPath, \"utf-8\");\n writeFileSync(`${fullPath}.bak`, raw);\n settings = JSON.parse(raw);\n }\n\n const hooks = (settings.hooks ?? {}) as Record<string, unknown[]>;\n settings.hooks = hooks;\n\n const eventHooks = (hooks[hookEvent] ?? []) as Array<{ hooks?: Array<{ type?: string; command?: string }> }>;\n hooks[hookEvent] = eventHooks;\n\n const alreadyInstalled = eventHooks.some((group) =>\n group.hooks?.some((h) => h.command?.includes(HOOK_MARKER)),\n );\n\n if (!alreadyInstalled) {\n eventHooks.push({\n hooks: [{ type: \"command\", command: hookScriptPath }],\n });\n }\n\n mkdirSync(dirname(fullPath), { recursive: true });\n writeFileSync(fullPath, JSON.stringify(settings, null, 2) + \"\\n\");\n}\n\nfunction mergeHooksJson(settingsPath: string, hookEvent: string, hookScriptPath: string): void {\n const fullPath = expandPath(settingsPath);\n let config: Record<string, unknown> = { version: 1 };\n\n if (existsSync(fullPath)) {\n const raw = readFileSync(fullPath, \"utf-8\");\n writeFileSync(`${fullPath}.bak`, raw);\n config = JSON.parse(raw);\n }\n\n const hooks = (config.hooks ?? {}) as Record<string, unknown[]>;\n config.hooks = hooks;\n\n const eventHooks = (hooks[hookEvent] ?? []) as Array<{ command?: string }>;\n hooks[hookEvent] = eventHooks;\n\n const alreadyInstalled = eventHooks.some((h) => h.command?.includes(HOOK_MARKER));\n\n if (!alreadyInstalled) {\n eventHooks.push({ command: hookScriptPath });\n }\n\n mkdirSync(dirname(fullPath), { recursive: true });\n writeFileSync(fullPath, JSON.stringify(config, null, 2) + \"\\n\");\n}\n\nfunction removeFromSettingsJson(settingsPath: string, hookEvent: string): void {\n const fullPath = expandPath(settingsPath);\n if (!existsSync(fullPath)) return;\n\n const raw = readFileSync(fullPath, \"utf-8\");\n const settings = JSON.parse(raw);\n const hooks = settings.hooks as Record<string, unknown[]> | undefined;\n if (!hooks?.[hookEvent]) return;\n\n hooks[hookEvent] = (hooks[hookEvent] as Array<{ hooks?: Array<{ command?: string }> }>).filter(\n (group) => !group.hooks?.some((h) => h.command?.includes(\"openacp-\")),\n );\n\n if ((hooks[hookEvent] as unknown[]).length === 0) {\n delete hooks[hookEvent];\n }\n\n writeFileSync(fullPath, JSON.stringify(settings, null, 2) + \"\\n\");\n}\n\nfunction removeFromHooksJson(settingsPath: string, hookEvent: string): void {\n const fullPath = expandPath(settingsPath);\n if (!existsSync(fullPath)) return;\n\n const raw = readFileSync(fullPath, \"utf-8\");\n const config = JSON.parse(raw);\n const hooks = config.hooks as Record<string, unknown[]> | undefined;\n if (!hooks?.[hookEvent]) return;\n\n hooks[hookEvent] = (hooks[hookEvent] as Array<{ command?: string }>).filter(\n (h) => !h.command?.includes(\"openacp-\"),\n );\n\n if ((hooks[hookEvent] as unknown[]).length === 0) {\n delete hooks[hookEvent];\n }\n\n writeFileSync(fullPath, JSON.stringify(config, null, 2) + \"\\n\");\n}\n\n// --- Core install/uninstall ---\n\nexport async function installIntegration(agentKey: string, spec: AgentIntegrationSpec): Promise<IntegrationResult> {\n const logs: string[] = [];\n try {\n // Check jq\n if (!commandExists(\"jq\")) {\n return {\n success: false,\n logs: [\"jq is required for handoff hooks. Install: brew install jq (macOS) or apt install jq (Linux)\"],\n };\n }\n\n const hooksDir = expandPath(spec.hooksDirPath);\n mkdirSync(hooksDir, { recursive: true });\n\n // Inject script\n const injectPath = join(hooksDir, \"openacp-inject-session.sh\");\n writeFileSync(injectPath, generateInjectScript(agentKey, spec));\n chmodSync(injectPath, 0o755);\n logs.push(`Created ${injectPath}`);\n\n // Handoff script\n const handoffPath = join(hooksDir, \"openacp-handoff.sh\");\n writeFileSync(handoffPath, generateHandoffScript(agentKey));\n chmodSync(handoffPath, 0o755);\n logs.push(`Created ${handoffPath}`);\n\n // Slash command / skill\n if (spec.commandsPath && spec.handoffCommandName) {\n if (spec.commandFormat === \"skill\") {\n const skillDir = expandPath(join(spec.commandsPath, spec.handoffCommandName));\n mkdirSync(skillDir, { recursive: true });\n const skillPath = join(skillDir, \"SKILL.md\");\n writeFileSync(skillPath, generateHandoffCommand(agentKey, spec));\n logs.push(`Created ${skillPath}`);\n } else {\n const cmdsDir = expandPath(spec.commandsPath);\n mkdirSync(cmdsDir, { recursive: true });\n const cmdPath = join(cmdsDir, `${spec.handoffCommandName}.md`);\n writeFileSync(cmdPath, generateHandoffCommand(agentKey, spec));\n logs.push(`Created ${cmdPath}`);\n }\n }\n\n // Merge settings\n const injectFullPath = join(hooksDir, \"openacp-inject-session.sh\");\n if (spec.settingsFormat === \"hooks_json\") {\n mergeHooksJson(spec.settingsPath, spec.hookEvent, injectFullPath);\n } else {\n mergeSettingsJson(spec.settingsPath, spec.hookEvent, injectFullPath);\n }\n logs.push(`Updated ${expandPath(spec.settingsPath)}`);\n\n return { success: true, logs };\n } catch (err) {\n logs.push(`Error: ${err instanceof Error ? err.message : String(err)}`);\n return { success: false, logs };\n }\n}\n\nexport async function uninstallIntegration(agentKey: string, spec: AgentIntegrationSpec): Promise<IntegrationResult> {\n const logs: string[] = [];\n try {\n const hooksDir = expandPath(spec.hooksDirPath);\n\n // Remove hook scripts\n for (const filename of [\"openacp-inject-session.sh\", \"openacp-handoff.sh\"]) {\n const filePath = join(hooksDir, filename);\n if (existsSync(filePath)) {\n unlinkSync(filePath);\n logs.push(`Removed ${filePath}`);\n }\n }\n\n // Remove slash command / skill\n if (spec.commandsPath && spec.handoffCommandName) {\n if (spec.commandFormat === \"skill\") {\n const skillDir = expandPath(join(spec.commandsPath, spec.handoffCommandName));\n const skillPath = join(skillDir, \"SKILL.md\");\n if (existsSync(skillPath)) {\n unlinkSync(skillPath);\n try { rmdirSync(skillDir); } catch { /* not empty */ }\n logs.push(`Removed ${skillPath}`);\n }\n } else {\n const cmdPath = expandPath(join(spec.commandsPath, `${spec.handoffCommandName}.md`));\n if (existsSync(cmdPath)) {\n unlinkSync(cmdPath);\n logs.push(`Removed ${cmdPath}`);\n }\n }\n }\n\n // Clean settings\n if (spec.settingsFormat === \"hooks_json\") {\n removeFromHooksJson(spec.settingsPath, spec.hookEvent);\n } else {\n removeFromSettingsJson(spec.settingsPath, spec.hookEvent);\n }\n logs.push(`Updated ${expandPath(spec.settingsPath)}`);\n\n return { success: true, logs };\n } catch (err) {\n logs.push(`Error: ${err instanceof Error ? err.message : String(err)}`);\n return { success: false, logs };\n }\n}\n\n// --- Public API (backward compat with existing cmdIntegrate / Telegram integrate) ---\n\nfunction buildHandoffItem(agentKey: string, spec: AgentIntegrationSpec): IntegrationItem {\n const hooksDir = expandPath(spec.hooksDirPath);\n return {\n id: \"handoff\",\n name: \"Handoff\",\n description: \"Transfer sessions between terminal and messaging platforms\",\n isInstalled(): boolean {\n return (\n existsSync(join(hooksDir, \"openacp-inject-session.sh\")) &&\n existsSync(join(hooksDir, \"openacp-handoff.sh\"))\n );\n },\n install: () => installIntegration(agentKey, spec),\n uninstall: () => uninstallIntegration(agentKey, spec),\n };\n}\n\nfunction getSkillBasePath(spec: AgentIntegrationSpec): string {\n // Skills go into the agent's skills directory (sibling to commands)\n // Claude: ~/.claude/skills/, Cursor: ~/.cursor/skills/\n const base = spec.commandsPath!;\n // If commandsPath is commands/, use skills/ instead\n const skillsBase = base.replace(/\\/commands\\/?$/, \"/skills/\");\n return expandPath(skillsBase);\n}\n\nfunction buildTunnelItem(spec: AgentIntegrationSpec): IntegrationItem | null {\n if (!spec.commandsPath) return null;\n\n function getTunnelPath(): string {\n return join(getSkillBasePath(spec), \"openacp-tunnel\", \"SKILL.md\");\n }\n\n return {\n id: \"tunnel\",\n name: \"Tunnel\",\n description: \"Expose local ports to the internet via OpenACP tunnel\",\n isInstalled(): boolean {\n return existsSync(getTunnelPath());\n },\n async install(): Promise<IntegrationResult> {\n const logs: string[] = [];\n try {\n const skillPath = getTunnelPath();\n mkdirSync(dirname(skillPath), { recursive: true });\n writeFileSync(skillPath, generateTunnelCommand());\n logs.push(`Created ${skillPath}`);\n return { success: true, logs };\n } catch (err) {\n logs.push(`Error: ${err instanceof Error ? err.message : String(err)}`);\n return { success: false, logs };\n }\n },\n async uninstall(): Promise<IntegrationResult> {\n const logs: string[] = [];\n try {\n const skillPath = getTunnelPath();\n if (existsSync(skillPath)) {\n unlinkSync(skillPath);\n try { rmdirSync(dirname(skillPath)); } catch { /* not empty */ }\n logs.push(`Removed ${skillPath}`);\n }\n return { success: true, logs };\n } catch (err) {\n logs.push(`Error: ${err instanceof Error ? err.message : String(err)}`);\n return { success: false, logs };\n }\n },\n };\n}\n\nexport function getIntegration(agentName: string): AgentIntegration | undefined {\n const caps = getAgentCapabilities(agentName);\n if (!caps.integration) return undefined;\n const items: IntegrationItem[] = [buildHandoffItem(agentName, caps.integration)];\n const tunnelItem = buildTunnelItem(caps.integration);\n if (tunnelItem) items.push(tunnelItem);\n return { items };\n}\n\nexport function listIntegrations(): string[] {\n return listAgentsWithIntegration();\n}\n","import type { Context } from \"grammy\";\nimport { InlineKeyboard } from \"grammy\";\nimport type { OpenACPCore } from \"../../../core/core.js\";\nimport type { InstallProgress } from \"../../../core/types.js\";\nimport { escapeHtml } from \"../formatting.js\";\n\nconst AGENTS_PER_PAGE = 6;\n\nexport async function handleAgents(ctx: Context, core: OpenACPCore, page = 0): Promise<void> {\n const catalog = core.agentCatalog;\n const items = catalog.getAvailable();\n\n const installed = items.filter((i) => i.installed);\n const available = items.filter((i) => !i.installed);\n\n let text = \"<b>🤖 Agents</b>\\n\\n\";\n\n // Installed agents section\n if (installed.length > 0) {\n text += \"<b>Installed:</b>\\n\";\n for (const item of installed) {\n text += `✅ <b>${escapeHtml(item.name)}</b>`;\n if (item.description) {\n text += ` — <i>${escapeHtml(truncate(item.description, 50))}</i>`;\n }\n text += \"\\n\";\n }\n text += \"\\n\";\n }\n\n // Available agents section (paginated)\n if (available.length > 0) {\n const totalPages = Math.ceil(available.length / AGENTS_PER_PAGE);\n const safePage = Math.max(0, Math.min(page, totalPages - 1));\n const pageItems = available.slice(safePage * AGENTS_PER_PAGE, (safePage + 1) * AGENTS_PER_PAGE);\n\n text += `<b>Available to install:</b>`;\n if (totalPages > 1) {\n text += ` (${safePage + 1}/${totalPages})`;\n }\n text += \"\\n\";\n\n for (const item of pageItems) {\n if (item.available) {\n text += `⬇️ <b>${escapeHtml(item.name)}</b>`;\n } else {\n const deps = item.missingDeps?.join(\", \") ?? \"requirements not met\";\n text += `⚠️ <b>${escapeHtml(item.name)}</b> <i>(needs: ${escapeHtml(deps)})</i>`;\n }\n if (item.description) {\n text += `\\n <i>${escapeHtml(truncate(item.description, 60))}</i>`;\n }\n text += \"\\n\";\n }\n\n // Install buttons for current page\n const keyboard = new InlineKeyboard();\n const installable = pageItems.filter((i) => i.available);\n for (let i = 0; i < installable.length; i += 2) {\n const row = installable.slice(i, i + 2);\n for (const item of row) {\n keyboard.text(`⬇️ ${item.name}`, `ag:install:${item.key}`);\n }\n keyboard.row();\n }\n\n // Pagination buttons\n if (totalPages > 1) {\n if (safePage > 0) {\n keyboard.text(\"◀️ Prev\", `ag:page:${safePage - 1}`);\n }\n if (safePage < totalPages - 1) {\n keyboard.text(\"Next ▶️\", `ag:page:${safePage + 1}`);\n }\n keyboard.row();\n }\n\n // Tip for CLI install\n if (available.some((i) => !i.available)) {\n text += \"\\n💡 <i>Agents marked ⚠️ need additional setup. Use</i> <code>openacp agents info &lt;name&gt;</code> <i>for details.</i>\\n\";\n }\n\n await ctx.reply(text, { parse_mode: \"HTML\", reply_markup: keyboard });\n } else {\n text += \"<i>All agents are already installed!</i>\";\n await ctx.reply(text, { parse_mode: \"HTML\" });\n }\n}\n\nexport async function handleInstall(ctx: Context, core: OpenACPCore): Promise<void> {\n const text = (ctx.message?.text ?? \"\").trim();\n const parts = text.split(/\\s+/);\n const nameOrId = parts[1];\n\n if (!nameOrId) {\n await ctx.reply(\n \"📦 <b>Install an agent</b>\\n\\n\" +\n \"Usage: <code>/install &lt;agent-name&gt;</code>\\n\" +\n \"Example: <code>/install gemini</code>\\n\\n\" +\n \"Use /agents to browse available agents.\",\n { parse_mode: \"HTML\" },\n );\n return;\n }\n\n await installAgentWithProgress(ctx, core, nameOrId);\n}\n\nexport async function handleAgentCallback(ctx: Context, core: OpenACPCore): Promise<void> {\n const data = ctx.callbackQuery?.data ?? \"\";\n await ctx.answerCallbackQuery();\n\n if (data.startsWith(\"ag:install:\")) {\n const nameOrId = data.replace(\"ag:install:\", \"\");\n await installAgentWithProgress(ctx, core, nameOrId);\n return;\n }\n\n if (data.startsWith(\"ag:page:\")) {\n const page = parseInt(data.replace(\"ag:page:\", \"\"), 10);\n // Edit the existing message with the new page\n try {\n const catalog = core.agentCatalog;\n const items = catalog.getAvailable();\n const installed = items.filter((i) => i.installed);\n const available = items.filter((i) => !i.installed);\n\n let text = \"<b>🤖 Agents</b>\\n\\n\";\n\n if (installed.length > 0) {\n text += \"<b>Installed:</b>\\n\";\n for (const item of installed) {\n text += `✅ <b>${escapeHtml(item.name)}</b>`;\n if (item.description) {\n text += ` — <i>${escapeHtml(truncate(item.description, 50))}</i>`;\n }\n text += \"\\n\";\n }\n text += \"\\n\";\n }\n\n const totalPages = Math.ceil(available.length / AGENTS_PER_PAGE);\n const safePage = Math.max(0, Math.min(page, totalPages - 1));\n const pageItems = available.slice(safePage * AGENTS_PER_PAGE, (safePage + 1) * AGENTS_PER_PAGE);\n\n text += `<b>Available to install:</b>`;\n if (totalPages > 1) {\n text += ` (${safePage + 1}/${totalPages})`;\n }\n text += \"\\n\";\n\n for (const item of pageItems) {\n if (item.available) {\n text += `⬇️ <b>${escapeHtml(item.name)}</b>`;\n } else {\n const deps = item.missingDeps?.join(\", \") ?? \"requirements not met\";\n text += `⚠️ <b>${escapeHtml(item.name)}</b> <i>(needs: ${escapeHtml(deps)})</i>`;\n }\n if (item.description) {\n text += `\\n <i>${escapeHtml(truncate(item.description, 60))}</i>`;\n }\n text += \"\\n\";\n }\n\n const keyboard = new InlineKeyboard();\n const installable = pageItems.filter((i) => i.available);\n for (let i = 0; i < installable.length; i += 2) {\n const row = installable.slice(i, i + 2);\n for (const item of row) {\n keyboard.text(`⬇️ ${item.name}`, `ag:install:${item.key}`);\n }\n keyboard.row();\n }\n\n if (totalPages > 1) {\n if (safePage > 0) {\n keyboard.text(\"◀️ Prev\", `ag:page:${safePage - 1}`);\n }\n if (safePage < totalPages - 1) {\n keyboard.text(\"Next ▶️\", `ag:page:${safePage + 1}`);\n }\n keyboard.row();\n }\n\n await ctx.editMessageText(text, { parse_mode: \"HTML\", reply_markup: keyboard });\n } catch { /* ignore edit failures */ }\n }\n}\n\nasync function installAgentWithProgress(ctx: Context, core: OpenACPCore, nameOrId: string): Promise<void> {\n const catalog = core.agentCatalog;\n const msg = await ctx.reply(`⏳ Installing <b>${escapeHtml(nameOrId)}</b>...`, { parse_mode: \"HTML\" });\n\n let lastEdit = 0;\n const EDIT_THROTTLE_MS = 1500;\n\n const progress: InstallProgress = {\n onStart(_id, _name) { /* initial message already sent */ },\n async onStep(step) {\n const now = Date.now();\n if (now - lastEdit > EDIT_THROTTLE_MS) {\n lastEdit = now;\n try {\n await ctx.api.editMessageText(msg.chat.id, msg.message_id, `⏳ <b>${escapeHtml(nameOrId)}</b>: ${escapeHtml(step)}`, { parse_mode: \"HTML\" });\n } catch { /* rate limit or unchanged */ }\n }\n },\n async onDownloadProgress(percent) {\n const now = Date.now();\n if (now - lastEdit > EDIT_THROTTLE_MS) {\n lastEdit = now;\n try {\n const bar = buildProgressBar(percent);\n await ctx.api.editMessageText(msg.chat.id, msg.message_id, `⏳ <b>${escapeHtml(nameOrId)}</b>\\nDownloading... ${bar} ${percent}%`, { parse_mode: \"HTML\" });\n } catch { /* rate limit */ }\n }\n },\n async onSuccess(name) {\n try {\n const keyboard = new InlineKeyboard().text(`🚀 Start session with ${name}`, `na:${nameOrId}`);\n await ctx.api.editMessageText(msg.chat.id, msg.message_id, `✅ <b>${escapeHtml(name)}</b> installed!`, { parse_mode: \"HTML\", reply_markup: keyboard });\n } catch { /* ignore */ }\n },\n async onError(error) {\n try {\n await ctx.api.editMessageText(msg.chat.id, msg.message_id, `❌ ${escapeHtml(error)}`, { parse_mode: \"HTML\" });\n } catch { /* ignore */ }\n },\n };\n\n const result = await catalog.install(nameOrId, progress);\n\n // Auto-integrate handoff if agent supports it\n if (result.ok) {\n const { getAgentCapabilities } = await import(\"../../../core/agents/agent-dependencies.js\");\n const caps = getAgentCapabilities(result.agentKey);\n if (caps.integration) {\n const { installIntegration } = await import(\"../../../cli/integrate.js\");\n const intResult = await installIntegration(result.agentKey, caps.integration);\n if (intResult.success) {\n try {\n await ctx.reply(`🔗 Handoff integration installed for <b>${escapeHtml(result.agentKey)}</b>`, { parse_mode: \"HTML\" });\n } catch { /* ignore */ }\n }\n }\n }\n\n // Show setup steps as a follow-up message with copyable commands\n if (result.ok && result.setupSteps?.length) {\n let setupText = `📋 <b>Setup for ${escapeHtml(result.agentKey)}:</b>\\n\\n`;\n for (const step of result.setupSteps) {\n setupText += `→ ${formatSetupStep(step)}\\n`;\n }\n setupText += `\\n💡 <i>Tap any command to copy it</i>`;\n try {\n await ctx.reply(setupText, { parse_mode: \"HTML\" });\n } catch { /* ignore */ }\n }\n}\n\n/**\n * Format a setup step for Telegram, wrapping commands in <code> for tap-to-copy.\n * Patterns handled:\n * \"Install Claude CLI: npm install -g @anthropic-ai/claude-code\"\n * \"Login: claude login (opens browser)\"\n * \"Or set API key: export OPENAI_API_KEY=<your-key>\"\n * \"Free tier: 60 requests/min\" (no command — plain text)\n */\nfunction formatSetupStep(step: string): string {\n const colonIdx = step.indexOf(\": \");\n if (colonIdx === -1) return escapeHtml(step);\n\n const label = step.slice(0, colonIdx);\n const rest = step.slice(colonIdx + 2);\n\n // Check if the part after \":\" looks like a command (starts with known command prefixes)\n const cmdPrefixes = [\n \"npm \", \"npx \", \"pip \", \"uvx \", \"export \", \"claude \", \"codex \",\n \"openacp \", \"goose \", \"gemini \", \"cursor \", \"gh \",\n ];\n const looksLikeCommand = cmdPrefixes.some((p) => rest.startsWith(p));\n\n if (looksLikeCommand) {\n // Split command from parenthetical explanation: \"claude login (opens browser)\"\n const parenIdx = rest.indexOf(\" (\");\n if (parenIdx !== -1) {\n const cmd = rest.slice(0, parenIdx);\n const explanation = rest.slice(parenIdx);\n return `${escapeHtml(label)}: <code>${escapeHtml(cmd)}</code> ${escapeHtml(explanation)}`;\n }\n return `${escapeHtml(label)}: <code>${escapeHtml(rest)}</code>`;\n }\n\n return escapeHtml(step);\n}\n\nfunction truncate(text: string, maxLen: number): string {\n if (text.length <= maxLen) return text;\n return text.slice(0, maxLen - 1) + \"…\";\n}\n\nfunction buildProgressBar(percent: number): string {\n const filled = Math.round(percent / 10);\n const empty = 10 - filled;\n return \"█\".repeat(filled) + \"░\".repeat(empty);\n}\n","import type { Bot, Context } from \"grammy\";\nimport { InlineKeyboard } from \"grammy\";\nimport type { OpenACPCore } from \"../../../core/index.js\";\nimport { escapeHtml } from \"../formatting.js\";\n\nexport async function handleIntegrate(ctx: Context, _core: OpenACPCore): Promise<void> {\n const { listIntegrations } = await import(\"../../../cli/integrate.js\");\n const agents = listIntegrations();\n\n const keyboard = new InlineKeyboard();\n for (const agent of agents) {\n keyboard.text(`🤖 ${agent}`, `i:agent:${agent}`).row();\n }\n\n await ctx.reply(\n `<b>🔗 Integrations</b>\\n\\nSelect an agent to manage its integrations.`,\n { parse_mode: \"HTML\", reply_markup: keyboard },\n );\n}\n\nfunction buildAgentItemsKeyboard(agentName: string, items: import(\"../../../cli/integrate.js\").IntegrationItem[]): InlineKeyboard {\n const keyboard = new InlineKeyboard();\n for (const item of items) {\n const installed = item.isInstalled();\n keyboard.text(\n installed ? `✅ ${item.name} — Uninstall` : `📦 ${item.name} — Install`,\n installed ? `i:uninstall:${agentName}:${item.id}` : `i:install:${agentName}:${item.id}`,\n ).row();\n }\n keyboard.text(\"← Back\", \"i:back\").row();\n return keyboard;\n}\n\nexport function setupIntegrateCallbacks(\n bot: Bot,\n core: OpenACPCore,\n): void {\n bot.callbackQuery(/^i:/, async (ctx) => {\n const data = ctx.callbackQuery.data;\n try {\n await ctx.answerCallbackQuery();\n } catch {\n /* expired */\n }\n\n // Back to agent list\n if (data === \"i:back\") {\n const { listIntegrations } = await import(\"../../../cli/integrate.js\");\n const agents = listIntegrations();\n const keyboard = new InlineKeyboard();\n for (const agent of agents) {\n keyboard.text(`🤖 ${agent}`, `i:agent:${agent}`).row();\n }\n try {\n await ctx.editMessageText(\n `<b>🔗 Integrations</b>\\n\\nSelect an agent to manage its integrations.`,\n { parse_mode: \"HTML\", reply_markup: keyboard },\n );\n } catch { /* message unchanged */ }\n return;\n }\n\n // Show agent items\n const agentMatch = data.match(/^i:agent:(.+)$/);\n if (agentMatch) {\n const agentName = agentMatch[1];\n const { getIntegration } = await import(\"../../../cli/integrate.js\");\n const integration = getIntegration(agentName);\n if (!integration) {\n await ctx.reply(`❌ No integration available for '${escapeHtml(agentName)}'.`, { parse_mode: \"HTML\" });\n return;\n }\n const keyboard = buildAgentItemsKeyboard(agentName, integration.items);\n try {\n await ctx.editMessageText(\n `<b>🔗 ${escapeHtml(agentName)} Integrations</b>\\n\\n${integration.items.map((i) => `• <b>${escapeHtml(i.name)}</b> — ${escapeHtml(i.description)}`).join(\"\\n\")}`,\n { parse_mode: \"HTML\", reply_markup: keyboard },\n );\n } catch {\n await ctx.reply(\n `<b>🔗 ${escapeHtml(agentName)} Integrations</b>`,\n { parse_mode: \"HTML\", reply_markup: keyboard },\n );\n }\n return;\n }\n\n // Install / uninstall item\n const actionMatch = data.match(/^i:(install|uninstall):([^:]+):(.+)$/);\n if (!actionMatch) return;\n\n const action = actionMatch[1] as \"install\" | \"uninstall\";\n const agentName = actionMatch[2];\n const itemId = actionMatch[3];\n\n const { getIntegration } = await import(\"../../../cli/integrate.js\");\n const integration = getIntegration(agentName);\n if (!integration) return;\n\n const item = integration.items.find((i) => i.id === itemId);\n if (!item) return;\n\n const result = action === \"install\"\n ? await item.install()\n : await item.uninstall();\n\n // Save state to config\n const installed = action === \"install\" && result.success;\n await core.configManager.save({\n integrations: {\n [agentName]: {\n installed,\n installedAt: installed ? new Date().toISOString() : undefined,\n },\n },\n });\n\n const statusEmoji = result.success ? \"✅\" : \"❌\";\n const actionLabel = action === \"install\" ? \"installed\" : \"uninstalled\";\n const logsText = result.logs.map((l) => `<code>${escapeHtml(l)}</code>`).join(\"\\n\");\n const resultText = `${statusEmoji} <b>${escapeHtml(item.name)}</b> ${actionLabel}.\\n\\n${logsText}`;\n\n const keyboard = buildAgentItemsKeyboard(agentName, integration.items);\n try {\n await ctx.editMessageText(\n `<b>🔗 ${escapeHtml(agentName)} Integrations</b>\\n\\n${resultText}`,\n { parse_mode: \"HTML\", reply_markup: keyboard },\n );\n } catch {\n await ctx.reply(resultText, { parse_mode: \"HTML\" });\n }\n });\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport type { Bot, Context } from \"grammy\";\nimport { InlineKeyboard } from \"grammy\";\nimport type { OpenACPCore } from \"../../../core/index.js\";\nimport type { ContextQuery } from \"../../../plugins/context/context-provider.js\";\nimport { DEFAULT_MAX_TOKENS } from \"../../../plugins/context/context-provider.js\";\nimport { CheckpointReader } from \"../../../plugins/context/entire/checkpoint-reader.js\";\nimport { escapeHtml } from \"../formatting.js\";\nimport { createSessionTopic, buildDeepLink } from \"../topics.js\";\nimport { buildSessionControlKeyboard } from \"./admin.js\";\nimport { createChildLogger } from \"../../../core/utils/log.js\";\nimport type { CommandsAssistantContext } from \"../types.js\";\n\nconst log = createChildLogger({ module: \"telegram-cmd-resume\" });\n\nconst PENDING_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes\n\nfunction botFromCtx(ctx: Context): Bot {\n return { api: ctx.api } as unknown as Bot;\n}\n\n// --- Pending state for interactive workspace picker ---\n\ninterface PendingResume {\n query: Omit<ContextQuery, \"repoPath\">;\n step: \"workspace\" | \"workspace_input\";\n messageId: number;\n threadId?: number;\n timer: ReturnType<typeof setTimeout>;\n}\n\nconst pendingResumes = new Map<number, PendingResume>();\n\nfunction cleanupPending(userId: number): void {\n const pending = pendingResumes.get(userId);\n if (pending) {\n clearTimeout(pending.timer);\n pendingResumes.delete(userId);\n }\n}\n\n// --- Arg parsing ---\n\nexport function parseResumeArgs(matchStr: string): { query: Omit<ContextQuery, \"repoPath\"> } | null {\n const args = matchStr.split(\" \").filter(Boolean);\n if (args.length === 0) return { query: { type: \"latest\", value: \"5\" } };\n\n const first = args[0];\n\n // Subcommands\n if (first === \"pr\") return args[1] ? { query: { type: \"pr\", value: args[1] } } : null;\n if (first === \"branch\") return args[1] ? { query: { type: \"branch\", value: args[1] } } : null;\n if (first === \"commit\") return args[1] ? { query: { type: \"commit\", value: args[1] } } : null;\n\n // Auto-detect ID format\n if (CheckpointReader.isCheckpointId(first)) return { query: { type: \"checkpoint\", value: first } };\n if (CheckpointReader.isSessionId(first)) return { query: { type: \"session\", value: first } };\n\n // GitHub PR URL: github.com/org/repo/pull/19\n if (first.includes(\"/pull/\")) {\n const prMatch = first.match(/\\/pull\\/(\\d+)/);\n return prMatch ? { query: { type: \"pr\", value: prMatch[1] } } : null;\n }\n\n // GitHub commit URL: github.com/org/repo/commit/e0dd2fa4...\n const ghCommitMatch = first.match(/github\\.com\\/[^/]+\\/[^/]+\\/commit\\/([0-9a-f]+)/);\n if (ghCommitMatch) return { query: { type: \"commit\", value: ghCommitMatch[1] } };\n\n // GitHub branch URL: github.com/org/repo/tree/branch-name\n const ghBranchMatch = first.match(/github\\.com\\/[^/]+\\/[^/]+\\/tree\\/(.+?)(?:\\?|#|$)/);\n if (ghBranchMatch) return { query: { type: \"branch\", value: ghBranchMatch[1] } };\n\n // GitHub compare URL: github.com/org/repo/compare/base...head\n const ghCompareMatch = first.match(/github\\.com\\/[^/]+\\/[^/]+\\/compare\\/(?:[^.]+\\.{2,3})(.+?)(?:\\?|#|$)/);\n if (ghCompareMatch) return { query: { type: \"branch\", value: ghCompareMatch[1] } };\n\n // GitHub bare repo URL: github.com/org/repo (no subpath) → latest\n if (first.match(/github\\.com\\/[^/]+\\/[^/]+\\/?$/) && !first.includes(\"/tree/\") && !first.includes(\"/pull/\") && !first.includes(\"/commit/\") && !first.includes(\"/compare/\")) {\n return { query: { type: \"latest\", value: \"5\" } };\n }\n\n // Entire.io checkpoint URL: entire.io/gh/{owner}/{repo}/checkpoints/{branch}/{checkpoint_id}\n const entireCheckpointMatch = first.match(/entire\\.io\\/gh\\/[^/]+\\/[^/]+\\/checkpoints\\/[^/]+\\/([0-9a-f]{12})/);\n if (entireCheckpointMatch) return { query: { type: \"checkpoint\", value: entireCheckpointMatch[1] } };\n\n // Entire.io commit URL: entire.io/gh/{owner}/{repo}/commit/{commit_hash}\n const entireCommitMatch = first.match(/entire\\.io\\/gh\\/[^/]+\\/[^/]+\\/commit\\/([0-9a-f]+)/);\n if (entireCommitMatch) return { query: { type: \"commit\", value: entireCommitMatch[1] } };\n\n // Unknown — default to latest\n return { query: { type: \"latest\", value: \"5\" } };\n}\n\nfunction looksLikePath(text: string): boolean {\n return text.startsWith(\"/\") || text.startsWith(\"~\") || text.startsWith(\".\");\n}\n\n// --- List subdirectories in workspace baseDir ---\n\nfunction listWorkspaceDirs(baseDir: string, maxItems = 10): string[] {\n const resolved = baseDir.replace(/^~/, os.homedir());\n try {\n if (!fs.existsSync(resolved)) return [];\n return fs.readdirSync(resolved, { withFileTypes: true })\n .filter(d => d.isDirectory() && !d.name.startsWith(\".\"))\n .map(d => d.name)\n .sort()\n .slice(0, maxItems);\n } catch {\n return [];\n }\n}\n\n// --- Workspace picker step ---\n\nasync function showWorkspacePicker(\n ctx: Context,\n core: OpenACPCore,\n chatId: number,\n userId: number,\n query: Omit<ContextQuery, \"repoPath\">,\n): Promise<void> {\n const config = core.configManager.get();\n const baseDir = config.workspace.baseDir;\n const resolvedBase = baseDir.replace(/^~/, os.homedir());\n const subdirs = listWorkspaceDirs(baseDir);\n\n const keyboard = new InlineKeyboard();\n\n // List subdirectories as buttons\n for (const dir of subdirs) {\n const fullPath = path.join(resolvedBase, dir);\n keyboard.text(`📁 ${dir}`, `m:resume:ws:${dir}`).row();\n }\n\n // Always offer base dir and custom input\n keyboard.text(`📁 Use ${baseDir}`, \"m:resume:ws:default\").row();\n keyboard.text(\"✏️ Enter project path\", \"m:resume:ws:custom\");\n\n const queryLabel = query.type === \"latest\" ? \"latest sessions\" : `${query.type}: ${query.value}`;\n const text =\n `📁 <b>Select project directory for resume</b>\\n\\n` +\n `Query: <code>${escapeHtml(queryLabel)}</code>\\n\\n` +\n `Choose the repo that has Entire checkpoints enabled:`;\n\n const msg = await ctx.reply(text, { parse_mode: \"HTML\", reply_markup: keyboard });\n\n cleanupPending(userId);\n pendingResumes.set(userId, {\n query,\n step: \"workspace\",\n messageId: msg.message_id,\n threadId: ctx.message?.message_thread_id,\n timer: setTimeout(() => pendingResumes.delete(userId), PENDING_TIMEOUT_MS),\n });\n}\n\n// --- Execute resume with resolved workspace ---\n\nasync function executeResume(\n ctx: Context,\n core: OpenACPCore,\n chatId: number,\n query: Omit<ContextQuery, \"repoPath\">,\n repoPath: string,\n): Promise<void> {\n // Check provider availability\n const provider = await core.contextManager.getProvider(repoPath);\n if (!provider) {\n await ctx.reply(\n `⚠️ <b>Entire not enabled in <code>${escapeHtml(repoPath)}</code></b>\\n\\n` +\n `To enable conversation history tracking:\\n` +\n `<code>cd ${escapeHtml(repoPath)} && npx entire enable</code>\\n\\n` +\n `Learn more: https://docs.entire.io/getting-started`,\n { parse_mode: \"HTML\" },\n );\n return;\n }\n\n // Scan sessions\n const fullQuery: ContextQuery = { ...query, repoPath };\n\n await ctx.reply(`🔍 Scanning ${query.type === \"latest\" ? \"latest sessions\" : `${query.type}: ${escapeHtml(query.value)}`}...`, { parse_mode: \"HTML\" });\n\n const listResult = await core.contextManager.listSessions(fullQuery);\n if (!listResult || listResult.sessions.length === 0) {\n await ctx.reply(\n `🔍 <b>No sessions found</b>\\n\\n` +\n `Query: <code>${escapeHtml(query.type)}: ${escapeHtml(query.value)}</code>\\n` +\n `Repo: <code>${escapeHtml(repoPath)}</code>`,\n { parse_mode: \"HTML\" },\n );\n return;\n }\n\n const config = core.configManager.get();\n const agentName = config.defaultAgent;\n\n let threadId: number | undefined;\n try {\n // Create topic FIRST (before session events fire — prevent race condition)\n const queryLabel = query.type === \"latest\" ? \"latest\" : `${query.type}: ${query.value.slice(0, 20)}`;\n const topicName = `📜 Resume — ${queryLabel}`;\n threadId = await createSessionTopic(botFromCtx(ctx), chatId, topicName);\n\n await ctx.api.sendMessage(chatId, `⏳ Loading context and starting session...`, {\n message_thread_id: threadId,\n parse_mode: \"HTML\",\n });\n\n // TODO: Over-budget interactive selection not yet implemented (F7)\n // Spec says: show options when context > 30K tokens, auto-select after 60s\n\n const { session, contextResult } = await core.createSessionWithContext({\n channelId: \"telegram\",\n agentName,\n workingDirectory: repoPath,\n contextQuery: fullQuery,\n contextOptions: { maxTokens: DEFAULT_MAX_TOKENS },\n });\n\n session.threadId = String(threadId);\n await core.sessionManager.patchRecord(session.id, { platform: { topicId: threadId } });\n\n // Build summary info\n const sessionCount = contextResult?.sessionCount ?? listResult.sessions.length;\n const mode = contextResult?.mode ?? \"full\";\n const tokens = contextResult?.tokenEstimate ?? listResult.estimatedTokens;\n\n const topicLink = buildDeepLink(chatId, threadId);\n const replyTarget = ctx.message?.message_thread_id;\n\n if (replyTarget !== threadId) {\n await ctx.reply(\n `✅ Session resumed → <a href=\"${topicLink}\">Open topic</a>`,\n { parse_mode: \"HTML\" },\n );\n }\n\n await ctx.api.sendMessage(\n chatId,\n `✅ <b>Session resumed with context</b>\\n` +\n `<b>Agent:</b> ${escapeHtml(session.agentName)}\\n` +\n `<b>Workspace:</b> <code>${escapeHtml(session.workingDirectory)}</code>\\n` +\n `<b>Sessions loaded:</b> ${sessionCount}\\n` +\n `<b>Mode:</b> ${escapeHtml(mode)}\\n` +\n `<b>~Tokens:</b> ${tokens.toLocaleString()}\\n\\n` +\n `Context is ready — chat here to continue working with the agent.`,\n {\n message_thread_id: threadId,\n parse_mode: \"HTML\",\n reply_markup: buildSessionControlKeyboard(session.id, false, false),\n },\n );\n\n session.warmup().catch((err) => log.error({ err }, \"Warm-up error\"));\n } catch (err) {\n log.error({ err }, \"Resume session creation failed\");\n if (threadId) {\n try {\n await ctx.api.deleteForumTopic(chatId, threadId);\n } catch { /* ignore cleanup failures */ }\n }\n const message = err instanceof Error ? err.message : (typeof err === \"object\" ? JSON.stringify(err) : String(err));\n await ctx.reply(`❌ ${escapeHtml(message)}`, { parse_mode: \"HTML\" });\n }\n}\n\n// --- Main handler ---\n\nexport async function handleResume(\n ctx: Context,\n core: OpenACPCore,\n chatId: number,\n assistant?: CommandsAssistantContext,\n): Promise<void> {\n const rawMatch = (ctx as Context & { match: unknown }).match;\n const matchStr = typeof rawMatch === \"string\" ? rawMatch : \"\";\n\n const parsed = parseResumeArgs(matchStr);\n if (!parsed) {\n await ctx.reply(\n `❌ <b>Invalid arguments.</b>\\n\\n` +\n `Usage examples:\\n` +\n `• <code>/resume</code> — latest 5 sessions\\n` +\n `• <code>/resume pr 19</code>\\n` +\n `• <code>/resume branch main</code>\\n` +\n `• <code>/resume commit e0dd2fa4</code>\\n` +\n `• <code>/resume f634acf05138</code> — checkpoint ID\\n` +\n `• <code>/resume https://entire.io/gh/.../checkpoints/.../2e884e2c402a</code>\\n` +\n `• <code>/resume https://entire.io/gh/.../commit/e0dd2fa4...</code>`,\n { parse_mode: \"HTML\" },\n );\n return;\n }\n\n const { query } = parsed;\n const userId = ctx.from?.id;\n if (!userId) return;\n\n // Always show workspace picker — user must choose working directory\n await showWorkspacePicker(ctx, core, chatId, userId, query);\n}\n\n// --- Text input handler for custom workspace path ---\n\nexport async function handlePendingResumeInput(\n ctx: Context,\n core: OpenACPCore,\n chatId: number,\n assistantTopicId?: number,\n): Promise<boolean> {\n const userId = ctx.from?.id;\n if (!userId) return false;\n const pending = pendingResumes.get(userId);\n if (!pending || !ctx.message?.text) return false;\n if (pending.step !== \"workspace_input\" && pending.step !== \"workspace\") return false;\n\n // Only intercept in assistant topic or general chat\n const threadId = ctx.message.message_thread_id;\n if (threadId && threadId !== assistantTopicId) return false;\n\n // At \"workspace\" step (picker shown), only intercept if text looks like a path\n if (pending.step === \"workspace\" && !looksLikePath(ctx.message.text.trim())) return false;\n\n let workspace = ctx.message.text.trim();\n if (!workspace) {\n await ctx.reply(\"⚠️ Please enter a valid directory path.\", { parse_mode: \"HTML\" });\n return true;\n }\n\n // Resolve relative paths against baseDir\n if (!workspace.startsWith(\"/\") && !workspace.startsWith(\"~\")) {\n const baseDir = core.configManager.get().workspace.baseDir;\n workspace = `${baseDir.replace(/\\/$/, \"\")}/${workspace}`;\n }\n const resolved = core.configManager.resolveWorkspace(workspace);\n\n cleanupPending(userId);\n await executeResume(ctx, core, chatId, pending.query, resolved);\n return true;\n}\n\n// --- Callback handlers for workspace picker buttons ---\n\nexport function setupResumeCallbacks(\n bot: Bot,\n core: OpenACPCore,\n chatId: number,\n): void {\n bot.callbackQuery(/^m:resume:/, async (ctx) => {\n const data = ctx.callbackQuery.data;\n const userId = ctx.from?.id;\n if (!userId) return;\n\n try {\n await ctx.answerCallbackQuery();\n } catch { /* expired or network — ignore */ }\n\n const pending = pendingResumes.get(userId);\n if (!pending) return;\n\n if (data === \"m:resume:ws:default\") {\n // Use baseDir directly\n const baseDir = core.configManager.get().workspace.baseDir;\n const resolved = core.configManager.resolveWorkspace(baseDir);\n cleanupPending(userId);\n try {\n await ctx.api.editMessageText(chatId, pending.messageId, `⏳ Using <code>${escapeHtml(resolved)}</code>...`, { parse_mode: \"HTML\" });\n } catch { /* ignore */ }\n await executeResume(ctx, core, chatId, pending.query, resolved);\n return;\n }\n\n if (data === \"m:resume:ws:custom\") {\n // Switch to text input mode\n try {\n await ctx.api.editMessageText(\n chatId,\n pending.messageId,\n `✏️ <b>Enter project path:</b>\\n\\n` +\n `Full path like <code>~/code/my-project</code>\\n` +\n `Or just the folder name (will use workspace baseDir)`,\n { parse_mode: \"HTML\" },\n );\n } catch {\n await ctx.reply(`✏️ <b>Enter project path:</b>`, { parse_mode: \"HTML\" });\n }\n clearTimeout(pending.timer);\n pending.step = \"workspace_input\";\n pending.timer = setTimeout(() => pendingResumes.delete(userId), PENDING_TIMEOUT_MS);\n return;\n }\n\n if (data.startsWith(\"m:resume:ws:\")) {\n // Subdirectory selected\n const dirName = data.replace(\"m:resume:ws:\", \"\");\n const baseDir = core.configManager.get().workspace.baseDir;\n const resolved = core.configManager.resolveWorkspace(path.join(baseDir.replace(/^~/, os.homedir()), dirName));\n cleanupPending(userId);\n try {\n await ctx.api.editMessageText(chatId, pending.messageId, `⏳ Using <code>${escapeHtml(resolved)}</code>...`, { parse_mode: \"HTML\" });\n } catch { /* ignore */ }\n await executeResume(ctx, core, chatId, pending.query, resolved);\n return;\n }\n });\n}\n","import type { Bot, Context } from \"grammy\";\nimport { InlineKeyboard } from \"grammy\";\nimport type { OpenACPCore } from \"../../../core/index.js\";\nimport { getSafeFields, resolveOptions, getConfigValue, isHotReloadable, type ConfigFieldDef } from \"../../../core/config/config-registry.js\";\nimport { createChildLogger } from \"../../../core/utils/log.js\";\n\nconst log = createChildLogger({ module: \"telegram-settings\" });\n\nfunction buildSettingsKeyboard(core: OpenACPCore): InlineKeyboard {\n const config = core.configManager.get();\n const fields = getSafeFields();\n const kb = new InlineKeyboard();\n\n for (const field of fields) {\n const value = getConfigValue(config, field.path);\n const label = formatFieldLabel(field, value);\n\n if (field.type === 'toggle') {\n kb.text(`${label}`, `s:toggle:${field.path}`).row();\n } else if (field.type === 'select') {\n kb.text(`${label}`, `s:select:${field.path}`).row();\n } else {\n kb.text(`${label}`, `s:input:${field.path}`).row();\n }\n }\n\n kb.text(\"◀️ Back to Menu\", \"s:back\");\n return kb;\n}\n\nfunction formatFieldLabel(field: ConfigFieldDef, value: unknown): string {\n const icons: Record<string, string> = {\n agent: '🤖', logging: '📝', tunnel: '🔗',\n security: '🔒', workspace: '📁', storage: '💾', speech: '🎤',\n };\n const icon = icons[field.group] ?? '⚙️';\n\n if (field.type === 'toggle') {\n return `${icon} ${field.displayName}: ${value ? 'ON' : 'OFF'}`;\n }\n const displayValue = value === null || value === undefined ? 'Not set' : String(value);\n return `${icon} ${field.displayName}: ${displayValue}`;\n}\n\nexport async function handleSettings(ctx: Context, core: OpenACPCore): Promise<void> {\n const kb = buildSettingsKeyboard(core);\n await ctx.reply(`<b>⚙️ Settings</b>\\nTap to change:`, {\n parse_mode: \"HTML\",\n reply_markup: kb,\n });\n}\n\nexport function setupSettingsCallbacks(\n bot: Bot,\n core: OpenACPCore,\n getAssistantSession: () => { topicId: number; enqueuePrompt: (p: string) => Promise<void> } | undefined,\n): void {\n bot.callbackQuery(/^s:toggle:/, async (ctx) => {\n const fieldPath = ctx.callbackQuery.data.replace('s:toggle:', '');\n const config = core.configManager.get();\n const currentValue = getConfigValue(config, fieldPath);\n const newValue = !currentValue;\n\n try {\n const updates = buildNestedUpdate(fieldPath, newValue);\n await core.configManager.save(updates, fieldPath);\n\n const toast = isHotReloadable(fieldPath)\n ? `✅ ${fieldPath} = ${newValue}`\n : `✅ ${fieldPath} = ${newValue} (restart needed)`;\n try { await ctx.answerCallbackQuery({ text: toast }); } catch { /* expired */ }\n\n try {\n await ctx.editMessageReplyMarkup({ reply_markup: buildSettingsKeyboard(core) });\n } catch { /* ignore */ }\n } catch (err) {\n log.error({ err, fieldPath }, 'Failed to toggle config');\n try { await ctx.answerCallbackQuery({ text: '❌ Failed to update' }); } catch { /* expired */ }\n }\n });\n\n bot.callbackQuery(/^s:select:/, async (ctx) => {\n const fieldPath = ctx.callbackQuery.data.replace('s:select:', '');\n const config = core.configManager.get();\n const fieldDef = getSafeFields().find(f => f.path === fieldPath);\n if (!fieldDef) return;\n\n const options = resolveOptions(fieldDef, config) ?? [];\n const currentValue = getConfigValue(config, fieldPath);\n const kb = new InlineKeyboard();\n\n for (const opt of options) {\n const marker = opt === String(currentValue) ? ' ✓' : '';\n kb.text(`${opt}${marker}`, `s:pick:${fieldPath}:${opt}`).row();\n }\n kb.text(\"◀️ Back\", \"s:back:refresh\");\n\n try { await ctx.answerCallbackQuery(); } catch { /* expired */ }\n\n try {\n await ctx.editMessageText(`<b>⚙️ ${fieldDef.displayName}</b>\\nSelect a value:`, {\n parse_mode: \"HTML\",\n reply_markup: kb,\n });\n } catch { /* ignore */ }\n });\n\n bot.callbackQuery(/^s:pick:/, async (ctx) => {\n const parts = ctx.callbackQuery.data.replace('s:pick:', '').split(':');\n const fieldPath = parts.slice(0, -1).join(':');\n const newValue = parts[parts.length - 1];\n\n try {\n // For speech.stt.provider: check if the selected provider has an API key configured\n if (fieldPath === 'speech.stt.provider') {\n const config = core.configManager.get();\n const providerConfig = config.speech?.stt?.providers?.[newValue];\n if (!providerConfig?.apiKey) {\n // No API key — delegate to assistant to collect it\n const assistant = getAssistantSession();\n if (assistant) {\n try { await ctx.answerCallbackQuery({ text: `🔑 API key needed — check Assistant topic` }); } catch { /* expired */ }\n const prompt = `User wants to enable ${newValue} as Speech-to-Text provider, but no API key is configured yet. Guide them to get a ${newValue} API key and set it up. After they provide the key, run both commands: \\`openacp config set speech.stt.providers.${newValue}.apiKey <key>\\` and \\`openacp config set speech.stt.provider ${newValue}\\``;\n await assistant.enqueuePrompt(prompt);\n return;\n }\n // No assistant — just warn\n try { await ctx.answerCallbackQuery({ text: `⚠️ Set API key first: openacp config set speech.stt.providers.${newValue}.apiKey <key>` }); } catch { /* expired */ }\n return;\n }\n }\n\n const updates = buildNestedUpdate(fieldPath, newValue);\n await core.configManager.save(updates, fieldPath);\n\n try { await ctx.answerCallbackQuery({ text: `✅ ${fieldPath} = ${newValue}` }); } catch { /* expired */ }\n try {\n await ctx.editMessageText(`<b>⚙️ Settings</b>\\nTap to change:`, {\n parse_mode: \"HTML\",\n reply_markup: buildSettingsKeyboard(core),\n });\n } catch { /* ignore */ }\n } catch (err) {\n log.error({ err, fieldPath }, 'Failed to set config');\n try { await ctx.answerCallbackQuery({ text: '❌ Failed to update' }); } catch { /* expired */ }\n }\n });\n\n bot.callbackQuery(/^s:input:/, async (ctx) => {\n const fieldPath = ctx.callbackQuery.data.replace('s:input:', '');\n const config = core.configManager.get();\n const fieldDef = getSafeFields().find(f => f.path === fieldPath);\n if (!fieldDef) return;\n\n const currentValue = getConfigValue(config, fieldPath);\n const assistant = getAssistantSession();\n\n if (!assistant) {\n try { await ctx.answerCallbackQuery({ text: '⚠️ Start the assistant first (/assistant)' }); } catch { /* expired */ }\n return;\n }\n\n try { await ctx.answerCallbackQuery({ text: `Delegating to assistant...` }); } catch { /* expired */ }\n\n const prompt = `User wants to change ${fieldDef.displayName} (config path: ${fieldPath}). Current value: ${JSON.stringify(currentValue)}. Ask them for the new value and apply it using: openacp config set ${fieldPath} <value>`;\n await assistant.enqueuePrompt(prompt);\n });\n\n bot.callbackQuery(\"s:back\", async (ctx) => {\n try { await ctx.answerCallbackQuery(); } catch { /* expired */ }\n const { buildMenuKeyboard } = await import('./menu.js');\n try {\n await ctx.editMessageText(`<b>OpenACP Menu</b>\\nChoose an action:`, {\n parse_mode: \"HTML\",\n reply_markup: buildMenuKeyboard(),\n });\n } catch { /* ignore */ }\n });\n\n bot.callbackQuery(\"s:back:refresh\", async (ctx) => {\n try { await ctx.answerCallbackQuery(); } catch { /* expired */ }\n try {\n await ctx.editMessageText(`<b>⚙️ Settings</b>\\nTap to change:`, {\n parse_mode: \"HTML\",\n reply_markup: buildSettingsKeyboard(core),\n });\n } catch { /* ignore */ }\n });\n}\n\nfunction buildNestedUpdate(dotPath: string, value: unknown): Record<string, unknown> {\n const parts = dotPath.split('.');\n const result: Record<string, unknown> = {};\n let target = result;\n for (let i = 0; i < parts.length - 1; i++) {\n target[parts[i]] = {};\n target = target[parts[i]] as Record<string, unknown>;\n }\n target[parts[parts.length - 1]] = value;\n return result;\n}\n","import * as fs from \"node:fs\";\nimport { ConfigSchema } from \"../../config/config.js\";\nimport { applyMigrations } from \"../../config/config-migrations.js\";\nimport type { DoctorCheck, CheckResult } from \"../types.js\";\n\nexport const configCheck: DoctorCheck = {\n name: \"Config\",\n order: 1,\n async run(ctx) {\n const results: CheckResult[] = [];\n\n if (!fs.existsSync(ctx.configPath)) {\n results.push({ status: \"fail\", message: \"Config file not found\" });\n return results;\n }\n results.push({ status: \"pass\", message: \"Config file exists\" });\n\n let raw: Record<string, unknown>;\n try {\n raw = JSON.parse(fs.readFileSync(ctx.configPath, \"utf-8\"));\n } catch (err) {\n results.push({\n status: \"fail\",\n message: `Config JSON invalid: ${err instanceof Error ? err.message : String(err)}`,\n });\n return results;\n }\n results.push({ status: \"pass\", message: \"JSON valid\" });\n\n const testRaw = structuredClone(raw);\n const { changed } = applyMigrations(testRaw);\n if (changed) {\n results.push({\n status: \"warn\",\n message: \"Pending config migrations\",\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n applyMigrations(raw);\n fs.writeFileSync(ctx.configPath, JSON.stringify(raw, null, 2));\n return { success: true, message: \"applied migrations\" };\n },\n });\n }\n\n const result = ConfigSchema.safeParse(raw);\n if (!result.success) {\n for (const issue of result.error.issues) {\n results.push({\n status: \"fail\",\n message: `Validation: ${issue.path.join(\".\")} — ${issue.message}`,\n });\n }\n } else {\n results.push({ status: \"pass\", message: \"Schema valid\" });\n }\n\n return results;\n },\n};\n","import { execFileSync } from \"node:child_process\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { DoctorCheck, CheckResult } from \"../types.js\";\n\nfunction commandExists(cmd: string): boolean {\n try {\n execFileSync(\"which\", [cmd], { stdio: \"pipe\" });\n return true;\n } catch {\n // not in PATH\n }\n let dir = process.cwd();\n while (true) {\n const binPath = path.join(dir, \"node_modules\", \".bin\", cmd);\n if (fs.existsSync(binPath)) return true;\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return false;\n}\n\nexport const agentsCheck: DoctorCheck = {\n name: \"Agents\",\n order: 2,\n async run(ctx) {\n const results: CheckResult[] = [];\n if (!ctx.config) {\n results.push({ status: \"fail\", message: \"Cannot check agents — config not loaded\" });\n return results;\n }\n\n const agents = ctx.config.agents;\n const defaultAgent = ctx.config.defaultAgent;\n\n if (!agents[defaultAgent]) {\n results.push({\n status: \"fail\",\n message: `Default agent \"${defaultAgent}\" not found in agents config`,\n });\n }\n\n for (const [name, agent] of Object.entries(agents)) {\n const isDefault = name === defaultAgent;\n if (commandExists(agent.command)) {\n results.push({\n status: \"pass\",\n message: `${agent.command} found${isDefault ? \" (default)\" : \"\"}`,\n });\n } else {\n results.push({\n status: isDefault ? \"fail\" : \"warn\",\n message: `${agent.command} not found in PATH${isDefault ? \" (default agent!)\" : \"\"}`,\n });\n }\n }\n\n return results;\n },\n};\n","import type { DoctorCheck, CheckResult } from \"../types.js\";\n\nconst BOT_TOKEN_REGEX = /^\\d+:[A-Za-z0-9_-]{35,}$/;\n\nexport const telegramCheck: DoctorCheck = {\n name: \"Telegram\",\n order: 3,\n async run(ctx) {\n const results: CheckResult[] = [];\n\n if (!ctx.config) {\n results.push({ status: \"fail\", message: \"Cannot check Telegram — config not loaded\" });\n return results;\n }\n\n const tgConfig = ctx.config.channels.telegram as Record<string, unknown> | undefined;\n if (!tgConfig || !tgConfig.enabled) {\n results.push({ status: \"pass\", message: \"Telegram not enabled (skipped)\" });\n return results;\n }\n\n const botToken = tgConfig.botToken as string | undefined;\n const chatId = tgConfig.chatId as number | undefined;\n\n if (!botToken || !BOT_TOKEN_REGEX.test(botToken)) {\n results.push({ status: \"fail\", message: \"Bot token format invalid\" });\n return results;\n }\n results.push({ status: \"pass\", message: \"Bot token format valid\" });\n\n let botId: number | undefined;\n try {\n const res = await fetch(`https://api.telegram.org/bot${botToken}/getMe`);\n const data = (await res.json()) as { ok: boolean; result?: { id: number; username: string }; description?: string };\n if (data.ok && data.result) {\n botId = data.result.id;\n results.push({ status: \"pass\", message: `Bot token valid (@${data.result.username})` });\n } else {\n results.push({ status: \"fail\", message: `Bot token rejected: ${data.description || \"unknown error\"}` });\n return results;\n }\n } catch (err) {\n results.push({ status: \"fail\", message: `Cannot reach Telegram API: ${err instanceof Error ? err.message : String(err)}` });\n return results;\n }\n\n if (!chatId || chatId === 0) {\n results.push({ status: \"fail\", message: \"Chat ID not configured\" });\n return results;\n }\n\n try {\n const res = await fetch(`https://api.telegram.org/bot${botToken}/getChat`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ chat_id: chatId }),\n });\n const data = (await res.json()) as {\n ok: boolean;\n result?: { type: string; is_forum?: boolean; title: string };\n description?: string;\n };\n if (!data.ok || !data.result) {\n results.push({ status: \"fail\", message: `Chat ID invalid: ${data.description || \"unknown error\"}` });\n return results;\n }\n if (data.result.type !== \"supergroup\") {\n results.push({ status: \"fail\", message: `Chat is \"${data.result.type}\", must be a supergroup` });\n return results;\n }\n if (!data.result.is_forum) {\n results.push({ status: \"warn\", message: \"Chat does not have topics enabled\" });\n } else {\n results.push({ status: \"pass\", message: `Chat is supergroup with topics (\"${data.result.title}\")` });\n }\n } catch (err) {\n results.push({ status: \"fail\", message: `Cannot validate chat: ${err instanceof Error ? err.message : String(err)}` });\n return results;\n }\n\n try {\n const res = await fetch(`https://api.telegram.org/bot${botToken}/getChatMember`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ chat_id: chatId, user_id: botId }),\n });\n const data = (await res.json()) as { ok: boolean; result?: { status: string }; description?: string };\n if (!data.ok || !data.result) {\n results.push({ status: \"fail\", message: `Cannot check bot membership: ${data.description || \"unknown\"}` });\n } else if (data.result.status === \"administrator\" || data.result.status === \"creator\") {\n results.push({ status: \"pass\", message: \"Bot is admin in group\" });\n } else {\n results.push({\n status: \"fail\",\n message: `Bot is \"${data.result.status}\" — must be admin. Promote bot in group settings.`,\n });\n }\n } catch (err) {\n results.push({ status: \"fail\", message: `Admin check failed: ${err instanceof Error ? err.message : String(err)}` });\n }\n\n return results;\n },\n};\n","import * as fs from \"node:fs\";\nimport type { DoctorCheck, CheckResult } from \"../types.js\";\n\nexport const storageCheck: DoctorCheck = {\n name: \"Storage\",\n order: 4,\n async run(ctx) {\n const results: CheckResult[] = [];\n\n if (!fs.existsSync(ctx.dataDir)) {\n results.push({\n status: \"fail\",\n message: \"Data directory ~/.openacp does not exist\",\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n fs.mkdirSync(ctx.dataDir, { recursive: true });\n return { success: true, message: \"created directory\" };\n },\n });\n } else {\n try {\n fs.accessSync(ctx.dataDir, fs.constants.W_OK);\n results.push({ status: \"pass\", message: \"Data directory exists and writable\" });\n } catch {\n results.push({ status: \"fail\", message: \"Data directory not writable\" });\n }\n }\n\n if (fs.existsSync(ctx.sessionsPath)) {\n try {\n const content = fs.readFileSync(ctx.sessionsPath, \"utf-8\");\n const data = JSON.parse(content);\n if (typeof data === \"object\" && data !== null && \"sessions\" in data) {\n results.push({ status: \"pass\", message: \"Sessions file valid\" });\n } else {\n results.push({\n status: \"fail\",\n message: \"Sessions file has invalid structure\",\n fixable: true,\n fixRisk: \"risky\",\n fix: async () => {\n fs.writeFileSync(ctx.sessionsPath, JSON.stringify({ version: 1, sessions: {} }, null, 2));\n return { success: true, message: \"reset sessions file\" };\n },\n });\n }\n } catch {\n results.push({\n status: \"fail\",\n message: \"Sessions file corrupt (invalid JSON)\",\n fixable: true,\n fixRisk: \"risky\",\n fix: async () => {\n fs.writeFileSync(ctx.sessionsPath, JSON.stringify({ version: 1, sessions: {} }, null, 2));\n return { success: true, message: \"reset sessions file\" };\n },\n });\n }\n } else {\n results.push({ status: \"pass\", message: \"Sessions file not present yet (created on first session)\" });\n }\n\n if (!fs.existsSync(ctx.logsDir)) {\n results.push({\n status: \"warn\",\n message: \"Log directory does not exist\",\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n fs.mkdirSync(ctx.logsDir, { recursive: true });\n return { success: true, message: \"created log directory\" };\n },\n });\n } else {\n try {\n fs.accessSync(ctx.logsDir, fs.constants.W_OK);\n results.push({ status: \"pass\", message: \"Log directory exists and writable\" });\n } catch {\n results.push({ status: \"fail\", message: \"Log directory not writable\" });\n }\n }\n\n return results;\n },\n};\n","import * as fs from \"node:fs\";\nimport { expandHome } from \"../../config/config.js\";\nimport type { DoctorCheck, CheckResult } from \"../types.js\";\n\nexport const workspaceCheck: DoctorCheck = {\n name: \"Workspace\",\n order: 5,\n async run(ctx) {\n const results: CheckResult[] = [];\n\n if (!ctx.config) {\n results.push({ status: \"fail\", message: \"Cannot check workspace — config not loaded\" });\n return results;\n }\n\n const baseDir = expandHome(ctx.config.workspace.baseDir);\n\n if (!fs.existsSync(baseDir)) {\n results.push({\n status: \"warn\",\n message: `Workspace directory does not exist: ${baseDir}`,\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n fs.mkdirSync(baseDir, { recursive: true });\n return { success: true, message: \"created directory\" };\n },\n });\n } else {\n try {\n fs.accessSync(baseDir, fs.constants.W_OK);\n results.push({ status: \"pass\", message: `Workspace directory exists: ${baseDir}` });\n } catch {\n results.push({ status: \"fail\", message: `Workspace directory not writable: ${baseDir}` });\n }\n }\n\n return results;\n },\n};\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { DoctorCheck, CheckResult } from \"../types.js\";\n\nexport const pluginsCheck: DoctorCheck = {\n name: \"Plugins\",\n order: 6,\n async run(ctx) {\n const results: CheckResult[] = [];\n\n if (!fs.existsSync(ctx.pluginsDir)) {\n results.push({\n status: \"warn\",\n message: \"Plugins directory does not exist\",\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n fs.mkdirSync(ctx.pluginsDir, { recursive: true });\n fs.writeFileSync(\n path.join(ctx.pluginsDir, \"package.json\"),\n JSON.stringify({ name: \"openacp-plugins\", private: true, dependencies: {} }, null, 2),\n );\n return { success: true, message: \"initialized plugins directory\" };\n },\n });\n return results;\n }\n results.push({ status: \"pass\", message: \"Plugins directory exists\" });\n\n const pkgPath = path.join(ctx.pluginsDir, \"package.json\");\n if (!fs.existsSync(pkgPath)) {\n results.push({\n status: \"warn\",\n message: \"Plugins package.json missing\",\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n fs.writeFileSync(\n pkgPath,\n JSON.stringify({ name: \"openacp-plugins\", private: true, dependencies: {} }, null, 2),\n );\n return { success: true, message: \"created package.json\" };\n },\n });\n return results;\n }\n\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n const deps = pkg.dependencies || {};\n const count = Object.keys(deps).length;\n results.push({ status: \"pass\", message: `Plugins package.json valid (${count} plugins)` });\n } catch {\n results.push({\n status: \"fail\",\n message: \"Plugins package.json is invalid JSON\",\n fixable: true,\n fixRisk: \"risky\",\n fix: async () => {\n fs.writeFileSync(\n pkgPath,\n JSON.stringify({ name: \"openacp-plugins\", private: true, dependencies: {} }, null, 2),\n );\n return { success: true, message: \"reset package.json\" };\n },\n });\n }\n\n return results;\n },\n};\n","import * as fs from \"node:fs\";\nimport * as net from \"node:net\";\nimport type { DoctorCheck, CheckResult } from \"../types.js\";\n\nfunction isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction checkPortInUse(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const server = net.createServer();\n server.once(\"error\", () => resolve(true));\n server.once(\"listening\", () => {\n server.close();\n resolve(false);\n });\n server.listen(port, \"127.0.0.1\");\n });\n}\n\nexport const daemonCheck: DoctorCheck = {\n name: \"Daemon\",\n order: 7,\n async run(ctx) {\n const results: CheckResult[] = [];\n\n if (fs.existsSync(ctx.pidPath)) {\n const content = fs.readFileSync(ctx.pidPath, \"utf-8\").trim();\n const pid = parseInt(content, 10);\n if (isNaN(pid)) {\n results.push({\n status: \"warn\",\n message: \"PID file contains invalid data\",\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n fs.unlinkSync(ctx.pidPath);\n return { success: true, message: \"removed invalid PID file\" };\n },\n });\n } else if (!isProcessAlive(pid)) {\n results.push({\n status: \"warn\",\n message: `Stale PID file (PID ${pid} not running)`,\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n fs.unlinkSync(ctx.pidPath);\n return { success: true, message: \"removed stale PID file\" };\n },\n });\n } else {\n results.push({ status: \"pass\", message: `Daemon running (PID ${pid})` });\n }\n }\n\n if (fs.existsSync(ctx.portFilePath)) {\n const content = fs.readFileSync(ctx.portFilePath, \"utf-8\").trim();\n const port = parseInt(content, 10);\n if (isNaN(port)) {\n results.push({\n status: \"warn\",\n message: \"Port file contains invalid data\",\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n fs.unlinkSync(ctx.portFilePath);\n return { success: true, message: \"removed invalid port file\" };\n },\n });\n } else {\n results.push({ status: \"pass\", message: `Port file valid (port ${port})` });\n }\n }\n\n if (ctx.config) {\n const apiPort = ctx.config.api.port;\n const inUse = await checkPortInUse(apiPort);\n if (inUse) {\n if (fs.existsSync(ctx.pidPath)) {\n const pid = parseInt(fs.readFileSync(ctx.pidPath, \"utf-8\").trim(), 10);\n if (!isNaN(pid) && isProcessAlive(pid)) {\n results.push({ status: \"pass\", message: `API port ${apiPort} in use by OpenACP daemon` });\n } else {\n results.push({ status: \"warn\", message: `API port ${apiPort} in use by another process` });\n }\n } else {\n results.push({ status: \"warn\", message: `API port ${apiPort} in use by another process` });\n }\n } else {\n results.push({ status: \"pass\", message: `API port ${apiPort} available` });\n }\n }\n\n return results;\n },\n};\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport { execFileSync } from \"node:child_process\";\nimport type { DoctorCheck, CheckResult } from \"../types.js\";\n\nexport const tunnelCheck: DoctorCheck = {\n name: \"Tunnel\",\n order: 8,\n async run(ctx) {\n const results: CheckResult[] = [];\n\n if (!ctx.config) {\n results.push({ status: \"fail\", message: \"Cannot check tunnel — config not loaded\" });\n return results;\n }\n\n if (!ctx.config.tunnel.enabled) {\n results.push({ status: \"pass\", message: \"Tunnel not enabled (skipped)\" });\n return results;\n }\n\n const provider = ctx.config.tunnel.provider;\n results.push({ status: \"pass\", message: `Tunnel provider: ${provider}` });\n\n if (provider === \"cloudflare\") {\n const binName = os.platform() === \"win32\" ? \"cloudflared.exe\" : \"cloudflared\";\n const binPath = path.join(ctx.dataDir, \"bin\", binName);\n let found = false;\n if (fs.existsSync(binPath)) {\n found = true;\n } else {\n try {\n execFileSync(\"which\", [\"cloudflared\"], { stdio: \"pipe\" });\n found = true;\n } catch {\n // not found\n }\n }\n\n if (found) {\n results.push({ status: \"pass\", message: \"cloudflared binary found\" });\n } else {\n results.push({\n status: \"warn\",\n message: \"cloudflared binary not found\",\n fixable: true,\n fixRisk: \"safe\",\n fix: async () => {\n try {\n const { ensureCloudflared } = await import(\"../../../plugins/tunnel/providers/install-cloudflared.js\");\n await ensureCloudflared();\n return { success: true, message: \"installed cloudflared\" };\n } catch (err) {\n return { success: false, message: err instanceof Error ? err.message : String(err) };\n }\n },\n });\n }\n }\n\n const tunnelPort = ctx.config.tunnel.port;\n if (tunnelPort < 1 || tunnelPort > 65535) {\n results.push({ status: \"fail\", message: `Invalid tunnel port: ${tunnelPort}` });\n } else {\n results.push({ status: \"pass\", message: `Tunnel port: ${tunnelPort}` });\n }\n\n return results;\n },\n};\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { DoctorCheck, DoctorContext, DoctorReport, CategoryResult, PendingFix, CheckResult } from \"./types.js\";\nimport { ConfigManager, expandHome } from \"../config/config.js\";\nimport { getGlobalRoot } from \"../instance-context.js\";\n\nimport { configCheck } from \"./checks/config.js\";\nimport { agentsCheck } from \"./checks/agents.js\";\nimport { telegramCheck } from \"./checks/telegram.js\";\nimport { storageCheck } from \"./checks/storage.js\";\nimport { workspaceCheck } from \"./checks/workspace.js\";\nimport { pluginsCheck } from \"./checks/plugins.js\";\nimport { daemonCheck } from \"./checks/daemon.js\";\nimport { tunnelCheck } from \"./checks/tunnel.js\";\n\nconst ALL_CHECKS: DoctorCheck[] = [\n configCheck,\n agentsCheck,\n telegramCheck,\n storageCheck,\n workspaceCheck,\n pluginsCheck,\n daemonCheck,\n tunnelCheck,\n];\n\nconst CHECK_TIMEOUT_MS = 10_000;\n\nexport class DoctorEngine {\n private dryRun: boolean;\n private dataDir: string;\n\n constructor(options?: { dryRun?: boolean; dataDir?: string }) {\n this.dryRun = options?.dryRun ?? false;\n this.dataDir = options?.dataDir ?? getGlobalRoot();\n }\n\n async runAll(): Promise<DoctorReport> {\n const ctx = await this.buildContext();\n const checks = [...ALL_CHECKS].sort((a, b) => a.order - b.order);\n\n const categories: CategoryResult[] = [];\n const pendingFixes: PendingFix[] = [];\n const summary = { passed: 0, warnings: 0, failed: 0, fixed: 0 };\n\n for (const check of checks) {\n let results: CheckResult[];\n try {\n results = await Promise.race([\n check.run(ctx),\n new Promise<CheckResult[]>((_, reject) =>\n setTimeout(() => reject(new Error(\"timeout\")), CHECK_TIMEOUT_MS),\n ),\n ]);\n } catch {\n results = [{ status: \"fail\", message: `${check.name} check timed out` }];\n }\n\n for (const result of results) {\n if (result.fixable && result.fix) {\n if (result.fixRisk === \"safe\" && !this.dryRun) {\n try {\n const fixResult = await result.fix();\n if (fixResult.success) {\n result.message += ` → Fixed (${fixResult.message})`;\n result.status = \"warn\";\n delete result.fix;\n summary.fixed++;\n }\n } catch {\n // Fix failed, leave as-is\n }\n } else if (result.fixRisk === \"risky\") {\n pendingFixes.push({\n category: check.name,\n message: result.message,\n fix: result.fix,\n });\n }\n }\n\n if (result.status === \"pass\") summary.passed++;\n else if (result.status === \"warn\") summary.warnings++;\n else if (result.status === \"fail\") summary.failed++;\n }\n\n categories.push({ name: check.name, results });\n }\n\n return { categories, summary, pendingFixes };\n }\n\n private async buildContext(): Promise<DoctorContext> {\n const dataDir = this.dataDir;\n const configPath = process.env.OPENACP_CONFIG_PATH || path.join(dataDir, \"config.json\");\n\n let config = null;\n let rawConfig: unknown = null;\n\n try {\n const content = fs.readFileSync(configPath, \"utf-8\");\n rawConfig = JSON.parse(content);\n const cm = new ConfigManager();\n await cm.load();\n config = cm.get();\n } catch {\n // Config may not exist or may be invalid — checks will handle this\n }\n\n const logsDir = config\n ? expandHome(config.logging.logDir)\n : path.join(dataDir, \"logs\");\n\n return {\n config,\n rawConfig,\n configPath,\n dataDir,\n sessionsPath: path.join(dataDir, \"sessions.json\"),\n pidPath: path.join(dataDir, \"openacp.pid\"),\n portFilePath: path.join(dataDir, \"api.port\"),\n pluginsDir: path.join(dataDir, \"plugins\"),\n logsDir,\n };\n }\n}\n\nexport type { DoctorReport, CategoryResult, PendingFix, CheckResult, DoctorContext } from \"./types.js\";\n","import type { Bot, Context } from \"grammy\";\nimport { InlineKeyboard } from \"grammy\";\nimport { DoctorEngine } from \"../../../core/doctor/index.js\";\nimport type { DoctorReport, PendingFix } from \"../../../core/doctor/types.js\";\nimport { createChildLogger } from \"../../../core/utils/log.js\";\n\nconst log = createChildLogger({ module: \"telegram-cmd-doctor\" });\n\nconst pendingFixesStore = new Map<string, PendingFix[]>();\n\nfunction renderReport(report: DoctorReport): { text: string; keyboard: InlineKeyboard | undefined } {\n const icons = { pass: \"✅\", warn: \"⚠️\", fail: \"❌\" };\n const lines: string[] = [\"🩺 <b>OpenACP Doctor</b>\\n\"];\n\n for (const category of report.categories) {\n lines.push(`<b>${category.name}</b>`);\n for (const result of category.results) {\n lines.push(` ${icons[result.status]} ${escapeHtml(result.message)}`);\n }\n lines.push(\"\");\n }\n\n const { passed, warnings, failed, fixed } = report.summary;\n const fixedStr = fixed > 0 ? `, ${fixed} fixed` : \"\";\n lines.push(`<b>Result:</b> ${passed} passed, ${warnings} warnings, ${failed} failed${fixedStr}`);\n\n let keyboard: InlineKeyboard | undefined;\n if (report.pendingFixes.length > 0) {\n keyboard = new InlineKeyboard();\n for (let i = 0; i < report.pendingFixes.length; i++) {\n const label = `🔧 Fix: ${report.pendingFixes[i].message.slice(0, 30)}`;\n keyboard.text(label, `m:doctor:fix:${i}`).row();\n }\n }\n\n return { text: lines.join(\"\\n\"), keyboard };\n}\n\nfunction escapeHtml(text: string): string {\n return text.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\n\nexport async function handleDoctor(ctx: Context): Promise<void> {\n const statusMsg = await ctx.reply(\"🩺 Running diagnostics...\", { parse_mode: \"HTML\" });\n\n try {\n const engine = new DoctorEngine();\n const report = await engine.runAll();\n const { text, keyboard } = renderReport(report);\n\n const storeKey = `${ctx.chat!.id}:${statusMsg.message_id}`;\n if (report.pendingFixes.length > 0) {\n pendingFixesStore.set(storeKey, report.pendingFixes);\n }\n\n await ctx.api.editMessageText(ctx.chat!.id, statusMsg.message_id, text, {\n parse_mode: \"HTML\",\n reply_markup: keyboard,\n });\n } catch (err) {\n log.error({ err }, \"Doctor command failed\");\n await ctx.api.editMessageText(\n ctx.chat!.id,\n statusMsg.message_id,\n `❌ Doctor failed: ${err instanceof Error ? err.message : String(err)}`,\n { parse_mode: \"HTML\" },\n );\n }\n}\n\nexport function setupDoctorCallbacks(bot: Bot): void {\n bot.callbackQuery(/^m:doctor:fix:/, async (ctx) => {\n const data = ctx.callbackQuery.data;\n const index = parseInt(data.replace(\"m:doctor:fix:\", \"\"), 10);\n const chatId = ctx.callbackQuery.message?.chat.id;\n const messageId = ctx.callbackQuery.message?.message_id;\n\n try {\n await ctx.answerCallbackQuery({ text: \"Applying fix...\" });\n } catch { /* expired */ }\n\n if (chatId === undefined || messageId === undefined) return;\n\n const storeKey = `${chatId}:${messageId}`;\n const fixes = pendingFixesStore.get(storeKey);\n if (!fixes || index < 0 || index >= fixes.length) {\n try { await ctx.answerCallbackQuery({ text: \"Fix no longer available\" }); } catch { /* */ }\n return;\n }\n\n const pending = fixes[index];\n try {\n const result = await pending.fix();\n if (result.success) {\n const engine = new DoctorEngine();\n const report = await engine.runAll();\n const { text, keyboard } = renderReport(report);\n\n if (report.pendingFixes.length > 0) {\n pendingFixesStore.set(storeKey, report.pendingFixes);\n } else {\n pendingFixesStore.delete(storeKey);\n }\n\n await ctx.editMessageText(text, { parse_mode: \"HTML\", reply_markup: keyboard });\n } else {\n try { await ctx.answerCallbackQuery({ text: `Fix failed: ${result.message}` }); } catch { /* */ }\n }\n } catch (err) {\n log.error({ err, index }, \"Doctor fix callback failed\");\n }\n });\n\n bot.callbackQuery(\"m:doctor\", async (ctx) => {\n try { await ctx.answerCallbackQuery(); } catch { /* */ }\n await handleDoctor(ctx);\n });\n}\n","import type { Context } from \"grammy\";\nimport { InlineKeyboard } from \"grammy\";\nimport type { OpenACPCore } from \"../../../core/index.js\";\nimport { escapeHtml } from \"../formatting.js\";\nimport { createChildLogger } from \"../../../core/utils/log.js\";\n\nconst log = createChildLogger({ module: \"telegram-cmd-tunnel\" });\n\nexport async function handleTunnel(\n ctx: Context,\n core: OpenACPCore,\n): Promise<void> {\n if (!core.tunnelService) {\n await ctx.reply(\"❌ Tunnel service is not enabled.\", { parse_mode: \"HTML\" });\n return;\n }\n\n const match = (ctx as Context & { match?: string }).match?.trim() ?? \"\";\n\n // /tunnel stop <port>\n if (match.startsWith(\"stop \")) {\n const portStr = match.slice(5).trim();\n const port = parseInt(portStr, 10);\n if (isNaN(port)) {\n await ctx.reply(\"❌ Invalid port number.\", { parse_mode: \"HTML\" });\n return;\n }\n\n try {\n await core.tunnelService.stopTunnel(port);\n await ctx.reply(`🔌 Tunnel stopped: port ${port}`, { parse_mode: \"HTML\" });\n } catch (err) {\n await ctx.reply(`❌ ${escapeHtml((err as Error).message)}`, { parse_mode: \"HTML\" });\n }\n return;\n }\n\n // /tunnel <port> [label]\n if (match) {\n const parts = match.split(/\\s+/);\n const port = parseInt(parts[0], 10);\n if (isNaN(port)) {\n await ctx.reply(\"❌ Invalid port number. Usage: <code>/tunnel 3000 [label]</code>\", { parse_mode: \"HTML\" });\n return;\n }\n const label = parts.slice(1).join(\" \") || undefined;\n\n // Find session for this thread\n const threadId = ctx.message?.message_thread_id;\n let sessionId: string | undefined;\n if (threadId) {\n const session = core.sessionManager.getSessionByThread(\"telegram\", String(threadId));\n if (session) sessionId = session.id;\n }\n\n try {\n await ctx.reply(`⏳ Starting tunnel for port ${port}...`, { parse_mode: \"HTML\" });\n const entry = await core.tunnelService.addTunnel(port, { label, sessionId });\n await ctx.reply(\n `🔗 <b>Tunnel active</b>\\n\\nPort ${port}${label ? ` (${escapeHtml(label)})` : \"\"}\\n→ <a href=\"${escapeHtml(entry.publicUrl || \"\")}\">${escapeHtml(entry.publicUrl || \"\")}</a>`,\n { parse_mode: \"HTML\" },\n );\n } catch (err) {\n await ctx.reply(`❌ ${escapeHtml((err as Error).message)}`, { parse_mode: \"HTML\" });\n }\n return;\n }\n\n // No args — show help\n await ctx.reply(\n `<b>Tunnel commands:</b>\\n\\n` +\n `<code>/tunnel &lt;port&gt; [label]</code> — Create tunnel\\n` +\n `<code>/tunnel stop &lt;port&gt;</code> — Stop tunnel\\n` +\n `<code>/tunnels</code> — List active tunnels`,\n { parse_mode: \"HTML\" },\n );\n}\n\nexport async function handleTunnels(\n ctx: Context,\n core: OpenACPCore,\n): Promise<void> {\n if (!core.tunnelService) {\n await ctx.reply(\"❌ Tunnel service is not enabled.\", { parse_mode: \"HTML\" });\n return;\n }\n\n // In session topic: show only that session's tunnels. In assistant/other: show all.\n const threadId = ctx.message?.message_thread_id;\n let entries = core.tunnelService.listTunnels();\n let sessionScoped = false;\n\n if (threadId) {\n const session = core.sessionManager.getSessionByThread(\"telegram\", String(threadId));\n if (session) {\n entries = entries.filter(e => e.sessionId === session.id);\n sessionScoped = true;\n }\n }\n\n if (entries.length === 0) {\n const hint = sessionScoped\n ? \"No tunnels for this session.\\n\\nUse <code>/tunnel &lt;port&gt;</code> to create one.\"\n : \"No active tunnels.\\n\\nUse <code>/tunnel &lt;port&gt;</code> to create one.\";\n await ctx.reply(hint, { parse_mode: \"HTML\" });\n return;\n }\n\n const lines = entries.map((e) => {\n const status = e.status === \"active\" ? \"✅\" : e.status === \"starting\" ? \"⏳\" : \"❌\";\n const label = e.label ? ` (${escapeHtml(e.label)})` : \"\";\n const url = e.publicUrl ? `\\n → <a href=\"${escapeHtml(e.publicUrl)}\">${escapeHtml(e.publicUrl)}</a>` : \"\";\n return `${status} Port <b>${e.port}</b>${label}${url}`;\n });\n\n const keyboard = new InlineKeyboard();\n for (const e of entries) {\n keyboard.text(`🔌 Stop ${e.port}${e.label ? ` (${e.label})` : \"\"}`, `tn:stop:${e.port}`).row();\n }\n if (entries.length > 1) {\n keyboard.text(\"🔌 Stop all\", \"tn:stop-all\").row();\n }\n\n await ctx.reply(\n `<b>Active tunnels:</b>\\n\\n${lines.join(\"\\n\\n\")}`,\n { parse_mode: \"HTML\", reply_markup: keyboard },\n );\n}\n\nexport function setupTunnelCallbacks(\n bot: import(\"grammy\").Bot,\n core: OpenACPCore,\n): void {\n bot.callbackQuery(/^tn:/, async (ctx) => {\n const data = ctx.callbackQuery.data;\n if (!core.tunnelService) {\n await ctx.answerCallbackQuery({ text: \"Tunnel not enabled\" });\n return;\n }\n\n try {\n if (data === \"tn:stop-all\") {\n const entries = core.tunnelService.listTunnels();\n for (const e of entries) {\n try { await core.tunnelService.stopTunnel(e.port); } catch { /* ignore system */ }\n }\n await ctx.answerCallbackQuery({ text: \"All tunnels stopped\" });\n await ctx.editMessageText(\"🔌 All tunnels stopped.\", { parse_mode: \"HTML\" });\n } else if (data.startsWith(\"tn:stop:\")) {\n const port = parseInt(data.replace(\"tn:stop:\", \"\"), 10);\n await core.tunnelService.stopTunnel(port);\n await ctx.answerCallbackQuery({ text: `Port ${port} stopped` });\n // Refresh list with keyboard\n const remaining = core.tunnelService.listTunnels();\n if (remaining.length === 0) {\n await ctx.editMessageText(\"🔌 All tunnels stopped.\", { parse_mode: \"HTML\" });\n } else {\n const kb = new InlineKeyboard();\n for (const e of remaining) {\n kb.text(`🔌 Stop ${e.port}${e.label ? ` (${e.label})` : \"\"}`, `tn:stop:${e.port}`).row();\n }\n if (remaining.length > 1) {\n kb.text(\"🔌 Stop all\", \"tn:stop-all\").row();\n }\n await ctx.editMessageText(\n `<b>Active tunnels:</b>\\n\\n` +\n remaining.map(e => {\n const status = e.status === \"active\" ? \"✅\" : \"⏳\";\n const label = e.label ? ` (${escapeHtml(e.label)})` : \"\";\n const url = e.publicUrl ? `\\n → <a href=\"${escapeHtml(e.publicUrl)}\">${escapeHtml(e.publicUrl)}</a>` : \"\";\n return `${status} Port <b>${e.port}</b>${label}${url}`;\n }).join(\"\\n\\n\"),\n { parse_mode: \"HTML\", reply_markup: kb },\n );\n }\n }\n } catch (err) {\n await ctx.answerCallbackQuery({ text: (err as Error).message });\n }\n });\n}\n","import type { Context } from \"grammy\";\nimport { InlineKeyboard } from \"grammy\";\nimport type { OpenACPCore } from \"../../../core/index.js\";\nimport { escapeHtml } from \"../formatting.js\";\nimport { createChildLogger } from \"../../../core/utils/log.js\";\n\nconst log = createChildLogger({ module: \"telegram-cmd-switch\" });\n\nexport async function handleSwitch(\n ctx: Context,\n core: OpenACPCore,\n): Promise<void> {\n const threadId = ctx.message?.message_thread_id;\n if (!threadId) return;\n\n const session = await core.getOrResumeSession(\"telegram\", String(threadId));\n if (!session) {\n await ctx.reply(\"No active session in this topic.\");\n return;\n }\n\n const rawMatch = (ctx as Context & { match: unknown }).match;\n const raw = (typeof rawMatch === \"string\" ? rawMatch : \"\").trim();\n\n // /switch label on|off\n if (raw.startsWith(\"label \")) {\n const value = raw.slice(6).trim().toLowerCase();\n if (value === \"on\" || value === \"off\") {\n await core.configManager.save(\n { agentSwitch: { labelHistory: value === \"on\" } },\n \"agentSwitch.labelHistory\",\n );\n await ctx.reply(`Agent label in history: ${value}`);\n } else {\n await ctx.reply(\"Usage: /switch label on|off\");\n }\n return;\n }\n\n // /switch (no args) → show menu\n if (!raw) {\n const agents = core.agentManager.getAvailableAgents();\n const currentAgent = session.agentName;\n const options = agents.filter((a) => a.name !== currentAgent);\n\n if (options.length === 0) {\n await ctx.reply(\"No other agents available.\");\n return;\n }\n\n const keyboard = new InlineKeyboard();\n for (const agent of options) {\n keyboard.text(agent.name, `sw:${agent.name}`).row();\n }\n\n await ctx.reply(\n `<b>Switch Agent</b>\\nCurrent: <code>${escapeHtml(currentAgent)}</code>\\n\\nSelect an agent:`,\n { parse_mode: \"HTML\", reply_markup: keyboard },\n );\n return;\n }\n\n // /switch <agentName> → direct switch\n // Check if a prompt is currently being processed\n if (session.promptRunning) {\n const keyboard = new InlineKeyboard();\n keyboard.text(\"Yes, switch now\", `swc:${raw}`).text(\"Cancel\", \"swc:cancel\");\n await ctx.reply(\n `A prompt is currently running. Switching will interrupt it.\\n\\nSwitch to <b>${escapeHtml(raw)}</b> anyway?`,\n { parse_mode: \"HTML\", reply_markup: keyboard },\n );\n return;\n }\n\n await executeSwitchAgent(ctx, core, session.id, raw);\n}\n\nexport async function executeSwitchAgent(\n ctx: Context,\n core: OpenACPCore,\n sessionId: string,\n agentName: string,\n): Promise<void> {\n try {\n const { resumed } = await core.switchSessionAgent(sessionId, agentName);\n const status = resumed ? \"resumed\" : \"new session\";\n await ctx.reply(\n `Switched to <b>${escapeHtml(agentName)}</b> (${status})`,\n { parse_mode: \"HTML\" },\n );\n log.info({ sessionId, agentName, resumed }, \"Agent switched via /switch\");\n } catch (err: any) {\n await ctx.reply(`Failed to switch agent: ${escapeHtml(String(err.message || err))}`);\n log.warn({ sessionId, agentName, err: err.message }, \"Agent switch failed\");\n }\n}\n\nexport function setupSwitchCallbacks(\n bot: import(\"grammy\").Bot,\n core: OpenACPCore,\n): void {\n bot.callbackQuery(/^sw:/, async (ctx) => {\n const agentName = ctx.callbackQuery.data!.replace(\"sw:\", \"\");\n await ctx.answerCallbackQuery();\n\n const threadId = ctx.callbackQuery.message?.message_thread_id;\n if (!threadId) return;\n\n const session = await core.getOrResumeSession(\"telegram\", String(threadId));\n if (!session) {\n await ctx.reply(\"No active session in this topic.\");\n return;\n }\n\n // Check if a prompt is currently being processed\n if (session.promptRunning) {\n const keyboard = new InlineKeyboard();\n keyboard.text(\"Yes, switch now\", `swc:${agentName}`).text(\"Cancel\", \"swc:cancel\");\n await ctx.reply(\n `A prompt is currently running. Switching will interrupt it.\\n\\nSwitch to <b>${escapeHtml(agentName)}</b> anyway?`,\n { parse_mode: \"HTML\", reply_markup: keyboard },\n );\n return;\n }\n\n await executeSwitchAgent(ctx, core, session.id, agentName);\n });\n\n // Handle switch confirmation callbacks (when prompt was in-flight)\n bot.callbackQuery(/^swc:/, async (ctx) => {\n const data = ctx.callbackQuery.data!.replace(\"swc:\", \"\");\n await ctx.answerCallbackQuery();\n\n if (data === \"cancel\") {\n await ctx.editMessageText(\"Switch cancelled.\");\n return;\n }\n\n const threadId = ctx.callbackQuery.message?.message_thread_id;\n if (!threadId) return;\n\n const session = await core.getOrResumeSession(\"telegram\", String(threadId));\n if (!session) {\n await ctx.reply(\"No active session in this topic.\");\n return;\n }\n\n // Cancel in-flight prompt before switching\n await session.abortPrompt();\n await executeSwitchAgent(ctx, core, session.id, data);\n });\n}\n","import type { Bot, Context } from \"grammy\";\nimport type { OpenACPCore } from \"../../../core/index.js\";\nimport type { CommandsAssistantContext } from \"../types.js\";\n\n// Domain modules\nimport { handleNew, handleNewChat, setupNewSessionCallbacks, createSessionDirect } from './new-session.js'\nimport { handleCancel, handleStatus, handleTopics, handleArchive, handleArchiveConfirm, setupSessionCallbacks } from './session.js'\nimport { handleEnableDangerous, handleDisableDangerous, handleUpdate, handleRestart, handleTTS, handleVerbosity, handleOutputMode } from './admin.js'\nimport { handleMenu, handleHelp, handleClear, buildMenuKeyboard } from './menu.js'\nimport { handleAgents, handleInstall, handleAgentCallback } from \"./agents.js\";\nimport { handleIntegrate } from \"./integrate.js\";\nimport {\n handleResume,\n setupResumeCallbacks,\n handlePendingResumeInput,\n} from \"./resume.js\";\nimport { handleSettings, setupSettingsCallbacks } from \"./settings.js\";\nimport { handleDoctor, setupDoctorCallbacks } from \"./doctor.js\";\nimport { handleTunnel, handleTunnels, setupTunnelCallbacks } from \"./tunnel.js\";\nimport { handleSwitch, setupSwitchCallbacks } from \"./switch.js\";\n\nexport function setupCommands(\n bot: Bot,\n core: OpenACPCore,\n chatId: number,\n assistant?: CommandsAssistantContext,\n): void {\n bot.command(\"new\", (ctx) => handleNew(ctx, core, chatId, assistant));\n bot.command(\"newchat\", (ctx) => handleNewChat(ctx, core, chatId));\n bot.command(\"cancel\", (ctx) => handleCancel(ctx, core, assistant));\n bot.command(\"status\", (ctx) => handleStatus(ctx, core));\n bot.command(\"sessions\", (ctx) => handleTopics(ctx, core));\n bot.command(\"agents\", (ctx) => handleAgents(ctx, core));\n bot.command(\"install\", (ctx) => handleInstall(ctx, core));\n bot.command(\"help\", (ctx) => handleHelp(ctx));\n bot.command(\"menu\", (ctx) => handleMenu(ctx));\n bot.command(\"enable_dangerous\", (ctx) => handleEnableDangerous(ctx, core));\n bot.command(\"disable_dangerous\", (ctx) => handleDisableDangerous(ctx, core));\n bot.command(\"restart\", (ctx) => handleRestart(ctx, core));\n bot.command(\"update\", (ctx) => handleUpdate(ctx, core));\n bot.command(\"integrate\", (ctx) => handleIntegrate(ctx, core));\n bot.command(\"clear\", (ctx) => handleClear(ctx, assistant));\n bot.command(\"doctor\", (ctx) => handleDoctor(ctx));\n bot.command(\"tunnel\", (ctx) => handleTunnel(ctx, core));\n bot.command(\"tunnels\", (ctx) => handleTunnels(ctx, core));\n bot.command(\"archive\", (ctx) => handleArchive(ctx, core));\n bot.command(\"text_to_speech\", (ctx) => handleTTS(ctx, core));\n bot.command(\"verbosity\", (ctx) => handleVerbosity(ctx, core));\n bot.command(\"outputmode\", (ctx) => handleOutputMode(ctx, core));\n bot.command(\"resume\", (ctx) => handleResume(ctx, core, chatId, assistant));\n bot.command(\"switch\", (ctx) => handleSwitch(ctx, core));\n}\n\nexport function setupAllCallbacks(\n bot: Bot,\n core: OpenACPCore,\n chatId: number,\n systemTopicIds?: { notificationTopicId: number; assistantTopicId: number },\n getAssistantSession?: () =>\n | { topicId: number; enqueuePrompt: (p: string) => Promise<void> }\n | undefined,\n): void {\n // Register specific prefix handlers FIRST (grammY middleware order matters)\n setupNewSessionCallbacks(bot, core, chatId);\n setupResumeCallbacks(bot, core, chatId);\n setupSessionCallbacks(bot, core, chatId, systemTopicIds);\n\n // Settings handlers — must be before broad m: handler\n setupSettingsCallbacks(bot, core, getAssistantSession ?? (() => undefined));\n\n // Doctor handlers — must be before broad m: handler\n setupDoctorCallbacks(bot);\n\n // Tunnel callbacks — must be before broad m: handler\n setupTunnelCallbacks(bot, core);\n\n // Switch agent callbacks — must be before broad m: handler\n setupSwitchCallbacks(bot, core);\n\n // Agent callbacks (install + pagination) — must be before broad m: handler\n bot.callbackQuery(/^ag:/, (ctx) => handleAgentCallback(ctx, core));\n\n // New session with specific agent callback — must be before broad m: handler\n bot.callbackQuery(/^na:/, async (ctx) => {\n const agentKey = ctx.callbackQuery.data!.replace(\"na:\", \"\");\n await ctx.answerCallbackQuery();\n await createSessionDirect(\n ctx,\n core,\n chatId,\n agentKey,\n core.configManager.get().workspace.baseDir,\n );\n });\n\n // Archive confirmation callbacks\n bot.callbackQuery(/^ar:/, (ctx) => handleArchiveConfirm(ctx, core, chatId));\n\n // Broad m: handler for remaining menu dispatch — LAST\n bot.callbackQuery(/^m:/, async (ctx) => {\n const data = ctx.callbackQuery.data;\n try {\n await ctx.answerCallbackQuery();\n } catch {\n /* expired or network — ignore */\n }\n\n switch (data) {\n case \"m:new\":\n await handleNew(ctx, core, chatId);\n break;\n case \"m:status\":\n await handleStatus(ctx, core);\n break;\n case \"m:agents\":\n await handleAgents(ctx, core);\n break;\n case \"m:help\":\n await handleHelp(ctx);\n break;\n case \"m:restart\":\n await handleRestart(ctx, core);\n break;\n case \"m:update\":\n await handleUpdate(ctx, core);\n break;\n case \"m:integrate\":\n await handleIntegrate(ctx, core);\n break;\n case \"m:topics\":\n await handleTopics(ctx, core);\n break;\n case \"m:settings\":\n await handleSettings(ctx, core);\n break;\n }\n });\n}\n\n// Backward compat alias\nexport { setupAllCallbacks as setupMenuCallbacks };\n\n// Re-exports for external consumers (adapter.ts, action-detect.ts)\nexport { buildMenuKeyboard } from \"./menu.js\";\nexport { buildSkillMessages } from \"./menu.js\";\nexport {\n handlePendingWorkspaceInput,\n executeNewSession,\n startInteractiveNewSession,\n} from \"./new-session.js\";\nexport { executeCancelSession } from \"./session.js\";\nexport {\n setupDangerousModeCallbacks,\n buildDangerousModeKeyboard,\n} from \"./admin.js\";\nexport {\n setupTTSCallbacks,\n setupVerbosityCallbacks,\n buildTTSKeyboard,\n buildSessionControlKeyboard,\n handleTTS,\n handleVerbosity,\n handleOutputMode,\n} from \"./admin.js\";\nexport { setupIntegrateCallbacks } from \"./integrate.js\";\nexport { setupSettingsCallbacks } from \"./settings.js\";\nexport { setupDoctorCallbacks } from \"./doctor.js\";\nexport { handlePendingResumeInput, setupResumeCallbacks } from \"./resume.js\";\n\nexport const STATIC_COMMANDS = [\n { command: \"new\", description: \"Create new session\" },\n { command: \"newchat\", description: \"New chat, same agent & workspace\" },\n { command: \"cancel\", description: \"Cancel current session\" },\n { command: \"status\", description: \"Show status\" },\n { command: \"sessions\", description: \"List all sessions\" },\n { command: \"agents\", description: \"List available agents\" },\n { command: \"install\", description: \"Install a new agent\" },\n { command: \"help\", description: \"Help\" },\n { command: \"menu\", description: \"Show menu\" },\n {\n command: \"enable_dangerous\",\n description: \"Auto-approve all permission requests (session only)\",\n },\n {\n command: \"disable_dangerous\",\n description: \"Restore normal permission prompts (session only)\",\n },\n { command: \"integrate\", description: \"Manage agent integrations\" },\n { command: \"handoff\", description: \"Continue this session in your terminal\" },\n { command: \"clear\", description: \"Clear assistant history\" },\n { command: \"restart\", description: \"Restart OpenACP\" },\n { command: \"update\", description: \"Update to latest version and restart\" },\n { command: \"doctor\", description: \"Run system diagnostics\" },\n { command: \"tunnel\", description: \"Create/stop tunnel for a local port\" },\n { command: \"tunnels\", description: \"List active tunnels\" },\n { command: 'archive', description: 'Archive session topic (recreate with clean history)' },\n { command: 'text_to_speech', description: 'Toggle Text to Speech (/text_to_speech on, /text_to_speech off)' },\n { command: 'verbosity', description: 'Deprecated: use /outputmode instead' },\n { command: \"outputmode\", description: \"Control output display level (low/medium/high)\" },\n { command: 'resume', description: 'Resume with conversation history from Entire checkpoints' },\n { command: 'switch', description: 'Switch agent in current session' },\n];\n","import type { Bot } from 'grammy'\nimport { InlineKeyboard } from 'grammy'\nimport { nanoid } from 'nanoid'\nimport type { PermissionRequest, NotificationMessage, Session } from '../../core/index.js'\nimport { escapeHtml } from './formatting.js'\nimport { buildDeepLink } from './topics.js'\nimport { createChildLogger } from '../../core/utils/log.js'\nconst log = createChildLogger({ module: 'telegram-permissions' })\n\n// Stored pending permission callbacks: callbackKey → { sessionId, requestId, options }\ninterface PendingPermission {\n sessionId: string\n requestId: string\n options: { id: string; isAllow: boolean }[]\n}\n\nexport class PermissionHandler {\n private pending: Map<string, PendingPermission> = new Map()\n\n constructor(\n private bot: Bot,\n private chatId: number,\n private getSession: (sessionId: string) => Session | undefined,\n private sendNotification: (notification: NotificationMessage) => Promise<void>,\n ) {}\n\n async sendPermissionRequest(session: Session, request: PermissionRequest): Promise<void> {\n const threadId = Number(session.threadId)\n\n // Short callback key (Telegram 64-byte limit on callback_data)\n const callbackKey = nanoid(8)\n this.pending.set(callbackKey, {\n sessionId: session.id,\n requestId: request.id,\n options: request.options.map(o => ({ id: o.id, isAllow: o.isAllow })),\n })\n\n // Build inline keyboard\n const keyboard = new InlineKeyboard()\n for (const option of request.options) {\n const emoji = option.isAllow ? '✅' : '❌'\n keyboard.text(`${emoji} ${option.label}`, `p:${callbackKey}:${option.id}`)\n }\n\n // Send in session topic WITH notification\n const msg = await this.bot.api.sendMessage(this.chatId,\n `🔐 <b>Permission request:</b>\\n\\n${escapeHtml(request.description)}`,\n {\n message_thread_id: threadId,\n parse_mode: 'HTML',\n reply_markup: keyboard,\n disable_notification: false,\n }\n )\n\n // Deep link for notification — include threadId so link navigates into the topic\n const deepLink = buildDeepLink(this.chatId, threadId, msg.message_id)\n\n // Notify in notification topic (fire-and-forget to avoid sendQueue deadlock:\n // this method runs INSIDE a sendQueue item, so awaiting another enqueue() deadlocks)\n void this.sendNotification({\n sessionId: session.id,\n sessionName: session.name,\n type: 'permission',\n summary: request.description,\n deepLink,\n })\n }\n\n setupCallbackHandler(): void {\n this.bot.on('callback_query:data', async (ctx) => {\n const data = ctx.callbackQuery.data\n if (!data.startsWith('p:')) return\n\n const parts = data.split(':')\n if (parts.length < 3) return\n const [, callbackKey, optionId] = parts\n\n const pending = this.pending.get(callbackKey)\n if (!pending) {\n try { await ctx.answerCallbackQuery({ text: '❌ Expired' }) } catch { /* old query */ }\n return\n }\n\n const session = this.getSession(pending.sessionId)\n const isAllow = pending.options.find(o => o.id === optionId)?.isAllow ?? false\n log.info({ requestId: pending.requestId, optionId, isAllow }, 'Permission responded')\n if (session?.permissionGate.requestId === pending.requestId) {\n session.permissionGate.resolve(optionId)\n }\n this.pending.delete(callbackKey)\n\n try { await ctx.answerCallbackQuery({ text: '✅ Responded' }) } catch { /* old query */ }\n\n // Remove buttons\n try {\n await ctx.editMessageReplyMarkup({ reply_markup: undefined })\n } catch { /* ignore */ }\n })\n }\n}\n","/**\n * OpenACP Product Guide — comprehensive reference for the AI assistant.\n * The assistant reads this at runtime to answer user questions about features.\n */\nexport const PRODUCT_GUIDE = `\n# OpenACP — Product Guide\n\nOpenACP lets you chat with AI coding agents (like Claude Code) through messaging platforms (Telegram, Discord).\nYou type messages in your chat platform, the agent reads/writes/runs code in your project folder, and results stream back in real time.\n\n---\n\n## Quick Start\n\n1. Start OpenACP: \\`openacp\\` (or \\`openacp start\\` for background daemon)\n2. Open your messaging platform (Telegram group or Discord server) — you'll see the Assistant topic/thread\n3. Tap/click 🆕 New Session or type /new\n4. Pick an agent and a project folder\n5. Chat in the session topic/thread — the agent works on your code\n\n---\n\n## Core Concepts\n\n### Sessions\nA session = one conversation with one AI agent working in one project folder.\nEach session gets its own topic (Telegram) or forum thread (Discord). Chat there to give instructions to the agent.\n\n### Agents\nAn agent is an AI coding tool (e.g., Claude Code, Gemini, Cursor, Codex, etc.).\nOpenACP supports 28+ agents from the official ACP Registry (agentclientprotocol.com).\nYou can install multiple agents and choose which one to use per session.\nThe default agent is used when you don't specify one.\n\n### Agent Management\n- Browse agents: \\`/agents\\` in your chat platform or \\`openacp agents\\` in CLI\n- Install: tap the install button in /agents, or \\`openacp agents install <name>\\`\n- Uninstall: \\`openacp agents uninstall <name>\\`\n- Setup/login: \\`openacp agents run <name> -- <args>\\` (e.g., \\`openacp agents run gemini -- auth login\\`)\n- Details: \\`openacp agents info <name>\\` shows version, dependencies, and setup steps\n\nSome agents need additional setup before they can be used:\n- Claude: requires \\`claude login\\`\n- Gemini: requires \\`openacp agents run gemini -- auth login\\`\n- Codex: requires setting \\`OPENAI_API_KEY\\` environment variable\n- GitHub Copilot: requires \\`openacp agents run copilot -- auth login\\`\n\nAgents are installed in three ways depending on the agent:\n- **npx** — Node.js agents, downloaded automatically on first use\n- **uvx** — Python agents, downloaded automatically on first use\n- **binary** — Platform-specific binaries, downloaded to \\`~/.openacp/agents/\\`\n\n### Project Folder (Workspace)\nThe directory where the agent reads, writes, and runs code.\nWhen creating a session, you choose which folder the agent works in.\nYou can type a full path like \\`~/code/my-project\\` or just a name like \\`my-project\\` (it becomes \\`<base-dir>/my-project\\`).\n\n### System Topics\n- **Assistant** — Always-on helper that can answer questions, create sessions, check status, troubleshoot\n- **Notifications** — System alerts (permission requests, session errors, completions)\n\n---\n\n## Creating Sessions\n\n### From menu\nTap 🆕 New Session → choose agent (if multiple) → choose project folder → confirm\n\n### From command\n- \\`/new\\` — Interactive flow (asks agent + folder)\n- \\`/new claude ~/code/my-project\\` — Create directly with specific agent and folder\n\n### From Assistant topic\nJust ask: \"Create a session for my-project with claude\" — the assistant handles it\n\n### Quick new chat\n\\`/newchat\\` in a session topic — creates new session with same agent and folder as current one\n\n---\n\n## Working with Sessions\n\n### Chat\nType messages in the session topic. The agent responds with code changes, explanations, tool outputs.\n\n### What you see while the agent works\n- **💭 Thinking indicator** — Shows when the agent is reasoning, with elapsed time\n- **Text responses** — Streamed in real time, updated every few seconds\n- **Tool calls** — When the agent runs commands or edits files, you see tool name, input, status, and output\n- **📋 Plan card** — Visual task progress with completed/in-progress/pending items and progress bar\n- **\"View File\" / \"View Diff\" buttons** — Opens in browser with Monaco editor (requires tunnel)\n\n### Session lifecycle\n1. **Creating** — Topic created, agent spawning\n2. **Warming up** — Agent primes its cache (happens automatically, invisible to you)\n3. **Active** — Ready for your messages\n4. **Auto-naming** — After your first message, the session gets a descriptive name (agent summarizes in ~5 words). The topic title updates automatically.\n5. **Finished/Error** — Session completed or hit an error\n\n### Agent skills\nSome agents provide slash commands (e.g., /compact, /review). Available skills are pinned in the session topic.\n\n### Permission requests\nWhen the agent wants to run a command, it asks for permission.\nYou see buttons: ✅ Allow, ❌ Reject (and sometimes \"Always Allow\").\nA notification also appears in the Notifications topic with a link to the request.\n\n### Dangerous mode\nAuto-approves ALL permission requests — the agent runs any command without asking.\n- Enable: \\`/enable_dangerous\\` or tap the ☠️ button in the session\n- Disable: \\`/disable_dangerous\\` or tap the 🔐 button\n- ⚠️ Use with caution — the agent can execute anything\n\n### Session timeout\nIdle sessions are automatically cancelled after a configurable timeout (default: 60 minutes).\nConfigure via \\`security.sessionTimeoutMinutes\\` in config.\n\n---\n\n## Session Transfer (Handoff)\n\n### Chat → Terminal\n1. Type \\`/handoff\\` in a session topic/thread\n2. You get a command like \\`claude --resume <SESSION_ID>\\`\n3. Copy and run it in your terminal — the session continues there with full conversation history\n\n### Terminal → Chat\n1. First time: run \\`openacp integrate claude\\` to install the handoff skill (one-time setup)\n2. In Claude Code, use the /openacp:handoff slash command\n3. The session appears as a new topic/thread and you can continue chatting there\n\n### How it works\n- The agent session ID is shared between platforms\n- Conversation history is preserved — pick up where you left off\n- The agent that supports resume (e.g., Claude with \\`--resume\\`) handles the actual transfer\n\n---\n\n## Managing Sessions\n\n### Status\n- \\`/status\\` — Shows active sessions count and details\n- Ask the Assistant: \"What sessions are running?\"\n\n### List all sessions\n- \\`/sessions\\` — Shows all sessions with status (active, finished, error)\n\n### Cancel\n- \\`/cancel\\` in a session topic — cancels that session\n- Ask the Assistant: \"Cancel the stuck session\"\n\n### Cleanup\n- From \\`/sessions\\` → tap cleanup buttons (finished, errors, all)\n- Ask the Assistant: \"Clean up old sessions\"\n\n---\n\n## Assistant Topic\n\nThe Assistant is an always-on AI helper in its own topic. It can:\n- Answer questions about OpenACP\n- Create sessions for you\n- Check status and health\n- Cancel sessions\n- Clean up old sessions\n- Troubleshoot issues\n- Manage configuration\n\nJust chat naturally: \"How do I create a session?\", \"What's the status?\", \"Something is stuck\"\n\n### Clear history\n\\`/clear\\` in the Assistant topic — resets the conversation\n\n---\n\n## System Commands\n\n| Command | Where | What it does |\n|---------|-------|-------------|\n| \\`/new [agent] [path]\\` | Anywhere | Create new session |\n| \\`/newchat\\` | Session topic | New session, same agent + folder |\n| \\`/cancel\\` | Session topic | Cancel current session |\n| \\`/status\\` | Anywhere | Show status |\n| \\`/sessions\\` | Anywhere | List all sessions |\n| \\`/agents\\` | Anywhere | Browse & install agents from ACP Registry |\n| \\`/install <name>\\` | Anywhere | Install an agent |\n| \\`/enable_dangerous\\` | Session topic | Auto-approve all permissions |\n| \\`/disable_dangerous\\` | Session topic | Restore permission prompts |\n| \\`/handoff\\` | Session topic | Transfer session to terminal |\n| \\`/clear\\` | Assistant topic | Clear assistant history |\n| \\`/menu\\` | Anywhere | Show action menu |\n| \\`/help\\` | Anywhere | Show help |\n| \\`/restart\\` | Anywhere | Restart OpenACP |\n| \\`/update\\` | Anywhere | Update to latest version |\n| \\`/integrate\\` | Anywhere | Manage agent integrations |\n\n---\n\n## Menu Buttons\n\n| Button | Action |\n|--------|--------|\n| 🆕 New Session | Create new session (interactive) |\n| 📋 Sessions | List all sessions with cleanup options |\n| 📊 Status | Show active/total session count |\n| 🤖 Agents | List available agents |\n| 🔗 Integrate | Manage agent integrations |\n| ❓ Help | Show help text |\n| 🔄 Restart | Restart OpenACP |\n| ⬆️ Update | Check and install updates |\n\n---\n\n## CLI Commands\n\n### Server\n- \\`openacp\\` — Start (uses configured mode: foreground or daemon)\n- \\`openacp start\\` — Start as background daemon\n- \\`openacp stop\\` — Stop daemon\n- \\`openacp status\\` — Show daemon status\n- \\`openacp logs\\` — Tail daemon logs\n- \\`openacp --foreground\\` — Force foreground mode (useful for debugging or containers)\n\n### Auto-start (run on boot)\n- macOS: installs a LaunchAgent in \\`~/Library/LaunchAgents/\\`\n- Linux: installs a systemd user service in \\`~/.config/systemd/user/\\`\n- Enabled automatically when you start the daemon. Remove with \\`openacp stop\\`.\n\n### Configuration\n- \\`openacp config\\` — Interactive config editor\n- \\`openacp reset\\` — Delete all data and start fresh\n\n### Agent Management (CLI)\n- \\`openacp agents\\` — List all agents (installed + available from ACP Registry)\n- \\`openacp agents install <name>\\` — Install an agent\n- \\`openacp agents uninstall <name>\\` — Remove an agent\n- \\`openacp agents info <name>\\` — Show details, dependencies, and setup guide\n- \\`openacp agents run <name> [-- args]\\` — Run agent CLI directly (for login, config, etc.)\n- \\`openacp agents refresh\\` — Force-refresh registry cache\n\n### Plugins\n- \\`openacp install <package>\\` — Install adapter plugin\n- \\`openacp uninstall <package>\\` — Remove adapter plugin\n- \\`openacp plugins\\` — List installed plugins\n\n### Integration\n- \\`openacp integrate <agent>\\` — Install agent integration (e.g., Claude handoff skill)\n- \\`openacp integrate <agent> --uninstall\\` — Remove integration\n\n### API (requires running daemon)\n\\`openacp api <command>\\` — Interact with running daemon:\n\n| Command | Description |\n|---------|-------------|\n| \\`status\\` | List active sessions |\n| \\`session <id>\\` | Session details |\n| \\`new <agent> <path>\\` | Create session |\n| \\`send <id> \"text\"\\` | Send prompt |\n| \\`cancel <id>\\` | Cancel session |\n| \\`dangerous <id> on/off\\` | Toggle dangerous mode |\n| \\`topics [--status x,y]\\` | List topics |\n| \\`delete-topic <id> [--force]\\` | Delete topic |\n| \\`cleanup [--status x,y]\\` | Cleanup old topics |\n| \\`agents\\` | List agents |\n| \\`health\\` | System health |\n| \\`config\\` | Show config |\n| \\`config set <key> <value>\\` | Update config |\n| \\`adapters\\` | List adapters |\n| \\`tunnel\\` | Tunnel status |\n| \\`notify \"message\"\\` | Send notification |\n| \\`version\\` | Daemon version |\n| \\`restart\\` | Restart daemon |\n\n---\n\n## File Viewer (Tunnel)\n\nWhen tunnel is enabled, file edits and diffs get \"View\" buttons that open in your browser:\n- **Monaco Editor** — Full VS Code editor with syntax highlighting\n- **Diff viewer** — Side-by-side or inline comparison\n- **Line highlighting** — Click lines to highlight\n- Dark/light theme toggle\n\n### Setup\nEnable in config: set \\`tunnel.enabled\\` to \\`true\\`.\nProviders: Cloudflare (default, free), ngrok, bore, Tailscale Funnel.\n\n### Port Tunneling\n\nExpose any local port (dev servers, APIs, etc.) to the internet:\n\n**CLI commands** (agent can call these directly):\n- \\`openacp tunnel add <port> --label <name>\\` — Create tunnel to a local port\n- \\`openacp tunnel list\\` — List active tunnels\n- \\`openacp tunnel stop <port>\\` — Stop a tunnel\n- \\`openacp tunnel stop-all\\` — Stop all user tunnels\n\n**Telegram commands**:\n- \\`/tunnel <port> [label]\\` — Create tunnel\n- \\`/tunnels\\` — List active tunnels\n- \\`/tunnel stop <port>\\` — Stop tunnel\n\nExample: after starting a dev server on port 3000, run \\`openacp tunnel add 3000 --label my-app\\` to get a public URL.\n\n---\n\n## Configuration\n\nConfig file: \\`~/.openacp/config.json\\`\n\n### Channels\n- **channels.telegram.botToken** — Your Telegram bot token\n- **channels.telegram.chatId** — Your Telegram supergroup ID\n- **channels.discord.botToken** — Your Discord bot token\n- **channels.discord.guildId** — Your Discord server (guild) ID\n\n### Agents\n- **defaultAgent** — Which agent to use by default\n- Agents are managed via \\`/agents\\` (Telegram) or \\`openacp agents\\` (CLI)\n- Installed agents are stored in \\`~/.openacp/agents.json\\`\n- Agent list is fetched from the ACP Registry CDN and cached locally (24h)\n\n### Workspace\n- **workspace.baseDir** — Base directory for project folders (default: \\`~/openacp-workspace\\`)\n\n### Security\n- **security.allowedUserIds** — Restrict who can use the bot (empty = everyone)\n- **security.maxConcurrentSessions** — Max parallel sessions (default: 5)\n- **security.sessionTimeoutMinutes** — Auto-cancel idle sessions (default: 60)\n\n### Tunnel / File Viewer\n- **tunnel.enabled** — Enable file viewer tunnel\n- **tunnel.provider** — Tunnel provider: cloudflare (default, free), ngrok, bore, tailscale\n- **tunnel.port** — Local port for tunnel server (default: 3100)\n- **tunnel.auth.enabled** — Enable authentication for tunnel URLs\n- **tunnel.auth.token** — Auth token for tunnel access\n- **tunnel.storeTtlMinutes** — How long viewer links stay cached (default: 60)\n\n### Logging\n- **logging.level** — Log level: silent, debug, info, warn, error, fatal (default: info)\n- **logging.logDir** — Log directory (default: \\`~/.openacp/logs\\`)\n- **logging.maxFileSize** — Max log file size before rotation\n- **logging.maxFiles** — Max number of rotated log files\n- **logging.sessionLogRetentionDays** — Auto-delete old session logs (default: 30)\n\n### Data Retention\n- **sessionStore.ttlDays** — How long session records persist (default: 30). Old records are cleaned up automatically.\n\n### Environment variables\nOverride config with env vars:\n- \\`OPENACP_TELEGRAM_BOT_TOKEN\\`\n- \\`OPENACP_TELEGRAM_CHAT_ID\\`\n- \\`OPENACP_DISCORD_BOT_TOKEN\\`\n- \\`OPENACP_DISCORD_GUILD_ID\\`\n- \\`OPENACP_DEFAULT_AGENT\\`\n- \\`OPENACP_RUN_MODE\\` — foreground or daemon\n- \\`OPENACP_API_PORT\\` — API server port (default: 21420)\n- \\`OPENACP_TUNNEL_ENABLED\\`\n- \\`OPENACP_TUNNEL_PORT\\`\n- \\`OPENACP_TUNNEL_PROVIDER\\`\n- \\`OPENACP_LOG_LEVEL\\`\n- \\`OPENACP_LOG_DIR\\`\n- \\`OPENACP_DEBUG\\` — Sets log level to debug\n\n---\n\n## Troubleshooting\n\n### Session stuck / not responding\n- Check status: ask Assistant \"Is anything stuck?\"\n- Cancel and create new: \\`/cancel\\` then \\`/new\\`\n- Check system health: Assistant can run health check\n\n### Agent not found\n- Check available agents: \\`/agents\\` or \\`openacp agents\\`\n- Install missing agent: \\`openacp agents install <name>\\`\n- Some agents need login first: \\`openacp agents info <name>\\` to see setup steps\n- Run agent CLI for setup: \\`openacp agents run <name> -- <args>\\`\n\n### Permission request not showing\n- Check Notifications topic for the alert\n- Try \\`/enable_dangerous\\` to auto-approve (if you trust the agent)\n\n### Session disappeared after restart\n- Sessions persist across restarts\n- Send a message in the old topic — it auto-resumes\n- If topic was deleted, the session record may still exist in status\n\n### Bot not responding at all\n- Check daemon: \\`openacp status\\`\n- Check logs: \\`openacp logs\\`\n- Restart: \\`openacp start\\` or \\`/restart\\`\n\n### Messages going to wrong topic\n- Each session is bound to a specific topic/thread\n- If you see messages appearing in the Assistant topic instead of the session topic, try creating a new session\n\n### Viewing logs\n- Session-specific logs: \\`~/.openacp/logs/sessions/\\`\n- System logs: \\`openacp logs\\` to tail live\n- Set \\`OPENACP_DEBUG=true\\` for verbose output\n\n---\n\n## Data & Storage\n\nAll data is stored in \\`~/.openacp/\\`:\n- \\`config.json\\` — Configuration\n- \\`agents.json\\` — Installed agents (managed by AgentCatalog)\n- \\`registry-cache.json\\` — Cached ACP Registry data (refreshes every 24h)\n- \\`agents/\\` — Downloaded binary agents\n- \\`sessions/\\` — Session records and state\n- \\`topics/\\` — Topic-to-session mappings\n- \\`logs/\\` — System and session logs\n- \\`plugins/\\` — Installed adapter plugins\n- \\`openacp.pid\\` — Daemon PID file\n\nSession records auto-cleanup: 30 days (configurable via \\`sessionStore.ttlDays\\`).\nSession logs auto-cleanup: 30 days (configurable via \\`logging.sessionLogRetentionDays\\`).\n`;\n","import type { OpenACPCore, IChannelAdapter, Config, Session } from \"../../core/index.js\";\nimport { createChildLogger } from \"../../core/utils/log.js\";\nimport { PRODUCT_GUIDE } from \"../../data/product-guide.js\";\nconst log = createChildLogger({ module: \"telegram-assistant\" });\n\nexport type SpawnAssistantResult = {\n session: Session;\n /** Resolves when the background system prompt completes (or fails). */\n ready: Promise<void>;\n};\n\nexport async function spawnAssistant(\n core: OpenACPCore,\n adapter: IChannelAdapter,\n assistantTopicId: number,\n): Promise<SpawnAssistantResult> {\n const config = core.configManager.get();\n\n // Create session with default agent via unified pipeline\n log.info({ agent: config.defaultAgent }, \"Creating assistant session...\");\n const session = await core.createSession({\n channelId: \"telegram\",\n agentName: config.defaultAgent,\n workingDirectory: core.configManager.resolveWorkspace(),\n initialName: \"Assistant\", // Prevent auto-naming from triggering after system prompt\n });\n session.threadId = String(assistantTopicId);\n log.info({ sessionId: session.id }, \"Assistant agent spawned\");\n\n // Build dynamic context for system prompt\n const allRecords = core.sessionManager.listRecords();\n const activeCount = allRecords.filter(r => r.status === 'active' || r.status === 'initializing').length;\n const statusCounts = new Map<string, number>();\n for (const r of allRecords) {\n statusCounts.set(r.status, (statusCounts.get(r.status) ?? 0) + 1);\n }\n const topicSummary = Array.from(statusCounts.entries()).map(([status, count]) => ({ status, count }));\n\n // Get agent info from catalog\n const installedAgents = Object.keys(core.agentCatalog.getInstalledEntries());\n const availableItems = core.agentCatalog.getAvailable();\n const availableAgentCount = availableItems.filter(i => !i.installed).length;\n\n const ctx: AssistantContext = {\n config,\n activeSessionCount: activeCount,\n totalSessionCount: allRecords.length,\n topicSummary,\n installedAgents,\n availableAgentCount,\n };\n\n // Fire system prompt in background — don't block startup.\n const systemPrompt = buildAssistantSystemPrompt(ctx);\n const ready = session.enqueuePrompt(systemPrompt)\n .then(() => { log.info({ sessionId: session.id }, \"Assistant system prompt completed\"); })\n .catch((err) => { log.warn({ err }, \"Assistant system prompt failed\"); });\n\n return { session, ready };\n}\n\nexport interface AssistantContext {\n config: Config\n activeSessionCount: number\n totalSessionCount: number\n topicSummary: { status: string; count: number }[]\n installedAgents?: string[]\n availableAgentCount?: number\n}\n\nexport interface WelcomeContext {\n activeCount: number;\n errorCount: number;\n totalCount: number;\n agents: string[];\n defaultAgent: string;\n}\n\nexport function buildWelcomeMessage(ctx: WelcomeContext): string {\n const { activeCount, errorCount, totalCount, agents, defaultAgent } = ctx;\n\n const agentList = agents\n .map((a) => `${a}${a === defaultAgent ? \" (default)\" : \"\"}`)\n .join(\", \");\n\n // Variant 1: No sessions\n if (totalCount === 0) {\n return `👋 <b>OpenACP is ready!</b>\\n\\nNo sessions yet. Tap 🆕 New Session to start, or ask me anything!`;\n }\n\n // Variant 2: Has errors\n if (errorCount > 0) {\n return (\n `👋 <b>OpenACP is ready!</b>\\n\\n` +\n `📊 ${activeCount} active, ${errorCount} errors / ${totalCount} total\\n` +\n `⚠️ ${errorCount} session${errorCount > 1 ? \"s have\" : \" has\"} errors — ask me to check if you'd like.\\n\\n` +\n `Agents: ${agentList}`\n );\n }\n\n // Variant 3/4: Has active or fallback\n return (\n `👋 <b>OpenACP is ready!</b>\\n\\n` +\n `📊 ${activeCount} active / ${totalCount} total\\n` +\n `Agents: ${agentList}`\n );\n}\n\nexport function buildAssistantSystemPrompt(ctx: AssistantContext): string {\n const { config, activeSessionCount, totalSessionCount, topicSummary, installedAgents, availableAgentCount } = ctx;\n const agentNames = installedAgents?.length ? installedAgents.join(\", \") : Object.keys(config.agents).join(\", \");\n const topicBreakdown =\n topicSummary.map((s) => `${s.status}: ${s.count}`).join(\", \") || \"none\";\n\n return `You are the OpenACP Assistant — a helpful guide for managing AI coding sessions.\n\n## Current State\n- Active sessions: ${activeSessionCount} / ${totalSessionCount} total\n- Topics by status: ${topicBreakdown}\n- Installed agents: ${agentNames}\n- Available in ACP Registry: ${availableAgentCount ?? \"28+\"} more agents (use /agents to browse)\n- Default agent: ${config.defaultAgent}\n- Workspace base directory: ${config.workspace.baseDir}\n- STT: ${config.speech?.stt?.provider ? `${config.speech.stt.provider} ✅` : \"Not configured\"}\n\n## Action Playbook\n\n### Create Session\n- The workspace is the project directory where the agent will work (read, write, execute code). It is NOT the base directory — it should be a specific project folder like \\`~/code/my-project\\` or \\`${config.workspace.baseDir}/my-app\\`.\n- Ask which agent to use (if multiple are installed). Show installed: ${agentNames}\n- Ask which project directory to use as workspace. Suggest \\`${config.workspace.baseDir}\\` as the base, but explain the user can provide any path.\n- Confirm before creating: show agent name + full workspace path.\n- Create via: \\`openacp api new <agent> <workspace> --channel telegram\\`\n\n### Browse & Install Agents\n- Guide users to /agents command to see all available agents (installed + from ACP Registry)\n- The /agents list is paginated with install buttons — users can tap to install directly\n- For CLI users: \\`openacp agents install <name>\\`\n- Some agents need login/setup after install — guide users to \\`openacp agents info <name>\\` for setup steps\n- To run agent CLI for login: \\`openacp agents run <name> -- <args>\\`\n- Common setup examples:\n - Gemini: \\`openacp agents run gemini -- auth login\\`\n - GitHub Copilot: \\`openacp agents run copilot -- auth login\\`\n - Codex: needs OPENAI_API_KEY environment variable\n\n### Check Status / List Sessions\n- Run \\`openacp api status\\` for active sessions overview\n- Run \\`openacp api topics\\` for full list with statuses\n- Format the output nicely for the user\n\n### Cancel Session\n- Run \\`openacp api status\\` to see what's active\n- If 1 active session → ask user to confirm → \\`openacp api cancel <id>\\`\n- If multiple → list them, ask user which one to cancel\n\n### Troubleshoot (Session Stuck, Errors)\n- Run \\`openacp api health\\` + \\`openacp api status\\` to diagnose\n- Small issue (stuck session) → suggest cancel + create new\n- Big issue (system-level) → suggest restart, ask for confirmation first\n\n### Cleanup Old Sessions\n- Run \\`openacp api topics --status finished,error\\` to see what can be cleaned\n- Report the count, ask user to confirm\n- Execute: \\`openacp api cleanup --status <statuses>\\`\n\n### Configuration\n- View: \\`openacp config\\` (or \\`openacp api config\\` — deprecated)\n- Update: \\`openacp config set <key> <value>\\`\n- When user asks about \"settings\" or \"config\", use \\`openacp config set\\` directly\n- When receiving a delegated request from the Settings menu, ask user for the new value, then apply with \\`openacp config set <path> <value>\\`\n\n### Voice / Speech-to-Text\n- OpenACP can transcribe voice messages to text using STT providers (Groq Whisper, OpenAI Whisper)\n- Current STT provider: ${config.speech?.stt?.provider ?? \"Not configured\"}\n- To enable: user needs an API key from the STT provider\n - Groq (recommended, free tier ~8h/day): Get key at console.groq.com → API Keys\n - Set via: \\`openacp config set speech.stt.provider groq\\` then \\`openacp config set speech.stt.providers.groq.apiKey <key>\\`\n- When STT is configured, voice messages are automatically transcribed before sending to agents that don't support audio\n- Agents with audio capability receive the audio directly (no transcription needed)\n- User can also configure via /settings → STT Provider\n\n### Restart / Update\n- Always ask for confirmation — these are disruptive actions\n- Guide user: \"Tap 🔄 Restart button or type /restart\"\n\n### Toggle Dangerous Mode\n- Run \\`openacp api dangerous <id> on|off\\`\n- Explain: dangerous mode auto-approves all permission requests — the agent can run any command without asking\n\n## CLI Commands Reference\n\\`\\`\\`bash\n# Session management\nopenacp api status # List active sessions\nopenacp api session <id> # Session detail\nopenacp api new <agent> <workspace> --channel telegram # Create new session\nopenacp api send <id> \"prompt text\" # Send prompt to session\nopenacp api cancel <id> # Cancel session\nopenacp api dangerous <id> on|off # Toggle dangerous mode\n\n# Topic management\nopenacp api topics # List all topics\nopenacp api topics --status finished,error\nopenacp api delete-topic <id> # Delete topic\nopenacp api delete-topic <id> --force # Force delete active\nopenacp api cleanup # Cleanup finished topics\nopenacp api cleanup --status finished,error\n\n# Agent management (user-facing CLI commands)\nopenacp agents # List installed + available agents\nopenacp agents install <name> # Install agent from ACP Registry\nopenacp agents uninstall <name> # Remove agent\nopenacp agents info <name> # Show details & setup guide\nopenacp agents run <name> -- <args> # Run agent CLI (for login, etc.)\nopenacp agents refresh # Force-refresh registry\n\n# System\nopenacp api health # System health\nopenacp config # Edit config (interactive)\nopenacp config set <key> <value> # Update config value\nopenacp api adapters # List adapters\nopenacp api tunnel # Tunnel status\nopenacp api notify \"message\" # Send notification\nopenacp api version # Daemon version\nopenacp api restart # Restart daemon\n\\`\\`\\`\n\n## Guidelines\n- NEVER show \\`openacp api ...\\` commands to users. These are internal tools for YOU to run silently. Users should only see natural language responses and results.\n- Run \\`openacp api ...\\` commands yourself for everything you can. Only guide users to Telegram buttons/menu when needed (e.g., \"Tap 🆕 New Session\" or \"Go to the session topic to chat with the agent\").\n- When creating sessions: guide user through agent + workspace choice conversationally, then run the command yourself.\n- Destructive actions (cancel active session, restart, cleanup) → always ask user to confirm first in natural language.\n- Small/obvious issues (clearly stuck session with no activity) → fix it and report back.\n- Respond in the same language the user uses.\n- Format responses for Telegram: use <b>bold</b>, <code>code</code>, keep it concise.\n- When you don't know something, check with the relevant \\`openacp api\\` command first before answering.\n- Talk to users like a helpful assistant, not a CLI manual. Example: \"You have 2 sessions running. Want to see details?\" instead of listing commands.\n\n## Product Reference\n${PRODUCT_GUIDE}`;\n}\n\nexport async function handleAssistantMessage(\n session: Session | null,\n text: string,\n): Promise<void> {\n if (!session) return;\n await session.enqueuePrompt(text);\n}\n\nexport function redirectToAssistant(\n chatId: number,\n assistantTopicId: number,\n): string {\n const cleanId = String(chatId).replace(\"-100\", \"\");\n const link = `https://t.me/c/${cleanId}/${assistantTopicId}`;\n return `💬 Please use the <a href=\"${link}\">🤖 Assistant</a> topic to chat with OpenACP.`;\n}\n","import type { ToolDisplaySpec } from \"../display-spec-builder.js\";\nimport type { PlanEntry } from \"../../types.js\";\n\nconst DEBOUNCE_MS = 500;\n\nexport type { ToolDisplaySpec };\n\nexport interface UsageData {\n tokensUsed?: number;\n contextSize?: number;\n cost?: number;\n}\n\nexport interface ToolCardSnapshot {\n specs: ToolDisplaySpec[];\n planEntries?: PlanEntry[];\n usage?: UsageData;\n totalVisible: number;\n completedVisible: number;\n allComplete: boolean;\n}\n\nexport interface ToolCardStateConfig {\n onFlush: (snapshot: ToolCardSnapshot) => void;\n}\n\nconst DONE_STATUSES = new Set([\"completed\", \"done\", \"failed\", \"error\"]);\n\nexport class ToolCardState {\n private specs: ToolDisplaySpec[] = [];\n private planEntries?: PlanEntry[];\n private usage?: UsageData;\n private finalized = false;\n private isFirstFlush = true;\n private debounceTimer?: ReturnType<typeof setTimeout>;\n private onFlush: (snapshot: ToolCardSnapshot) => void;\n\n constructor(config: ToolCardStateConfig) {\n this.onFlush = config.onFlush;\n }\n\n updateFromSpec(spec: ToolDisplaySpec): void {\n const existingIdx = this.specs.findIndex((s) => s.id === spec.id);\n if (existingIdx >= 0) {\n this.specs[existingIdx] = spec;\n } else {\n this.specs.push(spec);\n }\n\n if (this.finalized) {\n this.onFlush(this.snapshot());\n return;\n }\n\n if (this.isFirstFlush) {\n this.isFirstFlush = false;\n this.flush();\n } else {\n this.scheduleFlush();\n }\n }\n\n updatePlan(entries: PlanEntry[]): void {\n if (this.finalized) return;\n this.planEntries = entries;\n\n if (this.specs.length === 0 && this.isFirstFlush) {\n this.isFirstFlush = false;\n this.flush();\n } else {\n this.scheduleFlush();\n }\n }\n\n appendUsage(usage: UsageData): void {\n if (this.finalized) return;\n this.usage = usage;\n this.scheduleFlush();\n }\n\n finalize(): void {\n if (this.finalized) return;\n this.finalized = true;\n this.clearDebounce();\n this.flush();\n }\n\n destroy(): void {\n this.finalized = true;\n this.clearDebounce();\n }\n\n hasContent(): boolean {\n return this.specs.length > 0 || this.planEntries !== undefined;\n }\n\n private snapshot(): ToolCardSnapshot {\n const visible = this.specs.filter((s) => !s.isHidden);\n const completedVisible = visible.filter((s) => DONE_STATUSES.has(s.status)).length;\n const allComplete = visible.length > 0 && completedVisible === visible.length;\n return {\n specs: this.specs,\n planEntries: this.planEntries,\n usage: this.usage,\n totalVisible: visible.length,\n completedVisible,\n allComplete,\n };\n }\n\n private flush(): void {\n this.clearDebounce();\n this.onFlush(this.snapshot());\n }\n\n private scheduleFlush(): void {\n this.clearDebounce();\n this.debounceTimer = setTimeout(() => {\n this.debounceTimer = undefined;\n this.flush();\n }, DEBOUNCE_MS);\n }\n\n private clearDebounce(): void {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = undefined;\n }\n }\n}\n","// src/core/adapter-primitives/stream-accumulator.ts\n\nimport type { ToolCallMeta, ViewerLinks } from \"./format-types.js\";\nimport { evaluateNoise } from \"./message-formatter.js\";\n\nexport interface ToolEntry {\n id: string;\n name: string;\n kind: string;\n rawInput: unknown;\n content: string | null;\n status: string;\n viewerLinks?: ViewerLinks;\n diffStats?: { added: number; removed: number };\n displaySummary?: string;\n displayTitle?: string;\n displayKind?: string;\n isNoise: boolean;\n}\n\ninterface PendingUpdate {\n status: string;\n rawInput?: unknown;\n content?: string | null;\n viewerLinks?: ViewerLinks;\n diffStats?: { added: number; removed: number };\n}\n\nexport class ToolStateMap {\n private entries: Map<string, ToolEntry> = new Map();\n private pendingUpdates: Map<string, PendingUpdate> = new Map();\n\n /**\n * Creates or updates an entry from a tool_call event.\n * If a pending update exists for this id, applies it immediately.\n */\n upsert(meta: ToolCallMeta, kind: string, rawInput: unknown): ToolEntry {\n const isNoise = evaluateNoise(meta.name, kind, rawInput) !== null;\n\n const entry: ToolEntry = {\n id: meta.id,\n name: meta.name,\n kind,\n rawInput,\n content: null,\n status: meta.status ?? \"running\",\n viewerLinks: meta.viewerLinks,\n displaySummary: meta.displaySummary,\n displayTitle: meta.displayTitle,\n displayKind: meta.displayKind,\n isNoise,\n };\n\n this.entries.set(meta.id, entry);\n\n // Apply any pending update that arrived before the initial call\n const pending = this.pendingUpdates.get(meta.id);\n if (pending) {\n this.pendingUpdates.delete(meta.id);\n this._applyUpdate(entry, pending);\n }\n\n return entry;\n }\n\n /**\n * Updates an existing entry from a tool_call_update event.\n * If the entry doesn't exist yet (out-of-order delivery), buffers the update.\n */\n merge(\n id: string,\n status: string,\n rawInput?: unknown,\n content?: string | null,\n viewerLinks?: ViewerLinks,\n diffStats?: { added: number; removed: number },\n ): ToolEntry | undefined {\n const entry = this.entries.get(id);\n\n if (!entry) {\n // Buffer the update for when upsert is called\n this.pendingUpdates.set(id, { status, rawInput, content, viewerLinks, diffStats });\n return undefined;\n }\n\n this._applyUpdate(entry, { status, rawInput, content, viewerLinks, diffStats });\n return entry;\n }\n\n private _applyUpdate(entry: ToolEntry, update: PendingUpdate): void {\n entry.status = update.status;\n if (update.rawInput !== undefined) {\n entry.rawInput = update.rawInput;\n }\n if (update.content !== undefined) {\n entry.content = update.content ?? null;\n }\n if (update.viewerLinks !== undefined) {\n entry.viewerLinks = update.viewerLinks;\n }\n if (update.diffStats !== undefined) {\n entry.diffStats = update.diffStats;\n }\n }\n\n get(id: string): ToolEntry | undefined {\n return this.entries.get(id);\n }\n\n clear(): void {\n this.entries.clear();\n this.pendingUpdates.clear();\n }\n}\n\nexport class ThoughtBuffer {\n private chunks: string[] = [];\n private sealed = false;\n\n append(chunk: string): void {\n if (this.sealed) return;\n this.chunks.push(chunk);\n }\n\n seal(): string {\n this.sealed = true;\n return this.chunks.join(\"\");\n }\n\n getText(): string {\n return this.chunks.join(\"\");\n }\n\n isSealed(): boolean {\n return this.sealed;\n }\n\n reset(): void {\n this.chunks = [];\n this.sealed = false;\n }\n}\n","// src/core/adapter-primitives/display-spec-builder.ts\n\nimport { KIND_ICONS } from \"./format-types.js\";\nimport type { OutputMode, ViewerLinks } from \"./format-types.js\";\nimport type { ToolEntry } from \"./stream-accumulator.js\";\nimport type { TunnelServiceInterface } from \"../plugin/types.js\";\n\n// ─── Output spec interfaces ────────────────────────────────────────────────\n\nexport interface ToolDisplaySpec {\n id: string;\n kind: string;\n icon: string;\n title: string;\n description: string | null;\n command: string | null;\n inputContent: string | null;\n outputSummary: string | null;\n outputContent: string | null;\n diffStats: { added: number; removed: number } | null;\n viewerLinks?: ViewerLinks;\n outputViewerLink?: string;\n outputFallbackContent?: string;\n status: string;\n isNoise: boolean;\n isHidden: boolean;\n}\n\nexport interface ThoughtDisplaySpec {\n indicator: string;\n content: string | null;\n}\n\n// ─── Constants ────────────────────────────────────────────────────────────\n\n/** Kinds that have a runnable command in rawInput.command */\nconst EXECUTE_KINDS = new Set([\"execute\", \"bash\", \"command\", \"terminal\"]);\n\nconst INLINE_MAX_LINES = 15;\nconst INLINE_MAX_CHARS = 800;\n\n// ─── Helpers ──────────────────────────────────────────────────────────────\n\nfunction asRecord(value: unknown): Record<string, unknown> {\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n return {};\n}\n\nfunction capitalize(s: string): string {\n return s.length === 0 ? s : s[0].toUpperCase() + s.slice(1);\n}\n\nfunction buildTitle(entry: ToolEntry, kind: string): string {\n // Explicit overrides take highest priority\n if (entry.displayTitle) return entry.displayTitle;\n if (entry.displaySummary) return entry.displaySummary;\n\n const input = asRecord(entry.rawInput);\n\n if (kind === \"read\") {\n const filePath = typeof input.file_path === \"string\" ? input.file_path : null;\n if (filePath) {\n // start_line/end_line style\n const startLine = typeof input.start_line === \"number\" ? input.start_line : null;\n const endLine = typeof input.end_line === \"number\" ? input.end_line : null;\n if (startLine !== null && endLine !== null) return `${filePath} (lines ${startLine}–${endLine})`;\n if (startLine !== null) return `${filePath} (from line ${startLine})`;\n // offset/limit style (Claude Code Read tool)\n const offset = typeof input.offset === \"number\" ? input.offset : null;\n const limit = typeof input.limit === \"number\" ? input.limit : null;\n if (offset !== null && limit !== null) return `${filePath} (lines ${offset}–${offset + limit - 1})`;\n if (offset !== null) return `${filePath} (from line ${offset})`;\n return filePath;\n }\n return capitalize(entry.name);\n }\n\n if (kind === \"edit\" || kind === \"write\" || kind === \"delete\") {\n const filePath =\n typeof input.file_path === \"string\"\n ? input.file_path\n : typeof input.path === \"string\"\n ? input.path\n : null;\n if (filePath) return filePath;\n return capitalize(entry.name);\n }\n\n if (EXECUTE_KINDS.has(kind)) {\n const description = typeof input.description === \"string\" ? input.description : null;\n if (description) return description;\n const command = typeof input.command === \"string\" ? input.command : null;\n if (command) return command.length > 60 ? command.slice(0, 57) + \"...\" : command;\n return capitalize(entry.name);\n }\n\n if (kind === \"agent\") {\n const skill = typeof input.skill === \"string\" ? input.skill : null;\n const description = typeof input.description === \"string\" ? input.description : null;\n const subtype = typeof input.subagent_type === \"string\" ? input.subagent_type : null;\n if (skill) return skill;\n if (description) return description.length > 60 ? description.slice(0, 57) + \"...\" : description;\n if (subtype) return subtype;\n return capitalize(entry.name);\n }\n\n if (kind === \"search\") {\n const pattern =\n typeof input.pattern === \"string\"\n ? input.pattern\n : typeof input.query === \"string\"\n ? input.query\n : null;\n if (pattern) {\n let title = `${capitalize(entry.name)} \"${pattern}\"`;\n const glob = typeof input.glob === \"string\" ? input.glob : null;\n const type = typeof input.type === \"string\" ? input.type : null;\n if (glob) title += ` (glob: ${glob})`;\n else if (type) title += ` (type: ${type})`;\n return title;\n }\n return capitalize(entry.name);\n }\n\n // Show skill name for Skill tool calls (e.g. Claude Code's Skill tool)\n if (entry.name.toLowerCase() === \"skill\" && typeof input.skill === \"string\" && input.skill) {\n return input.skill;\n }\n\n return entry.name;\n}\n\nfunction buildOutputSummary(content: string): string {\n const lines = content.split(\"\\n\").length;\n return `${lines} line${lines === 1 ? \"\" : \"s\"} of output`;\n}\n\nfunction isShortOutput(content: string): boolean {\n return content.split(\"\\n\").length <= INLINE_MAX_LINES && content.length <= INLINE_MAX_CHARS;\n}\n\n/** Check if title was derived from the command (exact match or truncated version) */\nfunction isTitleFromCommand(title: string, command: string): boolean {\n return title === command || (command.length > 60 && title === command.slice(0, 57) + \"...\");\n}\n\n// ─── DisplaySpecBuilder ───────────────────────────────────────────────────\n\nexport class DisplaySpecBuilder {\n constructor(private tunnelService?: TunnelServiceInterface) {}\n\n buildToolSpec(\n entry: ToolEntry,\n mode: OutputMode,\n sessionContext?: { id: string; workingDirectory: string },\n ): ToolDisplaySpec {\n const effectiveKind = entry.displayKind ?? entry.kind;\n const icon = KIND_ICONS[effectiveKind] ?? KIND_ICONS[\"other\"] ?? \"🛠️\";\n const title = buildTitle(entry, effectiveKind);\n const isHidden = entry.isNoise && mode !== \"high\";\n\n // Fields that are always null on low\n const includeMeta = mode !== \"low\";\n\n const input = asRecord(entry.rawInput);\n\n // Deduplicate: skip description if it matches title, kind label, or tool name\n const rawDescription = typeof input.description === \"string\" ? input.description : null;\n const descLower = rawDescription?.toLowerCase();\n const description =\n includeMeta && rawDescription && rawDescription !== title\n && descLower !== effectiveKind && descLower !== entry.name.toLowerCase()\n ? rawDescription : null;\n\n // Deduplicate: skip command if title was derived from it\n const rawCommand =\n EXECUTE_KINDS.has(effectiveKind) && typeof input.command === \"string\"\n ? input.command\n : null;\n const command =\n includeMeta && rawCommand && !isTitleFromCommand(title, rawCommand)\n ? rawCommand\n : null;\n\n const inputContent: string | null = null;\n\n const content = entry.content;\n\n let outputSummary: string | null = null;\n let outputContent: string | null = null;\n let outputViewerLink: string | undefined = undefined;\n let outputFallbackContent: string | undefined = undefined;\n\n if (content && content.trim().length > 0 && includeMeta) {\n outputSummary = buildOutputSummary(content);\n\n const isLong =\n content.split(\"\\n\").length > INLINE_MAX_LINES || content.length > INLINE_MAX_CHARS;\n\n if (isLong) {\n const publicUrl = this.tunnelService?.getPublicUrl();\n const hasPublicTunnel = !!publicUrl && !publicUrl.startsWith(\"http://localhost\") && !publicUrl.startsWith(\"http://127.0.0.1\");\n if (this.tunnelService && sessionContext && hasPublicTunnel) {\n const label =\n typeof input.command === \"string\" ? input.command : entry.name;\n const id = this.tunnelService.getStore().storeOutput(sessionContext.id, label, content);\n if (id !== null) {\n outputViewerLink = this.tunnelService.outputUrl(id);\n }\n } else if (mode === \"high\") {\n outputFallbackContent = content;\n }\n } else if (mode === \"high\") {\n outputContent = content;\n }\n }\n\n const diffStats = includeMeta ? (entry.diffStats ?? null) : null;\n\n return {\n id: entry.id,\n kind: effectiveKind,\n icon,\n title,\n description,\n command,\n inputContent,\n outputSummary,\n outputContent,\n diffStats,\n viewerLinks: entry.viewerLinks,\n outputViewerLink,\n outputFallbackContent,\n status: entry.status,\n isNoise: entry.isNoise,\n isHidden,\n };\n }\n\n buildThoughtSpec(content: string, mode: OutputMode): ThoughtDisplaySpec {\n const indicator = \"Thinking...\";\n return {\n indicator,\n content: mode === \"high\" ? content : null,\n };\n }\n}\n","import type { Bot } from \"grammy\";\nimport { createChildLogger } from \"../../core/utils/log.js\";\nimport type { PlanEntry } from \"../../core/types.js\";\nimport type { ToolCallMeta, ViewerLinks } from \"../../core/adapter-primitives/format-types.js\";\nimport type { SendQueue } from \"../../core/adapter-primitives/primitives/send-queue.js\";\nimport type { DebugTracer } from \"../../core/utils/debug-tracer.js\";\nimport { ToolCardState } from \"../../core/adapter-primitives/primitives/tool-card-state.js\";\nimport type { ToolCardSnapshot } from \"../../core/adapter-primitives/primitives/tool-card-state.js\";\nimport { escapeHtml, renderToolCard, splitToolCardText } from \"./formatting.js\";\nimport { ToolStateMap } from \"../../core/adapter-primitives/stream-accumulator.js\";\nimport { ThoughtBuffer } from \"../../core/adapter-primitives/stream-accumulator.js\";\nimport { DisplaySpecBuilder } from \"../../core/adapter-primitives/display-spec-builder.js\";\nimport type { ToolDisplaySpec } from \"../../core/adapter-primitives/display-spec-builder.js\";\nimport type { OutputMode } from \"../../core/adapter-primitives/format-types.js\";\nimport type { TunnelServiceInterface } from \"../../core/plugin/types.js\";\n\nconst log = createChildLogger({ module: \"telegram:activity\" });\n\n// ─── ThinkingIndicator ────────────────────────────────────────────────────────\n\nconst THINKING_REFRESH_MS = 15_000;\nconst THINKING_MAX_MS = 3 * 60 * 1000;\n\nexport class ThinkingIndicator {\n private msgId?: number;\n private sending = false;\n private dismissed = false;\n private refreshTimer?: ReturnType<typeof setInterval>;\n private showTime = 0;\n private tracer: DebugTracer | null;\n\n constructor(\n private api: Bot[\"api\"],\n private chatId: number,\n private threadId: number,\n private sendQueue: SendQueue,\n private sessionId: string = \"\",\n tracer: DebugTracer | null = null,\n ) {\n this.tracer = tracer;\n }\n\n async show(): Promise<void> {\n if (this.sending || this.dismissed) return;\n if (this.msgId) return;\n this.sending = true;\n this.showTime = Date.now();\n const text = \"💭 <i>Thinking...</i>\";\n try {\n const result = await this.sendQueue.enqueue(() =>\n this.api.sendMessage(this.chatId, text, {\n message_thread_id: this.threadId,\n parse_mode: \"HTML\",\n disable_notification: true,\n }),\n );\n if (result) {\n this.tracer?.log(\"telegram\", { action: \"thinking:show\", sessionId: this.sessionId, msgId: result.message_id });\n if (this.dismissed) {\n // dismissed during queue wait — message stays in chat (no delete to save API calls)\n } else {\n this.msgId = result.message_id;\n this.startRefreshTimer();\n }\n }\n } catch (err) {\n log.warn({ err }, \"ThinkingIndicator.show() failed\");\n } finally {\n this.sending = false;\n }\n }\n\n /** Edit the indicator message to append a viewer link, then dismiss. */\n async finalizeWithViewerLink(url: string): Promise<void> {\n this.stopRefreshTimer();\n if (this.msgId && !this.dismissed) {\n const text = `💭 <i>Thinking...</i> <a href=\"${escapeHtml(url)}\">View thinking</a>`;\n await this.sendQueue\n .enqueue(() => {\n if (!this.msgId) return Promise.resolve(undefined);\n return this.api.editMessageText(this.chatId, this.msgId, text, { parse_mode: \"HTML\" });\n })\n .catch(() => {});\n }\n this.dismissed = true;\n this.msgId = undefined;\n }\n\n /** Dismiss indicator: stops refresh timer. Message is left in chat to reduce API calls. */\n async dismiss(): Promise<void> {\n if (this.dismissed) return;\n this.dismissed = true;\n this.tracer?.log(\"telegram\", { action: \"thinking:dismiss\", sessionId: this.sessionId });\n this.stopRefreshTimer();\n this.msgId = undefined;\n }\n\n /** Reset for a new prompt cycle */\n reset(): void {\n this.dismissed = false;\n }\n\n private startRefreshTimer(): void {\n this.stopRefreshTimer();\n this.refreshTimer = setInterval(() => {\n if (\n this.dismissed ||\n !this.msgId ||\n Date.now() - this.showTime >= THINKING_MAX_MS\n ) {\n this.stopRefreshTimer();\n return;\n }\n const elapsed = Math.round((Date.now() - this.showTime) / 1000);\n const refreshText = `💭 <i>Still thinking... (${elapsed}s)</i>`;\n this.sendQueue\n .enqueue(() => {\n // Re-check after waiting in queue — dismiss may have been called\n if (this.dismissed || !this.msgId) return Promise.resolve(undefined);\n return this.api.editMessageText(\n this.chatId,\n this.msgId,\n refreshText,\n { parse_mode: \"HTML\" },\n );\n })\n .then(() => {})\n .catch(() => {});\n }, THINKING_REFRESH_MS);\n }\n\n private stopRefreshTimer(): void {\n if (this.refreshTimer) {\n clearInterval(this.refreshTimer);\n this.refreshTimer = undefined;\n }\n }\n}\n\n// ─── ToolCard ─────────────────────────────────────────────────────────────────\n\nexport class ToolCard {\n private state: ToolCardState;\n private msgId?: number;\n private lastSentText?: string;\n private flushPromise: Promise<void> = Promise.resolve();\n private overflowMsgIds: number[] = [];\n private tracer: DebugTracer | null;\n private sessionId: string;\n\n constructor(\n private api: Bot[\"api\"],\n private chatId: number,\n private threadId: number,\n private sendQueue: SendQueue,\n sessionId: string = \"\",\n tracer: DebugTracer | null = null,\n ) {\n this.tracer = tracer;\n this.sessionId = sessionId;\n this.state = new ToolCardState({\n onFlush: (snapshot) => {\n this.flushPromise = this.flushPromise\n .then(() => this._sendOrEdit(snapshot))\n .catch(() => {});\n },\n });\n }\n\n updateFromSpec(spec: ToolDisplaySpec): void {\n this.state.updateFromSpec(spec);\n }\n\n updatePlan(entries: PlanEntry[]): void {\n this.state.updatePlan(entries);\n }\n\n appendUsage(usage: { tokensUsed?: number; contextSize?: number; cost?: number }): void {\n this.state.appendUsage(usage);\n }\n\n async finalize(): Promise<void> {\n this.state.finalize();\n await this.flushPromise;\n }\n\n destroy(): void {\n this.state.destroy();\n }\n\n hasContent(): boolean {\n return this.state.hasContent();\n }\n\n getMsgId(): number | undefined {\n return this.msgId;\n }\n\n private async _sendOrEdit(snapshot: ToolCardSnapshot): Promise<void> {\n // Overflow strip: if full render exceeds Telegram limit, strip inline outputContent\n let snapshotToRender = snapshot;\n let fullText = renderToolCard(snapshotToRender);\n if (fullText.length > 4096) {\n snapshotToRender = {\n ...snapshot,\n specs: snapshot.specs.map((s) =>\n s.outputContent ? { ...s, outputContent: null } : s\n ),\n };\n fullText = renderToolCard(snapshotToRender);\n }\n\n if (!fullText) return;\n if (this.msgId && fullText === this.lastSentText) return;\n this.lastSentText = fullText;\n\n const chunks = splitToolCardText(fullText);\n this.tracer?.log(\"telegram\", { action: \"toolCard:render\", sessionId: this.sessionId, chunks: chunks.length, total: snapshot.totalVisible, completed: snapshot.completedVisible, allComplete: snapshot.allComplete, msgId: this.msgId, entries: snapshot.specs.map(s => ({ id: s.id, kind: s.kind, icon: s.icon, title: s.title })), html: fullText });\n\n try {\n const firstChunk = chunks[0];\n if (this.msgId) {\n await this.sendQueue.enqueue(() =>\n this.api.editMessageText(this.chatId, this.msgId!, firstChunk, { parse_mode: \"HTML\" }),\n );\n this.tracer?.log(\"telegram\", { action: \"telegram:edit\", sessionId: this.sessionId, msgId: this.msgId, html: firstChunk });\n } else {\n const result = await this.sendQueue.enqueue(() =>\n this.api.sendMessage(this.chatId, firstChunk, {\n message_thread_id: this.threadId,\n parse_mode: \"HTML\",\n disable_notification: true,\n }),\n );\n if (result) this.msgId = result.message_id;\n this.tracer?.log(\"telegram\", { action: \"telegram:send\", sessionId: this.sessionId, msgId: result?.message_id, html: firstChunk });\n }\n\n for (let i = 1; i < chunks.length; i++) {\n const overflowIdx = i - 1;\n if (overflowIdx < this.overflowMsgIds.length) {\n await this.sendQueue.enqueue(() =>\n this.api.editMessageText(this.chatId, this.overflowMsgIds[overflowIdx], chunks[i], { parse_mode: \"HTML\" }),\n );\n this.tracer?.log(\"telegram\", { action: \"telegram:edit:overflow\", sessionId: this.sessionId, msgId: this.overflowMsgIds[overflowIdx] });\n } else {\n const result = await this.sendQueue.enqueue(() =>\n this.api.sendMessage(this.chatId, chunks[i], {\n message_thread_id: this.threadId,\n parse_mode: \"HTML\",\n disable_notification: true,\n }),\n );\n if (result) this.overflowMsgIds.push(result.message_id);\n this.tracer?.log(\"telegram\", { action: \"telegram:send:overflow\", sessionId: this.sessionId, msgId: result?.message_id });\n }\n }\n } catch (err) {\n log.warn({ err }, \"[ToolCard] send/edit failed\");\n }\n }\n}\n\n// ─── ActivityTracker ──────────────────────────────────────────────────────────\n\nexport class ActivityTracker {\n private isFirstEvent = true;\n private thinking: ThinkingIndicator;\n private toolCard: ToolCard;\n private previousToolCard?: ToolCard;\n private toolStateMap: ToolStateMap;\n private previousToolStateMap?: ToolStateMap;\n private specBuilder: DisplaySpecBuilder;\n private thoughtBuffer: ThoughtBuffer;\n private _outputMode: OutputMode;\n private tracer: DebugTracer | null;\n private sessionId: string;\n private sessionContext?: { id: string; workingDirectory: string };\n private tunnelService?: TunnelServiceInterface;\n\n constructor(\n private api: Bot[\"api\"],\n private chatId: number,\n private threadId: number,\n private sendQueue: SendQueue,\n outputMode: OutputMode = \"medium\",\n sessionId: string = \"\",\n tracer: DebugTracer | null = null,\n tunnelService?: TunnelServiceInterface,\n sessionContext?: { id: string; workingDirectory: string },\n ) {\n this._outputMode = outputMode;\n this.tracer = tracer;\n this.sessionId = sessionId;\n this.sessionContext = sessionContext;\n this.tunnelService = tunnelService;\n this.specBuilder = new DisplaySpecBuilder(tunnelService);\n this.toolStateMap = new ToolStateMap();\n this.thoughtBuffer = new ThoughtBuffer();\n this.thinking = new ThinkingIndicator(api, chatId, threadId, sendQueue, sessionId, tracer);\n this.toolCard = new ToolCard(api, chatId, threadId, sendQueue, sessionId, tracer);\n }\n\n setOutputMode(mode: OutputMode): void {\n this._outputMode = mode;\n }\n\n async onNewPrompt(): Promise<void> {\n this.tracer?.log(\"telegram\", { action: \"tracker:newPrompt\", sessionId: this.sessionId });\n this.isFirstEvent = true;\n this.thoughtBuffer.reset();\n await this.thinking.dismiss();\n this.thinking.reset();\n await this.toolCard.finalize();\n // Clear previous card references so tool updates from new prompt don't leak into old messages\n this.previousToolCard = undefined;\n this.previousToolStateMap = undefined;\n this.toolStateMap.clear();\n this.toolCard = new ToolCard(this.api, this.chatId, this.threadId, this.sendQueue, this.sessionId, this.tracer);\n }\n\n async onThought(text: string): Promise<void> {\n this.tracer?.log(\"telegram\", { action: \"tracker:thought\", sessionId: this.sessionId });\n this.isFirstEvent = false;\n if (!this.thoughtBuffer.isSealed()) this.thoughtBuffer.append(text);\n await this.sealToolCardIfNeeded();\n await this.thinking.show();\n }\n\n async onTextStart(): Promise<void> {\n this.tracer?.log(\"telegram\", { action: \"tracker:textStart\", sessionId: this.sessionId });\n this.isFirstEvent = false;\n this.thoughtBuffer.seal();\n\n // In high mode with tunnel: store thought content and show a viewer link before dismissing\n if (this._outputMode === \"high\" && this.tunnelService && this.sessionContext) {\n const thoughtText = this.thoughtBuffer.getText();\n if (thoughtText.trim().length > 0) {\n const id = this.tunnelService.getStore().storeOutput(\n this.sessionContext.id,\n \"thinking\",\n thoughtText,\n );\n if (id !== null) {\n await this.thinking.finalizeWithViewerLink(this.tunnelService.outputUrl(id));\n } else {\n await this.thinking.dismiss();\n }\n } else {\n await this.thinking.dismiss();\n }\n } else {\n await this.thinking.dismiss();\n }\n\n await this.sealToolCardIfNeeded();\n }\n\n async onToolCall(\n meta: ToolCallMeta,\n kind: string,\n rawInput: unknown,\n ): Promise<void> {\n this.tracer?.log(\"telegram\", { action: \"tracker:toolCall\", sessionId: this.sessionId, meta, kind, rawInput });\n this.isFirstEvent = false;\n await this.thinking.dismiss();\n this.thinking.reset();\n\n const entry = this.toolStateMap.upsert(meta, kind, rawInput);\n const spec = this.specBuilder.buildToolSpec(entry, this._outputMode, this.sessionContext);\n this.toolCard.updateFromSpec(spec);\n }\n\n async onToolUpdate(\n id: string,\n status: string,\n viewerLinks?: ViewerLinks,\n viewerFilePath?: string,\n content?: string | null,\n rawInput?: unknown,\n diffStats?: { added: number; removed: number },\n ): Promise<void> {\n this.tracer?.log(\"telegram\", { action: \"tracker:toolUpdate\", sessionId: this.sessionId, toolId: id, status, viewerLinks, viewerFilePath, hasPrevCard: !!this.previousToolCard });\n\n // Forward to previous card first if the tool originated there (out-of-order update after seal)\n if (this.previousToolStateMap?.get(id)) {\n this.previousToolStateMap.merge(id, status, rawInput, content, viewerLinks, diffStats);\n const prevEntry = this.previousToolStateMap.get(id);\n if (prevEntry) {\n const prevSpec = this.specBuilder.buildToolSpec(prevEntry, this._outputMode, this.sessionContext);\n this.previousToolCard?.updateFromSpec(prevSpec);\n }\n }\n\n const existed = !!this.toolStateMap.get(id);\n const entry = this.toolStateMap.merge(id, status, rawInput, content, viewerLinks, diffStats);\n // Skip spec build for out-of-order updates — buffered in pendingUpdates\n if (!existed || !entry) return;\n\n if (viewerLinks || entry.viewerLinks) {\n log.debug({ toolId: id, status, hasIncomingLinks: !!viewerLinks, hasEntryLinks: !!entry.viewerLinks, entryLinks: entry.viewerLinks }, \"toolUpdate: viewer links trace\");\n }\n const spec = this.specBuilder.buildToolSpec(entry, this._outputMode, this.sessionContext);\n this.toolCard.updateFromSpec(spec);\n }\n\n async onPlan(entries: PlanEntry[]): Promise<void> {\n this.tracer?.log(\"telegram\", { action: \"tracker:plan\", sessionId: this.sessionId, entries });\n this.isFirstEvent = false;\n await this.thinking.dismiss();\n this.toolCard.updatePlan(entries);\n }\n\n /** @deprecated Usage is now sent as a separate message by the adapter */\n async sendUsage(_usage: {\n tokensUsed?: number;\n contextSize?: number;\n cost?: number;\n }): Promise<void> {\n // no-op — adapter sends usage as a standalone message\n }\n\n getToolCardMsgId(): number | undefined {\n return this.toolCard.getMsgId();\n }\n\n async cleanup(): Promise<void> {\n await this.thinking.dismiss();\n await this.toolCard.finalize();\n this.toolCard.destroy();\n }\n\n destroy(): void {\n void this.thinking.dismiss();\n this.toolCard.destroy();\n }\n\n private async sealToolCardIfNeeded(): Promise<void> {\n if (!this.toolCard.hasContent()) return;\n this.tracer?.log(\"telegram\", { action: \"tracker:seal\", sessionId: this.sessionId });\n await this.toolCard.finalize();\n this.previousToolCard = this.toolCard;\n this.previousToolStateMap = this.toolStateMap;\n this.toolStateMap = new ToolStateMap();\n this.toolCard = new ToolCard(this.api, this.chatId, this.threadId, this.sendQueue, this.sessionId, this.tracer);\n }\n}\n","export type QueueItemType = 'text' | 'other'\n\nexport interface SendQueueConfig {\n minInterval: number\n categoryIntervals?: Record<string, number>\n onRateLimited?: () => void\n onError?: (error: Error) => void\n}\n\nexport interface EnqueueOptions {\n type?: QueueItemType\n key?: string\n category?: string\n}\n\ninterface QueueItem<T = unknown> {\n fn: () => Promise<T>\n type: QueueItemType\n key?: string\n category?: string\n resolve: (value: T | undefined) => void\n reject: (err: unknown) => void\n promise: Promise<T | undefined>\n}\n\nexport class SendQueue {\n private items: QueueItem[] = []\n private processing = false\n private lastExec = 0\n private lastCategoryExec = new Map<string, number>()\n\n constructor(private config: SendQueueConfig) {}\n\n get pending(): number {\n return this.items.length\n }\n\n enqueue<T>(\n fn: () => Promise<T>,\n opts?: EnqueueOptions,\n ): Promise<T | undefined> {\n const type = opts?.type ?? 'other'\n const key = opts?.key\n const category = opts?.category\n\n let resolve!: (value: T | undefined) => void\n let reject!: (err: unknown) => void\n const promise = new Promise<T | undefined>((res, rej) => {\n resolve = res\n reject = rej\n })\n // Suppress unhandled rejection — callers are expected to handle via .catch or await\n promise.catch(() => {})\n\n if (type === 'text' && key) {\n const idx = this.items.findIndex(\n (item) => item.type === 'text' && item.key === key,\n )\n if (idx !== -1) {\n this.items[idx].resolve(undefined)\n this.items[idx] = { fn, type, key, category, resolve, reject, promise } as QueueItem\n this.scheduleProcess()\n return promise\n }\n }\n\n this.items.push({ fn, type, key, category, resolve, reject, promise } as QueueItem)\n this.scheduleProcess()\n return promise\n }\n\n onRateLimited(): void {\n this.config.onRateLimited?.()\n const remaining: QueueItem[] = []\n for (const item of this.items) {\n if (item.type === 'text') {\n item.resolve(undefined)\n } else {\n remaining.push(item)\n }\n }\n this.items = remaining\n }\n\n clear(): void {\n for (const item of this.items) {\n item.resolve(undefined)\n }\n this.items = []\n }\n\n private scheduleProcess(): void {\n if (this.processing) return\n if (this.items.length === 0) return\n\n const item = this.items[0]\n const interval = this.getInterval(item.category)\n const lastExec = item.category\n ? this.lastCategoryExec.get(item.category) ?? 0\n : this.lastExec\n const elapsed = Date.now() - lastExec\n const delay = Math.max(0, interval - elapsed)\n\n this.processing = true\n setTimeout(() => void this.processNext(), delay)\n }\n\n private getInterval(category?: string): number {\n if (category && this.config.categoryIntervals?.[category] != null) {\n return this.config.categoryIntervals[category]\n }\n return this.config.minInterval\n }\n\n private async processNext(): Promise<void> {\n const item = this.items.shift()\n if (!item) {\n this.processing = false\n return\n }\n\n try {\n const result = await item.fn()\n item.resolve(result)\n } catch (err) {\n this.config.onError?.(err instanceof Error ? err : new Error(String(err)))\n item.reject(err)\n } finally {\n const now = Date.now()\n this.lastExec = now\n if (item.category) {\n this.lastCategoryExec.set(item.category, now)\n }\n this.processing = false\n this.scheduleProcess()\n }\n }\n}\n","import { nanoid } from \"nanoid\";\nimport { InlineKeyboard } from \"grammy\";\nimport type { Bot } from \"grammy\";\nimport type { OpenACPCore } from \"../../core/core.js\";\nimport { executeNewSession, executeCancelSession, startInteractiveNewSession } from \"./commands/index.js\";\n\nexport interface DetectedAction {\n action: \"new_session\" | \"cancel_session\";\n agent?: string;\n workspace?: string;\n}\n\n// Command patterns: /new [agent] [workspace], /cancel\n// Agent and workspace are ASCII-only tokens (no Unicode letters) to avoid matching non-ASCII words\nconst CMD_NEW_RE =\n /\\/new(?:\\s+([^\\s\\u0080-\\uFFFF]+)(?:\\s+([^\\s\\u0080-\\uFFFF]+))?)?/;\nconst CMD_CANCEL_RE = /\\/cancel\\b/;\n\n// Keyword patterns (compound phrases only to avoid false positives)\nconst KW_NEW_RE = /(?:create|new)\\s+session/i;\nconst KW_CANCEL_RE = /(?:cancel|stop)\\s+session/i;\n\nexport function detectAction(text: string): DetectedAction | null {\n if (!text) return null;\n\n // Priority 1: command pattern\n const cancelCmd = CMD_CANCEL_RE.exec(text);\n if (cancelCmd) return { action: \"cancel_session\" };\n\n const newCmd = CMD_NEW_RE.exec(text);\n if (newCmd) {\n return {\n action: \"new_session\",\n agent: newCmd[1] || undefined,\n workspace: newCmd[2] || undefined,\n };\n }\n\n // Priority 2: keyword matching\n if (KW_CANCEL_RE.test(text)) return { action: \"cancel_session\" };\n if (KW_NEW_RE.test(text))\n return { action: \"new_session\", agent: undefined, workspace: undefined };\n\n return null;\n}\n\n// --- Callback map for action buttons ---\n\nconst ACTION_TTL_MS = 5 * 60 * 1000; // 5 minutes\nconst actionMap: Map<string, { action: DetectedAction; createdAt: number }> =\n new Map();\n\nexport function storeAction(action: DetectedAction): string {\n const id = nanoid(10);\n actionMap.set(id, { action, createdAt: Date.now() });\n // Cleanup expired entries\n for (const [key, entry] of actionMap) {\n if (Date.now() - entry.createdAt > ACTION_TTL_MS) {\n actionMap.delete(key);\n }\n }\n return id;\n}\n\nexport function getAction(id: string): DetectedAction | undefined {\n const entry = actionMap.get(id);\n if (!entry) return undefined;\n if (Date.now() - entry.createdAt > ACTION_TTL_MS) {\n actionMap.delete(id);\n return undefined;\n }\n return entry.action;\n}\n\nexport function removeAction(id: string): void {\n actionMap.delete(id);\n}\n\nexport function buildActionKeyboard(\n actionId: string,\n action: DetectedAction,\n): InlineKeyboard {\n const keyboard = new InlineKeyboard();\n if (action.action === \"new_session\") {\n keyboard.text(\"✅ Create session\", `a:${actionId}`);\n keyboard.text(\"❌ Cancel\", `a:dismiss:${actionId}`);\n } else {\n keyboard.text(\"⛔ Cancel session\", `a:${actionId}`);\n keyboard.text(\"❌ No\", `a:dismiss:${actionId}`);\n }\n return keyboard;\n}\n\nexport function setupActionCallbacks(\n bot: Bot,\n core: OpenACPCore,\n chatId: number,\n getAssistantSessionId: () => string | undefined,\n): void {\n // IMPORTANT: dismiss handler MUST be registered BEFORE generic a: handler\n // because grammY routes to the first matching handler and /^a:/ also matches a:dismiss:\n bot.callbackQuery(/^a:dismiss:/, async (ctx) => {\n const actionId = ctx.callbackQuery.data.replace(\"a:dismiss:\", \"\");\n removeAction(actionId);\n try {\n await ctx.editMessageReplyMarkup({\n reply_markup: { inline_keyboard: [] },\n });\n } catch {\n /* message may be old */\n }\n await ctx.answerCallbackQuery({ text: \"Dismissed\" });\n });\n\n bot.callbackQuery(/^a:(?!dismiss)/, async (ctx) => {\n const actionId = ctx.callbackQuery.data.replace(\"a:\", \"\");\n const action = getAction(actionId);\n if (!action) {\n await ctx.answerCallbackQuery({ text: \"Action expired\" });\n return;\n }\n removeAction(actionId);\n\n try {\n if (action.action === \"new_session\") {\n // If both agent and workspace provided → create directly\n if (action.agent && action.workspace) {\n await ctx.answerCallbackQuery({ text: \"⏳ Creating session...\" });\n const { threadId, firstMsgId } = await executeNewSession(\n bot,\n core,\n chatId,\n action.agent,\n action.workspace,\n );\n const cleanId = String(chatId).replace(\"-100\", \"\");\n const topicLink = firstMsgId\n ? `https://t.me/c/${cleanId}/${threadId}/${firstMsgId}`\n : `https://t.me/c/${cleanId}/${threadId}`;\n const originalText = ctx.callbackQuery.message?.text ?? \"\";\n try {\n await ctx.editMessageText(\n originalText +\n `\\n\\n✅ Session created → <a href=\"${topicLink}\">Go to topic</a>`,\n { parse_mode: \"HTML\" },\n );\n } catch {\n await ctx.editMessageReplyMarkup({\n reply_markup: { inline_keyboard: [] },\n });\n }\n } else {\n // Missing workspace → start interactive flow\n await ctx.answerCallbackQuery();\n try {\n await ctx.editMessageReplyMarkup({\n reply_markup: { inline_keyboard: [] },\n });\n } catch { /* best effort */ }\n await startInteractiveNewSession(ctx, core, chatId, action.agent);\n }\n } else if (action.action === \"cancel_session\") {\n const assistantId = getAssistantSessionId();\n const cancelled = await executeCancelSession(core, assistantId);\n if (cancelled) {\n await ctx.answerCallbackQuery({ text: \"⛔ Session cancelled\" });\n const originalText = ctx.callbackQuery.message?.text ?? \"\";\n try {\n await ctx.editMessageText(\n originalText +\n `\\n\\n⛔ Session \"${cancelled.name ?? cancelled.id}\" cancelled`,\n { parse_mode: \"HTML\" },\n );\n } catch {\n await ctx.editMessageReplyMarkup({\n reply_markup: { inline_keyboard: [] },\n });\n }\n } else {\n await ctx.answerCallbackQuery({\n text: \"No active session\",\n });\n try {\n await ctx.editMessageReplyMarkup({\n reply_markup: { inline_keyboard: [] },\n });\n } catch {\n /* best effort */\n }\n }\n }\n } catch {\n await ctx.answerCallbackQuery({ text: \"❌ Error, try again later\" });\n try {\n await ctx.editMessageReplyMarkup({\n reply_markup: { inline_keyboard: [] },\n });\n } catch {\n /* best effort */\n }\n }\n });\n}\n","import type { Bot } from 'grammy'\nimport { markdownToTelegramHtml, splitMessage } from './formatting.js'\nimport type { SendQueue } from '../../core/adapter-primitives/primitives/send-queue.js'\nimport type { DebugTracer } from '../../core/utils/debug-tracer.js'\n\nconst FLUSH_INTERVAL = 5000\n\nexport class MessageDraft {\n private buffer: string = ''\n private messageId?: number\n private firstFlushPending = false\n private flushTimer?: ReturnType<typeof setTimeout>\n private flushPromise: Promise<void> = Promise.resolve()\n private lastSentBuffer: string = ''\n private displayTruncated = false\n private tracer: DebugTracer | null\n\n constructor(\n private bot: Bot,\n private chatId: number,\n private threadId: number,\n private sendQueue: SendQueue,\n private sessionId: string,\n tracer: DebugTracer | null = null,\n ) {\n this.tracer = tracer\n }\n\n append(text: string): void {\n if (!text) return\n this.buffer += text\n this.scheduleFlush()\n }\n\n private scheduleFlush(): void {\n if (this.flushTimer) return\n this.flushTimer = setTimeout(() => {\n this.flushTimer = undefined\n this.flushPromise = this.flushPromise\n .then(() => this.flush())\n .catch(() => {})\n }, FLUSH_INTERVAL)\n }\n\n private async flush(): Promise<void> {\n if (!this.buffer) return\n if (this.firstFlushPending) return\n\n // CRITICAL: Snapshot the buffer BEFORE any await.\n // append() can be called synchronously while we're awaiting sendQueue,\n // so this.buffer may change. We must track what was ACTUALLY sent.\n const snapshot = this.buffer\n\n let html = markdownToTelegramHtml(snapshot)\n if (!html) return\n let truncated = false\n if (html.length > 4096) {\n // Estimate markdown cut point proportionally, then find a line boundary\n const ratio = 4000 / html.length\n const targetLen = Math.floor(snapshot.length * ratio)\n let cutAt = snapshot.lastIndexOf('\\n', targetLen)\n if (cutAt < targetLen * 0.5) cutAt = targetLen\n html = markdownToTelegramHtml(snapshot.slice(0, cutAt) + '\\n…')\n truncated = true\n if (html.length > 4096) {\n html = html.slice(0, 4090) + '\\n…'\n }\n }\n\n if (!this.messageId) {\n this.firstFlushPending = true\n try {\n const result = await this.sendQueue.enqueue(\n () => this.bot.api.sendMessage(this.chatId, html, {\n message_thread_id: this.threadId,\n parse_mode: 'HTML',\n disable_notification: true,\n }),\n { type: 'other' },\n )\n if (result) {\n this.messageId = result.message_id\n this.tracer?.log(\"telegram\", { action: \"draft:send\", sessionId: this.sessionId, msgId: result.message_id, textLen: snapshot.length, truncated, text: snapshot })\n if (!truncated) {\n this.lastSentBuffer = snapshot\n this.displayTruncated = false\n } else {\n this.displayTruncated = true\n }\n }\n } catch {\n // sendMessage failed — next flush will retry\n } finally {\n this.firstFlushPending = false\n }\n } else {\n try {\n const result = await this.sendQueue.enqueue(\n () => this.bot.api.editMessageText(this.chatId, this.messageId!, html, {\n parse_mode: 'HTML',\n }),\n { type: 'text', key: this.sessionId },\n )\n // Only mark as sent if the edit was actually executed (not dropped by dedup/rate-limit)\n if (result !== undefined) {\n this.tracer?.log(\"telegram\", { action: \"draft:edit\", sessionId: this.sessionId, msgId: this.messageId, textLen: snapshot.length, truncated, text: snapshot })\n if (!truncated) {\n this.lastSentBuffer = snapshot\n this.displayTruncated = false\n } else {\n this.displayTruncated = true\n }\n }\n } catch {\n // Don't reset messageId — transient errors (rate limit, network) would cause\n // the next flush to sendMessage the full buffer as a NEW message, creating duplicates.\n // If the message was truly deleted, finalize() handles the fallback.\n }\n }\n }\n\n async finalize(): Promise<number | undefined> {\n this.tracer?.log(\"telegram\", { action: \"draft:finalize\", sessionId: this.sessionId, bufferLen: this.buffer.length, msgId: this.messageId })\n if (this.flushTimer) {\n clearTimeout(this.flushTimer)\n this.flushTimer = undefined\n }\n\n await this.flushPromise\n\n if (!this.buffer) return this.messageId\n\n // Skip if buffer was already fully sent by flush() and nothing new was appended.\n // Do NOT skip if flush() truncated the display — finalize must send the full content.\n if (this.messageId && this.buffer === this.lastSentBuffer && !this.displayTruncated) {\n return this.messageId\n }\n\n // Try sending full buffer as a single message (most common case).\n // Only split if HTML exceeds Telegram's 4096 char limit.\n const fullHtml = markdownToTelegramHtml(this.buffer)\n if (fullHtml.length <= 4096) {\n // Single enqueue — no ordering issue possible\n try {\n if (this.messageId) {\n await this.sendQueue.enqueue(\n () => this.bot.api.editMessageText(this.chatId, this.messageId!, fullHtml, {\n parse_mode: 'HTML',\n }),\n { type: 'other' },\n )\n this.tracer?.log(\"telegram\", { action: \"draft:finalize:edit\", sessionId: this.sessionId, msgId: this.messageId })\n } else {\n const msg = await this.sendQueue.enqueue(\n () => this.bot.api.sendMessage(this.chatId, fullHtml, {\n message_thread_id: this.threadId,\n parse_mode: 'HTML',\n disable_notification: true,\n }),\n { type: 'other' },\n )\n if (msg) this.messageId = msg.message_id\n this.tracer?.log(\"telegram\", { action: \"draft:finalize:send\", sessionId: this.sessionId, msgId: msg?.message_id })\n }\n return this.messageId\n } catch {\n // HTML send failed — fall through to split/fallback below\n }\n }\n\n // HTML > 4096 or single send failed — split markdown, convert each chunk separately.\n // This prevents breaking HTML tags (e.g. <pre><code>) at split boundaries.\n //\n // CRITICAL: Enqueue ALL chunks in a tight synchronous loop (no await between\n // enqueues). This prevents concurrent event handlers (usage, session_end) from\n // slipping their messages between our chunks in the sendQueue.\n const mdChunks = splitMessage(this.buffer)\n const chunkPromises: Promise<void>[] = []\n\n for (let i = 0; i < mdChunks.length; i++) {\n const html = markdownToTelegramHtml(mdChunks[i])\n const isEdit = i === 0 && !!this.messageId\n const chunkMd = mdChunks[i]\n\n const fn = isEdit\n ? () => this.bot.api.editMessageText(this.chatId, this.messageId!, html, { parse_mode: 'HTML' }) as Promise<unknown>\n : () => this.bot.api.sendMessage(this.chatId, html, {\n message_thread_id: this.threadId,\n parse_mode: 'HTML',\n disable_notification: true,\n })\n const promise = this.sendQueue.enqueue(fn, { type: 'other' })\n .then((result) => {\n if (!isEdit && result && typeof result === 'object' && 'message_id' in (result as Record<string, unknown>)) {\n this.messageId = (result as { message_id: number }).message_id\n }\n })\n .catch(() => {\n // HTML failed — enqueue plain text fallback (goes after all chunks, acceptable)\n const fallbackFn = isEdit\n ? () => this.bot.api.editMessageText(this.chatId, this.messageId!, chunkMd.slice(0, 4096)) as Promise<unknown>\n : () => this.bot.api.sendMessage(this.chatId, chunkMd.slice(0, 4096), {\n message_thread_id: this.threadId,\n disable_notification: true,\n })\n return this.sendQueue.enqueue(fallbackFn, { type: 'other' })\n .then((result) => {\n if (!isEdit && result && typeof result === 'object' && 'message_id' in (result as Record<string, unknown>)) {\n this.messageId = (result as { message_id: number }).message_id\n }\n })\n .catch(() => {})\n })\n\n chunkPromises.push(promise)\n }\n\n // All chunks are now in the queue — any items enqueued by concurrent handlers\n // (usage, session_end) will go AFTER our chunks. Safe to await.\n await Promise.all(chunkPromises)\n this.tracer?.log(\"telegram\", { action: \"draft:finalize:split\", sessionId: this.sessionId, chunks: mdChunks.length })\n\n return this.messageId\n }\n\n getMessageId(): number | undefined {\n return this.messageId\n }\n\n async stripPattern(pattern: RegExp): Promise<void> {\n if (!this.messageId || !this.buffer) return\n\n const stripped = this.buffer.replace(pattern, '').trim()\n if (stripped === this.buffer.trim()) return\n\n this.buffer = stripped\n this.lastSentBuffer = stripped\n\n const html = markdownToTelegramHtml(stripped)\n if (!html) return\n\n try {\n await this.sendQueue.enqueue(\n () => this.bot.api.editMessageText(this.chatId, this.messageId!, html, {\n parse_mode: 'HTML',\n }),\n { type: 'other' },\n )\n } catch {\n // Best effort — non-critical edit\n }\n }\n}\n","import type { Bot } from \"grammy\";\nimport { MessageDraft } from \"./streaming.js\";\nimport type { SendQueue } from \"../../core/adapter-primitives/primitives/send-queue.js\";\nimport type { DebugTracer } from \"../../core/utils/debug-tracer.js\";\nimport {\n detectAction,\n storeAction,\n buildActionKeyboard,\n} from \"./action-detect.js\";\n\ninterface FinalizedDraft {\n messageId: number;\n draft: MessageDraft;\n}\n\nexport class DraftManager {\n private drafts: Map<string, MessageDraft> = new Map();\n private textBuffers: Map<string, string> = new Map();\n private finalizedDrafts: Map<string, FinalizedDraft> = new Map();\n\n constructor(\n private bot: Bot,\n private chatId: number,\n private sendQueue: SendQueue,\n ) {}\n\n getOrCreate(sessionId: string, threadId: number, tracer: DebugTracer | null = null): MessageDraft {\n let draft = this.drafts.get(sessionId);\n if (!draft) {\n draft = new MessageDraft(\n this.bot,\n this.chatId,\n threadId,\n this.sendQueue,\n sessionId,\n tracer,\n );\n this.drafts.set(sessionId, draft);\n }\n return draft;\n }\n\n hasDraft(sessionId: string): boolean {\n return this.drafts.has(sessionId);\n }\n\n getDraft(sessionId: string): MessageDraft | undefined {\n return this.drafts.get(sessionId);\n }\n\n appendText(sessionId: string, text: string): void {\n this.textBuffers.set(\n sessionId,\n (this.textBuffers.get(sessionId) ?? \"\") + text,\n );\n }\n\n /**\n * Finalize the current draft and return the message ID.\n * Optionally detects actions in assistant responses.\n */\n async finalize(\n sessionId: string,\n assistantSessionId?: string,\n ): Promise<void> {\n const draft = this.drafts.get(sessionId);\n if (!draft) return;\n\n // Delete BEFORE awaiting to prevent concurrent finalizeDraft() calls\n // from double-finalizing the same draft\n this.drafts.delete(sessionId);\n const finalMsgId = await draft.finalize();\n\n // Keep finalized draft reference so tts_strip can edit after finalization\n if (finalMsgId) {\n this.finalizedDrafts.set(sessionId, { messageId: finalMsgId, draft });\n }\n\n // Detect actions in assistant responses and attach keyboard\n if (assistantSessionId && sessionId === assistantSessionId) {\n const fullText = this.textBuffers.get(sessionId);\n this.textBuffers.delete(sessionId);\n if (fullText && finalMsgId) {\n const detected = detectAction(fullText);\n if (detected) {\n const actionId = storeAction(detected);\n const keyboard = buildActionKeyboard(actionId, detected);\n try {\n await this.bot.api.editMessageReplyMarkup(\n this.chatId,\n finalMsgId,\n { reply_markup: keyboard },\n );\n } catch {\n // Best effort — keyboard attachment is non-critical\n }\n }\n }\n } else {\n this.textBuffers.delete(sessionId);\n }\n }\n\n /**\n * Strip a regex pattern from the active or finalized draft for a session.\n * Used by tts_strip to remove [TTS]...[/TTS] blocks after TTS audio is sent.\n */\n async stripPattern(sessionId: string, pattern: RegExp): Promise<void> {\n const draft = this.drafts.get(sessionId);\n if (draft) {\n await draft.stripPattern(pattern);\n return;\n }\n const finalized = this.finalizedDrafts.get(sessionId);\n if (finalized) {\n await finalized.draft.stripPattern(pattern);\n }\n // If no draft found (e.g., TTS synthesis slower than next prompt cycle), the\n // [TTS] block will remain visible. This is a rare edge case — log for debugging.\n }\n\n cleanup(sessionId: string): void {\n this.drafts.delete(sessionId);\n this.textBuffers.delete(sessionId);\n this.finalizedDrafts.delete(sessionId);\n }\n}\n","import type { Bot } from \"grammy\";\nimport type { SendQueue } from \"../../core/adapter-primitives/primitives/send-queue.js\";\nimport type { AgentCommand } from \"../../core/types.js\";\nimport type { SessionManager } from \"../../core/sessions/session-manager.js\";\nimport type { TelegramPlatformData } from \"../../core/types.js\";\nimport { buildSkillMessages } from \"./commands/index.js\";\nimport { createChildLogger } from \"../../core/utils/log.js\";\n\nconst log = createChildLogger({ module: \"skill-commands\" });\n\nexport class SkillCommandManager {\n private messages: Map<string, number> = new Map(); // sessionId → pinned msgId\n\n constructor(\n private bot: Bot,\n private chatId: number,\n private sendQueue: SendQueue,\n private sessionManager: SessionManager,\n ) {}\n\n async send(\n sessionId: string,\n threadId: number,\n commands: AgentCommand[],\n ): Promise<void> {\n // Restore skillMsgIds from persisted platform data if not in memory\n if (!this.messages.has(sessionId)) {\n const record = this.sessionManager.getSessionRecord(sessionId);\n const platform = record?.platform as TelegramPlatformData | undefined;\n if (platform?.skillMsgId) {\n this.messages.set(sessionId, platform.skillMsgId);\n }\n }\n\n // Empty commands → remove pinned message\n if (commands.length === 0) {\n await this.cleanup(sessionId);\n return;\n }\n\n const messages = buildSkillMessages(commands);\n const existingMsgId = this.messages.get(sessionId);\n\n if (existingMsgId) {\n try {\n await this.bot.api.editMessageText(\n this.chatId,\n existingMsgId,\n messages[0],\n { parse_mode: \"HTML\" },\n );\n return;\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : \"\";\n if (msg.includes(\"message is not modified\")) return;\n try {\n await this.bot.api.deleteMessage(this.chatId, existingMsgId);\n } catch { /* already gone */ }\n this.messages.delete(sessionId);\n }\n }\n\n // Send new messages and pin the first one\n try {\n let firstMsgId: number | undefined;\n for (const text of messages) {\n const msg = await this.sendQueue.enqueue(() =>\n this.bot.api.sendMessage(this.chatId, text, {\n message_thread_id: threadId,\n parse_mode: \"HTML\",\n disable_notification: true,\n }),\n );\n if (!firstMsgId) firstMsgId = msg!.message_id;\n }\n\n this.messages.set(sessionId, firstMsgId!);\n\n // Persist skillMsgId so it survives restarts\n const record = this.sessionManager.getSessionRecord(sessionId);\n if (record) {\n await this.sessionManager.patchRecord(sessionId, {\n platform: { ...record.platform, skillMsgId: firstMsgId },\n });\n }\n\n await this.bot.api.pinChatMessage(this.chatId, firstMsgId!, {\n disable_notification: true,\n });\n } catch (err) {\n log.error({ err, sessionId }, \"Failed to send skill commands\");\n }\n }\n\n async cleanup(sessionId: string): Promise<void> {\n const msgId = this.messages.get(sessionId);\n if (!msgId) return;\n\n try {\n await this.bot.api.editMessageText(\n this.chatId,\n msgId,\n \"🛠 <i>Session ended</i>\",\n { parse_mode: \"HTML\" },\n );\n await this.bot.api.unpinChatMessage(this.chatId, msgId);\n } catch { /* message may already be deleted */ }\n\n this.messages.delete(sessionId);\n\n // Clear persisted skillMsgId\n const record = this.sessionManager.getSessionRecord(sessionId);\n if (record) {\n const platform = record.platform;\n if (platform && typeof platform === 'object' && 'topicId' in platform) {\n const { skillMsgId: _removed, ...rest } = platform as unknown as TelegramPlatformData;\n await this.sessionManager.patchRecord(sessionId, { platform: rest });\n }\n }\n }\n}\n","import type {\n IChannelAdapter,\n ChannelConfig,\n AdapterCapabilities,\n} from \"../channel.js\";\nimport type {\n OutgoingMessage,\n PermissionRequest,\n NotificationMessage,\n} from \"../types.js\";\nimport type { DisplayVerbosity, ToolCallMeta } from \"./format-types.js\";\nimport type { IRenderer } from \"./rendering/renderer.js\";\nimport { evaluateNoise } from \"./message-formatter.js\";\n\nexport interface AdapterContext {\n configManager: { get(): Record<string, unknown> };\n fileService?: unknown;\n}\n\nexport interface MessagingAdapterConfig extends ChannelConfig {\n maxMessageLength: number;\n flushInterval?: number;\n sendInterval?: number;\n thinkingRefreshInterval?: number;\n thinkingDuration?: number;\n displayVerbosity?: DisplayVerbosity;\n}\n\nexport interface SentMessage {\n messageId: string;\n}\n\nconst HIDDEN_ON_LOW = new Set([\"thought\", \"usage\"]);\n\nexport abstract class MessagingAdapter implements IChannelAdapter {\n abstract readonly name: string;\n abstract readonly renderer: IRenderer;\n abstract readonly capabilities: AdapterCapabilities;\n\n constructor(\n protected context: AdapterContext,\n protected adapterConfig: MessagingAdapterConfig,\n ) {}\n\n // === Message dispatch flow ===\n\n async sendMessage(\n sessionId: string,\n content: OutgoingMessage,\n ): Promise<void> {\n const verbosity = this.getVerbosity();\n if (!this.shouldDisplay(content, verbosity)) return;\n await this.dispatchMessage(sessionId, content, verbosity);\n }\n\n protected async dispatchMessage(\n sessionId: string,\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): Promise<void> {\n switch (content.type) {\n case \"text\":\n return this.handleText(sessionId, content);\n case \"thought\":\n return this.handleThought(sessionId, content, verbosity);\n case \"tool_call\":\n return this.handleToolCall(sessionId, content, verbosity);\n case \"tool_update\":\n return this.handleToolUpdate(sessionId, content, verbosity);\n case \"plan\":\n return this.handlePlan(sessionId, content, verbosity);\n case \"usage\":\n return this.handleUsage(sessionId, content, verbosity);\n case \"error\":\n return this.handleError(sessionId, content);\n case \"attachment\":\n return this.handleAttachment(sessionId, content);\n case \"system_message\":\n return this.handleSystem(sessionId, content);\n case \"session_end\":\n return this.handleSessionEnd(sessionId, content);\n case \"mode_change\":\n return this.handleModeChange(sessionId, content);\n case \"config_update\":\n return this.handleConfigUpdate(sessionId, content);\n case \"model_update\":\n return this.handleModelUpdate(sessionId, content);\n case \"user_replay\":\n return this.handleUserReplay(sessionId, content);\n case \"resource\":\n return this.handleResource(sessionId, content);\n case \"resource_link\":\n return this.handleResourceLink(sessionId, content);\n }\n }\n\n // === Default handlers — all protected, all overridable ===\n\n protected async handleText(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleThought(\n _sessionId: string,\n _content: OutgoingMessage,\n _verbosity: DisplayVerbosity,\n ): Promise<void> {}\n protected async handleToolCall(\n _sessionId: string,\n _content: OutgoingMessage,\n _verbosity: DisplayVerbosity,\n ): Promise<void> {}\n protected async handleToolUpdate(\n _sessionId: string,\n _content: OutgoingMessage,\n _verbosity: DisplayVerbosity,\n ): Promise<void> {}\n protected async handlePlan(\n _sessionId: string,\n _content: OutgoingMessage,\n _verbosity: DisplayVerbosity,\n ): Promise<void> {}\n protected async handleUsage(\n _sessionId: string,\n _content: OutgoingMessage,\n _verbosity: DisplayVerbosity,\n ): Promise<void> {}\n protected async handleError(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleAttachment(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleSystem(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleSessionEnd(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleModeChange(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleConfigUpdate(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleModelUpdate(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleUserReplay(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleResource(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleResourceLink(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n\n // === Helpers ===\n\n protected getVerbosity(): DisplayVerbosity {\n const config = this.context.configManager.get();\n const channelConfig = (config as Record<string, unknown>).channels as\n | Record<string, Record<string, unknown>>\n | undefined;\n const v =\n channelConfig?.[this.name]?.displayVerbosity ??\n this.adapterConfig.displayVerbosity;\n if (v === \"low\" || v === \"high\") return v;\n return \"medium\";\n }\n\n protected shouldDisplay(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): boolean {\n if (verbosity === \"low\" && HIDDEN_ON_LOW.has(content.type)) return false;\n\n if (content.type === \"tool_call\") {\n const meta = (content.metadata ?? {}) as Partial<ToolCallMeta>;\n const toolName = meta.name ?? content.text ?? \"\";\n const toolKind = String(meta.kind ?? \"other\");\n const noiseAction = evaluateNoise(toolName, toolKind, meta.rawInput);\n if (noiseAction === \"hide\" && verbosity !== \"high\") return false;\n if (noiseAction === \"collapse\" && verbosity === \"low\") return false;\n }\n\n return true;\n }\n\n // === Abstract — adapter MUST implement ===\n\n abstract start(): Promise<void>;\n abstract stop(): Promise<void>;\n abstract createSessionThread(\n sessionId: string,\n name: string,\n ): Promise<string>;\n abstract renameSessionThread(\n sessionId: string,\n newName: string,\n ): Promise<void>;\n abstract sendPermissionRequest(\n sessionId: string,\n request: PermissionRequest,\n ): Promise<void>;\n abstract sendNotification(notification: NotificationMessage): Promise<void>;\n}\n","import type {\n OutgoingMessage,\n PermissionRequest,\n NotificationMessage,\n} from \"../../types.js\";\nimport type {\n DisplayVerbosity,\n ToolCallMeta,\n ToolUpdateMeta,\n} from \"../format-types.js\";\nimport {\n formatToolSummary,\n formatToolTitle,\n resolveToolIcon,\n} from \"../message-formatter.js\";\nimport { progressBar, formatTokens } from \"../format-utils.js\";\n\nexport interface RenderedMessage<TComponents = unknown> {\n body: string;\n format: \"html\" | \"markdown\" | \"plain\" | \"structured\";\n attachments?: RenderedAttachment[];\n components?: TComponents;\n}\n\nexport interface RenderedPermission<\n TComponents = unknown,\n> extends RenderedMessage<TComponents> {\n actions: RenderedAction[];\n}\n\nexport interface RenderedAction {\n id: string;\n label: string;\n isAllow?: boolean;\n}\n\nexport interface RenderedAttachment {\n type: \"file\" | \"image\" | \"audio\";\n data: Buffer | string;\n mimeType?: string;\n filename?: string;\n}\n\nexport interface IRenderer {\n renderText(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage;\n renderToolCall(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage;\n renderToolUpdate(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage;\n renderPlan(content: OutgoingMessage): RenderedMessage;\n renderUsage(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage;\n renderPermission(request: PermissionRequest): RenderedPermission;\n renderError(content: OutgoingMessage): RenderedMessage;\n renderNotification(notification: NotificationMessage): RenderedMessage;\n renderThought?(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage;\n renderAttachment?(content: OutgoingMessage): RenderedMessage;\n renderSessionEnd?(content: OutgoingMessage): RenderedMessage;\n renderSystemMessage?(content: OutgoingMessage): RenderedMessage;\n renderModeChange?(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage;\n renderConfigUpdate?(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage;\n renderModelUpdate?(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage;\n renderResource?(content: OutgoingMessage): RenderedMessage;\n renderResourceLink?(content: OutgoingMessage): RenderedMessage;\n}\n\n/**\n * BaseRenderer — plain text defaults. Extend for platform-specific rendering.\n */\nexport class BaseRenderer implements IRenderer {\n renderText(content: OutgoingMessage): RenderedMessage {\n return { body: content.text, format: \"plain\" };\n }\n\n renderToolCall(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage {\n const meta = (content.metadata ?? {}) as Partial<ToolCallMeta>;\n const name = meta.name ?? content.text ?? \"Tool\";\n const icon = resolveToolIcon(meta);\n const label =\n verbosity === \"low\"\n ? formatToolTitle(\n name,\n meta.rawInput,\n meta.displayTitle as string | undefined,\n )\n : formatToolSummary(\n name,\n meta.rawInput,\n meta.displaySummary as string | undefined,\n );\n return { body: `${icon} ${label}`, format: \"plain\" };\n }\n\n renderToolUpdate(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage {\n const meta = (content.metadata ?? {}) as Partial<ToolUpdateMeta>;\n const name = meta.name ?? content.text ?? \"Tool\";\n const icon = resolveToolIcon(meta);\n const label =\n verbosity === \"low\"\n ? formatToolTitle(\n name,\n meta.rawInput,\n meta.displayTitle as string | undefined,\n )\n : formatToolSummary(\n name,\n meta.rawInput,\n meta.displaySummary as string | undefined,\n );\n return { body: `${icon} ${label}`, format: \"plain\" };\n }\n\n renderPlan(content: OutgoingMessage): RenderedMessage {\n const entries =\n (\n content.metadata as {\n entries?: Array<{ content: string; status: string }>;\n }\n )?.entries ?? [];\n const lines = entries.map((e, i) => {\n const icon =\n e.status === \"completed\"\n ? \"✅\"\n : e.status === \"in_progress\"\n ? \"🔄\"\n : \"⬜\";\n return `${icon} ${i + 1}. ${e.content}`;\n });\n return { body: `📋 Plan\\n${lines.join(\"\\n\")}`, format: \"plain\" };\n }\n\n renderUsage(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage {\n const meta = content.metadata as\n | { tokensUsed?: number; contextSize?: number; cost?: number }\n | undefined;\n if (!meta?.tokensUsed)\n return { body: \"📊 Usage data unavailable\", format: \"plain\" };\n const costStr = meta.cost != null ? ` · $${meta.cost.toFixed(2)}` : \"\";\n if (verbosity === \"medium\") {\n return {\n body: `📊 ${formatTokens(meta.tokensUsed)} tokens${costStr}`,\n format: \"plain\",\n };\n }\n if (!meta.contextSize)\n return {\n body: `📊 ${formatTokens(meta.tokensUsed)} tokens`,\n format: \"plain\",\n };\n const ratio = meta.tokensUsed / meta.contextSize;\n const pct = Math.round(ratio * 100);\n const bar = progressBar(ratio);\n let text = `📊 ${formatTokens(meta.tokensUsed)} / ${formatTokens(meta.contextSize)} tokens\\n${bar} ${pct}%`;\n if (meta.cost != null) text += `\\n💰 $${meta.cost.toFixed(2)}`;\n return { body: text, format: \"plain\" };\n }\n\n renderPermission(request: PermissionRequest): RenderedPermission {\n return {\n body: request.description,\n format: \"plain\",\n actions: request.options.map((o) => ({\n id: o.id,\n label: o.label,\n isAllow: o.isAllow,\n })),\n };\n }\n\n renderError(content: OutgoingMessage): RenderedMessage {\n return { body: `❌ Error: ${content.text}`, format: \"plain\" };\n }\n\n renderNotification(notification: NotificationMessage): RenderedMessage {\n const emoji: Record<string, string> = {\n completed: \"✅\",\n error: \"❌\",\n permission: \"🔐\",\n input_required: \"💬\",\n budget_warning: \"⚠️\",\n };\n return {\n body: `${emoji[notification.type] || \"ℹ️\"} ${notification.sessionName || \"Session\"}\\n${notification.summary}`,\n format: \"plain\",\n };\n }\n\n renderSystemMessage(content: OutgoingMessage): RenderedMessage {\n return { body: content.text, format: \"plain\" };\n }\n\n renderModeChange(content: OutgoingMessage): RenderedMessage {\n const modeId = (content.metadata as Record<string, unknown>)?.modeId ?? \"\";\n return { body: `🔄 Mode: ${modeId}`, format: \"plain\" };\n }\n\n renderConfigUpdate(): RenderedMessage {\n return { body: \"⚙️ Config updated\", format: \"plain\" };\n }\n\n renderModelUpdate(content: OutgoingMessage): RenderedMessage {\n const modelId =\n (content.metadata as Record<string, unknown>)?.modelId ?? \"\";\n return { body: `🤖 Model: ${modelId}`, format: \"plain\" };\n }\n\n renderResource(content: OutgoingMessage): RenderedMessage {\n const uri = (content.metadata as Record<string, unknown>)?.uri ?? \"\";\n return { body: `📄 Resource: ${content.text} (${uri})`, format: \"plain\" };\n }\n\n renderResourceLink(content: OutgoingMessage): RenderedMessage {\n const uri = (content.metadata as Record<string, unknown>)?.uri ?? \"\";\n return { body: `🔗 ${content.text}: ${uri}`, format: \"plain\" };\n }\n}\n","import { BaseRenderer } from \"../../core/adapter-primitives/rendering/renderer.js\";\nimport type { RenderedMessage } from \"../../core/adapter-primitives/rendering/renderer.js\";\nimport type { OutgoingMessage, NotificationMessage } from \"../../core/types.js\";\nimport type {\n DisplayVerbosity,\n ToolCallMeta,\n ToolUpdateMeta,\n} from \"../../core/adapter-primitives/format-types.js\";\nimport {\n escapeHtml,\n formatToolCall,\n formatToolUpdate,\n formatPlan,\n formatUsage,\n} from \"./formatting.js\";\n\nexport class TelegramRenderer extends BaseRenderer {\n renderToolCall(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage {\n const meta = (content.metadata ?? {}) as Partial<ToolCallMeta>;\n return {\n body: formatToolCall(meta as ToolCallMeta, verbosity),\n format: \"html\",\n };\n }\n\n renderToolUpdate(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage {\n const meta = (content.metadata ?? {}) as Partial<ToolUpdateMeta>;\n return {\n body: formatToolUpdate(meta as ToolUpdateMeta, verbosity),\n format: \"html\",\n };\n }\n\n renderPlan(content: OutgoingMessage): RenderedMessage {\n const meta = content.metadata as\n | { entries?: Array<{ content: string; status: string }> }\n | undefined;\n return {\n body: formatPlan({ entries: meta?.entries ?? [] }),\n format: \"html\",\n };\n }\n\n renderUsage(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage {\n const meta = content.metadata as\n | { tokensUsed?: number; contextSize?: number; cost?: number }\n | undefined;\n return { body: formatUsage(meta ?? {}, verbosity), format: \"html\" };\n }\n\n renderError(content: OutgoingMessage): RenderedMessage {\n return {\n body: `❌ <b>Error:</b> ${escapeHtml(content.text)}`,\n format: \"html\",\n };\n }\n\n renderNotification(notification: NotificationMessage): RenderedMessage {\n const emoji: Record<string, string> = {\n completed: \"✅\",\n error: \"❌\",\n permission: \"🔐\",\n input_required: \"💬\",\n budget_warning: \"⚠️\",\n };\n let text = `${emoji[notification.type] || \"ℹ️\"} <b>${escapeHtml(notification.sessionName || \"Session\")}</b>\\n`;\n text += escapeHtml(notification.summary);\n return { body: text, format: \"html\" };\n }\n\n renderSystemMessage(content: OutgoingMessage): RenderedMessage {\n return { body: escapeHtml(content.text), format: \"html\" };\n }\n\n renderModeChange(content: OutgoingMessage): RenderedMessage {\n const modeId = (content.metadata as Record<string, unknown>)?.modeId ?? \"\";\n return {\n body: `🔄 <b>Mode:</b> ${escapeHtml(String(modeId))}`,\n format: \"html\",\n };\n }\n\n renderConfigUpdate(): RenderedMessage {\n return { body: \"⚙️ <b>Config updated</b>\", format: \"html\" };\n }\n\n renderModelUpdate(content: OutgoingMessage): RenderedMessage {\n const modelId =\n (content.metadata as Record<string, unknown>)?.modelId ?? \"\";\n return {\n body: `🤖 <b>Model:</b> ${escapeHtml(String(modelId))}`,\n format: \"html\",\n };\n }\n}\n","// src/core/adapter-primitives/output-mode-resolver.ts\nimport type { OutputMode } from \"./format-types.js\";\n\ninterface ConfigManagerLike {\n get(): Record<string, unknown>;\n}\n\ninterface SessionManagerLike {\n getSession(id: string): { record?: { outputMode?: OutputMode } } | undefined;\n}\n\nconst VALID_MODES = new Set<string>([\"low\", \"medium\", \"high\"]);\nfunction toOutputMode(v: unknown): OutputMode | undefined {\n return typeof v === \"string\" && VALID_MODES.has(v) ? (v as OutputMode) : undefined;\n}\n\nexport class OutputModeResolver {\n resolve(\n configManager: ConfigManagerLike,\n adapterName: string,\n sessionId?: string,\n sessionManager?: SessionManagerLike,\n ): OutputMode {\n const config = configManager.get();\n // 1. Global default\n let mode: OutputMode = toOutputMode(config.outputMode) ?? \"medium\";\n // 2. Per-adapter override\n const channels = config.channels as Record<string, unknown> | undefined;\n const channelCfg = channels?.[adapterName] as Record<string, unknown> | undefined;\n const adapterMode = toOutputMode(channelCfg?.outputMode);\n if (adapterMode) mode = adapterMode;\n // 3. Per-session override (most specific)\n if (sessionId && sessionManager) {\n const session = sessionManager.getSession(sessionId);\n const sessionMode = session?.record?.outputMode;\n if (sessionMode) mode = sessionMode;\n }\n return mode;\n }\n}\n","import { Bot, InputFile } from \"grammy\";\nimport path from \"node:path\";\nimport type {\n OpenACPCore,\n OutgoingMessage,\n PermissionRequest,\n NotificationMessage,\n Session,\n AgentCommand,\n FileServiceInterface,\n} from \"../../core/index.js\";\nimport { createChildLogger } from \"../../core/utils/log.js\";\nimport type { DebugTracer } from \"../../core/utils/debug-tracer.js\";\nconst log = createChildLogger({ module: \"telegram\" });\nimport type { TelegramChannelConfig } from \"./types.js\";\nimport type { CommandRegistry } from \"../../core/command-registry.js\";\nimport type { CommandResponse } from \"../../core/plugin/types.js\";\nimport {\n ensureTopics,\n createSessionTopic,\n renameSessionTopic,\n deleteSessionTopic,\n} from \"./topics.js\";\nimport {\n setupCommands,\n setupMenuCallbacks,\n setupDangerousModeCallbacks,\n setupTTSCallbacks,\n setupVerbosityCallbacks,\n setupIntegrateCallbacks,\n buildMenuKeyboard,\n handlePendingWorkspaceInput,\n handlePendingResumeInput,\n STATIC_COMMANDS,\n} from \"./commands/index.js\";\nimport { PermissionHandler } from \"./permissions.js\";\nimport {\n spawnAssistant,\n handleAssistantMessage,\n redirectToAssistant,\n buildWelcomeMessage,\n type SpawnAssistantResult,\n} from \"./assistant.js\";\nimport { escapeHtml, formatUsage } from \"./formatting.js\";\nimport { ActivityTracker } from \"./activity.js\";\nimport { SendQueue } from \"../../core/adapter-primitives/primitives/send-queue.js\";\nimport { setupActionCallbacks } from \"./action-detect.js\";\nimport { DraftManager } from \"./draft-manager.js\";\nimport { SkillCommandManager } from \"./skill-command-manager.js\";\nimport {\n MessagingAdapter,\n type MessagingAdapterConfig,\n} from \"../../core/adapter-primitives/messaging-adapter.js\";\nimport type { IRenderer } from \"../../core/adapter-primitives/rendering/renderer.js\";\nimport { TelegramRenderer } from \"./renderer.js\";\nimport type { AdapterCapabilities } from \"../../core/channel.js\";\nimport type {\n DisplayVerbosity,\n ToolCallMeta,\n ToolUpdateMeta,\n OutputMode,\n} from \"../../core/adapter-primitives/format-types.js\";\nimport { OutputModeResolver } from \"../../core/adapter-primitives/output-mode-resolver.js\";\nimport type { TunnelServiceInterface } from \"../../core/plugin/types.js\";\n// evaluateNoise is handled by MessagingAdapter.shouldDisplay()\n\ninterface PlanMetadata {\n entries: Array<{ content: string; status: string; priority: string }>;\n}\n\ninterface UsageMetadata {\n tokensUsed?: number;\n contextSize?: number;\n}\n\n/**\n * Wraps native fetch to work around grammY's polyfilled AbortController.\n * grammY uses abort-controller polyfill whose AbortSignal fails instanceof\n * checks in Node 24+ native fetch. This wrapper re-creates a native\n * AbortSignal from the polyfilled one before passing it to fetch.\n */\nfunction patchedFetch(\n input: RequestInfo | URL,\n init?: RequestInit,\n): Promise<Response> {\n if (init?.signal && !(init.signal instanceof AbortSignal)) {\n const nativeController = new AbortController();\n const polyfillSignal = init.signal as unknown as {\n aborted: boolean;\n addEventListener: (event: string, fn: () => void) => void;\n };\n if (polyfillSignal.aborted) {\n nativeController.abort();\n } else {\n polyfillSignal.addEventListener(\"abort\", () => nativeController.abort());\n }\n init = { ...init, signal: nativeController.signal };\n }\n return fetch(input, init);\n}\n\nexport class TelegramAdapter extends MessagingAdapter {\n readonly name = \"telegram\";\n readonly renderer: IRenderer = new TelegramRenderer();\n readonly capabilities: AdapterCapabilities = {\n streaming: true,\n richFormatting: true,\n threads: true,\n reactions: true,\n fileUpload: true,\n voice: true,\n };\n\n private core: OpenACPCore;\n private bot!: Bot;\n private telegramConfig: TelegramChannelConfig;\n private saveTopicIds?: (updates: { notificationTopicId?: number; assistantTopicId?: number }) => Promise<void>;\n private permissionHandler!: PermissionHandler;\n private assistantSession: Session | null = null;\n private assistantInitializing = false;\n private notificationTopicId!: number;\n private assistantTopicId!: number;\n private sendQueue = new SendQueue({ minInterval: 3000 });\n private _sessionThreadIds = new Map<string, number>();\n private outputModeResolver = new OutputModeResolver();\n\n // Extracted managers\n private draftManager!: DraftManager;\n private skillManager!: SkillCommandManager;\n private fileService!: FileServiceInterface;\n private sessionTrackers: Map<string, ActivityTracker> = new Map();\n private callbackCache = new Map<string, string>();\n private callbackCounter = 0;\n\n private getThreadId(sessionId: string): number {\n const threadId = this._sessionThreadIds.get(sessionId);\n if (threadId === undefined) {\n throw new Error(`No threadId stored for session ${sessionId}`);\n }\n return threadId;\n }\n\n private getOrCreateTracker(\n sessionId: string,\n threadId: number,\n outputMode: OutputMode = \"medium\",\n ): ActivityTracker {\n let tracker = this.sessionTrackers.get(sessionId);\n if (!tracker) {\n const tunnelService = this.core.lifecycleManager?.serviceRegistry?.get(\"tunnel\") as TunnelServiceInterface | undefined;\n const session = this.core.sessionManager.getSession(sessionId);\n const sessionContext = session ? {\n id: sessionId,\n workingDirectory: session.workingDirectory,\n } : undefined;\n tracker = new ActivityTracker(\n this.bot.api,\n this.telegramConfig.chatId,\n threadId,\n this.sendQueue,\n outputMode,\n sessionId,\n this.getTracer(sessionId),\n tunnelService,\n sessionContext,\n );\n this.sessionTrackers.set(sessionId, tracker);\n } else {\n tracker.setOutputMode(outputMode);\n }\n return tracker;\n }\n\n constructor(\n core: OpenACPCore,\n config: TelegramChannelConfig,\n saveTopicIds?: (updates: { notificationTopicId?: number; assistantTopicId?: number }) => Promise<void>,\n ) {\n super({ configManager: core.configManager }, {\n ...(config as Record<string, unknown>),\n maxMessageLength: 4096,\n enabled: config.enabled ?? true,\n } as MessagingAdapterConfig);\n this.core = core;\n this.telegramConfig = config;\n this.saveTopicIds = saveTopicIds;\n }\n\n async start(): Promise<void> {\n this.bot = new Bot(this.telegramConfig.botToken, {\n client: {\n baseFetchConfig: { duplex: \"half\" } as RequestInit,\n fetch: patchedFetch,\n },\n });\n this.fileService = this.core.fileService;\n\n // Initialize extracted managers\n this.draftManager = new DraftManager(\n this.bot,\n this.telegramConfig.chatId,\n this.sendQueue,\n );\n this.skillManager = new SkillCommandManager(\n this.bot,\n this.telegramConfig.chatId,\n this.sendQueue,\n this.core.sessionManager,\n );\n\n // Global error handler — prevent unhandled errors from crashing the bot\n this.bot.catch((err) => {\n const rootCause = err.error instanceof Error ? err.error : err;\n log.error({ err: rootCause }, \"Telegram bot error\");\n });\n\n // Auto-retry on 429 (Too Many Requests)\n this.bot.api.config.use(async (prev, method, payload, signal) => {\n const maxRetries = 3;\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n const result = await prev(method, payload, signal);\n if (\n result.ok ||\n (result as { error_code?: number }).error_code !== 429 ||\n attempt === maxRetries\n ) {\n return result;\n }\n const retryAfter =\n ((result as { parameters?: { retry_after?: number } }).parameters\n ?.retry_after ?? 5) + 1;\n const rateLimitedMethods = [\n \"sendMessage\",\n \"editMessageText\",\n \"editMessageReplyMarkup\",\n ];\n if (rateLimitedMethods.includes(method)) {\n this.sendQueue.onRateLimited();\n }\n log.warn(\n { method, retryAfter, attempt: attempt + 1 },\n \"Rate limited by Telegram, retrying\",\n );\n await new Promise((r) => setTimeout(r, retryAfter * 1000));\n }\n return prev(method, payload, signal);\n });\n\n // Ensure allowed_updates includes callback_query on every poll\n this.bot.api.config.use((prev, method, payload, signal) => {\n if (method === \"getUpdates\") {\n const p = payload as Record<string, unknown>;\n p.allowed_updates = (p.allowed_updates as string[] | undefined) ?? [\n \"message\",\n \"callback_query\",\n ];\n }\n return prev(method, payload, signal);\n });\n\n // Register static commands for Telegram autocomplete\n await this.bot.api.setMyCommands(STATIC_COMMANDS, {\n scope: { type: \"chat\", chat_id: this.telegramConfig.chatId },\n });\n\n // Middleware: only accept updates from configured chatId\n this.bot.use((ctx, next) => {\n const chatId = ctx.chat?.id ?? ctx.callbackQuery?.message?.chat?.id;\n if (chatId !== this.telegramConfig.chatId) return;\n return next();\n });\n\n // Ensure system topics exist\n const topics = await ensureTopics(\n this.bot,\n this.telegramConfig.chatId,\n this.telegramConfig,\n async (updates) => {\n if (this.saveTopicIds) {\n await this.saveTopicIds(updates);\n } else {\n // Fallback for legacy usage without plugin settings\n await this.core.configManager.save({\n channels: { telegram: updates },\n });\n }\n },\n );\n this.notificationTopicId = topics.notificationTopicId;\n this.assistantTopicId = topics.assistantTopicId;\n\n // Setup permission handler\n this.permissionHandler = new PermissionHandler(\n this.bot,\n this.telegramConfig.chatId,\n (sessionId) => this.core.sessionManager.getSession(sessionId),\n (notification) => this.sendNotification(notification),\n );\n\n // Generic CommandRegistry dispatch — handles any command registered via plugin system.\n // Must be early so registry commands run before legacy bot.command() handlers.\n this.bot.on(\"message:text\", async (ctx, next) => {\n const text = ctx.message?.text;\n if (!text?.startsWith(\"/\")) return next();\n\n const registry =\n this.core.lifecycleManager?.serviceRegistry?.get<CommandRegistry>(\n \"command-registry\",\n );\n if (!registry) return next();\n\n // Extract command name (remove / and @botname suffix)\n const rawCommand = text.split(\" \")[0].slice(1);\n const atIdx = rawCommand.indexOf(\"@\");\n // If command is directed at another bot, ignore it\n if (\n atIdx !== -1 &&\n rawCommand.slice(atIdx + 1).toLowerCase() !==\n ctx.me.username.toLowerCase()\n ) {\n return next();\n }\n const commandName =\n atIdx === -1 ? rawCommand : rawCommand.slice(0, atIdx);\n const def = registry.get(commandName);\n if (!def) return next(); // not in registry, fall through to existing handlers\n\n const chatId = ctx.chat.id;\n const topicId = ctx.message.message_thread_id;\n\n try {\n const sessionId =\n topicId != null\n ? (this.core.sessionManager.getSessionByThread(\n \"telegram\",\n String(topicId),\n )?.id ?? null)\n : null;\n\n const response = await registry.execute(text, {\n raw: \"\",\n sessionId,\n channelId: \"telegram\",\n userId: String(ctx.from?.id),\n reply: async (content) => {\n if (typeof content === \"string\") {\n await ctx.reply(content);\n } else if (\n typeof content === \"object\" &&\n content !== null &&\n \"type\" in content\n ) {\n await this.renderCommandResponse(\n content as CommandResponse,\n chatId,\n topicId,\n );\n }\n },\n });\n\n if (response.type === \"silent\") {\n // Silent means the registry has no UI for this command — pass through\n // to adapter-specific handlers (e.g. handleNewChat, handleCancel).\n return next();\n }\n await this.renderCommandResponse(response, chatId, topicId);\n } catch (err) {\n await ctx.reply(`\\u26a0\\ufe0f Command failed: ${String(err)}`);\n }\n });\n\n // Callback query handler for command buttons (c/ prefix)\n this.bot.callbackQuery(/^c\\//, async (ctx) => {\n const data = ctx.callbackQuery.data;\n const command = this.fromCallbackData(data);\n\n const registry =\n this.core.lifecycleManager?.serviceRegistry?.get<CommandRegistry>(\n \"command-registry\",\n );\n if (!registry) return;\n\n const chatId = ctx.chat!.id;\n const topicId = ctx.callbackQuery.message?.message_thread_id;\n\n try {\n const sessionId =\n topicId != null\n ? (this.core.sessionManager.getSessionByThread(\n \"telegram\",\n String(topicId),\n )?.id ?? null)\n : null;\n\n const response = await registry.execute(command, {\n raw: \"\",\n sessionId,\n channelId: \"telegram\",\n userId: String(ctx.from?.id),\n reply: async (content) => {\n if (typeof content === \"string\") {\n await ctx.editMessageText(content).catch(() => {});\n }\n },\n });\n\n await ctx.answerCallbackQuery();\n if (response.type !== \"silent\") {\n await this.renderCommandResponse(response, chatId, topicId);\n }\n } catch {\n await ctx.answerCallbackQuery({ text: \"Command failed\" });\n }\n });\n\n // Callback registration order matters!\n setupDangerousModeCallbacks(this.bot, this.core as OpenACPCore);\n setupTTSCallbacks(this.bot, this.core as OpenACPCore);\n setupVerbosityCallbacks(this.bot, this.core as OpenACPCore);\n setupActionCallbacks(\n this.bot,\n this.core as OpenACPCore,\n this.telegramConfig.chatId,\n () => this.assistantSession?.id,\n );\n setupIntegrateCallbacks(this.bot, this.core as OpenACPCore);\n setupMenuCallbacks(\n this.bot,\n this.core as OpenACPCore,\n this.telegramConfig.chatId,\n {\n notificationTopicId: this.notificationTopicId,\n assistantTopicId: this.assistantTopicId,\n },\n () => {\n if (!this.assistantSession) return undefined;\n return {\n topicId: this.assistantTopicId,\n enqueuePrompt: (p: string) => this.assistantSession!.enqueuePrompt(p),\n };\n },\n );\n setupCommands(\n this.bot,\n this.core as OpenACPCore,\n this.telegramConfig.chatId,\n {\n topicId: this.assistantTopicId,\n getSession: () => this.assistantSession,\n respawn: async () => {\n if (this.assistantSession) {\n await this.assistantSession.destroy();\n this.assistantSession = null;\n }\n const { session, ready } = await spawnAssistant(\n this.core as OpenACPCore,\n this,\n this.assistantTopicId,\n );\n this.assistantSession = session;\n this.assistantInitializing = true;\n ready.then(() => {\n this.assistantInitializing = false;\n });\n },\n },\n );\n this.permissionHandler.setupCallbackHandler();\n\n // /handoff command\n this.bot.command(\"handoff\", async (ctx) => {\n const threadId = ctx.message?.message_thread_id;\n if (!threadId) return;\n\n if (\n threadId === this.notificationTopicId ||\n threadId === this.assistantTopicId\n ) {\n await ctx.reply(\"This command only works in session topics.\", {\n message_thread_id: threadId,\n });\n return;\n }\n\n const session = this.core.sessionManager.getSessionByThread(\n \"telegram\",\n String(threadId),\n );\n const record = session\n ? undefined\n : this.core.sessionManager.getRecordByThread(\n \"telegram\",\n String(threadId),\n );\n\n const agentName = session?.agentName ?? record?.agentName;\n const agentSessionId = session?.agentSessionId ?? record?.agentSessionId;\n\n if (!agentName || !agentSessionId) {\n await ctx.reply(\"No session found for this topic.\", {\n message_thread_id: threadId,\n });\n return;\n }\n\n const { getAgentCapabilities } =\n await import(\"../../core/agents/agent-registry.js\");\n const caps = getAgentCapabilities(agentName);\n\n if (!caps.supportsResume || !caps.resumeCommand) {\n await ctx.reply(\"This agent does not support session transfer.\", {\n message_thread_id: threadId,\n });\n return;\n }\n\n const command = caps.resumeCommand(agentSessionId);\n\n await ctx.reply(\n `Run this in your terminal to continue the session:\\n\\n<code>${command}</code>`,\n {\n message_thread_id: threadId,\n parse_mode: \"HTML\",\n },\n );\n });\n\n // Setup message routing\n this.setupRoutes();\n\n // Start bot polling\n this.bot.start({\n allowed_updates: [\"message\", \"callback_query\"],\n onStart: () =>\n log.info(\n { chatId: this.telegramConfig.chatId },\n \"Telegram bot started\",\n ),\n });\n\n // Send welcome message\n try {\n const config = this.core.configManager.get();\n const agents = this.core.agentManager.getAvailableAgents();\n const allRecords = this.core.sessionManager.listRecords();\n\n const welcomeText = buildWelcomeMessage({\n activeCount: allRecords.filter(\n (r) => r.status === \"active\" || r.status === \"initializing\",\n ).length,\n errorCount: allRecords.filter((r) => r.status === \"error\").length,\n totalCount: allRecords.length,\n agents: agents.map((a) => a.name),\n defaultAgent: config.defaultAgent,\n });\n\n await this.bot.api.sendMessage(this.telegramConfig.chatId, welcomeText, {\n message_thread_id: this.assistantTopicId,\n parse_mode: \"HTML\",\n reply_markup: buildMenuKeyboard(),\n });\n } catch (err) {\n log.warn({ err }, \"Failed to send welcome message\");\n }\n\n // Spawn assistant in background\n try {\n log.info(\"Spawning assistant session...\");\n const { session, ready } = await spawnAssistant(\n this.core as OpenACPCore,\n this,\n this.assistantTopicId,\n );\n this.assistantSession = session;\n this.assistantInitializing = true;\n log.info(\n { sessionId: session.id },\n \"Assistant session ready, system prompt running in background\",\n );\n ready.then(() => {\n this.assistantInitializing = false;\n log.info(\n { sessionId: session.id },\n \"Assistant ready for user messages\",\n );\n });\n } catch (err) {\n log.error({ err }, \"Failed to spawn assistant\");\n this.bot.api\n .sendMessage(\n this.telegramConfig.chatId,\n `⚠️ <b>Failed to start assistant session.</b>\\n\\n<code>${err instanceof Error ? err.message : String(err)}</code>`,\n { message_thread_id: this.assistantTopicId, parse_mode: \"HTML\" },\n )\n .catch(() => {});\n }\n }\n\n async stop(): Promise<void> {\n // Cleanup activity trackers (interval timers)\n for (const tracker of this.sessionTrackers.values()) {\n tracker.destroy();\n }\n this.sessionTrackers.clear();\n\n // Clear send queue\n this.sendQueue.clear();\n\n // Destroy assistant session\n if (this.assistantSession) {\n await this.assistantSession.destroy();\n }\n\n await this.bot.stop();\n log.info(\"Telegram bot stopped\");\n }\n\n // --- CommandRegistry response rendering ---\n\n private async renderCommandResponse(\n response: CommandResponse,\n chatId: number,\n topicId?: number,\n ): Promise<void> {\n switch (response.type) {\n case \"text\":\n await this.bot.api.sendMessage(chatId, response.text, {\n message_thread_id: topicId,\n });\n break;\n case \"error\":\n await this.bot.api.sendMessage(\n chatId,\n `\\u26a0\\ufe0f ${response.message}`,\n { message_thread_id: topicId },\n );\n break;\n case \"menu\": {\n const keyboard = response.options.map((opt) => [\n {\n text: `${opt.label}${opt.hint ? ` \\u2014 ${opt.hint}` : \"\"}`,\n callback_data: this.toCallbackData(opt.command),\n },\n ]);\n await this.bot.api.sendMessage(chatId, response.title, {\n message_thread_id: topicId,\n reply_markup: { inline_keyboard: keyboard },\n });\n break;\n }\n case \"list\": {\n const lines = response.items.map(\n (i) => `\\u2022 ${i.label}${i.detail ? ` \\u2014 ${i.detail}` : \"\"}`,\n );\n const text = `${response.title}\\n${lines.join(\"\\n\")}`;\n await this.bot.api.sendMessage(chatId, text, {\n message_thread_id: topicId,\n });\n break;\n }\n case \"confirm\": {\n const buttons = [\n [\n {\n text: \"\\u2705 Yes\",\n callback_data: this.toCallbackData(response.onYes),\n },\n ],\n ];\n if (response.onNo) {\n buttons[0].push({\n text: \"\\u274c No\",\n callback_data: this.toCallbackData(response.onNo),\n });\n }\n await this.bot.api.sendMessage(chatId, response.question, {\n message_thread_id: topicId,\n reply_markup: { inline_keyboard: buttons },\n });\n break;\n }\n case \"silent\":\n break;\n }\n }\n\n private toCallbackData(command: string): string {\n const data = `c/${command}`;\n if (data.length <= 64) return data;\n const id = String(++this.callbackCounter);\n this.callbackCache.set(id, command);\n if (this.callbackCache.size > 1000) {\n const first = this.callbackCache.keys().next().value;\n if (first) this.callbackCache.delete(first);\n }\n return `c/#${id}`;\n }\n\n private fromCallbackData(data: string): string {\n if (data.startsWith(\"c/#\")) {\n return this.callbackCache.get(data.slice(3)) ?? data.slice(2);\n }\n return data.slice(2);\n }\n\n private setupRoutes(): void {\n this.bot.on(\"message:text\", async (ctx) => {\n const threadId = ctx.message.message_thread_id;\n const text = ctx.message.text;\n\n // Check for pending workspace input from interactive /new flow\n if (\n await handlePendingWorkspaceInput(\n ctx,\n this.core,\n this.telegramConfig.chatId,\n this.assistantTopicId,\n )\n ) {\n return;\n }\n\n // Check for pending workspace input from interactive /resume flow\n if (\n await handlePendingResumeInput(\n ctx,\n this.core,\n this.telegramConfig.chatId,\n this.assistantTopicId,\n )\n ) {\n return;\n }\n\n // General topic or no thread → redirect to assistant\n if (!threadId) {\n const html = redirectToAssistant(\n this.telegramConfig.chatId,\n this.assistantTopicId,\n );\n await ctx.reply(html, { parse_mode: \"HTML\" });\n return;\n }\n\n // Notification topic → ignore\n if (threadId === this.notificationTopicId) return;\n\n // Strip leading \"/\" from unrecognized commands — registered commands\n // (e.g. /new, /cancel) are already handled by bot.command() above.\n // Unrecognized slash commands can cause agent subprocesses to hang.\n const forwardText = text.startsWith(\"/\") ? text.slice(1) : text;\n\n // Assistant topic → forward to assistant session\n if (threadId === this.assistantTopicId) {\n if (!this.assistantSession) {\n await ctx.reply(\n \"⚠️ Assistant is not available yet. Please try again shortly.\",\n { parse_mode: \"HTML\" },\n );\n return;\n }\n await this.draftManager.finalize(\n this.assistantSession.id,\n this.assistantSession.id,\n );\n ctx.replyWithChatAction(\"typing\").catch(() => {});\n handleAssistantMessage(this.assistantSession, forwardText).catch(\n (err) => log.error({ err }, \"Assistant error\"),\n );\n return;\n }\n\n // Session topic → forward to core\n const sessionId = this.core.sessionManager.getSessionByThread(\n \"telegram\",\n String(threadId),\n )?.id;\n if (sessionId) {\n this.getTracer(sessionId)?.log(\"telegram\", { action: \"incoming:message\", sessionId, userId: String(ctx.from?.id), text: ctx.message?.text });\n await this.draftManager.finalize(sessionId, this.assistantSession?.id);\n }\n if (sessionId) {\n const tracker = this.sessionTrackers.get(sessionId);\n if (tracker) await tracker.onNewPrompt();\n }\n ctx.replyWithChatAction(\"typing\").catch(() => {});\n this.core\n .handleMessage({\n channelId: \"telegram\",\n threadId: String(threadId),\n userId: String(ctx.from.id),\n text: forwardText,\n })\n .catch((err) => log.error({ err }, \"handleMessage error\"));\n });\n\n // --- Incoming media handlers ---\n\n this.bot.on(\"message:photo\", async (ctx) => {\n const threadId = ctx.message.message_thread_id;\n if (!threadId || threadId === this.notificationTopicId) return;\n\n const photos = ctx.message.photo;\n const largest = photos[photos.length - 1];\n const ext = \".jpg\";\n await this.handleIncomingMedia(\n threadId,\n ctx.from.id,\n largest.file_id,\n `photo${ext}`,\n \"image/jpeg\",\n ctx.message.caption || undefined,\n );\n });\n\n this.bot.on(\"message:document\", async (ctx) => {\n const threadId = ctx.message.message_thread_id;\n if (!threadId || threadId === this.notificationTopicId) return;\n\n const doc = ctx.message.document;\n await this.handleIncomingMedia(\n threadId,\n ctx.from.id,\n doc.file_id,\n doc.file_name || \"document\",\n doc.mime_type || \"application/octet-stream\",\n ctx.message.caption || undefined,\n );\n });\n\n this.bot.on(\"message:voice\", async (ctx) => {\n const threadId = ctx.message.message_thread_id;\n if (!threadId || threadId === this.notificationTopicId) return;\n\n const voice = ctx.message.voice;\n await this.handleIncomingMedia(\n threadId,\n ctx.from.id,\n voice.file_id,\n \"voice.wav\",\n \"audio/wav\",\n undefined,\n true,\n );\n });\n\n this.bot.on(\"message:audio\", async (ctx) => {\n const threadId = ctx.message.message_thread_id;\n if (!threadId || threadId === this.notificationTopicId) return;\n\n const audio = ctx.message.audio;\n await this.handleIncomingMedia(\n threadId,\n ctx.from.id,\n audio.file_id,\n audio.file_name || \"audio.mp3\",\n audio.mime_type || \"audio/mpeg\",\n ctx.message.caption || undefined,\n );\n });\n\n this.bot.on(\"message:video_note\", async (ctx) => {\n const threadId = ctx.message.message_thread_id;\n if (!threadId || threadId === this.notificationTopicId) return;\n\n const videoNote = ctx.message.video_note;\n await this.handleIncomingMedia(\n threadId,\n ctx.from.id,\n videoNote.file_id,\n \"video_note.mp4\",\n \"video/mp4\",\n );\n });\n }\n\n // --- MessagingAdapter overrides ---\n\n /**\n * Per-session serial dispatch queues.\n * SessionBridge fires sendMessage() as fire-and-forget, so multiple events\n * (tool_call, tool_update, text) can arrive concurrently. Without serialization,\n * fast handlers (tool_update) overtake slow ones (tool_call with draftManager.finalize),\n * causing out-of-order processing where a tool's completion update is processed before\n * its creation event. This queue ensures events are processed in the order they arrive.\n */\n private _dispatchQueues = new Map<string, Promise<void>>();\n\n private getTracer(sessionId: string): DebugTracer | null {\n return this.core.sessionManager.getSession(sessionId)?.agentInstance?.debugTracer ?? null;\n }\n\n async sendMessage(\n sessionId: string,\n content: OutgoingMessage,\n ): Promise<void> {\n // Suppress assistant messages during system prompt\n if (this.assistantInitializing && sessionId === this.assistantSession?.id)\n return;\n\n const session = this.core.sessionManager.getSession(sessionId);\n if (!session) return;\n\n // Drop messages while topic is being recreated (archive in progress)\n if (session.archiving) return;\n const threadId = Number(session.threadId);\n if (!threadId || isNaN(threadId)) {\n log.warn(\n { sessionId, threadId: session.threadId },\n \"Session has no valid threadId, skipping message\",\n );\n return;\n }\n\n // Serialize dispatch per session to preserve event ordering\n const prev = this._dispatchQueues.get(sessionId) ?? Promise.resolve();\n const next = prev.then(async () => {\n this.getTracer(sessionId)?.log(\"telegram\", { action: \"dispatch:enter\", sessionId, message: content });\n this._sessionThreadIds.set(sessionId, threadId);\n try {\n await super.sendMessage(sessionId, content);\n } finally {\n this._sessionThreadIds.delete(sessionId);\n }\n }).catch((err) => {\n log.warn({ err, sessionId }, \"Dispatch queue error\");\n });\n this._dispatchQueues.set(sessionId, next);\n await next;\n }\n\n protected async handleThought(\n sessionId: string,\n content: OutgoingMessage,\n _verbosity: DisplayVerbosity,\n ): Promise<void> {\n this.getTracer(sessionId)?.log(\"telegram\", { action: \"handle:thought\", sessionId, text: content.text });\n const threadId = this.getThreadId(sessionId);\n const mode = this.outputModeResolver.resolve(\n this.context.configManager,\n this.name,\n sessionId,\n this.core.sessionManager as any,\n );\n const tracker = this.getOrCreateTracker(sessionId, threadId, mode);\n await tracker.onThought(content.text);\n }\n\n protected async handleText(\n sessionId: string,\n content: OutgoingMessage,\n ): Promise<void> {\n this.getTracer(sessionId)?.log(\"telegram\", { action: \"handle:text\", sessionId, text: content.text });\n const threadId = this.getThreadId(sessionId);\n // Per-session dispatch queue serializes all events, so we can safely await here.\n if (!this.draftManager.hasDraft(sessionId)) {\n const mode = this.outputModeResolver.resolve(\n this.context.configManager,\n this.name,\n sessionId,\n this.core.sessionManager as any,\n );\n const tracker = this.getOrCreateTracker(sessionId, threadId, mode);\n await tracker.onTextStart();\n }\n const draft = this.draftManager.getOrCreate(sessionId, threadId, this.getTracer(sessionId));\n draft.append(content.text);\n this.draftManager.appendText(sessionId, content.text);\n }\n\n protected async handleToolCall(\n sessionId: string,\n content: OutgoingMessage,\n _verbosity: DisplayVerbosity,\n ): Promise<void> {\n const threadId = this.getThreadId(sessionId);\n const meta = (content.metadata ?? {}) as Partial<ToolCallMeta>;\n this.getTracer(sessionId)?.log(\"telegram\", { action: \"handle:toolCall\", sessionId, toolId: meta.id, toolName: meta.name, kind: meta.kind, status: meta.status, displaySummary: meta.displaySummary, rawInput: meta.rawInput });\n\n const mode = this.outputModeResolver.resolve(\n this.context.configManager,\n this.name,\n sessionId,\n this.core.sessionManager as any,\n );\n const tracker = this.getOrCreateTracker(sessionId, threadId, mode);\n await this.draftManager.finalize(sessionId, this.assistantSession?.id);\n await tracker.onToolCall(\n {\n id: meta.id ?? \"\",\n name: meta.name ?? content.text ?? \"Tool\",\n kind: meta.kind,\n status: meta.status,\n content: meta.content,\n rawInput: meta.rawInput,\n viewerLinks: meta.viewerLinks,\n viewerFilePath: meta.viewerFilePath,\n displaySummary: meta.displaySummary as string | undefined,\n displayTitle: meta.displayTitle as string | undefined,\n displayKind: meta.displayKind as string | undefined,\n },\n String(meta.kind ?? \"\"),\n meta.rawInput,\n );\n }\n\n protected async handleToolUpdate(\n sessionId: string,\n content: OutgoingMessage,\n _verbosity: DisplayVerbosity,\n ): Promise<void> {\n const threadId = this.getThreadId(sessionId);\n const meta = (content.metadata ?? {}) as Partial<ToolUpdateMeta>;\n this.getTracer(sessionId)?.log(\"telegram\", { action: \"handle:toolUpdate\", sessionId, toolId: meta.id, name: meta.name, kind: meta.kind, status: meta.status, viewerLinks: meta.viewerLinks, viewerFilePath: meta.viewerFilePath });\n const mode = this.outputModeResolver.resolve(\n this.context.configManager,\n this.name,\n sessionId,\n this.core.sessionManager as any,\n );\n const tracker = this.getOrCreateTracker(sessionId, threadId, mode);\n await tracker.onToolUpdate(\n meta.id ?? \"\",\n meta.status ?? \"completed\",\n meta.viewerLinks as { file?: string; diff?: string } | undefined,\n meta.viewerFilePath as string | undefined,\n typeof meta.content === \"string\" ? meta.content : null,\n meta.rawInput ?? undefined,\n (meta as any).diffStats as { added: number; removed: number } | undefined,\n );\n }\n\n protected async handlePlan(\n sessionId: string,\n content: OutgoingMessage,\n _verbosity: DisplayVerbosity,\n ): Promise<void> {\n const threadId = this.getThreadId(sessionId);\n const meta = (content.metadata ?? {}) as Partial<PlanMetadata>;\n const entries = meta.entries ?? [];\n this.getTracer(sessionId)?.log(\"telegram\", { action: \"handle:plan\", sessionId, entryCount: entries.length });\n const mode = this.outputModeResolver.resolve(\n this.context.configManager,\n this.name,\n sessionId,\n this.core.sessionManager as any,\n );\n const tracker = this.getOrCreateTracker(sessionId, threadId, mode);\n await tracker.onPlan(\n entries.map((e) => ({\n content: e.content,\n status: e.status as \"pending\" | \"in_progress\" | \"completed\",\n priority: (e.priority ?? \"medium\") as \"high\" | \"medium\" | \"low\",\n })),\n );\n }\n\n protected async handleUsage(\n sessionId: string,\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): Promise<void> {\n const threadId = this.getThreadId(sessionId);\n const meta = content.metadata as UsageMetadata | undefined;\n this.getTracer(sessionId)?.log(\"telegram\", { action: \"handle:usage\", sessionId, tokensUsed: meta?.tokensUsed, contextSize: meta?.contextSize, cost: (meta as Record<string, unknown>)?.cost });\n await this.draftManager.finalize(sessionId, this.assistantSession?.id);\n\n // Send usage as a separate message (not part of the tool card)\n const usageText = formatUsage(meta ?? {}, verbosity);\n let usageMsgId: number | undefined;\n try {\n const result = await this.sendQueue.enqueue(() =>\n this.bot.api.sendMessage(this.telegramConfig.chatId, usageText, {\n message_thread_id: threadId,\n parse_mode: \"HTML\",\n disable_notification: true,\n }),\n );\n usageMsgId = result?.message_id;\n } catch (err) {\n log.warn({ err, sessionId }, \"Failed to send usage message\");\n }\n\n // Notify the Notifications topic that a prompt has completed\n if (this.notificationTopicId && sessionId !== this.assistantSession?.id) {\n const sess = this.core.sessionManager.getSession(sessionId);\n const sessionName = sess?.name || \"Session\";\n const chatIdStr = String(this.telegramConfig.chatId);\n const numericId = chatIdStr.startsWith(\"-100\")\n ? chatIdStr.slice(4)\n : chatIdStr.replace(\"-\", \"\");\n const deepLink = usageMsgId\n ? `https://t.me/c/${numericId}/${threadId}/${usageMsgId}`\n : `https://t.me/c/${numericId}/${threadId}`;\n const text = `✅ <b>${escapeHtml(sessionName)}</b>\\nTask completed.\\n\\n<a href=\"${deepLink}\">→ Go to topic</a>`;\n this.sendQueue\n .enqueue(() =>\n this.bot.api.sendMessage(this.telegramConfig.chatId, text, {\n message_thread_id: this.notificationTopicId,\n parse_mode: \"HTML\",\n disable_notification: false,\n }),\n )\n .catch(() => {});\n }\n }\n\n protected async handleAttachment(\n sessionId: string,\n content: OutgoingMessage,\n ): Promise<void> {\n this.getTracer(sessionId)?.log(\"telegram\", { action: \"handle:attachment\", sessionId, type: content.attachment?.type, fileName: content.attachment?.fileName });\n const threadId = this.getThreadId(sessionId);\n if (!content.attachment) return;\n const { attachment } = content;\n\n // Telegram bot API upload limit: 50MB\n if (attachment.size > 50 * 1024 * 1024) {\n log.warn(\n {\n sessionId,\n fileName: attachment.fileName,\n size: attachment.size,\n },\n \"File too large for Telegram (>50MB)\",\n );\n await this.sendQueue.enqueue(() =>\n this.bot.api.sendMessage(\n this.telegramConfig.chatId,\n `⚠️ File too large to send (${Math.round(attachment.size / 1024 / 1024)}MB): ${escapeHtml(attachment.fileName)}`,\n { message_thread_id: threadId, parse_mode: \"HTML\" },\n ),\n );\n return;\n }\n\n try {\n const inputFile = new InputFile(attachment.filePath);\n if (attachment.type === \"image\") {\n await this.sendQueue.enqueue(() =>\n this.bot.api.sendPhoto(this.telegramConfig.chatId, inputFile, {\n message_thread_id: threadId,\n }),\n );\n } else if (attachment.type === \"audio\") {\n await this.sendQueue.enqueue(() =>\n this.bot.api.sendVoice(this.telegramConfig.chatId, inputFile, {\n message_thread_id: threadId,\n }),\n );\n // Strip [TTS]...[/TTS] block from the text message after voice is sent\n const draft = this.draftManager.getDraft(sessionId);\n if (draft) {\n draft.stripPattern(/\\[TTS\\][\\s\\S]*?\\[\\/TTS\\]/g).catch(() => {});\n }\n } else {\n await this.sendQueue.enqueue(() =>\n this.bot.api.sendDocument(this.telegramConfig.chatId, inputFile, {\n message_thread_id: threadId,\n }),\n );\n }\n } catch (err) {\n log.error(\n { err, sessionId, fileName: attachment.fileName },\n \"Failed to send attachment\",\n );\n }\n }\n\n protected async handleSessionEnd(\n sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {\n this.getTracer(sessionId)?.log(\"telegram\", { action: \"handle:sessionEnd\", sessionId });\n const threadId = this.getThreadId(sessionId);\n await this.draftManager.finalize(sessionId, this.assistantSession?.id);\n this.draftManager.cleanup(sessionId);\n await this.skillManager.cleanup(sessionId);\n const tracker = this.sessionTrackers.get(sessionId);\n if (tracker) {\n await tracker.cleanup();\n this.sessionTrackers.delete(sessionId);\n } else {\n await this.sendQueue.enqueue(() =>\n this.bot.api.sendMessage(this.telegramConfig.chatId, `✅ <b>Done</b>`, {\n message_thread_id: threadId,\n parse_mode: \"HTML\",\n disable_notification: true,\n }),\n );\n }\n }\n\n protected async handleError(\n sessionId: string,\n content: OutgoingMessage,\n ): Promise<void> {\n this.getTracer(sessionId)?.log(\"telegram\", { action: \"handle:error\", sessionId, text: content.text });\n const threadId = this.getThreadId(sessionId);\n await this.draftManager.finalize(sessionId, this.assistantSession?.id);\n const tracker = this.sessionTrackers.get(sessionId);\n if (tracker) {\n tracker.destroy();\n this.sessionTrackers.delete(sessionId);\n }\n await this.sendQueue.enqueue(() =>\n this.bot.api.sendMessage(\n this.telegramConfig.chatId,\n `❌ <b>Error:</b> ${escapeHtml(content.text)}`,\n {\n message_thread_id: threadId,\n parse_mode: \"HTML\",\n disable_notification: true,\n },\n ),\n );\n }\n\n protected async handleSystem(\n sessionId: string,\n content: OutgoingMessage,\n ): Promise<void> {\n this.getTracer(sessionId)?.log(\"telegram\", { action: \"handle:system\", sessionId, text: content.text });\n const threadId = this.getThreadId(sessionId);\n await this.sendQueue.enqueue(() =>\n this.bot.api.sendMessage(\n this.telegramConfig.chatId,\n escapeHtml(content.text),\n {\n message_thread_id: threadId,\n parse_mode: \"HTML\",\n disable_notification: true,\n },\n ),\n );\n }\n\n async sendPermissionRequest(\n sessionId: string,\n request: PermissionRequest,\n ): Promise<void> {\n this.getTracer(sessionId)?.log(\"telegram\", { action: \"permission:send\", sessionId, requestId: request.id, description: request.description });\n log.info({ sessionId, requestId: request.id }, \"Permission request sent\");\n const session = this.core.sessionManager.getSession(sessionId);\n if (!session) return;\n\n await this.sendQueue.enqueue(() =>\n this.permissionHandler.sendPermissionRequest(session, request),\n );\n }\n\n async sendNotification(notification: NotificationMessage): Promise<void> {\n this.getTracer(notification.sessionId)?.log(\"telegram\", { action: \"notification:send\", sessionId: notification.sessionId, type: notification.type });\n if (notification.sessionId === this.assistantSession?.id) return;\n\n log.info(\n { sessionId: notification.sessionId, type: notification.type },\n \"Notification sent\",\n );\n if (!this.notificationTopicId) return;\n const emoji: Record<string, string> = {\n completed: \"✅\",\n error: \"❌\",\n permission: \"🔐\",\n input_required: \"💬\",\n };\n let text = `${emoji[notification.type] || \"ℹ️\"} <b>${escapeHtml(notification.sessionName || \"New session\")}</b>\\n`;\n text += escapeHtml(notification.summary);\n\n const deepLink =\n notification.deepLink ??\n (() => {\n const session = this.core.sessionManager.getSession(\n notification.sessionId,\n );\n const threadId = session?.threadId;\n if (!threadId) return undefined;\n const chatIdStr = String(this.telegramConfig.chatId);\n const numericId = chatIdStr.startsWith(\"-100\")\n ? chatIdStr.slice(4)\n : chatIdStr.replace(\"-\", \"\");\n return `https://t.me/c/${numericId}/${threadId}`;\n })();\n\n if (deepLink) {\n text += `\\n\\n<a href=\"${deepLink}\">→ Go to topic</a>`;\n }\n\n await this.sendQueue.enqueue(() =>\n this.bot.api.sendMessage(this.telegramConfig.chatId, text, {\n message_thread_id: this.notificationTopicId,\n parse_mode: \"HTML\",\n disable_notification: false,\n }),\n );\n }\n\n async createSessionThread(sessionId: string, name: string): Promise<string> {\n this.getTracer(sessionId)?.log(\"telegram\", { action: \"thread:create\", sessionId, name });\n log.info({ sessionId, name }, \"Session topic created\");\n return String(\n await createSessionTopic(this.bot, this.telegramConfig.chatId, name),\n );\n }\n\n async renameSessionThread(sessionId: string, newName: string): Promise<void> {\n this.getTracer(sessionId)?.log(\"telegram\", { action: \"thread:rename\", sessionId, newName });\n const session = this.core.sessionManager.getSession(sessionId);\n if (!session) return;\n await renameSessionTopic(\n this.bot,\n this.telegramConfig.chatId,\n Number(session.threadId),\n newName,\n );\n await this.core.sessionManager.patchRecord(sessionId, { name: newName });\n }\n\n async deleteSessionThread(sessionId: string): Promise<void> {\n const record = this.core.sessionManager.getSessionRecord(sessionId);\n const platform = record?.platform as\n | import(\"../../core/types.js\").TelegramPlatformData\n | undefined;\n const topicId = platform?.topicId;\n if (!topicId) return;\n\n try {\n await this.bot.api.deleteForumTopic(this.telegramConfig.chatId, topicId);\n } catch (err) {\n log.warn(\n { err, sessionId, topicId },\n \"Failed to delete forum topic (may already be deleted)\",\n );\n }\n }\n\n async sendSkillCommands(\n sessionId: string,\n commands: AgentCommand[],\n ): Promise<void> {\n if (sessionId === this.assistantSession?.id) return;\n\n const session = this.core.sessionManager.getSession(sessionId);\n if (!session) return;\n const threadId = Number(session.threadId);\n if (!threadId) return;\n\n await this.skillManager.send(sessionId, threadId, commands);\n }\n\n private resolveSessionId(threadId: number): string | undefined {\n return this.core.sessionManager.getSessionByThread(\n \"telegram\",\n String(threadId),\n )?.id;\n }\n\n private async downloadTelegramFile(\n fileId: string,\n ): Promise<{ buffer: Buffer; filePath: string } | null> {\n try {\n const file = await this.bot.api.getFile(fileId);\n if (!file.file_path) return null;\n const url = `https://api.telegram.org/file/bot${this.telegramConfig.botToken}/${file.file_path}`;\n const response = await fetch(url);\n if (!response.ok) return null;\n const buffer = Buffer.from(await response.arrayBuffer());\n return { buffer, filePath: file.file_path };\n } catch (err) {\n log.error({ err }, \"Failed to download file from Telegram\");\n return null;\n }\n }\n\n private async handleIncomingMedia(\n threadId: number,\n userId: number,\n fileId: string,\n fileName: string,\n mimeType: string,\n caption?: string,\n convertOggToWav?: boolean,\n ): Promise<void> {\n const downloaded = await this.downloadTelegramFile(fileId);\n if (!downloaded) return;\n\n let buffer = downloaded.buffer;\n let originalFilePath: string | undefined;\n const sessionId = this.resolveSessionId(threadId) || \"unknown\";\n\n if (convertOggToWav) {\n // Save original OGG for STT (smaller, API-compatible)\n const oggAtt = await this.fileService.saveFile(\n sessionId,\n \"voice.ogg\",\n downloaded.buffer,\n \"audio/ogg\",\n );\n originalFilePath = oggAtt.filePath;\n\n try {\n buffer = await this.fileService.convertOggToWav(buffer);\n } catch (err) {\n log.warn({ err }, \"OGG→WAV conversion failed, saving original OGG\");\n fileName = \"voice.ogg\";\n mimeType = \"audio/ogg\";\n originalFilePath = undefined;\n }\n }\n\n const att = await this.fileService.saveFile(\n sessionId,\n fileName,\n buffer,\n mimeType,\n );\n if (originalFilePath) {\n att.originalFilePath = originalFilePath;\n }\n\n const rawText =\n caption ||\n `[${att.type === \"image\" ? \"Photo\" : att.type === \"audio\" ? \"Audio\" : \"File\"}: ${att.fileName}]`;\n const text = rawText.startsWith(\"/\") ? rawText.slice(1) : rawText;\n\n // Assistant topic\n if (threadId === this.assistantTopicId) {\n if (this.assistantSession) {\n await this.assistantSession.enqueuePrompt(text, [att]);\n }\n return;\n }\n\n // Session topic\n const sid = this.resolveSessionId(threadId);\n if (sid) await this.draftManager.finalize(sid, this.assistantSession?.id);\n this.core\n .handleMessage({\n channelId: \"telegram\",\n threadId: String(threadId),\n userId: String(userId),\n text,\n attachments: [att],\n })\n .catch((err) => log.error({ err }, \"handleMessage error\"));\n }\n\n async cleanupSkillCommands(sessionId: string): Promise<void> {\n await this.skillManager.cleanup(sessionId);\n }\n\n async cleanupSessionState(sessionId: string): Promise<void> {\n // Finalize and clean up draft state\n await this.draftManager.finalize(sessionId, this.assistantSession?.id);\n this.draftManager.cleanup(sessionId);\n\n // Destroy activity tracker (stops ThinkingIndicator timers, finalizes ToolCard)\n const tracker = this.sessionTrackers.get(sessionId);\n if (tracker) {\n tracker.destroy();\n this.sessionTrackers.delete(sessionId);\n }\n }\n\n async stripTTSBlock(sessionId: string): Promise<void> {\n await this.draftManager.stripPattern(sessionId, /\\[TTS\\][\\s\\S]*?\\[\\/TTS\\]/g);\n }\n\n async archiveSessionTopic(sessionId: string): Promise<string> {\n this.getTracer(sessionId)?.log(\"telegram\", { action: \"thread:archive\", sessionId });\n const core = this.core as OpenACPCore;\n const session = core.sessionManager.getSession(sessionId);\n if (!session) throw new Error(\"Session not found\");\n\n const chatId = this.telegramConfig.chatId;\n const oldTopicId = Number(session.threadId);\n\n // Set archiving flag — sendMessage will skip while this is true.\n session.archiving = true;\n\n // Finalize any pending draft\n await this.draftManager.finalize(session.id, this.assistantSession?.id);\n\n // Cleanup all trackers\n this.draftManager.cleanup(session.id);\n await this.skillManager.cleanup(session.id);\n const tracker = this.sessionTrackers.get(session.id);\n if (tracker) {\n tracker.destroy();\n this.sessionTrackers.delete(session.id);\n }\n\n // 1. Delete old topic (removes all messages)\n await deleteSessionTopic(this.bot, chatId, oldTopicId);\n\n // 2. Create new topic with session name\n const topicName = session.name ?? `Session ${session.id.slice(0, 6)}`;\n const newTopicId = await createSessionTopic(this.bot, chatId, topicName);\n\n // Clear archiving flag — messages can now be sent to new topic\n session.archiving = false;\n\n return String(newTopicId);\n }\n}\n","import type { OpenACPPlugin, InstallContext } from '../../core/plugin/types.js'\nimport type { OpenACPCore } from '../../core/core.js'\nimport type { TelegramChannelConfig } from './types.js'\n\nfunction createTelegramPlugin(): OpenACPPlugin {\n let adapter: { stop(): Promise<void> } | null = null\n\n return {\n name: '@openacp/telegram',\n version: '1.0.0',\n description: 'Telegram adapter with forum topics',\n essential: true,\n pluginDependencies: {\n '@openacp/security': '^1.0.0',\n '@openacp/notifications': '^1.0.0',\n },\n optionalPluginDependencies: {\n '@openacp/speech': '^1.0.0',\n },\n permissions: ['services:register', 'kernel:access', 'events:read'],\n inheritableKeys: [],\n\n async install(ctx: InstallContext) {\n const { terminal, settings, legacyConfig } = ctx\n\n // Migrate from legacy config if present\n if (legacyConfig) {\n const tg = legacyConfig.channels as Record<string, unknown> | undefined\n const telegramCfg = tg?.telegram as Record<string, unknown> | undefined\n if (telegramCfg?.botToken) {\n await settings.setAll({\n botToken: telegramCfg.botToken,\n chatId: telegramCfg.chatId,\n notificationTopicId: telegramCfg.notificationTopicId ?? null,\n assistantTopicId: telegramCfg.assistantTopicId ?? null,\n })\n terminal.log.success('Telegram settings migrated from legacy config')\n return\n }\n }\n\n // Interactive setup via terminal\n const { validateBotToken, validateChatId, validateBotAdmin } = await import('./validators.js')\n\n let botToken = ''\n while (true) {\n botToken = await terminal.text({\n message: 'Telegram bot token (from @BotFather):',\n validate: (val) => {\n if (!val.trim()) return 'Token cannot be empty'\n return undefined\n },\n })\n botToken = botToken.trim()\n\n const spin = terminal.spinner()\n spin.start('Validating token...')\n const result = await validateBotToken(botToken)\n if (result.ok) {\n spin.stop(`Connected to @${result.botUsername}`)\n break\n }\n spin.fail(result.error)\n const action = await terminal.select({\n message: 'What to do?',\n options: [\n { label: 'Re-enter token', value: 'retry' },\n { label: 'Use as-is (skip validation)', value: 'skip' },\n ],\n })\n if (action === 'skip') break\n }\n\n // Chat ID detection\n terminal.log.info('Send a message in your Telegram supergroup to detect the chat ID,')\n terminal.log.info('or enter the chat ID manually.')\n\n const chatIdMethod = await terminal.select({\n message: 'How to get the chat ID?',\n options: [\n { value: 'manual', label: 'Enter chat ID manually' },\n { value: 'detect', label: 'Auto-detect from group message' },\n ],\n })\n\n let chatId: number\n if (chatIdMethod === 'manual') {\n const val = await terminal.text({\n message: 'Supergroup chat ID (e.g. -1001234567890):',\n validate: (v) => {\n const n = Number(v.trim())\n if (isNaN(n) || !Number.isInteger(n)) return 'Chat ID must be an integer'\n return undefined\n },\n })\n chatId = Number(val.trim())\n } else {\n // Simple polling-based detection\n terminal.log.step('Listening for messages... Send \"hi\" in the group.')\n chatId = await detectChatIdViaPolling(botToken, terminal)\n }\n\n // Validate chat ID\n const chatResult = await validateChatId(botToken, chatId)\n if (chatResult.ok) {\n terminal.log.success(`Group: ${chatResult.title}${chatResult.isForum ? ' (Topics enabled)' : ''}`)\n } else {\n terminal.log.warning(chatResult.error)\n }\n\n // Validate admin\n const adminResult = await validateBotAdmin(botToken, chatId)\n if (adminResult.ok) {\n terminal.log.success('Bot has admin privileges')\n } else {\n terminal.log.warning(adminResult.error)\n }\n\n await settings.setAll({\n botToken,\n chatId,\n notificationTopicId: null,\n assistantTopicId: null,\n })\n terminal.log.success('Telegram settings saved')\n },\n\n async configure(ctx: InstallContext) {\n const { terminal, settings } = ctx\n const current = await settings.getAll()\n\n const choice = await terminal.select({\n message: 'What to configure?',\n options: [\n { value: 'token', label: 'Change bot token' },\n { value: 'chatId', label: 'Change chat ID' },\n { value: 'done', label: 'Done' },\n ],\n })\n\n if (choice === 'token') {\n const token = await terminal.text({\n message: 'New bot token:',\n validate: (v) => (!v.trim() ? 'Token cannot be empty' : undefined),\n })\n await settings.set('botToken', token.trim())\n terminal.log.success('Bot token updated')\n } else if (choice === 'chatId') {\n const val = await terminal.text({\n message: 'New chat ID:',\n defaultValue: String(current.chatId ?? ''),\n validate: (v) => {\n const n = Number(v.trim())\n if (isNaN(n) || !Number.isInteger(n)) return 'Chat ID must be an integer'\n return undefined\n },\n })\n await settings.set('chatId', Number(val.trim()))\n terminal.log.success('Chat ID updated')\n }\n },\n\n async uninstall(ctx: InstallContext, opts: { purge: boolean }) {\n if (opts.purge) {\n await ctx.settings.clear()\n ctx.terminal.log.success('Telegram settings cleared')\n }\n },\n\n async setup(ctx) {\n const config = ctx.pluginConfig as Record<string, unknown>\n if (!config.botToken || !config.chatId) {\n ctx.log.info('Telegram disabled (missing botToken or chatId)')\n return\n }\n\n const core = ctx.core as OpenACPCore\n const settingsManager = core.lifecycleManager?.settingsManager\n\n // If topic IDs are null in plugin settings but present in main config, migrate them.\n // This handles users who ran a version where ensureTopics saved to main config instead of plugin settings.\n if ((config.notificationTopicId == null || config.assistantTopicId == null) && settingsManager) {\n const mainCfg = core.configManager.get()\n const legacy = (mainCfg as any)?.channels?.telegram as Record<string, unknown> | undefined\n const migrated: Record<string, unknown> = {}\n if (legacy?.notificationTopicId != null && config.notificationTopicId == null) {\n config.notificationTopicId = legacy.notificationTopicId\n migrated.notificationTopicId = legacy.notificationTopicId\n }\n if (legacy?.assistantTopicId != null && config.assistantTopicId == null) {\n config.assistantTopicId = legacy.assistantTopicId\n migrated.assistantTopicId = legacy.assistantTopicId\n }\n if (Object.keys(migrated).length > 0) {\n await settingsManager.updatePluginSettings(ctx.pluginName, migrated)\n ctx.log.info('Migrated topic IDs from main config to plugin settings')\n }\n }\n\n const { TelegramAdapter } = await import('./adapter.js')\n // config is a Record<string, unknown> from pluginConfig; at runtime it\n // contains all TelegramChannelConfig fields populated from the migrated config.\n adapter = new TelegramAdapter(core, {\n ...config,\n enabled: true,\n maxMessageLength: 4096,\n } as unknown as TelegramChannelConfig, async (updates) => {\n // Save topic IDs to plugin settings so they persist across restarts\n if (settingsManager) {\n await settingsManager.updatePluginSettings(ctx.pluginName, updates)\n }\n })\n\n ctx.registerService('adapter:telegram', adapter)\n ctx.log.info('Telegram adapter registered')\n },\n\n async teardown() {\n if (adapter) {\n await adapter.stop()\n }\n },\n }\n}\n\nasync function detectChatIdViaPolling(\n token: string,\n terminal: InstallContext['terminal'],\n): Promise<number> {\n let lastUpdateId = 0\n try {\n const clearRes = await fetch(`https://api.telegram.org/bot${token}/getUpdates?offset=-1`)\n const clearData = (await clearRes.json()) as { ok: boolean; result?: Array<{ update_id: number }> }\n if (clearData.ok && clearData.result?.length) {\n lastUpdateId = clearData.result[clearData.result.length - 1].update_id\n }\n } catch {\n // ignore\n }\n\n const MAX_ATTEMPTS = 120\n const POLL_INTERVAL = 2000\n\n for (let i = 0; i < MAX_ATTEMPTS; i++) {\n try {\n const offset = lastUpdateId ? lastUpdateId + 1 : 0\n const res = await fetch(`https://api.telegram.org/bot${token}/getUpdates?offset=${offset}&timeout=2`)\n const data = (await res.json()) as {\n ok: boolean\n result?: Array<{\n update_id: number\n message?: { chat: { id: number; title?: string; type: string } }\n my_chat_member?: { chat: { id: number; title?: string; type: string } }\n }>\n }\n\n if (data.ok && data.result?.length) {\n for (const update of data.result) {\n lastUpdateId = update.update_id\n const chat = update.message?.chat ?? update.my_chat_member?.chat\n if (chat && (chat.type === 'supergroup' || chat.type === 'group')) {\n terminal.log.success(`Group detected: ${chat.title ?? chat.id} (${chat.id})`)\n return chat.id\n }\n }\n }\n } catch {\n // Network error, retry\n }\n await new Promise((r) => setTimeout(r, POLL_INTERVAL))\n }\n\n // Fallback to manual\n terminal.log.warning('Timed out waiting for messages. Enter chat ID manually.')\n const val = await terminal.text({\n message: 'Supergroup chat ID (e.g. -1001234567890):',\n validate: (v) => {\n const n = Number(v.trim())\n if (isNaN(n) || !Number.isInteger(n)) return 'Chat ID must be an integer'\n return undefined\n },\n })\n return Number(val.trim())\n}\n\nexport default createTelegramPlugin()\n","/**\n * All built-in plugins: services, infrastructure, and adapters.\n * Booted by LifecycleManager in dependency order.\n * Adapter plugins depend on service plugins, so they boot last.\n */\nimport securityPlugin from './security/index.js'\nimport fileServicePlugin from './file-service/index.js'\nimport contextPlugin from './context/index.js'\nimport speechPlugin from './speech/index.js'\nimport notificationsPlugin from './notifications/index.js'\nimport tunnelPlugin from './tunnel/index.js'\nimport apiServerPlugin from './api-server/index.js'\nimport telegramPlugin from './telegram/index.js'\n\nexport const corePlugins = [\n // Service plugins (no adapter dependencies)\n securityPlugin,\n fileServicePlugin,\n contextPlugin,\n speechPlugin,\n notificationsPlugin,\n // Infrastructure plugins\n tunnelPlugin,\n apiServerPlugin,\n // Adapter plugins (depend on security, notifications, etc.)\n telegramPlugin,\n]\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { SettingsAPI } from './types.js'\nimport type { ZodSchema } from 'zod'\n\nexport interface ValidationResult {\n valid: boolean\n errors?: string[]\n}\n\nexport class SettingsManager {\n constructor(private basePath: string) {}\n\n getBasePath(): string {\n return this.basePath\n }\n\n createAPI(pluginName: string): SettingsAPI {\n const settingsPath = this.getSettingsPath(pluginName)\n return new SettingsAPIImpl(settingsPath)\n }\n\n async loadSettings(pluginName: string): Promise<Record<string, unknown>> {\n const settingsPath = this.getSettingsPath(pluginName)\n try {\n const content = fs.readFileSync(settingsPath, 'utf-8')\n return JSON.parse(content)\n } catch {\n return {}\n }\n }\n\n validateSettings(\n _pluginName: string,\n settings: unknown,\n schema?: ZodSchema,\n ): ValidationResult {\n if (!schema) return { valid: true }\n const result = schema.safeParse(settings)\n if (result.success) return { valid: true }\n return {\n valid: false,\n errors: result.error.errors.map(\n (e: { path: (string | number)[]; message: string }) =>\n `${e.path.join('.')}: ${e.message}`,\n ),\n }\n }\n\n getSettingsPath(pluginName: string): string {\n return path.join(this.basePath, pluginName, 'settings.json')\n }\n\n async getPluginSettings(pluginName: string): Promise<Record<string, unknown>> {\n return this.loadSettings(pluginName)\n }\n\n async updatePluginSettings(pluginName: string, updates: Record<string, unknown>): Promise<void> {\n const api = this.createAPI(pluginName)\n const current = await api.getAll()\n await api.setAll({ ...current, ...updates })\n }\n}\n\nclass SettingsAPIImpl implements SettingsAPI {\n private cache: Record<string, unknown> | null = null\n\n constructor(private settingsPath: string) {}\n\n private readFile(): Record<string, unknown> {\n if (this.cache !== null) return this.cache\n try {\n const content = fs.readFileSync(this.settingsPath, 'utf-8')\n this.cache = JSON.parse(content)\n return this.cache!\n } catch {\n this.cache = {}\n return this.cache\n }\n }\n\n private writeFile(data: Record<string, unknown>): void {\n const dir = path.dirname(this.settingsPath)\n fs.mkdirSync(dir, { recursive: true })\n fs.writeFileSync(this.settingsPath, JSON.stringify(data, null, 2))\n this.cache = data\n }\n\n async get<T = unknown>(key: string): Promise<T | undefined> {\n const data = this.readFile()\n return data[key] as T | undefined\n }\n\n async set<T = unknown>(key: string, value: T): Promise<void> {\n const data = this.readFile()\n data[key] = value\n this.writeFile(data)\n }\n\n async getAll(): Promise<Record<string, unknown>> {\n return { ...this.readFile() }\n }\n\n async setAll(settings: Record<string, unknown>): Promise<void> {\n this.writeFile({ ...settings })\n }\n\n async delete(key: string): Promise<void> {\n const data = this.readFile()\n delete data[key]\n this.writeFile(data)\n }\n\n async clear(): Promise<void> {\n this.writeFile({})\n }\n\n async has(key: string): Promise<boolean> {\n const data = this.readFile()\n return key in data\n }\n}\n","import * as clack from '@clack/prompts'\nimport type { TerminalIO } from './types.js'\n\nfunction isCancel(value: unknown): value is symbol {\n return typeof value === 'symbol'\n}\n\nfunction guardCancel<T>(value: T | symbol): T {\n if (isCancel(value)) {\n throw new Error('cancelled')\n }\n return value as T\n}\n\nexport function createTerminalIO(): TerminalIO {\n return {\n async text(opts) {\n const result = await clack.text(opts as Parameters<typeof clack.text>[0])\n return guardCancel(result)\n },\n async select<T>(opts: {\n message: string\n options: { value: T; label: string; hint?: string }[]\n }): Promise<T> {\n const result = await clack.select(opts as Parameters<typeof clack.select>[0])\n return guardCancel(result) as T\n },\n async confirm(opts) {\n const result = await clack.confirm(opts as Parameters<typeof clack.confirm>[0])\n return guardCancel(result)\n },\n async password(opts) {\n const result = await clack.password(opts as Parameters<typeof clack.password>[0])\n return guardCancel(result)\n },\n async multiselect<T>(opts: {\n message: string\n options: { value: T; label: string; hint?: string }[]\n required?: boolean\n }): Promise<T[]> {\n const result = await clack.multiselect(opts as Parameters<typeof clack.multiselect>[0])\n return guardCancel(result) as T[]\n },\n log: {\n info: (msg) => clack.log.info(msg),\n success: (msg) => clack.log.success(msg),\n warning: (msg) => clack.log.warning(msg),\n error: (msg) => clack.log.error(msg),\n step: (msg) => clack.log.step(msg),\n },\n spinner() {\n const s = clack.spinner()\n return {\n start: (msg: string) => s.start(msg),\n stop: (msg?: string) => s.stop(msg),\n fail: (msg?: string) => s.stop(msg ?? 'Failed'),\n }\n },\n note: (msg, title) => clack.note(msg, title),\n cancel: (msg) => clack.cancel(msg),\n }\n}\n","import path from 'node:path'\nimport type { InstallContext } from './types.js'\nimport type { SettingsManager } from './settings-manager.js'\nimport { createTerminalIO } from './terminal-io.js'\nimport { log as rootLog } from '../utils/log.js'\n\nexport interface CreateInstallContextOpts {\n pluginName: string\n settingsManager: SettingsManager\n basePath: string\n legacyConfig?: Record<string, unknown>\n instanceRoot?: string\n}\n\nexport function createInstallContext(opts: CreateInstallContextOpts): InstallContext {\n const { pluginName, settingsManager, basePath, legacyConfig, instanceRoot } = opts\n const dataDir = path.join(basePath, pluginName, 'data')\n\n return {\n pluginName,\n terminal: createTerminalIO(),\n settings: settingsManager.createAPI(pluginName),\n legacyConfig,\n dataDir,\n log: rootLog.child({ plugin: pluginName }),\n instanceRoot,\n }\n}\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport * as os from 'node:os'\n\nconst DEFAULT_ROOT = path.join(os.homedir(), '.openacp')\n\nfunction defaultPortFile(root?: string): string {\n return path.join(root ?? DEFAULT_ROOT, 'api.port')\n}\n\nfunction defaultSecretFile(root?: string): string {\n return path.join(root ?? DEFAULT_ROOT, 'api-secret')\n}\n\nexport function readApiPort(portFilePath?: string, instanceRoot?: string): number | null {\n const filePath = portFilePath ?? defaultPortFile(instanceRoot)\n try {\n const content = fs.readFileSync(filePath, 'utf-8').trim()\n const port = parseInt(content, 10)\n return isNaN(port) ? null : port\n } catch {\n return null\n }\n}\n\nexport function readApiSecret(secretFilePath?: string, instanceRoot?: string): string | null {\n const filePath = secretFilePath ?? defaultSecretFile(instanceRoot)\n try {\n const content = fs.readFileSync(filePath, 'utf-8').trim()\n return content || null\n } catch {\n return null\n }\n}\n\nexport function removeStalePortFile(portFilePath?: string, instanceRoot?: string): void {\n const filePath = portFilePath ?? defaultPortFile(instanceRoot)\n try {\n fs.unlinkSync(filePath)\n } catch {\n // ignore\n }\n}\n\nexport async function apiCall(\n port: number,\n urlPath: string,\n options?: RequestInit,\n instanceRoot?: string,\n): Promise<Response> {\n const secret = readApiSecret(undefined, instanceRoot)\n const headers = new Headers(options?.headers)\n if (secret) {\n headers.set('Authorization', `Bearer ${secret}`)\n }\n return fetch(`http://127.0.0.1:${port}${urlPath}`, { ...options, headers })\n}\n","import { distance } from \"fastest-levenshtein\";\n\nexport function suggestMatch(\n input: string,\n candidates: string[],\n maxDistance: number = 2,\n): string | undefined {\n if (candidates.length === 0) return undefined;\n\n const lower = input.toLowerCase();\n\n // Exact match — no suggestion needed\n if (candidates.some((c) => c.toLowerCase() === lower)) return undefined;\n\n // 1. Prefix match — candidate starts with input\n const prefixMatches = candidates.filter((c) =>\n c.toLowerCase().startsWith(lower),\n );\n if (prefixMatches.length > 0) {\n return prefixMatches.sort((a, b) => a.length - b.length)[0];\n }\n\n // 2. Substring match — candidate contains input (min 3 chars to avoid noise)\n if (lower.length >= 3) {\n const substringMatches = candidates.filter((c) =>\n c.toLowerCase().includes(lower),\n );\n if (substringMatches.length > 0) {\n return substringMatches.sort((a, b) => a.length - b.length)[0];\n }\n }\n\n // 3. Levenshtein distance\n let best: string | undefined;\n let bestDist = Infinity;\n for (const candidate of candidates) {\n const effectiveMax = candidate.length <= 3 ? Math.min(maxDistance, 1) : maxDistance;\n const d = distance(lower, candidate.toLowerCase());\n if (d <= effectiveMax && d < bestDist) {\n bestDist = d;\n best = candidate;\n }\n }\n\n return best;\n}\n","import { spawn } from 'node:child_process'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport * as os from 'node:os'\nimport { expandHome } from '../core/config/config.js'\n\nconst DEFAULT_ROOT = path.join(os.homedir(), '.openacp')\n\nexport function getPidPath(root?: string): string {\n const base = root ?? DEFAULT_ROOT\n return path.join(base, 'openacp.pid')\n}\n\nexport function getLogDir(root?: string): string {\n const base = root ?? DEFAULT_ROOT\n return path.join(base, 'logs')\n}\n\nexport function getRunningMarker(root?: string): string {\n const base = root ?? DEFAULT_ROOT\n return path.join(base, 'running')\n}\n\nexport function writePidFile(pidPath: string, pid: number): void {\n const dir = path.dirname(pidPath)\n fs.mkdirSync(dir, { recursive: true })\n fs.writeFileSync(pidPath, String(pid))\n}\n\nexport function readPidFile(pidPath: string): number | null {\n try {\n const content = fs.readFileSync(pidPath, 'utf-8').trim()\n const pid = parseInt(content, 10)\n return isNaN(pid) ? null : pid\n } catch {\n return null\n }\n}\n\nexport function removePidFile(pidPath: string): void {\n try {\n fs.unlinkSync(pidPath)\n } catch {\n // ignore if already gone\n }\n}\n\nexport function isProcessRunning(pidPath: string): boolean {\n const pid = readPidFile(pidPath)\n if (pid === null) return false\n try {\n process.kill(pid, 0)\n return true\n } catch {\n // Process not running, clean up stale PID file\n removePidFile(pidPath)\n return false\n }\n}\n\nexport function getStatus(pidPath: string = getPidPath()): { running: boolean; pid?: number } {\n const pid = readPidFile(pidPath)\n if (pid === null) return { running: false }\n try {\n process.kill(pid, 0)\n return { running: true, pid }\n } catch {\n removePidFile(pidPath)\n return { running: false }\n }\n}\n\nexport function startDaemon(pidPath: string = getPidPath(), logDir?: string, instanceRoot?: string): { pid: number } | { error: string } {\n // Mark as running so auto-start works on next boot\n markRunning(instanceRoot)\n\n // Check if already running\n if (isProcessRunning(pidPath)) {\n const pid = readPidFile(pidPath)!\n return { error: `Already running (PID ${pid})` }\n }\n\n const resolvedLogDir = logDir ? expandHome(logDir) : getLogDir(instanceRoot)\n fs.mkdirSync(resolvedLogDir, { recursive: true })\n const logFile = path.join(resolvedLogDir, 'openacp.log')\n\n // Find the CLI entry point\n const cliPath = path.resolve(process.argv[1])\n const nodePath = process.execPath\n\n const out = fs.openSync(logFile, 'a')\n const err = fs.openSync(logFile, 'a')\n\n const child = spawn(nodePath, [cliPath, '--daemon-child'], {\n detached: true,\n stdio: ['ignore', out, err],\n env: {\n ...process.env,\n ...(instanceRoot ? { OPENACP_INSTANCE_ROOT: instanceRoot } : {}),\n },\n })\n\n // Close file descriptors in parent — child has its own copies\n fs.closeSync(out)\n fs.closeSync(err)\n\n if (!child.pid) {\n return { error: 'Failed to spawn daemon process' }\n }\n\n // PID file is written by the child process itself (in main.ts startServer)\n // to avoid race conditions and ensure consistency with LaunchAgent/systemd starts.\n // We still write it here as a fallback in case the child hasn't written it yet\n // when the parent needs to report the PID.\n writePidFile(pidPath, child.pid)\n child.unref()\n\n return { pid: child.pid }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n\nfunction isProcessAlive(pid: number): 'alive' | 'dead' | 'eperm' {\n try {\n process.kill(pid, 0)\n return 'alive'\n } catch (e) {\n const err = e as NodeJS.ErrnoException\n if (err.code === 'EPERM') return 'eperm'\n return 'dead'\n }\n}\n\nexport async function stopDaemon(pidPath: string = getPidPath(), instanceRoot?: string): Promise<{ stopped: boolean; pid?: number; error?: string }> {\n const pid = readPidFile(pidPath)\n if (pid === null) return { stopped: false, error: 'Not running (no PID file)' }\n\n const status = isProcessAlive(pid)\n if (status === 'dead') {\n removePidFile(pidPath)\n return { stopped: false, error: 'Not running (stale PID file removed)' }\n }\n if (status === 'eperm') {\n removePidFile(pidPath)\n return { stopped: false, error: 'PID belongs to another process (stale PID file removed)' }\n }\n\n try {\n process.kill(pid, 'SIGTERM')\n } catch (e) {\n return { stopped: false, error: `Failed to stop: ${(e as Error).message}` }\n }\n\n clearRunning(instanceRoot)\n\n const POLL_INTERVAL = 100\n const TIMEOUT = 5000\n const start = Date.now()\n\n while (Date.now() - start < TIMEOUT) {\n await sleep(POLL_INTERVAL)\n const s = isProcessAlive(pid)\n if (s === 'dead' || s === 'eperm') {\n removePidFile(pidPath)\n return { stopped: true, pid }\n }\n }\n\n try {\n process.kill(pid, 'SIGKILL')\n } catch (e) {\n const err = e as NodeJS.ErrnoException\n if (err.code === 'EPERM') {\n return { stopped: false, pid, error: 'PID may have been reused by another process. Run `openacp status` to verify, or manually delete the PID file.' }\n }\n }\n\n const killStart = Date.now()\n while (Date.now() - killStart < 1000) {\n await sleep(POLL_INTERVAL)\n const s = isProcessAlive(pid)\n if (s === 'dead' || s === 'eperm') {\n removePidFile(pidPath)\n return { stopped: true, pid }\n }\n }\n\n // SIGKILL sent but process still alive after 1s — extremely rare (uninterruptible I/O).\n return { stopped: false, pid, error: 'Process did not exit after SIGKILL (possible uninterruptible I/O). PID file retained.' }\n}\n\n/** Mark that the daemon should auto-start on boot */\nexport function markRunning(root?: string): void {\n const marker = getRunningMarker(root)\n fs.mkdirSync(path.dirname(marker), { recursive: true })\n fs.writeFileSync(marker, '')\n}\n\n/** Remove running marker — daemon won't auto-start on boot */\nexport function clearRunning(root?: string): void {\n try { fs.unlinkSync(getRunningMarker(root)) } catch { /* ignore */ }\n}\n\n/** Check if the daemon was running before (should auto-start on boot) */\nexport function shouldAutoStart(root?: string): boolean {\n return fs.existsSync(getRunningMarker(root))\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\n\nexport interface InstanceRegistryEntry {\n id: string\n root: string\n}\n\ninterface RegistryData {\n version: 1\n instances: Record<string, InstanceRegistryEntry>\n}\n\nexport class InstanceRegistry {\n private data: RegistryData = { version: 1, instances: {} }\n\n constructor(private registryPath: string) {}\n\n async load(): Promise<void> {\n try {\n const raw = fs.readFileSync(this.registryPath, 'utf-8')\n const parsed = JSON.parse(raw) as RegistryData\n if (parsed.version === 1 && parsed.instances) {\n this.data = parsed\n }\n } catch {\n // File doesn't exist or invalid — start fresh\n }\n }\n\n async save(): Promise<void> {\n const dir = path.dirname(this.registryPath)\n fs.mkdirSync(dir, { recursive: true })\n fs.writeFileSync(this.registryPath, JSON.stringify(this.data, null, 2))\n }\n\n register(id: string, root: string): void {\n this.data.instances[id] = { id, root }\n }\n\n remove(id: string): void {\n delete this.data.instances[id]\n }\n\n get(id: string): InstanceRegistryEntry | undefined {\n return this.data.instances[id]\n }\n\n getByRoot(root: string): InstanceRegistryEntry | undefined {\n return Object.values(this.data.instances).find((e) => e.root === root)\n }\n\n list(): InstanceRegistryEntry[] {\n return Object.values(this.data.instances)\n }\n\n uniqueId(baseId: string): string {\n if (!this.data.instances[baseId]) return baseId\n let n = 2\n while (this.data.instances[`${baseId}-${n}`]) n++\n return `${baseId}-${n}`\n }\n}\n","import { execFileSync } from 'node:child_process'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport * as os from 'node:os'\nimport { createChildLogger } from '../core/utils/log.js'\n\nconst log = createChildLogger({ module: 'autostart' })\n\nconst LAUNCHD_LABEL = 'com.openacp.daemon'\nconst LAUNCHD_PLIST_PATH = path.join(os.homedir(), 'Library', 'LaunchAgents', `${LAUNCHD_LABEL}.plist`)\nconst SYSTEMD_SERVICE_PATH = path.join(os.homedir(), '.config', 'systemd', 'user', 'openacp.service')\n\nexport function isAutoStartSupported(): boolean {\n return process.platform === 'darwin' || process.platform === 'linux'\n}\n\nexport function escapeXml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;')\n}\n\nexport function escapeSystemdValue(str: string): string {\n const escaped = str\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\$/g, '$$$$')\n .replace(/%/g, '%%')\n return `\"${escaped}\"`\n}\n\nexport function generateLaunchdPlist(nodePath: string, cliPath: string, logDir: string): string {\n const logFile = path.join(logDir, 'openacp.log')\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${LAUNCHD_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${escapeXml(nodePath)}</string>\n <string>${escapeXml(cliPath)}</string>\n <string>--daemon-child</string>\n </array>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <dict>\n <key>SuccessfulExit</key>\n <false/>\n </dict>\n <key>StandardOutPath</key>\n <string>${escapeXml(logFile)}</string>\n <key>StandardErrorPath</key>\n <string>${escapeXml(logFile)}</string>\n</dict>\n</plist>\n`\n}\n\nexport function generateSystemdUnit(nodePath: string, cliPath: string): string {\n return `[Unit]\nDescription=OpenACP Daemon\n\n[Service]\nExecStart=${escapeSystemdValue(nodePath)} ${escapeSystemdValue(cliPath)} --daemon-child\nRestart=on-failure\n\n[Install]\nWantedBy=default.target\n`\n}\n\nexport function installAutoStart(logDir: string): { success: boolean; error?: string } {\n if (!isAutoStartSupported()) {\n return { success: false, error: 'Auto-start not supported on this platform' }\n }\n\n const nodePath = process.execPath\n const cliPath = path.resolve(process.argv[1])\n const resolvedLogDir = logDir.startsWith('~')\n ? path.join(os.homedir(), logDir.slice(1))\n : logDir\n\n try {\n if (process.platform === 'darwin') {\n const plist = generateLaunchdPlist(nodePath, cliPath, resolvedLogDir)\n const dir = path.dirname(LAUNCHD_PLIST_PATH)\n fs.mkdirSync(dir, { recursive: true })\n fs.writeFileSync(LAUNCHD_PLIST_PATH, plist)\n execFileSync('launchctl', ['load', LAUNCHD_PLIST_PATH], { stdio: 'pipe' })\n log.info('LaunchAgent installed')\n return { success: true }\n }\n\n if (process.platform === 'linux') {\n const unit = generateSystemdUnit(nodePath, cliPath)\n const dir = path.dirname(SYSTEMD_SERVICE_PATH)\n fs.mkdirSync(dir, { recursive: true })\n fs.writeFileSync(SYSTEMD_SERVICE_PATH, unit)\n execFileSync('systemctl', ['--user', 'daemon-reload'], { stdio: 'pipe' })\n execFileSync('systemctl', ['--user', 'enable', 'openacp'], { stdio: 'pipe' })\n log.info('systemd user service installed')\n return { success: true }\n }\n\n return { success: false, error: 'Unsupported platform' }\n } catch (e) {\n const msg = (e as Error).message\n log.error({ err: msg }, 'Failed to install auto-start')\n return { success: false, error: msg }\n }\n}\n\nexport function uninstallAutoStart(): { success: boolean; error?: string } {\n if (!isAutoStartSupported()) {\n return { success: false, error: 'Auto-start not supported on this platform' }\n }\n\n try {\n if (process.platform === 'darwin') {\n if (fs.existsSync(LAUNCHD_PLIST_PATH)) {\n try {\n execFileSync('launchctl', ['unload', LAUNCHD_PLIST_PATH], { stdio: 'pipe' })\n } catch {\n // may already be unloaded\n }\n fs.unlinkSync(LAUNCHD_PLIST_PATH)\n log.info('LaunchAgent removed')\n }\n return { success: true }\n }\n\n if (process.platform === 'linux') {\n if (fs.existsSync(SYSTEMD_SERVICE_PATH)) {\n try {\n execFileSync('systemctl', ['--user', 'disable', 'openacp'], { stdio: 'pipe' })\n } catch {\n // may already be disabled\n }\n fs.unlinkSync(SYSTEMD_SERVICE_PATH)\n execFileSync('systemctl', ['--user', 'daemon-reload'], { stdio: 'pipe' })\n log.info('systemd user service removed')\n }\n return { success: true }\n }\n\n return { success: false, error: 'Unsupported platform' }\n } catch (e) {\n const msg = (e as Error).message\n log.error({ err: msg }, 'Failed to uninstall auto-start')\n return { success: false, error: msg }\n }\n}\n\nexport function isAutoStartInstalled(): boolean {\n if (process.platform === 'darwin') {\n return fs.existsSync(LAUNCHD_PLIST_PATH)\n }\n if (process.platform === 'linux') {\n return fs.existsSync(SYSTEMD_SERVICE_PATH)\n }\n return false\n}\n","import * as path from 'node:path'\nimport * as clack from '@clack/prompts'\nimport type { Config, ConfigManager } from './config.js'\n\n// Compatibility wrappers — convert @inquirer/prompts API to @clack/prompts\nasync function select<T extends string>(opts: { message: string; choices: Array<{ name: string; value: T; description?: string }>; default?: T }): Promise<T> {\n const result = await clack.select({\n message: opts.message,\n options: opts.choices.map(ch => ({ label: ch.name, value: ch.value, hint: ch.description })) as any,\n initialValue: opts.default,\n })\n if (clack.isCancel(result)) { clack.cancel('Cancelled.'); process.exit(0) }\n return result as T\n}\n\nasync function input(opts: { message: string; default?: string; validate?: (val: string) => string | boolean }): Promise<string> {\n const result = await clack.text({\n message: opts.message,\n initialValue: opts.default,\n validate: opts.validate ? (val) => {\n const r = opts.validate!((val ?? \"\") as string)\n if (r === true || r === undefined) return undefined\n if (typeof r === 'string') return r\n return undefined\n } : undefined,\n })\n if (clack.isCancel(result)) { clack.cancel('Cancelled.'); process.exit(0) }\n return result as string\n}\nimport { installAutoStart, uninstallAutoStart, isAutoStartInstalled, isAutoStartSupported } from '../../cli/autostart.js'\nimport { expandHome } from './config.js'\n\n// ANSI color helpers\nconst c = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n cyan: '\\x1b[36m',\n}\n\nconst ok = (msg: string) => `${c.green}${c.bold}✓${c.reset} ${c.green}${msg}${c.reset}`\nconst warn = (msg: string) => `${c.yellow}⚠ ${msg}${c.reset}`\nconst dim = (msg: string) => `${c.dim}${msg}${c.reset}`\nconst header = (title: string) => `\\n${c.cyan}${c.bold}[${title}]${c.reset}\\n`\n\ntype ConfigUpdates = Record<string, unknown>\n\n// --- Edit: Telegram ---\n\nasync function editTelegram(config: Config, updates: ConfigUpdates): Promise<void> {\n const tg = (config.channels?.telegram ?? {}) as Record<string, unknown>\n const currentToken = (tg.botToken as string) ?? ''\n const currentChatId = (tg.chatId as number) ?? 0\n const currentEnabled = (tg.enabled as boolean) ?? false\n\n console.log(header('Telegram'))\n console.log(` Enabled : ${currentEnabled ? ok('yes') : dim('no')}`)\n const tokenDisplay = currentToken.length > 12\n ? currentToken.slice(0, 6) + '...' + currentToken.slice(-6)\n : currentToken || dim('(not set)')\n console.log(` Bot Token : ${tokenDisplay}`)\n console.log(` Chat ID : ${currentChatId || dim('(not set)')}`)\n console.log('')\n\n const ensureTelegramUpdates = () => {\n if (!updates.channels) updates.channels = {}\n if (!(updates.channels as Record<string, unknown>).telegram) {\n (updates.channels as Record<string, unknown>).telegram = {}\n }\n return (updates.channels as Record<string, unknown>).telegram as Record<string, unknown>\n }\n\n while (true) {\n const isEnabled = (() => {\n const ch = updates.channels as Record<string, unknown> | undefined\n const tgUp = ch?.telegram as Record<string, unknown> | undefined\n if (tgUp && 'enabled' in tgUp) return tgUp.enabled as boolean\n return currentEnabled\n })()\n\n const choice = await select({\n message: 'Telegram settings:',\n choices: [\n { name: isEnabled ? 'Disable Telegram' : 'Enable Telegram', value: 'toggle' },\n { name: 'Change Bot Token', value: 'token' },\n { name: 'Change Chat ID', value: 'chatid' },\n { name: 'Back', value: 'back' },\n ],\n })\n\n if (choice === 'back') break\n\n if (choice === 'toggle') {\n const tgUp = ensureTelegramUpdates()\n tgUp.enabled = !isEnabled\n console.log(!isEnabled ? ok('Telegram enabled') : ok('Telegram disabled'))\n }\n\n if (choice === 'token') {\n const token = await input({\n message: 'New bot token:',\n default: currentToken,\n validate: (val) => val.trim().length > 0 || 'Token cannot be empty',\n })\n\n try {\n const { validateBotToken } = await import('../../plugins/telegram/validators.js')\n const result = await validateBotToken(token.trim())\n if (result.ok) {\n console.log(ok(`Connected to @${result.botUsername}`))\n } else {\n console.log(warn(`Validation failed: ${result.error} — saving anyway`))\n }\n } catch {\n console.log(warn('Telegram validator not available — skipping validation'))\n }\n\n const tgUp = ensureTelegramUpdates()\n tgUp.botToken = token.trim()\n tgUp.enabled = true\n }\n\n if (choice === 'chatid') {\n const chatIdStr = await input({\n message: 'New chat ID (e.g. -1001234567890):',\n default: String(currentChatId),\n validate: (val) => {\n const n = Number(val.trim())\n if (isNaN(n) || !Number.isInteger(n)) return 'Chat ID must be an integer'\n return true\n },\n })\n\n const chatId = Number(chatIdStr.trim())\n\n // Use the current (or already-updated) token for validation\n const tokenForValidation = (() => {\n const ch = updates.channels as Record<string, unknown> | undefined\n const tgUp = ch?.telegram as Record<string, unknown> | undefined\n if (typeof tgUp?.botToken === 'string') return tgUp.botToken\n return currentToken\n })()\n\n try {\n const { validateChatId } = await import('../../plugins/telegram/validators.js')\n const result = await validateChatId(tokenForValidation, chatId)\n if (result.ok) {\n console.log(ok(`Group: ${result.title}${result.isForum ? '' : warn(' (topics not enabled)')}`))\n } else {\n console.log(warn(`Validation failed: ${result.error} — saving anyway`))\n }\n } catch {\n console.log(warn('Telegram validator not available — skipping validation'))\n }\n\n const tgUp = ensureTelegramUpdates()\n tgUp.chatId = chatId\n }\n }\n}\n\n// --- Edit: Discord (delegates to plugin's configure()) ---\n\nconst DISCORD_PACKAGE = '@openacp/adapter-discord'\n\nasync function ensureDiscordPlugin(): Promise<any | null> {\n try {\n return await import(DISCORD_PACKAGE)\n } catch {\n const shouldInstall = await select({\n message: `${DISCORD_PACKAGE} is not installed. Install it now?`,\n choices: [\n { name: 'Yes, install now', value: 'yes' },\n { name: 'No, skip', value: 'no' },\n ],\n })\n if (shouldInstall === 'no') {\n console.log(warn(`Install later with: openacp plugin add ${DISCORD_PACKAGE}`))\n return null\n }\n try {\n console.log(dim(`Installing ${DISCORD_PACKAGE}...`))\n const { installNpmPlugin } = await import('../plugin/plugin-installer.js')\n const mod = await installNpmPlugin(DISCORD_PACKAGE)\n console.log(ok(`${DISCORD_PACKAGE} installed`))\n return mod\n } catch (err) {\n console.log(warn(`Failed to install: ${(err as Error).message}`))\n return null\n }\n }\n}\n\nasync function editDiscord(_config: Config, _updates: ConfigUpdates): Promise<void> {\n const pluginModule = await ensureDiscordPlugin()\n if (!pluginModule) return\n\n const plugin = pluginModule.default\n if (plugin?.configure) {\n const { SettingsManager } = await import('../plugin/settings-manager.js')\n const { createInstallContext } = await import('../plugin/install-context.js')\n const { getGlobalRoot } = await import('../instance-context.js')\n const root = getGlobalRoot()\n const basePath = path.join(root, 'plugins')\n const settingsManager = new SettingsManager(basePath)\n const ctx = createInstallContext({\n pluginName: plugin.name,\n settingsManager,\n basePath,\n instanceRoot: root,\n })\n await plugin.configure(ctx)\n } else {\n console.log(warn('This plugin does not have a configure() method yet.'))\n }\n}\n\n// --- Edit: Channels (parent menu) ---\n\nasync function editChannels(config: Config, updates: ConfigUpdates): Promise<void> {\n const tgEnabled = (config.channels?.telegram as Record<string, unknown>)?.enabled !== false && config.channels?.telegram\n const dcEnabled = (config.channels?.discord as Record<string, unknown>)?.enabled !== false && config.channels?.discord\n\n console.log(header('Channels'))\n console.log(` Telegram : ${tgEnabled ? ok('configured') : dim('not configured')}`)\n console.log(` Discord : ${dcEnabled ? ok('configured') : dim('not configured')}`)\n console.log('')\n\n while (true) {\n const choice = await select({\n message: 'Channel settings:',\n choices: [\n { name: 'Telegram', value: 'telegram' },\n { name: 'Discord', value: 'discord' },\n { name: 'Back', value: 'back' },\n ],\n })\n\n if (choice === 'back') break\n\n if (choice === 'telegram') await editTelegram(config, updates)\n if (choice === 'discord') await editDiscord(config, updates)\n }\n}\n\n// --- Edit: Agent ---\n\nasync function editAgent(config: Config, updates: ConfigUpdates): Promise<void> {\n const agentNames = Object.keys(config.agents ?? {})\n const currentDefault = config.defaultAgent\n\n console.log(header('Agent'))\n console.log(` Default agent : ${c.bold}${currentDefault}${c.reset}`)\n console.log(` Available : ${agentNames.join(', ') || dim('(none)')}`)\n console.log('')\n\n while (true) {\n const choice = await select({\n message: 'Agent settings:',\n choices: [\n { name: 'Change default agent', value: 'default' },\n { name: 'Back', value: 'back' },\n ],\n })\n\n if (choice === 'back') break\n\n if (choice === 'default') {\n if (agentNames.length === 0) {\n console.log(warn('No agents configured.'))\n continue\n }\n\n const chosen = await select({\n message: 'Select default agent:',\n choices: agentNames.map((name) => ({ name, value: name })),\n })\n\n updates.defaultAgent = chosen\n console.log(ok(`Default agent set to ${chosen}`))\n }\n }\n}\n\n// --- Edit: Workspace ---\n\nasync function editWorkspace(config: Config, updates: ConfigUpdates): Promise<void> {\n const currentDir = config.workspace?.baseDir ?? '~/openacp-workspace'\n\n console.log(header('Workspace'))\n console.log(` Base directory : ${currentDir}`)\n console.log('')\n\n const newDir = await input({\n message: 'Workspace base directory:',\n default: currentDir,\n validate: (val) => val.trim().length > 0 || 'Path cannot be empty',\n })\n\n updates.workspace = { baseDir: newDir.trim() }\n console.log(ok(`Workspace set to ${newDir.trim()}`))\n}\n\n// --- Edit: Security ---\n\nasync function editSecurity(config: Config, updates: ConfigUpdates): Promise<void> {\n const sec = config.security ?? { allowedUserIds: [], maxConcurrentSessions: 20, sessionTimeoutMinutes: 60 }\n\n console.log(header('Security'))\n console.log(` Allowed user IDs : ${sec.allowedUserIds?.length ? sec.allowedUserIds.join(', ') : dim('(all users allowed)')}`)\n console.log(` Max concurrent sessions : ${sec.maxConcurrentSessions}`)\n console.log(` Session timeout (min) : ${sec.sessionTimeoutMinutes}`)\n console.log('')\n\n while (true) {\n const choice = await select({\n message: 'Security settings:',\n choices: [\n { name: 'Max concurrent sessions', value: 'maxSessions' },\n { name: 'Session timeout (minutes)', value: 'timeout' },\n { name: 'Back', value: 'back' },\n ],\n })\n\n if (choice === 'back') break\n\n if (choice === 'maxSessions') {\n const val = await input({\n message: 'Max concurrent sessions:',\n default: String(sec.maxConcurrentSessions),\n validate: (v) => {\n const n = Number(v.trim())\n if (!Number.isInteger(n) || n < 1) return 'Must be a positive integer'\n return true\n },\n })\n\n if (!updates.security) updates.security = {}\n ;(updates.security as Record<string, unknown>).maxConcurrentSessions = Number(val.trim())\n console.log(ok(`Max concurrent sessions set to ${val.trim()}`))\n }\n\n if (choice === 'timeout') {\n const val = await input({\n message: 'Session timeout in minutes:',\n default: String(sec.sessionTimeoutMinutes),\n validate: (v) => {\n const n = Number(v.trim())\n if (!Number.isInteger(n) || n < 1) return 'Must be a positive integer'\n return true\n },\n })\n\n if (!updates.security) updates.security = {}\n ;(updates.security as Record<string, unknown>).sessionTimeoutMinutes = Number(val.trim())\n console.log(ok(`Session timeout set to ${val.trim()} minutes`))\n }\n }\n}\n\n// --- Edit: Logging ---\n\nasync function editLogging(config: Config, updates: ConfigUpdates): Promise<void> {\n const logging = config.logging ?? { level: 'info', logDir: '~/.openacp/logs', maxFileSize: '10m', maxFiles: 7, sessionLogRetentionDays: 30 }\n\n console.log(header('Logging'))\n console.log(` Log level : ${logging.level}`)\n console.log(` Log dir : ${logging.logDir}`)\n console.log('')\n\n while (true) {\n const choice = await select({\n message: 'Logging settings:',\n choices: [\n { name: 'Log level', value: 'level' },\n { name: 'Log directory', value: 'logDir' },\n { name: 'Back', value: 'back' },\n ],\n })\n\n if (choice === 'back') break\n\n if (choice === 'level') {\n const level = await select({\n message: 'Select log level:',\n choices: [\n { name: 'silent', value: 'silent' },\n { name: 'debug', value: 'debug' },\n { name: 'info', value: 'info' },\n { name: 'warn', value: 'warn' },\n { name: 'error', value: 'error' },\n { name: 'fatal', value: 'fatal' },\n ],\n })\n\n if (!updates.logging) updates.logging = {}\n ;(updates.logging as Record<string, unknown>).level = level\n console.log(ok(`Log level set to ${level}`))\n }\n\n if (choice === 'logDir') {\n const dir = await input({\n message: 'Log directory:',\n default: logging.logDir,\n validate: (val) => val.trim().length > 0 || 'Path cannot be empty',\n })\n\n if (!updates.logging) updates.logging = {}\n ;(updates.logging as Record<string, unknown>).logDir = dir.trim()\n console.log(ok(`Log directory set to ${dir.trim()}`))\n }\n }\n}\n\n// --- Edit: Run Mode ---\n\nasync function editRunMode(config: Config, updates: ConfigUpdates): Promise<void> {\n const currentMode = config.runMode ?? 'foreground'\n const currentAutoStart = config.autoStart ?? false\n const autoStartInstalled = isAutoStartInstalled()\n const autoStartSupported = isAutoStartSupported()\n\n console.log(header('Run Mode'))\n console.log(` Current mode : ${c.bold}${currentMode}${c.reset}`)\n console.log(` Auto-start : ${currentAutoStart ? ok('enabled') : dim('disabled')}${autoStartInstalled ? ` ${dim('(installed)')}` : ''}`)\n console.log('')\n\n while (true) {\n const isDaemon = (() => {\n if ('runMode' in updates) return updates.runMode === 'daemon'\n return currentMode === 'daemon'\n })()\n\n const choices = [\n isDaemon\n ? { name: 'Switch to foreground mode', value: 'foreground' }\n : { name: 'Switch to daemon mode', value: 'daemon' },\n ]\n\n if (autoStartSupported) {\n const autoStartCurrent = (() => {\n if ('autoStart' in updates) return updates.autoStart as boolean\n return currentAutoStart\n })()\n choices.push({\n name: autoStartCurrent ? 'Disable auto-start' : 'Enable auto-start',\n value: 'toggleAutoStart',\n })\n }\n\n choices.push({ name: 'Back', value: 'back' })\n\n const choice = await select({\n message: 'Run mode settings:',\n choices,\n })\n\n if (choice === 'back') break\n\n if (choice === 'daemon') {\n updates.runMode = 'daemon'\n const logDir = (config.logging?.logDir) ?? '~/.openacp/logs'\n const result = installAutoStart(expandHome(logDir))\n if (result.success) {\n updates.autoStart = true\n console.log(ok('Switched to daemon mode with auto-start'))\n } else {\n console.log(warn(`Switched to daemon mode (auto-start failed: ${result.error})`))\n }\n }\n\n if (choice === 'foreground') {\n updates.runMode = 'foreground'\n updates.autoStart = false\n uninstallAutoStart()\n console.log(ok('Switched to foreground mode'))\n }\n\n if (choice === 'toggleAutoStart') {\n const autoStartCurrent = (() => {\n if ('autoStart' in updates) return updates.autoStart as boolean\n return currentAutoStart\n })()\n\n if (autoStartCurrent) {\n const result = uninstallAutoStart()\n updates.autoStart = false\n if (result.success) {\n console.log(ok('Auto-start disabled'))\n } else {\n console.log(warn(`Auto-start uninstall failed: ${result.error}`))\n }\n } else {\n const logDir = (config.logging?.logDir) ?? '~/.openacp/logs'\n const result = installAutoStart(expandHome(logDir))\n updates.autoStart = result.success\n if (result.success) {\n console.log(ok('Auto-start enabled'))\n } else {\n console.log(warn(`Auto-start install failed: ${result.error}`))\n }\n }\n }\n }\n}\n\n// --- Edit: API ---\n\nasync function editApi(config: Config, updates: ConfigUpdates): Promise<void> {\n const api = config.api ?? { port: 21420, host: '127.0.0.1' }\n\n console.log(header('API'))\n console.log(` Port : ${api.port}`)\n console.log(` Host : ${api.host} ${dim('(localhost only)')}`)\n console.log('')\n\n const newPort = await input({\n message: 'API port:',\n default: String(api.port),\n validate: (v) => {\n const n = Number(v.trim())\n if (!Number.isInteger(n) || n < 1 || n > 65535) return 'Must be a valid port (1-65535)'\n return true\n },\n })\n\n updates.api = { port: Number(newPort.trim()) }\n console.log(ok(`API port set to ${newPort.trim()}`))\n}\n\n// --- Edit: Tunnel ---\n\nasync function editTunnel(config: Config, updates: ConfigUpdates): Promise<void> {\n const tunnel = config.tunnel ?? { enabled: false, port: 3100, provider: 'cloudflare', options: {}, storeTtlMinutes: 60, auth: { enabled: false } }\n const currentUpdates = (updates.tunnel ?? {}) as Record<string, unknown>\n\n const getVal = <T>(key: string, fallback: T): T =>\n (key in currentUpdates ? currentUpdates[key] : (tunnel as Record<string, unknown>)[key] ?? fallback) as T\n\n console.log(header('Tunnel'))\n console.log(` Enabled : ${getVal('enabled', false) ? ok('yes') : dim('no')}`)\n console.log(` Provider : ${c.bold}${getVal('provider', 'cloudflare')}${c.reset}`)\n console.log(` Port : ${getVal('port', 3100)}`)\n const authEnabled = (getVal('auth', { enabled: false }) as { enabled: boolean }).enabled\n console.log(` Auth : ${authEnabled ? ok('enabled') : dim('disabled')}`)\n console.log('')\n\n while (true) {\n const choice = await select({\n message: 'Tunnel settings:',\n choices: [\n { name: getVal('enabled', false) ? 'Disable tunnel' : 'Enable tunnel', value: 'toggle' },\n { name: 'Change provider', value: 'provider' },\n { name: 'Change port', value: 'port' },\n { name: 'Provider options', value: 'options' },\n { name: authEnabled ? 'Disable auth' : 'Enable auth', value: 'auth' },\n { name: 'Back', value: 'back' },\n ],\n })\n\n if (choice === 'back') break\n\n if (!updates.tunnel) updates.tunnel = { ...tunnel }\n const tun = updates.tunnel as Record<string, unknown>\n\n if (choice === 'toggle') {\n const current = getVal('enabled', false)\n tun.enabled = !current\n console.log(!current ? ok('Tunnel enabled') : ok('Tunnel disabled'))\n }\n\n if (choice === 'provider') {\n const provider = await select({\n message: 'Select tunnel provider:',\n choices: [\n { name: 'Cloudflare (default)', value: 'cloudflare' },\n { name: 'ngrok', value: 'ngrok' },\n { name: 'bore', value: 'bore' },\n { name: 'Tailscale Funnel', value: 'tailscale' },\n ],\n })\n tun.provider = provider\n tun.options = {} // reset options when switching provider\n console.log(ok(`Provider set to ${provider}`))\n }\n\n if (choice === 'port') {\n const val = await input({\n message: 'Tunnel port:',\n default: String(getVal('port', 3100)),\n validate: (v) => {\n const n = Number(v.trim())\n if (!Number.isInteger(n) || n < 1 || n > 65535) return 'Must be a valid port (1-65535)'\n return true\n },\n })\n tun.port = Number(val.trim())\n console.log(ok(`Tunnel port set to ${val.trim()}`))\n }\n\n if (choice === 'options') {\n const provider = getVal('provider', 'cloudflare')\n const currentOptions = getVal('options', {}) as Record<string, unknown>\n await editProviderOptions(provider, currentOptions, tun)\n }\n\n if (choice === 'auth') {\n const currentAuth = getVal('auth', { enabled: false }) as { enabled: boolean; token?: string }\n if (currentAuth.enabled) {\n tun.auth = { enabled: false }\n console.log(ok('Tunnel auth disabled'))\n } else {\n const token = await input({\n message: 'Auth token (leave empty to auto-generate):',\n default: '',\n })\n tun.auth = token.trim()\n ? { enabled: true, token: token.trim() }\n : { enabled: true }\n console.log(ok('Tunnel auth enabled'))\n }\n }\n }\n}\n\nasync function editProviderOptions(\n provider: string,\n currentOptions: Record<string, unknown>,\n tun: Record<string, unknown>,\n): Promise<void> {\n if (provider === 'cloudflare') {\n const domain = await input({\n message: 'Custom domain (leave empty for random):',\n default: (currentOptions.domain as string) ?? '',\n })\n tun.options = domain.trim() ? { domain: domain.trim() } : {}\n if (domain.trim()) console.log(ok(`Domain set to ${domain.trim()}`))\n else console.log(dim('Using random cloudflare domain'))\n } else if (provider === 'ngrok') {\n const authtoken = await input({\n message: 'ngrok authtoken (leave empty to skip):',\n default: (currentOptions.authtoken as string) ?? '',\n })\n const domain = await input({\n message: 'ngrok domain (leave empty for random):',\n default: (currentOptions.domain as string) ?? '',\n })\n const region = await input({\n message: 'ngrok region (us, eu, ap — leave empty for default):',\n default: (currentOptions.region as string) ?? '',\n })\n const opts: Record<string, string> = {}\n if (authtoken.trim()) opts.authtoken = authtoken.trim()\n if (domain.trim()) opts.domain = domain.trim()\n if (region.trim()) opts.region = region.trim()\n tun.options = opts\n console.log(ok('ngrok options saved'))\n } else if (provider === 'bore') {\n const server = await input({\n message: 'bore server:',\n default: (currentOptions.server as string) ?? 'bore.pub',\n })\n const port = await input({\n message: 'bore port (leave empty for auto):',\n default: currentOptions.port ? String(currentOptions.port) : '',\n })\n const secret = await input({\n message: 'bore secret (leave empty to skip):',\n default: (currentOptions.secret as string) ?? '',\n })\n const opts: Record<string, unknown> = { server: server.trim() }\n if (port.trim()) opts.port = Number(port.trim())\n if (secret.trim()) opts.secret = secret.trim()\n tun.options = opts\n console.log(ok('bore options saved'))\n } else if (provider === 'tailscale') {\n const bg = await select({\n message: 'Run Tailscale Funnel in background?',\n choices: [\n { name: 'No', value: 'no' },\n { name: 'Yes', value: 'yes' },\n ],\n })\n tun.options = bg === 'yes' ? { bg: true } : {}\n console.log(ok('Tailscale options saved'))\n } else {\n console.log(dim(`No configurable options for provider \"${provider}\"`))\n }\n}\n\n// --- Main Config Editor ---\n\nexport async function runConfigEditor(\n configManager: ConfigManager,\n mode: 'file' | 'api' = 'file',\n apiPort?: number,\n): Promise<void> {\n await configManager.load()\n const config = configManager.get()\n const updates: ConfigUpdates = {}\n\n console.log(`\\n${c.cyan}${c.bold}OpenACP Config Editor${c.reset}`)\n console.log(dim(`Config: ${configManager.getConfigPath()}`))\n console.log('')\n\n try {\n while (true) {\n const hasChanges = mode === 'file' ? Object.keys(updates).length > 0 : false\n const choice = await select({\n message: `What would you like to edit?${hasChanges ? ` ${c.yellow}(unsaved changes)${c.reset}` : ''}`,\n choices: [\n { name: 'Channels', value: 'channels' },\n { name: 'Agent', value: 'agent' },\n { name: 'Workspace', value: 'workspace' },\n { name: 'Security', value: 'security' },\n { name: 'Logging', value: 'logging' },\n { name: 'Run Mode', value: 'runMode' },\n { name: 'API', value: 'api' },\n { name: 'Tunnel', value: 'tunnel' },\n { name: hasChanges ? 'Save & Exit' : 'Exit', value: 'exit' },\n ],\n })\n\n if (choice === 'exit') {\n if (mode === 'file' && hasChanges) {\n await configManager.save(updates)\n console.log(ok(`Config saved to ${configManager.getConfigPath()}`))\n } else if (mode === 'file') {\n console.log(dim('No changes made.'))\n }\n break\n }\n\n const sectionUpdates: ConfigUpdates = {}\n\n if (choice === 'channels') await editChannels(config, sectionUpdates)\n else if (choice === 'agent') await editAgent(config, sectionUpdates)\n else if (choice === 'workspace') await editWorkspace(config, sectionUpdates)\n else if (choice === 'security') await editSecurity(config, sectionUpdates)\n else if (choice === 'logging') await editLogging(config, sectionUpdates)\n else if (choice === 'runMode') await editRunMode(config, sectionUpdates)\n else if (choice === 'api') await editApi(config, sectionUpdates)\n else if (choice === 'tunnel') await editTunnel(config, sectionUpdates)\n\n if (mode === 'api' && Object.keys(sectionUpdates).length > 0) {\n await sendConfigViaApi(apiPort!, sectionUpdates)\n // Refresh in-memory config\n await configManager.load()\n Object.assign(config, configManager.get())\n } else {\n // Accumulate for file mode\n Object.assign(updates, sectionUpdates)\n }\n }\n } catch (err) {\n if ((err as Error).name === 'ExitPromptError') {\n console.log(dim('\\nConfig editor cancelled. Changes discarded.'))\n return\n }\n throw err\n }\n}\n\nasync function sendConfigViaApi(port: number, updates: ConfigUpdates): Promise<void> {\n const { apiCall: call } = await import('../../cli/api-client.js')\n\n const paths = flattenToPaths(updates)\n for (const { path, value } of paths) {\n const res = await call(port, '/api/config', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path, value }),\n })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.log(warn(`Failed to update ${path}: ${data.error}`))\n } else if (data.needsRestart) {\n console.log(warn(`${path} updated — restart required`))\n }\n }\n}\n\nfunction flattenToPaths(obj: Record<string, unknown>, prefix = ''): Array<{ path: string; value: unknown }> {\n const result: Array<{ path: string; value: unknown }> = []\n for (const [key, val] of Object.entries(obj)) {\n const fullPath = prefix ? `${prefix}.${key}` : key\n if (val && typeof val === 'object' && !Array.isArray(val)) {\n result.push(...flattenToPaths(val as Record<string, unknown>, fullPath))\n } else {\n result.push({ path: fullPath, value: val })\n }\n }\n return result\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport { z } from \"zod\";\nimport type { InstalledAgent } from \"../types.js\";\nimport { createChildLogger } from \"../utils/log.js\";\n\nconst log = createChildLogger({ module: \"agent-store\" });\n\nconst InstalledAgentSchema = z.object({\n registryId: z.string().nullable(),\n name: z.string(),\n version: z.string(),\n distribution: z.enum([\"npx\", \"uvx\", \"binary\", \"custom\"]),\n command: z.string(),\n args: z.array(z.string()).default([]),\n env: z.record(z.string(), z.string()).default({}),\n workingDirectory: z.string().optional(),\n installedAt: z.string(),\n binaryPath: z.string().nullable().default(null),\n});\n\nconst AgentStoreSchema = z.object({\n version: z.number().default(1),\n installed: z.record(z.string(), InstalledAgentSchema).default({}),\n});\n\ntype AgentStoreData = z.infer<typeof AgentStoreSchema>;\n\nexport class AgentStore {\n private data: AgentStoreData = { version: 1, installed: {} };\n private filePath: string;\n\n constructor(filePath?: string) {\n this.filePath = filePath ?? path.join(os.homedir(), \".openacp\", \"agents.json\");\n }\n\n load(): void {\n fs.mkdirSync(path.dirname(this.filePath), { recursive: true });\n\n if (!fs.existsSync(this.filePath)) {\n this.data = { version: 1, installed: {} };\n return;\n }\n\n try {\n const raw = JSON.parse(fs.readFileSync(this.filePath, \"utf-8\") as string);\n const result = AgentStoreSchema.safeParse(raw);\n if (result.success) {\n this.data = result.data;\n } else {\n log.warn({ errors: result.error.issues }, \"Invalid agents.json, starting fresh\");\n this.data = { version: 1, installed: {} };\n }\n } catch (err) {\n log.warn({ err }, \"Failed to read agents.json, starting fresh\");\n this.data = { version: 1, installed: {} };\n }\n }\n\n exists(): boolean {\n return fs.existsSync(this.filePath);\n }\n\n getInstalled(): Record<string, InstalledAgent> {\n return this.data.installed;\n }\n\n getAgent(key: string): InstalledAgent | undefined {\n return this.data.installed[key];\n }\n\n addAgent(key: string, agent: InstalledAgent): void {\n this.data.installed[key] = agent;\n this.save();\n }\n\n removeAgent(key: string): void {\n delete this.data.installed[key];\n this.save();\n }\n\n hasAgent(key: string): boolean {\n return key in this.data.installed;\n }\n\n private save(): void {\n const tmpPath = this.filePath + \".tmp\";\n fs.writeFileSync(tmpPath, JSON.stringify(this.data, null, 2));\n fs.renameSync(tmpPath, this.filePath);\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport { createChildLogger } from \"../utils/log.js\";\nimport type { InstalledAgent, RegistryAgent, InstallProgress, InstallResult } from \"../types.js\";\nimport { getAgentAlias, checkDependencies, checkRuntimeAvailable, getAgentSetup } from \"./agent-dependencies.js\";\nimport { AgentStore } from \"./agent-store.js\";\n\nconst log = createChildLogger({ module: \"agent-installer\" });\n\nconst DEFAULT_AGENTS_DIR = path.join(os.homedir(), \".openacp\", \"agents\");\n\nconst ARCH_MAP: Record<string, string> = {\n arm64: \"aarch64\",\n x64: \"x86_64\",\n};\n\nconst PLATFORM_MAP: Record<string, string> = {\n darwin: \"darwin\",\n linux: \"linux\",\n win32: \"windows\",\n};\n\nexport function getPlatformKey(): string {\n const platform = PLATFORM_MAP[process.platform] ?? process.platform;\n const arch = ARCH_MAP[process.arch] ?? process.arch;\n return `${platform}-${arch}`;\n}\n\nexport type ResolvedDistribution =\n | { type: \"npx\"; package: string; args: string[]; env?: Record<string, string> }\n | { type: \"uvx\"; package: string; args: string[]; env?: Record<string, string> }\n | { type: \"binary\"; archive: string; cmd: string; args: string[]; env?: Record<string, string> };\n\nexport function resolveDistribution(agent: RegistryAgent): ResolvedDistribution | null {\n const dist = agent.distribution;\n\n if (dist.npx) {\n return { type: \"npx\", package: dist.npx.package, args: dist.npx.args ?? [], env: dist.npx.env };\n }\n if (dist.uvx) {\n return { type: \"uvx\", package: dist.uvx.package, args: dist.uvx.args ?? [], env: dist.uvx.env };\n }\n if (dist.binary) {\n const platformKey = getPlatformKey();\n const target = dist.binary[platformKey];\n if (!target) return null;\n return { type: \"binary\", archive: target.archive, cmd: target.cmd, args: target.args ?? [], env: target.env };\n }\n return null;\n}\n\nexport function buildInstalledAgent(\n registryId: string,\n name: string,\n version: string,\n dist: ResolvedDistribution,\n binaryPath?: string,\n): InstalledAgent {\n if (dist.type === \"npx\") {\n // Use latest version: strip pinned version from package name (e.g. @google/gemini-cli@0.34.0 → @google/gemini-cli)\n const npxPackage = stripPackageVersion(dist.package);\n return {\n registryId, name, version, distribution: \"npx\",\n command: \"npx\", args: [npxPackage, ...dist.args],\n env: dist.env ?? {}, installedAt: new Date().toISOString(), binaryPath: null,\n };\n }\n if (dist.type === \"uvx\") {\n // Strip pinned version: \"fast-agent-acp==0.6.6\" → \"fast-agent-acp\", \"minion-code@0.1.44\" → \"minion-code\"\n const uvxPackage = stripPythonPackageVersion(dist.package);\n return {\n registryId, name, version, distribution: \"uvx\",\n command: \"uvx\", args: [uvxPackage, ...dist.args],\n env: dist.env ?? {}, installedAt: new Date().toISOString(), binaryPath: null,\n };\n }\n // binary\n const absCmd = path.resolve(binaryPath!, dist.cmd);\n return {\n registryId, name, version, distribution: \"binary\",\n command: absCmd, args: dist.args,\n env: dist.env ?? {}, installedAt: new Date().toISOString(), binaryPath: binaryPath!,\n };\n}\n\n/**\n * Strip pinned version from npm package name so npx always uses latest.\n * e.g. \"@google/gemini-cli@0.34.0\" → \"@google/gemini-cli\"\n * \"cline@2.9.0\" → \"cline\"\n * \"@scope/pkg\" → \"@scope/pkg\" (no version, unchanged)\n */\nfunction stripPackageVersion(pkg: string): string {\n // Scoped: @scope/name@version → find the second @\n if (pkg.startsWith(\"@\")) {\n const afterScope = pkg.indexOf(\"/\");\n if (afterScope === -1) return pkg;\n const versionAt = pkg.indexOf(\"@\", afterScope + 1);\n return versionAt === -1 ? pkg : pkg.slice(0, versionAt);\n }\n // Unscoped: name@version\n const at = pkg.indexOf(\"@\");\n return at === -1 ? pkg : pkg.slice(0, at);\n}\n\n/**\n * Strip pinned version from Python package name so uvx always uses latest.\n * e.g. \"fast-agent-acp==0.6.6\" → \"fast-agent-acp\"\n * \"minion-code@0.1.44\" → \"minion-code\"\n * \"crow-cli\" → \"crow-cli\" (no version, unchanged)\n */\nfunction stripPythonPackageVersion(pkg: string): string {\n // Python-style: name==version or name>=version\n const pyMatch = pkg.match(/^([^=@><!]+)/);\n if (pyMatch && pkg.includes(\"==\")) return pyMatch[1]!;\n // npm-style @ used in some uvx packages\n const at = pkg.indexOf(\"@\");\n return at === -1 ? pkg : pkg.slice(0, at);\n}\n\nexport async function installAgent(\n agent: RegistryAgent,\n store: AgentStore,\n progress?: InstallProgress,\n agentsDir?: string,\n): Promise<InstallResult> {\n const agentKey = getAgentAlias(agent.id);\n await progress?.onStart(agent.id, agent.name);\n\n // 1. Check dependencies\n await progress?.onStep(\"Checking requirements...\");\n const depResult = checkDependencies(agent.id);\n if (!depResult.available) {\n const hints = depResult.missing!.map((m) => ` ${m.label}: ${m.installHint}`).join(\"\\n\");\n const msg = `${agent.name} needs some tools installed first:\\n${hints}`;\n await progress?.onError(msg);\n return { ok: false, agentKey, error: msg };\n }\n\n // 2. Resolve distribution\n const dist = resolveDistribution(agent);\n if (!dist) {\n const platformKey = getPlatformKey();\n const msg = `${agent.name} is not available for your system (${platformKey}). Check their website for other install options.`;\n await progress?.onError(msg);\n return { ok: false, agentKey, error: msg };\n }\n\n // 3. Check runtime\n if (dist.type === \"uvx\" && !checkRuntimeAvailable(\"uvx\")) {\n const msg = `${agent.name} requires Python's uvx tool.\\nInstall it with: pip install uv`;\n await progress?.onError(msg, \"pip install uv\");\n return { ok: false, agentKey, error: msg, hint: \"pip install uv\" };\n }\n\n // 4. Install based on type\n let binaryPath: string | undefined;\n\n if (dist.type === \"binary\") {\n try {\n binaryPath = await downloadAndExtract(agent.id, dist.archive, progress, agentsDir);\n } catch (err) {\n const msg = `Failed to download ${agent.name}. Please try again or install manually.`;\n await progress?.onError(msg);\n return { ok: false, agentKey, error: msg };\n }\n } else {\n await progress?.onStep(\"Setting up... (will download on first use)\");\n }\n\n // 5. Save to store\n const installed = buildInstalledAgent(agent.id, agent.name, agent.version, dist, binaryPath);\n store.addAgent(agentKey, installed);\n\n const setup = getAgentSetup(agent.id);\n await progress?.onSuccess(agent.name);\n return { ok: true, agentKey, setupSteps: setup?.setupSteps };\n}\n\nasync function downloadAndExtract(\n agentId: string,\n archiveUrl: string,\n progress?: InstallProgress,\n agentsDir?: string,\n): Promise<string> {\n const destDir = path.join(agentsDir ?? DEFAULT_AGENTS_DIR, agentId);\n fs.mkdirSync(destDir, { recursive: true });\n\n await progress?.onStep(\"Downloading...\");\n log.info({ agentId, url: archiveUrl }, \"Downloading agent binary\");\n\n const response = await fetch(archiveUrl);\n if (!response.ok) {\n throw new Error(`Download failed: ${response.status} ${response.statusText}`);\n }\n\n const contentLength = Number(response.headers.get(\"content-length\") || 0);\n const buffer = await readResponseWithProgress(response, contentLength, progress);\n\n await progress?.onStep(\"Extracting...\");\n\n if (archiveUrl.endsWith(\".zip\")) {\n await extractZip(buffer, destDir);\n } else {\n await extractTarGz(buffer, destDir);\n }\n\n await progress?.onStep(\"Ready!\");\n return destDir;\n}\n\nasync function readResponseWithProgress(\n response: Response,\n contentLength: number,\n progress?: InstallProgress,\n): Promise<Buffer> {\n if (!response.body || contentLength === 0) {\n const arrayBuffer = await response.arrayBuffer();\n return Buffer.from(arrayBuffer);\n }\n\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let received = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n received += value.length;\n if (contentLength > 0) {\n await progress?.onDownloadProgress(Math.round((received / contentLength) * 100));\n }\n }\n\n return Buffer.concat(chunks);\n}\n\nfunction validateExtractedPaths(destDir: string): void {\n const realDest = fs.realpathSync(destDir);\n const entries = fs.readdirSync(destDir, { recursive: true, withFileTypes: true });\n for (const entry of entries) {\n // Node <20.12 uses `path`, >=20.12 uses `parentPath` on Dirent with recursive readdir\n const dirent = entry as fs.Dirent & { parentPath?: string; path?: string };\n const parentPath = dirent.parentPath ?? dirent.path ?? destDir;\n const fullPath = path.join(parentPath, entry.name);\n let realPath: string;\n try {\n realPath = fs.realpathSync(fullPath);\n } catch {\n // Broken symlink — check where it points\n const linkTarget = fs.readlinkSync(fullPath);\n realPath = path.resolve(path.dirname(fullPath), linkTarget);\n }\n if (!realPath.startsWith(realDest + path.sep) && realPath !== realDest) {\n fs.rmSync(destDir, { recursive: true, force: true });\n throw new Error(`Archive contains unsafe path: ${entry.name}`);\n }\n }\n}\n\nasync function extractTarGz(buffer: Buffer, destDir: string): Promise<void> {\n const { execFileSync } = await import(\"node:child_process\");\n const tmpFile = path.join(destDir, \"_archive.tar.gz\");\n fs.writeFileSync(tmpFile, buffer);\n try {\n execFileSync(\"tar\", [\"xzf\", tmpFile, \"-C\", destDir], { stdio: \"pipe\" });\n } finally {\n fs.unlinkSync(tmpFile);\n }\n validateExtractedPaths(destDir);\n}\n\nasync function extractZip(buffer: Buffer, destDir: string): Promise<void> {\n const { execFileSync } = await import(\"node:child_process\");\n const tmpFile = path.join(destDir, \"_archive.zip\");\n fs.writeFileSync(tmpFile, buffer);\n try {\n execFileSync(\"unzip\", [\"-o\", tmpFile, \"-d\", destDir], { stdio: \"pipe\" });\n } finally {\n fs.unlinkSync(tmpFile);\n }\n validateExtractedPaths(destDir);\n}\n\nexport async function uninstallAgent(\n agentKey: string,\n store: AgentStore,\n): Promise<void> {\n const agent = store.getAgent(agentKey);\n if (!agent) return;\n\n if (agent.binaryPath && fs.existsSync(agent.binaryPath)) {\n fs.rmSync(agent.binaryPath, { recursive: true, force: true });\n log.info({ agentKey, binaryPath: agent.binaryPath }, \"Deleted agent binary\");\n }\n\n store.removeAgent(agentKey);\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport { AgentStore } from \"./agent-store.js\";\nimport { installAgent, uninstallAgent, resolveDistribution } from \"./agent-installer.js\";\nimport { getAgentAlias, checkDependencies } from \"./agent-dependencies.js\";\nimport type {\n AgentDefinition,\n RegistryAgent,\n AgentListItem,\n AvailabilityResult,\n InstallProgress,\n InstallResult,\n InstalledAgent,\n} from \"../types.js\";\nimport { createChildLogger } from \"../utils/log.js\";\n\nconst log = createChildLogger({ module: \"agent-catalog\" });\n\nconst REGISTRY_URL = \"https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json\";\nconst DEFAULT_TTL_HOURS = 24;\n\ninterface RegistryCache {\n fetchedAt: string;\n ttlHours: number;\n data: { agents: RegistryAgent[] };\n}\n\nexport class AgentCatalog {\n private store: AgentStore;\n private registryAgents: RegistryAgent[] = [];\n private cachePath: string;\n\n constructor(store?: AgentStore, cachePath?: string) {\n this.store = store ?? new AgentStore();\n this.cachePath = cachePath ?? path.join(os.homedir(), \".openacp\", \"registry-cache.json\");\n }\n\n load(): void {\n this.store.load();\n this.loadRegistryFromCacheOrSnapshot();\n this.enrichInstalledFromRegistry();\n }\n\n // --- Registry ---\n\n async fetchRegistry(): Promise<void> {\n try {\n log.info(\"Fetching agent registry from CDN...\");\n const response = await fetch(REGISTRY_URL);\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n const data = await response.json() as { agents: RegistryAgent[] };\n this.registryAgents = data.agents ?? [];\n\n const cache: RegistryCache = {\n fetchedAt: new Date().toISOString(),\n ttlHours: DEFAULT_TTL_HOURS,\n data,\n };\n fs.mkdirSync(path.dirname(this.cachePath), { recursive: true });\n fs.writeFileSync(this.cachePath, JSON.stringify(cache, null, 2));\n log.info({ count: this.registryAgents.length }, \"Registry updated\");\n } catch (err) {\n log.warn({ err }, \"Failed to fetch registry, using cached data\");\n }\n }\n\n async refreshRegistryIfStale(): Promise<void> {\n if (this.isCacheStale()) {\n await this.fetchRegistry();\n }\n }\n\n getRegistryAgents(): RegistryAgent[] {\n return this.registryAgents;\n }\n\n getRegistryAgent(registryId: string): RegistryAgent | undefined {\n return this.registryAgents.find((a) => a.id === registryId);\n }\n\n findRegistryAgent(keyOrId: string): RegistryAgent | undefined {\n const byId = this.registryAgents.find((a) => a.id === keyOrId);\n if (byId) return byId;\n return this.registryAgents.find((a) => getAgentAlias(a.id) === keyOrId);\n }\n\n // --- Installed ---\n\n getInstalled(): InstalledAgent[] {\n return Object.values(this.store.getInstalled());\n }\n\n getInstalledEntries(): Record<string, InstalledAgent> {\n return this.store.getInstalled();\n }\n\n getInstalledAgent(key: string): InstalledAgent | undefined {\n return this.store.getAgent(key);\n }\n\n // --- Discovery ---\n\n getAvailable(): AgentListItem[] {\n const installed = this.store.getInstalled();\n const items: AgentListItem[] = [];\n const seenKeys = new Set<string>();\n\n for (const [key, agent] of Object.entries(installed)) {\n seenKeys.add(key);\n const availability = agent.registryId\n ? checkDependencies(agent.registryId)\n : { available: true };\n const registryEntry = agent.registryId\n ? this.registryAgents.find((a) => a.id === agent.registryId)\n : undefined;\n items.push({\n key,\n registryId: agent.registryId ?? key,\n name: agent.name,\n version: agent.version,\n description: registryEntry?.description,\n distribution: agent.distribution,\n installed: true,\n available: availability.available,\n missingDeps: availability.missing?.map((m) => m.label),\n });\n }\n\n for (const agent of this.registryAgents) {\n const alias = getAgentAlias(agent.id);\n if (seenKeys.has(alias)) continue;\n seenKeys.add(alias);\n\n const dist = resolveDistribution(agent);\n const availability = checkDependencies(agent.id);\n\n items.push({\n key: alias,\n registryId: agent.id,\n name: agent.name,\n version: agent.version,\n description: agent.description,\n distribution: dist?.type ?? \"binary\",\n installed: false,\n available: dist !== null && availability.available,\n missingDeps: availability.missing?.map((m) => m.label),\n });\n }\n\n return items;\n }\n\n checkAvailability(keyOrId: string): AvailabilityResult {\n const agent = this.findRegistryAgent(keyOrId);\n if (!agent) return { available: false, reason: \"Not found in the agent registry.\" };\n\n const dist = resolveDistribution(agent);\n if (!dist) {\n return { available: false, reason: `Not available for your system. Check ${agent.website ?? agent.repository ?? \"their website\"} for other options.` };\n }\n\n return checkDependencies(agent.id);\n }\n\n // --- Install/Uninstall ---\n\n async install(keyOrId: string, progress?: InstallProgress, force?: boolean): Promise<InstallResult> {\n const agent = this.findRegistryAgent(keyOrId);\n if (!agent) {\n const msg = `\"${keyOrId}\" was not found in the agent registry. Run \"openacp agents\" to see what's available.`;\n await progress?.onError(msg);\n return { ok: false, agentKey: keyOrId, error: msg };\n }\n\n const agentKey = getAgentAlias(agent.id);\n if (this.store.hasAgent(agentKey) && !force) {\n const existing = this.store.getAgent(agentKey)!;\n const msg = `${agent.name} is already installed (v${existing.version}). Use --force to reinstall.`;\n await progress?.onError(msg);\n return { ok: false, agentKey, error: msg };\n }\n\n return installAgent(agent, this.store, progress);\n }\n\n async uninstall(key: string): Promise<{ ok: boolean; error?: string }> {\n if (!this.store.hasAgent(key)) {\n return { ok: false, error: `\"${key}\" is not installed.` };\n }\n await uninstallAgent(key, this.store);\n return { ok: true };\n }\n\n // --- Resolution (for AgentManager) ---\n\n resolve(key: string): AgentDefinition | undefined {\n const agent = this.store.getAgent(key);\n if (!agent) return undefined;\n return {\n name: key,\n command: agent.command,\n args: agent.args,\n workingDirectory: agent.workingDirectory,\n env: agent.env,\n };\n }\n\n // --- Internal ---\n\n /**\n * Enrich installed agents (especially migrated ones) with registry data.\n * Fixes agents that were migrated with version:\"unknown\", distribution:\"custom\",\n * or generic names by matching them to registry entries.\n */\n private enrichInstalledFromRegistry(): void {\n const installed = this.store.getInstalled();\n let changed = false;\n\n for (const [key, agent] of Object.entries(installed)) {\n const regAgent = agent.registryId\n ? this.registryAgents.find((a) => a.id === agent.registryId)\n : this.registryAgents.find((a) => getAgentAlias(a.id) === key);\n\n if (!regAgent) continue;\n\n let updated = false;\n\n // Enrich name if it's a generic capitalized key (e.g. \"Claude\" from migration)\n if (agent.name !== regAgent.name) {\n agent.name = regAgent.name;\n updated = true;\n }\n\n // Enrich version if unknown\n if (agent.version === \"unknown\") {\n agent.version = regAgent.version;\n updated = true;\n }\n\n // Enrich registryId if missing\n if (!agent.registryId) {\n agent.registryId = regAgent.id;\n updated = true;\n }\n\n // Enrich distribution from \"custom\" to actual type\n if (agent.distribution === \"custom\") {\n const dist = resolveDistribution(regAgent);\n if (dist) {\n agent.distribution = dist.type;\n updated = true;\n }\n }\n\n if (updated) {\n this.store.addAgent(key, agent);\n changed = true;\n }\n }\n\n if (changed) {\n log.info(\"Enriched installed agents with registry data\");\n }\n }\n\n private isCacheStale(): boolean {\n if (!fs.existsSync(this.cachePath)) return true;\n try {\n const raw = JSON.parse(fs.readFileSync(this.cachePath, \"utf-8\") as string) as RegistryCache;\n const fetchedAt = new Date(raw.fetchedAt).getTime();\n const ttlMs = (raw.ttlHours ?? DEFAULT_TTL_HOURS) * 60 * 60 * 1000;\n return Date.now() - fetchedAt > ttlMs;\n } catch {\n return true;\n }\n }\n\n private loadRegistryFromCacheOrSnapshot(): void {\n // Try cache first\n if (fs.existsSync(this.cachePath)) {\n try {\n const raw = JSON.parse(fs.readFileSync(this.cachePath, \"utf-8\") as string) as RegistryCache;\n if (raw.data?.agents) {\n this.registryAgents = raw.data.agents;\n log.debug({ count: this.registryAgents.length }, \"Loaded registry from cache\");\n return;\n }\n } catch {\n log.warn(\"Failed to load registry cache\");\n }\n }\n\n // Fallback: bundled snapshot\n try {\n // Try multiple paths for tsc and tsup builds\n const candidates = [\n path.join(import.meta.dirname, \"data\", \"registry-snapshot.json\"),\n path.join(import.meta.dirname, \"..\", \"data\", \"registry-snapshot.json\"),\n path.join(import.meta.dirname, \"..\", \"..\", \"data\", \"registry-snapshot.json\"),\n ];\n\n for (const candidate of candidates) {\n if (fs.existsSync(candidate)) {\n const raw = JSON.parse(fs.readFileSync(candidate, \"utf-8\") as string);\n this.registryAgents = raw.agents ?? [];\n log.debug({ count: this.registryAgents.length }, \"Loaded registry from bundled snapshot\");\n return;\n }\n }\n\n log.warn(\"No registry data available (no cache, no snapshot)\");\n } catch {\n log.warn(\"Failed to load bundled registry snapshot\");\n }\n }\n}\n","export type OnboardSection =\n | \"channels\"\n | \"agents\"\n | \"workspace\"\n | \"runMode\"\n | \"integrations\";\n\nexport type ConfiguredChannelAction = \"modify\" | \"disable\" | \"delete\" | \"skip\";\n\nexport type ChannelId = string;\n\nexport type ChannelStatus = {\n id: ChannelId;\n label: string;\n configured: boolean;\n enabled: boolean;\n hint?: string;\n};\n\nexport const ONBOARD_SECTION_OPTIONS: Array<{\n value: OnboardSection;\n label: string;\n hint: string;\n}> = [\n { value: \"channels\", label: \"Channels\", hint: \"Link/update messaging platforms\" },\n { value: \"agents\", label: \"Agents\", hint: \"Install agents, change default\" },\n { value: \"workspace\", label: \"Workspace\", hint: \"Set workspace directory\" },\n { value: \"runMode\", label: \"Run mode\", hint: \"Foreground/daemon, auto-start\" },\n { value: \"integrations\", label: \"Integrations\", hint: \"Claude CLI session transfer\" },\n];\n\nexport const CHANNEL_META: Record<string, { label: string; method: string }> = {\n telegram: { label: \"Telegram\", method: \"Bot API\" },\n discord: { label: \"Discord\", method: \"Bot API\" },\n};\n\nexport interface CommunityAdapterOption {\n name: string // npm package name, e.g. \"@openacp/adapter-slack\"\n displayName: string // e.g. \"Slack Adapter\"\n icon: string // e.g. \"💬\"\n verified: boolean\n}\n\n","import * as clack from \"@clack/prompts\";\nimport type { Config } from \"../config/config.js\";\n\n// --- ANSI colors ---\n\nexport const c = {\n reset: \"\\x1b[0m\",\n bold: \"\\x1b[1m\",\n dim: \"\\x1b[2m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n red: \"\\x1b[31m\",\n cyan: \"\\x1b[36m\",\n white: \"\\x1b[37m\",\n};\n\nexport const ok = (msg: string) =>\n `${c.green}${c.bold}✓${c.reset} ${c.green}${msg}${c.reset}`;\nexport const warn = (msg: string) => `${c.yellow}⚠ ${msg}${c.reset}`;\nexport const fail = (msg: string) => `${c.red}✗ ${msg}${c.reset}`;\nexport const step = (n: number, total: number, title: string) =>\n `\\n${c.cyan}${c.bold}[${n}/${total}]${c.reset} ${c.bold}${title}${c.reset}\\n`;\nexport const dim = (msg: string) => `${c.dim}${msg}${c.reset}`;\n\nexport function guardCancel<T>(value: T | symbol): T {\n if (clack.isCancel(value)) {\n clack.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n return value as T;\n}\n\n// --- Banner ---\n\nfunction applyGradient(text: string): string {\n const colors = [135, 99, 63, 33, 39, 44, 44];\n const lines = text.split(\"\\n\");\n return lines\n .map((line, i) => {\n const colorIdx = Math.min(i, colors.length - 1);\n return `\\x1b[38;5;${colors[colorIdx]}m${line}\\x1b[0m`;\n })\n .join(\"\\n\");\n}\n\nconst BANNER = `\n ██████╗ ██████╗ ███████╗███╗ ██╗ █████╗ ██████╗██████╗\n ██╔═══██╗██╔══██╗██╔════╝████╗ ██║██╔══██╗██╔════╝██╔══██╗\n ██║ ██║██████╔╝█████╗ ██╔██╗ ██║███████║██║ ██████╔╝\n ██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║██╔══██║██║ ██╔═══╝\n ╚██████╔╝██║ ███████╗██║ ╚████║██║ ██║╚██████╗██║\n ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═════╝╚═╝\n`;\n\nexport async function printStartBanner(): Promise<void> {\n let version = \"0.0.0\";\n try {\n const { getCurrentVersion } = await import(\"../../cli/version.js\");\n version = getCurrentVersion();\n } catch {\n // ignore\n }\n console.log(applyGradient(BANNER));\n console.log(`${c.dim} AI coding agents, anywhere. v${version}${c.reset}\\n`);\n}\n\n// --- Config summary ---\n\nexport function summarizeConfig(config: Config): string {\n const lines: string[] = [];\n\n // Channels\n const channelStatuses: string[] = [];\n for (const [id, meta] of Object.entries({\n telegram: \"Telegram\",\n discord: \"Discord\",\n })) {\n const ch = config.channels[id] as { enabled?: boolean } | undefined;\n if (ch?.enabled) {\n channelStatuses.push(`${meta} (enabled)`);\n } else if (ch && Object.keys(ch).length > 1) {\n channelStatuses.push(`${meta} (disabled)`);\n } else {\n channelStatuses.push(`${meta} (not configured)`);\n }\n }\n lines.push(`Channels: ${channelStatuses.join(\", \")}`);\n\n // Default agent\n lines.push(`Default agent: ${config.defaultAgent}`);\n\n // Workspace\n lines.push(`Workspace: ${config.workspace.baseDir}`);\n\n // Run mode\n lines.push(`Run mode: ${config.runMode}${config.autoStart ? \" (auto-start)\" : \"\"}`);\n\n return lines.join(\"\\n\");\n}\n","import { execFileSync } from \"node:child_process\";\nimport * as clack from \"@clack/prompts\";\nimport { commandExists } from \"../agents/agent-dependencies.js\";\nimport { guardCancel, ok, warn, c } from \"./helpers.js\";\n\nconst KNOWN_AGENTS: Array<{ name: string; commands: string[] }> = [\n // claude-agent-acp is bundled as a dependency — no detection needed, but\n // kept here so detectAgents() still returns it for display purposes.\n { name: \"claude\", commands: [\"claude-agent-acp\"] },\n { name: \"codex\", commands: [\"codex\"] },\n];\n\nexport async function detectAgents(): Promise<\n Array<{ name: string; command: string }>\n> {\n const found: Array<{ name: string; command: string }> = [];\n for (const agent of KNOWN_AGENTS) {\n // Find all available commands for this agent (PATH + node_modules/.bin)\n const available: string[] = [];\n for (const cmd of agent.commands) {\n if (commandExists(cmd)) {\n available.push(cmd);\n }\n }\n if (available.length > 0) {\n // Prefer claude-agent-acp over claude/claude-code (priority order)\n found.push({ name: agent.name, command: available[0] });\n }\n }\n return found;\n}\n\nexport async function validateAgentCommand(command: string): Promise<boolean> {\n try {\n execFileSync(\"which\", [command], { stdio: \"pipe\" });\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function setupAgents(): Promise<{\n defaultAgent: string;\n}> {\n const { AgentCatalog } = await import(\"../agents/agent-catalog.js\");\n const { muteLogger, unmuteLogger } = await import(\"../utils/log.js\");\n\n muteLogger();\n const catalog = new AgentCatalog();\n catalog.load();\n\n const s = clack.spinner();\n s.start(\"Checking available agents...\");\n await catalog.refreshRegistryIfStale();\n\n // Claude is always pre-installed (bundled dependency)\n if (!catalog.getInstalledAgent(\"claude\")) {\n const claudeRegistry = catalog.findRegistryAgent(\"claude-acp\");\n if (claudeRegistry) {\n await catalog.install(\"claude-acp\");\n } else {\n // Fallback: register bundled claude-agent-acp directly\n const { AgentStore } = await import(\"../agents/agent-store.js\");\n const store = new AgentStore();\n store.load();\n store.addAgent(\"claude\", {\n registryId: \"claude-acp\",\n name: \"Claude Agent\",\n version: \"bundled\",\n distribution: \"npx\",\n command: \"npx\",\n args: [\"@agentclientprotocol/claude-agent-acp\"],\n env: {},\n installedAt: new Date().toISOString(),\n binaryPath: null,\n });\n }\n }\n s.stop(ok(\"Claude Agent ready\"));\n unmuteLogger();\n\n const available = catalog.getAvailable();\n const installed = available.filter((a) => a.installed);\n const installable = available.filter((a) => !a.installed && a.available);\n\n // Offer agent selection — show installed agents as pre-checked + installable agents\n if (installed.length > 0 || installable.length > 0) {\n // Deduplicate by key AND name\n const seen = new Set<string>();\n const options: Array<{ label: string; value: string }> = [];\n\n for (const a of installed) {\n const dedupeKey = `${a.key}::${a.name}`;\n if (seen.has(dedupeKey)) continue;\n seen.add(dedupeKey);\n options.push({\n label: `${a.name} (installed)`,\n value: a.key,\n });\n }\n for (const a of installable) {\n const dedupeKey = `${a.key}::${a.name}`;\n if (seen.has(dedupeKey)) continue;\n seen.add(dedupeKey);\n options.push({\n label: `${a.name} (${a.distribution})`,\n value: a.key,\n });\n }\n\n const installedKeys = installed.map(a => a.key);\n const selected = guardCancel(\n await clack.autocompleteMultiselect({\n message: \"Install additional agents? (type to search, Space to select)\",\n options,\n initialValues: installedKeys,\n required: false,\n }),\n ) as string[];\n\n for (const key of selected) {\n const regAgent = catalog.findRegistryAgent(key);\n if (regAgent) {\n const installSpinner = clack.spinner();\n installSpinner.start(`Installing ${regAgent.name}...`);\n muteLogger();\n const result = await catalog.install(key);\n unmuteLogger();\n if (result.ok) {\n installSpinner.stop(ok(\"done\"));\n } else {\n installSpinner.stop(warn(`skipped: ${result.error}`));\n }\n }\n }\n }\n\n // Choose default agent\n const installedAgents = Object.keys(catalog.getInstalledEntries());\n let defaultAgent = \"claude\";\n\n if (installedAgents.length > 1) {\n defaultAgent = guardCancel(\n await clack.select({\n message: \"Which agent should be the default?\",\n options: installedAgents.map((key) => {\n const agent = catalog.getInstalledAgent(key)!;\n return { label: `${agent.name} (${key})`, value: key };\n }),\n initialValue: \"claude\",\n }),\n ) as string;\n }\n\n console.log(ok(`Default agent: ${c.bold}${defaultAgent}${c.reset}`));\n return { defaultAgent };\n}\n","import * as clack from \"@clack/prompts\";\nimport { guardCancel, step } from \"./helpers.js\";\n\nexport async function setupWorkspace(opts?: {\n existing?: string;\n stepNum?: number;\n totalSteps?: number;\n}): Promise<{ baseDir: string }> {\n const { existing, stepNum, totalSteps } = opts ?? {};\n if (stepNum != null && totalSteps != null) {\n console.log(step(stepNum, totalSteps, \"Workspace\"));\n }\n\n const baseDir = guardCancel(\n await clack.text({\n message: \"Base directory for workspaces:\",\n initialValue: existing ?? \"~/openacp-workspace\",\n validate: (val) =>\n (val ?? \"\").toString().trim().length > 0 ? undefined : \"Path cannot be empty\",\n }),\n ) as string;\n\n return { baseDir: baseDir.trim().replace(/^['\"]|['\"]$/g, \"\") };\n}\n","import * as clack from \"@clack/prompts\";\nimport { expandHome } from \"../config/config.js\";\nimport { guardCancel, ok, warn, dim, step } from \"./helpers.js\";\n\nexport async function setupRunMode(opts?: {\n existing?: { runMode: string; autoStart: boolean };\n stepNum?: number;\n totalSteps?: number;\n}): Promise<{ runMode: 'foreground' | 'daemon'; autoStart: boolean }> {\n const { existing, stepNum, totalSteps } = opts ?? {};\n if (stepNum != null && totalSteps != null) {\n console.log(step(stepNum, totalSteps, 'Run Mode'));\n }\n\n // Don't show daemon option on Windows\n if (process.platform === 'win32') {\n console.log(dim(' (Daemon mode not available on Windows)'));\n return { runMode: 'foreground', autoStart: false };\n }\n\n const initialValue = (existing?.runMode === 'daemon' ? 'daemon' : 'foreground') as 'foreground' | 'daemon';\n\n const mode = guardCancel(\n await clack.select({\n message: 'How would you like to run OpenACP?',\n options: [\n {\n label: 'Background (daemon)',\n value: 'daemon' as const,\n hint: 'Runs silently, auto-starts on boot. Manage with: openacp status | stop | logs',\n },\n {\n label: 'Foreground (terminal)',\n value: 'foreground' as const,\n hint: 'Runs in current terminal session. Start with: openacp',\n },\n ],\n initialValue,\n }),\n );\n\n const wasDaemon = existing?.runMode === 'daemon';\n\n if (mode === 'daemon') {\n const { installAutoStart, isAutoStartSupported } = await import('../../cli/autostart.js');\n const { muteLogger, unmuteLogger } = await import('../utils/log.js');\n const autoStart = isAutoStartSupported();\n if (autoStart) {\n muteLogger();\n const result = installAutoStart(expandHome('~/.openacp/logs'));\n unmuteLogger();\n if (result.success) {\n console.log(ok('Auto-start on boot enabled'));\n } else {\n console.log(warn(`Auto-start failed: ${result.error}`));\n }\n }\n return { runMode: 'daemon', autoStart };\n }\n\n // Switching from daemon → foreground: stop daemon + uninstall autostart\n if (wasDaemon) {\n const { muteLogger, unmuteLogger } = await import('../utils/log.js');\n muteLogger();\n try {\n const { stopDaemon } = await import('../../cli/daemon.js');\n const result = await stopDaemon();\n unmuteLogger();\n if (result.stopped) {\n console.log(ok(`Daemon stopped (was PID ${result.pid})`));\n }\n } catch {\n unmuteLogger();\n // Daemon may not be running\n }\n muteLogger();\n try {\n const { uninstallAutoStart } = await import('../../cli/autostart.js');\n uninstallAutoStart();\n unmuteLogger();\n } catch {\n unmuteLogger();\n // ignore\n }\n }\n\n return { runMode: 'foreground', autoStart: false };\n}\n","import * as clack from \"@clack/prompts\";\nimport type { Config } from \"../config/config.js\";\nimport { guardCancel } from \"./helpers.js\";\n\nexport async function setupIntegrations(config?: Config): Promise<void> {\n const claudeIntegration = (config?.integrations as Record<string, unknown> | undefined)?.claude as { installed?: boolean } | undefined;\n const isInstalled = claudeIntegration?.installed === true;\n\n const installClaude = guardCancel(\n await clack.confirm({\n message: isInstalled\n ? \"Claude CLI integration is installed. Reinstall?\"\n : \"Install session transfer for Claude? (enables /openacp:handoff in your terminal)\",\n initialValue: !isInstalled,\n }),\n );\n\n if (installClaude) {\n try {\n const { getIntegration } = await import(\"../../cli/integrate.js\");\n const integration = getIntegration(\"claude\");\n if (integration) {\n for (const item of integration.items) {\n const result = await item.install();\n for (const log of result.logs) console.log(` ${log}`);\n }\n }\n console.log(\"Claude CLI integration installed.\\n\");\n } catch (err) {\n console.log(`Could not install Claude CLI integration: ${err instanceof Error ? err.message : err}`);\n console.log(\" You can install it later with: openacp integrate claude\\n\");\n }\n }\n}\n","import * as path from \"node:path\";\nimport { getGlobalRoot } from \"../instance-context.js\";\nimport * as clack from \"@clack/prompts\";\nimport type { Config } from \"../config/config.js\";\nimport type { ConfiguredChannelAction, ChannelId, ChannelStatus } from \"./types.js\";\nimport { CHANNEL_META } from \"./types.js\";\nimport { guardCancel, ok, c } from \"./helpers.js\";\n\nexport function getChannelStatuses(config: Config): ChannelStatus[] {\n const statuses: ChannelStatus[] = [];\n\n for (const [id, meta] of Object.entries(CHANNEL_META) as [ChannelId, typeof CHANNEL_META[ChannelId]][]) {\n const ch = config.channels[id] as Record<string, unknown> | undefined;\n const enabled = ch?.enabled === true;\n const configured = !!ch && Object.keys(ch).length > 1;\n\n let hint: string | undefined;\n if (id === \"telegram\" && ch?.botToken && typeof ch.botToken === \"string\" && ch.botToken !== \"YOUR_BOT_TOKEN_HERE\") {\n hint = `Chat ID: ${ch.chatId}`;\n }\n if (id === \"discord\" && ch?.guildId) {\n hint = `Guild: ${ch.guildId}`;\n }\n\n statuses.push({ id, label: meta.label, configured, enabled, hint });\n }\n\n return statuses;\n}\n\nexport function noteChannelStatus(config: Config): void {\n const statuses = getChannelStatuses(config);\n const lines = statuses.map((s) => {\n const status = s.enabled ? \"enabled\" : s.configured ? \"disabled\" : \"not configured\";\n const hintStr = s.hint ? ` — ${s.hint}` : \"\";\n return ` ${s.label}: ${status}${hintStr}`;\n });\n\n console.log(\"\");\n console.log(`${c.bold} Channel status${c.reset}`);\n for (const line of lines) console.log(line);\n console.log(\"\");\n}\n\nasync function promptConfiguredAction(label: string): Promise<ConfiguredChannelAction> {\n return guardCancel(\n await clack.select({\n message: `${label} already configured. What do you want to do?`,\n options: [\n { value: \"modify\" as const, label: \"Modify settings\" },\n { value: \"disable\" as const, label: \"Disable bot\" },\n { value: \"delete\" as const, label: \"Delete config\" },\n { value: \"skip\" as const, label: \"Skip (leave as-is)\" },\n ],\n initialValue: \"modify\" as const,\n }),\n );\n}\n\nasync function configureViaPlugin(channelId: string): Promise<void> {\n const pluginMap: Record<string, { importPath: string; name: string }> = {\n telegram: { importPath: '../../plugins/telegram/index.js', name: '@openacp/telegram' },\n };\n\n const pluginInfo = pluginMap[channelId];\n\n let plugin: any;\n if (pluginInfo) {\n const pluginModule = await import(pluginInfo.importPath);\n plugin = pluginModule.default;\n } else {\n // Try dynamic import for community plugins (npm package name)\n try {\n const pluginModule = await import(channelId);\n plugin = pluginModule.default;\n } catch (err) {\n console.log(`Could not load plugin \"${channelId}\": ${(err as Error).message}`);\n return;\n }\n }\n\n if (plugin?.configure) {\n const { SettingsManager } = await import('../plugin/settings-manager.js');\n const { createInstallContext } = await import('../plugin/install-context.js');\n const basePath = path.join(getGlobalRoot(), 'plugins', 'data');\n const settingsManager = new SettingsManager(basePath);\n const ctx = createInstallContext({\n pluginName: plugin.name,\n settingsManager,\n basePath,\n });\n await plugin.configure(ctx);\n }\n}\n\nexport async function configureChannels(config: Config): Promise<{ config: Config; changed: boolean }> {\n const next = structuredClone(config);\n let changed = false;\n\n noteChannelStatus(next);\n\n while (true) {\n const statuses = getChannelStatuses(next);\n const options = statuses.map((s) => {\n const status = s.enabled ? \"enabled\" : s.configured ? \"disabled\" : \"not configured\";\n return {\n value: s.id,\n label: `${s.label} (${CHANNEL_META[s.id].method})`,\n hint: status + (s.hint ? ` · ${s.hint}` : \"\"),\n };\n });\n\n const choice = guardCancel(\n await clack.select({\n message: \"Select a channel\",\n options: [\n ...options,\n { value: \"__done__\" as const, label: \"Finished\" },\n ],\n }),\n );\n\n if (choice === \"__done__\") break;\n\n const channelId = choice as ChannelId;\n const meta = CHANNEL_META[channelId];\n const existing = next.channels[channelId] as Record<string, unknown> | undefined;\n const isConfigured = !!existing && Object.keys(existing).length > 1;\n\n if (isConfigured) {\n const action = await promptConfiguredAction(meta.label);\n\n if (action === \"skip\") continue;\n if (action === \"disable\") {\n (next.channels[channelId] as Record<string, unknown>).enabled = false;\n changed = true;\n console.log(ok(`${meta.label} disabled`));\n continue;\n }\n if (action === \"delete\") {\n const confirmed = guardCancel(\n await clack.confirm({\n message: `Delete ${meta.label} config? This cannot be undone.`,\n initialValue: false,\n }),\n );\n if (confirmed) {\n delete next.channels[channelId];\n changed = true;\n console.log(ok(`${meta.label} config deleted`));\n }\n continue;\n }\n // action === \"modify\" — fall through to plugin configure\n }\n\n // Run channel configuration via plugin configure()\n await configureViaPlugin(channelId);\n changed = true;\n }\n\n return { config: next, changed };\n}\n","// src/core/instance-copy.ts\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nexport interface CopyOptions {\n inheritableKeys?: Record<string, string[]>\n onProgress?: (step: string, status: 'start' | 'done') => void\n}\n\nexport async function copyInstance(src: string, dst: string, opts: CopyOptions): Promise<void> {\n const { inheritableKeys = {}, onProgress } = opts\n fs.mkdirSync(dst, { recursive: true })\n\n // 1. config.json — remove instanceName and port fields\n const configSrc = path.join(src, 'config.json')\n if (fs.existsSync(configSrc)) {\n onProgress?.('Configuration', 'start')\n const config = JSON.parse(fs.readFileSync(configSrc, 'utf-8'))\n delete config.instanceName\n if (config.api) delete config.api.port\n if (config.tunnel) delete config.tunnel.port\n fs.writeFileSync(path.join(dst, 'config.json'), JSON.stringify(config, null, 2))\n onProgress?.('Configuration', 'done')\n }\n\n // 2. plugins.json\n const pluginsSrc = path.join(src, 'plugins.json')\n if (fs.existsSync(pluginsSrc)) {\n onProgress?.('Plugin list', 'start')\n fs.copyFileSync(pluginsSrc, path.join(dst, 'plugins.json'))\n onProgress?.('Plugin list', 'done')\n }\n\n // 3. plugins/ (package.json + node_modules)\n const pluginsDir = path.join(src, 'plugins')\n if (fs.existsSync(pluginsDir)) {\n onProgress?.('Plugins', 'start')\n const dstPlugins = path.join(dst, 'plugins')\n fs.mkdirSync(dstPlugins, { recursive: true })\n const pkgJson = path.join(pluginsDir, 'package.json')\n if (fs.existsSync(pkgJson)) fs.copyFileSync(pkgJson, path.join(dstPlugins, 'package.json'))\n const nodeModules = path.join(pluginsDir, 'node_modules')\n if (fs.existsSync(nodeModules)) fs.cpSync(nodeModules, path.join(dstPlugins, 'node_modules'), { recursive: true })\n onProgress?.('Plugins', 'done')\n }\n\n // 4. agents.json + agents/\n const agentsJson = path.join(src, 'agents.json')\n if (fs.existsSync(agentsJson)) {\n onProgress?.('Agents', 'start')\n fs.copyFileSync(agentsJson, path.join(dst, 'agents.json'))\n const agentsDir = path.join(src, 'agents')\n if (fs.existsSync(agentsDir)) fs.cpSync(agentsDir, path.join(dst, 'agents'), { recursive: true })\n onProgress?.('Agents', 'done')\n }\n\n // 5. bin/\n const binDir = path.join(src, 'bin')\n if (fs.existsSync(binDir)) {\n onProgress?.('Tools', 'start')\n fs.cpSync(binDir, path.join(dst, 'bin'), { recursive: true })\n onProgress?.('Tools', 'done')\n }\n\n // 6. Plugin settings filtered by inheritableKeys\n const pluginDataSrc = path.join(src, 'plugins', 'data')\n if (fs.existsSync(pluginDataSrc)) {\n onProgress?.('Preferences', 'start')\n copyPluginSettings(pluginDataSrc, path.join(dst, 'plugins', 'data'), inheritableKeys)\n onProgress?.('Preferences', 'done')\n }\n}\n\nfunction copyPluginSettings(srcData: string, dstData: string, inheritableKeys: Record<string, string[]>): void {\n walkPluginDirs(srcData, (pluginName, settingsPath) => {\n const allowedKeys = inheritableKeys[pluginName]\n if (!allowedKeys || allowedKeys.length === 0) return\n try {\n const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'))\n const filtered: Record<string, unknown> = {}\n for (const key of allowedKeys) {\n if (key in settings) filtered[key] = settings[key]\n }\n if (Object.keys(filtered).length > 0) {\n const relative = path.relative(srcData, path.dirname(settingsPath))\n const dstDir = path.join(dstData, relative)\n fs.mkdirSync(dstDir, { recursive: true })\n fs.writeFileSync(path.join(dstDir, 'settings.json'), JSON.stringify(filtered, null, 2))\n }\n } catch { /* skip invalid */ }\n })\n}\n\nfunction walkPluginDirs(base: string, cb: (pluginName: string, settingsPath: string) => void): void {\n if (!fs.existsSync(base)) return\n for (const entry of fs.readdirSync(base, { withFileTypes: true })) {\n if (!entry.isDirectory()) continue\n if (entry.name.startsWith('@')) {\n const scopeDir = path.join(base, entry.name)\n for (const sub of fs.readdirSync(scopeDir, { withFileTypes: true })) {\n if (!sub.isDirectory()) continue\n const pluginName = `${entry.name}/${sub.name}`\n const settingsPath = path.join(scopeDir, sub.name, 'settings.json')\n if (fs.existsSync(settingsPath)) cb(pluginName, settingsPath)\n }\n } else {\n const settingsPath = path.join(base, entry.name, 'settings.json')\n if (fs.existsSync(settingsPath)) cb(entry.name, settingsPath)\n }\n }\n}\n","import * as path from \"node:path\";\nimport * as fs from \"node:fs\";\nimport * as clack from \"@clack/prompts\";\nimport type { Config, ConfigManager } from \"../config/config.js\";\nimport type { ChannelId } from \"./types.js\";\nimport type { OnboardSection } from \"./types.js\";\nimport { ONBOARD_SECTION_OPTIONS } from \"./types.js\";\nimport type { CommunityAdapterOption } from \"./types.js\";\nimport { guardCancel, ok, fail, printStartBanner, summarizeConfig } from \"./helpers.js\";\nimport { setupAgents } from \"./setup-agents.js\";\nimport { setupWorkspace } from \"./setup-workspace.js\";\nimport { setupRunMode } from \"./setup-run-mode.js\";\nimport { setupIntegrations } from \"./setup-integrations.js\";\nimport { configureChannels } from \"./setup-channels.js\";\nimport { RegistryClient } from \"../plugin/registry-client.js\";\nimport type { SettingsManager } from \"../plugin/settings-manager.js\";\nimport type { PluginRegistry } from \"../plugin/plugin-registry.js\";\nimport { InstanceRegistry } from \"../instance-registry.js\";\nimport { generateSlug, getGlobalRoot } from \"../instance-context.js\";\nimport { copyInstance } from \"../instance-copy.js\";\n\n// ─── Registry discovery ───\n\nasync function fetchCommunityAdapters(): Promise<CommunityAdapterOption[]> {\n try {\n const client = new RegistryClient()\n const registry = await client.getRegistry()\n return registry.plugins\n .filter(p => p.category === 'adapter' && p.verified)\n .map(p => ({\n name: p.npm,\n displayName: p.displayName ?? p.name,\n icon: p.icon,\n verified: p.verified,\n }))\n } catch {\n return []\n }\n}\n\n// ─── First-run setup ───\n\nexport async function runSetup(\n configManager: ConfigManager,\n opts?: {\n skipRunMode?: boolean\n settingsManager?: SettingsManager\n pluginRegistry?: PluginRegistry\n instanceName?: string\n from?: string // path to copy from (parent dir, not .openacp)\n instanceRoot?: string // the .openacp dir being set up\n },\n): Promise<boolean> {\n await printStartBanner();\n clack.intro(\"Let's set up OpenACP\");\n\n const { settingsManager, pluginRegistry } = opts ?? {};\n\n try {\n if (!settingsManager || !pluginRegistry) {\n console.log(fail('Plugin system not initialized. Cannot set up channels.'));\n return false;\n }\n\n // ─── Instance name prompt ───\n\n const instanceRoot = opts?.instanceRoot ?? getGlobalRoot();\n const isGlobal = instanceRoot === getGlobalRoot();\n\n let instanceName = opts?.instanceName;\n if (!instanceName) {\n const defaultName = isGlobal ? 'Main' : `openacp-${Date.now()}`;\n const nameResult = await clack.text({\n message: 'Give this setup a name',\n defaultValue: defaultName,\n validate: (v) => (!v?.trim() ? 'Name cannot be empty' : undefined),\n });\n if (clack.isCancel(nameResult)) return false;\n instanceName = nameResult.trim();\n }\n\n // ─── Copy-from flow ───\n\n const globalRoot = getGlobalRoot();\n const registryPath = path.join(globalRoot, 'instances.json');\n const instanceRegistry = new InstanceRegistry(registryPath);\n await instanceRegistry.load();\n\n let didCopy = false;\n\n // Check --from flag first\n if (opts?.from) {\n const fromRoot = path.join(opts.from, '.openacp');\n if (fs.existsSync(path.join(fromRoot, 'config.json'))) {\n const inheritableMap = buildInheritableKeysMap();\n await copyInstance(fromRoot, instanceRoot, { inheritableKeys: inheritableMap });\n didCopy = true;\n } else {\n console.error(`No OpenACP setup found at ${fromRoot}`);\n return false;\n }\n }\n\n // If no --from, check if we can offer to copy interactively\n if (!didCopy) {\n const existingInstances = instanceRegistry.list().filter(e =>\n fs.existsSync(path.join(e.root, 'config.json')) && e.root !== instanceRoot\n );\n\n if (existingInstances.length > 0) {\n const shouldCopy = await clack.confirm({\n message: 'Use settings from an existing setup as a starting point?',\n initialValue: true,\n });\n\n if (clack.isCancel(shouldCopy)) return false;\n\n if (shouldCopy === true) {\n let sourceRoot: string;\n if (existingInstances.length === 1) {\n sourceRoot = existingInstances[0]!.root;\n } else {\n const choice = await clack.select({\n message: 'Which setup to copy from?',\n options: existingInstances.map(e => {\n let name = e.id;\n try {\n const cfg = JSON.parse(fs.readFileSync(path.join(e.root, 'config.json'), 'utf-8'));\n if (cfg.instanceName) name = cfg.instanceName;\n } catch {}\n const displayPath = e.root.replace(/\\/.openacp$/, '');\n return { value: e.root, label: `${name} (${displayPath})` };\n }),\n });\n if (clack.isCancel(choice)) return false;\n sourceRoot = choice;\n }\n\n const inheritableMap = buildInheritableKeysMap();\n await copyInstance(sourceRoot, instanceRoot, {\n inheritableKeys: inheritableMap,\n onProgress: (step, status) => {\n if (status === 'done') console.log(` ✓ ${step}`);\n },\n });\n didCopy = true;\n }\n }\n }\n\n // If copied, reload config so the wizard sees existing values\n if (didCopy && await configManager.exists()) {\n await configManager.load();\n }\n\n const communityAdapters = await fetchCommunityAdapters()\n\n const builtInOptions = [\n { label: 'Telegram', value: 'telegram' },\n ]\n\n const communityOptions = communityAdapters.map(a => ({\n label: `${a.icon} ${a.displayName}${a.verified ? ' (verified)' : ''}`,\n value: `community:${a.name}`,\n }))\n\n // Ask user which channels to set up\n const channelChoices = guardCancel(\n await clack.multiselect({\n message: 'Which channels do you want to set up?',\n options: [\n ...builtInOptions.map(o => ({ value: o.value, label: o.label, hint: 'built-in' })),\n ...(communityOptions.length > 0\n ? communityOptions.map(o => ({ value: o.value, label: o.label, hint: 'from plugin registry' }))\n : []),\n ],\n required: true,\n initialValues: ['telegram' as const],\n }),\n ) as string[];\n\n // Calculate total steps dynamically: channel(s) + workspace + run mode\n const channelSteps = channelChoices.length;\n const runModeSteps = opts?.skipRunMode ? 0 : 1;\n const totalSteps = channelSteps + 1 + runModeSteps; // + workspace + optional run mode\n\n let currentStep = 0;\n\n const { createInstallContext } = await import('../plugin/install-context.js');\n\n for (const channelId of channelChoices) {\n currentStep++;\n\n if (channelId === 'telegram') {\n const telegramPlugin = (await import('../../plugins/telegram/index.js')).default;\n const ctx = createInstallContext({\n pluginName: telegramPlugin.name,\n settingsManager,\n basePath: settingsManager.getBasePath(),\n });\n await telegramPlugin.install!(ctx);\n pluginRegistry.register(telegramPlugin.name, {\n version: telegramPlugin.version,\n source: 'builtin',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(telegramPlugin.name),\n description: telegramPlugin.description,\n });\n }\n\n\n // Handle community plugin selections\n if (channelId.startsWith('community:')) {\n const npmPackage = channelId.slice('community:'.length);\n const { execFileSync } = await import('node:child_process');\n const pluginsDir = path.join(getGlobalRoot(), 'plugins');\n const nodeModulesDir = path.join(pluginsDir, 'node_modules');\n\n // Install from npm\n try {\n execFileSync('npm', ['install', npmPackage, '--prefix', pluginsDir, '--save'], {\n stdio: 'inherit',\n timeout: 60000,\n });\n } catch {\n console.log(fail(`Failed to install ${npmPackage}.`));\n return false;\n }\n\n // Load and run install hook\n try {\n const { readFileSync } = await import('node:fs');\n const installedPkgPath = path.join(nodeModulesDir, npmPackage, 'package.json');\n const installedPkg = JSON.parse(readFileSync(installedPkgPath, 'utf-8'));\n const pluginModule = await import(path.join(nodeModulesDir, npmPackage, installedPkg.main ?? 'dist/index.js'));\n const plugin = pluginModule.default;\n\n if (plugin?.install) {\n const installCtx = createInstallContext({\n pluginName: plugin.name ?? npmPackage,\n settingsManager,\n basePath: settingsManager.getBasePath(),\n });\n await plugin.install(installCtx);\n }\n\n pluginRegistry.register(plugin?.name ?? npmPackage, {\n version: installedPkg.version,\n source: 'npm',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(plugin?.name ?? npmPackage),\n description: plugin?.description ?? installedPkg.description,\n });\n } catch (err) {\n // Plugin installed via npm but failed to load — register as disabled\n console.log(fail(`Failed to load ${npmPackage}: ${(err as Error).message}`));\n pluginRegistry.register(npmPackage, {\n version: 'unknown',\n source: 'npm',\n enabled: false,\n settingsPath: settingsManager.getSettingsPath(npmPackage),\n });\n }\n }\n }\n\n // Persist any community plugin registrations from the loop above\n await pluginRegistry.save();\n\n const { defaultAgent } = await setupAgents();\n\n // Offer Claude CLI integration\n await setupIntegrations();\n\n currentStep++;\n const workspace = await setupWorkspace({ stepNum: currentStep, totalSteps });\n\n let runMode: 'foreground' | 'daemon' = 'foreground';\n let autoStart = false;\n if (!opts?.skipRunMode) {\n currentStep++;\n const result = await setupRunMode({ stepNum: currentStep, totalSteps });\n runMode = result.runMode;\n autoStart = result.autoStart;\n }\n\n const security = {\n allowedUserIds: [] as string[],\n maxConcurrentSessions: 20,\n sessionTimeoutMinutes: 60,\n };\n\n const config: Config = {\n instanceName,\n channels: {},\n agents: {},\n defaultAgent,\n workspace,\n security,\n logging: {\n level: \"info\",\n logDir: \"~/.openacp/logs\",\n maxFileSize: \"10m\",\n maxFiles: 7,\n sessionLogRetentionDays: 30,\n },\n runMode,\n autoStart,\n api: {\n port: 21420,\n host: '127.0.0.1',\n },\n sessionStore: { ttlDays: 30 },\n tunnel: {\n enabled: true,\n port: 3100,\n provider: \"cloudflare\",\n options: {},\n maxUserTunnels: 5,\n storeTtlMinutes: 60,\n auth: { enabled: false },\n },\n usage: {\n enabled: true,\n warningThreshold: 0.8,\n currency: \"USD\",\n retentionDays: 90,\n },\n integrations: {},\n speech: {\n stt: { provider: null, providers: {} },\n tts: { provider: null, providers: {} },\n },\n agentSwitch: { labelHistory: true },\n };\n\n try {\n await configManager.writeNew(config);\n } catch (writeErr) {\n console.log(\n fail(`Could not save config: ${(writeErr as Error).message}`),\n );\n return false;\n }\n\n // Auto-register remaining built-in plugins in the registry\n if (settingsManager && pluginRegistry) {\n await registerBuiltinPlugins(settingsManager, pluginRegistry);\n await pluginRegistry.save();\n }\n\n // Register instance in the global registry\n const id = instanceRegistry.uniqueId(generateSlug(instanceName));\n instanceRegistry.register(id, instanceRoot);\n await instanceRegistry.save();\n\n clack.outro(`Config saved to ${configManager.getConfigPath()}`);\n\n if (!opts?.skipRunMode) {\n console.log(ok(\"Starting OpenACP...\"));\n console.log(\"\");\n }\n\n return true;\n } catch (err) {\n if ((err as Error).name === \"ExitPromptError\") {\n clack.cancel(\"Setup cancelled.\");\n return false;\n }\n throw err;\n }\n}\n\n/**\n * Register all built-in plugins that haven't been registered yet.\n * Called after first-run setup to populate the registry with defaults.\n */\nasync function registerBuiltinPlugins(\n settingsManager: SettingsManager,\n pluginRegistry: PluginRegistry,\n): Promise<void> {\n const builtinPlugins = [\n { name: '@openacp/security', version: '1.0.0', description: 'User access control and session limits' },\n { name: '@openacp/file-service', version: '1.0.0', description: 'File storage and management' },\n { name: '@openacp/context', version: '1.0.0', description: 'Conversation context management' },\n { name: '@openacp/speech', version: '1.0.0', description: 'Text-to-speech and speech-to-text' },\n { name: '@openacp/notifications', version: '1.0.0', description: 'Cross-session notification routing' },\n { name: '@openacp/tunnel', version: '1.0.0', description: 'Expose local services via tunnel' },\n { name: '@openacp/api-server', version: '1.0.0', description: 'REST API + SSE streaming server' },\n ];\n\n for (const p of builtinPlugins) {\n if (!pluginRegistry.get(p.name)) {\n pluginRegistry.register(p.name, {\n version: p.version,\n source: 'builtin',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(p.name),\n description: p.description,\n });\n }\n }\n}\n\n// ─── Inheritable keys for copy flow ───\n\nfunction buildInheritableKeysMap(): Record<string, string[]> {\n // Hardcoded for built-in plugins — community plugins declare their own\n return {\n '@openacp/tunnel': ['provider', 'maxUserTunnels', 'auth'],\n '@openacp/api-server': ['host'],\n '@openacp/security': ['allowedUsers', 'maxSessionsPerUser', 'rateLimits'],\n '@openacp/usage': ['budget'],\n '@openacp/speech': ['tts'],\n };\n}\n\n// ─── Reconfigure (section-based, for existing config) ───\n\ntype ReconfigureSection = OnboardSection | \"__continue\";\n\nasync function selectSection(hasSelection: boolean): Promise<ReconfigureSection> {\n return guardCancel(\n await clack.select({\n message: \"Select sections to configure\",\n options: [\n ...ONBOARD_SECTION_OPTIONS,\n {\n value: \"__continue\" as const,\n label: \"Continue\",\n hint: hasSelection ? \"Done\" : \"Skip for now\",\n },\n ],\n initialValue: ONBOARD_SECTION_OPTIONS[0].value,\n }),\n ) as ReconfigureSection;\n}\n\nexport async function runReconfigure(configManager: ConfigManager): Promise<void> {\n await printStartBanner();\n clack.intro(\"OpenACP — Reconfigure\");\n\n try {\n await configManager.load();\n let config = configManager.get();\n\n // Show current config summary\n clack.note(summarizeConfig(config), \"Current configuration\");\n\n let ranSection = false;\n\n while (true) {\n const choice = await selectSection(ranSection);\n if (choice === \"__continue\") break;\n ranSection = true;\n\n if (choice === \"channels\") {\n const result = await configureChannels(config);\n if (result.changed) {\n // IMPORTANT: Use writeNew() instead of save() because save() uses deepMerge\n // which cannot delete keys. Channel deletion (delete next.channels.telegram)\n // would be silently ignored by deepMerge. writeNew() overwrites the full config.\n config = { ...config, channels: result.config.channels };\n await configManager.writeNew(config);\n }\n }\n\n if (choice === \"agents\") {\n const { defaultAgent } = await setupAgents();\n await configManager.save({ defaultAgent });\n config = configManager.get();\n }\n\n if (choice === \"workspace\") {\n const { baseDir } = await setupWorkspace({\n existing: config.workspace.baseDir,\n });\n await configManager.save({ workspace: { baseDir } });\n config = configManager.get();\n }\n\n if (choice === \"runMode\") {\n const result = await setupRunMode({\n existing: { runMode: config.runMode, autoStart: config.autoStart },\n });\n await configManager.save({\n runMode: result.runMode,\n autoStart: result.autoStart,\n });\n config = configManager.get();\n }\n\n if (choice === \"integrations\") {\n await setupIntegrations(config);\n }\n }\n\n if (!ranSection) {\n clack.outro(\"No changes made.\");\n return;\n }\n\n clack.outro(`Config saved to ${configManager.getConfigPath()}`);\n } catch (err) {\n if ((err as Error).name === \"ExitPromptError\") {\n clack.cancel(\"Setup cancelled.\");\n return;\n }\n throw err;\n }\n}\n","// Public API — maintains backward compatibility with all existing imports from setup.ts\n\nexport { runSetup, runReconfigure } from \"./wizard.js\";\nexport { printStartBanner } from \"./helpers.js\";\n\n// Validation functions (re-exported from plugin locations for backward compat)\nexport {\n validateBotToken,\n validateChatId,\n validateBotAdmin,\n} from \"../../plugins/telegram/validators.js\";\n\n// Agent detection (used by tests)\nexport { detectAgents, validateAgentCommand } from \"./setup-agents.js\";\n\n// Setup functions — re-exported for backward compat (were public in old setup.ts)\nexport { setupAgents } from \"./setup-agents.js\";\nexport { setupWorkspace } from \"./setup-workspace.js\";\nexport { setupRunMode } from \"./setup-run-mode.js\";\n","export function nodeToWebWritable(nodeStream: NodeJS.WritableStream): WritableStream<Uint8Array> {\n return new WritableStream<Uint8Array>({\n write(chunk) {\n return new Promise<void>((resolve, reject) => {\n const ok = nodeStream.write(chunk);\n if (ok) { resolve(); return; }\n (nodeStream as any).once(\"drain\", resolve);\n (nodeStream as any).once(\"error\", reject);\n });\n },\n close() {\n (nodeStream as any).end();\n },\n abort(reason) {\n (nodeStream as any).destroy(reason instanceof Error ? reason : new Error(String(reason)));\n },\n });\n}\n\nexport function nodeToWebReadable(nodeStream: NodeJS.ReadableStream): ReadableStream<Uint8Array> {\n return new ReadableStream<Uint8Array>({\n start(controller) {\n nodeStream.on(\"data\", (chunk: Buffer) => controller.enqueue(new Uint8Array(chunk)));\n nodeStream.on(\"end\", () => controller.close());\n nodeStream.on(\"error\", (err) => controller.error(err));\n },\n cancel() {\n (nodeStream as any).destroy();\n },\n });\n}\n","export class StderrCapture {\n private lines: string[] = []\n\n constructor(private maxLines: number = 50) {}\n\n append(chunk: string): void {\n this.lines.push(...chunk.split('\\n').filter(Boolean))\n if (this.lines.length > this.maxLines) {\n this.lines = this.lines.slice(-this.maxLines)\n }\n }\n\n getLastLines(): string {\n return this.lines.join('\\n')\n }\n}\n","/**\n * A minimal, generic typed event emitter.\n *\n * Usage:\n * interface MyEvents {\n * data: (payload: string) => void\n * error: (err: Error) => void\n * }\n * const emitter = new TypedEmitter<MyEvents>()\n * emitter.on('data', (payload) => { ... })\n * emitter.emit('data', 'hello')\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class TypedEmitter<T extends Record<string & keyof T, (...args: any[]) => void>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private listeners = new Map<keyof T, Set<(...args: any[]) => void>>()\n private paused = false\n private buffer: Array<{ event: keyof T; args: unknown[] }> = []\n\n on<K extends keyof T>(event: K, listener: T[K]): this {\n let set = this.listeners.get(event)\n if (!set) {\n set = new Set()\n this.listeners.set(event, set)\n }\n set.add(listener)\n return this\n }\n\n off<K extends keyof T>(event: K, listener: T[K]): this {\n this.listeners.get(event)?.delete(listener)\n return this\n }\n\n emit<K extends keyof T>(event: K, ...args: Parameters<T[K]>): void {\n if (this.paused) {\n // Check passthrough filter — some events may bypass the pause\n if (this.passthroughFn?.(event, args)) {\n this.deliver(event, args)\n } else {\n this.buffer.push({ event, args })\n }\n return\n }\n this.deliver(event, args)\n }\n\n /**\n * Pause event delivery. Events emitted while paused are buffered.\n * Optionally pass a filter to allow specific events through even while paused.\n */\n pause(passthrough?: (event: keyof T, args: unknown[]) => boolean): void {\n this.paused = true\n this.passthroughFn = passthrough\n }\n private passthroughFn?: (event: keyof T, args: unknown[]) => boolean\n\n /** Resume event delivery and replay buffered events in order. */\n resume(): void {\n this.paused = false\n this.passthroughFn = undefined\n const buffered = this.buffer.splice(0)\n for (const { event, args } of buffered) {\n this.deliver(event, args)\n }\n }\n\n /** Discard all buffered events without delivering them. */\n clearBuffer(): void {\n this.buffer.length = 0\n }\n\n get isPaused(): boolean {\n return this.paused\n }\n\n get bufferSize(): number {\n return this.buffer.length\n }\n\n removeAllListeners(event?: keyof T): void {\n if (event) {\n this.listeners.delete(event)\n } else {\n this.listeners.clear()\n }\n }\n\n private deliver(event: keyof T, args: unknown[]): void {\n const set = this.listeners.get(event)\n if (!set) return\n for (const listener of set) {\n (listener as (...a: unknown[]) => void)(...args)\n }\n }\n}\n","import { spawn, type ChildProcess } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport type { MiddlewareChain } from \"../plugin/middleware-chain.js\";\n\ninterface TerminalState {\n process: ChildProcess;\n output: string;\n exitStatus: { exitCode: number | null; signal: string | null } | null;\n command: string;\n startTime: number;\n}\n\ninterface CreateTerminalParams {\n command: string;\n args?: string[] | Array<{ name: string; value: string }>;\n env?: Array<{ name: string; value: string }>;\n cwd?: string;\n outputByteLimit?: number;\n}\n\ninterface TerminalOutputResult {\n output: string;\n truncated: boolean;\n exitStatus?: { exitCode: number | null; signal: string | null };\n}\n\ninterface WaitForExitResult {\n exitCode: number | null;\n signal: string | null;\n}\n\nexport class TerminalManager {\n private terminals: Map<string, TerminalState> = new Map();\n private maxOutputBytes: number;\n\n constructor(maxOutputBytes = 1024 * 1024) {\n this.maxOutputBytes = maxOutputBytes;\n }\n\n async createTerminal(\n sessionId: string,\n params: CreateTerminalParams,\n middlewareChain?: MiddlewareChain,\n ): Promise<{ terminalId: string }> {\n let termCommand = params.command;\n let termArgs = params.args ?? [];\n let termEnvArr = params.env ?? [];\n let termCwd = params.cwd ?? undefined;\n\n if (middlewareChain) {\n const envRecord: Record<string, string> = {};\n for (const ev of termEnvArr) { envRecord[ev.name] = ev.value; }\n const result = await middlewareChain.execute('terminal:beforeCreate', {\n sessionId,\n command: termCommand,\n args: termArgs as string[],\n env: envRecord,\n cwd: termCwd,\n }, async (p) => p);\n if (!result) return { terminalId: \"\" }; // blocked by middleware\n termCommand = result.command;\n termArgs = result.args ?? termArgs;\n termCwd = result.cwd ?? termCwd;\n if (result.env) {\n termEnvArr = Object.entries(result.env).map(([name, value]) => ({ name, value }));\n }\n }\n\n const terminalId = randomUUID();\n const args = termArgs as string[];\n const env: Record<string, string> = {};\n for (const ev of termEnvArr) {\n env[ev.name] = ev.value;\n }\n\n const childProcess = spawn(termCommand, args, {\n cwd: termCwd,\n env: { ...process.env, ...env },\n shell: false,\n });\n\n const state: TerminalState = {\n process: childProcess,\n output: \"\",\n exitStatus: null,\n command: termCommand,\n startTime: Date.now(),\n };\n this.terminals.set(terminalId, state);\n\n const outputByteLimit = params.outputByteLimit ?? this.maxOutputBytes;\n\n const appendOutput = (chunk: string) => {\n state.output += chunk;\n const bytes = Buffer.byteLength(state.output, \"utf-8\");\n if (bytes > outputByteLimit) {\n const excess = bytes - outputByteLimit;\n state.output = state.output.slice(excess);\n }\n };\n\n childProcess.stdout?.on(\"data\", (chunk: Buffer) =>\n appendOutput(chunk.toString()),\n );\n childProcess.stderr?.on(\"data\", (chunk: Buffer) =>\n appendOutput(chunk.toString()),\n );\n\n childProcess.on(\"exit\", (code, signal) => {\n state.exitStatus = { exitCode: code, signal };\n if (middlewareChain) {\n middlewareChain.execute('terminal:afterExit', {\n sessionId,\n terminalId,\n command: state.command,\n exitCode: code ?? -1,\n durationMs: Date.now() - state.startTime,\n }, async (p) => p).catch(() => {});\n }\n });\n\n return { terminalId };\n }\n\n getOutput(terminalId: string): TerminalOutputResult {\n const state = this.terminals.get(terminalId);\n if (!state) {\n throw new Error(`Terminal not found: ${terminalId}`);\n }\n return {\n output: state.output,\n truncated: false,\n exitStatus: state.exitStatus\n ? {\n exitCode: state.exitStatus.exitCode,\n signal: state.exitStatus.signal,\n }\n : undefined,\n };\n }\n\n async waitForExit(terminalId: string): Promise<WaitForExitResult> {\n const state = this.terminals.get(terminalId);\n if (!state) {\n throw new Error(`Terminal not found: ${terminalId}`);\n }\n if (state.exitStatus !== null) {\n return {\n exitCode: state.exitStatus.exitCode,\n signal: state.exitStatus.signal,\n };\n }\n return new Promise((resolve) => {\n state.process.on(\"exit\", (code, signal) => {\n resolve({ exitCode: code, signal });\n });\n });\n }\n\n kill(terminalId: string): void {\n const state = this.terminals.get(terminalId);\n if (!state) {\n throw new Error(`Terminal not found: ${terminalId}`);\n }\n state.process.kill(\"SIGTERM\");\n }\n\n release(terminalId: string): void {\n const state = this.terminals.get(terminalId);\n if (!state) {\n return;\n }\n state.process.kill(\"SIGKILL\");\n this.terminals.delete(terminalId);\n }\n\n destroyAll(): void {\n for (const [, t] of this.terminals) {\n t.process.kill(\"SIGKILL\");\n }\n this.terminals.clear();\n }\n}\n","import type { McpServerConfig } from \"../types.js\";\n\n/**\n * Resolves MCP server configuration for agent sessions.\n * Centralizes the logic for providing MCP servers to newSession/resumeSession/loadSession/forkSession.\n */\nexport class McpManager {\n /**\n * Resolve the MCP server config to pass to ACP session methods.\n * Returns the provided config array or an empty array if none given.\n */\n resolve(sessionConfig?: McpServerConfig[]): McpServerConfig[] {\n return sessionConfig ?? [];\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\nexport type TraceLayer = \"acp\" | \"core\" | \"telegram\";\n\n// Evaluated once at module load — zero overhead when disabled\nconst DEBUG_ENABLED = process.env.OPENACP_DEBUG === \"true\" || process.env.OPENACP_DEBUG === \"1\";\n\n/**\n * Per-session debug trace logger. Writes JSONL files to <workingDirectory>/.log/.\n * Only active when OPENACP_DEBUG=true. Zero overhead when disabled.\n *\n * Note: Uses appendFileSync for simplicity. This blocks the event loop briefly per write,\n * which is acceptable for a debug-only tool. The DEBUG_ENABLED guard ensures zero overhead\n * in production.\n */\nexport class DebugTracer {\n private dirCreated = false;\n private logDir: string;\n\n constructor(\n private sessionId: string,\n private workingDirectory: string,\n ) {\n this.logDir = path.join(workingDirectory, \".log\");\n }\n\n log(layer: TraceLayer, data: Record<string, unknown>): void {\n try {\n if (!this.dirCreated) {\n fs.mkdirSync(this.logDir, { recursive: true });\n this.dirCreated = true;\n }\n const filePath = path.join(this.logDir, `${this.sessionId}_${layer}.jsonl`);\n const line = JSON.stringify({ ts: Date.now(), ...data }) + \"\\n\";\n fs.appendFileSync(filePath, line);\n } catch {\n // Debug logging must never crash the app\n }\n }\n\n /** No-op cleanup — establishes the pattern for future async implementations */\n destroy(): void {\n // No file handles to close with appendFileSync\n }\n}\n\n/**\n * Create a DebugTracer if debug mode is enabled, otherwise return null.\n * The DEBUG_ENABLED const is evaluated once at module load time from process.env.OPENACP_DEBUG.\n */\nexport function createDebugTracer(sessionId: string, workingDirectory: string): DebugTracer | null {\n if (!DEBUG_ENABLED) return null;\n return new DebugTracer(sessionId, workingDirectory);\n}\n","import { spawn, execFileSync, type ChildProcess } from \"node:child_process\";\nimport { Transform } from \"node:stream\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { ClientSideConnection, ndJsonStream } from \"@agentclientprotocol/sdk\";\nimport type {\n Agent,\n Client,\n PromptResponse,\n PermissionOption as SdkPermissionOption,\n} from \"@agentclientprotocol/sdk\";\nimport { nodeToWebWritable, nodeToWebReadable } from \"../utils/streams.js\";\nimport { StderrCapture } from \"../utils/stderr-capture.js\";\nimport { TypedEmitter } from \"../utils/typed-emitter.js\";\nimport type {\n AgentDefinition,\n AgentEvent,\n Attachment,\n ConfigOption,\n McpServerConfig,\n PermissionRequest,\n SetConfigOptionValue,\n} from \"../types.js\";\nimport { readTextFileWithRange } from \"../utils/read-text-file.js\";\nimport type { MiddlewareChain } from \"../plugin/middleware-chain.js\";\nimport { PROTOCOL_VERSION } from \"@agentclientprotocol/sdk\";\nimport { TerminalManager } from \"../sessions/terminal-manager.js\";\nimport { McpManager } from \"./mcp-manager.js\";\nimport type {\n ListSessionsResponse,\n LoadSessionResponse,\n ForkSessionResponse,\n SetSessionConfigOptionResponse,\n} from \"@agentclientprotocol/sdk\";\nimport { createDebugTracer, type DebugTracer } from \"../utils/debug-tracer.js\";\nimport { createChildLogger } from \"../utils/log.js\";\nconst log = createChildLogger({ module: \"agent-instance\" });\n\n/** Find the nearest ancestor directory containing package.json */\nfunction findPackageRoot(startDir: string): string {\n let dir = startDir;\n while (dir !== path.dirname(dir)) {\n if (fs.existsSync(path.join(dir, \"package.json\"))) {\n return dir;\n }\n dir = path.dirname(dir);\n }\n return startDir;\n}\n\n/** Resolve an agent command to a directly executable form (avoids shell wrappers) */\nfunction resolveAgentCommand(cmd: string): { command: string; args: string[] } {\n // Directories to search for node_modules: cwd AND the package's own directory\n const searchRoots = [process.cwd()];\n // Add the directory where this package is installed (for global installs)\n // Use findPackageRoot instead of hardcoded \"../..\" to handle both tsc (dist/core/)\n // and tsup bundle (dist/) directory structures correctly\n const ownDir = findPackageRoot(import.meta.dirname);\n if (ownDir !== process.cwd()) {\n searchRoots.push(ownDir);\n }\n\n // 1. Check node_modules for the package's actual JS entry point\n for (const root of searchRoots) {\n const packageDirs = [\n path.resolve(root, \"node_modules\", \"@zed-industries\", cmd, \"dist\", \"index.js\"),\n path.resolve(root, \"node_modules\", cmd, \"dist\", \"index.js\"),\n ];\n for (const jsPath of packageDirs) {\n if (fs.existsSync(jsPath)) {\n return { command: process.execPath, args: [jsPath] };\n }\n }\n }\n\n // 2. Check .bin — if it's a JS file with shebang, run with node directly\n for (const root of searchRoots) {\n const localBin = path.resolve(root, \"node_modules\", \".bin\", cmd);\n if (fs.existsSync(localBin)) {\n const content = fs.readFileSync(localBin, \"utf-8\");\n if (content.startsWith(\"#!/usr/bin/env node\")) {\n return { command: process.execPath, args: [localBin] };\n }\n // Shell wrapper — try to find the target JS file\n const match = content.match(/\"([^\"]+\\.js)\"/);\n if (match) {\n const target = path.resolve(path.dirname(localBin), match[1]);\n if (fs.existsSync(target)) {\n return { command: process.execPath, args: [target] };\n }\n }\n }\n }\n\n // 3. Try resolving from PATH using which\n try {\n const fullPath = execFileSync(\"which\", [cmd], { encoding: \"utf-8\" }).trim();\n if (fullPath) {\n const content = fs.readFileSync(fullPath, \"utf-8\");\n if (content.startsWith(\"#!/usr/bin/env node\")) {\n return { command: process.execPath, args: [fullPath] };\n }\n }\n } catch {\n // which failed\n }\n\n // 4. Fallback: use command as-is\n return { command: cmd, args: [] };\n}\n\n// TerminalState has been extracted to TerminalManager\n\n// Local types for ACP session update shapes not fully typed by SDK\ninterface SdkToolCallFields {\n rawInput?: unknown;\n rawOutput?: unknown;\n _meta?: Record<string, unknown>;\n}\n\ninterface SdkSessionInfoUpdate {\n sessionUpdate: 'session_info_update';\n title?: string | null;\n updatedAt?: string | null;\n _meta?: Record<string, unknown>;\n}\n\ninterface SdkCurrentModeUpdate {\n sessionUpdate: 'current_mode_update';\n currentModeId: string;\n _meta?: Record<string, unknown>;\n}\n\ninterface SdkConfigOptionUpdate {\n sessionUpdate: 'config_option_update';\n configOptions: unknown[];\n _meta?: Record<string, unknown>;\n}\n\ninterface SdkUserMessageChunk {\n sessionUpdate: 'user_message_chunk';\n content: { type: string; text?: string };\n}\n\ninterface SdkReadTextFileParams {\n path: string;\n line?: number;\n limit?: number;\n}\n\nexport interface AgentInstanceEvents {\n agent_event: (event: AgentEvent) => void;\n}\n\nexport class AgentInstance extends TypedEmitter<AgentInstanceEvents> {\n private connection!: ClientSideConnection;\n private child!: ChildProcess;\n private stderrCapture!: StderrCapture;\n private terminalManager = new TerminalManager();\n private static mcpManager = new McpManager();\n private _destroying = false;\n\n sessionId!: string;\n agentName: string;\n promptCapabilities?: { image?: boolean; audio?: boolean };\n middlewareChain?: MiddlewareChain;\n debugTracer: DebugTracer | null = null;\n\n // Callback — set by core when wiring events\n onPermissionRequest: (request: PermissionRequest) => Promise<string> =\n async () => \"\";\n\n private constructor(agentName: string) {\n super();\n this.agentName = agentName;\n }\n\n private static async spawnSubprocess(\n agentDef: AgentDefinition,\n workingDirectory: string,\n ): Promise<AgentInstance> {\n const instance = new AgentInstance(agentDef.name);\n const resolved = resolveAgentCommand(agentDef.command);\n log.debug(\n {\n agentName: agentDef.name,\n command: resolved.command,\n args: resolved.args,\n },\n \"Resolved agent command\",\n );\n\n instance.child = spawn(\n resolved.command,\n [...resolved.args, ...agentDef.args],\n {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n cwd: workingDirectory,\n env: { ...process.env, ...agentDef.env },\n },\n );\n\n await new Promise<void>((resolve, reject) => {\n instance.child.on(\"error\", (err) => {\n reject(\n new Error(\n `Failed to spawn agent \"${agentDef.name}\": ${err.message}. Is \"${agentDef.command}\" installed?`,\n ),\n );\n });\n instance.child.on(\"spawn\", () => resolve());\n });\n\n instance.stderrCapture = new StderrCapture(50);\n instance.child.stderr!.on(\"data\", (chunk: Buffer) => {\n instance.stderrCapture.append(chunk.toString());\n });\n\n const stdinLogger = new Transform({\n transform(chunk, _enc, cb) {\n if (instance.debugTracer) {\n const raw = chunk.toString().trimEnd();\n try {\n instance.debugTracer.log(\"acp\", { dir: \"send\", data: JSON.parse(raw) });\n } catch {\n instance.debugTracer.log(\"acp\", { dir: \"send\", data: raw });\n }\n }\n cb(null, chunk);\n },\n });\n stdinLogger.pipe(instance.child.stdin!);\n\n const stdoutLogger = new Transform({\n transform(chunk, _enc, cb) {\n if (instance.debugTracer) {\n const raw = chunk.toString().trimEnd();\n try {\n instance.debugTracer.log(\"acp\", { dir: \"recv\", data: JSON.parse(raw) });\n } catch {\n instance.debugTracer.log(\"acp\", { dir: \"recv\", data: raw });\n }\n }\n cb(null, chunk);\n },\n });\n instance.child.stdout!.pipe(stdoutLogger);\n\n const toAgent = nodeToWebWritable(stdinLogger);\n const fromAgent = nodeToWebReadable(stdoutLogger);\n const stream = ndJsonStream(toAgent, fromAgent);\n\n instance.connection = new ClientSideConnection(\n (_agent: Agent): Client => instance.createClient(_agent),\n stream,\n );\n\n const initResponse = await instance.connection.initialize({\n protocolVersion: PROTOCOL_VERSION,\n clientCapabilities: {\n fs: { readTextFile: true, writeTextFile: true },\n terminal: true,\n },\n });\n\n if (initResponse.protocolVersion !== PROTOCOL_VERSION) {\n log.warn(\n { expected: PROTOCOL_VERSION, got: initResponse.protocolVersion },\n \"ACP protocol version mismatch — some features may not work correctly\",\n );\n }\n\n instance.promptCapabilities =\n initResponse.agentCapabilities?.promptCapabilities;\n\n log.info(\n { promptCapabilities: instance.promptCapabilities ?? {} },\n \"Agent prompt capabilities\",\n );\n\n return instance;\n }\n\n private setupCrashDetection(): void {\n this.child.on(\"exit\", (code, signal) => {\n if (this._destroying) return;\n log.info(\n { sessionId: this.sessionId, exitCode: code, signal },\n \"Agent process exited\",\n );\n if ((code !== 0 && code !== null) || signal) {\n const stderr = this.stderrCapture.getLastLines();\n this.emit('agent_event', {\n type: \"error\",\n message: signal\n ? `Agent killed by signal ${signal}\\n${stderr}`\n : `Agent crashed (exit code ${code})\\n${stderr}`,\n });\n }\n });\n\n this.connection.closed.then(() => {\n log.debug({ sessionId: this.sessionId }, \"ACP connection closed\");\n });\n }\n\n static async spawn(\n agentDef: AgentDefinition,\n workingDirectory: string,\n mcpServers?: McpServerConfig[],\n ): Promise<AgentInstance> {\n log.debug(\n { agentName: agentDef.name, command: agentDef.command },\n \"Spawning agent\",\n );\n const spawnStart = Date.now();\n\n const instance = await AgentInstance.spawnSubprocess(\n agentDef,\n workingDirectory,\n );\n\n const resolvedMcp = AgentInstance.mcpManager.resolve(mcpServers);\n const response = await instance.connection.newSession({\n cwd: workingDirectory,\n mcpServers: resolvedMcp as any,\n });\n instance.sessionId = response.sessionId;\n instance.debugTracer = createDebugTracer(response.sessionId, workingDirectory);\n instance.setupCrashDetection();\n\n log.info(\n { sessionId: response.sessionId, durationMs: Date.now() - spawnStart },\n \"Agent spawn complete\",\n );\n return instance;\n }\n\n static async resume(\n agentDef: AgentDefinition,\n workingDirectory: string,\n agentSessionId: string,\n mcpServers?: McpServerConfig[],\n ): Promise<AgentInstance> {\n log.debug({ agentName: agentDef.name, agentSessionId }, \"Resuming agent\");\n const spawnStart = Date.now();\n\n const instance = await AgentInstance.spawnSubprocess(\n agentDef,\n workingDirectory,\n );\n\n try {\n const response = await instance.connection.unstable_resumeSession({\n sessionId: agentSessionId,\n cwd: workingDirectory,\n });\n instance.sessionId = response.sessionId;\n instance.debugTracer = createDebugTracer(response.sessionId, workingDirectory);\n log.info(\n { sessionId: response.sessionId, durationMs: Date.now() - spawnStart },\n \"Agent resume complete\",\n );\n } catch (err) {\n log.warn(\n { err, agentSessionId },\n \"Resume failed, falling back to new session\",\n );\n const resolvedMcp = AgentInstance.mcpManager.resolve(mcpServers);\n const response = await instance.connection.newSession({\n cwd: workingDirectory,\n mcpServers: resolvedMcp as any,\n });\n instance.sessionId = response.sessionId;\n instance.debugTracer = createDebugTracer(response.sessionId, workingDirectory);\n log.info(\n { sessionId: response.sessionId, durationMs: Date.now() - spawnStart },\n \"Agent fallback spawn complete\",\n );\n }\n\n instance.setupCrashDetection();\n return instance;\n }\n\n // createClient — implemented in Task 6b\n private createClient(_agent: Agent): Client {\n const self = this;\n const MAX_OUTPUT_BYTES = 1024 * 1024; // 1MB cap\n\n return {\n // ── Session updates ──────────────────────────────────────────────────\n async sessionUpdate(params) {\n const update = params.update;\n let event: AgentEvent | null = null;\n\n switch (update.sessionUpdate) {\n case \"agent_message_chunk\":\n if (update.content.type === \"text\") {\n event = { type: \"text\", content: update.content.text };\n } else if (update.content.type === \"image\") {\n // ACP SDK types don't expose data/mimeType fields for image content\n const c = update.content as unknown as { data: string; mimeType: string };\n event = { type: \"image_content\", data: c.data, mimeType: c.mimeType };\n } else if (update.content.type === \"audio\") {\n // ACP SDK types don't expose data/mimeType fields for audio content\n const c = update.content as unknown as { data: string; mimeType: string };\n event = { type: \"audio_content\", data: c.data, mimeType: c.mimeType };\n } else if (update.content.type === \"resource\") {\n // EmbeddedResource: content.resource is TextResourceContents or BlobResourceContents\n // TextResourceContents has { uri, text, mimeType? }\n // BlobResourceContents has { uri, blob, mimeType? }\n const c = update.content as unknown as {\n resource: { uri: string; text?: string; blob?: string; mimeType?: string };\n annotations?: { audience?: string[]; priority?: number };\n };\n // The EmbeddedResource content block doesn't carry a top-level name field —\n // use the uri as a fallback name since AgentEvent.resource_content requires one.\n event = {\n type: \"resource_content\",\n uri: c.resource.uri,\n name: c.resource.uri,\n text: c.resource.text ?? undefined,\n blob: c.resource.blob ?? undefined,\n mimeType: c.resource.mimeType ?? undefined,\n };\n } else if (update.content.type === \"resource_link\") {\n // ResourceLink: { uri, name, mimeType?, title?, description?, size? }\n const c = update.content as unknown as {\n uri: string;\n name: string;\n mimeType?: string | null;\n title?: string | null;\n description?: string | null;\n size?: number | null;\n };\n event = {\n type: \"resource_link\",\n uri: c.uri,\n name: c.name,\n mimeType: c.mimeType ?? undefined,\n title: c.title ?? undefined,\n description: c.description ?? undefined,\n size: c.size ?? undefined,\n };\n }\n break;\n case \"agent_thought_chunk\":\n if (update.content.type === \"text\") {\n event = { type: \"thought\", content: update.content.text };\n }\n break;\n case \"tool_call\": {\n const tc = update as unknown as SdkToolCallFields;\n event = {\n type: \"tool_call\",\n id: update.toolCallId,\n name: update.title,\n kind: update.kind ?? undefined,\n status: update.status ?? \"pending\",\n content: update.content ?? undefined,\n rawInput: tc.rawInput ?? undefined,\n rawOutput: tc.rawOutput ?? undefined,\n meta: tc._meta ?? undefined,\n };\n break;\n }\n case \"tool_call_update\": {\n const tcu = update as unknown as SdkToolCallFields;\n event = {\n type: \"tool_update\",\n id: update.toolCallId,\n name: update.title ?? undefined,\n kind: update.kind ?? undefined,\n status: update.status ?? \"pending\",\n content: update.content ?? undefined,\n rawInput: tcu.rawInput ?? undefined,\n rawOutput: tcu.rawOutput ?? undefined,\n meta: tcu._meta ?? undefined,\n };\n break;\n }\n case \"plan\":\n event = { type: \"plan\", entries: update.entries };\n break;\n case \"usage_update\":\n event = {\n type: \"usage\",\n tokensUsed: update.used,\n contextSize: update.size,\n cost: update.cost ?? undefined,\n };\n break;\n case \"available_commands_update\":\n event = {\n type: \"commands_update\",\n commands: update.availableCommands,\n };\n break;\n case \"session_info_update\": {\n const si = update as unknown as SdkSessionInfoUpdate;\n event = {\n type: \"session_info_update\",\n title: si.title ?? undefined,\n updatedAt: si.updatedAt ?? undefined,\n _meta: si._meta ?? undefined,\n };\n break;\n }\n case \"current_mode_update\": {\n const cm = update as unknown as SdkCurrentModeUpdate;\n event = {\n type: \"current_mode_update\",\n modeId: cm.currentModeId,\n };\n break;\n }\n case \"config_option_update\": {\n const co = update as unknown as SdkConfigOptionUpdate;\n event = {\n type: \"config_option_update\",\n options: (co.configOptions ?? []) as ConfigOption[],\n };\n break;\n }\n case \"user_message_chunk\": {\n const um = update as unknown as SdkUserMessageChunk;\n event = {\n type: \"user_message_chunk\",\n content: um.content?.text ?? \"\",\n };\n break;\n }\n // NOTE: model_update is NOT a session update type in the ACP SDK schema.\n // Model changes are applied via the unstable_setSessionModel() method and\n // the response is synchronous — the SDK does not push a model_update\n // notification to the client. Therefore AgentEvent \"model_update\" cannot\n // originate from sessionUpdate and must be emitted by callers of setModel()\n // if they need to propagate the change downstream.\n default:\n // Unknown update type — ignore\n return;\n }\n\n if (event !== null) {\n self.emit('agent_event', event);\n }\n },\n\n // ── Permission requests ──────────────────────────────────────────────\n async requestPermission(params) {\n const permissionRequest: PermissionRequest = {\n id: params.toolCall.toolCallId,\n description: params.toolCall.title ?? params.toolCall.toolCallId,\n options: params.options.map((opt: SdkPermissionOption) => ({\n id: opt.optionId,\n label: opt.name,\n isAllow: opt.kind === \"allow_once\" || opt.kind === \"allow_always\",\n })),\n };\n\n const selectedOptionId =\n await self.onPermissionRequest(permissionRequest);\n return {\n outcome: { outcome: \"selected\" as const, optionId: selectedOptionId },\n };\n },\n\n // ── File operations ──────────────────────────────────────────────────\n async readTextFile(params) {\n const p = params as unknown as SdkReadTextFileParams;\n // Hook: fs:beforeRead — modifiable, can block\n if (self.middlewareChain) {\n const result = await self.middlewareChain.execute('fs:beforeRead', { sessionId: self.sessionId, path: p.path, line: p.line, limit: p.limit }, async (r) => r);\n if (!result) return { content: \"\" }; // blocked by middleware\n p.path = result.path;\n }\n const content = await readTextFileWithRange(p.path, {\n line: p.line ?? undefined,\n limit: p.limit ?? undefined,\n });\n return { content };\n },\n\n async writeTextFile(params) {\n // Hook: fs:beforeWrite — modifiable, can block\n let writePath = params.path;\n let writeContent = params.content;\n if (self.middlewareChain) {\n const result = await self.middlewareChain.execute('fs:beforeWrite', { sessionId: self.sessionId, path: writePath, content: writeContent }, async (r) => r);\n if (!result) return {}; // blocked by middleware\n writePath = result.path;\n writeContent = result.content;\n }\n await fs.promises.mkdir(path.dirname(writePath), { recursive: true });\n await fs.promises.writeFile(writePath, writeContent, \"utf-8\");\n return {};\n },\n\n // ── Terminal operations (delegated to TerminalManager) ─────────────\n async createTerminal(params) {\n return self.terminalManager.createTerminal(\n self.sessionId,\n {\n command: params.command,\n args: params.args,\n env: params.env,\n cwd: params.cwd,\n outputByteLimit: params.outputByteLimit ?? MAX_OUTPUT_BYTES,\n },\n self.middlewareChain,\n );\n },\n\n async terminalOutput(params) {\n return self.terminalManager.getOutput(params.terminalId);\n },\n\n async waitForTerminalExit(params) {\n return self.terminalManager.waitForExit(params.terminalId);\n },\n\n async killTerminal(params) {\n self.terminalManager.kill(params.terminalId);\n return {};\n },\n\n async releaseTerminal(params) {\n self.terminalManager.release(params.terminalId);\n },\n };\n }\n\n // ── New ACP methods ──────────────────────────────────────────────────\n\n async setMode(modeId: string): Promise<void> {\n await this.connection.setSessionMode({ sessionId: this.sessionId, modeId });\n }\n\n async setConfigOption(\n configId: string,\n value: SetConfigOptionValue,\n ): Promise<SetSessionConfigOptionResponse> {\n return await this.connection.setSessionConfigOption({\n sessionId: this.sessionId,\n configId,\n ...value,\n } as any);\n }\n\n async setModel(modelId: string): Promise<void> {\n await this.connection.unstable_setSessionModel({\n sessionId: this.sessionId,\n modelId,\n });\n }\n\n async listSessions(\n cwd?: string,\n cursor?: string,\n ): Promise<ListSessionsResponse> {\n return await this.connection.listSessions({\n cwd: cwd ?? null,\n cursor: cursor ?? null,\n });\n }\n\n async loadSession(\n sessionId: string,\n cwd: string,\n mcpServers?: McpServerConfig[],\n ): Promise<LoadSessionResponse> {\n const resolvedMcp = AgentInstance.mcpManager.resolve(mcpServers);\n return await this.connection.loadSession({\n sessionId,\n cwd,\n mcpServers: resolvedMcp as any,\n });\n }\n\n async authenticate(methodId: string): Promise<void> {\n await this.connection.authenticate({ methodId });\n }\n\n async forkSession(\n sessionId: string,\n cwd: string,\n mcpServers?: McpServerConfig[],\n ): Promise<ForkSessionResponse> {\n const resolvedMcp = AgentInstance.mcpManager.resolve(mcpServers);\n return await this.connection.unstable_forkSession({\n sessionId,\n cwd,\n mcpServers: resolvedMcp as any,\n });\n }\n\n async closeSession(sessionId: string): Promise<void> {\n await this.connection.unstable_closeSession({ sessionId });\n }\n\n // ── Prompt & lifecycle ──────────────────────────────────────────────\n\n async prompt(text: string, attachments?: Attachment[]): Promise<PromptResponse> {\n const contentBlocks: Array<Record<string, unknown>> = [{ type: \"text\", text }];\n\n // MIME types supported by Claude API for base64 image content\n const SUPPORTED_IMAGE_MIMES = new Set([\"image/jpeg\", \"image/png\", \"image/gif\", \"image/webp\"]);\n\n for (const att of attachments ?? []) {\n const tooLarge = att.size > 10 * 1024 * 1024; // 10MB base64 guard\n\n if (att.type === \"image\" && this.promptCapabilities?.image && !tooLarge && SUPPORTED_IMAGE_MIMES.has(att.mimeType)) {\n const data = await fs.promises.readFile(att.filePath);\n contentBlocks.push({ type: \"image\", data: data.toString(\"base64\"), mimeType: att.mimeType });\n } else if (att.type === \"audio\" && this.promptCapabilities?.audio && !tooLarge) {\n const data = await fs.promises.readFile(att.filePath);\n contentBlocks.push({ type: \"audio\", data: data.toString(\"base64\"), mimeType: att.mimeType });\n } else {\n // Fallback: append file path to text so agent can read from disk\n if ((att.type === \"image\" || att.type === \"audio\") && !tooLarge) {\n log.debug(\n { type: att.type, capabilities: this.promptCapabilities ?? {} },\n \"Agent does not support %s content, falling back to file path\",\n att.type,\n );\n }\n (contentBlocks[0] as { text: string }).text += `\\n\\n[Attached file: ${att.filePath}]`;\n }\n }\n\n return this.connection.prompt({\n sessionId: this.sessionId,\n prompt: contentBlocks as any,\n });\n }\n\n async cancel(): Promise<void> {\n await this.connection.cancel({ sessionId: this.sessionId });\n }\n\n async destroy(): Promise<void> {\n this._destroying = true;\n\n // Cleanup terminals\n this.terminalManager.destroyAll();\n\n // If process already exited, nothing to do\n if (this.child.exitCode !== null) return;\n\n // Kill agent subprocess and wait for it to actually exit\n await new Promise<void>((resolve) => {\n // Register exit listener BEFORE sending signal to avoid race\n this.child.on(\"exit\", () => {\n clearTimeout(forceKillTimer);\n resolve();\n });\n\n this.child.kill(\"SIGTERM\");\n\n const forceKillTimer = setTimeout(() => {\n // Use exitCode check — child.killed is true after ANY kill() call\n if (this.child.exitCode === null) this.child.kill(\"SIGKILL\");\n resolve();\n }, 10_000);\n if (typeof forceKillTimer === 'object' && forceKillTimer !== null && 'unref' in forceKillTimer) {\n (forceKillTimer as NodeJS.Timeout).unref();\n }\n });\n }\n}\n","import type { AgentDefinition } from \"../types.js\";\nimport { AgentInstance } from \"./agent-instance.js\";\nimport type { AgentCatalog } from \"./agent-catalog.js\";\n\nexport class AgentManager {\n constructor(private catalog: AgentCatalog) {}\n\n getAvailableAgents(): AgentDefinition[] {\n const installed = this.catalog.getInstalledEntries();\n return Object.entries(installed).map(([key, agent]) => ({\n name: key,\n command: agent.command,\n args: agent.args,\n env: agent.env,\n }));\n }\n\n getAgent(name: string): AgentDefinition | undefined {\n return this.catalog.resolve(name);\n }\n\n async spawn(\n agentName: string,\n workingDirectory: string,\n ): Promise<AgentInstance> {\n const agentDef = this.getAgent(agentName);\n if (!agentDef) throw new Error(`Agent \"${agentName}\" is not installed. Run \"openacp agents install ${agentName}\" to add it.`);\n return AgentInstance.spawn(agentDef, workingDirectory);\n }\n\n async resume(\n agentName: string,\n workingDirectory: string,\n agentSessionId: string,\n ): Promise<AgentInstance> {\n const agentDef = this.getAgent(agentName);\n if (!agentDef) throw new Error(`Agent \"${agentName}\" is not installed. Run \"openacp agents install ${agentName}\" to add it.`);\n return AgentInstance.resume(agentDef, workingDirectory, agentSessionId);\n }\n}\n","import type { Attachment } from '../types.js'\n\n/**\n * Serial prompt queue — ensures prompts are processed one at a time.\n */\nexport class PromptQueue {\n private queue: Array<{ text: string; attachments?: Attachment[]; resolve: () => void }> = []\n private processing = false\n private abortController: AbortController | null = null\n\n constructor(\n private processor: (text: string, attachments?: Attachment[]) => Promise<void>,\n private onError?: (err: unknown) => void,\n ) {}\n\n async enqueue(text: string, attachments?: Attachment[]): Promise<void> {\n if (this.processing) {\n return new Promise<void>((resolve) => {\n this.queue.push({ text, attachments, resolve })\n })\n }\n await this.process(text, attachments)\n }\n\n private async process(text: string, attachments?: Attachment[]): Promise<void> {\n this.processing = true\n this.abortController = new AbortController()\n const { signal } = this.abortController\n try {\n await Promise.race([\n this.processor(text, attachments),\n new Promise<never>((_, reject) => {\n signal.addEventListener('abort', () => reject(new Error('Prompt aborted')), { once: true })\n }),\n ])\n } catch (err) {\n // Only forward non-abort errors to onError handler\n if (!(err instanceof Error && err.message === 'Prompt aborted')) {\n this.onError?.(err)\n }\n } finally {\n this.abortController = null\n this.processing = false\n this.drainNext()\n }\n }\n\n private drainNext(): void {\n const next = this.queue.shift()\n if (next) {\n this.process(next.text, next.attachments).then(next.resolve)\n }\n }\n\n clear(): void {\n // Abort the currently running prompt so the queue can drain\n if (this.abortController) {\n this.abortController.abort()\n }\n // Resolve pending promises so callers don't hang\n for (const item of this.queue) {\n item.resolve()\n }\n this.queue = []\n }\n\n get pending(): number {\n return this.queue.length\n }\n\n get isProcessing(): boolean {\n return this.processing\n }\n}\n","import type { PermissionRequest } from \"../types.js\";\n\nconst DEFAULT_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes\n\n/**\n * Encapsulates pending permission state with a typed Promise API.\n */\nexport class PermissionGate {\n private request?: PermissionRequest;\n private resolveFn?: (optionId: string) => void;\n private rejectFn?: (reason: Error) => void;\n private settled = false;\n private timeoutTimer?: ReturnType<typeof setTimeout>;\n private timeoutMs: number;\n\n constructor(timeoutMs?: number) {\n this.timeoutMs = timeoutMs ?? DEFAULT_TIMEOUT_MS;\n }\n\n setPending(request: PermissionRequest): Promise<string> {\n // Reject any existing pending promise so callers don't hang forever\n if (!this.settled && this.rejectFn) {\n this.rejectFn(new Error(\"Superseded by new permission request\"));\n }\n this.request = request;\n this.settled = false;\n this.clearTimeout();\n\n return new Promise<string>((resolve, reject) => {\n this.resolveFn = resolve;\n this.rejectFn = reject;\n\n this.timeoutTimer = setTimeout(() => {\n this.reject(\"Permission request timed out (no response received)\");\n }, this.timeoutMs);\n if (typeof this.timeoutTimer === 'object' && 'unref' in this.timeoutTimer) {\n (this.timeoutTimer as NodeJS.Timeout).unref();\n }\n });\n }\n\n resolve(optionId: string): void {\n if (this.settled || !this.resolveFn) return;\n this.settled = true;\n this.clearTimeout();\n this.resolveFn(optionId);\n this.cleanup();\n }\n\n reject(reason?: string): void {\n if (this.settled || !this.rejectFn) return;\n this.settled = true;\n this.clearTimeout();\n this.rejectFn(new Error(reason ?? \"Permission rejected\"));\n this.cleanup();\n }\n\n get isPending(): boolean {\n return !!this.request && !this.settled;\n }\n\n get currentRequest(): PermissionRequest | undefined {\n return this.isPending ? this.request : undefined;\n }\n\n /** The request ID of the current pending request, undefined after settlement */\n get requestId(): string | undefined {\n return this.request?.id;\n }\n\n private clearTimeout(): void {\n if (this.timeoutTimer) {\n clearTimeout(this.timeoutTimer);\n this.timeoutTimer = undefined;\n }\n }\n\n private cleanup(): void {\n this.request = undefined;\n this.resolveFn = undefined;\n this.rejectFn = undefined;\n }\n}\n","import { nanoid } from \"nanoid\";\nimport type { AgentInstance } from \"../agents/agent-instance.js\";\nimport type { AgentCapabilities, AgentEvent, AgentSwitchEntry, Attachment, PermissionRequest, SessionStatus, SessionMode, ConfigOption, ModelInfo, SessionModeState, SessionModelState } from \"../types.js\";\nimport { TypedEmitter } from \"../utils/typed-emitter.js\";\nimport { PromptQueue } from \"./prompt-queue.js\";\nimport { PermissionGate } from \"./permission-gate.js\";\nimport { createChildLogger, createSessionLogger, closeSessionLogger, type Logger } from \"../utils/log.js\";\nimport type { SpeechService } from \"../../plugins/speech/exports.js\";\nimport type { MiddlewareChain } from \"../plugin/middleware-chain.js\";\nimport * as fs from \"node:fs\";\nconst moduleLog = createChildLogger({ module: \"session\" });\n\n// TTS constants\nexport const TTS_PROMPT_INSTRUCTION = `\\n\\nAdditionally, include a [TTS]...[/TTS] block with a spoken-friendly summary of your response. Focus on key information, decisions the user needs to make, or actions required. The agent decides what to say and how long. Respond in the same language the user is using. This instruction applies to this message only.`;\nexport const TTS_BLOCK_REGEX = /\\[TTS\\]([\\s\\S]*?)\\[\\/TTS\\]/;\nexport const TTS_MAX_LENGTH = 5000;\nexport const TTS_TIMEOUT_MS = 30_000;\n\n// Valid state transitions: from → Set<to>\nconst VALID_TRANSITIONS: Record<SessionStatus, Set<SessionStatus>> = {\n initializing: new Set([\"active\", \"error\"]),\n active: new Set([\"error\", \"finished\", \"cancelled\"]),\n error: new Set([\"active\", \"cancelled\"]),\n cancelled: new Set([\"active\"]),\n finished: new Set(),\n};\n\nexport interface SessionEvents {\n agent_event: (event: AgentEvent) => void;\n permission_request: (request: PermissionRequest) => void;\n session_end: (reason: string) => void;\n status_change: (from: SessionStatus, to: SessionStatus) => void;\n named: (name: string) => void;\n error: (error: Error) => void;\n prompt_count_changed: (count: number) => void;\n}\n\nexport class Session extends TypedEmitter<SessionEvents> {\n id: string;\n channelId: string;\n threadId: string = \"\";\n agentName: string;\n workingDirectory: string;\n agentInstance: AgentInstance;\n agentSessionId: string = \"\";\n private _status: SessionStatus = \"initializing\";\n name?: string;\n createdAt: Date = new Date();\n voiceMode: \"off\" | \"next\" | \"on\" = \"off\";\n dangerousMode: boolean = false;\n currentMode?: string;\n availableModes: SessionMode[] = [];\n configOptions: ConfigOption[] = [];\n currentModel?: string;\n availableModels: ModelInfo[] = [];\n agentCapabilities?: AgentCapabilities;\n archiving: boolean = false;\n promptCount: number = 0;\n firstAgent: string;\n agentSwitchHistory: AgentSwitchEntry[] = [];\n log: Logger;\n middlewareChain?: MiddlewareChain;\n\n readonly permissionGate = new PermissionGate();\n private readonly queue: PromptQueue;\n private speechService?: SpeechService;\n private pendingContext: string | null = null;\n\n constructor(opts: {\n id?: string;\n channelId: string;\n agentName: string;\n workingDirectory: string;\n agentInstance: AgentInstance;\n speechService?: SpeechService;\n }) {\n super();\n this.id = opts.id || nanoid(12);\n this.channelId = opts.channelId;\n this.agentName = opts.agentName;\n this.firstAgent = opts.agentName;\n this.workingDirectory = opts.workingDirectory;\n this.agentInstance = opts.agentInstance;\n this.speechService = opts.speechService;\n this.log = createSessionLogger(this.id, moduleLog);\n this.log.info({ agentName: this.agentName }, \"Session created\");\n\n this.queue = new PromptQueue(\n (text, attachments) => this.processPrompt(text, attachments),\n (err) => {\n this.fail(\"Prompt execution failed\");\n this.log.error({ err }, \"Prompt execution failed\");\n },\n );\n }\n\n // --- State Machine ---\n\n get status(): SessionStatus {\n return this._status;\n }\n\n\n /** Transition to active — from initializing, error, or cancelled */\n activate(): void {\n this.transition(\"active\");\n }\n\n /** Transition to error — from initializing or active */\n fail(reason: string): void {\n this.transition(\"error\");\n this.emit(\"error\", new Error(reason));\n }\n\n /** Transition to finished — from active only. Emits session_end for backward compat. */\n finish(reason?: string): void {\n this.transition(\"finished\");\n this.emit(\"session_end\", reason ?? \"completed\");\n }\n\n /** Transition to cancelled — from active only (terminal session cancel) */\n markCancelled(): void {\n this.transition(\"cancelled\");\n }\n\n private transition(to: SessionStatus): void {\n const from = this._status;\n const allowed = VALID_TRANSITIONS[from];\n if (!allowed?.has(to)) {\n throw new Error(\n `Invalid session transition: ${from} → ${to}`,\n );\n }\n this._status = to;\n this.log.debug({ from, to }, \"Session status transition\");\n this.emit(\"status_change\", from, to);\n }\n\n /** Number of prompts waiting in queue */\n get queueDepth(): number {\n return this.queue.pending;\n }\n\n get promptRunning(): boolean {\n return this.queue.isProcessing;\n }\n\n // --- Context Injection ---\n\n setContext(markdown: string): void {\n this.pendingContext = markdown;\n }\n\n // --- Voice Mode ---\n\n setVoiceMode(mode: \"off\" | \"next\" | \"on\"): void {\n this.voiceMode = mode;\n this.log.info({ voiceMode: mode }, \"TTS mode changed\");\n }\n\n // --- Public API ---\n\n async enqueuePrompt(text: string, attachments?: Attachment[]): Promise<void> {\n // Hook: agent:beforePrompt — modifiable, can block\n if (this.middlewareChain) {\n const payload = { text, attachments, sessionId: this.id };\n const result = await this.middlewareChain.execute('agent:beforePrompt', payload, async (p) => p);\n if (!result) return; // blocked by middleware\n text = result.text;\n attachments = result.attachments;\n }\n await this.queue.enqueue(text, attachments);\n }\n\n private async processPrompt(text: string, attachments?: Attachment[]): Promise<void> {\n if (text === \"\\x00__warmup__\") {\n await this.runWarmup();\n return;\n }\n\n // Don't process prompts for finished sessions (queue may still drain)\n if (this._status === \"finished\") return;\n\n this.promptCount++;\n this.emit('prompt_count_changed', this.promptCount);\n\n if (this._status === \"initializing\" || this._status === \"cancelled\" || this._status === \"error\") {\n this.activate();\n }\n const promptStart = Date.now();\n this.log.debug(\"Prompt execution started\");\n\n // Context injection: prepend on first real prompt only\n const contextUsed = this.pendingContext;\n if (contextUsed) {\n text = `[CONVERSATION HISTORY - This is context from previous sessions, not current conversation]\\n\\n${contextUsed}\\n\\n[END CONVERSATION HISTORY]\\n\\n${text}`;\n this.log.debug(\"Context injected into prompt\");\n }\n\n // STT: transcribe audio attachments if agent doesn't support audio\n const processed = await this.maybeTranscribeAudio(text, attachments);\n\n // TTS: determine if TTS is active for this prompt\n const ttsActive =\n this.voiceMode !== \"off\" &&\n !!this.speechService?.isTTSAvailable();\n\n // TTS: inject prompt instruction\n if (ttsActive) {\n processed.text += TTS_PROMPT_INSTRUCTION;\n }\n\n // TTS: set up text accumulator before prompting\n let accumulatedText = \"\";\n const accumulatorListener = ttsActive\n ? (event: AgentEvent) => {\n if (event.type === \"text\") {\n accumulatedText += event.content;\n }\n }\n : null;\n\n if (accumulatorListener) {\n this.on(\"agent_event\", accumulatorListener);\n }\n\n // Hook: turn:start — read-only, fire-and-forget\n if (this.middlewareChain) {\n this.middlewareChain.execute('turn:start', { sessionId: this.id, promptText: processed.text, promptNumber: this.promptCount }, async (p) => p).catch(() => {});\n }\n\n let stopReason: string = 'end_turn';\n try {\n const response = await this.agentInstance.prompt(processed.text, processed.attachments);\n if (response && typeof response === 'object' && 'stopReason' in response) {\n stopReason = (response as { stopReason?: string }).stopReason ?? 'end_turn';\n }\n // Clear context only after successful prompt — if prompt fails, context is preserved for retry\n if (contextUsed) {\n this.pendingContext = null;\n }\n // Reset \"next\" voice mode only after successful prompt\n if (ttsActive && this.voiceMode === \"next\") {\n this.voiceMode = \"off\";\n }\n } finally {\n if (accumulatorListener) {\n this.off(\"agent_event\", accumulatorListener);\n }\n }\n\n // Hook: turn:end — read-only, fire-and-forget\n if (this.middlewareChain) {\n this.middlewareChain.execute('turn:end', { sessionId: this.id, stopReason: stopReason as import('../types.js').StopReason, durationMs: Date.now() - promptStart }, async (p) => p).catch(() => {});\n }\n\n this.log.info(\n { durationMs: Date.now() - promptStart },\n \"Prompt execution completed\",\n );\n\n // TTS: fire-and-forget post-response synthesis\n if (ttsActive && accumulatedText) {\n this.processTTSResponse(accumulatedText).catch((err) => {\n this.log.warn({ err }, \"TTS post-processing failed\");\n });\n }\n\n if (!this.name) {\n await this.autoName();\n }\n }\n\n private async maybeTranscribeAudio(\n text: string,\n attachments?: Attachment[],\n ): Promise<{ text: string; attachments?: Attachment[] }> {\n if (!attachments?.length || !this.speechService) {\n return { text, attachments };\n }\n\n const hasAudioCapability = this.agentInstance.promptCapabilities?.audio === true;\n if (hasAudioCapability) {\n return { text, attachments };\n }\n\n if (!this.speechService.isSTTAvailable()) {\n return { text, attachments };\n }\n\n let transcribedText = text;\n const remainingAttachments: Attachment[] = [];\n\n for (const att of attachments) {\n if (att.type !== \"audio\") {\n remainingAttachments.push(att);\n continue;\n }\n\n try {\n const audioPath = att.originalFilePath || att.filePath;\n const audioMime = att.originalFilePath ? \"audio/ogg\" : att.mimeType;\n const audioBuffer = await fs.promises.readFile(audioPath);\n const result = await this.speechService.transcribe(audioBuffer, audioMime);\n this.log.info({ provider: \"stt\", duration: result.duration }, \"Voice transcribed\");\n // Notify user of transcription result\n this.emit(\"agent_event\", {\n type: \"system_message\",\n message: `🎤 You said: ${result.text}`,\n });\n // Strip [Audio: ...] placeholder since we have the transcription\n transcribedText = transcribedText.replace(/\\[Audio:\\s*[^\\]]*\\]\\s*/g, \"\").trim();\n transcribedText = transcribedText\n ? `${transcribedText}\\n${result.text}`\n : result.text;\n } catch (err) {\n this.log.warn({ err }, \"STT transcription failed, keeping audio attachment\");\n this.emit(\"agent_event\", {\n type: \"error\",\n message: `Voice transcription failed: ${(err as Error).message}`,\n });\n remainingAttachments.push(att);\n }\n }\n\n return {\n text: transcribedText,\n attachments: remainingAttachments.length > 0 ? remainingAttachments : undefined,\n };\n }\n\n private async processTTSResponse(responseText: string): Promise<void> {\n const match = TTS_BLOCK_REGEX.exec(responseText);\n if (!match?.[1]) {\n this.log.debug(\"No [TTS] block found in response, skipping synthesis\");\n return;\n }\n\n let ttsText = match[1].trim();\n if (!ttsText) return;\n\n if (ttsText.length > TTS_MAX_LENGTH) {\n ttsText = ttsText.slice(0, TTS_MAX_LENGTH);\n }\n\n try {\n let ttsTimer: ReturnType<typeof setTimeout>;\n const timeoutPromise = new Promise<never>((_, reject) => {\n ttsTimer = setTimeout(() => reject(new Error(\"TTS synthesis timed out\")), TTS_TIMEOUT_MS);\n });\n try {\n const result = await Promise.race([\n this.speechService!.synthesize(ttsText),\n timeoutPromise,\n ]);\n const base64 = result.audioBuffer.toString(\"base64\");\n this.emit(\"agent_event\", {\n type: \"audio_content\",\n data: base64,\n mimeType: result.mimeType,\n });\n this.emit(\"agent_event\", { type: \"tts_strip\" });\n this.log.info(\"TTS synthesis completed\");\n } finally {\n clearTimeout(ttsTimer!);\n }\n } catch (err) {\n this.log.warn({ err }, \"TTS synthesis failed, skipping\");\n }\n }\n\n // NOTE: This injects a summary prompt into the agent's conversation history.\n private async autoName(): Promise<void> {\n let title = \"\";\n\n // Temporarily remove all agent_event listeners so auto-name output\n // is not forwarded to the adapter. Add a capture-only listener instead.\n const captureHandler = (event: AgentEvent) => {\n if (event.type === \"text\") title += event.content;\n // Swallow all other events from auto-name prompt\n };\n\n // Pause the session emitter so agent_event emissions from SessionBridge\n // don't reach the adapter during auto-name. The AgentInstance emitter\n // stays active — we just intercept with our capture handler.\n this.pause((event) => event !== \"agent_event\");\n this.agentInstance.on(\"agent_event\", captureHandler);\n\n try {\n await this.agentInstance.prompt(\n \"Summarize this conversation in max 5 words for a topic title. Reply ONLY with the title, nothing else.\",\n );\n this.name = title.trim().slice(0, 50) || `Session ${this.id.slice(0, 6)}`;\n this.log.info({ name: this.name }, \"Session auto-named\");\n\n // Emit named event — SessionBridge listens to rename the thread\n this.emit(\"named\", this.name);\n } catch {\n this.name = `Session ${this.id.slice(0, 6)}`;\n } finally {\n this.agentInstance.off(\"agent_event\", captureHandler);\n // Discard buffered auto-name agent_events, then resume normal delivery\n this.clearBuffer();\n this.resume();\n }\n }\n\n /** Fire-and-forget warm-up: primes model cache while user types their first message */\n async warmup(): Promise<void> {\n // Route through PromptQueue to prevent concurrent prompt execution.\n // Any user prompts arriving during warmup will be queued and drained after.\n await this.queue.enqueue(\"\\x00__warmup__\");\n }\n\n private async runWarmup(): Promise<void> {\n // Pause events but let commands_update pass through\n this.pause((_event, args) => {\n const agentEvent = args[0] as AgentEvent;\n return agentEvent?.type === \"commands_update\";\n });\n\n try {\n const start = Date.now();\n await this.agentInstance.prompt('Reply with only \"ready\".');\n this.activate();\n this.log.info({ durationMs: Date.now() - start }, \"Warm-up complete\");\n } catch (err) {\n this.log.error({ err }, \"Warm-up failed\");\n } finally {\n this.clearBuffer();\n this.resume();\n }\n }\n\n // --- ACP Mode / Config / Model State ---\n\n setInitialAcpState(state: {\n modes?: SessionModeState | null;\n configOptions?: ConfigOption[] | null;\n models?: SessionModelState | null;\n agentCapabilities?: AgentCapabilities | null;\n }): void {\n if (state.modes) {\n this.currentMode = state.modes.currentModeId;\n this.availableModes = state.modes.availableModes;\n }\n if (state.configOptions) {\n this.configOptions = state.configOptions;\n }\n if (state.models) {\n this.currentModel = state.models.currentModelId;\n this.availableModels = state.models.availableModels;\n }\n if (state.agentCapabilities) {\n this.agentCapabilities = state.agentCapabilities;\n }\n }\n\n /** Set session name explicitly and emit 'named' event */\n setName(name: string): void {\n this.name = name;\n this.emit(\"named\", name);\n }\n\n async updateMode(modeId: string): Promise<void> {\n // Hook: mode:beforeChange — await-able, can block\n if (this.middlewareChain) {\n const result = await this.middlewareChain.execute('mode:beforeChange', { sessionId: this.id, fromMode: this.currentMode, toMode: modeId }, async (p) => p);\n if (!result) return; // blocked by middleware\n }\n this.currentMode = modeId;\n }\n\n async updateConfigOptions(options: ConfigOption[]): Promise<void> {\n // Hook: config:beforeChange — await-able, can block\n if (this.middlewareChain) {\n const result = await this.middlewareChain.execute('config:beforeChange', { sessionId: this.id, configId: 'options', oldValue: this.configOptions, newValue: options }, async (p) => p);\n if (!result) return; // blocked by middleware\n }\n this.configOptions = options;\n }\n\n async updateModel(modelId: string): Promise<void> {\n // Hook: model:beforeChange — await-able, can block\n if (this.middlewareChain) {\n const result = await this.middlewareChain.execute('model:beforeChange', { sessionId: this.id, fromModel: this.currentModel, toModel: modelId }, async (p) => p);\n if (!result) return; // blocked by middleware\n }\n this.currentModel = modelId;\n }\n\n /** Cancel the current prompt and clear the queue. Stays in active state. */\n async abortPrompt(): Promise<void> {\n // Hook: agent:beforeCancel — modifiable, can block\n if (this.middlewareChain) {\n const result = await this.middlewareChain.execute('agent:beforeCancel', { sessionId: this.id }, async (p) => p);\n if (!result) return; // blocked by middleware\n }\n this.queue.clear();\n this.log.info(\"Prompt aborted\");\n await this.agentInstance.cancel();\n }\n\n /** Search backward through agentSwitchHistory for the last entry matching agentName */\n findLastSwitchEntry(agentName: string): AgentSwitchEntry | undefined {\n for (let i = this.agentSwitchHistory.length - 1; i >= 0; i--) {\n if (this.agentSwitchHistory[i].agentName === agentName) {\n return this.agentSwitchHistory[i];\n }\n }\n return undefined;\n }\n\n /** Switch the agent instance in-place, preserving session identity */\n async switchAgent(agentName: string, createAgent: () => Promise<AgentInstance>): Promise<void> {\n if (agentName === this.agentName) {\n throw new Error(`Already using ${agentName}`);\n }\n\n // Record current agent in history\n this.agentSwitchHistory.push({\n agentName: this.agentName,\n agentSessionId: this.agentSessionId,\n switchedAt: new Date().toISOString(),\n promptCount: this.promptCount,\n });\n\n // Clear queued prompts and abort in-flight prompt before destroying old agent\n this.queue.clear();\n\n // Reject any pending permission request before destroying old agent\n if (this.permissionGate.isPending) {\n this.permissionGate.reject(\"Agent switched\");\n }\n\n // Destroy old agent\n await this.agentInstance.destroy();\n\n // Create and wire new agent\n const newAgent = await createAgent();\n this.agentInstance = newAgent;\n this.agentName = agentName;\n this.agentSessionId = newAgent.sessionId;\n this.promptCount = 0;\n\n // Reset agent-specific ACP state (will be re-populated by new agent)\n this.agentCapabilities = undefined;\n this.currentMode = undefined;\n this.availableModes = [];\n this.currentModel = undefined;\n this.availableModels = [];\n this.configOptions = [];\n\n this.log.info({ from: this.agentSwitchHistory.at(-1)!.agentName, to: agentName }, \"Agent switched\");\n }\n\n async destroy(): Promise<void> {\n this.log.info(\"Session destroyed\");\n // Reject any pending permission promise so callers don't hang\n if (this.permissionGate.isPending) {\n this.permissionGate.reject(\"Session destroyed\");\n }\n // Clear queued prompts\n this.queue.clear();\n await this.agentInstance.destroy();\n closeSessionLogger(this.log);\n }\n}\n","import type { AgentManager } from \"../agents/agent-manager.js\";\nimport { Session } from \"./session.js\";\nimport type { SessionStore } from \"./session-store.js\";\nimport type { EventBus } from \"../event-bus.js\";\nimport type { MiddlewareChain } from \"../plugin/middleware-chain.js\";\n\nexport class SessionManager {\n private sessions: Map<string, Session> = new Map();\n private store: SessionStore | null;\n private eventBus?: EventBus;\n middlewareChain?: MiddlewareChain;\n\n setEventBus(eventBus: EventBus): void {\n this.eventBus = eventBus;\n }\n\n constructor(store: SessionStore | null = null) {\n this.store = store;\n }\n\n async createSession(\n channelId: string,\n agentName: string,\n workingDirectory: string,\n agentManager: AgentManager,\n ): Promise<Session> {\n const agentInstance = await agentManager.spawn(agentName, workingDirectory);\n const session = new Session({\n channelId,\n agentName,\n workingDirectory,\n agentInstance,\n });\n this.sessions.set(session.id, session);\n session.agentSessionId = session.agentInstance.sessionId;\n\n if (this.store) {\n await this.store.save({\n sessionId: session.id,\n agentSessionId: session.agentInstance.sessionId,\n agentName: session.agentName,\n workingDir: session.workingDirectory,\n channelId,\n status: session.status,\n createdAt: session.createdAt.toISOString(),\n lastActiveAt: new Date().toISOString(),\n name: session.name,\n dangerousMode: false,\n platform: {},\n });\n }\n\n return session;\n }\n\n getSession(sessionId: string): Session | undefined {\n return this.sessions.get(sessionId);\n }\n\n getSessionByThread(channelId: string, threadId: string): Session | undefined {\n for (const session of this.sessions.values()) {\n if (session.channelId === channelId && session.threadId === threadId) {\n return session;\n }\n }\n return undefined;\n }\n\n getSessionByAgentSessionId(agentSessionId: string): Session | undefined {\n for (const session of this.sessions.values()) {\n if (session.agentSessionId === agentSessionId) {\n return session;\n }\n }\n return undefined;\n }\n\n getRecordByAgentSessionId(\n agentSessionId: string,\n ): import(\"../types.js\").SessionRecord | undefined {\n return this.store?.findByAgentSessionId(agentSessionId);\n }\n\n getRecordByThread(\n channelId: string,\n threadId: string,\n ): import(\"../types.js\").SessionRecord | undefined {\n return this.store?.findByPlatform(\n channelId,\n (p) => String(p.topicId) === threadId || p.threadId === threadId,\n );\n }\n\n registerSession(session: Session): void {\n this.sessions.set(session.id, session);\n }\n\n async patchRecord(\n sessionId: string,\n patch: Partial<import(\"../types.js\").SessionRecord>,\n ): Promise<void> {\n if (!this.store) return;\n const record = this.store.get(sessionId);\n if (record) {\n await this.store.save({ ...record, ...patch });\n } else if (patch.sessionId) {\n // Initial save — treat patch as full record\n await this.store.save(patch as import(\"../types.js\").SessionRecord);\n }\n }\n\n getSessionRecord(\n sessionId: string,\n ): import(\"../types.js\").SessionRecord | undefined {\n return this.store?.get(sessionId);\n }\n\n async cancelSession(sessionId: string): Promise<void> {\n const session = this.sessions.get(sessionId);\n if (session) {\n try {\n await session.abortPrompt();\n } catch {\n // Agent may already be dead — continue with cleanup\n }\n session.markCancelled();\n this.sessions.delete(sessionId);\n }\n if (this.store) {\n const record = this.store.get(sessionId);\n if (record && record.status !== \"cancelled\") {\n await this.store.save({ ...record, status: \"cancelled\" });\n }\n }\n // Hook: session:afterDestroy — read-only, fire-and-forget\n if (this.middlewareChain) {\n this.middlewareChain.execute('session:afterDestroy', { sessionId }, async (p) => p).catch(() => {});\n }\n }\n\n listSessions(channelId?: string): Session[] {\n const all = Array.from(this.sessions.values());\n if (channelId) return all.filter((s) => s.channelId === channelId);\n return all;\n }\n\n listRecords(filter?: {\n statuses?: string[];\n }): import(\"../types.js\").SessionRecord[] {\n if (!this.store) return [];\n let records = this.store.list();\n if (filter?.statuses?.length) {\n records = records.filter((r) => filter.statuses!.includes(r.status));\n }\n return records;\n }\n\n async removeRecord(sessionId: string): Promise<void> {\n if (!this.store) return;\n await this.store.remove(sessionId);\n this.eventBus?.emit(\"session:deleted\", { sessionId });\n }\n\n /**\n * Graceful shutdown: persist session state without killing agent subprocesses.\n * Agent processes will exit naturally when the parent process terminates.\n */\n async shutdownAll(): Promise<void> {\n if (this.store) {\n for (const session of this.sessions.values()) {\n const record = this.store.get(session.id);\n if (record) {\n await this.store.save({ ...record, status: \"finished\" });\n }\n }\n }\n this.sessions.clear();\n }\n\n /**\n * Forcefully destroy all sessions (kill agent subprocesses).\n * Use only when sessions must be fully torn down (e.g. archive).\n */\n async destroyAll(): Promise<void> {\n if (this.store) {\n for (const session of this.sessions.values()) {\n const record = this.store.get(session.id);\n if (record) {\n await this.store.save({ ...record, status: \"finished\" });\n }\n }\n }\n const sessionIds = [...this.sessions.keys()];\n for (const session of this.sessions.values()) {\n await session.destroy();\n }\n this.sessions.clear();\n // Hook: session:afterDestroy — read-only, fire-and-forget\n if (this.middlewareChain) {\n for (const sessionId of sessionIds) {\n this.middlewareChain.execute('session:afterDestroy', { sessionId }, async (p) => p).catch(() => {});\n }\n }\n }\n}\n","import type { Session } from \"./session.js\";\nimport type { IChannelAdapter } from \"../channel.js\";\nimport type { MessageTransformer } from \"../message-transformer.js\";\nimport type { NotificationManager } from \"../../plugins/notifications/notification.js\";\nimport type { SessionManager } from \"./session-manager.js\";\nimport type { AgentEvent, PermissionRequest, SessionStatus } from \"../types.js\";\nimport type { EventBus } from \"../event-bus.js\";\nimport type { FileServiceInterface } from \"../plugin/types.js\";\nimport type { MiddlewareChain } from \"../plugin/middleware-chain.js\";\nimport type { DebugTracer } from \"../utils/debug-tracer.js\";\nimport { createChildLogger } from \"../utils/log.js\";\n\nconst log = createChildLogger({ module: \"session-bridge\" });\n\nexport interface BridgeDeps {\n messageTransformer: MessageTransformer;\n notificationManager: NotificationManager;\n sessionManager: SessionManager;\n eventBus?: EventBus;\n fileService?: FileServiceInterface;\n middlewareChain?: MiddlewareChain;\n}\n\nexport class SessionBridge {\n private connected = false;\n private agentEventHandler?: (event: AgentEvent) => void;\n private sessionEventHandler?: (event: AgentEvent) => void;\n private statusChangeHandler?: (\n from: SessionStatus,\n to: SessionStatus,\n ) => void;\n private namedHandler?: (name: string) => void;\n private promptCountHandler?: (count: number) => void;\n\n constructor(\n private session: Session,\n private adapter: IChannelAdapter,\n private deps: BridgeDeps,\n ) {}\n\n private get tracer(): DebugTracer | null {\n return this.session.agentInstance.debugTracer ?? null;\n }\n\n /** Send message to adapter, optionally running through message:outgoing middleware */\n private async sendMessage(sessionId: string, message: ReturnType<MessageTransformer[\"transform\"]>): Promise<void> {\n try {\n const mw = this.deps.middlewareChain;\n if (mw) {\n const result = await mw.execute('message:outgoing', { sessionId, message }, async (m) => m);\n this.tracer?.log(\"core\", { step: \"middleware:outgoing\", sessionId, hook: \"message:outgoing\", blocked: !result });\n if (!result) return;\n this.tracer?.log(\"core\", { step: \"dispatch\", sessionId, message: result.message });\n this.adapter.sendMessage(sessionId, result.message).catch((err) => {\n log.error({ err, sessionId }, \"Failed to send message to adapter\");\n });\n } else {\n this.tracer?.log(\"core\", { step: \"dispatch\", sessionId, message });\n this.adapter.sendMessage(sessionId, message).catch((err) => {\n log.error({ err, sessionId }, \"Failed to send message to adapter\");\n });\n }\n } catch (err) {\n log.error({ err, sessionId }, \"Error in sendMessage middleware\");\n }\n }\n\n connect(): void {\n if (this.connected) return;\n this.connected = true;\n\n this.wireAgentToSession();\n this.wireSessionToAdapter();\n this.wirePermissions();\n this.wireLifecycle();\n }\n\n disconnect(): void {\n if (!this.connected) return;\n this.connected = false;\n\n if (this.agentEventHandler) {\n this.session.agentInstance.off(\"agent_event\", this.agentEventHandler);\n }\n if (this.sessionEventHandler) {\n this.session.off(\"agent_event\", this.sessionEventHandler);\n }\n if (this.statusChangeHandler) {\n this.session.off(\"status_change\", this.statusChangeHandler);\n }\n if (this.namedHandler) {\n this.session.off(\"named\", this.namedHandler);\n }\n if (this.promptCountHandler) {\n this.session.off(\"prompt_count_changed\", this.promptCountHandler);\n }\n\n // Reset agent callbacks to no-op\n this.session.agentInstance.onPermissionRequest = async () => \"\";\n }\n\n private wireAgentToSession(): void {\n this.agentEventHandler = (event: AgentEvent) => {\n this.session.emit(\"agent_event\", event);\n };\n this.session.agentInstance.on(\"agent_event\", this.agentEventHandler);\n }\n\n private wireSessionToAdapter(): void {\n this.sessionEventHandler = (event: AgentEvent) => {\n this.tracer?.log(\"core\", { step: \"agent_event\", sessionId: this.session.id, event });\n // Hook: agent:beforeEvent — modifiable, can block\n const mw = this.deps.middlewareChain;\n if (mw) {\n mw.execute('agent:beforeEvent', { sessionId: this.session.id, event }, async (e) => e).then((result) => {\n this.tracer?.log(\"core\", { step: \"middleware:before\", sessionId: this.session.id, hook: \"agent:beforeEvent\", blocked: !result });\n if (!result) return; // blocked by middleware\n try {\n const transformedEvent = result.event;\n const outgoing = this.handleAgentEvent(transformedEvent);\n // Hook: agent:afterEvent — read-only, fire-and-forget\n mw.execute('agent:afterEvent', {\n sessionId: this.session.id,\n event: transformedEvent,\n outgoingMessage: outgoing ?? { type: 'text' as const, text: '' },\n }, async (e) => e).catch(() => {});\n } catch (err) {\n log.error({ err, sessionId: this.session.id }, \"Error handling agent event after middleware\");\n }\n }).catch(() => {\n // Middleware error — proceed with original event\n try {\n this.handleAgentEvent(event);\n } catch (err) {\n log.error({ err, sessionId: this.session.id }, \"Error handling agent event (middleware fallback)\");\n }\n });\n } else {\n try {\n this.handleAgentEvent(event);\n } catch (err) {\n log.error({ err, sessionId: this.session.id }, \"Error handling agent event\");\n }\n }\n };\n\n this.session.on(\"agent_event\", this.sessionEventHandler);\n }\n\n private handleAgentEvent(event: AgentEvent): import('../types.js').OutgoingMessage | undefined {\n const session = this.session;\n const ctx = {\n get id() {\n return session.id;\n },\n get workingDirectory() {\n return session.workingDirectory;\n },\n };\n\n let outgoing: import('../types.js').OutgoingMessage | undefined;\n\n switch (event.type) {\n case \"text\":\n case \"thought\":\n case \"tool_call\":\n case \"tool_update\":\n case \"plan\":\n case \"usage\":\n outgoing = this.deps.messageTransformer.transform(event, ctx);\n this.tracer?.log(\"core\", { step: \"transform\", sessionId: this.session.id, input: event, output: outgoing });\n this.sendMessage(this.session.id, outgoing);\n break;\n\n case \"session_end\":\n this.session.finish(event.reason);\n this.adapter.cleanupSkillCommands?.(this.session.id);\n outgoing = this.deps.messageTransformer.transform(event);\n this.sendMessage(this.session.id, outgoing);\n this.deps.notificationManager.notify(this.session.channelId, {\n sessionId: this.session.id,\n sessionName: this.session.name,\n type: \"completed\",\n summary: `Session \"${this.session.name || this.session.id}\" completed\\n⏱ ${Math.round((Date.now() - this.session.createdAt.getTime()) / 60000)} min · 💬 ${this.session.promptCount} prompts`,\n });\n break;\n\n case \"error\":\n this.session.fail(event.message);\n this.adapter.cleanupSkillCommands?.(this.session.id);\n outgoing = this.deps.messageTransformer.transform(event);\n this.sendMessage(this.session.id, outgoing);\n this.deps.notificationManager.notify(this.session.channelId, {\n sessionId: this.session.id,\n sessionName: this.session.name,\n type: \"error\",\n summary: event.message,\n });\n break;\n\n case \"image_content\": {\n if (this.deps.fileService) {\n const fs = this.deps.fileService;\n const sid = this.session.id;\n const { data, mimeType } = event;\n const buffer = Buffer.from(data, \"base64\");\n const ext = fs.extensionFromMime(mimeType);\n fs.saveFile(sid, `agent-image${ext}`, buffer, mimeType)\n .then((att) => {\n this.sendMessage(sid, {\n type: \"attachment\",\n text: \"\",\n attachment: att,\n });\n })\n .catch((err) => log.error({ err }, \"Failed to save agent image\"));\n }\n break;\n }\n case \"audio_content\": {\n if (this.deps.fileService) {\n const fs = this.deps.fileService;\n const sid = this.session.id;\n const { data, mimeType } = event;\n const buffer = Buffer.from(data, \"base64\");\n const ext = fs.extensionFromMime(mimeType);\n fs.saveFile(sid, `agent-audio${ext}`, buffer, mimeType)\n .then((att) => {\n this.sendMessage(sid, {\n type: \"attachment\",\n text: \"\",\n attachment: att,\n });\n })\n .catch((err) => log.error({ err }, \"Failed to save agent audio\"));\n }\n break;\n }\n\n case \"commands_update\":\n log.debug({ commands: event.commands }, \"Commands available\");\n this.adapter.sendSkillCommands?.(this.session.id, event.commands);\n break;\n\n case \"system_message\":\n outgoing = this.deps.messageTransformer.transform(event);\n this.sendMessage(this.session.id, outgoing);\n break;\n\n case \"session_info_update\":\n if (event.title) {\n this.session.setName(event.title);\n }\n outgoing = this.deps.messageTransformer.transform(event);\n this.sendMessage(this.session.id, outgoing);\n break;\n\n case \"current_mode_update\":\n this.session.updateMode(event.modeId);\n outgoing = this.deps.messageTransformer.transform(event);\n this.sendMessage(this.session.id, outgoing);\n break;\n\n case \"config_option_update\":\n this.session.updateConfigOptions(event.options);\n outgoing = this.deps.messageTransformer.transform(event);\n this.sendMessage(this.session.id, outgoing);\n break;\n\n case \"model_update\":\n this.session.updateModel(event.modelId);\n outgoing = this.deps.messageTransformer.transform(event);\n this.sendMessage(this.session.id, outgoing);\n break;\n\n case \"user_message_chunk\":\n outgoing = this.deps.messageTransformer.transform(event);\n this.sendMessage(this.session.id, outgoing);\n break;\n\n case \"resource_content\":\n case \"resource_link\":\n outgoing = this.deps.messageTransformer.transform(event);\n this.sendMessage(this.session.id, outgoing);\n break;\n\n case \"tts_strip\":\n this.adapter.stripTTSBlock?.(this.session.id);\n break;\n }\n\n this.deps.eventBus?.emit(\"agent:event\", {\n sessionId: this.session.id,\n event,\n });\n\n return outgoing;\n }\n\n private wirePermissions(): void {\n const mw = this.deps.middlewareChain;\n\n this.session.agentInstance.onPermissionRequest = async (\n request: PermissionRequest,\n ) => {\n const startTime = Date.now();\n\n // Hook: permission:beforeRequest — modifiable, can block or autoResolve\n let permReq = request;\n if (mw) {\n const payload = { sessionId: this.session.id, request, autoResolve: undefined as string | undefined };\n const result = await mw.execute('permission:beforeRequest', payload, async (r) => r);\n if (!result) return \"\"; // blocked by middleware\n permReq = result.request;\n // I4: If middleware set autoResolve, skip UI and return directly\n if (result.autoResolve) {\n if (mw) {\n mw.execute('permission:afterResolve', {\n sessionId: this.session.id, requestId: permReq.id, decision: result.autoResolve, userId: 'middleware', durationMs: Date.now() - startTime,\n }, async (p) => p).catch(() => {});\n }\n return result.autoResolve;\n }\n }\n\n this.session.emit(\"permission_request\", permReq);\n this.deps.eventBus?.emit(\"permission:request\", {\n sessionId: this.session.id,\n permission: permReq,\n });\n\n // Auto-approve openacp CLI commands\n if (permReq.description.toLowerCase().includes(\"openacp\")) {\n const allowOption = permReq.options.find((o) => o.isAllow);\n if (allowOption) {\n log.info(\n { sessionId: this.session.id, requestId: permReq.id },\n \"Auto-approving openacp command\",\n );\n // Hook: permission:afterResolve — read-only, fire-and-forget\n if (mw) {\n mw.execute('permission:afterResolve', {\n sessionId: this.session.id, requestId: permReq.id, decision: allowOption.id, userId: 'system', durationMs: Date.now() - startTime,\n }, async (p) => p).catch(() => {});\n }\n return allowOption.id;\n }\n }\n\n // Dangerous mode: auto-approve all permissions\n if (this.session.dangerousMode) {\n const allowOption = permReq.options.find((o) => o.isAllow);\n if (allowOption) {\n log.info(\n { sessionId: this.session.id, requestId: permReq.id, optionId: allowOption.id },\n \"Dangerous mode: auto-approving permission\",\n );\n // Hook: permission:afterResolve — read-only, fire-and-forget\n if (mw) {\n mw.execute('permission:afterResolve', {\n sessionId: this.session.id, requestId: permReq.id, decision: allowOption.id, userId: 'system', durationMs: Date.now() - startTime,\n }, async (p) => p).catch(() => {});\n }\n return allowOption.id;\n }\n }\n\n // Set pending BEFORE sending UI to avoid race condition\n const promise = this.session.permissionGate.setPending(permReq);\n\n // Send permission UI to session topic\n await this.adapter.sendPermissionRequest(this.session.id, permReq);\n\n // Wait for user response — adapter resolves this promise\n const optionId = await promise;\n\n // Hook: permission:afterResolve — read-only, fire-and-forget\n if (mw) {\n mw.execute('permission:afterResolve', {\n sessionId: this.session.id, requestId: permReq.id, decision: optionId, userId: 'user', durationMs: Date.now() - startTime,\n }, async (p) => p).catch(() => {});\n }\n\n return optionId;\n };\n }\n\n private wireLifecycle(): void {\n // Persist status changes and auto-disconnect on terminal states\n this.statusChangeHandler = (from: SessionStatus, to: SessionStatus) => {\n this.deps.sessionManager.patchRecord(this.session.id, {\n status: to,\n lastActiveAt: new Date().toISOString(),\n });\n this.deps.eventBus?.emit(\"session:updated\", {\n sessionId: this.session.id,\n status: to,\n });\n\n // Auto-disconnect on terminal states (finished only — cancelled sessions can resume)\n if (to === \"finished\") {\n // Disconnect on next tick so current event handlers can complete\n queueMicrotask(() => this.disconnect());\n }\n };\n this.session.on(\"status_change\", this.statusChangeHandler);\n\n // Persist and relay name changes\n this.namedHandler = (name: string) => {\n this.deps.sessionManager.patchRecord(this.session.id, { name });\n this.deps.eventBus?.emit(\"session:updated\", {\n sessionId: this.session.id,\n name,\n });\n this.adapter.renameSessionThread(this.session.id, name);\n };\n this.session.on(\"named\", this.namedHandler);\n\n // Persist prompt count after each prompt for resume decisions\n this.promptCountHandler = (count: number) => {\n this.deps.sessionManager.patchRecord(this.session.id, { currentPromptCount: count });\n };\n this.session.on(\"prompt_count_changed\", this.promptCountHandler);\n }\n}\n","export interface FileInfo {\n filePath: string\n content: string\n oldContent?: string\n}\n\n/**\n * Extract file path and content from ACP tool_call/tool_update content.\n *\n * ACP content formats observed:\n * - Diff block: [{ type: \"diff\", path: \"...\", oldText: \"...\", newText: \"...\" }]\n * - Content wrapper: [{ type: \"content\", content: { type: \"text\", text: \"...\" } }]\n * - Text block: { type: \"text\", text: \"...\" }\n * - rawInput: { file_path: \"...\", content: \"...\" }\n */\nexport function extractFileInfo(\n name: string,\n kind: string | undefined,\n content: unknown,\n rawInput?: unknown,\n meta?: unknown,\n): FileInfo | null {\n // Only process file-related tool kinds\n if (kind && !['read', 'edit', 'write'].includes(kind)) return null\n\n let info: Partial<FileInfo> | null = null\n\n // 1. Try agent-specific _meta extensions (e.g. _meta.claudeCode.toolResponse)\n // This is the highest-fidelity source — raw file content without formatting.\n // Falls through to generic paths 2-3 for agents that don't use this namespace.\n if (meta) {\n const m = meta as Record<string, unknown>\n const toolResponse = resolveToolResponse(m)\n\n if (toolResponse) {\n // Read: toolResponse.file.filePath + file.content\n const file = toolResponse.file as Record<string, unknown> | undefined\n if (typeof file?.filePath === 'string' && typeof file?.content === 'string') {\n info = { filePath: file.filePath, content: file.content }\n }\n // Edit: toolResponse.originalFile (full before-edit content) + oldString/newString\n if (!info && typeof toolResponse.filePath === 'string' && typeof toolResponse.originalFile === 'string') {\n const originalFile = toolResponse.originalFile as string\n const oldString = typeof toolResponse.oldString === 'string' ? toolResponse.oldString : undefined\n const newString = typeof toolResponse.newString === 'string' ? toolResponse.newString : undefined\n const newContent = oldString && newString\n ? originalFile.replace(oldString, newString)\n : originalFile\n info = { filePath: toolResponse.filePath as string, content: newContent, oldContent: originalFile }\n }\n // Write: toolResponse.filePath + toolResponse.content\n if (!info && typeof toolResponse.filePath === 'string' && typeof toolResponse.content === 'string') {\n info = { filePath: toolResponse.filePath, content: toolResponse.content }\n }\n }\n }\n\n // 2. Try rawInput for file path + content\n if (!info && rawInput && typeof rawInput === 'object') {\n const ri = rawInput as Record<string, unknown>\n const filePath = ri?.file_path || ri?.filePath || ri?.path\n if (typeof filePath === 'string') {\n const parsed = content ? parseContent(content) : null\n const riContent = typeof ri?.content === 'string' ? ri.content : undefined\n\n if (kind === 'edit') {\n // Edit tool: use old_string/new_string from rawInput for diff viewer\n const oldStr = typeof ri.old_string === 'string' ? ri.old_string : typeof ri.oldText === 'string' ? ri.oldText : undefined\n const newStr = typeof ri.new_string === 'string' ? ri.new_string : typeof ri.newText === 'string' ? ri.newText : undefined\n if (newStr) {\n info = { filePath, content: newStr, oldContent: oldStr }\n } else {\n // Fallback to riContent, then parsed content (e.g. ACP diff blocks)\n info = { filePath, content: riContent || parsed?.content, oldContent: parsed?.oldContent }\n }\n } else if (kind === 'write') {\n // Write tool: prefer rawInput.content (the actual file content) over tool result message\n info = { filePath, content: riContent || parsed?.content, oldContent: parsed?.oldContent }\n } else {\n // Read and other kinds: tool_update content IS the file content\n info = { filePath, content: parsed?.content || riContent, oldContent: parsed?.oldContent }\n }\n }\n }\n\n // 3. Try to extract from known ACP content patterns\n if (!info && content) {\n info = parseContent(content)\n }\n\n if (!info) return null\n\n // Infer file path from tool name if not in content\n if (!info.filePath) {\n const pathMatch = name.match(/(?:Read|Edit|Write|View)\\s+(.+)/i)\n if (pathMatch) info.filePath = pathMatch[1].trim()\n }\n\n if (!info.filePath || !info.content) return null\n return info as FileInfo\n}\n\n/**\n * Resolve toolResponse from agent-specific _meta namespaces.\n * Supports: _meta.claudeCode.toolResponse (Claude Code)\n * Add new agents here as they adopt the pattern.\n */\nfunction resolveToolResponse(meta: Record<string, unknown>): Record<string, unknown> | undefined {\n // Claude Code namespace\n const claudeCode = meta.claudeCode as Record<string, unknown> | undefined\n if (claudeCode?.toolResponse && typeof claudeCode.toolResponse === 'object') {\n return claudeCode.toolResponse as Record<string, unknown>\n }\n // Generic: _meta.toolResponse (for agents that put it directly)\n if (meta.toolResponse && typeof meta.toolResponse === 'object') {\n return meta.toolResponse as Record<string, unknown>\n }\n return undefined\n}\n\nfunction parseContent(content: unknown): Partial<FileInfo> | null {\n if (typeof content === 'string') {\n return { content }\n }\n\n if (Array.isArray(content)) {\n // Array of content blocks — try each\n for (const block of content) {\n const result = parseContent(block)\n if (result?.content || result?.filePath) return result\n }\n return null\n }\n\n if (typeof content === 'object' && content !== null) {\n const c = content as Record<string, unknown>\n\n // ACP diff block: { type: 'diff', path: '...', oldText: '...', newText: '...' }\n if (c.type === 'diff' && typeof c.path === 'string') {\n const newText = c.newText as string | null | undefined\n const oldText = c.oldText as string | null | undefined\n if (newText) {\n return {\n filePath: c.path as string,\n content: newText,\n oldContent: oldText ?? undefined,\n }\n }\n }\n\n // ACP content wrapper: { type: 'content', content: { type: 'text', text: '...' } }\n if (c.type === 'content' && c.content) {\n return parseContent(c.content)\n }\n\n // ACP text block: { type: 'text', text: '...' }\n if (c.type === 'text' && typeof c.text === 'string') {\n return { content: c.text, filePath: c.filePath as string | undefined }\n }\n\n // Direct fields\n if (typeof c.text === 'string') {\n return { content: c.text, filePath: c.filePath as string | undefined }\n }\n\n // Tool input with file path: { file_path: '...', content: '...' }\n if (typeof c.file_path === 'string' || typeof c.filePath === 'string' || typeof c.path === 'string') {\n const filePath = (c.file_path || c.filePath || c.path) as string\n const fileContent = (c.content || c.text || c.output || c.newText) as string | undefined\n if (typeof fileContent === 'string') {\n return {\n filePath,\n content: fileContent,\n oldContent: (c.old_content || c.oldText) as string | undefined,\n }\n }\n }\n\n // Nested input/output\n if (c.input) {\n const result = parseContent(c.input)\n if (result) return result\n }\n if (c.output) {\n const result = parseContent(c.output)\n if (result) return result\n }\n }\n\n return null\n}\n","import type { AgentEvent, OutgoingMessage } from \"./types.js\";\nimport type { TunnelServiceInterface } from \"./plugin/types.js\";\nimport { extractFileInfo } from \"./utils/extract-file-info.js\";\nimport { createChildLogger } from \"./utils/log.js\";\n\nconst log = createChildLogger({ module: \"message-transformer\" });\n\n/**\n * Compute actual line-level diff by stripping common prefix/suffix lines.\n * This avoids counting unchanged context lines as added/removed.\n */\nfunction computeLineDiff(oldStr: string, newStr: string): { added: number; removed: number } {\n const oldLines = oldStr ? oldStr.split(\"\\n\") : [];\n const newLines = newStr ? newStr.split(\"\\n\") : [];\n\n // Find common prefix\n let prefixLen = 0;\n const minLen = Math.min(oldLines.length, newLines.length);\n while (prefixLen < minLen && oldLines[prefixLen] === newLines[prefixLen]) {\n prefixLen++;\n }\n\n // Find common suffix (not overlapping with prefix)\n let suffixLen = 0;\n const maxSuffix = minLen - prefixLen;\n while (\n suffixLen < maxSuffix &&\n oldLines[oldLines.length - 1 - suffixLen] === newLines[newLines.length - 1 - suffixLen]\n ) {\n suffixLen++;\n }\n\n return {\n added: Math.max(0, newLines.length - prefixLen - suffixLen),\n removed: Math.max(0, oldLines.length - prefixLen - suffixLen),\n };\n}\n\nexport class MessageTransformer {\n tunnelService?: TunnelServiceInterface;\n /** Cache rawInput from tool_call so it's available in tool_update (which often lacks it) */\n private toolRawInputCache: Map<string, unknown> = new Map();\n /** Cache viewer links generated from intermediate updates so completion events carry them */\n private toolViewerCache: Map<string, { viewerLinks: Record<string, string>; viewerFilePath: string }> = new Map();\n\n constructor(tunnelService?: TunnelServiceInterface) {\n this.tunnelService = tunnelService;\n }\n\n transform(\n event: AgentEvent,\n sessionContext?: { id: string; workingDirectory: string },\n ): OutgoingMessage {\n switch (event.type) {\n case \"text\":\n return { type: \"text\", text: event.content };\n case \"thought\":\n return { type: \"thought\", text: event.content };\n case \"tool_call\": {\n // Cache rawInput (only if non-empty) for later tool_update events\n if (event.id && this.isNonEmptyInput(event.rawInput)) {\n this.toolRawInputCache.set(event.id, event.rawInput);\n }\n const meta = event.meta as Record<string, unknown> | undefined;\n const metadata: Record<string, unknown> = {\n id: event.id,\n name: event.name,\n kind: event.kind,\n status: event.status,\n content: event.content,\n locations: event.locations,\n rawInput: event.rawInput,\n displaySummary: meta?.displaySummary,\n displayTitle: meta?.displayTitle,\n displayKind: meta?.displayKind,\n };\n this.enrichWithViewerLinks(event, metadata, sessionContext);\n return { type: \"tool_call\", text: event.name, metadata };\n }\n case \"tool_update\": {\n // Update cache if this update carries non-empty rawInput (some agents send it on first update)\n if (event.id && this.isNonEmptyInput(event.rawInput)) {\n this.toolRawInputCache.set(event.id, event.rawInput);\n }\n // Merge cached rawInput when tool_update doesn't carry it\n const cachedRawInput = event.id ? this.toolRawInputCache.get(event.id) : undefined;\n const effectiveRawInput = this.isNonEmptyInput(event.rawInput) ? event.rawInput : cachedRawInput;\n // Clean up cache on terminal status\n if (event.id && (event.status === \"completed\" || event.status === \"done\" || event.status === \"failed\" || event.status === \"error\")) {\n this.toolRawInputCache.delete(event.id);\n }\n const meta = event.meta as Record<string, unknown> | undefined;\n const metadata: Record<string, unknown> = {\n id: event.id,\n name: event.name,\n kind: event.kind,\n status: event.status,\n content: event.content,\n rawInput: effectiveRawInput,\n displaySummary: meta?.displaySummary,\n displayTitle: meta?.displayTitle,\n displayKind: meta?.displayKind,\n };\n // Use a synthetic event with merged rawInput for enrichWithViewerLinks\n const enrichEvent = { ...event, rawInput: effectiveRawInput };\n this.enrichWithViewerLinks(enrichEvent as typeof event, metadata, sessionContext);\n // Viewer link caching: intermediate updates have raw content (preferred),\n // completion events have formatted content (with line numbers) — always prefer cached\n if (event.id) {\n const cached = this.toolViewerCache.get(event.id);\n if (cached) {\n // Cache already has links from intermediate update (raw content) — always use those\n metadata.viewerLinks = cached.viewerLinks;\n metadata.viewerFilePath = cached.viewerFilePath;\n } else if (metadata.viewerLinks) {\n // First time generating links — cache them\n this.toolViewerCache.set(event.id, {\n viewerLinks: metadata.viewerLinks as Record<string, string>,\n viewerFilePath: metadata.viewerFilePath as string,\n });\n }\n // Clean up viewer cache on terminal status\n if (event.status === \"completed\" || event.status === \"done\" || event.status === \"failed\" || event.status === \"error\") {\n this.toolViewerCache.delete(event.id);\n }\n }\n return { type: \"tool_update\", text: \"\", metadata };\n }\n case \"plan\":\n return {\n type: \"plan\",\n text: \"\",\n metadata: { entries: event.entries },\n };\n case \"usage\":\n return {\n type: \"usage\",\n text: \"\",\n metadata: {\n tokensUsed: event.tokensUsed,\n contextSize: event.contextSize,\n cost: event.cost?.amount,\n },\n };\n case \"session_end\":\n return { type: \"session_end\", text: `Done (${event.reason})` };\n case \"error\":\n return { type: \"error\", text: event.message };\n case \"system_message\":\n return { type: \"system_message\", text: event.message };\n case \"session_info_update\":\n return {\n type: \"system_message\",\n text: `Session updated: ${event.title ?? \"\"}`.trim(),\n metadata: { title: event.title, updatedAt: event.updatedAt },\n };\n case \"current_mode_update\":\n return {\n type: \"mode_change\",\n text: `Mode: ${event.modeId}`,\n metadata: { modeId: event.modeId },\n };\n case \"config_option_update\":\n return {\n type: \"config_update\",\n text: \"Config updated\",\n metadata: { options: event.options },\n };\n case \"model_update\":\n return {\n type: \"model_update\",\n text: `Model: ${event.modelId}`,\n metadata: { modelId: event.modelId },\n };\n case \"user_message_chunk\":\n return {\n type: \"user_replay\",\n text: event.content,\n };\n case \"resource_content\":\n return {\n type: \"resource\",\n text: event.name,\n metadata: { uri: event.uri, text: event.text, blob: event.blob, mimeType: event.mimeType },\n };\n case \"resource_link\":\n return {\n type: \"resource_link\",\n text: event.name,\n metadata: { uri: event.uri, mimeType: event.mimeType, title: event.title, description: event.description, size: event.size },\n };\n default:\n return { type: \"text\", text: \"\" };\n }\n }\n\n /** Check if rawInput is a non-empty object (not null, not {}) */\n private isNonEmptyInput(input: unknown): input is Record<string, unknown> {\n return input !== null && input !== undefined && typeof input === \"object\" && !Array.isArray(input) && Object.keys(input as object).length > 0;\n }\n\n private enrichWithViewerLinks(\n event: AgentEvent & { type: \"tool_call\" | \"tool_update\" },\n metadata: Record<string, unknown>,\n sessionContext?: { id: string; workingDirectory: string },\n ): void {\n // Compute diffStats from rawInput even without tunnelService\n const kind = \"kind\" in event ? event.kind : undefined;\n if (!metadata.diffStats && (kind === \"edit\" || kind === \"write\")) {\n const ri = event.rawInput as Record<string, unknown> | undefined;\n if (ri) {\n const oldStr = typeof ri.old_string === \"string\" ? ri.old_string : typeof ri.oldText === \"string\" ? ri.oldText : null;\n const newStr = typeof ri.new_string === \"string\" ? ri.new_string : typeof ri.newText === \"string\" ? ri.newText : typeof ri.content === \"string\" ? ri.content : null;\n if (oldStr !== null && newStr !== null) {\n const stats = computeLineDiff(oldStr, newStr);\n if (stats.added > 0 || stats.removed > 0) {\n metadata.diffStats = stats;\n }\n } else if (oldStr === null && newStr !== null && kind === \"write\") {\n // New file creation — no old content, count all new lines as added\n const added = newStr.split(\"\\n\").length;\n if (added > 0) metadata.diffStats = { added, removed: 0 };\n }\n }\n }\n\n if (!this.tunnelService || !sessionContext) {\n log.debug(\n { hasTunnel: !!this.tunnelService, hasCtx: !!sessionContext, kind },\n \"enrichWithViewerLinks: skipping (no tunnel or session context)\",\n );\n return;\n }\n\n const name = \"name\" in event ? event.name || \"\" : \"\";\n\n log.debug(\n { name, kind, status: event.status, hasContent: !!event.content, hasRawInput: !!event.rawInput },\n \"enrichWithViewerLinks: inspecting event\",\n );\n\n const fileInfo = extractFileInfo(\n name,\n kind,\n event.content,\n event.rawInput,\n event.meta,\n );\n if (!fileInfo) {\n log.debug(\n { name, kind, hasContent: !!event.content, hasRawInput: !!event.rawInput, hasMeta: !!event.meta },\n \"enrichWithViewerLinks: extractFileInfo returned null\",\n );\n return;\n }\n\n // Skip viewer link generation if the tunnel only has a localhost URL —\n // Telegram strips <a href=\"localhost:...\"> tags, rendering plain unclickable text.\n const publicUrl = this.tunnelService.getPublicUrl();\n if (publicUrl.startsWith(\"http://localhost\") || publicUrl.startsWith(\"http://127.0.0.1\")) {\n log.debug({ kind, filePath: fileInfo.filePath }, \"enrichWithViewerLinks: skipping (no public tunnel URL)\");\n return;\n }\n\n log.info(\n {\n name,\n kind,\n filePath: fileInfo.filePath,\n hasOldContent: !!fileInfo.oldContent,\n },\n \"enrichWithViewerLinks: extracted file info\",\n );\n\n const store = this.tunnelService.getStore();\n const viewerLinks: Record<string, string> = {};\n\n // For edits/writes with diff data (oldText + newText)\n if (fileInfo.oldContent) {\n const id = store.storeDiff(\n sessionContext.id,\n fileInfo.filePath,\n fileInfo.oldContent,\n fileInfo.content,\n sessionContext.workingDirectory,\n );\n if (id) viewerLinks.diff = this.tunnelService.diffUrl(id);\n\n // Compute diff stats from full file content only if not already set from rawInput\n if (!metadata.diffStats) {\n const stats = computeLineDiff(fileInfo.oldContent, fileInfo.content);\n if (stats.added > 0 || stats.removed > 0) {\n metadata.diffStats = stats;\n }\n }\n }\n\n // Always store as file view (new file creation or read)\n const id = store.storeFile(\n sessionContext.id,\n fileInfo.filePath,\n fileInfo.content,\n sessionContext.workingDirectory,\n );\n if (id) viewerLinks.file = this.tunnelService.fileUrl(id);\n\n if (Object.keys(viewerLinks).length > 0) {\n metadata.viewerLinks = viewerLinks;\n metadata.viewerFilePath = fileInfo.filePath;\n }\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { SessionRecord } from \"../types.js\";\nimport { createChildLogger } from \"../utils/log.js\";\n\nconst log = createChildLogger({ module: \"session-store\" });\n\nexport interface SessionStore {\n save(record: SessionRecord): Promise<void>;\n get(sessionId: string): SessionRecord | undefined;\n findByPlatform(\n channelId: string,\n predicate: (platform: Record<string, unknown>) => boolean,\n ): SessionRecord | undefined;\n findByAgentSessionId(agentSessionId: string): SessionRecord | undefined;\n list(channelId?: string): SessionRecord[];\n remove(sessionId: string): Promise<void>;\n}\n\ninterface StoreFile {\n version: number;\n sessions: Record<string, SessionRecord>;\n}\n\nconst DEBOUNCE_MS = 2000;\n\nexport class JsonFileSessionStore implements SessionStore {\n private records: Map<string, SessionRecord> = new Map();\n private filePath: string;\n private ttlDays: number;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private cleanupInterval: ReturnType<typeof setInterval> | null = null;\n private flushHandler: (() => void) | null = null;\n\n constructor(filePath: string, ttlDays: number) {\n this.filePath = filePath;\n this.ttlDays = ttlDays;\n this.load();\n this.cleanup();\n\n // Daily cleanup for long-running instances\n this.cleanupInterval = setInterval(\n () => this.cleanup(),\n 24 * 60 * 60 * 1000,\n );\n\n // Force flush on shutdown\n this.flushHandler = () => this.flushSync();\n process.on(\"SIGTERM\", this.flushHandler);\n process.on(\"SIGINT\", this.flushHandler);\n process.on(\"exit\", this.flushHandler);\n }\n\n async save(record: SessionRecord): Promise<void> {\n this.records.set(record.sessionId, { ...record });\n this.scheduleDiskWrite();\n }\n\n get(sessionId: string): SessionRecord | undefined {\n return this.records.get(sessionId);\n }\n\n findByPlatform(\n channelId: string,\n predicate: (platform: Record<string, unknown>) => boolean,\n ): SessionRecord | undefined {\n for (const record of this.records.values()) {\n if (record.channelId === channelId && predicate(record.platform)) {\n return record;\n }\n }\n return undefined;\n }\n\n findByAgentSessionId(agentSessionId: string): SessionRecord | undefined {\n for (const record of this.records.values()) {\n if (\n record.agentSessionId === agentSessionId ||\n record.originalAgentSessionId === agentSessionId\n ) {\n return record;\n }\n // Also search switch history\n if (record.agentSwitchHistory?.some((e) => e.agentSessionId === agentSessionId)) {\n return record;\n }\n }\n return undefined;\n }\n\n list(channelId?: string): SessionRecord[] {\n const all = [...this.records.values()];\n if (channelId) return all.filter((r) => r.channelId === channelId);\n return all;\n }\n\n async remove(sessionId: string): Promise<void> {\n this.records.delete(sessionId);\n this.scheduleDiskWrite();\n }\n\n flushSync(): void {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n const data: StoreFile = {\n version: 1,\n sessions: Object.fromEntries(this.records),\n };\n const dir = path.dirname(this.filePath);\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(this.filePath, JSON.stringify(data, null, 2));\n }\n\n destroy(): void {\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\n if (this.cleanupInterval) clearInterval(this.cleanupInterval);\n if (this.flushHandler) {\n process.removeListener(\"SIGTERM\", this.flushHandler);\n process.removeListener(\"SIGINT\", this.flushHandler);\n process.removeListener(\"exit\", this.flushHandler);\n this.flushHandler = null;\n }\n }\n\n private load(): void {\n if (!fs.existsSync(this.filePath)) return;\n try {\n const raw = JSON.parse(\n fs.readFileSync(this.filePath, \"utf-8\"),\n ) as StoreFile;\n if (raw.version !== 1) {\n log.warn(\n { version: raw.version },\n \"Unknown session store version, skipping load\",\n );\n return;\n }\n for (const [id, record] of Object.entries(raw.sessions)) {\n this.records.set(id, record);\n }\n log.debug({ count: this.records.size }, \"Loaded session records\");\n } catch (err) {\n log.error({ err }, \"Failed to load session store, backing up corrupt file\");\n try {\n fs.renameSync(this.filePath, `${this.filePath}.bak`);\n } catch { /* best effort */ }\n }\n }\n\n private cleanup(): void {\n const cutoff = Date.now() - this.ttlDays * 24 * 60 * 60 * 1000;\n let removed = 0;\n for (const [id, record] of this.records) {\n if (record.status === \"active\" || record.status === \"initializing\")\n continue;\n const lastActive = new Date(record.lastActiveAt).getTime();\n if (lastActive < cutoff) {\n this.records.delete(id);\n removed++;\n }\n }\n if (removed > 0) {\n log.info({ removed }, \"Cleaned up expired session records\");\n this.scheduleDiskWrite();\n }\n }\n\n private scheduleDiskWrite(): void {\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\n this.debounceTimer = setTimeout(() => {\n this.flushSync();\n }, DEBOUNCE_MS);\n }\n}\n","import type { AgentManager } from \"../agents/agent-manager.js\";\nimport type { SessionManager } from \"./session-manager.js\";\nimport type { SpeechService } from \"../../plugins/speech/exports.js\";\nimport type { EventBus } from \"../event-bus.js\";\nimport type { NotificationManager } from \"../../plugins/notifications/notification.js\";\nimport type { TunnelService } from \"../../plugins/tunnel/tunnel-service.js\";\nimport type { AgentEvent } from \"../types.js\";\nimport type { MiddlewareChain } from \"../plugin/middleware-chain.js\";\nimport { Session } from \"./session.js\";\nimport { createChildLogger } from \"../utils/log.js\";\n\nconst log = createChildLogger({ module: \"session-factory\" });\n\nexport interface SessionCreateParams {\n channelId: string;\n agentName: string;\n workingDirectory: string;\n resumeAgentSessionId?: string;\n existingSessionId?: string;\n initialName?: string;\n}\n\nexport interface SideEffectDeps {\n eventBus: EventBus;\n notificationManager: NotificationManager;\n tunnelService?: TunnelService;\n}\n\nexport class SessionFactory {\n middlewareChain?: MiddlewareChain;\n\n constructor(\n private agentManager: AgentManager,\n private sessionManager: SessionManager,\n private speechServiceAccessor: SpeechService | (() => SpeechService),\n private eventBus: EventBus,\n ) {}\n\n private get speechService(): SpeechService {\n return typeof this.speechServiceAccessor === 'function'\n ? this.speechServiceAccessor()\n : this.speechServiceAccessor;\n }\n\n async create(params: SessionCreateParams): Promise<Session> {\n // Hook: session:beforeCreate — modifiable, can block\n let createParams = params;\n if (this.middlewareChain) {\n const payload = {\n agentName: params.agentName,\n workingDir: params.workingDirectory,\n userId: '', // userId is not part of SessionCreateParams — resolved upstream\n channelId: params.channelId,\n threadId: '', // threadId is assigned after session creation\n };\n const result = await this.middlewareChain.execute('session:beforeCreate', payload, async (p) => p);\n if (!result) throw new Error(\"Session creation blocked by middleware\");\n // Apply any middleware modifications back to create params\n createParams = {\n ...params,\n agentName: result.agentName,\n workingDirectory: result.workingDir,\n channelId: result.channelId,\n };\n }\n\n // 1. Spawn or resume agent\n const agentInstance = createParams.resumeAgentSessionId\n ? await this.agentManager.resume(\n createParams.agentName,\n createParams.workingDirectory,\n createParams.resumeAgentSessionId,\n )\n : await this.agentManager.spawn(\n createParams.agentName,\n createParams.workingDirectory,\n );\n\n // Wire middleware chain to agent instance for FS/terminal hooks\n agentInstance.middlewareChain = this.middlewareChain;\n\n // 2. Create Session instance\n const session = new Session({\n id: createParams.existingSessionId,\n channelId: createParams.channelId,\n agentName: createParams.agentName,\n workingDirectory: createParams.workingDirectory,\n agentInstance,\n speechService: this.speechService,\n });\n session.agentSessionId = agentInstance.sessionId;\n session.middlewareChain = this.middlewareChain;\n if (createParams.initialName) {\n session.name = createParams.initialName;\n }\n\n // 3. Register in SessionManager\n this.sessionManager.registerSession(session);\n this.eventBus.emit(\"session:created\", {\n sessionId: session.id,\n agent: session.agentName,\n status: session.status,\n });\n\n return session;\n }\n\n wireSideEffects(session: Session, deps: SideEffectDeps): void {\n // Wire usage tracking via event bus (consumed by usage plugin)\n session.on(\"agent_event\", (event: AgentEvent) => {\n if (event.type !== \"usage\") return;\n deps.eventBus.emit(\"usage:recorded\", {\n sessionId: session.id,\n agentName: session.agentName,\n timestamp: new Date().toISOString(),\n tokensUsed: event.tokensUsed ?? 0,\n contextSize: event.contextSize ?? 0,\n cost: event.cost,\n });\n });\n\n // Clean up user tunnels when session ends\n session.on(\"status_change\", (_from, to) => {\n if ((to === \"finished\" || to === \"cancelled\") && deps.tunnelService) {\n deps.tunnelService\n .stopBySession(session.id)\n .then((stopped) => {\n for (const entry of stopped) {\n deps.notificationManager\n .notifyAll({\n sessionId: session.id,\n sessionName: session.name,\n type: \"completed\",\n summary: `Tunnel stopped: port ${entry.port}${entry.label ? ` (${entry.label})` : \"\"} — session ended`,\n })\n .catch(() => {});\n }\n })\n .catch(() => {});\n }\n });\n }\n}\n","import { TypedEmitter } from \"./utils/typed-emitter.js\";\nimport type { AgentEvent, PermissionRequest, SessionStatus, UsageRecordEvent } from \"./types.js\";\n\nexport interface EventBusEvents {\n \"session:created\": (data: {\n sessionId: string;\n agent: string;\n status: SessionStatus;\n }) => void;\n \"session:updated\": (data: {\n sessionId: string;\n status?: SessionStatus;\n name?: string;\n dangerousMode?: boolean;\n }) => void;\n \"session:deleted\": (data: { sessionId: string }) => void;\n \"agent:event\": (data: { sessionId: string; event: AgentEvent }) => void;\n \"permission:request\": (data: {\n sessionId: string;\n permission: PermissionRequest;\n }) => void;\n \"permission:resolved\": (data: {\n sessionId: string;\n requestId: string;\n decision: string;\n }) => void;\n\n // System lifecycle\n \"kernel:booted\": () => void;\n \"system:ready\": () => void;\n \"system:shutdown\": () => void;\n \"system:commands-ready\": (data: {\n commands: Array<{ name: string; description: string }>;\n }) => void;\n\n // Plugin lifecycle\n \"plugin:loaded\": (data: { name: string; version: string }) => void;\n \"plugin:failed\": (data: { name: string; error: string }) => void;\n \"plugin:disabled\": (data: { name: string; reason: string }) => void;\n \"plugin:unloaded\": (data: { name: string }) => void;\n\n // Session (additional)\n \"session:ended\": (data: { sessionId: string; reason: string }) => void;\n \"session:named\": (data: { sessionId: string; name: string }) => void;\n\n // Agent (additional)\n \"agent:prompt\": (data: {\n sessionId: string;\n text: string;\n attachments?: unknown[];\n }) => void;\n\n // Usage tracking (consumed by usage plugin)\n \"usage:recorded\": (data: UsageRecordEvent) => void;\n}\n\nexport class EventBus extends TypedEmitter<EventBusEvents> {}\n","import { createHash } from 'node:crypto'\nimport { readFileSync } from 'node:fs'\nimport type { OpenACPPlugin } from './types.js'\n\n/**\n * Resolve plugin load order via topological sort.\n * - Handles `overrides` field: overridden plugins are removed before sorting.\n * - Detects circular dependencies and throws.\n * - Missing dependencies: skip plugin + all dependents (cascade).\n */\nexport function resolveLoadOrder(plugins: OpenACPPlugin[]): OpenACPPlugin[] {\n // Phase 1: Apply overrides — remove overridden plugins\n const overrideTargets = new Set<string>()\n for (const p of plugins) {\n if (p.overrides) {\n overrideTargets.add(p.overrides)\n }\n }\n let remaining = plugins.filter((p) => !overrideTargets.has(p.name))\n\n // Phase 2: Build name→plugin map\n const byName = new Map<string, OpenACPPlugin>()\n for (const p of remaining) {\n byName.set(p.name, p)\n }\n\n // Phase 3: Find missing deps and cascade-skip\n const skipped = new Set<string>()\n\n function cascadeSkip(name: string): void {\n if (skipped.has(name)) return\n skipped.add(name)\n // Skip all plugins that depend on this one\n for (const p of remaining) {\n if (p.pluginDependencies && name in p.pluginDependencies) {\n cascadeSkip(p.name)\n }\n }\n }\n\n for (const p of remaining) {\n if (p.pluginDependencies) {\n for (const dep of Object.keys(p.pluginDependencies)) {\n if (!byName.has(dep)) {\n cascadeSkip(p.name)\n }\n }\n }\n }\n\n remaining = remaining.filter((p) => !skipped.has(p.name))\n\n // Rebuild map after skipping\n byName.clear()\n for (const p of remaining) {\n byName.set(p.name, p)\n }\n\n // Phase 4: Topological sort with cycle detection (DFS)\n const visited = new Set<string>()\n const inStack = new Set<string>()\n const order: OpenACPPlugin[] = []\n\n function visit(name: string): void {\n if (visited.has(name)) return\n if (inStack.has(name)) {\n throw new Error(`Circular dependency detected: ${name}`)\n }\n\n inStack.add(name)\n const plugin = byName.get(name)!\n if (plugin.pluginDependencies) {\n for (const dep of Object.keys(plugin.pluginDependencies)) {\n visit(dep)\n }\n }\n inStack.delete(name)\n visited.add(name)\n order.push(plugin)\n }\n\n for (const p of remaining) {\n visit(p.name)\n }\n\n return order\n}\n\n/**\n * Compute SHA-256 checksum of a file, returned as 64-char hex string.\n */\nexport function computeChecksum(filePath: string): string {\n const data = readFileSync(filePath)\n return createHash('sha256').update(data).digest('hex')\n}\n\n/**\n * Verify that actual checksum matches expected.\n */\nexport function verifyChecksum(_name: string, expected: string, actual: string): boolean {\n return expected === actual\n}\n","export class ServiceRegistry {\n private services = new Map<string, { implementation: unknown; pluginName: string }>()\n\n register<T>(name: string, implementation: T, pluginName: string): void {\n if (this.services.has(name)) {\n const existing = this.services.get(name)!\n throw new Error(`Service '${name}' already registered by ${existing.pluginName}. Plugin ${pluginName} cannot register it without override.`)\n }\n this.services.set(name, { implementation, pluginName })\n }\n\n registerOverride<T>(name: string, implementation: T, pluginName: string): void {\n this.services.set(name, { implementation, pluginName })\n }\n\n get<T>(name: string): T | undefined {\n return this.services.get(name)?.implementation as T | undefined\n }\n\n has(name: string): boolean {\n return this.services.has(name)\n }\n\n list(): Array<{ name: string; pluginName: string }> {\n return [...this.services.entries()].map(([name, { pluginName }]) => ({ name, pluginName }))\n }\n\n unregister(name: string): void {\n this.services.delete(name)\n }\n\n unregisterByPlugin(pluginName: string): void {\n for (const [name, entry] of this.services) {\n if (entry.pluginName === pluginName) {\n this.services.delete(name)\n }\n }\n }\n}\n","import type { ErrorTracker } from './error-tracker.js'\n\nconst MIDDLEWARE_TIMEOUT_MS = 5000\n\ntype HandlerEntry = {\n pluginName: string\n priority: number\n handler: Function\n}\n\nexport class MiddlewareChain {\n private chains = new Map<string, Array<HandlerEntry>>()\n private errorHandler?: (pluginName: string, error: Error) => void\n private errorTracker?: ErrorTracker\n\n add(\n hook: string,\n pluginName: string,\n opts: { priority?: number; handler: Function },\n ): void {\n const entry: HandlerEntry = {\n pluginName,\n priority: opts.priority ?? 100,\n handler: opts.handler,\n }\n const existing = this.chains.get(hook)\n if (existing) {\n existing.push(entry)\n existing.sort((a, b) => a.priority - b.priority)\n } else {\n this.chains.set(hook, [entry])\n }\n }\n\n async execute<T>(\n hook: string,\n payload: T,\n coreHandler: (p: T) => T | Promise<T>,\n ): Promise<T | null> {\n const handlers = this.chains.get(hook)\n if (!handlers || handlers.length === 0) {\n return coreHandler(payload)\n }\n\n // Handlers are pre-sorted by priority at registration time\n const sorted = handlers\n\n // Build the chain\n let cachedResult: { value: T | null } | undefined = undefined\n\n const buildNext = (index: number, currentPayload: T): (() => Promise<T | null>) => {\n return async () => {\n // Return cached result on double-call\n if (cachedResult !== undefined) {\n return cachedResult.value\n }\n\n if (index >= sorted.length) {\n // End of middleware chain — call core handler\n const result = await coreHandler(currentPayload)\n cachedResult = { value: result }\n return result\n }\n\n const entry = sorted[index]\n\n // Skip disabled plugins\n if (this.errorTracker?.isDisabled(entry.pluginName)) {\n const skipFn = buildNext(index + 1, currentPayload)\n return skipFn()\n }\n\n const nextFn = buildNext(index + 1, currentPayload)\n\n // Wrap next to detect when it has been called and cache\n let nextCalled = false\n let nextResult: T | null = null\n const wrappedNext = async (newPayload?: T): Promise<T | null> => {\n if (!nextCalled) {\n nextCalled = true\n const payloadForNext = newPayload !== undefined ? newPayload : currentPayload\n // Rebuild chain from next index with potentially updated payload\n const newNextFn = buildNext(index + 1, payloadForNext)\n nextResult = await newNextFn()\n }\n return nextResult\n }\n\n let handlerResult: T | null\n let timeoutTimer: ReturnType<typeof setTimeout> | undefined\n try {\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutTimer = setTimeout(\n () => reject(new Error(`Middleware timeout: ${entry.pluginName} on hook ${hook}`)),\n MIDDLEWARE_TIMEOUT_MS,\n )\n if (typeof timeoutTimer === 'object' && timeoutTimer !== null && 'unref' in timeoutTimer) {\n ;(timeoutTimer as NodeJS.Timeout).unref()\n }\n })\n\n handlerResult = await Promise.race([\n entry.handler(currentPayload, wrappedNext),\n timeoutPromise,\n ])\n } catch (err) {\n // Report error\n if (this.errorHandler) {\n this.errorHandler(entry.pluginName, err instanceof Error ? err : new Error(String(err)))\n }\n // Track error for circuit-breaking\n this.errorTracker?.increment(entry.pluginName)\n // Skip this handler — pass ORIGINAL payload to next\n return nextFn()\n } finally {\n clearTimeout(timeoutTimer!)\n }\n\n // Handler returned null — block\n if (handlerResult === null) {\n return null\n }\n\n return handlerResult\n }\n }\n\n const start = buildNext(0, payload)\n return start()\n }\n\n removeAll(pluginName: string): void {\n for (const [hook, handlers] of this.chains.entries()) {\n const filtered = handlers.filter((h) => h.pluginName !== pluginName)\n if (filtered.length === 0) {\n this.chains.delete(hook)\n } else {\n this.chains.set(hook, filtered)\n }\n }\n }\n\n setErrorHandler(fn: (pluginName: string, error: Error) => void): void {\n this.errorHandler = fn\n }\n\n setErrorTracker(tracker: ErrorTracker): void {\n this.errorTracker = tracker\n }\n}\n","export interface ErrorBudgetConfig {\n maxErrors: number // default 10\n windowMs: number // default 3600000 (1 hour)\n}\n\nexport class ErrorTracker {\n private errors = new Map<string, { count: number; windowStart: number }>()\n private disabled = new Set<string>()\n private exempt = new Set<string>()\n private config: ErrorBudgetConfig\n\n onDisabled?: (pluginName: string, reason: string) => void\n\n constructor(config?: Partial<ErrorBudgetConfig>) {\n this.config = { maxErrors: config?.maxErrors ?? 10, windowMs: config?.windowMs ?? 3600000 }\n }\n\n increment(pluginName: string): void {\n if (this.exempt.has(pluginName)) return\n\n const now = Date.now()\n const entry = this.errors.get(pluginName)\n\n if (!entry || now - entry.windowStart >= this.config.windowMs) {\n this.errors.set(pluginName, { count: 1, windowStart: now })\n } else {\n entry.count += 1\n }\n\n const current = this.errors.get(pluginName)!\n if (current.count >= this.config.maxErrors && !this.disabled.has(pluginName)) {\n this.disabled.add(pluginName)\n const reason = `Error budget exceeded: ${current.count} errors within ${this.config.windowMs}ms window`\n this.onDisabled?.(pluginName, reason)\n }\n }\n\n isDisabled(pluginName: string): boolean {\n return this.disabled.has(pluginName)\n }\n\n reset(pluginName: string): void {\n this.disabled.delete(pluginName)\n this.errors.delete(pluginName)\n }\n\n setExempt(pluginName: string): void {\n this.exempt.add(pluginName)\n }\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { PluginStorage } from './types.js'\n\nexport class PluginStorageImpl implements PluginStorage {\n private readonly kvPath: string\n private readonly dataDir: string\n private writeChain: Promise<void> = Promise.resolve()\n\n constructor(baseDir: string) {\n this.dataDir = path.join(baseDir, 'data')\n this.kvPath = path.join(baseDir, 'kv.json')\n fs.mkdirSync(baseDir, { recursive: true })\n }\n\n private readKv(): Record<string, unknown> {\n try {\n const raw = fs.readFileSync(this.kvPath, 'utf-8')\n return JSON.parse(raw) as Record<string, unknown>\n } catch {\n return {}\n }\n }\n\n private writeKv(data: Record<string, unknown>): void {\n fs.writeFileSync(this.kvPath, JSON.stringify(data), 'utf-8')\n }\n\n async get<T>(key: string): Promise<T | undefined> {\n const data = this.readKv()\n return key in data ? (data[key] as T) : undefined\n }\n\n async set<T>(key: string, value: T): Promise<void> {\n this.writeChain = this.writeChain.then(() => {\n const data = this.readKv()\n data[key] = value\n this.writeKv(data)\n })\n return this.writeChain\n }\n\n async delete(key: string): Promise<void> {\n this.writeChain = this.writeChain.then(() => {\n const data = this.readKv()\n delete data[key]\n this.writeKv(data)\n })\n return this.writeChain\n }\n\n async list(): Promise<string[]> {\n return Object.keys(this.readKv())\n }\n\n getDataDir(): string {\n fs.mkdirSync(this.dataDir, { recursive: true })\n return this.dataDir\n }\n}\n","import path from 'node:path'\nimport os from 'node:os'\nimport type {\n PluginContext,\n PluginPermission,\n CommandDef,\n MiddlewareHook,\n MiddlewareOptions,\n MiddlewarePayloadMap,\n PluginStorage,\n EventBus,\n Logger,\n OutgoingMessage,\n} from './types.js'\nimport { ServiceRegistry } from './service-registry.js'\nimport { MiddlewareChain } from './middleware-chain.js'\nimport { ErrorTracker } from './error-tracker.js'\nimport { PluginStorageImpl } from './plugin-storage.js'\n\ninterface CreatePluginContextOpts {\n pluginName: string\n pluginConfig: Record<string, unknown>\n permissions: PluginPermission[]\n serviceRegistry: ServiceRegistry\n middlewareChain: MiddlewareChain\n errorTracker: ErrorTracker\n eventBus: EventBus & {\n on(event: string, handler: (...args: unknown[]) => void): void\n off(event: string, handler: (...args: unknown[]) => void): void\n emit(event: string, payload: unknown): void\n }\n storagePath: string\n sessions: unknown\n config: unknown\n core?: unknown\n log?: Logger\n instanceRoot?: string\n}\n\nfunction requirePermission(permissions: PluginPermission[], required: PluginPermission, action: string): void {\n if (!permissions.includes(required)) {\n throw new Error(`Plugin does not have '${required}' permission required for ${action}`)\n }\n}\n\nexport function createPluginContext(opts: CreatePluginContextOpts): PluginContext & { cleanup(): void } {\n const {\n pluginName,\n pluginConfig,\n permissions,\n serviceRegistry,\n middlewareChain,\n eventBus,\n storagePath,\n sessions,\n config,\n core,\n } = opts\n const instanceRoot = opts.instanceRoot ?? path.join(os.homedir(), '.openacp')\n\n // Track registered items for cleanup\n const registeredListeners: Array<{ event: string; handler: (...args: unknown[]) => void }> = []\n const registeredCommands: CommandDef[] = []\n\n const noopLog: Logger = {\n trace() {},\n debug() {},\n info() {},\n warn() {},\n error() {},\n fatal() {},\n child() { return noopLog },\n }\n const baseLog: Logger = opts.log ?? noopLog\n const log: Logger = typeof baseLog.child === 'function'\n ? baseLog.child({ plugin: pluginName })\n : baseLog\n\n const storageImpl = new PluginStorageImpl(storagePath)\n\n // Create permission-guarded storage proxy\n const storage: PluginStorage = {\n async get<T>(key: string): Promise<T | undefined> {\n requirePermission(permissions, 'storage:read', 'storage.get')\n return storageImpl.get<T>(key)\n },\n async set<T>(key: string, value: T): Promise<void> {\n requirePermission(permissions, 'storage:write', 'storage.set')\n return storageImpl.set(key, value)\n },\n async delete(key: string): Promise<void> {\n requirePermission(permissions, 'storage:write', 'storage.delete')\n return storageImpl.delete(key)\n },\n async list(): Promise<string[]> {\n requirePermission(permissions, 'storage:read', 'storage.list')\n return storageImpl.list()\n },\n getDataDir(): string {\n requirePermission(permissions, 'storage:read', 'storage.getDataDir')\n return storageImpl.getDataDir()\n },\n }\n\n const ctx: PluginContext & { cleanup(): void } = {\n pluginName,\n pluginConfig,\n log,\n storage,\n\n on(event: string, handler: (...args: unknown[]) => void): void {\n requirePermission(permissions, 'events:read', 'on()')\n eventBus.on(event, handler)\n registeredListeners.push({ event, handler })\n },\n\n off(event: string, handler: (...args: unknown[]) => void): void {\n requirePermission(permissions, 'events:read', 'off()')\n eventBus.off(event, handler)\n const idx = registeredListeners.findIndex((l) => l.event === event && l.handler === handler)\n if (idx >= 0) registeredListeners.splice(idx, 1)\n },\n\n emit(event: string, payload: unknown): void {\n requirePermission(permissions, 'events:emit', 'emit()')\n eventBus.emit(event, payload)\n },\n\n registerMiddleware<H extends MiddlewareHook>(hook: H, middlewareOpts: MiddlewareOptions<MiddlewarePayloadMap[H]>): void {\n requirePermission(permissions, 'middleware:register', 'registerMiddleware()')\n middlewareChain.add(hook, pluginName, middlewareOpts as { priority?: number; handler: Function })\n },\n\n registerService<T>(name: string, implementation: T): void {\n requirePermission(permissions, 'services:register', 'registerService()')\n serviceRegistry.register(name, implementation, pluginName)\n },\n\n getService<T>(name: string): T | undefined {\n requirePermission(permissions, 'services:use', 'getService()')\n return serviceRegistry.get<T>(name)\n },\n\n registerCommand(def: CommandDef): void {\n requirePermission(permissions, 'commands:register', 'registerCommand()')\n registeredCommands.push(def)\n const registry = serviceRegistry.get<{ register(def: CommandDef, pluginName: string): void }>('command-registry')\n if (registry && typeof registry.register === 'function') {\n registry.register(def, pluginName)\n log.debug(`Command '/${def.name}' registered`)\n }\n },\n\n async sendMessage(_sessionId: string, _content: OutgoingMessage): Promise<void> {\n requirePermission(permissions, 'services:use', 'sendMessage()')\n // Delegate to message routing service\n const router = serviceRegistry.get<{ send(sessionId: string, content: OutgoingMessage): Promise<void> }>('message-router')\n if (router) {\n await router.send(_sessionId, _content)\n }\n },\n\n get sessions() {\n requirePermission(permissions, 'kernel:access', 'sessions')\n return sessions as any\n },\n\n get config() {\n requirePermission(permissions, 'kernel:access', 'config')\n return config as any\n },\n\n get eventBus() {\n requirePermission(permissions, 'kernel:access', 'eventBus')\n return eventBus as any\n },\n\n get core() {\n requirePermission(permissions, 'kernel:access', 'core')\n return core\n },\n\n instanceRoot,\n\n cleanup(): void {\n // Remove all event listeners registered by this plugin\n for (const { event, handler } of registeredListeners) {\n eventBus.off(event, handler)\n }\n registeredListeners.length = 0\n\n // Remove all middleware registered by this plugin\n middlewareChain.removeAll(pluginName)\n\n // Unregister services owned by this plugin\n serviceRegistry.unregisterByPlugin(pluginName)\n\n // Unregister commands from CommandRegistry\n const cmdRegistry = serviceRegistry.get<{ unregisterByPlugin(name: string): void }>('command-registry')\n if (cmdRegistry && typeof cmdRegistry.unregisterByPlugin === 'function') {\n cmdRegistry.unregisterByPlugin(pluginName)\n }\n\n // Clear commands\n registeredCommands.length = 0\n },\n }\n\n return ctx\n}\n","import { resolveLoadOrder } from './plugin-loader.js'\nimport { ServiceRegistry } from './service-registry.js'\nimport { MiddlewareChain } from './middleware-chain.js'\nimport { ErrorTracker } from './error-tracker.js'\nimport { createPluginContext } from './plugin-context.js'\nimport type { OpenACPPlugin, EventBus, Logger, MigrateContext } from './types.js'\nimport type { SettingsManager } from './settings-manager.js'\nimport type { PluginRegistry } from './plugin-registry.js'\n\nconst SETUP_TIMEOUT_MS = 30_000\nconst TEARDOWN_TIMEOUT_MS = 10_000\n\nfunction withTimeout<T>(promise: Promise<T>, ms: number, label: string): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => reject(new Error(`Timeout: ${label} exceeded ${ms}ms`)), ms)\n if (typeof timer === 'object' && timer !== null && 'unref' in timer) {\n ;(timer as NodeJS.Timeout).unref()\n }\n promise.then(resolve, reject).finally(() => clearTimeout(timer))\n })\n}\n\nfunction resolvePluginConfig(pluginName: string, configManager: unknown): Record<string, unknown> {\n try {\n const allConfig = (configManager as any)?.get?.() ?? {}\n // Try new format: plugins.builtin['@openacp/speech'].config\n const pluginEntry = allConfig.plugins?.builtin?.[pluginName]\n if (pluginEntry?.config && Object.keys(pluginEntry.config).length > 0) {\n return pluginEntry.config\n }\n // @deprecated Legacy config path mapping — kept for backward compat with pre-plugin configs.\n // New plugins should use plugins.builtin['<name>'].config format. Remove when all users have migrated.\n const legacyMap: Record<string, string> = {\n '@openacp/security': 'security',\n '@openacp/speech': 'speech',\n '@openacp/tunnel': 'tunnel',\n '@openacp/usage': 'usage',\n '@openacp/file-service': 'files',\n '@openacp/api-server': 'api',\n '@openacp/telegram': 'channels.telegram',\n '@openacp/discord': 'channels.discord',\n '@openacp/adapter-discord': 'channels.discord',\n '@openacp/plugin-discord': 'channels.discord', // alias for old name\n '@openacp/slack': 'channels.slack',\n }\n const legacyKey = legacyMap[pluginName]\n if (legacyKey) {\n const parts = legacyKey.split('.')\n let obj: any = allConfig\n for (const p of parts) obj = obj?.[p]\n if (obj && typeof obj === 'object') return { ...obj }\n }\n } catch {\n // Gracefully degrade — return empty config\n }\n return {}\n}\n\nexport interface LifecycleManagerOpts {\n serviceRegistry?: ServiceRegistry\n middlewareChain?: MiddlewareChain\n errorTracker?: ErrorTracker\n eventBus?: EventBus & {\n on(event: string, handler: (...args: unknown[]) => void): void\n off(event: string, handler: (...args: unknown[]) => void): void\n emit(event: string, payload: unknown): void\n }\n storagePath?: string\n sessions?: unknown\n config?: unknown\n core?: unknown\n log?: Logger\n settingsManager?: SettingsManager\n pluginRegistry?: PluginRegistry\n /** Root directory for this OpenACP instance (default: ~/.openacp) */\n instanceRoot?: string\n}\n\nexport class LifecycleManager {\n readonly serviceRegistry: ServiceRegistry\n readonly middlewareChain: MiddlewareChain\n readonly errorTracker: ErrorTracker\n\n private eventBus: LifecycleManagerOpts['eventBus']\n private storagePath: string\n private sessions: unknown\n private config: unknown\n private core: unknown\n private log: Logger | undefined\n settingsManager: SettingsManager | undefined\n private pluginRegistry: PluginRegistry | undefined\n private instanceRoot: string | undefined\n\n private contexts = new Map<string, ReturnType<typeof createPluginContext>>()\n private loadOrder: OpenACPPlugin[] = []\n private _loaded = new Set<string>()\n private _failed = new Set<string>()\n\n get loadedPlugins(): string[] {\n return [...this._loaded]\n }\n\n get failedPlugins(): string[] {\n return [...this._failed]\n }\n\n get registry(): PluginRegistry | undefined {\n return this.pluginRegistry\n }\n\n constructor(opts?: LifecycleManagerOpts) {\n this.serviceRegistry = opts?.serviceRegistry ?? new ServiceRegistry()\n this.middlewareChain = opts?.middlewareChain ?? new MiddlewareChain()\n this.errorTracker = opts?.errorTracker ?? new ErrorTracker()\n this.eventBus = opts?.eventBus ?? {\n on() {},\n off() {},\n emit() {},\n }\n this.storagePath = opts?.storagePath ?? '/tmp/openacp-plugins'\n this.sessions = opts?.sessions ?? {}\n this.config = opts?.config ?? {}\n this.core = opts?.core\n this.log = opts?.log\n this.settingsManager = opts?.settingsManager\n this.pluginRegistry = opts?.pluginRegistry\n this.instanceRoot = opts?.instanceRoot\n }\n\n private getPluginLogger(pluginName: string): Logger {\n if (this.log && typeof (this.log as any).child === 'function') {\n return (this.log as any).child({ plugin: pluginName })\n }\n return this.log ?? { trace() {}, debug() {}, info() {}, warn() {}, error() {}, fatal() {}, child() { return this } } as Logger\n }\n\n async boot(plugins: OpenACPPlugin[]): Promise<void> {\n // Resolve load order via topological sort.\n // resolveLoadOrder will skip plugins whose dependencies are missing entirely\n // (not present in the input list). But we also need to handle runtime setup failures.\n // Include already-loaded plugins so dependency checks pass for late-booted plugins\n // (e.g., dev plugins booted after core plugins).\n const newNames = new Set(plugins.map(p => p.name))\n const allForResolution = [...this.loadOrder.filter(p => !newNames.has(p.name)), ...plugins]\n\n let sorted: OpenACPPlugin[]\n try {\n sorted = resolveLoadOrder(allForResolution)\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err))\n this.log?.error(`Plugin dependency resolution failed: ${error.message}`)\n for (const p of plugins) {\n this._failed.add(p.name)\n }\n return\n }\n\n // Only boot new plugins (already-loaded ones were included just for dependency resolution)\n sorted = sorted.filter(p => newNames.has(p.name))\n\n // Append to existing loadOrder (don't overwrite — hot-reload boots single plugins)\n for (const p of sorted) {\n if (!this.loadOrder.some(existing => existing.name === p.name)) {\n this.loadOrder.push(p)\n } else {\n // Replace in-place (hot-reload case: plugin was unloaded then re-booted)\n const idx = this.loadOrder.findIndex(existing => existing.name === p.name)\n this.loadOrder[idx] = p\n }\n }\n\n for (const plugin of sorted) {\n // Check if any required dependency failed at runtime\n if (plugin.pluginDependencies) {\n const depFailed = Object.keys(plugin.pluginDependencies).some(\n (dep) => this._failed.has(dep),\n )\n if (depFailed) {\n this._failed.add(plugin.name)\n continue\n }\n }\n\n // Check if disabled in registry\n const registryEntry = this.pluginRegistry?.get(plugin.name)\n if (registryEntry && registryEntry.enabled === false) {\n this.eventBus?.emit('plugin:disabled', { name: plugin.name })\n continue\n }\n\n // Check version mismatch → migrate\n if (registryEntry && plugin.migrate && registryEntry.version !== plugin.version && this.settingsManager) {\n try {\n const oldSettings = await this.settingsManager.loadSettings(plugin.name)\n const pluginLog = this.getPluginLogger(plugin.name)\n const migrateCtx: MigrateContext = {\n pluginName: plugin.name,\n settings: this.settingsManager.createAPI(plugin.name),\n log: pluginLog,\n }\n const newSettings = await withTimeout(\n plugin.migrate(migrateCtx, oldSettings, registryEntry.version),\n SETUP_TIMEOUT_MS,\n `${plugin.name}.migrate()`,\n )\n if (newSettings && typeof newSettings === 'object') {\n await migrateCtx.settings.setAll(newSettings as Record<string, unknown>)\n }\n this.pluginRegistry!.updateVersion(plugin.name, plugin.version)\n await this.pluginRegistry!.save()\n } catch (err) {\n this.getPluginLogger(plugin.name).warn(`Migration failed, continuing with old settings: ${err}`)\n }\n }\n\n // Resolve config: prefer settings.json, fallback to legacy\n let pluginConfig: Record<string, unknown>\n if (this.settingsManager) {\n pluginConfig = await this.settingsManager.loadSettings(plugin.name)\n const settingsPath = this.settingsManager.getSettingsPath(plugin.name)\n this.getPluginLogger(plugin.name).debug(`Settings loaded from ${settingsPath}: ${Object.keys(pluginConfig).length} keys`)\n if (Object.keys(pluginConfig).length === 0) {\n pluginConfig = resolvePluginConfig(plugin.name, this.config)\n }\n } else {\n pluginConfig = resolvePluginConfig(plugin.name, this.config)\n this.getPluginLogger(plugin.name).debug('No settingsManager, using legacy config')\n }\n\n // Validate settings against schema if plugin provides one\n if (plugin.settingsSchema && this.settingsManager) {\n const validation = this.settingsManager.validateSettings(plugin.name, pluginConfig, plugin.settingsSchema)\n if (!validation.valid) {\n this._failed.add(plugin.name)\n this.getPluginLogger(plugin.name).error(`Settings validation failed: ${validation.errors?.join('; ')}`)\n this.eventBus?.emit('plugin:failed', { name: plugin.name, error: `Settings validation failed: ${validation.errors?.join('; ')}` })\n continue\n }\n }\n\n // Create context for this plugin\n const ctx = createPluginContext({\n pluginName: plugin.name,\n pluginConfig,\n permissions: plugin.permissions ?? [],\n serviceRegistry: this.serviceRegistry,\n middlewareChain: this.middlewareChain,\n errorTracker: this.errorTracker,\n eventBus: this.eventBus!,\n storagePath: `${this.storagePath}/${plugin.name}`,\n sessions: this.sessions,\n config: this.config,\n core: this.core,\n log: this.log,\n instanceRoot: this.instanceRoot,\n })\n\n try {\n await withTimeout(plugin.setup(ctx), SETUP_TIMEOUT_MS, `${plugin.name}.setup()`)\n this.contexts.set(plugin.name, ctx)\n this._loaded.add(plugin.name)\n this.eventBus?.emit('plugin:loaded', { name: plugin.name, version: plugin.version })\n } catch (err) {\n this._failed.add(plugin.name)\n ctx.cleanup()\n this.getPluginLogger(plugin.name).error(`setup() failed: ${err}`)\n this.eventBus?.emit('plugin:failed', { name: plugin.name, error: String(err) })\n }\n }\n }\n\n async unloadPlugin(name: string): Promise<void> {\n if (!this._loaded.has(name)) return\n\n const plugin = this.loadOrder.find(p => p.name === name)\n\n if (plugin?.teardown) {\n try {\n await withTimeout(plugin.teardown(), TEARDOWN_TIMEOUT_MS, `${name}.teardown()`)\n } catch {\n // Swallow teardown errors\n }\n }\n\n const ctx = this.contexts.get(name)\n if (ctx) {\n ctx.cleanup()\n this.contexts.delete(name)\n }\n\n this._loaded.delete(name)\n this._failed.delete(name)\n this.loadOrder = this.loadOrder.filter(p => p.name !== name)\n\n this.eventBus?.emit('plugin:unloaded', { name })\n }\n\n async shutdown(): Promise<void> {\n // Teardown in reverse load order\n const reversed = [...this.loadOrder].reverse()\n\n for (const plugin of reversed) {\n if (!this._loaded.has(plugin.name)) continue\n\n if (plugin.teardown) {\n try {\n await withTimeout(plugin.teardown(), TEARDOWN_TIMEOUT_MS, `${plugin.name}.teardown()`)\n } catch {\n // Swallow teardown errors — graceful shutdown\n }\n }\n\n // Clean up the context\n const ctx = this.contexts.get(plugin.name)\n if (ctx) {\n ctx.cleanup()\n this.contexts.delete(plugin.name)\n }\n\n this.eventBus?.emit('plugin:unloaded', { name: plugin.name })\n }\n\n this._loaded.clear()\n this.loadOrder = []\n }\n}\n","import path from \"node:path\";\nimport os from \"node:os\";\nimport { ConfigManager } from \"./config/config.js\";\nimport { AgentManager } from \"./agents/agent-manager.js\";\nimport { SessionManager } from \"./sessions/session-manager.js\";\nimport { SessionBridge } from \"./sessions/session-bridge.js\";\nimport type { NotificationManager } from \"../plugins/notifications/notification.js\";\nimport type { IChannelAdapter } from \"./channel.js\";\nimport { Session } from \"./sessions/session.js\";\nimport { MessageTransformer } from \"./message-transformer.js\";\nimport type { FileServiceInterface } from \"./plugin/types.js\";\nimport { JsonFileSessionStore, type SessionStore } from \"./sessions/session-store.js\";\nimport type { SecurityGuard } from \"../plugins/security/security-guard.js\";\nimport { SessionFactory } from \"./sessions/session-factory.js\";\nimport type { IncomingMessage } from \"./types.js\";\nimport type { TunnelService } from \"../plugins/tunnel/tunnel-service.js\";\nimport { getAgentCapabilities } from \"./agents/agent-registry.js\";\nimport { AgentCatalog } from \"./agents/agent-catalog.js\";\nimport { EventBus } from \"./event-bus.js\";\nimport { LifecycleManager } from \"./plugin/lifecycle-manager.js\";\nimport { ServiceRegistry } from \"./plugin/service-registry.js\";\nimport { MiddlewareChain } from \"./plugin/middleware-chain.js\";\nimport { ErrorTracker } from \"./plugin/error-tracker.js\";\nimport { createChildLogger } from \"./utils/log.js\";\nimport type { SpeechService } from \"../plugins/speech/exports.js\";\nimport type { ContextManager } from \"../plugins/context/context-manager.js\";\nimport type { ContextQuery, ContextOptions, ContextResult } from \"../plugins/context/context-provider.js\";\nimport type { InstanceContext } from \"./instance-context.js\";\nconst log = createChildLogger({ module: \"core\" });\n\nexport class OpenACPCore {\n configManager: ConfigManager;\n agentCatalog: AgentCatalog;\n agentManager: AgentManager;\n sessionManager: SessionManager;\n messageTransformer: MessageTransformer;\n adapters: Map<string, IChannelAdapter> = new Map();\n /** sessionId → SessionBridge — tracks active bridges for disconnect/reconnect during agent switch */\n private bridges: Map<string, SessionBridge> = new Map();\n /** Set by main.ts — triggers graceful shutdown with restart exit code */\n requestRestart: (() => Promise<void>) | null = null;\n private _tunnelService?: TunnelService;\n private sessionStore: SessionStore | null = null;\n private resumeLocks: Map<string, Promise<Session | null>> = new Map();\n private switchingLocks = new Set<string>();\n eventBus: EventBus;\n sessionFactory: SessionFactory;\n readonly lifecycleManager: LifecycleManager;\n public readonly instanceContext?: InstanceContext;\n\n // --- Lazy getters: resolve from ServiceRegistry (populated by plugins during boot) ---\n\n private getService<T>(name: string): T {\n const svc = this.lifecycleManager.serviceRegistry.get<T>(name);\n if (!svc) throw new Error(`Service '${name}' not registered — is the ${name} plugin loaded?`);\n return svc;\n }\n\n get securityGuard(): SecurityGuard {\n return this.getService<SecurityGuard>('security');\n }\n\n get notificationManager(): NotificationManager {\n return this.getService<NotificationManager>('notifications');\n }\n\n get fileService(): FileServiceInterface {\n return this.getService<FileServiceInterface>('file-service');\n }\n\n get speechService(): SpeechService {\n return this.getService<SpeechService>('speech');\n }\n\n get contextManager(): ContextManager {\n return this.getService<ContextManager>('context');\n }\n\n constructor(configManager: ConfigManager, ctx?: InstanceContext) {\n this.configManager = configManager;\n this.instanceContext = ctx;\n const config = configManager.get();\n this.agentCatalog = new AgentCatalog();\n this.agentCatalog.load();\n this.agentManager = new AgentManager(this.agentCatalog);\n const storePath = ctx?.paths.sessions ?? path.join(os.homedir(), \".openacp\", \"sessions.json\");\n this.sessionStore = new JsonFileSessionStore(\n storePath,\n config.sessionStore.ttlDays,\n );\n this.sessionManager = new SessionManager(this.sessionStore);\n\n this.messageTransformer = new MessageTransformer();\n this.eventBus = new EventBus();\n this.sessionManager.setEventBus(this.eventBus);\n\n // SessionFactory uses a lazy accessor for speechService (resolved from ServiceRegistry after plugin boot)\n this.sessionFactory = new SessionFactory(\n this.agentManager,\n this.sessionManager,\n () => this.speechService,\n this.eventBus,\n );\n\n // Initialize plugin lifecycle manager (before setting middlewareChain on factory)\n this.lifecycleManager = new LifecycleManager({\n serviceRegistry: new ServiceRegistry(),\n middlewareChain: new MiddlewareChain(),\n errorTracker: new ErrorTracker(),\n eventBus: this.eventBus as any,\n sessions: this.sessionManager,\n config: this.configManager,\n core: this,\n storagePath: ctx?.paths.pluginsData ?? path.join(os.homedir(), \".openacp\", \"plugins\", \"data\"),\n log: createChildLogger({ module: \"plugin\" }),\n });\n\n // Wire middleware chain to session factory and session manager\n this.sessionFactory.middlewareChain = this.lifecycleManager.middlewareChain;\n this.sessionManager.middlewareChain = this.lifecycleManager.middlewareChain;\n\n // Hot-reload: handle config changes that need side effects\n this.configManager.on(\n \"config:changed\",\n async ({ path: configPath, value }: { path: string; value: unknown }) => {\n if (configPath === \"logging.level\" && typeof value === \"string\") {\n const { setLogLevel } = await import(\"./utils/log.js\");\n setLogLevel(value);\n log.info({ level: value }, \"Log level changed at runtime\");\n }\n if (configPath.startsWith(\"speech.\")) {\n const speechSvc = this.speechService;\n if (speechSvc) {\n const newConfig = this.configManager.get();\n const newSpeechConfig = newConfig.speech ?? {\n stt: { provider: null, providers: {} },\n tts: { provider: null, providers: {} },\n };\n speechSvc.refreshProviders(newSpeechConfig);\n log.info(\"Speech service config updated at runtime\");\n }\n }\n },\n );\n }\n\n get tunnelService(): TunnelService | undefined {\n return this._tunnelService;\n }\n\n set tunnelService(service: TunnelService | undefined) {\n this._tunnelService = service;\n this.messageTransformer.tunnelService = service;\n }\n\n registerAdapter(name: string, adapter: IChannelAdapter): void {\n this.adapters.set(name, adapter);\n }\n\n async start(): Promise<void> {\n this.agentCatalog.refreshRegistryIfStale().catch((err) => {\n log.warn({ err }, \"Background registry refresh failed\");\n });\n for (const adapter of this.adapters.values()) {\n await adapter.start();\n }\n }\n\n async stop(): Promise<void> {\n // 1. Notify users (best effort — service may not be available)\n try {\n const nm = this.lifecycleManager.serviceRegistry.get<NotificationManager>('notifications');\n if (nm) {\n await nm.notifyAll({\n sessionId: \"system\",\n type: \"error\",\n summary: \"OpenACP is shutting down\",\n });\n }\n } catch {\n /* best effort */\n }\n\n // 2. Persist session state (don't kill agents — they exit with parent)\n await this.sessionManager.shutdownAll();\n\n // 3. Stop adapters\n for (const adapter of this.adapters.values()) {\n await adapter.stop();\n }\n }\n\n // --- Archive ---\n\n async archiveSession(sessionId: string): Promise<{ ok: true; newThreadId: string } | { ok: false; error: string }> {\n const session = this.sessionManager.getSession(sessionId);\n if (!session) return { ok: false, error: \"Session not found (must be in memory)\" };\n\n // Must be active (not initializing or finished)\n if (session.status !== \"active\" && session.status !== \"cancelled\" && session.status !== \"error\") {\n return { ok: false, error: `Cannot archive session in '${session.status}' state` };\n }\n\n const adapter = this.adapters.get(session.channelId);\n if (!adapter) return { ok: false, error: \"Adapter not found for session\" };\n if (!adapter.archiveSessionTopic) return { ok: false, error: \"Adapter does not support topic archiving\" };\n\n try {\n // archiveSessionTopic handles: cleanup trackers → delete old topic → create new topic\n const newThreadId = await adapter.archiveSessionTopic(session.id);\n\n // Rewire session to new topic\n session.threadId = newThreadId;\n\n // Update session store with new topic ID (best-effort — topic is already recreated)\n try {\n const platform: Record<string, unknown> = {};\n if (session.channelId === \"telegram\") {\n platform.topicId = Number(newThreadId);\n } else {\n platform.threadId = newThreadId;\n }\n await this.sessionManager.patchRecord(sessionId, { platform });\n } catch (patchErr) {\n log.warn({ err: patchErr, sessionId }, \"Failed to update session record after archive — session will work but may not survive restart\");\n }\n\n return { ok: true, newThreadId };\n } catch (err) {\n // Clear archiving flag on error\n session.archiving = false;\n return { ok: false, error: (err as Error).message };\n }\n }\n\n // --- Message Routing ---\n\n async handleMessage(message: IncomingMessage): Promise<void> {\n log.debug(\n {\n channelId: message.channelId,\n threadId: message.threadId,\n userId: message.userId,\n },\n \"Incoming message\",\n );\n\n // Hook: message:incoming — modifiable, can block\n if (this.lifecycleManager?.middlewareChain) {\n const result = await this.lifecycleManager.middlewareChain.execute(\n 'message:incoming',\n message,\n async (msg) => msg,\n );\n if (!result) return; // blocked by middleware\n message = result;\n }\n\n // Security: check user access and session limits\n const access = this.securityGuard.checkAccess(message);\n if (!access.allowed) {\n log.warn({ userId: message.userId, reason: access.reason }, \"Access denied\");\n if (access.reason.includes(\"Session limit\")) {\n const adapter = this.adapters.get(message.channelId);\n if (adapter) {\n await adapter.sendMessage(message.threadId, {\n type: \"error\",\n text: `⚠️ ${access.reason}. Please cancel existing sessions with /cancel before starting new ones.`,\n });\n }\n }\n return;\n }\n\n // Find session by thread\n let session = this.sessionManager.getSessionByThread(\n message.channelId,\n message.threadId,\n );\n\n // Lazy resume: try to restore session from store\n if (!session) {\n session = (await this.lazyResume(message)) ?? undefined;\n }\n\n if (!session) {\n log.warn(\n { channelId: message.channelId, threadId: message.threadId },\n \"No session found for thread (in-memory miss + lazy resume returned null)\",\n );\n return;\n }\n\n // Update activity timestamp\n this.sessionManager.patchRecord(session.id, {\n lastActiveAt: new Date().toISOString(),\n });\n\n // Forward to session\n await session.enqueuePrompt(message.text, message.attachments);\n }\n\n // --- Unified Session Creation Pipeline ---\n\n async createSession(params: {\n channelId: string;\n agentName: string;\n workingDirectory: string;\n resumeAgentSessionId?: string;\n existingSessionId?: string;\n createThread?: boolean;\n initialName?: string;\n threadId?: string;\n }): Promise<Session> {\n // 1-3. Spawn/resume agent, create Session, register in SessionManager\n const session = await this.sessionFactory.create(params);\n\n // Set threadId early so agent events during bridge.connect() can find the thread\n if (params.threadId) {\n session.threadId = params.threadId;\n }\n\n // 4. Create thread if needed\n const adapter = this.adapters.get(params.channelId);\n if (params.createThread && adapter) {\n const threadId = await adapter.createSessionThread(\n session.id,\n params.initialName ?? `🔄 ${params.agentName} — New Session`,\n );\n session.threadId = threadId;\n }\n\n // 5. Connect SessionBridge\n if (adapter) {\n const bridge = this.createBridge(session, adapter);\n bridge.connect();\n }\n\n // 5b-5c. Wire usage tracking and tunnel cleanup\n this.sessionFactory.wireSideEffects(session, {\n eventBus: this.eventBus,\n notificationManager: this.notificationManager,\n tunnelService: this._tunnelService,\n });\n\n // 6. Persist initial record\n // Preserve existing platform data (e.g. topicId) when resuming an existing session\n const existingRecord = this.sessionStore?.get(session.id);\n const platform: Record<string, unknown> = {\n ...(existingRecord?.platform ?? {}),\n };\n if (session.threadId) {\n if (params.channelId === \"telegram\") {\n platform.topicId = Number(session.threadId);\n } else {\n platform.threadId = session.threadId;\n }\n }\n await this.sessionManager.patchRecord(session.id, {\n sessionId: session.id,\n agentSessionId: session.agentSessionId,\n agentName: params.agentName,\n workingDir: params.workingDirectory,\n channelId: params.channelId,\n status: session.status,\n createdAt: session.createdAt.toISOString(),\n lastActiveAt: new Date().toISOString(),\n name: session.name,\n platform,\n firstAgent: session.firstAgent,\n currentPromptCount: session.promptCount,\n agentSwitchHistory: session.agentSwitchHistory,\n });\n\n log.info(\n { sessionId: session.id, agentName: params.agentName },\n \"Session created via pipeline\",\n );\n return session;\n }\n\n async handleNewSession(\n channelId: string,\n agentName?: string,\n workspacePath?: string,\n options?: { createThread?: boolean },\n ): Promise<Session> {\n const config = this.configManager.get();\n const resolvedAgent = agentName || config.defaultAgent;\n log.info({ channelId, agentName: resolvedAgent }, \"New session request\");\n const agentDef = this.agentCatalog.resolve(resolvedAgent);\n const resolvedWorkspace = this.configManager.resolveWorkspace(\n workspacePath || agentDef?.workingDirectory,\n );\n\n return this.createSession({\n channelId,\n agentName: resolvedAgent,\n workingDirectory: resolvedWorkspace,\n createThread: options?.createThread,\n });\n }\n\n async adoptSession(\n agentName: string,\n agentSessionId: string,\n cwd: string,\n channelId?: string,\n ): Promise<\n | {\n ok: true;\n sessionId: string;\n threadId: string;\n status: \"adopted\" | \"existing\";\n }\n | { ok: false; error: string; message: string }\n > {\n // 1. Validate agent supports resume\n const caps = getAgentCapabilities(agentName);\n if (!caps.supportsResume) {\n return {\n ok: false,\n error: \"agent_not_supported\",\n message: `Agent '${agentName}' does not support session resume`,\n };\n }\n\n const agentDef = this.agentManager.getAgent(agentName);\n if (!agentDef) {\n return {\n ok: false,\n error: \"agent_not_supported\",\n message: `Agent '${agentName}' not found`,\n };\n }\n\n // 2. Validate cwd\n const { existsSync } = await import(\"node:fs\");\n if (!existsSync(cwd)) {\n return {\n ok: false,\n error: \"invalid_cwd\",\n message: `Directory does not exist: ${cwd}`,\n };\n }\n\n // 3. Check session limit\n const maxSessions = this.configManager.get().security.maxConcurrentSessions;\n if (this.sessionManager.listSessions().length >= maxSessions) {\n return {\n ok: false,\n error: \"session_limit\",\n message: \"Maximum concurrent sessions reached\",\n };\n }\n\n // 4. Check if session already exists on the same channel\n const existingRecord =\n this.sessionManager.getRecordByAgentSessionId(agentSessionId);\n if (existingRecord) {\n const sameChannel = !channelId || existingRecord.channelId === channelId;\n const platform = existingRecord.platform as { topicId?: number; threadId?: string } | undefined;\n const existingThreadId = platform?.topicId ? String(platform.topicId) : platform?.threadId;\n if (existingThreadId && sameChannel) {\n const adapter = this.adapters.get(existingRecord.channelId) ?? this.adapters.values().next().value;\n if (adapter) {\n try {\n await adapter.sendMessage(existingRecord.sessionId, {\n type: \"text\",\n text: \"Session resumed from CLI.\",\n });\n } catch { /* Topic/thread may be deleted */ }\n }\n return {\n ok: true,\n sessionId: existingRecord.sessionId,\n threadId: existingThreadId,\n status: \"existing\",\n };\n }\n }\n\n // 5. Find adapter (explicit channel or default first)\n let adapterChannelId: string;\n if (channelId) {\n if (!this.adapters.has(channelId)) {\n const available = Array.from(this.adapters.keys()).join(\", \") || \"none\";\n return { ok: false, error: \"adapter_not_found\", message: `Adapter '${channelId}' is not connected. Available: ${available}` };\n }\n adapterChannelId = channelId;\n } else {\n const firstEntry = this.adapters.entries().next().value;\n if (!firstEntry) {\n return { ok: false, error: \"no_adapter\", message: \"No channel adapter registered\" };\n }\n adapterChannelId = firstEntry[0];\n }\n\n // 6. Create session via unified pipeline\n let session: Session;\n try {\n session = await this.createSession({\n channelId: adapterChannelId,\n agentName,\n workingDirectory: cwd,\n resumeAgentSessionId: agentSessionId,\n createThread: true,\n initialName: \"Adopted session\",\n });\n } catch (err) {\n return {\n ok: false,\n error: \"resume_failed\",\n message: `Failed to resume session: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n // 7. Update store with adopt-specific fields\n const adoptPlatform: Record<string, unknown> = {};\n if (adapterChannelId === 'telegram') {\n adoptPlatform.topicId = Number(session.threadId);\n } else {\n adoptPlatform.threadId = session.threadId;\n }\n await this.sessionManager.patchRecord(session.id, {\n originalAgentSessionId: agentSessionId,\n platform: adoptPlatform,\n });\n\n return {\n ok: true,\n sessionId: session.id,\n threadId: session.threadId,\n status: \"adopted\",\n };\n }\n\n async handleNewChat(\n channelId: string,\n currentThreadId: string,\n ): Promise<Session | null> {\n const currentSession = this.sessionManager.getSessionByThread(\n channelId,\n currentThreadId,\n );\n\n if (currentSession) {\n return this.handleNewSession(\n channelId,\n currentSession.agentName,\n currentSession.workingDirectory,\n );\n }\n\n // Fallback: look up from store (e.g. after restart before lazy resume)\n const record = this.sessionManager.getRecordByThread(\n channelId,\n currentThreadId,\n );\n if (!record || record.status === \"cancelled\" || record.status === \"error\")\n return null;\n\n return this.handleNewSession(\n channelId,\n record.agentName,\n record.workingDir,\n );\n }\n\n async createSessionWithContext(params: {\n channelId: string;\n agentName: string;\n workingDirectory: string;\n contextQuery: ContextQuery;\n contextOptions?: ContextOptions;\n createThread?: boolean;\n }): Promise<{ session: Session; contextResult: ContextResult | null }> {\n let contextResult: ContextResult | null = null;\n try {\n contextResult = await this.contextManager.buildContext(\n params.contextQuery,\n params.contextOptions,\n );\n } catch (err) {\n log.warn({ err }, \"Context building failed, proceeding without context\");\n }\n\n const session = await this.createSession({\n channelId: params.channelId,\n agentName: params.agentName,\n workingDirectory: params.workingDirectory,\n createThread: params.createThread,\n });\n\n if (contextResult) {\n session.setContext(contextResult.markdown);\n }\n\n return { session, contextResult };\n }\n\n // --- Agent Switch ---\n\n async switchSessionAgent(sessionId: string, toAgent: string): Promise<{ resumed: boolean }> {\n // Prevent concurrent switches on the same session\n if (this.switchingLocks.has(sessionId)) {\n throw new Error('Switch already in progress');\n }\n this.switchingLocks.add(sessionId);\n try {\n return await this._doSwitchSessionAgent(sessionId, toAgent);\n } finally {\n this.switchingLocks.delete(sessionId);\n }\n }\n\n private async _doSwitchSessionAgent(sessionId: string, toAgent: string): Promise<{ resumed: boolean }> {\n const session = this.sessionManager.getSession(sessionId);\n if (!session) throw new Error(`Session ${sessionId} not found`);\n\n // Validate target agent exists before doing anything destructive\n const agentDef = this.agentManager.getAgent(toAgent);\n if (!agentDef) throw new Error(`Agent \"${toAgent}\" is not installed`);\n\n const fromAgent = session.agentName;\n\n // 1. Middleware: agent:beforeSwitch (blocking)\n const middlewareChain = this.lifecycleManager.middlewareChain;\n const result = await middlewareChain.execute('agent:beforeSwitch', {\n sessionId,\n fromAgent,\n toAgent,\n }, async (payload) => payload);\n if (!result) throw new Error('Agent switch blocked by middleware');\n\n // 2. Determine resume vs new\n const lastEntry = session.findLastSwitchEntry(toAgent);\n const caps = getAgentCapabilities(toAgent);\n const canResume = !!(lastEntry && caps.supportsResume && lastEntry.promptCount === 0);\n const resumed = canResume;\n\n // 3. Disconnect bridge\n const bridge = this.bridges.get(sessionId);\n if (bridge) bridge.disconnect();\n\n // Clear old agent's skill commands so they don't linger in the UI\n const switchAdapter = this.adapters.get(session.channelId);\n if (switchAdapter?.sendSkillCommands) {\n await switchAdapter.sendSkillCommands(session.id, []);\n }\n\n // Clean up adapter-side per-session state (draft manager, activity tracker, etc.)\n if (switchAdapter?.cleanupSessionState) {\n await switchAdapter.cleanupSessionState(session.id);\n }\n\n // Capture pre-switch state for rollback\n const fromAgentSessionId = session.agentSessionId;\n\n // 4. Switch agent on session (with rollback on failure)\n try {\n await session.switchAgent(toAgent, async () => {\n if (canResume) {\n return this.agentManager.resume(toAgent, session.workingDirectory, lastEntry!.agentSessionId);\n } else {\n const instance = await this.agentManager.spawn(toAgent, session.workingDirectory);\n // Inject context if context service available\n try {\n const contextService = this.lifecycleManager.serviceRegistry.get<ContextManager>('context');\n if (contextService) {\n const config = this.configManager.get();\n const labelAgent = config.agentSwitch?.labelHistory ?? true;\n const contextResult = await contextService.buildContext(\n { type: 'session', value: sessionId, repoPath: session.workingDirectory },\n { labelAgent },\n );\n if (contextResult?.markdown) {\n session.setContext(contextResult.markdown);\n }\n }\n } catch {\n // Context injection is best-effort\n }\n return instance;\n }\n });\n } catch (err) {\n // Rollback: try to restore the old agent so the session isn't left broken\n try {\n let rollbackInstance;\n try {\n // Try resume first to preserve conversation history\n rollbackInstance = await this.agentManager.resume(fromAgent, session.workingDirectory, fromAgentSessionId);\n } catch {\n // Fall back to fresh spawn if resume fails\n rollbackInstance = await this.agentManager.spawn(fromAgent, session.workingDirectory);\n }\n const oldInstance = rollbackInstance;\n // switchAgent already pushed to history, so undo it\n session.agentSwitchHistory.pop();\n session.agentInstance = oldInstance;\n session.agentName = fromAgent;\n session.agentSessionId = oldInstance.sessionId;\n // Reconnect bridge after rollback\n const adapter = this.adapters.get(session.channelId);\n if (adapter) {\n const rollbackBridge = this.createBridge(session, adapter);\n rollbackBridge.connect();\n }\n log.warn({ sessionId, fromAgent, toAgent, err }, \"Agent switch failed, rolled back to previous agent\");\n } catch (rollbackErr) {\n session.fail(`Switch failed and rollback failed: ${rollbackErr instanceof Error ? rollbackErr.message : String(rollbackErr)}`);\n log.error({ sessionId, fromAgent, toAgent, err, rollbackErr }, \"Agent switch failed and rollback also failed\");\n }\n throw err;\n }\n\n // 5. Reconnect bridge\n if (bridge) {\n // Re-create bridge with new agent instance wiring\n const adapter = this.adapters.get(session.channelId);\n if (adapter) {\n const newBridge = this.createBridge(session, adapter);\n newBridge.connect();\n }\n }\n\n // 6. Persist\n await this.sessionManager.patchRecord(sessionId, {\n agentName: toAgent,\n agentSessionId: session.agentSessionId,\n firstAgent: session.firstAgent,\n currentPromptCount: 0,\n agentSwitchHistory: session.agentSwitchHistory,\n });\n\n // 7. Middleware: agent:afterSwitch (fire-and-forget)\n middlewareChain.execute('agent:afterSwitch', {\n sessionId,\n fromAgent,\n toAgent,\n resumed,\n }, async (p) => p).catch(() => {});\n\n return { resumed };\n }\n\n // --- Lazy Resume ---\n\n /**\n * Get active session by thread, or attempt lazy resume from store.\n * Used by adapter command handlers that need a session but don't go through handleMessage().\n */\n async getOrResumeSession(channelId: string, threadId: string): Promise<Session | null> {\n const session = this.sessionManager.getSessionByThread(channelId, threadId);\n if (session) return session;\n return this.lazyResume({ channelId, threadId, userId: \"\", text: \"\" });\n }\n\n private async lazyResume(message: IncomingMessage): Promise<Session | null> {\n const store = this.sessionStore;\n if (!store) return null;\n\n const lockKey = `${message.channelId}:${message.threadId}`;\n\n // Check for existing resume in progress\n const existing = this.resumeLocks.get(lockKey);\n if (existing) return existing;\n\n const record = store.findByPlatform(\n message.channelId,\n (p) => String(p.topicId) === message.threadId,\n );\n if (!record) {\n log.debug(\n { threadId: message.threadId, channelId: message.channelId },\n \"No session record found for thread\",\n );\n return null;\n }\n\n // Don't resume errored or cancelled sessions\n if (record.status === \"error\" || record.status === \"cancelled\") {\n log.debug(\n {\n threadId: message.threadId,\n sessionId: record.sessionId,\n status: record.status,\n },\n \"Skipping resume of error session\",\n );\n return null;\n }\n\n log.info(\n {\n threadId: message.threadId,\n sessionId: record.sessionId,\n status: record.status,\n },\n \"Lazy resume: found record, attempting resume\",\n );\n\n const resumePromise = (async (): Promise<Session | null> => {\n try {\n const session = await this.createSession({\n channelId: record.channelId,\n agentName: record.agentName,\n workingDirectory: record.workingDir,\n resumeAgentSessionId: record.agentSessionId,\n existingSessionId: record.sessionId,\n initialName: record.name,\n threadId: message.threadId,\n });\n session.activate();\n session.dangerousMode = record.dangerousMode ?? false;\n if (record.firstAgent) session.firstAgent = record.firstAgent;\n if (record.agentSwitchHistory) session.agentSwitchHistory = record.agentSwitchHistory;\n if (record.currentPromptCount != null) session.promptCount = record.currentPromptCount;\n\n log.info(\n { sessionId: session.id, threadId: message.threadId },\n \"Lazy resume successful\",\n );\n return session;\n } catch (err) {\n log.error({ err, record }, \"Lazy resume failed\");\n // Send error feedback to user instead of silent drop\n const adapter = this.adapters.get(message.channelId);\n if (adapter) {\n try {\n await adapter.sendMessage(message.threadId, {\n type: \"error\",\n text: `⚠️ Failed to resume session: ${err instanceof Error ? err.message : String(err)}`,\n });\n } catch {\n /* best effort */\n }\n }\n return null;\n } finally {\n this.resumeLocks.delete(lockKey);\n }\n })();\n\n this.resumeLocks.set(lockKey, resumePromise);\n return resumePromise;\n }\n\n // --- Event Wiring ---\n\n /** Create a SessionBridge for the given session and adapter */\n createBridge(session: Session, adapter: IChannelAdapter): SessionBridge {\n const bridge = new SessionBridge(session, adapter, {\n messageTransformer: this.messageTransformer,\n notificationManager: this.notificationManager,\n sessionManager: this.sessionManager,\n eventBus: this.eventBus,\n fileService: this.fileService,\n middlewareChain: this.lifecycleManager?.middlewareChain,\n });\n this.bridges.set(session.id, bridge);\n return bridge;\n }\n}\n","import type { CommandDef, CommandArgs, CommandResponse } from './plugin/types.js'\n\ninterface RegisteredCommand extends CommandDef {\n /** Scope extracted from pluginName, e.g. '@openacp/speech' → 'speech' */\n scope?: string\n}\n\n/**\n * Central command registry with namespace resolution and adapter-specific overrides.\n *\n * Namespace rules:\n * - System commands always own the short name.\n * - Among plugins, the first to register wins the short name.\n * - Every plugin command also gets a qualified name: `scope:name`.\n * - Adapter plugins (@openacp/telegram, @openacp/discord)\n * registering a command that already exists → stored as an override\n * keyed by `channelId:commandName`, used when channelId matches.\n */\nexport class CommandRegistry {\n /** Main registry: short names + qualified names → RegisteredCommand */\n private commands = new Map<string, RegisteredCommand>()\n\n /** Adapter-specific overrides: `channelId:commandName` → RegisteredCommand */\n private overrides = new Map<string, RegisteredCommand>()\n\n private static ADAPTER_SCOPES = new Set(['telegram', 'discord'])\n\n /**\n * Register a command definition.\n * @param def - Command definition\n * @param pluginName - Plugin that owns the command (set automatically by PluginContext)\n */\n register(def: CommandDef, pluginName?: string): void {\n const cmd: RegisteredCommand = {\n ...def,\n pluginName: pluginName ?? def.pluginName,\n }\n\n if (pluginName) {\n cmd.scope = CommandRegistry.extractScope(pluginName)\n }\n\n const qualifiedName = cmd.scope ? `${cmd.scope}:${cmd.name}` : undefined\n\n // Check if this is an adapter plugin overriding an existing command\n if (cmd.scope && CommandRegistry.ADAPTER_SCOPES.has(cmd.scope) && this.commands.has(cmd.name)) {\n // Store as adapter override\n this.overrides.set(`${cmd.scope}:${cmd.name}`, cmd)\n return\n }\n\n // Always register qualified name if available\n if (qualifiedName) {\n this.commands.set(qualifiedName, cmd)\n }\n\n // Short name logic\n if (this.commands.has(cmd.name)) {\n const existing = this.commands.get(cmd.name)!\n // System commands always win the short name\n if (existing.category === 'system') {\n // Plugin gets qualified name only (already registered above)\n return\n }\n // First plugin wins short name; later plugins get qualified only\n return\n }\n\n // No conflict — register short name\n this.commands.set(cmd.name, cmd)\n }\n\n /** Retrieve a command by name (short or qualified). */\n get(name: string): RegisteredCommand | undefined {\n return this.commands.get(name)\n }\n\n /** Remove a command by name (short or qualified). Also removes its qualified name entry. */\n unregister(name: string): void {\n const cmd = this.commands.get(name)\n if (!cmd) return\n this.commands.delete(name)\n if (cmd.scope) {\n // If we deleted by short name, also delete qualified name\n this.commands.delete(`${cmd.scope}:${cmd.name}`)\n // If we deleted by qualified name, also delete short name\n this.commands.delete(cmd.name)\n }\n }\n\n /** Remove all commands registered by a given plugin. */\n unregisterByPlugin(pluginName: string): void {\n const toDelete: string[] = []\n\n for (const [key, cmd] of this.commands) {\n if (cmd.pluginName === pluginName) {\n toDelete.push(key)\n }\n }\n\n for (const key of toDelete) {\n this.commands.delete(key)\n }\n\n // Also remove adapter overrides\n for (const [key, cmd] of this.overrides) {\n if (cmd.pluginName === pluginName) {\n this.overrides.delete(key)\n }\n }\n }\n\n /** Return all unique commands (deduplicated — each command appears once). */\n getAll(): RegisteredCommand[] {\n const seen = new Set<RegisteredCommand>()\n for (const cmd of this.commands.values()) {\n seen.add(cmd)\n }\n return [...seen]\n }\n\n /** Filter commands by category. */\n getByCategory(category: 'system' | 'plugin'): RegisteredCommand[] {\n return this.getAll().filter((cmd) => cmd.category === category)\n }\n\n /**\n * Parse and execute a command string.\n * @param commandString - Full command string, e.g. \"/greet hello world\"\n * @param baseArgs - Base arguments (channelId, userId, etc.)\n * @returns CommandResponse\n */\n async execute(commandString: string, baseArgs: CommandArgs): Promise<CommandResponse> {\n // Parse command name and raw args\n const trimmed = commandString.trim()\n const spaceIdx = trimmed.indexOf(' ')\n const rawCmd = spaceIdx === -1 ? trimmed.slice(1) : trimmed.slice(1, spaceIdx)\n const cmdName = rawCmd.split(\"@\")[0]\n const rawArgs = spaceIdx === -1 ? '' : trimmed.slice(spaceIdx + 1)\n\n // Check for adapter-specific override first\n const overrideKey = `${baseArgs.channelId}:${cmdName}`\n const override = this.overrides.get(overrideKey)\n\n const cmd = override ?? this.commands.get(cmdName)\n\n if (!cmd) {\n return { type: 'error', message: `Unknown command: /${cmdName}` }\n }\n\n const args: CommandArgs = {\n ...baseArgs,\n raw: rawArgs,\n }\n\n try {\n const result = await cmd.handler(args)\n if (result === undefined || result === null) {\n return { type: 'silent' }\n }\n return result\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { type: 'error', message: `Command /${cmdName} failed: ${message}` }\n }\n }\n\n /** Extract scope from plugin name: '@openacp/speech' → 'speech', 'my-plugin' → 'my-plugin' */\n static extractScope(pluginName: string): string {\n const slashIdx = pluginName.lastIndexOf('/')\n if (slashIdx !== -1) {\n return pluginName.slice(slashIdx + 1)\n }\n return pluginName\n }\n}\n","import type { CommandRegistry } from '../command-registry.js'\nimport type { CommandResponse } from '../plugin/types.js'\n\n/**\n * System session commands — these are placeholder registrations for discovery\n * (autocomplete, help text, etc.). The actual logic lives in adapter-specific\n * handlers. Handlers return 'silent' so the generic dispatch passes through\n * to the adapter's dedicated handler via next().\n */\nexport function registerSessionCommands(registry: CommandRegistry, _core: unknown): void {\n registry.register({\n name: 'new',\n description: 'Start a new session',\n usage: '[agent-name]',\n category: 'system',\n handler: async () => {\n return { type: 'silent' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'cancel',\n description: 'Cancel the current agent turn',\n category: 'system',\n handler: async () => {\n return { type: 'silent' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'status',\n description: 'Show current session status',\n category: 'system',\n handler: async () => {\n return { type: 'silent' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'sessions',\n description: 'List all active sessions',\n category: 'system',\n handler: async () => {\n return { type: 'silent' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'clear',\n description: 'Clear session history',\n category: 'system',\n handler: async () => {\n return { type: 'silent' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'newchat',\n description: 'New chat, same agent & workspace',\n category: 'system',\n handler: async () => {\n return { type: 'silent' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'resume',\n description: 'Resume a previous session',\n usage: '<session-number>',\n category: 'system',\n handler: async () => {\n return { type: 'silent' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'handoff',\n description: 'Hand off session to another agent',\n usage: '<agent-name>',\n category: 'system',\n handler: async () => {\n return { type: 'silent' } satisfies CommandResponse\n },\n })\n}\n","import type { CommandRegistry } from '../command-registry.js'\nimport type { CommandResponse } from '../plugin/types.js'\n\nexport function registerAgentCommands(registry: CommandRegistry, _core: unknown): void {\n registry.register({\n name: 'agents',\n description: 'List available agents',\n category: 'system',\n handler: async () => {\n return { type: 'text', text: 'No agents configured.' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'install',\n description: 'Install a plugin',\n usage: '<plugin-name>',\n category: 'system',\n handler: async (args) => {\n const plugin = args.raw.trim()\n if (!plugin) {\n return { type: 'error', message: 'Usage: /install <plugin-name>' } satisfies CommandResponse\n }\n return { type: 'text', text: `Installing plugin: ${plugin}...` } satisfies CommandResponse\n },\n })\n}\n","import type { CommandRegistry } from '../command-registry.js'\nimport type { CommandResponse } from '../plugin/types.js'\n\nexport function registerAdminCommands(registry: CommandRegistry, _core: unknown): void {\n registry.register({\n name: 'restart',\n description: 'Restart the server',\n category: 'system',\n handler: async () => {\n return { type: 'silent' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'update',\n description: 'Check for and apply updates',\n category: 'system',\n handler: async () => {\n return { type: 'text', text: 'Checking for updates...' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'doctor',\n description: 'Run system diagnostics',\n category: 'system',\n handler: async () => {\n return { type: 'text', text: 'Running diagnostics...' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'integrate',\n description: 'Set up a new channel integration',\n usage: '<channel>',\n category: 'system',\n handler: async (args) => {\n const channel = args.raw.trim()\n if (!channel) {\n return {\n type: 'menu',\n title: 'Available Integrations',\n options: [\n { label: 'Telegram', command: '/integrate telegram' },\n { label: 'Discord', command: '/integrate discord' },\n ],\n } satisfies CommandResponse\n }\n return { type: 'text', text: `Setting up ${channel} integration...` } satisfies CommandResponse\n },\n })\n}\n","import type { CommandRegistry } from '../command-registry.js'\nimport type { CommandResponse } from '../plugin/types.js'\n\nexport function registerHelpCommand(registry: CommandRegistry, _core: unknown): void {\n registry.register({\n name: 'help',\n description: 'Show available commands',\n usage: '[command]',\n category: 'system',\n handler: async (args) => {\n const query = args.raw.trim()\n\n if (query) {\n const cmd = registry.get(query)\n if (!cmd) {\n return { type: 'error', message: `Unknown command: /${query}` } satisfies CommandResponse\n }\n let text = `/${cmd.name}`\n if (cmd.usage) text += ` ${cmd.usage}`\n text += `\\n${cmd.description}`\n return { type: 'text', text } satisfies CommandResponse\n }\n\n // Auto-generate help from registry at invocation time\n const systemCmds = registry.getByCategory('system')\n const pluginCmds = registry.getByCategory('plugin')\n\n const lines: string[] = []\n\n if (systemCmds.length > 0) {\n lines.push('System Commands:')\n for (const cmd of systemCmds) {\n const usage = cmd.usage ? ` ${cmd.usage}` : ''\n lines.push(` /${cmd.name}${usage} — ${cmd.description}`)\n }\n }\n\n if (pluginCmds.length > 0) {\n if (lines.length > 0) lines.push('')\n lines.push('Plugin Commands:')\n for (const cmd of pluginCmds) {\n const usage = cmd.usage ? ` ${cmd.usage}` : ''\n lines.push(` /${cmd.name}${usage} — ${cmd.description}`)\n }\n }\n\n if (lines.length === 0) {\n return { type: 'text', text: 'No commands registered.' } satisfies CommandResponse\n }\n\n return { type: 'text', text: lines.join('\\n') } satisfies CommandResponse\n },\n })\n}\n","import type { CommandRegistry } from '../command-registry.js'\nimport type { CommandResponse } from '../plugin/types.js'\n\nexport function registerMenuCommand(registry: CommandRegistry, _core: unknown): void {\n registry.register({\n name: 'menu',\n description: 'Show the main menu',\n category: 'system',\n handler: async () => {\n return {\n type: 'menu',\n title: 'Main Menu',\n options: [\n { label: 'New Session', command: '/new' },\n { label: 'Active Sessions', command: '/sessions' },\n { label: 'Available Agents', command: '/agents' },\n { label: 'Usage', command: '/usage' },\n { label: 'Help', command: '/help' },\n ],\n } satisfies CommandResponse\n },\n })\n}\n","import type { CommandRegistry } from '../command-registry.js'\nimport type { CommandResponse } from '../plugin/types.js'\n\nexport function registerSwitchCommands(registry: CommandRegistry): void {\n registry.register({\n name: 'switch',\n description: 'Switch to a different agent',\n usage: '[agent-name | label on|off]',\n category: 'system',\n handler: async (args) => {\n const raw = args.raw.trim()\n\n // /switch label on|off\n if (raw.startsWith('label ')) {\n const value = raw.slice(6).trim().toLowerCase()\n if (value !== 'on' && value !== 'off') {\n return { type: 'error', message: 'Usage: /switch label on|off' } satisfies CommandResponse\n }\n return { type: 'silent' } satisfies CommandResponse\n }\n\n // /switch (no args) → show menu, or /switch <agent> → direct switch\n // Both delegated to adapter handler\n return { type: 'silent' } satisfies CommandResponse\n },\n })\n}\n","import type { CommandRegistry } from '../command-registry.js'\nimport { registerSessionCommands } from './session.js'\nimport { registerAgentCommands } from './agents.js'\nimport { registerAdminCommands } from './admin.js'\nimport { registerHelpCommand } from './help.js'\nimport { registerMenuCommand } from './menu.js'\nimport { registerSwitchCommands } from './switch.js'\n\nexport function registerSystemCommands(registry: CommandRegistry, core: unknown): void {\n registerSessionCommands(registry, core)\n registerAgentCommands(registry, core)\n registerAdminCommands(registry, core)\n registerHelpCommand(registry, core)\n registerMenuCommand(registry, core)\n registerSwitchCommands(registry)\n}\n","import { ensureBinary, type BinarySpec } from './install-binary.js'\n\nconst JQ_SPEC: BinarySpec = {\n name: 'jq',\n githubBaseUrl: 'https://github.com/jqlang/jq/releases/latest/download',\n platforms: {\n darwin: {\n x64: 'jq-macos-amd64',\n arm64: 'jq-macos-arm64',\n },\n win32: {\n x64: 'jq-windows-amd64.exe',\n },\n linux: {\n x64: 'jq-linux-amd64',\n arm64: 'jq-linux-arm64',\n },\n },\n}\n\nexport async function ensureJq(): Promise<string> {\n return ensureBinary(JQ_SPEC)\n}\n","import { createChildLogger } from \"../core/utils/log.js\";\nimport { commandExists } from \"../core/agents/agent-dependencies.js\";\nimport type { Config } from \"../core/config/config.js\";\n\nconst log = createChildLogger({ module: \"post-upgrade\" });\n\n/**\n * Post-upgrade dependency check — runs on every start.\n * Centralized source of truth for all binary dependency management.\n * Silent if everything is OK.\n */\nexport async function runPostUpgradeChecks(config: Config): Promise<void> {\n // 1. Tunnel provider binary\n if (config.tunnel.enabled) {\n if (config.tunnel.provider === \"cloudflare\") {\n try {\n const { ensureCloudflared } = await import(\n \"../plugins/tunnel/providers/install-cloudflared.js\"\n );\n await ensureCloudflared();\n } catch (err) {\n log.warn(\n { err: (err as Error).message },\n \"Could not install cloudflared. Tunnel may not work.\",\n );\n }\n } else {\n if (!commandExists(config.tunnel.provider)) {\n log.warn(\n `Tunnel provider \"${config.tunnel.provider}\" is not installed. Install it or switch to cloudflare (free, auto-installed).`,\n );\n }\n }\n }\n\n // 2. Claude CLI integration + jq\n try {\n const { getIntegration } = await import(\"./integrate.js\");\n const integration = getIntegration(\"claude\");\n if (integration) {\n const allInstalled = integration.items.every((item) => item.isInstalled());\n if (!allInstalled) {\n log.info(\n 'Claude CLI integration not installed. Run \"openacp integrate claude\" for session transfer + tunnel skill.',\n );\n }\n\n const handoff = integration.items.find((i) => i.id === \"handoff\");\n if (handoff?.isInstalled() && !commandExists(\"jq\")) {\n try {\n const { ensureJq } = await import(\"../core/utils/install-jq.js\");\n await ensureJq();\n } catch (err) {\n log.warn(\n { err: (err as Error).message },\n \"Could not install jq. Handoff hooks may not work.\",\n );\n }\n }\n }\n } catch {\n // integrate module not available — skip\n }\n\n // 3. unzip (needed for binary agent installs)\n if (!commandExists(\"unzip\")) {\n log.warn(\n \"unzip is not installed. Some agent installations (binary distribution) may fail. Install: brew install unzip (macOS) or apt install unzip (Linux)\",\n );\n }\n\n // 4. uvx (needed for Python-based agents)\n try {\n const { AgentStore } = await import(\"../core/agents/agent-store.js\");\n const store = new AgentStore();\n store.load();\n const entries = store.getInstalled();\n const hasUvxAgent = Object.values(entries).some(\n (a: { distribution?: string }) => a.distribution === \"uvx\",\n );\n if (hasUvxAgent && !commandExists(\"uvx\")) {\n log.warn(\n \"uvx is not installed but you have Python-based agents. Install: pip install uv\",\n );\n }\n } catch {\n // skip\n }\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { OpenACPPlugin } from './types.js'\n\nlet loadCounter = 0\n\nexport class DevPluginLoader {\n private pluginPath: string\n\n constructor(pluginPath: string) {\n this.pluginPath = path.resolve(pluginPath)\n }\n\n async load(): Promise<OpenACPPlugin> {\n const distIndex = path.join(this.pluginPath, 'dist', 'index.js')\n const srcIndex = path.join(this.pluginPath, 'src', 'index.ts')\n\n if (!fs.existsSync(distIndex) && !fs.existsSync(srcIndex)) {\n throw new Error(`Plugin not found at ${this.pluginPath}. Expected dist/index.js or src/index.ts`)\n }\n\n if (!fs.existsSync(distIndex)) {\n throw new Error(`Built plugin not found at ${distIndex}. Run 'npm run build' first.`)\n }\n\n // Node.js caches ESM imports by URL. Use a unique query string to bust\n // the cache on each reload while keeping the file in its original directory\n // so that relative imports (e.g., './adapter.js') still resolve correctly.\n const cacheBuster = `v=${Date.now()}-${++loadCounter}`\n const mod = await import(`file://${distIndex}?${cacheBuster}`)\n const plugin = mod.default as OpenACPPlugin\n\n if (!plugin || !plugin.name || !plugin.setup) {\n throw new Error(`Invalid plugin at ${distIndex}. Must export default OpenACPPlugin with name and setup().`)\n }\n\n return plugin\n }\n\n getPluginPath(): string {\n return this.pluginPath\n }\n\n getDistPath(): string {\n return path.join(this.pluginPath, 'dist')\n }\n}\n","#!/usr/bin/env node\n\nimport path from 'node:path'\nimport { ConfigManager } from './core/config/config.js'\nimport type { InstanceContext } from './core/instance-context.js'\nimport { createInstanceContext, getGlobalRoot } from './core/instance-context.js'\nimport { OpenACPCore } from './core/core.js'\nimport { initLogger, shutdownLogger, cleanupOldSessionLogs, log, muteLogger, unmuteLogger } from './core/utils/log.js'\nimport { corePlugins } from './plugins/core-plugins.js'\nimport { SettingsManager } from './core/plugin/settings-manager.js'\nimport { PluginRegistry } from './core/plugin/plugin-registry.js'\nimport { CommandRegistry } from './core/command-registry.js'\nimport { registerSystemCommands } from './core/commands/index.js'\nimport type { IChannelAdapter } from './core/channel.js'\nimport type { TunnelService } from './plugins/tunnel/tunnel-service.js'\nimport { InstanceRegistry } from './core/instance-registry.js'\nimport fs from 'node:fs'\n\nexport const RESTART_EXIT_CODE = 75\nlet shuttingDown = false\n\n\nexport interface StartServerOptions {\n devPluginPath?: string\n noWatch?: boolean\n instanceContext?: InstanceContext\n}\n\nexport async function startServer(opts?: StartServerOptions) {\n const ctx = opts?.instanceContext ?? createInstanceContext({\n id: 'main',\n root: getGlobalRoot(),\n isGlobal: true,\n })\n\n // 0. If running as daemon child, check state and write PID file\n if (process.argv.includes('--daemon-child')) {\n const { writePidFile, readPidFile, shouldAutoStart } = await import('./cli/daemon.js')\n\n // Only auto-start if the daemon was previously running (user started it)\n if (!shouldAutoStart(ctx.root)) {\n process.exit(0)\n }\n\n const pidPath = ctx.paths.pid\n const existingPid = readPidFile(pidPath)\n if (existingPid !== null && existingPid !== process.pid) {\n try {\n process.kill(existingPid, 0)\n console.error(`Another OpenACP instance is already running (PID ${existingPid}). Exiting.`)\n process.exit(1)\n } catch {\n // Stale PID file — safe to overwrite\n }\n }\n writePidFile(pidPath, process.pid)\n }\n\n // Create SettingsManager and PluginRegistry early (needed by wizard + boot)\n const settingsManager = new SettingsManager(ctx.paths.pluginsData)\n const pluginRegistry = new PluginRegistry(ctx.paths.pluginRegistry)\n await pluginRegistry.load()\n\n // 1. Check config exists, run setup if not\n const configManager = new ConfigManager(ctx.paths.config)\n const configExists = await configManager.exists()\n\n if (!configExists) {\n const { runSetup } = await import('./core/setup/index.js')\n const shouldStart = await runSetup(configManager, { settingsManager, pluginRegistry })\n if (!shouldStart) process.exit(0)\n }\n\n // 2. Load config (validates with Zod)\n await configManager.load()\n const config = configManager.get()\n initLogger(config.logging)\n log.debug({ configPath: configManager.getConfigPath() }, 'Config loaded')\n\n // First boot: auto-register built-in plugins if registry is empty\n if (pluginRegistry.list().size === 0) {\n await autoRegisterBuiltinPlugins(settingsManager, pluginRegistry, configManager)\n }\n\n // Show banner in foreground TTY mode (not daemon, not piped)\n const isForegroundTTY = !!(process.stdout.isTTY && !process.env.NO_COLOR && config.runMode !== 'daemon')\n if (isForegroundTTY) {\n const { printStartBanner } = await import('./core/setup/index.js')\n await printStartBanner()\n }\n\n // Mute pino during startup, show spinner instead\n let spinner: ReturnType<typeof import('ora').default> | undefined\n if (isForegroundTTY) {\n muteLogger()\n const ora = (await import('ora')).default\n spinner = ora({ text: 'Starting OpenACP...', spinner: 'dots' }).start()\n }\n\n // Post-upgrade dependency check (blocking — must complete before server start)\n try {\n const { runPostUpgradeChecks } = await import('./cli/post-upgrade.js')\n await runPostUpgradeChecks(config)\n } catch (err) {\n log.warn({ err }, 'Post-upgrade check failed')\n }\n\n // Async cleanup of old session logs (non-blocking)\n cleanupOldSessionLogs(config.logging.sessionLogRetentionDays).catch(err =>\n log.warn({ err }, 'Session log cleanup failed')\n )\n\n // 3. Create core\n const core = new OpenACPCore(configManager, ctx)\n\n // 3b. Create CommandRegistry and register as service\n const commandRegistry = new CommandRegistry()\n const serviceRegistry = core.lifecycleManager.serviceRegistry\n serviceRegistry.register('command-registry', commandRegistry, 'core')\n\n // 3c. Register system commands\n registerSystemCommands(commandRegistry, core)\n\n // 4. Boot all plugins (services, infrastructure, adapters)\n try {\n // Emit kernel:booted before plugin boot\n core.eventBus.emit('kernel:booted')\n\n // Pass settingsManager and pluginRegistry to LifecycleManager\n ;(core.lifecycleManager as any).settingsManager = settingsManager\n ;(core.lifecycleManager as any).pluginRegistry = pluginRegistry\n\n // Boot all built-in plugins in dependency order\n await core.lifecycleManager.boot(corePlugins)\n\n // Load community plugins from registry (npm and local sources)\n try {\n const communityPlugins: import('./core/plugin/types.js').OpenACPPlugin[] = []\n const npmPlugins = pluginRegistry.listBySource('npm')\n const localPlugins = pluginRegistry.listBySource('local')\n const allCommunityEntries = new Map([...npmPlugins, ...localPlugins])\n\n for (const [name, entry] of allCommunityEntries) {\n if (!entry.enabled) continue\n\n try {\n let modulePath: string\n\n if (name.startsWith('/') || name.startsWith('.')) {\n // Absolute or relative path (local install via `plugin add /path/to/plugin`)\n const resolved = path.resolve(name)\n const pkgPath = path.join(resolved, 'package.json')\n const pkg = JSON.parse(await fs.promises.readFile(pkgPath, 'utf-8'))\n modulePath = path.join(resolved, pkg.main || 'dist/index.js')\n } else {\n // npm package: try direct name first, then scan node_modules for matching plugin name\n const nodeModulesDir = path.join(ctx.paths.plugins, 'node_modules')\n let pkgDir = path.join(nodeModulesDir, name)\n\n if (!fs.existsSync(path.join(pkgDir, 'package.json'))) {\n // Plugin name doesn't match npm package name — scan installed packages\n // Match by openacp.pluginName field in package.json (no code execution)\n let found = false\n const scopes = fs.existsSync(nodeModulesDir)\n ? fs.readdirSync(nodeModulesDir).filter(d => d.startsWith('@'))\n : []\n for (const scope of scopes) {\n const scopeDir = path.join(nodeModulesDir, scope)\n const pkgs = fs.readdirSync(scopeDir)\n for (const pkg of pkgs) {\n const candidateDir = path.join(scopeDir, pkg)\n const candidatePkgPath = path.join(candidateDir, 'package.json')\n if (fs.existsSync(candidatePkgPath)) {\n try {\n const candidatePkg = JSON.parse(fs.readFileSync(candidatePkgPath, 'utf-8'))\n const pluginName = candidatePkg.openacp?.pluginName as string | undefined\n if (pluginName === name) {\n pkgDir = candidateDir\n found = true\n break\n }\n } catch { /* skip */ }\n }\n }\n if (found) break\n }\n }\n\n const pkgJsonPath = path.join(pkgDir, 'package.json')\n const pkg = JSON.parse(await fs.promises.readFile(pkgJsonPath, 'utf-8'))\n modulePath = path.join(pkgDir, pkg.main || 'dist/index.js')\n }\n\n log.debug({ plugin: name, modulePath }, 'Loading community plugin')\n const mod = await import(modulePath)\n const plugin = mod.default\n\n if (!plugin || !plugin.name || !plugin.setup) {\n log.warn({ plugin: name }, 'Community plugin has invalid exports (missing name or setup), skipping')\n continue\n }\n\n communityPlugins.push(plugin)\n } catch (err) {\n log.warn({ err, plugin: name }, 'Failed to load community plugin, skipping')\n }\n }\n\n if (communityPlugins.length > 0) {\n log.debug({ plugins: communityPlugins.map(p => p.name) }, 'Booting community plugins')\n await core.lifecycleManager.boot(communityPlugins)\n }\n } catch (err) {\n log.warn({ err }, 'Community plugin loading failed')\n }\n\n // Load dev plugin if running in dev mode\n if (opts?.devPluginPath) {\n const { DevPluginLoader } = await import('./core/plugin/dev-loader.js')\n const devLoader = new DevPluginLoader(opts.devPluginPath)\n\n try {\n const devPlugin = await devLoader.load()\n await core.lifecycleManager.boot([devPlugin])\n log.info({ plugin: devPlugin.name, version: devPlugin.version }, 'Dev plugin loaded')\n\n // Watch dist/ directory for changes and hot-reload\n if (!opts.noWatch) {\n const distPath = devLoader.getDistPath()\n let reloadTimer: ReturnType<typeof setTimeout> | null = null\n\n fs.watch(distPath, { recursive: true }, (_eventType, filename) => {\n if (!filename?.endsWith('.js')) return\n\n // Debounce: wait 500ms after last change\n if (reloadTimer) clearTimeout(reloadTimer)\n reloadTimer = setTimeout(async () => {\n try {\n log.info({ filename }, 'Dev plugin changed, reloading...')\n await core.lifecycleManager.unloadPlugin(devPlugin.name)\n const reloaded = await devLoader.load()\n await core.lifecycleManager.boot([reloaded])\n log.info({ plugin: reloaded.name, version: reloaded.version }, 'Dev plugin reloaded')\n } catch (err) {\n log.error({ err }, 'Dev plugin reload failed')\n }\n }, 500)\n })\n\n log.info({ distPath }, 'Watching dev plugin for changes')\n }\n } catch (err) {\n log.error({ err, pluginPath: opts.devPluginPath }, 'Failed to load dev plugin')\n }\n }\n\n // Wire adapters from service registry into core (discovered dynamically)\n for (const { name } of serviceRegistry.list()) {\n if (!name.startsWith('adapter:')) continue\n const adapterName = name.slice('adapter:'.length)\n const adapter = serviceRegistry.get<IChannelAdapter>(name)\n if (adapter) {\n core.registerAdapter(adapterName, adapter)\n log.info({ adapter: adapterName }, 'Adapter registered')\n }\n }\n\n // Wire tunnel service from service registry into core\n const tunnelSvc = serviceRegistry.get<TunnelService>('tunnel')\n if (tunnelSvc) {\n core.tunnelService = tunnelSvc\n }\n\n // Emit system:commands-ready with all registered commands\n core.eventBus.emit('system:commands-ready', { commands: commandRegistry.getAll() })\n\n core.eventBus.emit('system:ready')\n } catch (err) {\n if (spinner) {\n spinner.fail('Plugin boot failed')\n spinner = undefined\n }\n unmuteLogger()\n log.error({ err }, 'Plugin boot failed')\n }\n\n if (core.adapters.size === 0) {\n log.error('No channels enabled. Enable at least one channel in config.')\n process.exit(1)\n }\n\n // 5. Setup shutdown handler\n const shutdown = async (signal: string, exitCode = 0) => {\n if (shuttingDown) return\n shuttingDown = true\n log.info({ signal, exitCode }, 'Signal received, shutting down')\n\n try {\n // 1. Send shutdown notification while plugins are still running\n try {\n const nm = serviceRegistry.get<import('./plugins/notifications/notification.js').NotificationManager>('notifications')\n if (nm) {\n await nm.notifyAll({\n sessionId: 'system',\n type: 'error',\n summary: 'OpenACP is shutting down',\n })\n }\n } catch {\n /* best effort */\n }\n\n // 2. Persist session state (don't kill agent subprocesses — they exit with parent)\n await core.sessionManager.shutdownAll()\n\n // 3. Lifecycle teardown stops all plugins (adapters, api-server, tunnel, etc.)\n await core.lifecycleManager.shutdown()\n // Note: do NOT call core.stop() here — it would double-stop adapters and\n // try to use the notification plugin after it has already been torn down.\n } catch (err) {\n log.error({ err }, 'Error during shutdown')\n }\n\n const isDaemon = process.argv.includes('--daemon-child')\n\n // Clean up PID file if running as daemon\n if (isDaemon) {\n const { removePidFile } = await import('./cli/daemon.js')\n removePidFile(ctx.paths.pid)\n }\n\n // Self-respawn on restart\n if (exitCode === RESTART_EXIT_CODE) {\n if (isDaemon) {\n // Daemon mode: spawn detached child writing to log file\n const { spawn: spawnChild } = await import('node:child_process')\n const { expandHome } = await import('./core/config/config.js')\n const fs = await import('node:fs')\n const pathMod = await import('node:path')\n\n const cliPath = pathMod.resolve(process.argv[1])\n const resolvedLogDir = expandHome(config.logging.logDir)\n fs.mkdirSync(resolvedLogDir, { recursive: true })\n const logFile = pathMod.join(resolvedLogDir, 'openacp.log')\n const out = fs.openSync(logFile, 'a')\n const err = fs.openSync(logFile, 'a')\n\n const child = spawnChild(process.execPath, [cliPath, '--daemon-child'], {\n detached: true,\n stdio: ['ignore', out, err],\n env: { ...process.env, OPENACP_SKIP_UPDATE_CHECK: '1' },\n })\n fs.closeSync(out)\n fs.closeSync(err)\n child.unref()\n log.info({ newPid: child.pid }, 'Respawned daemon for restart')\n } else if (!process.env.OPENACP_DEV_LOOP) {\n // Foreground production mode: spawn replacement process with inherited stdio\n const { spawn: spawnChild } = await import('node:child_process')\n const child = spawnChild(process.execPath, process.argv.slice(1), {\n stdio: 'inherit',\n env: { ...process.env, OPENACP_SKIP_UPDATE_CHECK: '1' },\n })\n await shutdownLogger()\n child.on('exit', (code) => process.exit(code ?? 0))\n return\n }\n }\n\n await shutdownLogger()\n process.exit(exitCode)\n }\n\n // Expose restart trigger for adapters (e.g. /restart command)\n core.requestRestart = () => shutdown('restart', RESTART_EXIT_CODE)\n\n process.on('SIGINT', () => shutdown('SIGINT'))\n process.on('SIGTERM', () => shutdown('SIGTERM'))\n\n process.on('uncaughtException', (err) => {\n log.error({ err }, 'Uncaught exception')\n })\n\n process.on('unhandledRejection', (err) => {\n log.error({ err }, 'Unhandled rejection')\n })\n\n await core.start()\n\n // Auto-register this instance in the global instance registry (backward compat for existing installs)\n try {\n const globalRoot = getGlobalRoot()\n const registryPath = path.join(globalRoot, 'instances.json')\n const instanceReg = new InstanceRegistry(registryPath)\n await instanceReg.load()\n if (!instanceReg.getByRoot(ctx.root)) {\n instanceReg.register(ctx.id, ctx.root)\n await instanceReg.save()\n }\n } catch {\n // Non-critical — don't fail startup if registry write fails\n }\n\n // 6. Log ready\n if (isForegroundTTY) {\n if (spinner) spinner.stop()\n const ok = (msg: string) => console.log(`\\x1b[32m✓\\x1b[0m ${msg}`)\n ok('Config loaded')\n ok('Dependencies checked')\n const tunnelSvc = core.lifecycleManager.serviceRegistry.get<TunnelService>('tunnel')\n if (tunnelSvc) {\n const tunnelUrl = tunnelSvc.getPublicUrl()\n const tunnelErr = tunnelSvc.getStartError()\n if (tunnelErr) {\n console.log(`\\x1b[33m⚠\\x1b[0m Tunnel failed (${tunnelErr}) — viewer links unavailable`)\n } else {\n ok(`Tunnel ready → ${tunnelUrl}`)\n }\n }\n for (const [name] of core.adapters) ok(`${name.charAt(0).toUpperCase() + name.slice(1)} connected`)\n const apiPort = config.api?.port ?? 21420\n if (core.lifecycleManager.serviceRegistry.get('api-server')) ok(`API server on port ${apiPort}`)\n console.log(`\\nOpenACP is running. Press Ctrl+C to stop.\\n`)\n unmuteLogger()\n }\n log.debug({ agents: Object.keys(config.agents) }, 'OpenACP started')\n}\n\n/**\n * Auto-register all built-in plugins when the registry is empty (first boot with new plugin system,\n * or upgrade from legacy config). Also runs legacy config migration for each plugin.\n */\nasync function autoRegisterBuiltinPlugins(\n settingsManager: SettingsManager,\n pluginRegistry: PluginRegistry,\n configManager: ConfigManager,\n): Promise<void> {\n const allPlugins = [\n { name: '@openacp/security', version: '1.0.0', description: 'User access control and session limits' },\n { name: '@openacp/file-service', version: '1.0.0', description: 'File storage and management' },\n { name: '@openacp/context', version: '1.0.0', description: 'Conversation context management' },\n { name: '@openacp/speech', version: '1.0.0', description: 'Text-to-speech and speech-to-text' },\n { name: '@openacp/notifications', version: '1.0.0', description: 'Cross-session notification routing' },\n { name: '@openacp/tunnel', version: '1.0.0', description: 'Expose local services via tunnel' },\n { name: '@openacp/api-server', version: '1.0.0', description: 'REST API + SSE streaming server' },\n { name: '@openacp/telegram', version: '1.0.0', description: 'Telegram adapter with forum topics' },\n ]\n\n // Try to read legacy config for migration\n let legacyConfig: Record<string, unknown> | undefined\n try {\n const cfg = configManager.get()\n if (cfg && typeof cfg === 'object') {\n legacyConfig = cfg as unknown as Record<string, unknown>\n }\n } catch {\n // No config loaded yet — skip migration\n }\n\n // Run legacy migration for each plugin silently\n if (legacyConfig) {\n const pluginModules = await Promise.allSettled([\n import('./plugins/security/index.js'),\n import('./plugins/file-service/index.js'),\n import('./plugins/context/index.js'),\n import('./plugins/speech/index.js'),\n import('./plugins/notifications/index.js'),\n import('./plugins/tunnel/index.js'),\n import('./plugins/api-server/index.js'),\n import('./plugins/telegram/index.js'),\n ])\n\n for (const result of pluginModules) {\n if (result.status !== 'fulfilled') continue\n const plugin = result.value.default\n if (plugin?.install) {\n try {\n // Check if settings already exist\n const existing = await settingsManager.loadSettings(plugin.name)\n if (Object.keys(existing).length > 0) continue\n\n // Create a silent install context for migration only\n const { createInstallContext } = await import('./core/plugin/install-context.js')\n const ctx = createInstallContext({\n pluginName: plugin.name,\n settingsManager,\n basePath: settingsManager.getBasePath(),\n legacyConfig,\n })\n // Override terminal to be silent\n ctx.terminal = createSilentTerminal()\n await plugin.install(ctx)\n } catch {\n // Silently skip — migration is best-effort\n }\n }\n }\n }\n\n for (const p of allPlugins) {\n pluginRegistry.register(p.name, {\n version: p.version,\n source: 'builtin',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(p.name),\n description: p.description,\n })\n }\n await pluginRegistry.save()\n log.info('Built-in plugins registered in plugin registry')\n}\n\n/**\n * Create a no-op terminal for silent migration (no user interaction).\n */\nfunction createSilentTerminal(): import('./core/plugin/types.js').TerminalIO {\n const noop = () => {}\n // Throw on interactive prompts — silent migration should only use log/spinner/note.\n // If a plugin enters interactive mode (no legacy config to migrate), this aborts it\n // so the try-catch in autoRegisterBuiltinPlugins skips it gracefully.\n const abort = () => { throw new Error('Silent migration: no interactive input available') }\n return {\n text: async () => abort() as never,\n select: async () => abort() as never,\n confirm: async () => abort() as never,\n password: async () => abort() as never,\n multiselect: async () => abort() as never,\n log: { info: noop, success: noop, warning: noop, error: noop, step: noop },\n spinner: () => ({ start: noop, stop: noop, fail: noop }),\n note: noop,\n cancel: noop,\n }\n}\n\n// Direct execution for dev (node dist/main.js)\nconst isDirectExecution = process.argv[1]?.endsWith('main.js')\nif (isDirectExecution) {\n startServer().catch((err) => {\n log.error({ err }, 'Fatal error')\n process.exit(1)\n })\n}\n","#!/usr/bin/env node\n\nimport { setDefaultAutoSelectFamily } from \"node:net\";\nsetDefaultAutoSelectFamily(false);\n\nimport path from 'node:path'\nimport {\n printHelp,\n cmdVersion,\n cmdInstall,\n cmdUninstall,\n cmdPlugins,\n cmdPlugin,\n cmdApi,\n cmdStart,\n cmdStop,\n cmdRestart,\n cmdStatus,\n cmdLogs,\n cmdConfig,\n cmdReset,\n cmdUpdate,\n cmdDefault,\n cmdAdopt,\n cmdIntegrate,\n cmdDoctor,\n cmdAgents,\n cmdTunnel,\n cmdOnboard,\n cmdDev,\n} from './cli/commands/index.js'\nimport { resolveInstanceRoot, getGlobalRoot } from './core/instance-context.js'\n\nexport interface InstanceFlags {\n local: boolean\n global: boolean\n dir?: string\n from?: string\n name?: string\n}\n\nfunction extractInstanceFlags(args: string[]): { flags: InstanceFlags; remaining: string[] } {\n const flags: InstanceFlags = { local: false, global: false }\n const remaining: string[] = []\n let i = 0\n while (i < args.length) {\n if (args[i] === '--local') { flags.local = true; i++ }\n else if (args[i] === '--global') { flags.global = true; i++ }\n else if (args[i] === '--dir' && args[i + 1]) { flags.dir = args[i + 1]; i += 2 }\n else if (args[i] === '--from' && args[i + 1]) { flags.from = args[i + 1]; i += 2 }\n else if (args[i] === '--name' && args[i + 1]) { flags.name = args[i + 1]; i += 2 }\n else { remaining.push(args[i]!); i++ }\n }\n return { flags, remaining }\n}\n\nlet resolvedInstanceRoot: string | null = null\nlet instanceFlags: InstanceFlags = { local: false, global: false }\n\nexport function getResolvedInstanceRoot(): string | null {\n return resolvedInstanceRoot\n}\n\nexport function getInstanceFlags(): InstanceFlags {\n return instanceFlags\n}\n\nconst allArgs = process.argv.slice(2)\nconst { flags, remaining } = extractInstanceFlags(allArgs)\ninstanceFlags = flags\nconst [command, ...args] = remaining\n\n// Resolve instance root from flags\nresolvedInstanceRoot = resolveInstanceRoot({\n dir: flags.dir,\n local: flags.local,\n global: flags.global,\n cwd: process.cwd(),\n})\n\nconst root = resolvedInstanceRoot ?? getGlobalRoot()\n\nconst commands: Record<string, () => Promise<void>> = {\n '--help': async () => printHelp(),\n '-h': async () => printHelp(),\n '--version': () => cmdVersion(),\n '-v': () => cmdVersion(),\n 'install': () => cmdInstall(args, root),\n 'uninstall': () => cmdUninstall(args, root),\n 'plugins': () => cmdPlugins(args, root),\n 'plugin': () => cmdPlugin(args, root),\n 'api': () => cmdApi(args),\n 'start': () => cmdStart(args, root),\n 'stop': () => cmdStop(args, root),\n 'restart': () => cmdRestart(args, root),\n 'status': () => cmdStatus(args),\n 'logs': () => cmdLogs(args),\n 'config': () => cmdConfig(args),\n 'reset': () => cmdReset(args, root),\n 'update': () => cmdUpdate(args),\n 'adopt': () => cmdAdopt(args),\n 'integrate': () => cmdIntegrate(args),\n 'doctor': () => cmdDoctor(args),\n 'agents': () => cmdAgents(args),\n 'tunnel': () => cmdTunnel(args),\n 'onboard': () => cmdOnboard(),\n 'dev': () => cmdDev(args),\n '--daemon-child': async () => {\n const { startServer } = await import('./main.js')\n const envRoot = process.env.OPENACP_INSTANCE_ROOT\n if (envRoot) {\n const { createInstanceContext, getGlobalRoot: getGlobal } = await import('./core/instance-context.js')\n const { InstanceRegistry } = await import('./core/instance-registry.js')\n const registry = new InstanceRegistry(path.join(getGlobal(), 'instances.json'))\n await registry.load()\n const entry = registry.getByRoot(envRoot)\n const id = entry?.id ?? 'unknown'\n const ctx = createInstanceContext({\n id,\n root: envRoot,\n isGlobal: envRoot === getGlobal(),\n })\n await startServer({ instanceContext: ctx })\n } else {\n await startServer()\n }\n },\n}\n\nasync function main() {\n const handler = command ? commands[command] : undefined\n if (handler) {\n await handler()\n } else {\n await cmdDefault(command, root)\n }\n}\n\nmain().catch((err) => {\n console.error(\"Fatal:\", err);\n process.exit(1);\n});\n","export function printHelp(): void {\n console.log(`\n\\x1b[1mOpenACP\\x1b[0m — Self-hosted bridge for AI coding agents\nConnect messaging platforms (Telegram, Discord) to 28+ AI coding agents via ACP protocol.\n\n\\x1b[1mGetting Started:\\x1b[0m\n openacp First run launches setup wizard\n openacp After setup, starts the server\n\n\\x1b[1mServer:\\x1b[0m\n openacp Start (mode from config)\n openacp start Start as background daemon\n openacp stop Stop background daemon\n openacp restart Restart background daemon\n openacp status Show daemon status\n openacp logs Tail daemon log file\n openacp --foreground Force foreground mode\n\n\\x1b[1mAgent Management:\\x1b[0m\n openacp agents Browse all agents (installed + available)\n openacp agents install <name> Install an agent from the ACP Registry\n openacp agents uninstall <name> Remove an installed agent\n openacp agents info <name> Show details, dependencies & setup guide\n openacp agents run <name> [-- args] Run agent CLI directly (login, config...)\n openacp agents refresh Force-refresh agent list from registry\n\n \\x1b[2mExamples:\\x1b[0m\n openacp agents install gemini Install Gemini CLI\n openacp agents run gemini Login to Google (first run)\n openacp agents info cursor See setup instructions\n\n\\x1b[1mConfiguration:\\x1b[0m\n openacp config Interactive config editor\n openacp config set <key> <value> Set a config value\n openacp onboard Re-run onboarding setup wizard\n openacp reset Re-run setup wizard\n openacp update Update to latest version\n openacp doctor Run system diagnostics\n openacp doctor --dry-run Check only, don't fix\n\n\\x1b[1mPlugins:\\x1b[0m\n openacp install <package> Install adapter plugin\n openacp uninstall <package> Remove adapter\n openacp plugins List installed plugins\n openacp plugin create Scaffold a new plugin project\n\n\\x1b[1mDevelopment:\\x1b[0m\n openacp dev <plugin-path> Run with local plugin (hot-reload)\n openacp dev <path> --no-watch Run without file watching\n openacp dev <path> --verbose Run with verbose logging\n\n\\x1b[1mSession Transfer:\\x1b[0m\n openacp integrate <agent> Install handoff integration\n openacp integrate <agent> --uninstall\n openacp adopt <agent> <id> Adopt an external session\n\n\\x1b[1mTunnels:\\x1b[0m\n openacp tunnel add <port> [--label name] Create tunnel to local port\n openacp tunnel list List active tunnels\n openacp tunnel stop <port> Stop a tunnel\n openacp tunnel stop-all Stop all user tunnels\n\n\\x1b[1mDaemon API:\\x1b[0m \\x1b[2m(requires running daemon)\\x1b[0m\n openacp api status Active sessions\n openacp api session <id> Session details\n openacp api new [agent] [workspace] Create session\n openacp api send <id> <prompt> Send prompt\n openacp api cancel <id> Cancel session\n openacp api dangerous <id> on|off Toggle dangerous mode\n openacp api topics [--status ...] List topics\n openacp api cleanup [--status ...] Cleanup old topics\n openacp api health System health check\n openacp api restart Restart daemon\n\n\\x1b[1mInstance Flags:\\x1b[0m\n --local Use setup in current directory\n --global Use main setup (~/.openacp)\n --dir <path> Use setup in specified directory\n --from <path> Copy settings from existing setup (on create)\n --name <name> Set instance name (on create)\n\n\\x1b[2mMore info: https://github.com/Open-ACP/OpenACP\\x1b[0m\n`)\n}\n","export async function cmdVersion(): Promise<void> {\n const { getCurrentVersion } = await import(\"../version.js\")\n console.log(`openacp v${getCurrentVersion()}`)\n}\n","import { execSync } from 'node:child_process'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport * as os from 'node:os'\nimport { wantsHelp } from './helpers.js'\n\nexport async function cmdInstall(args: string[], instanceRoot?: string): Promise<void> {\n const root = instanceRoot ?? path.join(os.homedir(), '.openacp')\n const pluginsDir = path.join(root, 'plugins')\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp install\\x1b[0m — Install a plugin adapter\n\n\\x1b[1mUsage:\\x1b[0m\n openacp install <package>\n\n\\x1b[1mArguments:\\x1b[0m\n <package> npm package name (e.g. @openacp/adapter-discord)\n\nInstalls the plugin to ~/.openacp/plugins/.\n\n\\x1b[1mExamples:\\x1b[0m\n openacp install @openacp/adapter-discord\n`)\n return\n }\n const pkg = args[1]\n if (!pkg) {\n console.error(\"Usage: openacp install <package>\")\n process.exit(1)\n }\n fs.mkdirSync(pluginsDir, { recursive: true })\n const pkgPath = path.join(pluginsDir, 'package.json')\n if (!fs.existsSync(pkgPath)) {\n fs.writeFileSync(pkgPath, JSON.stringify({ name: 'openacp-plugins', private: true, dependencies: {} }, null, 2))\n }\n console.log(`Installing ${pkg}...`)\n execSync(`npm install ${pkg} --prefix \"${pluginsDir}\"`, { stdio: 'inherit' })\n console.log(`Plugin ${pkg} installed successfully.`)\n}\n","export function wantsHelp(args: string[]): boolean {\n return args.includes('--help') || args.includes('-h')\n}\n\nexport function buildNestedUpdateFromPath(dotPath: string, value: unknown): Record<string, unknown> {\n const parts = dotPath.split('.')\n const result: Record<string, unknown> = {}\n let target = result\n for (let i = 0; i < parts.length - 1; i++) {\n target[parts[i]] = {}\n target = target[parts[i]] as Record<string, unknown>\n }\n target[parts[parts.length - 1]] = value\n return result\n}\n","import { execSync } from 'node:child_process'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport * as os from 'node:os'\nimport { wantsHelp } from './helpers.js'\n\nexport async function cmdUninstall(args: string[], instanceRoot?: string): Promise<void> {\n const root = instanceRoot ?? path.join(os.homedir(), '.openacp')\n const pluginsDir = path.join(root, 'plugins')\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp uninstall\\x1b[0m — Remove a plugin adapter\n\n\\x1b[1mUsage:\\x1b[0m\n openacp uninstall <package>\n\n\\x1b[1mArguments:\\x1b[0m\n <package> npm package name to remove\n\n\\x1b[1mExamples:\\x1b[0m\n openacp uninstall @openacp/adapter-discord\n`)\n return\n }\n const pkg = args[1]\n if (!pkg) {\n console.error(\"Usage: openacp uninstall <package>\")\n process.exit(1)\n }\n fs.mkdirSync(pluginsDir, { recursive: true })\n const pkgPath = path.join(pluginsDir, 'package.json')\n if (!fs.existsSync(pkgPath)) {\n fs.writeFileSync(pkgPath, JSON.stringify({ name: 'openacp-plugins', private: true, dependencies: {} }, null, 2))\n }\n console.log(`Uninstalling ${pkg}...`)\n execSync(`npm uninstall ${pkg} --prefix \"${pluginsDir}\"`, { stdio: 'inherit' })\n console.log(`Plugin ${pkg} uninstalled.`)\n}\n","import { wantsHelp } from './helpers.js'\n\nexport async function cmdPlugins(args: string[] = [], instanceRoot?: string): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp plugins\\x1b[0m — List installed plugins\n\n\\x1b[1mUsage:\\x1b[0m\n openacp plugins\n\nShows all plugins registered in the plugin registry.\n`)\n return\n }\n\n const os = await import('node:os')\n const path = await import('node:path')\n const { PluginRegistry } = await import('../../core/plugin/plugin-registry.js')\n\n const root = instanceRoot ?? path.join(os.homedir(), '.openacp')\n const registryPath = path.join(root, 'plugins.json')\n const registry = new PluginRegistry(registryPath)\n await registry.load()\n\n const plugins = registry.list()\n if (plugins.size === 0) {\n console.log(\"No plugins installed.\")\n } else {\n console.log(\"Installed plugins:\")\n for (const [name, entry] of plugins) {\n const status = entry.enabled ? '' : ' (disabled)'\n console.log(` ${name}@${entry.version}${status}`)\n }\n }\n}\n\n/**\n * `openacp plugin <subcommand>` — Extended plugin management.\n *\n * Subcommands:\n * list — List all plugins with status (same as `openacp plugins`)\n * add|install <pkg> — Install a plugin package\n * remove|uninstall — Remove a plugin package (--purge to delete data)\n * enable <name> — Enable a plugin\n * disable <name> — Disable a plugin\n * configure <name> — Run interactive configuration for a plugin\n */\nexport async function cmdPlugin(args: string[] = [], instanceRoot?: string): Promise<void> {\n const subcommand = args[1] // args[0] is 'plugin'\n\n if (wantsHelp(args) || !subcommand) {\n console.log(`\n\\x1b[1mopenacp plugin\\x1b[0m — Plugin management\n\n\\x1b[1mUsage:\\x1b[0m\n openacp plugin list List all plugins with status\n openacp plugin search <query> Search the plugin registry\n openacp plugin add <package>[@version] Install a plugin package\n openacp plugin install <package> Alias for add\n openacp plugin remove <package> Remove a plugin package\n openacp plugin uninstall <package> Alias for remove (--purge to delete data)\n openacp plugin enable <name> Enable a plugin\n openacp plugin disable <name> Disable a plugin\n openacp plugin configure <name> Run interactive configuration\n openacp plugin create Scaffold a new plugin project\n\n\\x1b[1mExamples:\\x1b[0m\n openacp plugin list\n openacp plugin search telegram\n openacp plugin add @openacp/adapter-discord\n openacp plugin add translator@1.2.0\n openacp plugin enable @openacp/adapter-discord\n openacp plugin configure @openacp/adapter-discord\n openacp plugin remove @openacp/adapter-discord --purge\n`)\n return\n }\n\n switch (subcommand) {\n case 'list':\n return cmdPlugins(args.slice(1), instanceRoot)\n\n case 'search': {\n const { cmdPluginSearch } = await import('./plugin-search.js')\n await cmdPluginSearch(args.slice(2))\n return\n }\n\n case 'add':\n case 'install': {\n const pkg = args[2]\n if (!pkg) {\n console.error('Error: missing package name. Usage: openacp plugin add <package>')\n process.exit(1)\n }\n await installPlugin(pkg, instanceRoot)\n return\n }\n\n case 'remove':\n case 'uninstall': {\n const pkg = args[2]\n if (!pkg) {\n console.error('Error: missing package name. Usage: openacp plugin remove <package> [--purge]')\n process.exit(1)\n }\n const purge = args.includes('--purge')\n await uninstallPlugin(pkg, purge, instanceRoot)\n return\n }\n\n case 'enable': {\n const name = args[2]\n if (!name) {\n console.error('Error: missing plugin name. Usage: openacp plugin enable <name>')\n process.exit(1)\n }\n await setPluginEnabled(name, true, instanceRoot)\n return\n }\n\n case 'disable': {\n const name = args[2]\n if (!name) {\n console.error('Error: missing plugin name. Usage: openacp plugin disable <name>')\n process.exit(1)\n }\n await setPluginEnabled(name, false, instanceRoot)\n return\n }\n\n case 'configure': {\n const name = args[2]\n if (!name) {\n console.error('Error: missing plugin name. Usage: openacp plugin configure <name>')\n process.exit(1)\n }\n await configurePlugin(name, instanceRoot)\n return\n }\n\n case 'create': {\n const { cmdPluginCreate } = await import('./plugin-create.js')\n await cmdPluginCreate()\n return\n }\n\n default:\n console.error(`Unknown subcommand: ${subcommand}`)\n console.error('Run \"openacp plugin --help\" for usage.')\n process.exit(1)\n }\n}\n\nasync function setPluginEnabled(name: string, enabled: boolean, instanceRoot?: string): Promise<void> {\n const os = await import('node:os')\n const path = await import('node:path')\n const { PluginRegistry } = await import('../../core/plugin/plugin-registry.js')\n\n const root = instanceRoot ?? path.join(os.homedir(), '.openacp')\n const registryPath = path.join(root, 'plugins.json')\n const registry = new PluginRegistry(registryPath)\n await registry.load()\n\n const entry = registry.get(name)\n if (!entry) {\n console.error(`Plugin \"${name}\" not found. Run \"openacp plugin list\" to see installed plugins.`)\n process.exit(1)\n }\n\n registry.setEnabled(name, enabled)\n await registry.save()\n console.log(`Plugin ${name} ${enabled ? 'enabled' : 'disabled'}. Restart to apply.`)\n}\n\nasync function configurePlugin(name: string, instanceRoot?: string): Promise<void> {\n const os = await import('node:os')\n const path = await import('node:path')\n const { corePlugins } = await import('../../plugins/core-plugins.js')\n const { SettingsManager } = await import('../../core/plugin/settings-manager.js')\n const { createInstallContext } = await import('../../core/plugin/install-context.js')\n\n const plugin = corePlugins.find(p => p.name === name)\n if (!plugin) {\n console.error(`Plugin \"${name}\" not found.`)\n process.exit(1)\n }\n\n const root = instanceRoot ?? path.join(os.homedir(), '.openacp')\n const basePath = path.join(root, 'plugins', 'data')\n const settingsManager = new SettingsManager(basePath)\n const ctx = createInstallContext({ pluginName: name, settingsManager, basePath })\n\n if (plugin.configure) {\n await plugin.configure(ctx)\n } else if (plugin.install) {\n await plugin.install(ctx)\n } else {\n console.log(`Plugin ${name} has no configure or install hook.`)\n }\n}\n\nasync function installPlugin(input: string, instanceRoot?: string): Promise<void> {\n const os = await import('node:os')\n const path = await import('node:path')\n const { execFileSync } = await import('node:child_process')\n const { getCurrentVersion } = await import('../version.js')\n const { SettingsManager } = await import('../../core/plugin/settings-manager.js')\n const { createInstallContext } = await import('../../core/plugin/install-context.js')\n const { PluginRegistry } = await import('../../core/plugin/plugin-registry.js')\n\n const root = instanceRoot ?? path.join(os.homedir(), '.openacp')\n\n // Parse input: \"translator\", \"translator@1.2.0\", \"@lucas/pkg@2.0.0\"\n let pkgName: string\n let pkgVersion: string | undefined\n\n // Handle scoped packages: @scope/name@version\n if (input.startsWith('@')) {\n const afterScope = input.indexOf('/', 1)\n if (afterScope === -1) {\n pkgName = input\n } else {\n const rest = input.slice(afterScope + 1)\n const atIdx = rest.indexOf('@')\n if (atIdx !== -1) {\n pkgName = input.slice(0, afterScope + 1 + atIdx)\n pkgVersion = rest.slice(atIdx + 1)\n } else {\n pkgName = input\n }\n }\n } else {\n const atIdx = input.lastIndexOf('@')\n if (atIdx > 0) {\n pkgName = input.slice(0, atIdx)\n pkgVersion = input.slice(atIdx + 1)\n } else {\n pkgName = input\n }\n }\n\n // Try resolve from registry\n const { RegistryClient } = await import('../../core/plugin/registry-client.js')\n const client = new RegistryClient()\n let registryPlugin: any = null\n try {\n const registry = await client.getRegistry()\n registryPlugin = registry.plugins.find(p => p.name === pkgName || p.npm === pkgName)\n if (registryPlugin) {\n console.log(`Resolved from registry: ${pkgName} → ${registryPlugin.npm}`)\n pkgName = registryPlugin.npm\n\n if (!registryPlugin.verified) {\n console.log('⚠️ This plugin is not verified by the OpenACP team.')\n }\n }\n } catch {\n // Registry unavailable\n }\n\n const installSpec = pkgVersion ? `${pkgName}@${pkgVersion}` : pkgName\n console.log(`Installing ${installSpec}...`)\n\n // Check if built-in plugin\n const { corePlugins } = await import('../../plugins/core-plugins.js')\n const builtinPlugin = corePlugins.find(p => p.name === pkgName)\n\n const basePath = path.join(root, 'plugins', 'data')\n const settingsManager = new SettingsManager(basePath)\n const registryPath = path.join(root, 'plugins.json')\n const pluginRegistry = new PluginRegistry(registryPath)\n await pluginRegistry.load()\n\n if (builtinPlugin) {\n // Built-in plugin — run install hook directly\n if (builtinPlugin.install) {\n const ctx = createInstallContext({ pluginName: builtinPlugin.name, settingsManager, basePath })\n await builtinPlugin.install(ctx)\n }\n\n pluginRegistry.register(builtinPlugin.name, {\n version: builtinPlugin.version,\n source: 'builtin',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(builtinPlugin.name),\n description: builtinPlugin.description,\n })\n await pluginRegistry.save()\n console.log(`✓ ${builtinPlugin.name} installed! Restart to activate.`)\n return\n }\n\n // Community plugin — npm install to plugins/\n const pluginsDir = path.join(root, 'plugins')\n const nodeModulesDir = path.join(pluginsDir, 'node_modules')\n\n try {\n execFileSync('npm', ['install', installSpec, '--prefix', pluginsDir, '--save'], {\n stdio: 'inherit',\n timeout: 60000,\n })\n } catch {\n console.error(`Failed to install ${installSpec}. Check the package name and try again.`)\n process.exit(1)\n }\n\n // Read installed plugin's package.json for compatibility check\n const cliVersion = getCurrentVersion()\n const isLocalPath = pkgName.startsWith('/') || pkgName.startsWith('.')\n try {\n const pluginRoot = isLocalPath ? path.resolve(pkgName) : path.join(nodeModulesDir, pkgName)\n const installedPkgPath = path.join(pluginRoot, 'package.json')\n const { readFileSync } = await import('node:fs')\n const installedPkg = JSON.parse(readFileSync(installedPkgPath, 'utf-8'))\n\n // Check engines.openacp compatibility\n const minVersion = installedPkg.engines?.openacp?.replace(/[>=^~\\s]/g, '')\n if (minVersion) {\n const { compareVersions } = await import('../version.js')\n if (compareVersions(cliVersion, minVersion) < 0) {\n console.log(`\\n⚠️ This plugin requires OpenACP >= ${minVersion}. You have ${cliVersion}.`)\n console.log(` Run 'openacp update' to get the latest version.\\n`)\n }\n }\n\n // Try to load and run install hook\n const pluginModule = await import(path.join(pluginRoot, installedPkg.main ?? 'dist/index.js'))\n const plugin = pluginModule.default\n\n if (plugin?.install) {\n const ctx = createInstallContext({ pluginName: plugin.name ?? pkgName, settingsManager, basePath })\n await plugin.install(ctx)\n }\n\n pluginRegistry.register(plugin?.name ?? pkgName, {\n version: installedPkg.version,\n source: 'npm',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(plugin?.name ?? pkgName),\n description: plugin?.description ?? installedPkg.description,\n })\n await pluginRegistry.save()\n\n console.log(`✓ ${plugin?.name ?? pkgName} installed! Restart to activate.`)\n } catch (err) {\n // Plugin installed via npm but no install hook or failed to load — still register\n pluginRegistry.register(pkgName, {\n version: pkgVersion ?? 'unknown',\n source: 'npm',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(pkgName),\n })\n await pluginRegistry.save()\n console.log(`✓ ${pkgName} installed (npm only). Restart to activate.`)\n }\n}\n\nasync function uninstallPlugin(name: string, purge: boolean, instanceRoot?: string): Promise<void> {\n const os = await import('node:os')\n const path = await import('node:path')\n const fs = await import('node:fs')\n const { PluginRegistry } = await import('../../core/plugin/plugin-registry.js')\n\n const root = instanceRoot ?? path.join(os.homedir(), '.openacp')\n const registryPath = path.join(root, 'plugins.json')\n const registry = new PluginRegistry(registryPath)\n await registry.load()\n\n const entry = registry.get(name)\n if (!entry) {\n console.error(`Plugin \"${name}\" not installed.`)\n process.exit(1)\n }\n\n if (entry.source === 'builtin') {\n console.error(`Cannot uninstall built-in plugin. Use \"openacp plugin disable ${name}\" instead.`)\n process.exit(1)\n }\n\n // Try to call uninstall hook\n try {\n const { corePlugins } = await import('../../plugins/core-plugins.js')\n const plugin = corePlugins.find(p => p.name === name)\n if (plugin?.uninstall) {\n const { SettingsManager } = await import('../../core/plugin/settings-manager.js')\n const { createInstallContext } = await import('../../core/plugin/install-context.js')\n const basePath = path.join(root, 'plugins', 'data')\n const settingsManager = new SettingsManager(basePath)\n const ctx = createInstallContext({ pluginName: name, settingsManager, basePath })\n await plugin.uninstall(ctx, { purge })\n }\n } catch {\n // Plugin module might not be loadable, continue\n }\n\n if (purge) {\n const pluginDir = path.join(root, 'plugins', name)\n fs.rmSync(pluginDir, { recursive: true, force: true })\n }\n\n registry.remove(name)\n await registry.save()\n console.log(`Plugin ${name} uninstalled${purge ? ' (purged)' : ''}.`)\n}\n","import { readApiPort, removeStalePortFile, apiCall } from '../api-client.js'\nimport { wantsHelp } from './helpers.js'\n\nfunction printApiHelp(): void {\n console.log(`\n\\x1b[1mopenacp api\\x1b[0m — Interact with the running OpenACP daemon\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api <command> [options]\n\n\\x1b[1mRequires a running daemon.\\x1b[0m Start with: openacp start\n\n\\x1b[1mSession Commands:\\x1b[0m\n openacp api status Show active sessions\n openacp api session <id> Show session details\n openacp api new [agent] [workspace] Create a new session\n [--channel <id>]\n openacp api send <id> <prompt> Send prompt to session\n openacp api cancel <id> Cancel a session\n openacp api dangerous <id> on|off Toggle dangerous mode\n\n\\x1b[1mTopic Commands:\\x1b[0m\n openacp api topics [--status s1,s2] List topics\n openacp api delete-topic <id> [--force] Delete a topic\n openacp api cleanup [--status s1,s2] Cleanup finished topics\n\n\\x1b[1mSystem Commands:\\x1b[0m\n openacp api health Show system health\n openacp api agents List available agents\n openacp api adapters List registered adapters\n openacp api tunnel Show tunnel status\n openacp api config Show runtime config\n openacp api config set <key> <value> Update config value\n openacp api notify <message> Send notification to all channels\n openacp api restart Restart daemon\n openacp api version Show daemon version\n\n\\x1b[1mOptions:\\x1b[0m\n -h, --help Show this help message\n`)\n}\n\nexport async function cmdApi(args: string[]): Promise<void> {\n const subCmd = args[1]\n\n if (wantsHelp(args) && (!subCmd || subCmd === '--help' || subCmd === '-h')) {\n printApiHelp()\n return\n }\n\n // Handle --help for individual api subcommands (before port check)\n if (wantsHelp(args) && subCmd) {\n const apiSubHelp: Record<string, string> = {\n 'status': `\n\\x1b[1mopenacp api status\\x1b[0m — Show active sessions\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api status\n\nLists all active sessions with their ID, agent, status, and name.\n`,\n 'session': `\n\\x1b[1mopenacp api session\\x1b[0m — Show session details\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api session <id>\n\n\\x1b[1mArguments:\\x1b[0m\n <id> Session ID\n\nShows detailed info: agent, status, name, workspace, creation time,\ndangerous mode, queue depth, and channel/thread IDs.\n`,\n 'new': `\n\\x1b[1mopenacp api new\\x1b[0m — Create a new session\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api new [agent] [workspace]\n openacp api new [agent] --workspace <path> [--channel <id>]\n\n\\x1b[1mArguments:\\x1b[0m\n [agent] Agent name (uses default if omitted)\n [workspace] Working directory for the session\n\n\\x1b[1mOptions:\\x1b[0m\n --channel <id> Target adapter (e.g. telegram, discord). Defaults to first registered adapter.\n\n\\x1b[1mExamples:\\x1b[0m\n openacp api new\n openacp api new claude /path/to/project\n openacp api new claude /path/to/project --channel discord\n`,\n 'send': `\n\\x1b[1mopenacp api send\\x1b[0m — Send prompt to a session\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api send <id> <prompt>\n\n\\x1b[1mArguments:\\x1b[0m\n <id> Session ID\n <prompt> Prompt text (all remaining arguments are joined)\n\n\\x1b[1mExamples:\\x1b[0m\n openacp api send abc123 \"Fix the login bug\"\n openacp api send abc123 refactor the auth module\n`,\n 'cancel': `\n\\x1b[1mopenacp api cancel\\x1b[0m — Cancel a session\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api cancel <id>\n\n\\x1b[1mArguments:\\x1b[0m\n <id> Session ID to cancel\n`,\n 'dangerous': `\n\\x1b[1mopenacp api dangerous\\x1b[0m — Toggle dangerous mode for a session\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api dangerous <id> on|off\n\n\\x1b[1mArguments:\\x1b[0m\n <id> Session ID\n on|off Enable or disable dangerous mode\n\nDangerous mode allows the agent to run destructive commands\nwithout confirmation prompts.\n`,\n 'topics': `\n\\x1b[1mopenacp api topics\\x1b[0m — List topics\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api topics [--status <statuses>]\n\n\\x1b[1mOptions:\\x1b[0m\n --status <s1,s2> Filter by status (comma-separated)\n\n\\x1b[1mExamples:\\x1b[0m\n openacp api topics\n openacp api topics --status active,finished\n`,\n 'delete-topic': `\n\\x1b[1mopenacp api delete-topic\\x1b[0m — Delete a topic\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api delete-topic <id> [--force]\n\n\\x1b[1mArguments:\\x1b[0m\n <id> Session ID of the topic to delete\n\n\\x1b[1mOptions:\\x1b[0m\n --force Delete even if session is active\n`,\n 'cleanup': `\n\\x1b[1mopenacp api cleanup\\x1b[0m — Cleanup finished topics\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api cleanup [--status <statuses>]\n\n\\x1b[1mOptions:\\x1b[0m\n --status <s1,s2> Filter by status (comma-separated, default: finished topics)\n\n\\x1b[1mExamples:\\x1b[0m\n openacp api cleanup\n openacp api cleanup --status finished,error\n`,\n 'health': `\n\\x1b[1mopenacp api health\\x1b[0m — Show system health\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api health\n\nShows status, uptime, version, memory usage, session counts,\nregistered adapters, and tunnel status.\n`,\n 'agents': `\n\\x1b[1mopenacp api agents\\x1b[0m — List available agents from running daemon\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api agents\n\nLists agents configured in the running daemon with their names\nand which one is the default.\n`,\n 'adapters': `\n\\x1b[1mopenacp api adapters\\x1b[0m — List registered adapters\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api adapters\n\nShows all channel adapters registered with the running daemon.\n`,\n 'tunnel': `\n\\x1b[1mopenacp api tunnel\\x1b[0m — Show tunnel status\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api tunnel\n\nShows whether a tunnel is enabled, the provider, and the URL.\n`,\n 'config': `\n\\x1b[1mopenacp api config\\x1b[0m — Show or update runtime config\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api config Show current runtime config\n openacp api config set <key> <value> Update a config value\n\n\\x1b[2mNote: Prefer 'openacp config' instead — it works whether daemon is running or not.\\x1b[0m\n`,\n 'restart': `\n\\x1b[1mopenacp api restart\\x1b[0m — Restart the daemon\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api restart\n\nSends a restart signal to the running daemon.\n`,\n 'notify': `\n\\x1b[1mopenacp api notify\\x1b[0m — Send notification to all channels\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api notify <message>\n\n\\x1b[1mArguments:\\x1b[0m\n <message> Notification text (all remaining arguments are joined)\n\n\\x1b[1mExamples:\\x1b[0m\n openacp api notify \"Deployment complete\"\n`,\n 'version': `\n\\x1b[1mopenacp api version\\x1b[0m — Show daemon version\n\n\\x1b[1mUsage:\\x1b[0m\n openacp api version\n\nShows the version of the currently running daemon process.\n`,\n }\n const help = apiSubHelp[subCmd]\n if (help) {\n console.log(help)\n return\n }\n // Unknown subcommand with --help, show general help\n printApiHelp()\n return\n }\n\n const port = readApiPort()\n if (port === null) {\n console.error('OpenACP is not running. Start with `openacp start`')\n process.exit(1)\n }\n\n try {\n if (subCmd === 'new') {\n const agent = args[2]\n const workspaceIdx = args.indexOf('--workspace')\n const workspace = workspaceIdx !== -1 ? args[workspaceIdx + 1] : args[3]\n const channelIdx = args.indexOf('--channel')\n const channel = channelIdx !== -1 ? args[channelIdx + 1] : undefined\n const body: Record<string, string> = {}\n if (agent) body.agent = agent\n if (workspace) body.workspace = workspace\n if (channel) body.channel = channel\n\n const res = await apiCall(port, '/api/sessions', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log('Session created')\n console.log(` ID : ${data.sessionId}`)\n console.log(` Agent : ${data.agent}`)\n console.log(` Workspace : ${data.workspace}`)\n console.log(` Status : ${data.status}`)\n\n } else if (subCmd === 'cancel') {\n const sessionId = args[2]\n if (!sessionId) {\n console.error('Usage: openacp api cancel <session-id>')\n process.exit(1)\n }\n const res = await apiCall(port, `/api/sessions/${encodeURIComponent(sessionId)}`, {\n method: 'DELETE',\n })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log(`Session ${sessionId} cancelled`)\n\n } else if (subCmd === 'status') {\n const res = await apiCall(port, '/api/sessions')\n const data = await res.json() as { sessions: Array<{ id: string; agent: string; status: string; name: string | null }> }\n if (data.sessions.length === 0) {\n console.log('No active sessions.')\n } else {\n console.log(`Active sessions: ${data.sessions.length}\\n`)\n for (const s of data.sessions) {\n const name = s.name ? ` \"${s.name}\"` : ''\n console.log(` ${s.id} ${s.agent} ${s.status}${name}`)\n }\n }\n\n } else if (subCmd === 'agents') {\n const res = await apiCall(port, '/api/agents')\n const data = await res.json() as { agents: Array<{ name: string; command: string; args: string[] }>; default: string }\n console.log('Available agents:')\n for (const a of data.agents) {\n const isDefault = a.name === data.default ? ' (default)' : ''\n console.log(` ${a.name}${isDefault}`)\n }\n\n } else if (subCmd === 'topics') {\n const statusIdx = args.indexOf('--status')\n const statusParam = statusIdx !== -1 ? args[statusIdx + 1] : undefined\n const query = statusParam ? `?status=${encodeURIComponent(statusParam)}` : ''\n const res = await apiCall(port, `/api/topics${query}`)\n const data = await res.json() as { topics: Array<{ sessionId: string; topicId: number | null; name: string | null; status: string; agentName: string; lastActiveAt: string }> }\n if (data.topics.length === 0) {\n console.log('No topics found.')\n } else {\n console.log(`Topics: ${data.topics.length}\\n`)\n for (const t of data.topics) {\n const name = t.name ? ` \"${t.name}\"` : ''\n const topic = t.topicId ? `Topic #${t.topicId}` : 'headless'\n console.log(` ${t.sessionId} ${t.agentName} ${t.status}${name} ${topic}`)\n }\n }\n\n } else if (subCmd === 'delete-topic') {\n const sessionId = args[2]\n if (!sessionId) {\n console.error('Usage: openacp api delete-topic <session-id> [--force]')\n process.exit(1)\n }\n const force = args.includes('--force')\n const query = force ? '?force=true' : ''\n const res = await apiCall(port, `/api/topics/${encodeURIComponent(sessionId)}${query}`, { method: 'DELETE' })\n const data = await res.json() as Record<string, unknown>\n if (res.status === 409) {\n const session = data.session as Record<string, unknown> | undefined\n console.error(`Session \"${sessionId}\" is active (${session?.status}). Use --force to delete.`)\n process.exit(1)\n }\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n const topicLabel = data.topicId ? `Topic #${data.topicId}` : 'headless session'\n console.log(`${topicLabel} deleted (session ${sessionId})`)\n\n } else if (subCmd === 'cleanup') {\n const statusIdx = args.indexOf('--status')\n const statusParam = statusIdx !== -1 ? args[statusIdx + 1] : undefined\n const body: Record<string, unknown> = {}\n if (statusParam) body.statuses = statusParam.split(',')\n const res = await apiCall(port, '/api/topics/cleanup', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n const data = await res.json() as { deleted: string[]; failed: Array<{ sessionId: string; error: string }> }\n if (data.deleted.length === 0 && data.failed.length === 0) {\n console.log('Nothing to clean up.')\n } else {\n console.log(`Cleaned up ${data.deleted.length} topics${data.deleted.length ? ': ' + data.deleted.join(', ') : ''} (${data.failed.length} failed)`)\n for (const f of data.failed) {\n console.error(` Failed: ${f.sessionId} — ${f.error}`)\n }\n }\n\n } else if (subCmd === 'send') {\n const sessionId = args[2]\n if (!sessionId) {\n console.error('Usage: openacp api send <session-id> <prompt>')\n process.exit(1)\n }\n const prompt = args.slice(3).join(' ')\n if (!prompt) {\n console.error('Usage: openacp api send <session-id> <prompt>')\n process.exit(1)\n }\n const res = await apiCall(port, `/api/sessions/${encodeURIComponent(sessionId)}/prompt`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ prompt }),\n })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log(`Prompt sent to session ${sessionId} (queue depth: ${data.queueDepth})`)\n\n } else if (subCmd === 'session') {\n const sessionId = args[2]\n if (!sessionId) {\n console.error('Usage: openacp api session <session-id>')\n process.exit(1)\n }\n const res = await apiCall(port, `/api/sessions/${encodeURIComponent(sessionId)}`)\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n const s = (data.session ?? data) as Record<string, unknown>\n console.log(`Session details:`)\n console.log(` ID : ${s.id}`)\n console.log(` Agent : ${s.agent}`)\n console.log(` Status : ${s.status}`)\n console.log(` Name : ${s.name ?? '(none)'}`)\n console.log(` Workspace : ${s.workspace}`)\n console.log(` Created : ${s.createdAt}`)\n console.log(` Dangerous : ${s.dangerousMode}`)\n console.log(` Queue depth : ${s.queueDepth}`)\n console.log(` Prompt active : ${s.promptRunning}`)\n console.log(` Channel : ${s.channelId ?? '(none)'}`)\n console.log(` Thread : ${s.threadId ?? '(none)'}`)\n\n } else if (subCmd === 'dangerous') {\n const sessionId = args[2]\n if (!sessionId) {\n console.error('Usage: openacp api dangerous <session-id> [on|off]')\n process.exit(1)\n }\n const toggle = args[3]\n if (!toggle || (toggle !== 'on' && toggle !== 'off')) {\n console.error('Usage: openacp api dangerous <session-id> [on|off]')\n process.exit(1)\n }\n const res = await apiCall(port, `/api/sessions/${encodeURIComponent(sessionId)}/dangerous`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ enabled: toggle === 'on' }),\n })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n const state = toggle === 'on' ? 'enabled' : 'disabled'\n console.log(`Dangerous mode ${state} for session ${sessionId}`)\n\n } else if (subCmd === 'health') {\n const res = await apiCall(port, '/api/health')\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n const uptimeMs = typeof data.uptime === 'number' ? data.uptime : 0\n const uptimeSeconds = Math.floor(uptimeMs / 1000)\n const hours = Math.floor(uptimeSeconds / 3600)\n const minutes = Math.floor((uptimeSeconds % 3600) / 60)\n const mem = data.memory as Record<string, number> | undefined\n const memoryMB = mem ? (mem.rss / 1024 / 1024).toFixed(1) : '0.0'\n const sessions = data.sessions as Record<string, unknown> ?? {}\n const tunnel = data.tunnel as Record<string, unknown> | undefined\n const tunnelStr = tunnel?.enabled ? `${tunnel.url}` : 'disabled'\n const adapters = Array.isArray(data.adapters) ? data.adapters.join(', ') : String(data.adapters ?? 'none')\n console.log(`Status : ${data.status}`)\n console.log(`Uptime : ${hours}h ${minutes}m`)\n console.log(`Version : ${data.version}`)\n console.log(`Memory : ${memoryMB} MB`)\n console.log(`Sessions : ${sessions.active ?? 0} active / ${sessions.total ?? 0} total`)\n console.log(`Adapters : ${adapters}`)\n console.log(`Tunnel : ${tunnelStr}`)\n\n } else if (subCmd === 'restart') {\n const res = await apiCall(port, '/api/restart', { method: 'POST' })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log('Restart signal sent. OpenACP is restarting...')\n\n } else if (subCmd === 'config') {\n console.warn('⚠️ Deprecated: use \"openacp config\" or \"openacp config set\" instead.')\n const subSubCmd = args[2]\n if (!subSubCmd) {\n const res = await apiCall(port, '/api/config')\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log(JSON.stringify(data.config, null, 2))\n } else if (subSubCmd === 'set') {\n const configPath = args[3]\n const configValue = args[4]\n if (!configPath || configValue === undefined) {\n console.error('Usage: openacp api config set <path> <value>')\n process.exit(1)\n }\n let value: unknown = configValue\n try {\n value = JSON.parse(configValue)\n } catch {\n // keep as string\n }\n const res = await apiCall(port, '/api/config', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: configPath, value }),\n })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log(`Config updated: ${configPath} = ${JSON.stringify(value)}`)\n if (data.needsRestart) {\n console.log('Note: restart required for this change to take effect.')\n }\n } else {\n console.error(`Unknown config subcommand: ${subSubCmd}`)\n console.log(' openacp api config Show runtime config')\n console.log(' openacp api config set <key> <value> Update config value')\n process.exit(1)\n }\n\n } else if (subCmd === 'adapters') {\n const res = await apiCall(port, '/api/adapters')\n const data = await res.json() as { adapters: Array<{ name: string; type: string }> }\n if (!res.ok) {\n console.error(`Error: ${(data as Record<string, unknown>).error}`)\n process.exit(1)\n }\n console.log('Registered adapters:')\n for (const a of data.adapters) {\n console.log(` ${a.name} (${a.type})`)\n }\n\n } else if (subCmd === 'tunnel') {\n const res = await apiCall(port, '/api/tunnel')\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n if (data.enabled) {\n console.log(`Tunnel provider : ${data.provider}`)\n console.log(`Tunnel URL : ${data.url}`)\n } else {\n console.log('Tunnel: not enabled')\n }\n\n } else if (subCmd === 'notify') {\n const message = args.slice(2).join(' ')\n if (!message) {\n console.error('Usage: openacp api notify <message>')\n process.exit(1)\n }\n const res = await apiCall(port, '/api/notify', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ message }),\n })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log('Notification sent to all channels.')\n\n } else if (subCmd === 'version') {\n const res = await apiCall(port, '/api/version')\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log(`Daemon version: ${data.version}`)\n\n } else {\n const { suggestMatch } = await import('../suggest.js')\n const apiSubcommands = [\n 'new', 'cancel', 'status', 'agents', 'topics', 'delete-topic',\n 'cleanup', 'send', 'session', 'dangerous', 'health', 'restart',\n 'config', 'adapters', 'tunnel', 'notify', 'version',\n ]\n const suggestion = suggestMatch(subCmd ?? '', apiSubcommands)\n console.error(`Unknown api command: ${subCmd || '(none)'}\\n`)\n if (suggestion) console.error(`Did you mean: ${suggestion}?\\n`)\n printApiHelp()\n process.exit(1)\n }\n } catch (err) {\n if (err instanceof TypeError && (err.cause as Record<string, unknown> | undefined)?.code === 'ECONNREFUSED') {\n console.error('OpenACP is not running (stale port file)')\n removeStalePortFile()\n process.exit(1)\n }\n throw err\n }\n}\n","import { checkAndPromptUpdate } from '../version.js'\nimport { wantsHelp } from './helpers.js'\nimport path from 'node:path'\nimport os from 'node:os'\n\nexport async function cmdStart(args: string[] = [], instanceRoot?: string): Promise<void> {\n const root = instanceRoot ?? path.join(os.homedir(), '.openacp')\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp start\\x1b[0m — Start OpenACP as a background daemon\n\n\\x1b[1mUsage:\\x1b[0m\n openacp start\n\nStarts the server as a background process (daemon mode).\nRequires an existing config — run 'openacp' first to set up.\n\n\\x1b[1mSee also:\\x1b[0m\n openacp stop Stop the daemon\n openacp restart Restart the daemon\n openacp status Check if daemon is running\n openacp logs Tail daemon log file\n`)\n return\n }\n await checkAndPromptUpdate()\n const { startDaemon, getPidPath } = await import('../daemon.js')\n const { ConfigManager } = await import('../../core/config/config.js')\n const cm = new ConfigManager()\n if (await cm.exists()) {\n await cm.load()\n const config = cm.get()\n const result = startDaemon(getPidPath(root), config.logging.logDir, root)\n if ('error' in result) {\n console.error(result.error)\n process.exit(1)\n }\n console.log(`OpenACP daemon started (PID ${result.pid})`)\n } else {\n console.error('No config found. Run \"openacp\" first to set up.')\n process.exit(1)\n }\n}\n","import { wantsHelp } from './helpers.js'\nimport path from 'node:path'\nimport os from 'node:os'\n\nexport async function cmdStop(args: string[] = [], instanceRoot?: string): Promise<void> {\n const root = instanceRoot ?? path.join(os.homedir(), '.openacp')\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp stop\\x1b[0m — Stop the background daemon\n\n\\x1b[1mUsage:\\x1b[0m\n openacp stop\n\nSends a stop signal to the running OpenACP daemon process.\n`)\n return\n }\n const { stopDaemon, getPidPath } = await import('../daemon.js')\n const result = await stopDaemon(getPidPath(root), root)\n if (result.stopped) {\n console.log(`OpenACP daemon stopped (was PID ${result.pid})`)\n } else {\n console.error(result.error)\n process.exit(1)\n }\n}\n","import { wantsHelp } from './helpers.js'\nimport path from 'node:path'\nimport os from 'node:os'\n\nexport async function cmdRestart(args: string[] = [], instanceRoot?: string): Promise<void> {\n const root = instanceRoot ?? path.join(os.homedir(), '.openacp')\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp restart\\x1b[0m — Restart the background daemon\n\n\\x1b[1mUsage:\\x1b[0m\n openacp restart\n\nStops the running daemon (if any) and starts a new one.\n\n\\x1b[1mSee also:\\x1b[0m\n openacp start Start the daemon\n openacp stop Stop the daemon\n openacp status Check if daemon is running\n`)\n return\n }\n\n const { stopDaemon, startDaemon, getPidPath } = await import('../daemon.js')\n const { ConfigManager } = await import('../../core/config/config.js')\n const { checkAndPromptUpdate } = await import('../version.js')\n\n await checkAndPromptUpdate()\n\n const pidPath = getPidPath(root)\n\n // Stop existing daemon (ignore errors — it may not be running)\n const stopResult = await stopDaemon(pidPath, root)\n if (stopResult.stopped) {\n console.log(`Stopped daemon (was PID ${stopResult.pid})`)\n }\n\n // Start new daemon\n const cm = new ConfigManager()\n if (await cm.exists()) {\n await cm.load()\n const config = cm.get()\n const result = startDaemon(pidPath, config.logging.logDir, root)\n if ('error' in result) {\n console.error(result.error)\n process.exit(1)\n }\n console.log(`OpenACP daemon started (PID ${result.pid})`)\n } else {\n console.error('No config found. Run \"openacp\" first to set up.')\n process.exit(1)\n }\n}\n","import { InstanceRegistry } from '../../core/instance-registry.js'\nimport { getGlobalRoot } from '../../core/instance-context.js'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\n\nexport async function cmdStatus(args: string[] = [], instanceRoot?: string): Promise<void> {\n // Handle --all flag\n if (args.includes('--all')) {\n await showAllInstances()\n return\n }\n\n // Handle --id flag\n const idIdx = args.indexOf('--id')\n if (idIdx !== -1 && args[idIdx + 1]) {\n await showInstanceById(args[idIdx + 1]!)\n return\n }\n\n // Default: show status of current/specified instance\n const root = instanceRoot ?? getGlobalRoot()\n await showSingleInstance(root)\n}\n\nasync function showAllInstances(): Promise<void> {\n const registryPath = path.join(getGlobalRoot(), 'instances.json')\n const registry = new InstanceRegistry(registryPath)\n await registry.load()\n const instances = registry.list()\n\n if (instances.length === 0) {\n console.log('No instances registered.')\n return\n }\n\n // Print table header\n console.log('')\n console.log(' Status ID Name Directory Mode Channels API Tunnel')\n console.log(' ' + '─'.repeat(100))\n\n for (const entry of instances) {\n const info = readInstanceInfo(entry.root)\n const status = info.pid ? '● online' : '○ offline'\n const mode = info.pid ? (info.runMode === 'daemon' ? 'daemon' : 'fg') : '—'\n const api = info.apiPort ? String(info.apiPort) : '—'\n const tunnel = info.tunnelPort ? String(info.tunnelPort) : '—'\n const dir = entry.root.replace(/\\/.openacp$/, '').replace(os.homedir(), '~')\n const channels = info.channels.join(', ') || '—'\n const name = info.name ?? entry.id\n\n console.log(` ${status.padEnd(10)} ${entry.id.padEnd(16)} ${name.padEnd(16)} ${dir.padEnd(20)} ${mode.padEnd(8)} ${channels.padEnd(10)} ${api.padEnd(6)} ${tunnel}`)\n }\n console.log('')\n}\n\nasync function showInstanceById(id: string): Promise<void> {\n const registryPath = path.join(getGlobalRoot(), 'instances.json')\n const registry = new InstanceRegistry(registryPath)\n await registry.load()\n const entry = registry.get(id)\n if (!entry) {\n console.error(`Instance \"${id}\" not found.`)\n process.exit(1)\n }\n await showSingleInstance(entry.root)\n}\n\nasync function showSingleInstance(root: string): Promise<void> {\n // Read PID and check if running\n const info = readInstanceInfo(root)\n\n if (info.pid) {\n console.log(`OpenACP is running (PID ${info.pid})`)\n if (info.name) console.log(` Name: ${info.name}`)\n if (info.apiPort) console.log(` API: port ${info.apiPort}`)\n if (info.tunnelPort) console.log(` Tunnel: port ${info.tunnelPort}`)\n if (info.channels.length > 0) console.log(` Channels: ${info.channels.join(', ')}`)\n } else {\n console.log('OpenACP is not running.')\n }\n}\n\nexport interface InstanceInfo {\n name: string | null\n pid: number | null\n apiPort: number | null\n tunnelPort: number | null\n runMode: string | null\n channels: string[]\n}\n\nexport function readInstanceInfo(root: string): InstanceInfo {\n const result: InstanceInfo = {\n name: null, pid: null, apiPort: null,\n tunnelPort: null, runMode: null, channels: [],\n }\n\n // Read name and runMode from config\n try {\n const config = JSON.parse(fs.readFileSync(path.join(root, 'config.json'), 'utf-8'))\n result.name = config.instanceName ?? null\n result.runMode = config.runMode ?? null\n } catch {}\n\n // Read PID and check if alive\n try {\n const pid = parseInt(fs.readFileSync(path.join(root, 'openacp.pid'), 'utf-8').trim())\n if (!isNaN(pid)) {\n process.kill(pid, 0) // throws if process doesn't exist\n result.pid = pid\n }\n } catch {}\n\n // Read API port\n try {\n const port = parseInt(fs.readFileSync(path.join(root, 'api.port'), 'utf-8').trim())\n if (!isNaN(port)) result.apiPort = port\n } catch {}\n\n // Read tunnel port from tunnels.json\n try {\n const tunnels = JSON.parse(fs.readFileSync(path.join(root, 'tunnels.json'), 'utf-8'))\n const entries = Object.values(tunnels) as any[]\n const systemEntry = entries.find((t: any) => t.type === 'system')\n if (systemEntry?.port) result.tunnelPort = systemEntry.port\n } catch {}\n\n // Read enabled channels from plugins.json\n try {\n const plugins = JSON.parse(fs.readFileSync(path.join(root, 'plugins.json'), 'utf-8'))\n const adapters = ['@openacp/telegram', '@openacp/discord', '@openacp/slack']\n for (const name of adapters) {\n if (plugins.installed?.[name] && plugins.installed[name].enabled !== false) {\n result.channels.push(name.replace('@openacp/', ''))\n }\n }\n } catch {}\n\n return result\n}\n","import { wantsHelp } from './helpers.js'\n\nexport async function cmdLogs(args: string[] = []): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp logs\\x1b[0m — Tail daemon log file\n\n\\x1b[1mUsage:\\x1b[0m\n openacp logs\n\nStreams the last 50 lines of the OpenACP log file and\nfollows new output (like tail -f). Press Ctrl+C to stop.\n\nLog file location is configured in config (default: ~/.openacp/logs/).\n`)\n return\n }\n const { spawn } = await import('node:child_process')\n const { ConfigManager, expandHome } = await import('../../core/config/config.js')\n const pathMod = await import('node:path')\n const cm = new ConfigManager()\n let logDir = '~/.openacp/logs'\n if (await cm.exists()) {\n await cm.load()\n logDir = cm.get().logging.logDir\n }\n const logFile = pathMod.join(expandHome(logDir), 'openacp.log')\n const tail = spawn('tail', ['-f', '-n', '50', logFile], { stdio: 'inherit' })\n tail.on('error', (err: Error) => {\n console.error(`Cannot tail log file: ${err.message}`)\n process.exit(1)\n })\n}\n","import { readApiPort, apiCall } from '../api-client.js'\nimport { wantsHelp, buildNestedUpdateFromPath } from './helpers.js'\n\nexport async function cmdConfig(args: string[] = []): Promise<void> {\n const subCmd = args[1] // 'set' or undefined\n\n if (wantsHelp(args) && subCmd === 'set') {\n console.log(`\n\\x1b[1mopenacp config set\\x1b[0m — Set a config value directly\n\n\\x1b[1mUsage:\\x1b[0m\n openacp config set <key> <value>\n\n\\x1b[1mArguments:\\x1b[0m\n <key> Dot-notation config path (e.g. telegram.botToken)\n <value> New value (JSON-parsed if possible, otherwise string)\n\n\\x1b[1mOptions:\\x1b[0m\n -h, --help Show this help message\n\nWorks with both running and stopped daemon. When running, uses\nthe API for live updates. When stopped, edits config file directly.\n\n\\x1b[1mExamples:\\x1b[0m\n openacp config set defaultAgent claude\n openacp config set security.maxConcurrentSessions 5\n openacp config set telegram.botToken \"123:ABC\"\n`)\n return\n }\n\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp config\\x1b[0m — View and edit configuration\n\n\\x1b[1mUsage:\\x1b[0m\n openacp config Open interactive config editor\n openacp config set <key> <value> Set a config value directly\n\n\\x1b[1mOptions:\\x1b[0m\n -h, --help Show this help message\n\nWorks with both running and stopped daemon. When running, uses\nthe API for live updates. When stopped, edits config file directly.\n\n\\x1b[1mExamples:\\x1b[0m\n openacp config\n openacp config set defaultAgent claude\n\n\\x1b[2mRun 'openacp config set --help' for more info on the set subcommand.\\x1b[0m\n`)\n return\n }\n\n if (subCmd === 'set') {\n // Non-interactive: openacp config set <key> <value>\n const configPath = args[2]\n const configValue = args[3]\n if (!configPath || configValue === undefined) {\n console.error('Usage: openacp config set <path> <value>')\n process.exit(1)\n }\n\n // Validate top-level config key\n const { ConfigSchema } = await import('../../core/config/config.js')\n const topLevelKey = configPath.split('.')[0]\n const validConfigKeys = Object.keys(ConfigSchema.shape)\n if (!validConfigKeys.includes(topLevelKey)) {\n const { suggestMatch } = await import('../suggest.js')\n const suggestion = suggestMatch(topLevelKey, validConfigKeys)\n console.error(`Unknown config key: ${topLevelKey}`)\n if (suggestion) console.error(`Did you mean: ${suggestion}?`)\n process.exit(1)\n }\n\n let value: unknown = configValue\n try { value = JSON.parse(configValue) } catch { /* keep as string */ }\n\n const port = readApiPort()\n if (port !== null) {\n // Server running — use API\n const res = await apiCall(port, '/api/config', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path: configPath, value }),\n })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log(`Config updated: ${configPath} = ${JSON.stringify(value)}`)\n if (data.needsRestart) {\n console.log('Note: restart required for this change to take effect.')\n }\n } else {\n // Server not running — update file directly\n const { ConfigManager } = await import('../../core/config/config.js')\n const cm = new ConfigManager()\n if (!(await cm.exists())) {\n console.error('No config found. Run \"openacp\" first to set up.')\n process.exit(1)\n }\n await cm.load()\n const updates = buildNestedUpdateFromPath(configPath, value)\n await cm.save(updates)\n console.log(`Config updated: ${configPath} = ${JSON.stringify(value)}`)\n }\n return\n }\n\n // Interactive editor\n const { runConfigEditor } = await import('../../core/config/config-editor.js')\n const { ConfigManager } = await import('../../core/config/config.js')\n const cm = new ConfigManager()\n if (!(await cm.exists())) {\n console.error('No config found. Run \"openacp\" first to set up.')\n process.exit(1)\n }\n\n const port = readApiPort()\n if (port !== null) {\n await runConfigEditor(cm, 'api', port)\n } else {\n await runConfigEditor(cm, 'file')\n }\n}\n","import { wantsHelp } from './helpers.js'\n\nexport async function cmdReset(args: string[] = [], instanceRoot?: string): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp reset\\x1b[0m — Re-run setup wizard\n\n\\x1b[1mUsage:\\x1b[0m\n openacp reset\n\nDeletes all OpenACP data (~/.openacp) and allows you to\nstart fresh with the setup wizard. The daemon must be stopped first.\n\n\\x1b[1m\\x1b[31mThis is destructive\\x1b[0m — config, plugins, agent data will be removed.\n`)\n return\n }\n const os = await import('node:os')\n const path = await import('node:path')\n const root = instanceRoot ?? path.join(os.homedir(), '.openacp')\n\n const { getStatus, getPidPath } = await import('../daemon.js')\n const status = getStatus(getPidPath(root))\n if (status.running) {\n console.error('OpenACP is running. Stop it first: openacp stop')\n process.exit(1)\n }\n\n const clack = await import('@clack/prompts')\n const yes = await clack.confirm({\n message: 'This will delete all OpenACP data (~/.openacp). You will need to set up again. Continue?',\n initialValue: false,\n })\n if (clack.isCancel(yes) || !yes) {\n console.log('Aborted.')\n return\n }\n\n const { uninstallAutoStart } = await import('../autostart.js')\n uninstallAutoStart()\n\n const fs = await import('node:fs')\n fs.rmSync(root, { recursive: true, force: true })\n\n console.log('Reset complete. Run `openacp` to set up again.')\n}\n","import { getCurrentVersion, getLatestVersion, compareVersions, runUpdate } from '../version.js'\nimport { wantsHelp } from './helpers.js'\n\nexport async function cmdUpdate(args: string[] = []): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp update\\x1b[0m — Update to latest version\n\n\\x1b[1mUsage:\\x1b[0m\n openacp update\n\nChecks npm for the latest version of @openacp/cli and\ninstalls it globally if an update is available.\n`)\n return\n }\n const current = getCurrentVersion()\n const latest = await getLatestVersion()\n if (!latest) {\n console.error('Could not check for updates. Check your internet connection.')\n process.exit(1)\n }\n if (compareVersions(current, latest) >= 0) {\n console.log(`Already up to date (v${current})`)\n return\n }\n console.log(`Update available: v${current} → v${latest}`)\n const ok = await runUpdate()\n if (ok) {\n console.log(`\\x1b[32m✓ Updated to v${latest}\\x1b[0m`)\n } else {\n console.error('Update failed. Try manually: npm install -g @openacp/cli@latest')\n process.exit(1)\n }\n}\n","import { readApiPort } from '../api-client.js'\nimport { wantsHelp } from './helpers.js'\n\nexport async function cmdAdopt(args: string[]): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp adopt\\x1b[0m — Adopt an external agent session\n\n\\x1b[1mUsage:\\x1b[0m\n openacp adopt <agent> <session_id> [--cwd <path>] [--channel <name>]\n\n\\x1b[1mArguments:\\x1b[0m\n <agent> Agent name (e.g. claude)\n <session_id> External session ID to adopt\n\n\\x1b[1mOptions:\\x1b[0m\n --cwd <path> Working directory for the session (default: current dir)\n --channel <name> Target channel adapter (e.g. telegram, discord). Default: first registered\n -h, --help Show this help message\n\nTransfers an existing agent session into OpenACP so it appears\nas a messaging thread. Requires a running daemon.\n\n\\x1b[1mExamples:\\x1b[0m\n openacp adopt claude abc123-def456\n openacp adopt claude abc123 --cwd /path/to/project\n openacp adopt claude abc123 --channel discord\n`)\n return\n }\n\n const agent = args[1];\n const sessionId = args[2];\n\n if (!agent || !sessionId) {\n console.log(\"Usage: openacp adopt <agent> <session_id> [--cwd <path>] [--channel <name>]\");\n console.log(\"Example: openacp adopt claude abc123-def456 --cwd /path/to/project\");\n process.exit(1);\n }\n\n const cwdIdx = args.indexOf(\"--cwd\");\n const cwd = cwdIdx !== -1 && args[cwdIdx + 1] ? args[cwdIdx + 1] : process.cwd();\n const channelIdx = args.indexOf(\"--channel\");\n const channel = channelIdx !== -1 && args[channelIdx + 1] ? args[channelIdx + 1] : undefined;\n\n const port = readApiPort();\n if (!port) {\n console.log(\"OpenACP is not running. Start it with: openacp start\");\n process.exit(1);\n }\n\n try {\n const { apiCall } = await import('../api-client.js')\n const res = await apiCall(port, '/api/sessions/adopt', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ agent, agentSessionId: sessionId, cwd, channel }),\n })\n const data = await res.json() as Record<string, unknown>;\n\n if (data.ok) {\n if (data.status === \"existing\") {\n console.log(`Session already active. Topic pinged.`);\n } else {\n console.log(`Session transferred to messaging platform.`);\n }\n console.log(` Session ID: ${data.sessionId}`);\n console.log(` Thread ID: ${data.threadId}`);\n } else {\n console.log(`Error: ${(data.message as string) || (data.error as string)}`);\n process.exit(1);\n }\n } catch (err) {\n console.log(`Failed to connect to OpenACP: ${err instanceof Error ? err.message : err}`);\n process.exit(1);\n }\n}\n","import { wantsHelp } from './helpers.js'\n\nexport async function cmdIntegrate(args: string[]): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp integrate\\x1b[0m — Manage agent integrations\n\n\\x1b[1mUsage:\\x1b[0m\n openacp integrate <agent> Install integration for an agent\n openacp integrate <agent> --uninstall Remove integration\n\n\\x1b[1mArguments:\\x1b[0m\n <agent> Agent name (e.g. claude)\n\n\\x1b[1mOptions:\\x1b[0m\n --uninstall Remove the integration instead of installing\n -h, --help Show this help message\n\nIntegrations enable features like session handoff from an agent\nto OpenACP (Telegram/Discord). For example, the Claude integration adds\na \"Handoff\" slash command to Claude Code.\n\n\\x1b[1mExamples:\\x1b[0m\n openacp integrate claude\n openacp integrate claude --uninstall\n`)\n return\n }\n\n const { getIntegration, listIntegrations } = await import(\"../integrate.js\");\n\n const agent = args[1];\n const uninstall = args.includes(\"--uninstall\");\n\n if (!agent) {\n console.log(\"Usage: openacp integrate <agent> [--uninstall]\");\n console.log(`Available integrations: ${listIntegrations().join(\", \")}`);\n process.exit(1);\n }\n\n const integration = getIntegration(agent);\n if (!integration) {\n const { suggestMatch } = await import('../suggest.js');\n const available = listIntegrations();\n const suggestion = suggestMatch(agent, available);\n console.log(`No integration available for '${agent}'.`);\n if (suggestion) console.log(`Did you mean: ${suggestion}?`);\n console.log(`Available: ${available.join(\", \")}`);\n process.exit(1);\n }\n\n for (const item of integration.items) {\n if (uninstall) {\n console.log(`Removing ${agent}/${item.id}...`);\n const result = await item.uninstall();\n for (const log of result.logs) console.log(` ${log}`);\n if (result.success) {\n console.log(` ${item.name} removed.`);\n } else {\n console.log(` Failed to remove ${item.name}.`);\n process.exit(1);\n }\n } else {\n console.log(`Installing ${agent}/${item.id}...`);\n const result = await item.install();\n for (const log of result.logs) console.log(` ${log}`);\n if (result.success) {\n console.log(` ${item.name} installed.`);\n } else {\n console.log(` Failed to install ${item.name}.`);\n process.exit(1);\n }\n }\n }\n}\n","import { wantsHelp } from './helpers.js'\n\nexport async function cmdDoctor(args: string[]): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp doctor\\x1b[0m — Run system diagnostics\n\n\\x1b[1mUsage:\\x1b[0m\n openacp doctor [--dry-run]\n\n\\x1b[1mOptions:\\x1b[0m\n --dry-run Check only, don't apply any fixes\n -h, --help Show this help message\n\nChecks your OpenACP installation for common issues including\nconfig validity, agent availability, dependencies, and connectivity.\nFixable issues can be auto-repaired when not using --dry-run.\n`)\n return\n }\n\n const knownFlags = [\"--dry-run\"];\n const unknownFlags = args.slice(1).filter(\n (a) => a.startsWith(\"--\") && !knownFlags.includes(a),\n );\n if (unknownFlags.length > 0) {\n const { suggestMatch } = await import('../suggest.js');\n for (const flag of unknownFlags) {\n const suggestion = suggestMatch(flag, knownFlags);\n console.error(`Unknown flag: ${flag}`);\n if (suggestion) console.error(`Did you mean: ${suggestion}?`);\n }\n process.exit(1);\n }\n\n const dryRun = args.includes(\"--dry-run\");\n const { DoctorEngine } = await import(\"../../core/doctor/index.js\");\n const engine = new DoctorEngine({ dryRun });\n\n console.log(\"\\n🩺 OpenACP Doctor\\n\");\n\n const report = await engine.runAll();\n\n // Render results\n const icons = { pass: \"\\x1b[32m✅\\x1b[0m\", warn: \"\\x1b[33m⚠️\\x1b[0m\", fail: \"\\x1b[31m❌\\x1b[0m\" };\n\n for (const category of report.categories) {\n console.log(`\\x1b[1m\\x1b[36m${category.name}\\x1b[0m`);\n for (const result of category.results) {\n console.log(` ${icons[result.status]} ${result.message}`);\n }\n console.log();\n }\n\n // Handle risky fixes\n if (report.pendingFixes.length > 0) {\n console.log(\"\\x1b[1mFixable issues:\\x1b[0m\\n\");\n for (const pending of report.pendingFixes) {\n if (dryRun) {\n console.log(` 🔧 ${pending.message} (use without --dry-run to fix)`);\n } else {\n const clack = await import(\"@clack/prompts\");\n const shouldFix = await clack.confirm({\n message: `Fix: ${pending.message}?`,\n initialValue: false,\n });\n if (clack.isCancel(shouldFix) || !shouldFix) {\n continue;\n }\n const fixResult = await pending.fix();\n if (fixResult.success) {\n console.log(` \\x1b[32m✓ ${fixResult.message}\\x1b[0m`);\n } else {\n console.log(` \\x1b[31m✗ Fix failed: ${fixResult.message}\\x1b[0m`);\n }\n }\n }\n console.log();\n }\n\n // Summary\n const { passed, warnings, failed, fixed } = report.summary;\n const fixedStr = fixed > 0 ? `, ${fixed} fixed` : \"\";\n console.log(`Result: ${passed} passed, ${warnings} warnings, ${failed} failed${fixedStr}`);\n\n if (failed > 0) {\n process.exit(1);\n }\n}\n","import { wantsHelp } from './helpers.js'\n\nexport async function cmdAgents(args: string[]): Promise<void> {\n const subcommand = args[1];\n\n if (wantsHelp(args) && (!subcommand || subcommand === '--help' || subcommand === '-h')) {\n console.log(`\n\\x1b[1mopenacp agents\\x1b[0m — Manage AI coding agents\n\n\\x1b[1mUsage:\\x1b[0m\n openacp agents Browse all agents (installed + available)\n openacp agents install <name> Install an agent from the ACP Registry\n openacp agents uninstall <name> Remove an installed agent\n openacp agents info <name> Show details, dependencies & setup guide\n openacp agents run <name> [-- args] Run agent CLI directly (login, config...)\n openacp agents refresh Force-refresh agent list from registry\n\n\\x1b[1mOptions:\\x1b[0m\n -h, --help Show this help message\n\n\\x1b[1mExamples:\\x1b[0m\n openacp agents install gemini Install Gemini CLI\n openacp agents run gemini Login to Google (first run)\n openacp agents info cursor See setup instructions\n\n\\x1b[2mRun 'openacp agents <command> --help' for more info on a subcommand.\\x1b[0m\n`)\n return;\n }\n\n switch (subcommand) {\n case \"install\":\n return agentsInstall(args[2], args.includes(\"--force\"), wantsHelp(args));\n case \"uninstall\":\n return agentsUninstall(args[2], wantsHelp(args));\n case \"refresh\":\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp agents refresh\\x1b[0m — Force-refresh agent list from registry\n\n\\x1b[1mUsage:\\x1b[0m\n openacp agents refresh\n\nFetches the latest agent catalog from the ACP Registry,\nbypassing the normal staleness check.\n`)\n return;\n }\n return agentsRefresh();\n case \"info\":\n return agentsInfo(args[2], wantsHelp(args));\n case \"run\":\n return agentsRun(args[2], args.slice(3), wantsHelp(args));\n case \"list\":\n case undefined:\n return agentsList();\n default: {\n const { suggestMatch } = await import('../suggest.js');\n const agentSubcommands = [\"install\", \"uninstall\", \"refresh\", \"info\", \"run\", \"list\"];\n const suggestion = suggestMatch(subcommand, agentSubcommands);\n console.error(`Unknown agents command: ${subcommand}`);\n if (suggestion) console.error(`Did you mean: ${suggestion}?`);\n console.error(`\\nRun 'openacp agents' to see available agents.`);\n process.exit(1);\n }\n }\n}\n\nasync function agentsList(): Promise<void> {\n const { AgentCatalog } = await import(\"../../core/agents/agent-catalog.js\");\n const catalog = new AgentCatalog();\n catalog.load();\n await catalog.refreshRegistryIfStale();\n\n const items = catalog.getAvailable();\n const installed = items.filter((i) => i.installed);\n const available = items.filter((i) => !i.installed);\n\n console.log(\"\");\n if (installed.length > 0) {\n console.log(\" \\x1b[1mInstalled agents:\\x1b[0m\\n\");\n for (const item of installed) {\n const deps = item.missingDeps?.length\n ? ` \\x1b[33m(needs: ${item.missingDeps.join(\", \")})\\x1b[0m`\n : \"\";\n console.log(\n ` \\x1b[32m✓\\x1b[0m ${item.key.padEnd(18)} ${item.name.padEnd(22)} v${item.version.padEnd(10)} ${item.distribution}${deps}`,\n );\n if (item.description) {\n console.log(` \\x1b[2m${item.description}\\x1b[0m`);\n }\n }\n console.log(\"\");\n }\n\n if (available.length > 0) {\n console.log(\" \\x1b[1mAvailable to install:\\x1b[0m\\n\");\n for (const item of available) {\n const icon = item.available ? \"\\x1b[2m⬇\\x1b[0m\" : \"\\x1b[33m⚠\\x1b[0m\";\n const deps = item.missingDeps?.length\n ? ` \\x1b[33m(needs: ${item.missingDeps.join(\", \")})\\x1b[0m`\n : \"\";\n console.log(\n ` ${icon} ${item.key.padEnd(18)} ${item.name.padEnd(22)} v${item.version.padEnd(10)} ${item.distribution}${deps}`,\n );\n if (item.description) {\n console.log(` \\x1b[2m${item.description}\\x1b[0m`);\n }\n }\n console.log(\"\");\n }\n\n console.log(\n ` \\x1b[2mInstall an agent: openacp agents install <name>\\x1b[0m`,\n );\n console.log(\"\");\n}\n\nasync function agentsInstall(nameOrId: string | undefined, force: boolean, help = false): Promise<void> {\n if (help || !nameOrId) {\n console.log(`\n\\x1b[1mopenacp agents install\\x1b[0m — Install an agent from the ACP Registry\n\n\\x1b[1mUsage:\\x1b[0m\n openacp agents install <name> [--force]\n\n\\x1b[1mArguments:\\x1b[0m\n <name> Agent name or ID (e.g. claude, gemini, copilot)\n\n\\x1b[1mOptions:\\x1b[0m\n --force Reinstall even if already installed\n -h, --help Show this help message\n\n\\x1b[1mExamples:\\x1b[0m\n openacp agents install claude\n openacp agents install gemini --force\n\nRun 'openacp agents' to see available agents.\n`)\n return;\n }\n\n const { AgentCatalog } = await import(\"../../core/agents/agent-catalog.js\");\n const catalog = new AgentCatalog();\n catalog.load();\n await catalog.refreshRegistryIfStale();\n\n const progress: import(\"../../core/types.js\").InstallProgress = {\n onStart(_id, name) {\n process.stdout.write(`\\n ⏳ Installing ${name}...\\n`);\n },\n onStep(step) {\n process.stdout.write(` \\x1b[32m✓\\x1b[0m ${step}\\n`);\n },\n onDownloadProgress(percent) {\n const filled = Math.round(percent / 5);\n const empty = 20 - filled;\n const bar = \"█\".repeat(filled) + \"░\".repeat(empty);\n process.stdout.write(`\\r ${bar} ${String(percent).padStart(3)}%`);\n if (percent >= 100) process.stdout.write(\"\\n\");\n },\n onSuccess(name) {\n console.log(`\\n \\x1b[32m✓ ${name} installed successfully!\\x1b[0m\\n`);\n },\n onError(error) {\n console.log(`\\n \\x1b[31m✗ ${error}\\x1b[0m\\n`);\n },\n };\n\n const result = await catalog.install(nameOrId, progress, force);\n if (!result.ok) {\n if (result.error?.includes('not found')) {\n const { suggestMatch } = await import('../suggest.js');\n const allKeys = catalog.getAvailable().map((a) => a.key);\n const suggestion = suggestMatch(nameOrId, allKeys);\n if (suggestion) console.log(` Did you mean: ${suggestion}?`);\n }\n process.exit(1);\n }\n\n // Auto-integrate handoff if agent supports it\n const { getAgentCapabilities } = await import(\"../../core/agents/agent-dependencies.js\");\n const caps = getAgentCapabilities(result.agentKey);\n if (caps.integration) {\n const { installIntegration } = await import(\"../integrate.js\");\n const intResult = await installIntegration(result.agentKey, caps.integration);\n if (intResult.success) {\n console.log(` \\x1b[32m✓\\x1b[0m Handoff integration installed for ${result.agentKey}`);\n } else {\n console.log(` \\x1b[33m⚠ Handoff integration failed: ${intResult.logs[intResult.logs.length - 1] ?? \"unknown error\"}\\x1b[0m`);\n }\n }\n\n // Show setup steps if any\n if (result.setupSteps?.length) {\n console.log(\" \\x1b[1mNext steps to get started:\\x1b[0m\\n\");\n for (const step of result.setupSteps) {\n console.log(` → ${step}`);\n }\n console.log(`\\n \\x1b[2mRun 'openacp agents info ${result.agentKey}' for more details.\\x1b[0m\\n`);\n }\n}\n\nasync function agentsUninstall(name: string | undefined, help = false): Promise<void> {\n if (help || !name) {\n console.log(`\n\\x1b[1mopenacp agents uninstall\\x1b[0m — Remove an installed agent\n\n\\x1b[1mUsage:\\x1b[0m\n openacp agents uninstall <name>\n\n\\x1b[1mArguments:\\x1b[0m\n <name> Agent name to remove\n\n\\x1b[1mExamples:\\x1b[0m\n openacp agents uninstall gemini\n`)\n return;\n }\n\n const { AgentCatalog } = await import(\"../../core/agents/agent-catalog.js\");\n const catalog = new AgentCatalog();\n catalog.load();\n\n const result = await catalog.uninstall(name);\n if (result.ok) {\n // Auto-uninstall handoff integration if exists\n const { getAgentCapabilities } = await import(\"../../core/agents/agent-dependencies.js\");\n const caps = getAgentCapabilities(name);\n if (caps.integration) {\n const { uninstallIntegration } = await import(\"../integrate.js\");\n await uninstallIntegration(name, caps.integration);\n console.log(` \\x1b[32m✓\\x1b[0m Handoff integration removed for ${name}`);\n }\n console.log(`\\n \\x1b[32m✓ ${name} removed.\\x1b[0m\\n`);\n } else {\n console.log(`\\n \\x1b[31m✗ ${result.error}\\x1b[0m`);\n if (result.error?.includes('not installed')) {\n const { suggestMatch } = await import('../suggest.js');\n const installedKeys = Object.keys(catalog.getInstalledEntries());\n const suggestion = suggestMatch(name, installedKeys);\n if (suggestion) console.log(` Did you mean: ${suggestion}?`);\n }\n console.log();\n }\n}\n\nasync function agentsRefresh(): Promise<void> {\n const { AgentCatalog } = await import(\"../../core/agents/agent-catalog.js\");\n const catalog = new AgentCatalog();\n catalog.load();\n console.log(\"\\n Updating agent list...\");\n await catalog.fetchRegistry();\n console.log(\" \\x1b[32m✓ Agent list updated.\\x1b[0m\\n\");\n}\n\nasync function agentsInfo(nameOrId: string | undefined, help = false): Promise<void> {\n if (help || !nameOrId) {\n console.log(`\n\\x1b[1mopenacp agents info\\x1b[0m — Show agent details, dependencies & setup guide\n\n\\x1b[1mUsage:\\x1b[0m\n openacp agents info <name>\n\n\\x1b[1mArguments:\\x1b[0m\n <name> Agent name or ID\n\nShows version, distribution type, command, setup steps, and\nwhether the agent is installed or available from the registry.\n\n\\x1b[1mExamples:\\x1b[0m\n openacp agents info claude\n openacp agents info cursor\n`)\n return;\n }\n\n const { AgentCatalog } = await import(\"../../core/agents/agent-catalog.js\");\n const catalog = new AgentCatalog();\n catalog.load();\n\n const { getAgentSetup } = await import(\"../../core/agents/agent-dependencies.js\");\n\n const installed = catalog.getInstalledAgent(nameOrId);\n if (installed) {\n console.log(`\\n \\x1b[1m${installed.name}\\x1b[0m`);\n console.log(` Version: ${installed.version}`);\n console.log(` Type: ${installed.distribution}`);\n console.log(` Command: ${installed.command} ${installed.args.join(\" \")}`);\n console.log(` Installed: ${new Date(installed.installedAt).toLocaleDateString()}`);\n if (installed.binaryPath) console.log(` Binary path: ${installed.binaryPath}`);\n\n const setup = installed.registryId ? getAgentSetup(installed.registryId) : undefined;\n if (setup) {\n console.log(`\\n \\x1b[1mSetup:\\x1b[0m`);\n for (const step of setup.setupSteps) {\n console.log(` → ${step}`);\n }\n }\n\n console.log(`\\n Run agent CLI: openacp agents run ${nameOrId} -- <args>`);\n console.log(\"\");\n return;\n }\n\n const regAgent = catalog.findRegistryAgent(nameOrId);\n if (regAgent) {\n const availability = catalog.checkAvailability(nameOrId);\n console.log(`\\n \\x1b[1m${regAgent.name}\\x1b[0m \\x1b[2m(not installed)\\x1b[0m`);\n console.log(` ${regAgent.description}`);\n console.log(` Version: ${regAgent.version}`);\n console.log(` License: ${regAgent.license ?? \"unknown\"}`);\n if (regAgent.website) console.log(` Website: ${regAgent.website}`);\n if (regAgent.repository) console.log(` Source: ${regAgent.repository}`);\n console.log(` Available: ${availability.available ? \"\\x1b[32mYes\\x1b[0m\" : `\\x1b[33mNo\\x1b[0m — ${availability.reason}`}`);\n\n const setup = getAgentSetup(regAgent.id);\n if (setup) {\n console.log(`\\n \\x1b[1mSetup after install:\\x1b[0m`);\n for (const step of setup.setupSteps) {\n console.log(` → ${step}`);\n }\n }\n\n console.log(`\\n Install: openacp agents install ${nameOrId}\\n`);\n return;\n }\n\n const { suggestMatch } = await import('../suggest.js');\n const allKeys = catalog.getAvailable().map((a) => a.key);\n const suggestion = suggestMatch(nameOrId, allKeys);\n console.log(`\\n \\x1b[31m\"${nameOrId}\" not found.\\x1b[0m`);\n if (suggestion) console.log(` Did you mean: ${suggestion}?`);\n console.log(` Run 'openacp agents' to see available agents.\\n`);\n}\n\nasync function agentsRun(nameOrId: string | undefined, extraArgs: string[], help = false): Promise<void> {\n if (help || !nameOrId) {\n console.log(`\n\\x1b[1mopenacp agents run\\x1b[0m — Run agent CLI directly\n\n\\x1b[1mUsage:\\x1b[0m\n openacp agents run <name> [-- <args>]\n\n\\x1b[1mArguments:\\x1b[0m\n <name> Installed agent name\n <args> Arguments to pass to the agent CLI\n\nUse \\x1b[1m--\\x1b[0m to separate OpenACP flags from agent arguments.\nACP-specific flags are automatically stripped.\n\n\\x1b[1mExamples:\\x1b[0m\n openacp agents run gemini Login to Google (first run)\n openacp agents run copilot Login to GitHub Copilot (first run)\n openacp agents run cline Setup API keys (first run)\n`)\n return;\n }\n\n const { AgentCatalog } = await import(\"../../core/agents/agent-catalog.js\");\n const catalog = new AgentCatalog();\n catalog.load();\n\n const installed = catalog.getInstalledAgent(nameOrId);\n if (!installed) {\n const { suggestMatch } = await import('../suggest.js');\n const installedKeys = Object.keys(catalog.getInstalledEntries());\n const suggestion = suggestMatch(nameOrId, installedKeys);\n console.log(`\\n \\x1b[31m\"${nameOrId}\" is not installed.\\x1b[0m`);\n if (suggestion) {\n console.log(` Did you mean: ${suggestion}?`);\n console.log(` Install first: openacp agents install ${suggestion}\\n`);\n } else {\n console.log(` Install first: openacp agents install ${nameOrId}\\n`);\n }\n return;\n }\n\n // Strip leading \"--\" separator if present\n const userArgs = extraArgs[0] === \"--\" ? extraArgs.slice(1) : extraArgs;\n\n const { spawnSync } = await import(\"node:child_process\");\n const command = installed.command;\n\n // Include agent's base args (e.g., package name for npx) but strip ACP-specific flags\n const acpFlags = new Set([\"--acp\", \"acp\", \"--acp=true\", \"--experimental-skills\"]);\n const baseArgs: string[] = [];\n for (let i = 0; i < installed.args.length; i++) {\n const arg = installed.args[i]!;\n // Skip standalone ACP flags\n if (acpFlags.has(arg)) continue;\n // Skip \"--output-format acp\" pair (factory-droid pattern)\n if (arg === \"--output-format\" && installed.args[i + 1] === \"acp\") { i++; continue; }\n // Skip \"exec\" subcommand used only in ACP mode (factory-droid)\n if (arg === \"exec\" && installed.args[i + 1] === \"--output-format\") continue;\n baseArgs.push(arg);\n }\n const fullArgs = [...baseArgs, ...userArgs];\n\n console.log(`\\n Running: ${command} ${fullArgs.join(\" \")}\\n`);\n\n const result = spawnSync(command, fullArgs, {\n stdio: \"inherit\",\n env: { ...process.env, ...installed.env },\n cwd: process.cwd(),\n });\n\n if (result.status !== null && result.status !== 0) {\n process.exit(result.status);\n }\n}\n","import { readApiPort, apiCall } from '../api-client.js'\n\nexport async function cmdTunnel(args: string[]): Promise<void> {\n const subCmd = args[1]\n const port = readApiPort()\n if (port === null) {\n console.error('OpenACP is not running. Start with `openacp start`')\n process.exit(1)\n }\n\n try {\n if (subCmd === 'add') {\n const tunnelPort = args[2]\n if (!tunnelPort) {\n console.error('Usage: openacp tunnel add <port> [--label name] [--session id]')\n process.exit(1)\n }\n const labelIdx = args.indexOf('--label')\n const label = labelIdx !== -1 ? args[labelIdx + 1] : undefined\n const sessionIdx = args.indexOf('--session')\n const sessionId = sessionIdx !== -1 ? args[sessionIdx + 1] : undefined\n\n const body: Record<string, unknown> = { port: parseInt(tunnelPort, 10) }\n if (label) body.label = label\n if (sessionId) body.sessionId = sessionId\n\n const res = await apiCall(port, '/api/tunnel', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log(`Tunnel active: port ${data.port} → ${data.publicUrl}`)\n\n } else if (subCmd === 'list') {\n const res = await apiCall(port, '/api/tunnel/list')\n const data = await res.json() as Array<Record<string, unknown>>\n if (data.length === 0) {\n console.log('No active tunnels.')\n return\n }\n console.log('Active tunnels:\\n')\n for (const t of data) {\n const label = t.label ? ` (${t.label})` : ''\n const status = t.status === 'active' ? '✅' : t.status === 'starting' ? '⏳' : '❌'\n console.log(` ${status} Port ${t.port}${label}`)\n if (t.publicUrl) console.log(` → ${t.publicUrl}`)\n }\n\n } else if (subCmd === 'stop') {\n const tunnelPort = args[2]\n if (!tunnelPort) {\n console.error('Usage: openacp tunnel stop <port>')\n process.exit(1)\n }\n const res = await apiCall(port, `/api/tunnel/${tunnelPort}`, { method: 'DELETE' })\n if (!res.ok) {\n const data = await res.json() as Record<string, unknown>\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log(`Tunnel stopped: port ${tunnelPort}`)\n\n } else if (subCmd === 'stop-all') {\n const res = await apiCall(port, '/api/tunnel', { method: 'DELETE' })\n if (!res.ok) {\n const data = await res.json() as Record<string, unknown>\n console.error(`Error: ${data.error}`)\n process.exit(1)\n }\n console.log('All user tunnels stopped.')\n\n } else {\n console.log(`\nTunnel Management:\n openacp tunnel add <port> [--label name] [--session id]\n openacp tunnel list\n openacp tunnel stop <port>\n openacp tunnel stop-all\n`)\n }\n } catch (err) {\n console.error(`Failed to connect to daemon: ${(err as Error).message}`)\n process.exit(1)\n }\n}\n","import * as path from 'node:path'\n\nexport async function cmdOnboard(): Promise<void> {\n const { ConfigManager } = await import('../../core/config/config.js')\n const { SettingsManager } = await import('../../core/plugin/settings-manager.js')\n const { PluginRegistry } = await import('../../core/plugin/plugin-registry.js')\n const { getGlobalRoot } = await import('../../core/instance-context.js')\n\n const OPENACP_DIR = getGlobalRoot()\n const PLUGINS_DATA_DIR = path.join(OPENACP_DIR, 'plugins', 'data')\n const REGISTRY_PATH = path.join(OPENACP_DIR, 'plugins.json')\n\n const cm = new ConfigManager()\n const settingsManager = new SettingsManager(PLUGINS_DATA_DIR)\n const pluginRegistry = new PluginRegistry(REGISTRY_PATH)\n await pluginRegistry.load()\n\n if (await cm.exists()) {\n const { runReconfigure } = await import('../../core/setup/index.js')\n await runReconfigure(cm)\n } else {\n const { runSetup } = await import('../../core/setup/index.js')\n await runSetup(cm, { skipRunMode: true, settingsManager, pluginRegistry })\n }\n}\n","import { checkAndPromptUpdate } from '../version.js'\nimport { printHelp } from './help.js'\nimport path from 'node:path'\nimport os from 'node:os'\nimport { createInstanceContext, getGlobalRoot } from '../../core/instance-context.js'\n\nexport async function cmdDefault(command: string | undefined, instanceRoot?: string): Promise<void> {\n const root = instanceRoot ?? path.join(os.homedir(), '.openacp')\n const pluginsDataDir = path.join(root, 'plugins', 'data')\n const registryPath = path.join(root, 'plugins.json')\n const forceForeground = command === '--foreground'\n\n // Reject unknown commands\n if (command && !command.startsWith('-')) {\n const { suggestMatch } = await import('../suggest.js')\n const topLevelCommands = [\n 'start', 'stop', 'status', 'logs', 'config', 'reset', 'update',\n 'install', 'uninstall', 'plugins', 'plugin', 'api', 'adopt', 'integrate', 'doctor', 'agents', 'onboard',\n ]\n const suggestion = suggestMatch(command, topLevelCommands)\n console.error(`Unknown command: ${command}`)\n if (suggestion) console.error(`Did you mean: ${suggestion}?`)\n printHelp()\n process.exit(1)\n }\n\n await checkAndPromptUpdate()\n\n const { ConfigManager } = await import('../../core/config/config.js')\n const cm = new ConfigManager()\n\n // If no config, run setup first\n if (!(await cm.exists())) {\n const { SettingsManager } = await import('../../core/plugin/settings-manager.js')\n const { PluginRegistry } = await import('../../core/plugin/plugin-registry.js')\n const settingsManager = new SettingsManager(pluginsDataDir)\n const pluginRegistry = new PluginRegistry(registryPath)\n await pluginRegistry.load()\n\n const { runSetup } = await import('../../core/setup/index.js')\n const shouldStart = await runSetup(cm, { settingsManager, pluginRegistry })\n if (!shouldStart) process.exit(0)\n }\n\n await cm.load()\n const config = cm.get()\n\n if (!forceForeground && config.runMode === 'daemon') {\n const { startDaemon, getPidPath } = await import('../daemon.js')\n const result = startDaemon(getPidPath(root), config.logging.logDir, root)\n if ('error' in result) {\n console.error(result.error)\n process.exit(1)\n }\n console.log(`OpenACP daemon started (PID ${result.pid})`)\n return\n }\n\n const { markRunning } = await import('../daemon.js')\n markRunning(root)\n const { startServer } = await import('../../main.js')\n const ctx = createInstanceContext({\n id: 'default',\n root,\n isGlobal: root === getGlobalRoot(),\n })\n await startServer({ instanceContext: ctx })\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport { wantsHelp } from './helpers.js'\n\nexport async function cmdDev(args: string[] = []): Promise<void> {\n if (wantsHelp(args)) {\n console.log(`\n\\x1b[1mopenacp dev\\x1b[0m — Run OpenACP with a local plugin in development mode\n\n\\x1b[1mUsage:\\x1b[0m\n openacp dev <plugin-path> [options]\n\n\\x1b[1mOptions:\\x1b[0m\n --no-watch Disable file watching (no hot-reload)\n --verbose Enable verbose logging\n\n\\x1b[1mExamples:\\x1b[0m\n openacp dev ./my-plugin\n openacp dev ../adapter-matrix --no-watch\n openacp dev ./my-plugin --verbose\n`)\n return\n }\n\n // Parse args: first non-flag arg after 'dev' is plugin path\n const pluginPathArg = args.slice(1).find(a => !a.startsWith('--'))\n const noWatch = args.includes('--no-watch')\n const verbose = args.includes('--verbose')\n\n if (!pluginPathArg) {\n console.error('Error: missing plugin path. Usage: openacp dev <plugin-path>')\n process.exit(1)\n }\n\n const pluginPath = path.resolve(pluginPathArg)\n\n if (!fs.existsSync(pluginPath)) {\n console.error(`Error: plugin path does not exist: ${pluginPath}`)\n process.exit(1)\n }\n\n const tsconfigPath = path.join(pluginPath, 'tsconfig.json')\n const hasTsconfig = fs.existsSync(tsconfigPath)\n\n // Initial TypeScript compile if tsconfig exists\n if (hasTsconfig) {\n console.log('Compiling plugin TypeScript...')\n const { execSync } = await import('node:child_process')\n try {\n execSync('npx tsc', { cwd: pluginPath, stdio: 'inherit' })\n console.log('Compilation complete.')\n } catch {\n console.error('TypeScript compilation failed. Fix errors and try again.')\n process.exit(1)\n }\n\n // Start tsc --watch in background if watching is enabled\n if (!noWatch) {\n const { spawn } = await import('node:child_process')\n const tscWatch = spawn('npx', ['tsc', '--watch', '--preserveWatchOutput'], {\n cwd: pluginPath,\n stdio: verbose ? 'inherit' : 'ignore',\n })\n tscWatch.unref()\n\n process.on('exit', () => {\n try { tscWatch.kill() } catch { /* ignore */ }\n })\n\n if (verbose) {\n console.log('Started tsc --watch for plugin')\n }\n }\n }\n\n // Set dev environment variables\n process.env.OPENACP_DEV_PLUGIN_PATH = pluginPath\n process.env.OPENACP_DEV_NO_WATCH = noWatch ? '1' : ''\n if (verbose) {\n process.env.OPENACP_DEBUG = '1'\n }\n process.env.OPENACP_DEV_LOOP = '1'\n\n // Start the server with dev plugin support\n const { startServer } = await import('../../main.js')\n await startServer({ devPluginPath: pluginPath, noWatch })\n}\n"],"mappings":";;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAS,qBAAqB;AAC9B,SAAS,SAAS,MAAM,eAAe;AACvC,SAAS,YAAY,oBAAoB;AAIzC,SAAS,kBAAiC;AACxC,MAAI,MAAM,QAAQ,cAAc,YAAY,GAAG,CAAC;AAChD,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,YAAY,KAAK,KAAK,cAAc;AAC1C,QAAI,WAAW,SAAS,EAAG,QAAO;AAClC,UAAM,SAAS,QAAQ,KAAK,IAAI;AAChC,QAAI,WAAW,IAAK;AACpB,UAAM;AAAA,EACR;AACA,SAAO;AACT;AAEO,SAAS,oBAA4B;AAC1C,MAAI;AACF,UAAM,UAAU,gBAAgB;AAChC,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,MAAM,KAAK,MAAM,aAAa,SAAS,OAAO,CAAC;AACrD,WAAO,IAAI;AAAA,EACb,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,mBAA2C;AAC/D,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,8BAA8B,WAAW,WAAW;AAAA,MAC1E,QAAQ,YAAY,QAAQ,GAAI;AAAA,IAClC,CAAC;AACD,QAAI,CAAC,IAAI,GAAI,QAAO;AACpB,UAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,WAAO,KAAK,WAAW;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,gBAAgB,SAAiB,QAA4B;AAC3E,QAAM,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI,MAAM;AACvC,QAAM,IAAI,OAAO,MAAM,GAAG,EAAE,IAAI,MAAM;AACtC,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,SAAK,EAAE,CAAC,KAAK,MAAM,EAAE,CAAC,KAAK,GAAI,QAAO;AACtC,SAAK,EAAE,CAAC,KAAK,MAAM,EAAE,CAAC,KAAK,GAAI,QAAO;AAAA,EACxC;AACA,SAAO;AACT;AAEA,eAAsB,YAA8B;AAClD,QAAM,EAAE,OAAAA,OAAM,IAAI,MAAM,OAAO,eAAoB;AACnD,SAAO,IAAI,QAAQ,CAACC,aAAY;AAC9B,UAAM,QAAQD,OAAM,OAAO,CAAC,WAAW,MAAM,GAAG,WAAW,SAAS,GAAG;AAAA,MACrE,OAAO;AAAA,MACP,OAAO;AAAA,IACT,CAAC;AACD,UAAM,WAAW,MAAM;AACrB,YAAM,KAAK,SAAS;AACpB,MAAAC,SAAQ,KAAK;AAAA,IACf;AACA,YAAQ,GAAG,UAAU,QAAQ;AAC7B,YAAQ,GAAG,WAAW,QAAQ;AAC9B,UAAM,GAAG,SAAS,CAAC,SAAS;AAC1B,cAAQ,IAAI,UAAU,QAAQ;AAC9B,cAAQ,IAAI,WAAW,QAAQ;AAC/B,MAAAA,SAAQ,SAAS,CAAC;AAAA,IACpB,CAAC;AAAA,EACH,CAAC;AACH;AAEA,eAAsB,uBAAsC;AAC1D,MAAI,QAAQ,IAAI,oBAAoB,QAAQ,IAAI,0BAA2B;AAE3E,QAAM,UAAU,kBAAkB;AAClC,MAAI,YAAY,YAAa;AAE7B,QAAM,SAAS,MAAM,iBAAiB;AACtC,MAAI,CAAC,UAAU,gBAAgB,SAAS,MAAM,KAAK,EAAG;AAEtD,UAAQ,IAAI,8BAA8B,OAAO,YAAO,MAAM,SAAS;AACvE,QAAMC,UAAQ,MAAM,OAAO,gBAAgB;AAC3C,QAAM,MAAM,MAAMA,QAAM,QAAQ;AAAA,IAC9B,SAAS;AAAA,EACX,CAAC;AACD,MAAIA,QAAM,SAAS,GAAG,KAAK,CAAC,KAAK;AAC/B;AAAA,EACF;AACA,QAAMC,MAAK,MAAM,UAAU;AAC3B,MAAIA,KAAI;AACN,YAAQ,IAAI,8BAAyB,MAAM,sCAAsC;AACjF,YAAQ,KAAK,CAAC;AAAA,EAChB,OAAO;AACL,YAAQ,MAAM,gEAAgE;AAAA,EAChF;AACF;AAjGA,IAIM;AAJN;AAAA;AAAA;AAIA,IAAM,cAAc;AAAA;AAAA;;;ACJpB;AAAA;AAAA;AAAA;AAAA,OAAOC,SAAQ;AACf,OAAOC,WAAU;AADjB,IAmBa;AAnBb;AAAA;AAAA;AAmBO,IAAM,iBAAN,MAAqB;AAAA,MAG1B,YAAoB,cAAsB;AAAtB;AAAA,MAAuB;AAAA,MAFnC,OAAqB,EAAE,WAAW,CAAC,EAAE;AAAA,MAI7C,OAAiC;AAC/B,eAAO,IAAI,IAAI,OAAO,QAAQ,KAAK,KAAK,SAAS,CAAC;AAAA,MACpD;AAAA,MAEA,IAAI,MAAuC;AACzC,eAAO,KAAK,KAAK,UAAU,IAAI;AAAA,MACjC;AAAA,MAEA,SAAS,MAAc,OAA4B;AACjD,cAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,aAAK,KAAK,UAAU,IAAI,IAAI,EAAE,GAAG,OAAO,aAAa,KAAK,WAAW,IAAI;AAAA,MAC3E;AAAA,MAEA,OAAO,MAAoB;AACzB,eAAO,KAAK,KAAK,UAAU,IAAI;AAAA,MACjC;AAAA,MAEA,WAAW,MAAc,SAAwB;AAC/C,cAAM,QAAQ,KAAK,KAAK,UAAU,IAAI;AACtC,YAAI,CAAC,MAAO;AACZ,cAAM,UAAU;AAChB,cAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,MAC3C;AAAA,MAEA,cAAc,MAAc,SAAuB;AACjD,cAAM,QAAQ,KAAK,KAAK,UAAU,IAAI;AACtC,YAAI,CAAC,MAAO;AACZ,cAAM,UAAU;AAChB,cAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,MAC3C;AAAA,MAEA,cAAwC;AACtC,eAAO,IAAI,IAAI,OAAO,QAAQ,KAAK,KAAK,SAAS,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;AAAA,MACjF;AAAA,MAEA,aAAa,QAAyD;AACpE,eAAO,IAAI,IAAI,OAAO,QAAQ,KAAK,KAAK,SAAS,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,MAAM,CAAC;AAAA,MAC3F;AAAA,MAEA,MAAM,OAAsB;AAC1B,YAAI;AACF,gBAAM,UAAUD,IAAG,aAAa,KAAK,cAAc,OAAO;AAC1D,gBAAM,SAAS,KAAK,MAAM,OAAO;AACjC,cAAI,UAAU,OAAO,OAAO,cAAc,UAAU;AAClD,iBAAK,OAAO;AAAA,UACd;AAAA,QACF,QAAQ;AACN,eAAK,OAAO,EAAE,WAAW,CAAC,EAAE;AAAA,QAC9B;AAAA,MACF;AAAA,MAEA,MAAM,OAAsB;AAC1B,cAAM,MAAMC,MAAK,QAAQ,KAAK,YAAY;AAC1C,QAAAD,IAAG,UAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AACrC,QAAAA,IAAG,cAAc,KAAK,cAAc,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,MACxE;AAAA,IACF;AAAA;AAAA;;;AChFA;AAAA;AAAA;AAAA;AAAA,IAAM,cACA,WA2BO;AA5Bb;AAAA;AAAA;AAAA,IAAM,eAAe;AACrB,IAAM,YAAY,KAAK;AA2BhB,IAAM,iBAAN,MAAqB;AAAA,MAClB,QAAsD;AAAA,MACtD;AAAA,MAER,YAAY,aAAsB;AAChC,aAAK,cAAc,eAAe;AAAA,MACpC;AAAA,MAEA,MAAM,cAAiC;AACrC,YAAI,KAAK,SAAS,KAAK,IAAI,IAAI,KAAK,MAAM,YAAY,WAAW;AAC/D,iBAAO,KAAK,MAAM;AAAA,QACpB;AACA,cAAM,MAAM,MAAM,MAAM,KAAK,WAAW;AACxC,YAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,6BAA6B,IAAI,MAAM,EAAE;AACtE,cAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,aAAK,QAAQ,EAAE,MAAM,WAAW,KAAK,IAAI,EAAE;AAC3C,eAAO;AAAA,MACT;AAAA,MAEA,MAAM,OAAO,OAA0C;AACrD,cAAM,WAAW,MAAM,KAAK,YAAY;AACxC,cAAM,IAAI,MAAM,YAAY;AAC5B,eAAO,SAAS,QAAQ,OAAO,CAAAE,OAAK;AAClC,gBAAMC,QAAO,GAAGD,GAAE,IAAI,IAAIA,GAAE,eAAe,EAAE,IAAIA,GAAE,WAAW,IAAIA,GAAE,MAAM,KAAK,GAAG,KAAK,EAAE,GAAG,YAAY;AACxG,iBAAOC,MAAK,SAAS,CAAC;AAAA,QACxB,CAAC;AAAA,MACH;AAAA,MAEA,MAAM,QAAQ,MAAsC;AAClD,cAAM,WAAW,MAAM,KAAK,YAAY;AACxC,cAAM,SAAS,SAAS,QAAQ,KAAK,CAAAD,OAAKA,GAAE,SAAS,IAAI;AACzD,eAAO,QAAQ,OAAO;AAAA,MACxB;AAAA,MAEA,aAAmB;AACjB,aAAK,QAAQ;AAAA,MACf;AAAA,IACF;AAAA;AAAA;;;ACjEA;AAAA;AAAA;AAAA;AAEA,eAAsB,gBAAgBE,OAA+B;AACnE,QAAM,QAAQA,MAAK,KAAK,GAAG,EAAE,KAAK;AAClC,MAAI,CAAC,OAAO;AACV,YAAQ,MAAM,sCAAsC;AACpD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,IAAI,eAAe;AAElC,MAAI;AACF,UAAM,UAAU,MAAM,OAAO,OAAO,KAAK;AAEzC,QAAI,QAAQ,WAAW,GAAG;AACxB,cAAQ,IAAI,8BAA8B,KAAK,GAAG;AAClD;AAAA,IACF;AAEA,YAAQ,IAAI;AAAA,QAAW,QAAQ,MAAM,UAAU,QAAQ,SAAS,IAAI,MAAM,EAAE,cAAc,KAAK;AAAA,CAAM;AACrG,eAAWC,MAAK,SAAS;AACvB,YAAM,WAAWA,GAAE,WAAW,YAAO;AACrC,YAAM,WAAWA,GAAE,WAAW,YAAO;AACrC,cAAQ,IAAI,KAAKA,GAAE,QAAQ,WAAI,IAAIA,GAAE,eAAeA,GAAE,IAAI,GAAG,QAAQ,GAAG,QAAQ,EAAE;AAClF,cAAQ,IAAI,QAAQA,GAAE,WAAW,EAAE;AACnC,cAAQ,IAAI,QAAQA,GAAE,QAAQ,OAAOA,GAAE,OAAO,WAAWA,GAAE,GAAG,EAAE;AAChE,cAAQ,IAAI,wCAAwCA,GAAE,IAAI,EAAE;AAC5D,cAAQ,IAAI;AAAA,IACd;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,MAAM,8BAA8B,GAAG,EAAE;AACjD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAjCA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACQO,SAAS,oBAAoB,QAAgC;AAClE,QAAM,cAAc;AAAA,IAClB,MAAM,OAAO;AAAA,IACb,SAAS;AAAA,IACT,aAAa,OAAO,eAAe;AAAA,IACnC,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,MACP,OAAO;AAAA,MACP,KAAK;AAAA,MACL,MAAM;AAAA,MACN,gBAAgB;AAAA,IAClB;AAAA,IACA,QAAQ,OAAO,UAAU;AAAA,IACzB,SAAS,OAAO;AAAA,IAChB,UAAU,CAAC,WAAW,gBAAgB;AAAA,IACtC,SAAS;AAAA,MACP,SAAS,KAAK,OAAO,UAAU;AAAA,IACjC;AAAA,IACA,kBAAkB;AAAA,MAChB,gBAAgB,KAAK,OAAO,UAAU;AAAA,IACxC;AAAA,IACA,iBAAiB;AAAA,MACf,uBAAuB,OAAO;AAAA,MAC9B,YAAY;AAAA,MACZ,QAAQ;AAAA,IACV;AAAA,EACF;AACA,SAAO,KAAK,UAAU,aAAa,MAAM,CAAC,IAAI;AAChD;AAtCA;AAAA;AAAA;AAAA;AAAA;;;ACAO,SAAS,mBAA2B;AACzC,QAAM,WAAW;AAAA,IACf,iBAAiB;AAAA,MACf,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,kBAAkB;AAAA,MAClB,aAAa;AAAA,MACb,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,iBAAiB;AAAA,MACjB,cAAc;AAAA,MACd,kCAAkC;AAAA,IACpC;AAAA,IACA,SAAS,CAAC,KAAK;AAAA,IACf,SAAS,CAAC,gBAAgB,QAAQ,kBAAkB;AAAA,EACtD;AACA,SAAO,KAAK,UAAU,UAAU,MAAM,CAAC,IAAI;AAC7C;AAlBA;AAAA;AAAA;AAAA;AAAA;;;ACAO,SAAS,oBAA4B;AAC1C,SAAO,CAAC,iBAAiB,SAAS,iBAAiB,aAAa,EAAE,EAAE,KAAK,IAAI;AAC/E;AAEO,SAAS,oBAA4B;AAC1C,SAAO,CAAC,QAAQ,iBAAiB,iBAAiB,cAAc,aAAa,cAAc,EAAE,EAAE,KAAK,IAAI;AAC1G;AAEO,SAAS,uBAA+B;AAC7C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AArBA;AAAA;AAAA;AAAA;AAAA;;;ACEO,SAAS,eAAe,QAAgC;AAC7D,SAAO;AAAA,IACL,KAAK,OAAO,UAAU;AAAA,IACtB;AAAA,IACA,OAAO,eAAe;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,sBAAsB,OAAO,UAAU;AAAA,IACvC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AA9BA;AAAA;AAAA;AAAA;AAAA;;;ACEO,SAAS,qBAAqB,QAAgC;AACnE,QAAM,UAAU,OAAO,WAAW,QAAQ,aAAa,EAAE;AACzD,QAAM,sBAAsB,OAAO,eAAe,IAAI,QAAQ,MAAM,KAAK;AAEzE,SAAO;AAAA;AAAA;AAAA,WAGE,OAAO,UAAU;AAAA;AAAA,kBAEV,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sDAgCkB,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kDAiBrB,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA,wCAI3B,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wDAaD,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA,yCAIhC,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qDAoBL,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA,0CAI5B,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAU3D;AAnHA;AAAA;AAAA;AAAA;AAAA;;;ACEO,SAAS,mBAAmB,QAAgC;AACjE,SAAO;AAAA;AAAA;AAAA;AAAA,YAIG,OAAO,UAAU;AAAA;AAAA,gCAEG,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAO5B,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAgBf,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQxC;AAxCA;AAAA;AAAA;AAAA;AAAA;;;ACEO,SAAS,iBAAiB,QAAgC;AAC/D,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAyBQ,OAAO,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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","names":["spawn","resolve","clack","ok","fs","path","p","text","args","p","fs","path","spinner","access","args","fs","fs","path","readTextFileWithRange","path","os","init_file_service","fs","path","os","path","args","text","text","estimateTokens","text","step","estimateTokens","text","step","fs","path","path","text","fs","os","path","args","fs","path","os","p","args","resolve","execFileSync","fs","path","fs","path","os","execSync","resolve","platform","log","fs","path","os","log","ensureCloudflared","args","resolve","spawn","log","SIGKILL_TIMEOUT_MS","args","resolve","spawn","log","SIGKILL_TIMEOUT_MS","args","resolve","spawn","execSync","log","SIGKILL_TIMEOUT_MS","args","resolve","fs","path","os","log","fs","path","log","text","escapeHtml","text","getMonacoLang","MONACO_LANGUAGE","escapeHtml","text","c","log","resolve","path","TunnelService","args","err","text","fs","path","fileURLToPath","path","log","path","fs","os","root","expandHome","p","fs","path","fs","path","log","command","expandHome","fs","path","os","p","log","getConfigValue","input","resolved","getSafeFields","resolveOptions","getConfigValue","p","getFieldDef","ConfigSchema","isHotReloadable","init_config","init_tunnel","fs","path","os","crypto","fileURLToPath","log","init_config","init_tunnel","resolve","api_server_exports","path","ApiServer","init_api_server","init_topics","text","remaining","c","args","path","p","escapeHtml","text","splitMessage","log","toastText","args","getCurrentVersion","getLatestVersion","compareVersions","runUpdate","escapeHtml","ok","InlineKeyboard","args","text","escapeHtml","log","init_topics","InlineKeyboard","log","escapeHtml","platform","header","InlineKeyboard","commands","header","c","existsSync","mkdirSync","readFileSync","writeFileSync","unlinkSync","join","dirname","homedir","p","group","InlineKeyboard","text","escapeHtml","step","getAgentCapabilities","installIntegration","p","init_agents","InlineKeyboard","listIntegrations","keyboard","agentName","getIntegration","integration","escapeHtml","init_integrate","fs","path","os","InlineKeyboard","botFromCtx","cleanupPending","args","text","escapeHtml","PENDING_TIMEOUT_MS","log","init_topics","InlineKeyboard","log","buildMenuKeyboard","fs","init_config","execFileSync","fs","path","commandExists","init_agents","fs","fs","expandHome","fs","path","fs","resolve","fs","path","os","execFileSync","init_tunnel","ensureCloudflared","fs","path","init_config","init_agents","init_tunnel","expandHome","InlineKeyboard","escapeHtml","text","log","init_doctor","InlineKeyboard","escapeHtml","remaining","log","init_tunnel","InlineKeyboard","escapeHtml","log","init_agents","init_integrate","init_doctor","init_tunnel","InlineKeyboard","nanoid","log","init_topics","escapeHtml","log","text","input","command","log","text","escapeHtml","resolve","remaining","nanoid","InlineKeyboard","text","text","splitMessage","text","log","commands","platform","text","text","init_renderer","escapeHtml","text","input","log","init_topics","init_renderer","p","text","command","getAgentCapabilities","escapeHtml","platform","commands","validateBotToken","validateChatId","validateBotAdmin","TelegramAdapter","init_telegram","init_file_service","init_api_server","init_telegram","fs","path","path","fs","path","os","root","input","c","spawn","fs","path","os","root","DEFAULT_ROOT","logDir","expandHome","resolve","isProcessAlive","init_daemon","fs","path","root","execFileSync","fs","path","os","logDir","log","path","clack","select","validateBotToken","tgUp","validateChatId","installNpmPlugin","SettingsManager","createInstallContext","getGlobalRoot","root","logDir","expandHome","fs","path","os","z","log","fs","path","os","platform","log","execFileSync","fs","path","os","log","REGISTRY_URL","clack","guardCancel","text","getCurrentVersion","c","ok","warn","dim","execFileSync","clack","command","AgentCatalog","muteLogger","unmuteLogger","AgentStore","ok","guardCancel","warn","c","clack","guardCancel","clack","dim","guardCancel","installAutoStart","isAutoStartSupported","muteLogger","unmuteLogger","expandHome","ok","warn","stopDaemon","uninstallAutoStart","clack","guardCancel","getIntegration","log","path","clack","c","guardCancel","SettingsManager","createInstallContext","ok","fs","path","path","fs","clack","p","step","guardCancel","createInstallContext","execFileSync","readFileSync","ok","resolve","ok","args","spawn","p","args","resolve","fs","path","spawn","execFileSync","fs","path","root","log","resolve","c","p","text","text","resolve","resolve","nanoid","fs","init_session","text","p","args","init_session","p","log","fs","p","c","log","input","id","fs","path","log","DEBOUNCE_MS","log","init_session","p","createHash","readFileSync","p","remaining","fs","path","path","os","log","resolve","p","path","os","log","setLogLevel","platform","access","existsSync","p","args","init_session","args","init_agents","args","init_admin","args","text","init_menu","args","init_switch","init_commands","init_session","init_agents","init_admin","init_menu","init_switch","ensureCloudflared","log","getIntegration","ensureJq","AgentStore","fs","path","path","fs","writePidFile","readPidFile","shouldAutoStart","runSetup","printStartBanner","spinner","runPostUpgradeChecks","pkg","p","DevPluginLoader","removePidFile","expandHome","ok","createInstallContext","init_commands","path","getCurrentVersion","args","args","root","execSync","fs","path","os","args","root","execSync","args","os","path","PluginRegistry","root","cmdPluginSearch","cmdPluginCreate","corePlugins","SettingsManager","createInstallContext","p","input","execFileSync","getCurrentVersion","RegistryClient","readFileSync","compareVersions","fs","args","suggestMatch","path","os","args","root","startDaemon","getPidPath","ConfigManager","path","os","args","root","stopDaemon","getPidPath","path","os","args","root","stopDaemon","startDaemon","getPidPath","ConfigManager","checkAndPromptUpdate","fs","path","os","args","root","args","spawn","ConfigManager","expandHome","logDir","args","ConfigSchema","suggestMatch","port","ConfigManager","cm","runConfigEditor","args","os","path","root","getStatus","getPidPath","clack","uninstallAutoStart","fs","args","ok","args","apiCall","args","getIntegration","listIntegrations","suggestMatch","log","args","suggestMatch","DoctorEngine","clack","args","suggestMatch","AgentCatalog","step","getAgentCapabilities","installIntegration","uninstallIntegration","getAgentSetup","command","args","path","ConfigManager","SettingsManager","PluginRegistry","getGlobalRoot","runReconfigure","runSetup","path","os","command","root","suggestMatch","ConfigManager","SettingsManager","PluginRegistry","runSetup","startDaemon","getPidPath","markRunning","startServer","fs","path","args","path","fs","execSync","spawn","startServer","args","flags","remaining","startServer","createInstanceContext","InstanceRegistry","path"]}