@openacp/cli 0.4.5 → 0.4.8

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 (38) hide show
  1. package/README.md +81 -15
  2. package/dist/agent-registry-7HC6D4CH.js +7 -0
  3. package/dist/{chunk-WHKLPZGK.js → chunk-6MJLVZXV.js} +8 -8
  4. package/dist/{chunk-V5P3K4A5.js → chunk-BBPWAWE3.js} +1137 -119
  5. package/dist/chunk-BBPWAWE3.js.map +1 -0
  6. package/dist/{chunk-3QACY5E3.js → chunk-C6YIUTGR.js} +2 -2
  7. package/dist/{chunk-2SY7Y2VB.js → chunk-HZD3CGPK.js} +2 -2
  8. package/dist/{chunk-BLVZFCKN.js → chunk-UAUTLC4E.js} +27 -3
  9. package/dist/{chunk-BLVZFCKN.js.map → chunk-UAUTLC4E.js.map} +1 -1
  10. package/dist/chunk-VA2M52CM.js +15 -0
  11. package/dist/chunk-VA2M52CM.js.map +1 -0
  12. package/dist/{chunk-WF5XDN4D.js → chunk-ZRFBLD3W.js} +6 -2
  13. package/dist/chunk-ZRFBLD3W.js.map +1 -0
  14. package/dist/cli.js +388 -38
  15. package/dist/cli.js.map +1 -1
  16. package/dist/{config-J5YQOMDU.js → config-H2DSEHNW.js} +2 -2
  17. package/dist/config-editor-SKS4LJLT.js +11 -0
  18. package/dist/{daemon-SLGQGRKO.js → daemon-VF6HJQXD.js} +3 -3
  19. package/dist/index.d.ts +111 -10
  20. package/dist/index.js +13 -10
  21. package/dist/integrate-WUPLRJD3.js +145 -0
  22. package/dist/integrate-WUPLRJD3.js.map +1 -0
  23. package/dist/{main-3CDOICYN.js → main-NV7YN3VY.js} +27 -14
  24. package/dist/main-NV7YN3VY.js.map +1 -0
  25. package/dist/{setup-JQZBPXWS.js → setup-FCVL75K6.js} +3 -3
  26. package/dist/setup-FCVL75K6.js.map +1 -0
  27. package/package.json +1 -1
  28. package/dist/chunk-V5P3K4A5.js.map +0 -1
  29. package/dist/chunk-WF5XDN4D.js.map +0 -1
  30. package/dist/config-editor-IXL4BFG3.js +0 -11
  31. package/dist/main-3CDOICYN.js.map +0 -1
  32. /package/dist/{config-J5YQOMDU.js.map → agent-registry-7HC6D4CH.js.map} +0 -0
  33. /package/dist/{chunk-WHKLPZGK.js.map → chunk-6MJLVZXV.js.map} +0 -0
  34. /package/dist/{chunk-3QACY5E3.js.map → chunk-C6YIUTGR.js.map} +0 -0
  35. /package/dist/{chunk-2SY7Y2VB.js.map → chunk-HZD3CGPK.js.map} +0 -0
  36. /package/dist/{config-editor-IXL4BFG3.js.map → config-H2DSEHNW.js.map} +0 -0
  37. /package/dist/{daemon-SLGQGRKO.js.map → config-editor-SKS4LJLT.js.map} +0 -0
  38. /package/dist/{setup-JQZBPXWS.js.map → daemon-VF6HJQXD.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/cli/integrate.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, chmodSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\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\n// --- Claude integration ---\n\nconst CLAUDE_DIR = join(homedir(), \".claude\");\nconst HOOKS_DIR = join(CLAUDE_DIR, \"hooks\");\nconst COMMANDS_DIR = join(CLAUDE_DIR, \"commands\");\nconst SETTINGS_FILE = join(CLAUDE_DIR, \"settings.json\");\n\nconst INJECT_HOOK_FILE = join(HOOKS_DIR, \"openacp-inject-session.sh\");\nconst HANDOFF_SCRIPT_FILE = join(HOOKS_DIR, \"openacp-handoff.sh\");\nconst HANDOFF_COMMAND_FILE = join(COMMANDS_DIR, \"openacp:handoff.md\");\n\nconst INJECT_HOOK_CONTENT = `#!/bin/bash\nINPUT=$(cat)\nSESSION_ID=$(echo \"$INPUT\" | jq -r '.session_id')\nCWD=$(echo \"$INPUT\" | jq -r '.cwd')\n\necho \"CLAUDE_SESSION_ID: $SESSION_ID\"\necho \"CLAUDE_WORKING_DIR: $CWD\"\n\nexit 0\n`;\n\nconst HANDOFF_SCRIPT_CONTENT = `#!/bin/bash\nSESSION_ID=$1\nCWD=$2\n\nif [ -z \"$SESSION_ID\" ]; then\n echo \"Usage: openacp-handoff.sh <session_id> [cwd]\"\n exit 1\nfi\n\nopenacp adopt claude \"$SESSION_ID\" \\${CWD:+--cwd \"$CWD\"}\n`;\n\nconst HANDOFF_COMMAND_CONTENT = `---\ndescription: Transfer current session to OpenACP (Telegram)\n---\n\nLook at the context injected at the start of this message to find\nCLAUDE_SESSION_ID and CLAUDE_WORKING_DIR, then run:\n\nbash ~/.claude/hooks/openacp-handoff.sh <CLAUDE_SESSION_ID> <CLAUDE_WORKING_DIR>\n`;\n\nconst HOOK_MARKER = \"openacp-inject-session.sh\";\n\nfunction mergeClaudeSettings(): void {\n let settings: Record<string, unknown> = {};\n\n if (existsSync(SETTINGS_FILE)) {\n const raw = readFileSync(SETTINGS_FILE, \"utf-8\");\n writeFileSync(`${SETTINGS_FILE}.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 userPromptSubmit = (hooks.UserPromptSubmit ?? []) as Array<{ hooks?: Array<{ type?: string; command?: string }> }>;\n hooks.UserPromptSubmit = userPromptSubmit;\n\n const alreadyInstalled = userPromptSubmit.some((group) =>\n group.hooks?.some((h) => h.command?.includes(HOOK_MARKER)),\n );\n\n if (!alreadyInstalled) {\n userPromptSubmit.push({\n hooks: [\n {\n type: \"command\",\n command: INJECT_HOOK_FILE,\n },\n ],\n });\n }\n\n writeFileSync(SETTINGS_FILE, JSON.stringify(settings, null, 2) + \"\\n\");\n}\n\nfunction removeClaudeSettings(): void {\n if (!existsSync(SETTINGS_FILE)) return;\n\n const raw = readFileSync(SETTINGS_FILE, \"utf-8\");\n const settings = JSON.parse(raw);\n\n const hooks = settings.hooks as Record<string, unknown[]> | undefined;\n if (!hooks?.UserPromptSubmit) return;\n\n hooks.UserPromptSubmit = (hooks.UserPromptSubmit as Array<{ hooks?: Array<{ command?: string }> }>).filter(\n (group) => !group.hooks?.some((h) => h.command?.includes(\"openacp-\")),\n );\n\n if (hooks.UserPromptSubmit.length === 0) {\n delete hooks.UserPromptSubmit;\n }\n\n writeFileSync(SETTINGS_FILE, JSON.stringify(settings, null, 2) + \"\\n\");\n}\n\nconst claudeHandoffItem: IntegrationItem = {\n id: \"handoff\",\n name: \"Handoff\",\n description: \"Transfer sessions between terminal and Telegram\",\n\n isInstalled(): boolean {\n return (\n existsSync(INJECT_HOOK_FILE) &&\n existsSync(HANDOFF_SCRIPT_FILE) &&\n existsSync(HANDOFF_COMMAND_FILE)\n );\n },\n\n async install(): Promise<IntegrationResult> {\n const logs: string[] = [];\n try {\n mkdirSync(HOOKS_DIR, { recursive: true });\n mkdirSync(COMMANDS_DIR, { recursive: true });\n\n writeFileSync(INJECT_HOOK_FILE, INJECT_HOOK_CONTENT);\n chmodSync(INJECT_HOOK_FILE, 0o755);\n logs.push(`Created ${INJECT_HOOK_FILE}`);\n\n writeFileSync(HANDOFF_SCRIPT_FILE, HANDOFF_SCRIPT_CONTENT);\n chmodSync(HANDOFF_SCRIPT_FILE, 0o755);\n logs.push(`Created ${HANDOFF_SCRIPT_FILE}`);\n\n writeFileSync(HANDOFF_COMMAND_FILE, HANDOFF_COMMAND_CONTENT);\n logs.push(`Created ${HANDOFF_COMMAND_FILE}`);\n\n mergeClaudeSettings();\n logs.push(`Updated ${SETTINGS_FILE}`);\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 async uninstall(): Promise<IntegrationResult> {\n const logs: string[] = [];\n try {\n for (const file of [INJECT_HOOK_FILE, HANDOFF_SCRIPT_FILE, HANDOFF_COMMAND_FILE]) {\n if (existsSync(file)) {\n unlinkSync(file);\n logs.push(`Removed ${file}`);\n }\n }\n\n removeClaudeSettings();\n logs.push(`Updated ${SETTINGS_FILE}`);\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\nconst claudeIntegration: AgentIntegration = {\n items: [claudeHandoffItem],\n};\n\n// --- Registry ---\n\nconst integrations: Record<string, AgentIntegration> = {\n claude: claudeIntegration,\n};\n\nexport function getIntegration(agentName: string): AgentIntegration | undefined {\n return integrations[agentName];\n}\n\nexport function listIntegrations(): string[] {\n return Object.keys(integrations);\n}\n"],"mappings":"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","names":[]}
@@ -2,18 +2,20 @@
2
2
  import {
3
3
  ApiServer,
4
4
  OpenACPCore,
5
- TelegramAdapter
6
- } from "./chunk-V5P3K4A5.js";
7
- import "./chunk-WHKLPZGK.js";
5
+ TelegramAdapter,
6
+ TopicManager
7
+ } from "./chunk-BBPWAWE3.js";
8
+ import "./chunk-6MJLVZXV.js";
9
+ import "./chunk-UAUTLC4E.js";
10
+ import "./chunk-VA2M52CM.js";
8
11
  import {
9
12
  loadAdapterFactory
10
- } from "./chunk-2SY7Y2VB.js";
11
- import "./chunk-3QACY5E3.js";
12
- import "./chunk-MRKYJ422.js";
13
- import "./chunk-BLVZFCKN.js";
13
+ } from "./chunk-HZD3CGPK.js";
14
+ import "./chunk-C6YIUTGR.js";
14
15
  import {
15
16
  ConfigManager
16
- } from "./chunk-WF5XDN4D.js";
17
+ } from "./chunk-ZRFBLD3W.js";
18
+ import "./chunk-MRKYJ422.js";
17
19
  import {
18
20
  cleanupOldSessionLogs,
19
21
  initLogger,
@@ -26,7 +28,7 @@ var RESTART_EXIT_CODE = 75;
26
28
  var shuttingDown = false;
27
29
  async function startServer() {
28
30
  if (process.argv.includes("--daemon-child")) {
29
- const { writePidFile, readPidFile, getPidPath, shouldAutoStart } = await import("./daemon-SLGQGRKO.js");
31
+ const { writePidFile, readPidFile, getPidPath, shouldAutoStart } = await import("./daemon-VF6HJQXD.js");
30
32
  if (!shouldAutoStart()) {
31
33
  process.exit(0);
32
34
  }
@@ -45,7 +47,7 @@ async function startServer() {
45
47
  const configManager = new ConfigManager();
46
48
  const configExists = await configManager.exists();
47
49
  if (!configExists) {
48
- const { runSetup } = await import("./setup-JQZBPXWS.js");
50
+ const { runSetup } = await import("./setup-FCVL75K6.js");
49
51
  const shouldStart = await runSetup(configManager);
50
52
  if (!shouldStart) process.exit(0);
51
53
  }
@@ -103,13 +105,13 @@ async function startServer() {
103
105
  }
104
106
  const isDaemon = process.argv.includes("--daemon-child");
105
107
  if (isDaemon) {
106
- const { removePidFile, getPidPath } = await import("./daemon-SLGQGRKO.js");
108
+ const { removePidFile, getPidPath } = await import("./daemon-VF6HJQXD.js");
107
109
  removePidFile(getPidPath());
108
110
  }
109
111
  if (exitCode === RESTART_EXIT_CODE) {
110
112
  if (isDaemon) {
111
113
  const { spawn: spawnChild } = await import("child_process");
112
- const { expandHome } = await import("./config-J5YQOMDU.js");
114
+ const { expandHome } = await import("./config-H2DSEHNW.js");
113
115
  const fs = await import("fs");
114
116
  const pathMod = await import("path");
115
117
  const cliPath = pathMod.resolve(process.argv[1]);
@@ -151,7 +153,18 @@ async function startServer() {
151
153
  log.error({ err }, "Unhandled rejection");
152
154
  });
153
155
  await core.start();
154
- apiServer = new ApiServer(core, config.api);
156
+ const updatedConfig = core.configManager.get();
157
+ const telegramAdapter = core.adapters.get("telegram") ?? null;
158
+ const telegramCfg = updatedConfig.channels?.telegram;
159
+ const topicManager = new TopicManager(
160
+ core.sessionManager,
161
+ telegramAdapter,
162
+ {
163
+ notificationTopicId: telegramCfg?.notificationTopicId ?? null,
164
+ assistantTopicId: telegramCfg?.assistantTopicId ?? null
165
+ }
166
+ );
167
+ apiServer = new ApiServer(core, config.api, void 0, topicManager);
155
168
  await apiServer.start();
156
169
  const agents = Object.keys(config.agents);
157
170
  log.info({ agents }, "OpenACP started");
@@ -168,4 +181,4 @@ export {
168
181
  RESTART_EXIT_CODE,
169
182
  startServer
170
183
  };
171
- //# sourceMappingURL=main-3CDOICYN.js.map
184
+ //# sourceMappingURL=main-NV7YN3VY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/main.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { ConfigManager } from './core/config.js'\nimport { OpenACPCore } from './core/core.js'\nimport { loadAdapterFactory } from './core/plugin-manager.js'\nimport { initLogger, shutdownLogger, cleanupOldSessionLogs, log } from './core/log.js'\nimport { TelegramAdapter } from './adapters/telegram/index.js'\nimport { ApiServer } from './core/api-server.js'\nimport { TopicManager } from './core/topic-manager.js'\n\nexport const RESTART_EXIT_CODE = 75\nlet shuttingDown = false\n\nexport async function startServer() {\n // 0. If running as daemon child, check state and write PID file\n if (process.argv.includes('--daemon-child')) {\n const { writePidFile, readPidFile, getPidPath, shouldAutoStart } = await import('./core/daemon.js')\n\n // Only auto-start if the daemon was previously running (user started it)\n if (!shouldAutoStart()) {\n process.exit(0)\n }\n\n const pidPath = getPidPath()\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 // 1. Check config exists, run setup if not\n const configManager = new ConfigManager()\n const configExists = await configManager.exists()\n\n if (!configExists) {\n const { runSetup } = await import('./core/setup.js')\n const shouldStart = await runSetup(configManager)\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.info({ configPath: configManager.getConfigPath() }, 'Config loaded')\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)\n\n // 3.5 Start tunnel if configured\n let tunnelService: import('./tunnel/tunnel-service.js').TunnelService | undefined\n if (config.tunnel.enabled) {\n const { TunnelService } = await import('./tunnel/tunnel-service.js')\n tunnelService = new TunnelService(config.tunnel)\n const publicUrl = await tunnelService.start()\n core.tunnelService = tunnelService\n log.info({ publicUrl }, 'Tunnel started')\n }\n\n // 4. Register adapters from config\n for (const [channelName, channelConfig] of Object.entries(config.channels)) {\n if (!channelConfig.enabled) continue\n\n if (channelName === 'telegram') {\n core.registerAdapter('telegram', new TelegramAdapter(core, channelConfig as any))\n log.info({ adapter: 'telegram' }, 'Adapter registered')\n } else if (channelConfig.adapter) {\n // Plugin adapter\n const factory = await loadAdapterFactory(channelConfig.adapter)\n if (factory) {\n const adapter = factory.createAdapter(core, channelConfig)\n core.registerAdapter(channelName, adapter)\n log.info({ adapter: channelName, plugin: channelConfig.adapter }, 'Adapter registered')\n } else {\n const name = channelName\n const err = channelConfig.adapter\n log.error({ adapter: name, err }, 'Failed to load adapter')\n }\n } else {\n log.error({ adapter: channelName }, 'Channel has no built-in adapter; set \"adapter\" field to a plugin package')\n }\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. Start\n let apiServer: ApiServer | undefined\n\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 if (apiServer) await apiServer.stop()\n await core.stop()\n if (tunnelService) await tunnelService.stop()\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, getPidPath } = await import('./core/daemon.js')\n removePidFile(getPidPath())\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.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 const updatedConfig = core.configManager.get()\n const telegramAdapter = core.adapters.get('telegram') ?? null\n const telegramCfg = updatedConfig.channels?.telegram as any\n const topicManager = new TopicManager(\n core.sessionManager,\n telegramAdapter,\n {\n notificationTopicId: telegramCfg?.notificationTopicId ?? null,\n assistantTopicId: telegramCfg?.assistantTopicId ?? null,\n },\n )\n\n apiServer = new ApiServer(core, config.api, undefined, topicManager)\n await apiServer.start()\n\n // 6. Log ready\n const agents = Object.keys(config.agents)\n log.info({ agents }, 'OpenACP started')\n log.info('Press Ctrl+C to stop')\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"],"mappings":"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","names":[]}
@@ -9,8 +9,8 @@ import {
9
9
  validateBotAdmin,
10
10
  validateBotToken,
11
11
  validateChatId
12
- } from "./chunk-BLVZFCKN.js";
13
- import "./chunk-WF5XDN4D.js";
12
+ } from "./chunk-UAUTLC4E.js";
13
+ import "./chunk-ZRFBLD3W.js";
14
14
  import "./chunk-LYKCQTH5.js";
15
15
  export {
16
16
  detectAgents,
@@ -24,4 +24,4 @@ export {
24
24
  validateBotToken,
25
25
  validateChatId
26
26
  };
27
- //# sourceMappingURL=setup-JQZBPXWS.js.map
27
+ //# sourceMappingURL=setup-FCVL75K6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openacp/cli",
3
- "version": "0.4.5",
3
+ "version": "0.4.8",
4
4
  "description": "Self-hosted bridge for AI coding agents via ACP protocol",
5
5
  "type": "module",
6
6
  "bin": {