@openacp/cli 0.5.2 → 0.5.3

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 (40) hide show
  1. package/dist/{chunk-JRF4G4X7.js → chunk-2Z2XPUD5.js} +2 -1
  2. package/dist/chunk-2Z2XPUD5.js.map +1 -0
  3. package/dist/{chunk-VBEWSWVL.js → chunk-5KYLXEG3.js} +2 -2
  4. package/dist/{chunk-NDR5JCS7.js → chunk-6DAZSKE5.js} +2 -2
  5. package/dist/{chunk-4ZGMSNRP.js → chunk-ECBD5I5R.js} +4 -3
  6. package/dist/{chunk-4ZGMSNRP.js.map → chunk-ECBD5I5R.js.map} +1 -1
  7. package/dist/{chunk-F4TB4UBK.js → chunk-IQIPQTQT.js} +3 -3
  8. package/dist/{chunk-IRGYTNLP.js → chunk-K53OZH5Y.js} +2 -2
  9. package/dist/{chunk-65XE66HK.js → chunk-LCJIPE5S.js} +335 -69
  10. package/dist/chunk-LCJIPE5S.js.map +1 -0
  11. package/dist/cli.js +110 -22
  12. package/dist/cli.js.map +1 -1
  13. package/dist/{config-PCPIBPUA.js → config-OH26EIWN.js} +2 -2
  14. package/dist/{config-editor-DDF3ZFJK.js → config-editor-5TICUK3K.js} +4 -4
  15. package/dist/{daemon-JZLFRUW6.js → daemon-VKCONJUY.js} +3 -3
  16. package/dist/doctor-X6UCE7GQ.js +9 -0
  17. package/dist/index.d.ts +35 -3
  18. package/dist/index.js +7 -7
  19. package/dist/{integrate-BLETI3UO.js → integrate-VOUYBPPZ.js} +106 -3
  20. package/dist/integrate-VOUYBPPZ.js.map +1 -0
  21. package/dist/{main-AH3NCVM3.js → main-NEYPQHB4.js} +13 -13
  22. package/dist/{setup-7JINXQOA.js → setup-ZCWGOEAH.js} +3 -3
  23. package/dist/{tunnel-service-LEVPLXAZ.js → tunnel-service-U6V4HQOO.js} +263 -47
  24. package/dist/tunnel-service-U6V4HQOO.js.map +1 -0
  25. package/package.json +1 -1
  26. package/dist/chunk-65XE66HK.js.map +0 -1
  27. package/dist/chunk-JRF4G4X7.js.map +0 -1
  28. package/dist/doctor-N2HKKUUQ.js +0 -9
  29. package/dist/integrate-BLETI3UO.js.map +0 -1
  30. package/dist/tunnel-service-LEVPLXAZ.js.map +0 -1
  31. /package/dist/{chunk-VBEWSWVL.js.map → chunk-5KYLXEG3.js.map} +0 -0
  32. /package/dist/{chunk-NDR5JCS7.js.map → chunk-6DAZSKE5.js.map} +0 -0
  33. /package/dist/{chunk-F4TB4UBK.js.map → chunk-IQIPQTQT.js.map} +0 -0
  34. /package/dist/{chunk-IRGYTNLP.js.map → chunk-K53OZH5Y.js.map} +0 -0
  35. /package/dist/{config-PCPIBPUA.js.map → config-OH26EIWN.js.map} +0 -0
  36. /package/dist/{config-editor-DDF3ZFJK.js.map → config-editor-5TICUK3K.js.map} +0 -0
  37. /package/dist/{daemon-JZLFRUW6.js.map → daemon-VKCONJUY.js.map} +0 -0
  38. /package/dist/{doctor-N2HKKUUQ.js.map → doctor-X6UCE7GQ.js.map} +0 -0
  39. /package/dist/{main-AH3NCVM3.js.map → main-NEYPQHB4.js.map} +0 -0
  40. /package/dist/{setup-7JINXQOA.js.map → setup-ZCWGOEAH.js.map} +0 -0
package/dist/index.d.ts CHANGED
@@ -236,6 +236,7 @@ declare const TunnelSchema: z.ZodDefault<z.ZodObject<{
236
236
  port: z.ZodDefault<z.ZodNumber>;
237
237
  provider: z.ZodDefault<z.ZodEnum<["cloudflare", "ngrok", "bore", "tailscale"]>>;
238
238
  options: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
239
+ maxUserTunnels: z.ZodDefault<z.ZodNumber>;
239
240
  storeTtlMinutes: z.ZodDefault<z.ZodNumber>;
240
241
  auth: z.ZodDefault<z.ZodObject<{
241
242
  enabled: z.ZodDefault<z.ZodBoolean>;
@@ -252,6 +253,7 @@ declare const TunnelSchema: z.ZodDefault<z.ZodObject<{
252
253
  enabled: boolean;
253
254
  port: number;
254
255
  provider: "cloudflare" | "ngrok" | "bore" | "tailscale";
256
+ maxUserTunnels: number;
255
257
  storeTtlMinutes: number;
256
258
  auth: {
257
259
  enabled: boolean;
@@ -262,6 +264,7 @@ declare const TunnelSchema: z.ZodDefault<z.ZodObject<{
262
264
  enabled?: boolean | undefined;
263
265
  port?: number | undefined;
264
266
  provider?: "cloudflare" | "ngrok" | "bore" | "tailscale" | undefined;
267
+ maxUserTunnels?: number | undefined;
265
268
  storeTtlMinutes?: number | undefined;
266
269
  auth?: {
267
270
  enabled?: boolean | undefined;
@@ -360,6 +363,7 @@ declare const ConfigSchema: z.ZodObject<{
360
363
  port: z.ZodDefault<z.ZodNumber>;
361
364
  provider: z.ZodDefault<z.ZodEnum<["cloudflare", "ngrok", "bore", "tailscale"]>>;
362
365
  options: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
366
+ maxUserTunnels: z.ZodDefault<z.ZodNumber>;
363
367
  storeTtlMinutes: z.ZodDefault<z.ZodNumber>;
364
368
  auth: z.ZodDefault<z.ZodObject<{
365
369
  enabled: z.ZodDefault<z.ZodBoolean>;
@@ -376,6 +380,7 @@ declare const ConfigSchema: z.ZodObject<{
376
380
  enabled: boolean;
377
381
  port: number;
378
382
  provider: "cloudflare" | "ngrok" | "bore" | "tailscale";
383
+ maxUserTunnels: number;
379
384
  storeTtlMinutes: number;
380
385
  auth: {
381
386
  enabled: boolean;
@@ -386,6 +391,7 @@ declare const ConfigSchema: z.ZodObject<{
386
391
  enabled?: boolean | undefined;
387
392
  port?: number | undefined;
388
393
  provider?: "cloudflare" | "ngrok" | "bore" | "tailscale" | undefined;
394
+ maxUserTunnels?: number | undefined;
389
395
  storeTtlMinutes?: number | undefined;
390
396
  auth?: {
391
397
  enabled?: boolean | undefined;
@@ -418,6 +424,7 @@ declare const ConfigSchema: z.ZodObject<{
418
424
  enabled: boolean;
419
425
  port: number;
420
426
  provider: "cloudflare" | "ngrok" | "bore" | "tailscale";
427
+ maxUserTunnels: number;
421
428
  storeTtlMinutes: number;
422
429
  auth: {
423
430
  enabled: boolean;
@@ -474,6 +481,7 @@ declare const ConfigSchema: z.ZodObject<{
474
481
  enabled?: boolean | undefined;
475
482
  port?: number | undefined;
476
483
  provider?: "cloudflare" | "ngrok" | "bore" | "tailscale" | undefined;
484
+ maxUserTunnels?: number | undefined;
477
485
  storeTtlMinutes?: number | undefined;
478
486
  auth?: {
479
487
  enabled?: boolean | undefined;
@@ -793,6 +801,7 @@ declare class PromptQueue {
793
801
  private onError?;
794
802
  private queue;
795
803
  private processing;
804
+ private abortController;
796
805
  constructor(processor: (text: string, attachments?: Attachment[]) => Promise<void>, onError?: ((err: unknown) => void) | undefined);
797
806
  enqueue(text: string, attachments?: Attachment[]): Promise<void>;
798
807
  private process;
@@ -802,6 +811,17 @@ declare class PromptQueue {
802
811
  get isProcessing(): boolean;
803
812
  }
804
813
 
814
+ interface TunnelEntry {
815
+ port: number;
816
+ type: 'system' | 'user';
817
+ provider: string;
818
+ label?: string;
819
+ publicUrl?: string;
820
+ sessionId?: string;
821
+ status: 'stopped' | 'starting' | 'active' | 'failed';
822
+ createdAt: string;
823
+ }
824
+
805
825
  interface ViewerEntry {
806
826
  id: string;
807
827
  type: 'file' | 'diff';
@@ -829,19 +849,27 @@ declare class ViewerStore {
829
849
  }
830
850
 
831
851
  declare class TunnelService {
832
- private provider;
852
+ private registry;
833
853
  private store;
834
854
  private server;
835
- private publicUrl;
836
855
  private config;
856
+ private systemPort;
837
857
  constructor(config: TunnelConfig);
838
858
  start(): Promise<string>;
839
859
  stop(): Promise<void>;
860
+ addTunnel(port: number, opts?: {
861
+ label?: string;
862
+ sessionId?: string;
863
+ }): Promise<TunnelEntry>;
864
+ stopTunnel(port: number): Promise<void>;
865
+ stopAllUser(): Promise<void>;
866
+ stopBySession(sessionId: string): Promise<TunnelEntry[]>;
867
+ listTunnels(): TunnelEntry[];
868
+ getTunnel(port: number): TunnelEntry | null;
840
869
  getPublicUrl(): string;
841
870
  getStore(): ViewerStore;
842
871
  fileUrl(entryId: string): string;
843
872
  diffUrl(entryId: string): string;
844
- private createProvider;
845
873
  }
846
874
 
847
875
  declare class MessageTransformer {
@@ -1081,6 +1109,10 @@ declare class ApiServer {
1081
1109
  private handleUpdateConfig;
1082
1110
  private handleListAdapters;
1083
1111
  private handleTunnelStatus;
1112
+ private handleTunnelList;
1113
+ private handleTunnelAdd;
1114
+ private handleTunnelStop;
1115
+ private handleTunnelStopAll;
1084
1116
  private handleNotify;
1085
1117
  private handleRestart;
1086
1118
  private handleCancelSession;
package/dist/index.js CHANGED
@@ -18,11 +18,11 @@ import {
18
18
  TypedEmitter,
19
19
  nodeToWebReadable,
20
20
  nodeToWebWritable
21
- } from "./chunk-65XE66HK.js";
21
+ } from "./chunk-LCJIPE5S.js";
22
22
  import {
23
23
  runConfigEditor
24
- } from "./chunk-F4TB4UBK.js";
25
- import "./chunk-IRGYTNLP.js";
24
+ } from "./chunk-IQIPQTQT.js";
25
+ import "./chunk-K53OZH5Y.js";
26
26
  import "./chunk-NAMYZIS5.js";
27
27
  import "./chunk-IURZ4QHG.js";
28
28
  import {
@@ -30,7 +30,7 @@ import {
30
30
  getStatus,
31
31
  startDaemon,
32
32
  stopDaemon
33
- } from "./chunk-VBEWSWVL.js";
33
+ } from "./chunk-5KYLXEG3.js";
34
34
  import {
35
35
  AgentCatalog
36
36
  } from "./chunk-J6X5SW6O.js";
@@ -43,14 +43,14 @@ import {
43
43
  isAutoStartSupported,
44
44
  uninstallAutoStart
45
45
  } from "./chunk-X6LLG7XN.js";
46
- import "./chunk-4ZGMSNRP.js";
46
+ import "./chunk-ECBD5I5R.js";
47
47
  import "./chunk-JKBFUAJK.js";
48
48
  import {
49
49
  installPlugin,
50
50
  listPlugins,
51
51
  loadAdapterFactory,
52
52
  uninstallPlugin
53
- } from "./chunk-NDR5JCS7.js";
53
+ } from "./chunk-6DAZSKE5.js";
54
54
  import {
55
55
  CONFIG_REGISTRY,
56
56
  getConfigValue,
@@ -63,7 +63,7 @@ import {
63
63
  ConfigManager,
64
64
  PLUGINS_DIR,
65
65
  expandHome
66
- } from "./chunk-JRF4G4X7.js";
66
+ } from "./chunk-2Z2XPUD5.js";
67
67
  import {
68
68
  cleanupOldSessionLogs,
69
69
  createChildLogger,
@@ -51,6 +51,56 @@ fi
51
51
  openacp adopt ${agentKey} "$SESSION_ID" \${CWD:+--cwd "$CWD"}
52
52
  `;
53
53
  }
54
+ function generateTunnelCommand() {
55
+ return `---
56
+ description: 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.
57
+ ---
58
+
59
+ You 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.
60
+
61
+ ## Commands
62
+
63
+ \`\`\`bash
64
+ # Create a tunnel \u2014 exposes local port to the internet
65
+ openacp tunnel add <port> --label <name>
66
+
67
+ # List all active tunnels with their public URLs
68
+ openacp tunnel list
69
+
70
+ # Stop a specific tunnel
71
+ openacp tunnel stop <port>
72
+
73
+ # Stop all tunnels
74
+ openacp tunnel stop-all
75
+ \`\`\`
76
+
77
+ ## When to use
78
+
79
+ User wants to:
80
+ - **Share their local app** \u2014 "share this on my phone", "let my friend see this", "preview on mobile"
81
+ - **Expose a port** \u2014 "expose port 3000", "map port 5173", "make port 8080 public"
82
+ - **Get a public URL** \u2014 "give me a public URL", "I need an external link", "make localhost accessible"
83
+ - **Open a tunnel** \u2014 "open tunnel", "start tunnel", "tunnel this", "b\u1EADt tunnel"
84
+ - **Forward/proxy a port** \u2014 "forward port 3000", "proxy my server"
85
+ - **Deploy preview** \u2014 "deploy preview", "share a preview link"
86
+ - **Access remotely** \u2014 "access from my phone", "access from outside"
87
+ - **Manage tunnels** \u2014 "show tunnels", "list tunnels", "stop tunnel", "close tunnel", "kill tunnel"
88
+
89
+ ## How to respond
90
+
91
+ 1. Run the CLI command
92
+ 2. Share the public URL with the user
93
+ 3. Mention the URL works on any device (phone, tablet, other computer)
94
+ 4. If the user hasn't started a dev server yet, remind them to start one first
95
+
96
+ ## Example flow
97
+
98
+ User: "I want to see this React app on my phone"
99
+ \u2192 Check if dev server is running (e.g. port 5173 for Vite)
100
+ \u2192 Run: \`openacp tunnel add 5173 --label react-app\`
101
+ \u2192 Share the public URL
102
+ `;
103
+ }
54
104
  function generateHandoffCommand(_agentKey, spec) {
55
105
  const sidVar = spec.sessionIdVar ?? "SESSION_ID";
56
106
  const cwdVar = spec.workingDirVar ?? "WORKING_DIR";
@@ -227,7 +277,7 @@ async function uninstallIntegration(agentKey, spec) {
227
277
  return { success: false, logs };
228
278
  }
229
279
  }
230
- function buildIntegrationItem(agentKey, spec) {
280
+ function buildHandoffItem(agentKey, spec) {
231
281
  const hooksDir = expandPath(spec.hooksDirPath);
232
282
  return {
233
283
  id: "handoff",
@@ -240,10 +290,63 @@ function buildIntegrationItem(agentKey, spec) {
240
290
  uninstall: () => uninstallIntegration(agentKey, spec)
241
291
  };
242
292
  }
293
+ function getSkillBasePath(spec) {
294
+ const base = spec.commandsPath;
295
+ const skillsBase = base.replace(/\/commands\/?$/, "/skills/");
296
+ return expandPath(skillsBase);
297
+ }
298
+ function buildTunnelItem(spec) {
299
+ if (!spec.commandsPath) return null;
300
+ function getTunnelPath() {
301
+ return join(getSkillBasePath(spec), "openacp-tunnel", "SKILL.md");
302
+ }
303
+ return {
304
+ id: "tunnel",
305
+ name: "Tunnel",
306
+ description: "Expose local ports to the internet via OpenACP tunnel",
307
+ isInstalled() {
308
+ return existsSync(getTunnelPath());
309
+ },
310
+ async install() {
311
+ const logs = [];
312
+ try {
313
+ const skillPath = getTunnelPath();
314
+ mkdirSync(dirname(skillPath), { recursive: true });
315
+ writeFileSync(skillPath, generateTunnelCommand());
316
+ logs.push(`Created ${skillPath}`);
317
+ return { success: true, logs };
318
+ } catch (err) {
319
+ logs.push(`Error: ${err instanceof Error ? err.message : String(err)}`);
320
+ return { success: false, logs };
321
+ }
322
+ },
323
+ async uninstall() {
324
+ const logs = [];
325
+ try {
326
+ const skillPath = getTunnelPath();
327
+ if (existsSync(skillPath)) {
328
+ unlinkSync(skillPath);
329
+ try {
330
+ rmdirSync(dirname(skillPath));
331
+ } catch {
332
+ }
333
+ logs.push(`Removed ${skillPath}`);
334
+ }
335
+ return { success: true, logs };
336
+ } catch (err) {
337
+ logs.push(`Error: ${err instanceof Error ? err.message : String(err)}`);
338
+ return { success: false, logs };
339
+ }
340
+ }
341
+ };
342
+ }
243
343
  function getIntegration(agentName) {
244
344
  const caps = getAgentCapabilities(agentName);
245
345
  if (!caps.integration) return void 0;
246
- return { items: [buildIntegrationItem(agentName, caps.integration)] };
346
+ const items = [buildHandoffItem(agentName, caps.integration)];
347
+ const tunnelItem = buildTunnelItem(caps.integration);
348
+ if (tunnelItem) items.push(tunnelItem);
349
+ return { items };
247
350
  }
248
351
  function listIntegrations() {
249
352
  return listAgentsWithIntegration();
@@ -254,4 +357,4 @@ export {
254
357
  listIntegrations,
255
358
  uninstallIntegration
256
359
  };
257
- //# sourceMappingURL=integrate-BLETI3UO.js.map
360
+ //# sourceMappingURL=integrate-VOUYBPPZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/cli/integrate.ts"],"sourcesContent":["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/agent-dependencies.js\";\nimport type { AgentIntegrationSpec } from \"../core/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 if (spec.outputFormat === \"plaintext\") {\n return `#!/bin/bash\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\nINPUT=$(cat)\nSESSION_ID=$(echo \"$INPUT\" | jq -r '${spec.sessionIdField}')\nCWD=$(echo \"$INPUT\" | jq -r '.cwd')\n\njq -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\n\nif [ -z \"$SESSION_ID\" ]; then\n echo \"Usage: openacp-handoff.sh <session_id> [cwd]\"\n exit 1\nfi\n\nopenacp adopt ${agentKey} \"$SESSION_ID\" \\${CWD:+--cwd \"$CWD\"}\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\", \"bật tunnel\"\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)\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}>\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 Telegram\",\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"],"mappings":"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","names":[]}
@@ -4,24 +4,24 @@ import {
4
4
  OpenACPCore,
5
5
  TelegramAdapter,
6
6
  TopicManager
7
- } from "./chunk-65XE66HK.js";
8
- import "./chunk-F4TB4UBK.js";
9
- import "./chunk-IRGYTNLP.js";
7
+ } from "./chunk-LCJIPE5S.js";
8
+ import "./chunk-IQIPQTQT.js";
9
+ import "./chunk-K53OZH5Y.js";
10
10
  import "./chunk-NAMYZIS5.js";
11
11
  import "./chunk-IURZ4QHG.js";
12
- import "./chunk-VBEWSWVL.js";
12
+ import "./chunk-5KYLXEG3.js";
13
13
  import "./chunk-J6X5SW6O.js";
14
14
  import "./chunk-5HGXUCMX.js";
15
15
  import "./chunk-X6LLG7XN.js";
16
- import "./chunk-4ZGMSNRP.js";
16
+ import "./chunk-ECBD5I5R.js";
17
17
  import "./chunk-JKBFUAJK.js";
18
18
  import {
19
19
  loadAdapterFactory
20
- } from "./chunk-NDR5JCS7.js";
20
+ } from "./chunk-6DAZSKE5.js";
21
21
  import "./chunk-Z46LGZ7R.js";
22
22
  import {
23
23
  ConfigManager
24
- } from "./chunk-JRF4G4X7.js";
24
+ } from "./chunk-2Z2XPUD5.js";
25
25
  import {
26
26
  cleanupOldSessionLogs,
27
27
  initLogger,
@@ -34,7 +34,7 @@ var RESTART_EXIT_CODE = 75;
34
34
  var shuttingDown = false;
35
35
  async function startServer() {
36
36
  if (process.argv.includes("--daemon-child")) {
37
- const { writePidFile, readPidFile, getPidPath, shouldAutoStart } = await import("./daemon-JZLFRUW6.js");
37
+ const { writePidFile, readPidFile, getPidPath, shouldAutoStart } = await import("./daemon-VKCONJUY.js");
38
38
  if (!shouldAutoStart()) {
39
39
  process.exit(0);
40
40
  }
@@ -53,7 +53,7 @@ async function startServer() {
53
53
  const configManager = new ConfigManager();
54
54
  const configExists = await configManager.exists();
55
55
  if (!configExists) {
56
- const { runSetup } = await import("./setup-7JINXQOA.js");
56
+ const { runSetup } = await import("./setup-ZCWGOEAH.js");
57
57
  const shouldStart = await runSetup(configManager);
58
58
  if (!shouldStart) process.exit(0);
59
59
  }
@@ -67,7 +67,7 @@ async function startServer() {
67
67
  const core = new OpenACPCore(configManager);
68
68
  let tunnelService;
69
69
  if (config.tunnel.enabled) {
70
- const { TunnelService } = await import("./tunnel-service-LEVPLXAZ.js");
70
+ const { TunnelService } = await import("./tunnel-service-U6V4HQOO.js");
71
71
  tunnelService = new TunnelService(config.tunnel);
72
72
  const publicUrl = await tunnelService.start();
73
73
  core.tunnelService = tunnelService;
@@ -111,13 +111,13 @@ async function startServer() {
111
111
  }
112
112
  const isDaemon = process.argv.includes("--daemon-child");
113
113
  if (isDaemon) {
114
- const { removePidFile, getPidPath } = await import("./daemon-JZLFRUW6.js");
114
+ const { removePidFile, getPidPath } = await import("./daemon-VKCONJUY.js");
115
115
  removePidFile(getPidPath());
116
116
  }
117
117
  if (exitCode === RESTART_EXIT_CODE) {
118
118
  if (isDaemon) {
119
119
  const { spawn: spawnChild } = await import("child_process");
120
- const { expandHome } = await import("./config-PCPIBPUA.js");
120
+ const { expandHome } = await import("./config-OH26EIWN.js");
121
121
  const fs = await import("fs");
122
122
  const pathMod = await import("path");
123
123
  const cliPath = pathMod.resolve(process.argv[1]);
@@ -187,4 +187,4 @@ export {
187
187
  RESTART_EXIT_CODE,
188
188
  startServer
189
189
  };
190
- //# sourceMappingURL=main-AH3NCVM3.js.map
190
+ //# sourceMappingURL=main-NEYPQHB4.js.map
@@ -9,9 +9,9 @@ import {
9
9
  validateBotAdmin,
10
10
  validateBotToken,
11
11
  validateChatId
12
- } from "./chunk-4ZGMSNRP.js";
12
+ } from "./chunk-ECBD5I5R.js";
13
13
  import "./chunk-JKBFUAJK.js";
14
- import "./chunk-JRF4G4X7.js";
14
+ import "./chunk-2Z2XPUD5.js";
15
15
  import "./chunk-ESOPMQAY.js";
16
16
  export {
17
17
  detectAgents,
@@ -25,4 +25,4 @@ export {
25
25
  validateBotToken,
26
26
  validateChatId
27
27
  };
28
- //# sourceMappingURL=setup-7JINXQOA.js.map
28
+ //# sourceMappingURL=setup-ZCWGOEAH.js.map