@openacp/cli 0.5.3 → 0.6.1

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 (100) hide show
  1. package/README.md +51 -16
  2. package/dist/action-detect-6M5GCGAU.js +15 -0
  3. package/dist/admin-IKPS5PFC.js +16 -0
  4. package/dist/agents-55NX3DHM.js +14 -0
  5. package/dist/{api-client-UN7BXQOQ.js → api-client-BH2JFHQW.js} +4 -2
  6. package/dist/{autostart-K73RQZVV.js → autostart-A7JRU4WJ.js} +6 -2
  7. package/dist/{chunk-ECBD5I5R.js → chunk-2KJC3ILH.js} +123 -16
  8. package/dist/chunk-2KJC3ILH.js.map +1 -0
  9. package/dist/{chunk-2Z2XPUD5.js → chunk-4LFDEW22.js} +53 -5
  10. package/dist/chunk-4LFDEW22.js.map +1 -0
  11. package/dist/{chunk-Z46LGZ7R.js → chunk-4TR5Y3MP.js} +18 -1
  12. package/dist/chunk-4TR5Y3MP.js.map +1 -0
  13. package/dist/chunk-7G5QKLLF.js +105 -0
  14. package/dist/chunk-7G5QKLLF.js.map +1 -0
  15. package/dist/{chunk-IURZ4QHG.js → chunk-7QJS2XBD.js} +2 -1
  16. package/dist/chunk-7QJS2XBD.js.map +1 -0
  17. package/dist/chunk-AKIU4JBF.js +145 -0
  18. package/dist/chunk-AKIU4JBF.js.map +1 -0
  19. package/dist/{chunk-KSIQZC3J.js → chunk-EVFJW45N.js} +1 -1
  20. package/dist/chunk-EVFJW45N.js.map +1 -0
  21. package/dist/chunk-GINCOFNW.js +134 -0
  22. package/dist/chunk-GINCOFNW.js.map +1 -0
  23. package/dist/chunk-H7ZMPBZC.js +203 -0
  24. package/dist/chunk-H7ZMPBZC.js.map +1 -0
  25. package/dist/chunk-I7WC6E5S.js +71 -0
  26. package/dist/chunk-I7WC6E5S.js.map +1 -0
  27. package/dist/{chunk-6DAZSKE5.js → chunk-IMILOCR5.js} +2 -2
  28. package/dist/chunk-LGQYTK55.js +442 -0
  29. package/dist/chunk-LGQYTK55.js.map +1 -0
  30. package/dist/{chunk-X6LLG7XN.js → chunk-PMGNLNSH.js} +15 -6
  31. package/dist/chunk-PMGNLNSH.js.map +1 -0
  32. package/dist/{chunk-LCJIPE5S.js → chunk-R3UJUOXI.js} +889 -591
  33. package/dist/chunk-R3UJUOXI.js.map +1 -0
  34. package/dist/chunk-SM3G6UAX.js +122 -0
  35. package/dist/chunk-SM3G6UAX.js.map +1 -0
  36. package/dist/chunk-T22OLSET.js +265 -0
  37. package/dist/chunk-T22OLSET.js.map +1 -0
  38. package/dist/chunk-THBR6OXH.js +62 -0
  39. package/dist/chunk-THBR6OXH.js.map +1 -0
  40. package/dist/{chunk-5KYLXEG3.js → chunk-TOZQ3JFN.js} +52 -9
  41. package/dist/chunk-TOZQ3JFN.js.map +1 -0
  42. package/dist/{chunk-IQIPQTQT.js → chunk-UB7XUO7C.js} +171 -26
  43. package/dist/chunk-UB7XUO7C.js.map +1 -0
  44. package/dist/{chunk-OORPX73T.js → chunk-W3EYKZNQ.js} +17 -2
  45. package/dist/chunk-W3EYKZNQ.js.map +1 -0
  46. package/dist/{chunk-K53OZH5Y.js → chunk-ZCHNAM3B.js} +76 -2
  47. package/dist/chunk-ZCHNAM3B.js.map +1 -0
  48. package/dist/cli.js +30 -29
  49. package/dist/cli.js.map +1 -1
  50. package/dist/{config-OH26EIWN.js → config-AK2W3E67.js} +2 -2
  51. package/dist/config-editor-VIA7A72X.js +12 -0
  52. package/dist/{config-registry-SNKA2EH2.js → config-registry-QQOJ2GQP.js} +2 -2
  53. package/dist/{daemon-VKCONJUY.js → daemon-G27YZUWB.js} +3 -3
  54. package/dist/discord-2DKRH45T.js +2044 -0
  55. package/dist/discord-2DKRH45T.js.map +1 -0
  56. package/dist/doctor-AN6AZ3PF.js +9 -0
  57. package/dist/doctor-CHCYUTV5.js +14 -0
  58. package/dist/doctor-CHCYUTV5.js.map +1 -0
  59. package/dist/index.d.ts +331 -6
  60. package/dist/index.js +21 -11
  61. package/dist/{main-NEYPQHB4.js → main-56SPFYW4.js} +32 -24
  62. package/dist/main-56SPFYW4.js.map +1 -0
  63. package/dist/{menu-J5YVH665.js → menu-XR2GET2B.js} +2 -2
  64. package/dist/menu-XR2GET2B.js.map +1 -0
  65. package/dist/new-session-DRRP2J7E.js +16 -0
  66. package/dist/new-session-DRRP2J7E.js.map +1 -0
  67. package/dist/session-FVFLBREJ.js +19 -0
  68. package/dist/session-FVFLBREJ.js.map +1 -0
  69. package/dist/settings-LPOLJ6SA.js +12 -0
  70. package/dist/settings-LPOLJ6SA.js.map +1 -0
  71. package/dist/{setup-ZCWGOEAH.js → setup-IPWJCIJM.js} +9 -5
  72. package/dist/setup-IPWJCIJM.js.map +1 -0
  73. package/dist/{version-VC5CPXBX.js → version-ALWGGVKM.js} +2 -2
  74. package/dist/version-ALWGGVKM.js.map +1 -0
  75. package/package.json +2 -1
  76. package/dist/chunk-2Z2XPUD5.js.map +0 -1
  77. package/dist/chunk-5KYLXEG3.js.map +0 -1
  78. package/dist/chunk-ECBD5I5R.js.map +0 -1
  79. package/dist/chunk-IQIPQTQT.js.map +0 -1
  80. package/dist/chunk-IURZ4QHG.js.map +0 -1
  81. package/dist/chunk-K53OZH5Y.js.map +0 -1
  82. package/dist/chunk-KSIQZC3J.js.map +0 -1
  83. package/dist/chunk-LCJIPE5S.js.map +0 -1
  84. package/dist/chunk-OORPX73T.js.map +0 -1
  85. package/dist/chunk-X6LLG7XN.js.map +0 -1
  86. package/dist/chunk-Z46LGZ7R.js.map +0 -1
  87. package/dist/config-editor-5TICUK3K.js +0 -12
  88. package/dist/doctor-X6UCE7GQ.js +0 -9
  89. package/dist/main-NEYPQHB4.js.map +0 -1
  90. /package/dist/{api-client-UN7BXQOQ.js.map → action-detect-6M5GCGAU.js.map} +0 -0
  91. /package/dist/{autostart-K73RQZVV.js.map → admin-IKPS5PFC.js.map} +0 -0
  92. /package/dist/{config-OH26EIWN.js.map → agents-55NX3DHM.js.map} +0 -0
  93. /package/dist/{config-editor-5TICUK3K.js.map → api-client-BH2JFHQW.js.map} +0 -0
  94. /package/dist/{config-registry-SNKA2EH2.js.map → autostart-A7JRU4WJ.js.map} +0 -0
  95. /package/dist/{chunk-6DAZSKE5.js.map → chunk-IMILOCR5.js.map} +0 -0
  96. /package/dist/{daemon-VKCONJUY.js.map → config-AK2W3E67.js.map} +0 -0
  97. /package/dist/{doctor-X6UCE7GQ.js.map → config-editor-VIA7A72X.js.map} +0 -0
  98. /package/dist/{menu-J5YVH665.js.map → config-registry-QQOJ2GQP.js.map} +0 -0
  99. /package/dist/{setup-ZCWGOEAH.js.map → daemon-G27YZUWB.js.map} +0 -0
  100. /package/dist/{version-VC5CPXBX.js.map → doctor-AN6AZ3PF.js.map} +0 -0
@@ -0,0 +1,442 @@
1
+ // src/core/channel.ts
2
+ var ChannelAdapter = class {
3
+ constructor(core, config) {
4
+ this.core = core;
5
+ this.config = config;
6
+ }
7
+ async deleteSessionThread(_sessionId) {
8
+ }
9
+ // Skill commands — override in adapters that support dynamic commands
10
+ async sendSkillCommands(_sessionId, _commands) {
11
+ }
12
+ async cleanupSkillCommands(_sessionId) {
13
+ }
14
+ // Archive — override in adapters that support topic archiving
15
+ async archiveSessionTopic(_sessionId) {
16
+ return null;
17
+ }
18
+ };
19
+
20
+ // src/product-guide.ts
21
+ var PRODUCT_GUIDE = `
22
+ # OpenACP \u2014 Product Guide
23
+
24
+ OpenACP lets you chat with AI coding agents (like Claude Code) through messaging platforms (Telegram, Discord).
25
+ You type messages in your chat platform, the agent reads/writes/runs code in your project folder, and results stream back in real time.
26
+
27
+ ---
28
+
29
+ ## Quick Start
30
+
31
+ 1. Start OpenACP: \`openacp\` (or \`openacp start\` for background daemon)
32
+ 2. Open your messaging platform (Telegram group or Discord server) \u2014 you'll see the Assistant topic/thread
33
+ 3. Tap/click \u{1F195} New Session or type /new
34
+ 4. Pick an agent and a project folder
35
+ 5. Chat in the session topic/thread \u2014 the agent works on your code
36
+
37
+ ---
38
+
39
+ ## Core Concepts
40
+
41
+ ### Sessions
42
+ A session = one conversation with one AI agent working in one project folder.
43
+ Each session gets its own topic (Telegram) or forum thread (Discord). Chat there to give instructions to the agent.
44
+
45
+ ### Agents
46
+ An agent is an AI coding tool (e.g., Claude Code, Gemini, Cursor, Codex, etc.).
47
+ OpenACP supports 28+ agents from the official ACP Registry (agentclientprotocol.com).
48
+ You can install multiple agents and choose which one to use per session.
49
+ The default agent is used when you don't specify one.
50
+
51
+ ### Agent Management
52
+ - Browse agents: \`/agents\` in your chat platform or \`openacp agents\` in CLI
53
+ - Install: tap the install button in /agents, or \`openacp agents install <name>\`
54
+ - Uninstall: \`openacp agents uninstall <name>\`
55
+ - Setup/login: \`openacp agents run <name> -- <args>\` (e.g., \`openacp agents run gemini -- auth login\`)
56
+ - Details: \`openacp agents info <name>\` shows version, dependencies, and setup steps
57
+
58
+ Some agents need additional setup before they can be used:
59
+ - Claude: requires \`claude login\`
60
+ - Gemini: requires \`openacp agents run gemini -- auth login\`
61
+ - Codex: requires setting \`OPENAI_API_KEY\` environment variable
62
+ - GitHub Copilot: requires \`openacp agents run copilot -- auth login\`
63
+
64
+ Agents are installed in three ways depending on the agent:
65
+ - **npx** \u2014 Node.js agents, downloaded automatically on first use
66
+ - **uvx** \u2014 Python agents, downloaded automatically on first use
67
+ - **binary** \u2014 Platform-specific binaries, downloaded to \`~/.openacp/agents/\`
68
+
69
+ ### Project Folder (Workspace)
70
+ The directory where the agent reads, writes, and runs code.
71
+ When creating a session, you choose which folder the agent works in.
72
+ You can type a full path like \`~/code/my-project\` or just a name like \`my-project\` (it becomes \`<base-dir>/my-project\`).
73
+
74
+ ### System Topics
75
+ - **Assistant** \u2014 Always-on helper that can answer questions, create sessions, check status, troubleshoot
76
+ - **Notifications** \u2014 System alerts (permission requests, session errors, completions)
77
+
78
+ ---
79
+
80
+ ## Creating Sessions
81
+
82
+ ### From menu
83
+ Tap \u{1F195} New Session \u2192 choose agent (if multiple) \u2192 choose project folder \u2192 confirm
84
+
85
+ ### From command
86
+ - \`/new\` \u2014 Interactive flow (asks agent + folder)
87
+ - \`/new claude ~/code/my-project\` \u2014 Create directly with specific agent and folder
88
+
89
+ ### From Assistant topic
90
+ Just ask: "Create a session for my-project with claude" \u2014 the assistant handles it
91
+
92
+ ### Quick new chat
93
+ \`/newchat\` in a session topic \u2014 creates new session with same agent and folder as current one
94
+
95
+ ---
96
+
97
+ ## Working with Sessions
98
+
99
+ ### Chat
100
+ Type messages in the session topic. The agent responds with code changes, explanations, tool outputs.
101
+
102
+ ### What you see while the agent works
103
+ - **\u{1F4AD} Thinking indicator** \u2014 Shows when the agent is reasoning, with elapsed time
104
+ - **Text responses** \u2014 Streamed in real time, updated every few seconds
105
+ - **Tool calls** \u2014 When the agent runs commands or edits files, you see tool name, input, status, and output
106
+ - **\u{1F4CB} Plan card** \u2014 Visual task progress with completed/in-progress/pending items and progress bar
107
+ - **"View File" / "View Diff" buttons** \u2014 Opens in browser with Monaco editor (requires tunnel)
108
+
109
+ ### Session lifecycle
110
+ 1. **Creating** \u2014 Topic created, agent spawning
111
+ 2. **Warming up** \u2014 Agent primes its cache (happens automatically, invisible to you)
112
+ 3. **Active** \u2014 Ready for your messages
113
+ 4. **Auto-naming** \u2014 After your first message, the session gets a descriptive name (agent summarizes in ~5 words). The topic title updates automatically.
114
+ 5. **Finished/Error** \u2014 Session completed or hit an error
115
+
116
+ ### Agent skills
117
+ Some agents provide slash commands (e.g., /compact, /review). Available skills are pinned in the session topic.
118
+
119
+ ### Permission requests
120
+ When the agent wants to run a command, it asks for permission.
121
+ You see buttons: \u2705 Allow, \u274C Reject (and sometimes "Always Allow").
122
+ A notification also appears in the Notifications topic with a link to the request.
123
+
124
+ ### Dangerous mode
125
+ Auto-approves ALL permission requests \u2014 the agent runs any command without asking.
126
+ - Enable: \`/enable_dangerous\` or tap the \u2620\uFE0F button in the session
127
+ - Disable: \`/disable_dangerous\` or tap the \u{1F510} button
128
+ - \u26A0\uFE0F Use with caution \u2014 the agent can execute anything
129
+
130
+ ### Session timeout
131
+ Idle sessions are automatically cancelled after a configurable timeout (default: 60 minutes).
132
+ Configure via \`security.sessionTimeoutMinutes\` in config.
133
+
134
+ ---
135
+
136
+ ## Session Transfer (Handoff)
137
+
138
+ ### Chat \u2192 Terminal
139
+ 1. Type \`/handoff\` in a session topic/thread
140
+ 2. You get a command like \`claude --resume <SESSION_ID>\`
141
+ 3. Copy and run it in your terminal \u2014 the session continues there with full conversation history
142
+
143
+ ### Terminal \u2192 Chat
144
+ 1. First time: run \`openacp integrate claude\` to install the handoff skill (one-time setup)
145
+ 2. In Claude Code, use the /openacp:handoff slash command
146
+ 3. The session appears as a new topic/thread and you can continue chatting there
147
+
148
+ ### How it works
149
+ - The agent session ID is shared between platforms
150
+ - Conversation history is preserved \u2014 pick up where you left off
151
+ - The agent that supports resume (e.g., Claude with \`--resume\`) handles the actual transfer
152
+
153
+ ---
154
+
155
+ ## Managing Sessions
156
+
157
+ ### Status
158
+ - \`/status\` \u2014 Shows active sessions count and details
159
+ - Ask the Assistant: "What sessions are running?"
160
+
161
+ ### List all sessions
162
+ - \`/sessions\` \u2014 Shows all sessions with status (active, finished, error)
163
+
164
+ ### Cancel
165
+ - \`/cancel\` in a session topic \u2014 cancels that session
166
+ - Ask the Assistant: "Cancel the stuck session"
167
+
168
+ ### Cleanup
169
+ - From \`/sessions\` \u2192 tap cleanup buttons (finished, errors, all)
170
+ - Ask the Assistant: "Clean up old sessions"
171
+
172
+ ---
173
+
174
+ ## Assistant Topic
175
+
176
+ The Assistant is an always-on AI helper in its own topic. It can:
177
+ - Answer questions about OpenACP
178
+ - Create sessions for you
179
+ - Check status and health
180
+ - Cancel sessions
181
+ - Clean up old sessions
182
+ - Troubleshoot issues
183
+ - Manage configuration
184
+
185
+ Just chat naturally: "How do I create a session?", "What's the status?", "Something is stuck"
186
+
187
+ ### Clear history
188
+ \`/clear\` in the Assistant topic \u2014 resets the conversation
189
+
190
+ ---
191
+
192
+ ## System Commands
193
+
194
+ | Command | Where | What it does |
195
+ |---------|-------|-------------|
196
+ | \`/new [agent] [path]\` | Anywhere | Create new session |
197
+ | \`/newchat\` | Session topic | New session, same agent + folder |
198
+ | \`/cancel\` | Session topic | Cancel current session |
199
+ | \`/status\` | Anywhere | Show status |
200
+ | \`/sessions\` | Anywhere | List all sessions |
201
+ | \`/agents\` | Anywhere | Browse & install agents from ACP Registry |
202
+ | \`/install <name>\` | Anywhere | Install an agent |
203
+ | \`/enable_dangerous\` | Session topic | Auto-approve all permissions |
204
+ | \`/disable_dangerous\` | Session topic | Restore permission prompts |
205
+ | \`/handoff\` | Session topic | Transfer session to terminal |
206
+ | \`/clear\` | Assistant topic | Clear assistant history |
207
+ | \`/menu\` | Anywhere | Show action menu |
208
+ | \`/help\` | Anywhere | Show help |
209
+ | \`/restart\` | Anywhere | Restart OpenACP |
210
+ | \`/update\` | Anywhere | Update to latest version |
211
+ | \`/integrate\` | Anywhere | Manage agent integrations |
212
+
213
+ ---
214
+
215
+ ## Menu Buttons
216
+
217
+ | Button | Action |
218
+ |--------|--------|
219
+ | \u{1F195} New Session | Create new session (interactive) |
220
+ | \u{1F4CB} Sessions | List all sessions with cleanup options |
221
+ | \u{1F4CA} Status | Show active/total session count |
222
+ | \u{1F916} Agents | List available agents |
223
+ | \u{1F517} Integrate | Manage agent integrations |
224
+ | \u2753 Help | Show help text |
225
+ | \u{1F504} Restart | Restart OpenACP |
226
+ | \u2B06\uFE0F Update | Check and install updates |
227
+
228
+ ---
229
+
230
+ ## CLI Commands
231
+
232
+ ### Server
233
+ - \`openacp\` \u2014 Start (uses configured mode: foreground or daemon)
234
+ - \`openacp start\` \u2014 Start as background daemon
235
+ - \`openacp stop\` \u2014 Stop daemon
236
+ - \`openacp status\` \u2014 Show daemon status
237
+ - \`openacp logs\` \u2014 Tail daemon logs
238
+ - \`openacp --foreground\` \u2014 Force foreground mode (useful for debugging or containers)
239
+
240
+ ### Auto-start (run on boot)
241
+ - macOS: installs a LaunchAgent in \`~/Library/LaunchAgents/\`
242
+ - Linux: installs a systemd user service in \`~/.config/systemd/user/\`
243
+ - Enabled automatically when you start the daemon. Remove with \`openacp stop\`.
244
+
245
+ ### Configuration
246
+ - \`openacp config\` \u2014 Interactive config editor
247
+ - \`openacp reset\` \u2014 Delete all data and start fresh
248
+
249
+ ### Agent Management (CLI)
250
+ - \`openacp agents\` \u2014 List all agents (installed + available from ACP Registry)
251
+ - \`openacp agents install <name>\` \u2014 Install an agent
252
+ - \`openacp agents uninstall <name>\` \u2014 Remove an agent
253
+ - \`openacp agents info <name>\` \u2014 Show details, dependencies, and setup guide
254
+ - \`openacp agents run <name> [-- args]\` \u2014 Run agent CLI directly (for login, config, etc.)
255
+ - \`openacp agents refresh\` \u2014 Force-refresh registry cache
256
+
257
+ ### Plugins
258
+ - \`openacp install <package>\` \u2014 Install adapter plugin
259
+ - \`openacp uninstall <package>\` \u2014 Remove adapter plugin
260
+ - \`openacp plugins\` \u2014 List installed plugins
261
+
262
+ ### Integration
263
+ - \`openacp integrate <agent>\` \u2014 Install agent integration (e.g., Claude handoff skill)
264
+ - \`openacp integrate <agent> --uninstall\` \u2014 Remove integration
265
+
266
+ ### API (requires running daemon)
267
+ \`openacp api <command>\` \u2014 Interact with running daemon:
268
+
269
+ | Command | Description |
270
+ |---------|-------------|
271
+ | \`status\` | List active sessions |
272
+ | \`session <id>\` | Session details |
273
+ | \`new <agent> <path>\` | Create session |
274
+ | \`send <id> "text"\` | Send prompt |
275
+ | \`cancel <id>\` | Cancel session |
276
+ | \`dangerous <id> on/off\` | Toggle dangerous mode |
277
+ | \`topics [--status x,y]\` | List topics |
278
+ | \`delete-topic <id> [--force]\` | Delete topic |
279
+ | \`cleanup [--status x,y]\` | Cleanup old topics |
280
+ | \`agents\` | List agents |
281
+ | \`health\` | System health |
282
+ | \`config\` | Show config |
283
+ | \`config set <key> <value>\` | Update config |
284
+ | \`adapters\` | List adapters |
285
+ | \`tunnel\` | Tunnel status |
286
+ | \`notify "message"\` | Send notification |
287
+ | \`version\` | Daemon version |
288
+ | \`restart\` | Restart daemon |
289
+
290
+ ---
291
+
292
+ ## File Viewer (Tunnel)
293
+
294
+ When tunnel is enabled, file edits and diffs get "View" buttons that open in your browser:
295
+ - **Monaco Editor** \u2014 Full VS Code editor with syntax highlighting
296
+ - **Diff viewer** \u2014 Side-by-side or inline comparison
297
+ - **Line highlighting** \u2014 Click lines to highlight
298
+ - Dark/light theme toggle
299
+
300
+ ### Setup
301
+ Enable in config: set \`tunnel.enabled\` to \`true\`.
302
+ Providers: Cloudflare (default, free), ngrok, bore, Tailscale Funnel.
303
+
304
+ ### Port Tunneling
305
+
306
+ Expose any local port (dev servers, APIs, etc.) to the internet:
307
+
308
+ **CLI commands** (agent can call these directly):
309
+ - \`openacp tunnel add <port> --label <name>\` \u2014 Create tunnel to a local port
310
+ - \`openacp tunnel list\` \u2014 List active tunnels
311
+ - \`openacp tunnel stop <port>\` \u2014 Stop a tunnel
312
+ - \`openacp tunnel stop-all\` \u2014 Stop all user tunnels
313
+
314
+ **Telegram commands**:
315
+ - \`/tunnel <port> [label]\` \u2014 Create tunnel
316
+ - \`/tunnels\` \u2014 List active tunnels
317
+ - \`/tunnel stop <port>\` \u2014 Stop tunnel
318
+
319
+ Example: after starting a dev server on port 3000, run \`openacp tunnel add 3000 --label my-app\` to get a public URL.
320
+
321
+ ---
322
+
323
+ ## Configuration
324
+
325
+ Config file: \`~/.openacp/config.json\`
326
+
327
+ ### Channels
328
+ - **channels.telegram.botToken** \u2014 Your Telegram bot token
329
+ - **channels.telegram.chatId** \u2014 Your Telegram supergroup ID
330
+ - **channels.discord.botToken** \u2014 Your Discord bot token
331
+ - **channels.discord.guildId** \u2014 Your Discord server (guild) ID
332
+
333
+ ### Agents
334
+ - **defaultAgent** \u2014 Which agent to use by default
335
+ - Agents are managed via \`/agents\` (Telegram) or \`openacp agents\` (CLI)
336
+ - Installed agents are stored in \`~/.openacp/agents.json\`
337
+ - Agent list is fetched from the ACP Registry CDN and cached locally (24h)
338
+
339
+ ### Workspace
340
+ - **workspace.baseDir** \u2014 Base directory for project folders (default: \`~/openacp-workspace\`)
341
+
342
+ ### Security
343
+ - **security.allowedUserIds** \u2014 Restrict who can use the bot (empty = everyone)
344
+ - **security.maxConcurrentSessions** \u2014 Max parallel sessions (default: 5)
345
+ - **security.sessionTimeoutMinutes** \u2014 Auto-cancel idle sessions (default: 60)
346
+
347
+ ### Tunnel / File Viewer
348
+ - **tunnel.enabled** \u2014 Enable file viewer tunnel
349
+ - **tunnel.provider** \u2014 Tunnel provider: cloudflare (default, free), ngrok, bore, tailscale
350
+ - **tunnel.port** \u2014 Local port for tunnel server (default: 3100)
351
+ - **tunnel.auth.enabled** \u2014 Enable authentication for tunnel URLs
352
+ - **tunnel.auth.token** \u2014 Auth token for tunnel access
353
+ - **tunnel.storeTtlMinutes** \u2014 How long viewer links stay cached (default: 60)
354
+
355
+ ### Logging
356
+ - **logging.level** \u2014 Log level: silent, debug, info, warn, error, fatal (default: info)
357
+ - **logging.logDir** \u2014 Log directory (default: \`~/.openacp/logs\`)
358
+ - **logging.maxFileSize** \u2014 Max log file size before rotation
359
+ - **logging.maxFiles** \u2014 Max number of rotated log files
360
+ - **logging.sessionLogRetentionDays** \u2014 Auto-delete old session logs (default: 30)
361
+
362
+ ### Data Retention
363
+ - **sessionStore.ttlDays** \u2014 How long session records persist (default: 30). Old records are cleaned up automatically.
364
+
365
+ ### Environment variables
366
+ Override config with env vars:
367
+ - \`OPENACP_TELEGRAM_BOT_TOKEN\`
368
+ - \`OPENACP_TELEGRAM_CHAT_ID\`
369
+ - \`OPENACP_DISCORD_BOT_TOKEN\`
370
+ - \`OPENACP_DISCORD_GUILD_ID\`
371
+ - \`OPENACP_DEFAULT_AGENT\`
372
+ - \`OPENACP_RUN_MODE\` \u2014 foreground or daemon
373
+ - \`OPENACP_API_PORT\` \u2014 API server port (default: 21420)
374
+ - \`OPENACP_TUNNEL_ENABLED\`
375
+ - \`OPENACP_TUNNEL_PORT\`
376
+ - \`OPENACP_TUNNEL_PROVIDER\`
377
+ - \`OPENACP_LOG_LEVEL\`
378
+ - \`OPENACP_LOG_DIR\`
379
+ - \`OPENACP_DEBUG\` \u2014 Sets log level to debug
380
+
381
+ ---
382
+
383
+ ## Troubleshooting
384
+
385
+ ### Session stuck / not responding
386
+ - Check status: ask Assistant "Is anything stuck?"
387
+ - Cancel and create new: \`/cancel\` then \`/new\`
388
+ - Check system health: Assistant can run health check
389
+
390
+ ### Agent not found
391
+ - Check available agents: \`/agents\` or \`openacp agents\`
392
+ - Install missing agent: \`openacp agents install <name>\`
393
+ - Some agents need login first: \`openacp agents info <name>\` to see setup steps
394
+ - Run agent CLI for setup: \`openacp agents run <name> -- <args>\`
395
+
396
+ ### Permission request not showing
397
+ - Check Notifications topic for the alert
398
+ - Try \`/enable_dangerous\` to auto-approve (if you trust the agent)
399
+
400
+ ### Session disappeared after restart
401
+ - Sessions persist across restarts
402
+ - Send a message in the old topic \u2014 it auto-resumes
403
+ - If topic was deleted, the session record may still exist in status
404
+
405
+ ### Bot not responding at all
406
+ - Check daemon: \`openacp status\`
407
+ - Check logs: \`openacp logs\`
408
+ - Restart: \`openacp start\` or \`/restart\`
409
+
410
+ ### Messages going to wrong topic
411
+ - Each session is bound to a specific topic/thread
412
+ - If you see messages appearing in the Assistant topic instead of the session topic, try creating a new session
413
+
414
+ ### Viewing logs
415
+ - Session-specific logs: \`~/.openacp/logs/sessions/\`
416
+ - System logs: \`openacp logs\` to tail live
417
+ - Set \`OPENACP_DEBUG=true\` for verbose output
418
+
419
+ ---
420
+
421
+ ## Data & Storage
422
+
423
+ All data is stored in \`~/.openacp/\`:
424
+ - \`config.json\` \u2014 Configuration
425
+ - \`agents.json\` \u2014 Installed agents (managed by AgentCatalog)
426
+ - \`registry-cache.json\` \u2014 Cached ACP Registry data (refreshes every 24h)
427
+ - \`agents/\` \u2014 Downloaded binary agents
428
+ - \`sessions/\` \u2014 Session records and state
429
+ - \`topics/\` \u2014 Topic-to-session mappings
430
+ - \`logs/\` \u2014 System and session logs
431
+ - \`plugins/\` \u2014 Installed adapter plugins
432
+ - \`openacp.pid\` \u2014 Daemon PID file
433
+
434
+ Session records auto-cleanup: 30 days (configurable via \`sessionStore.ttlDays\`).
435
+ Session logs auto-cleanup: 30 days (configurable via \`logging.sessionLogRetentionDays\`).
436
+ `;
437
+
438
+ export {
439
+ ChannelAdapter,
440
+ PRODUCT_GUIDE
441
+ };
442
+ //# sourceMappingURL=chunk-LGQYTK55.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/channel.ts","../../src/product-guide.ts"],"sourcesContent":["import type { OutgoingMessage, PermissionRequest, NotificationMessage, AgentCommand } from './types.js'\n\nexport interface ChannelConfig {\n enabled: boolean\n [key: string]: unknown\n}\n\nexport interface IChannelAdapter {\n start(): Promise<void>\n stop(): Promise<void>\n\n // Outgoing: core → channel\n sendMessage(sessionId: string, content: OutgoingMessage): Promise<void>\n sendPermissionRequest(sessionId: string, request: PermissionRequest): Promise<void>\n sendNotification(notification: NotificationMessage): Promise<void>\n\n // Session lifecycle on channel side\n createSessionThread(sessionId: string, name: string): Promise<string> // returns threadId\n renameSessionThread(sessionId: string, newName: string): Promise<void>\n deleteSessionThread(sessionId: string): Promise<void>\n\n // Skill commands — optional\n sendSkillCommands(sessionId: string, commands: AgentCommand[]): Promise<void>\n cleanupSkillCommands(sessionId: string): Promise<void>\n}\n\n/**\n * Base class providing default no-op implementations for optional methods.\n * Adapters can extend this or implement IChannelAdapter directly.\n */\nexport abstract class ChannelAdapter<TCore = unknown> implements IChannelAdapter {\n constructor(protected core: TCore, protected config: ChannelConfig) {}\n\n abstract start(): Promise<void>\n abstract stop(): Promise<void>\n\n // Outgoing: core → channel\n abstract sendMessage(sessionId: string, content: OutgoingMessage): Promise<void>\n abstract sendPermissionRequest(sessionId: string, request: PermissionRequest): Promise<void>\n abstract sendNotification(notification: NotificationMessage): Promise<void>\n\n // Session lifecycle on channel side\n abstract createSessionThread(sessionId: string, name: string): Promise<string> // returns threadId\n abstract renameSessionThread(sessionId: string, newName: string): Promise<void>\n async deleteSessionThread(_sessionId: string): Promise<void> {}\n\n // Skill commands — override in adapters that support dynamic commands\n async sendSkillCommands(_sessionId: string, _commands: AgentCommand[]): Promise<void> {}\n async cleanupSkillCommands(_sessionId: string): Promise<void> {}\n\n // Archive — override in adapters that support topic archiving\n async archiveSessionTopic(_sessionId: string): Promise<{ newThreadId: string } | null> {\n return null;\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"],"mappings":";AA8BO,IAAe,iBAAf,MAA0E;AAAA,EAC/E,YAAsB,MAAuB,QAAuB;AAA9C;AAAuB;AAAA,EAAwB;AAAA,EAarE,MAAM,oBAAoB,YAAmC;AAAA,EAAC;AAAA;AAAA,EAG9D,MAAM,kBAAkB,YAAoB,WAA0C;AAAA,EAAC;AAAA,EACvF,MAAM,qBAAqB,YAAmC;AAAA,EAAC;AAAA;AAAA,EAG/D,MAAM,oBAAoB,YAA6D;AACrF,WAAO;AAAA,EACT;AACF;;;AClDO,IAAM,gBAAgB;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;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;AAAA;AAAA;AAAA;AAAA;AAAA;","names":[]}
@@ -14,6 +14,13 @@ var SYSTEMD_SERVICE_PATH = path.join(os.homedir(), ".config", "systemd", "user",
14
14
  function isAutoStartSupported() {
15
15
  return process.platform === "darwin" || process.platform === "linux";
16
16
  }
17
+ function escapeXml(str) {
18
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
19
+ }
20
+ function escapeSystemdValue(str) {
21
+ const escaped = str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\$/g, "$$$$").replace(/%/g, "%%");
22
+ return `"${escaped}"`;
23
+ }
17
24
  function generateLaunchdPlist(nodePath, cliPath, logDir) {
18
25
  const logFile = path.join(logDir, "openacp.log");
19
26
  return `<?xml version="1.0" encoding="UTF-8"?>
@@ -24,8 +31,8 @@ function generateLaunchdPlist(nodePath, cliPath, logDir) {
24
31
  <string>${LAUNCHD_LABEL}</string>
25
32
  <key>ProgramArguments</key>
26
33
  <array>
27
- <string>${nodePath}</string>
28
- <string>${cliPath}</string>
34
+ <string>${escapeXml(nodePath)}</string>
35
+ <string>${escapeXml(cliPath)}</string>
29
36
  <string>--daemon-child</string>
30
37
  </array>
31
38
  <key>RunAtLoad</key>
@@ -36,9 +43,9 @@ function generateLaunchdPlist(nodePath, cliPath, logDir) {
36
43
  <false/>
37
44
  </dict>
38
45
  <key>StandardOutPath</key>
39
- <string>${logFile}</string>
46
+ <string>${escapeXml(logFile)}</string>
40
47
  <key>StandardErrorPath</key>
41
- <string>${logFile}</string>
48
+ <string>${escapeXml(logFile)}</string>
42
49
  </dict>
43
50
  </plist>
44
51
  `;
@@ -48,7 +55,7 @@ function generateSystemdUnit(nodePath, cliPath) {
48
55
  Description=OpenACP Daemon
49
56
 
50
57
  [Service]
51
- ExecStart=${nodePath} ${cliPath} --daemon-child
58
+ ExecStart=${escapeSystemdValue(nodePath)} ${escapeSystemdValue(cliPath)} --daemon-child
52
59
  Restart=on-failure
53
60
 
54
61
  [Install]
@@ -136,10 +143,12 @@ function isAutoStartInstalled() {
136
143
 
137
144
  export {
138
145
  isAutoStartSupported,
146
+ escapeXml,
147
+ escapeSystemdValue,
139
148
  generateLaunchdPlist,
140
149
  generateSystemdUnit,
141
150
  installAutoStart,
142
151
  uninstallAutoStart,
143
152
  isAutoStartInstalled
144
153
  };
145
- //# sourceMappingURL=chunk-X6LLG7XN.js.map
154
+ //# sourceMappingURL=chunk-PMGNLNSH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/autostart.ts"],"sourcesContent":["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 './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"],"mappings":";;;;;AAAA,SAAS,oBAAoB;AAC7B,YAAY,QAAQ;AACpB,YAAY,UAAU;AACtB,YAAY,QAAQ;AAGpB,IAAM,MAAM,kBAAkB,EAAE,QAAQ,YAAY,CAAC;AAErD,IAAM,gBAAgB;AACtB,IAAM,qBAA0B,UAAQ,WAAQ,GAAG,WAAW,gBAAgB,GAAG,aAAa,QAAQ;AACtG,IAAM,uBAA4B,UAAQ,WAAQ,GAAG,WAAW,WAAW,QAAQ,iBAAiB;AAE7F,SAAS,uBAAgC;AAC9C,SAAO,QAAQ,aAAa,YAAY,QAAQ,aAAa;AAC/D;AAEO,SAAS,UAAU,KAAqB;AAC7C,SAAO,IACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,QAAQ;AAC3B;AAEO,SAAS,mBAAmB,KAAqB;AACtD,QAAM,UAAU,IACb,QAAQ,OAAO,MAAM,EACrB,QAAQ,MAAM,KAAK,EACnB,QAAQ,OAAO,MAAM,EACrB,QAAQ,MAAM,IAAI;AACrB,SAAO,IAAI,OAAO;AACpB;AAEO,SAAS,qBAAqB,UAAkB,SAAiB,QAAwB;AAC9F,QAAM,UAAe,UAAK,QAAQ,aAAa;AAC/C,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA,YAKG,aAAa;AAAA;AAAA;AAAA,cAGX,UAAU,QAAQ,CAAC;AAAA,cACnB,UAAU,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAWpB,UAAU,OAAO,CAAC;AAAA;AAAA,YAElB,UAAU,OAAO,CAAC;AAAA;AAAA;AAAA;AAI9B;AAEO,SAAS,oBAAoB,UAAkB,SAAyB;AAC7E,SAAO;AAAA;AAAA;AAAA;AAAA,YAIG,mBAAmB,QAAQ,CAAC,IAAI,mBAAmB,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAMvE;AAEO,SAAS,iBAAiB,QAAsD;AACrF,MAAI,CAAC,qBAAqB,GAAG;AAC3B,WAAO,EAAE,SAAS,OAAO,OAAO,4CAA4C;AAAA,EAC9E;AAEA,QAAM,WAAW,QAAQ;AACzB,QAAM,UAAe,aAAQ,QAAQ,KAAK,CAAC,CAAC;AAC5C,QAAM,iBAAiB,OAAO,WAAW,GAAG,IACnC,UAAQ,WAAQ,GAAG,OAAO,MAAM,CAAC,CAAC,IACvC;AAEJ,MAAI;AACF,QAAI,QAAQ,aAAa,UAAU;AACjC,YAAM,QAAQ,qBAAqB,UAAU,SAAS,cAAc;AACpE,YAAM,MAAW,aAAQ,kBAAkB;AAC3C,MAAG,aAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AACrC,MAAG,iBAAc,oBAAoB,KAAK;AAC1C,mBAAa,aAAa,CAAC,QAAQ,kBAAkB,GAAG,EAAE,OAAO,OAAO,CAAC;AACzE,UAAI,KAAK,uBAAuB;AAChC,aAAO,EAAE,SAAS,KAAK;AAAA,IACzB;AAEA,QAAI,QAAQ,aAAa,SAAS;AAChC,YAAM,OAAO,oBAAoB,UAAU,OAAO;AAClD,YAAM,MAAW,aAAQ,oBAAoB;AAC7C,MAAG,aAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AACrC,MAAG,iBAAc,sBAAsB,IAAI;AAC3C,mBAAa,aAAa,CAAC,UAAU,eAAe,GAAG,EAAE,OAAO,OAAO,CAAC;AACxE,mBAAa,aAAa,CAAC,UAAU,UAAU,SAAS,GAAG,EAAE,OAAO,OAAO,CAAC;AAC5E,UAAI,KAAK,gCAAgC;AACzC,aAAO,EAAE,SAAS,KAAK;AAAA,IACzB;AAEA,WAAO,EAAE,SAAS,OAAO,OAAO,uBAAuB;AAAA,EACzD,SAAS,GAAG;AACV,UAAM,MAAO,EAAY;AACzB,QAAI,MAAM,EAAE,KAAK,IAAI,GAAG,8BAA8B;AACtD,WAAO,EAAE,SAAS,OAAO,OAAO,IAAI;AAAA,EACtC;AACF;AAEO,SAAS,qBAA2D;AACzE,MAAI,CAAC,qBAAqB,GAAG;AAC3B,WAAO,EAAE,SAAS,OAAO,OAAO,4CAA4C;AAAA,EAC9E;AAEA,MAAI;AACF,QAAI,QAAQ,aAAa,UAAU;AACjC,UAAO,cAAW,kBAAkB,GAAG;AACrC,YAAI;AACF,uBAAa,aAAa,CAAC,UAAU,kBAAkB,GAAG,EAAE,OAAO,OAAO,CAAC;AAAA,QAC7E,QAAQ;AAAA,QAER;AACA,QAAG,cAAW,kBAAkB;AAChC,YAAI,KAAK,qBAAqB;AAAA,MAChC;AACA,aAAO,EAAE,SAAS,KAAK;AAAA,IACzB;AAEA,QAAI,QAAQ,aAAa,SAAS;AAChC,UAAO,cAAW,oBAAoB,GAAG;AACvC,YAAI;AACF,uBAAa,aAAa,CAAC,UAAU,WAAW,SAAS,GAAG,EAAE,OAAO,OAAO,CAAC;AAAA,QAC/E,QAAQ;AAAA,QAER;AACA,QAAG,cAAW,oBAAoB;AAClC,qBAAa,aAAa,CAAC,UAAU,eAAe,GAAG,EAAE,OAAO,OAAO,CAAC;AACxE,YAAI,KAAK,8BAA8B;AAAA,MACzC;AACA,aAAO,EAAE,SAAS,KAAK;AAAA,IACzB;AAEA,WAAO,EAAE,SAAS,OAAO,OAAO,uBAAuB;AAAA,EACzD,SAAS,GAAG;AACV,UAAM,MAAO,EAAY;AACzB,QAAI,MAAM,EAAE,KAAK,IAAI,GAAG,gCAAgC;AACxD,WAAO,EAAE,SAAS,OAAO,OAAO,IAAI;AAAA,EACtC;AACF;AAEO,SAAS,uBAAgC;AAC9C,MAAI,QAAQ,aAAa,UAAU;AACjC,WAAU,cAAW,kBAAkB;AAAA,EACzC;AACA,MAAI,QAAQ,aAAa,SAAS;AAChC,WAAU,cAAW,oBAAoB;AAAA,EAC3C;AACA,SAAO;AACT;","names":[]}