@openacp/cli 2026.326.4 → 2026.327.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/README.md +2 -2
  2. package/dist/{adapter-6ANPBSVU.js → adapter-LC2QSDAS.js} +4 -5
  3. package/dist/{adapter-PQGHVG4K.js → adapter-Y55NXX6I.js} +2 -2
  4. package/dist/{api-server-3PYLRBCN.js → api-server-7G3ZUZRM.js} +2 -2
  5. package/dist/{api-server-CHVSUDBX.js → api-server-CAYNPUF2.js} +2 -2
  6. package/dist/{chunk-UNJUWWQO.js → chunk-2YCW3QDV.js} +21 -14
  7. package/dist/chunk-2YCW3QDV.js.map +1 -0
  8. package/dist/{chunk-Y64XWMJ4.js → chunk-36YQ44D7.js} +2 -2
  9. package/dist/{chunk-UB2QB6DE.js → chunk-3ASUU6WW.js} +2 -2
  10. package/dist/{chunk-V5JT5TPD.js → chunk-4GMLGCF2.js} +2 -2
  11. package/dist/chunk-CDAUYTVP.js +41 -0
  12. package/dist/chunk-CDAUYTVP.js.map +1 -0
  13. package/dist/{chunk-Q6ZXJTZB.js → chunk-HUWOFP2H.js} +9 -17
  14. package/dist/chunk-HUWOFP2H.js.map +1 -0
  15. package/dist/{chunk-P4SNGQNI.js → chunk-KMMEFXIE.js} +2 -2
  16. package/dist/{chunk-RKB2ZK6S.js → chunk-LP45RCA4.js} +579 -153
  17. package/dist/chunk-LP45RCA4.js.map +1 -0
  18. package/dist/{chunk-L7YNNBI5.js → chunk-QAQDGPB4.js} +1 -75
  19. package/dist/chunk-QAQDGPB4.js.map +1 -0
  20. package/dist/{chunk-V2M243KZ.js → chunk-TRXBJEZ5.js} +55 -53
  21. package/dist/chunk-TRXBJEZ5.js.map +1 -0
  22. package/dist/{chunk-NBFIBGAT.js → chunk-UMT7RU77.js} +45 -118
  23. package/dist/chunk-UMT7RU77.js.map +1 -0
  24. package/dist/{chunk-FQEBWOZR.js → chunk-XIBG7LSL.js} +181 -128
  25. package/dist/chunk-XIBG7LSL.js.map +1 -0
  26. package/dist/cli.js +155 -49
  27. package/dist/cli.js.map +1 -1
  28. package/dist/{config-editor-HNEKXRLQ.js → config-editor-3IKBPZA7.js} +2 -2
  29. package/dist/{core-plugins-VEUNFTMB.js → core-plugins-ROU4GPLT.js} +8 -12
  30. package/dist/{dev-loader-RDC5E2CW.js → dev-loader-DRU3R7ZM.js} +7 -18
  31. package/dist/dev-loader-DRU3R7ZM.js.map +1 -0
  32. package/dist/{doctor-H72BZOPA.js → doctor-QZQAP46W.js} +2 -2
  33. package/dist/index.d.ts +128 -66
  34. package/dist/index.js +41 -20
  35. package/dist/index.js.map +1 -1
  36. package/dist/{integrate-5C6KSU6D.js → integrate-G6CVXTGT.js} +3 -4
  37. package/dist/integrate-G6CVXTGT.js.map +1 -0
  38. package/dist/{main-T5WVCCFN.js → main-UVTZ46WP.js} +39 -185
  39. package/dist/main-UVTZ46WP.js.map +1 -0
  40. package/dist/plugin-create-5HQRF2ID.js +967 -0
  41. package/dist/plugin-create-5HQRF2ID.js.map +1 -0
  42. package/dist/plugin-installer-GQ2P3Q3E.js +23 -0
  43. package/dist/plugin-installer-GQ2P3Q3E.js.map +1 -0
  44. package/dist/plugin-search-HQ4WQKOF.js +40 -0
  45. package/dist/plugin-search-HQ4WQKOF.js.map +1 -0
  46. package/dist/{post-upgrade-XLHZ6ZB7.js → post-upgrade-3ADZRMYJ.js} +2 -2
  47. package/dist/registry-client-AVGRE4CF.js +8 -0
  48. package/dist/{setup-BAI2F24H.js → setup-EYAFK2WI.js} +77 -50
  49. package/dist/setup-EYAFK2WI.js.map +1 -0
  50. package/dist/{slack-KH7E3VBS.js → slack-37ZWBDUI.js} +2 -2
  51. package/dist/{telegram-ZDC3JQF2.js → telegram-2ZCCCZIY.js} +2 -2
  52. package/dist/{tunnel-M47I7H4B.js → tunnel-45HA72MB.js} +2 -2
  53. package/dist/{tunnel-service-WADYHREX.js → tunnel-service-QJPUYEKU.js} +11 -3
  54. package/dist/tunnel-service-QJPUYEKU.js.map +1 -0
  55. package/package.json +2 -3
  56. package/dist/action-detect-QPA775HB.js +0 -16
  57. package/dist/adapter-77ZCVABT.js +0 -2394
  58. package/dist/adapter-77ZCVABT.js.map +0 -1
  59. package/dist/admin-GBPZFFAU.js +0 -23
  60. package/dist/agents-BWU4MRRD.js +0 -15
  61. package/dist/chunk-2CX4IEEC.js +0 -124
  62. package/dist/chunk-2CX4IEEC.js.map +0 -1
  63. package/dist/chunk-4KGLKKQK.js +0 -298
  64. package/dist/chunk-4KGLKKQK.js.map +0 -1
  65. package/dist/chunk-5ZOFBTOR.js +0 -553
  66. package/dist/chunk-5ZOFBTOR.js.map +0 -1
  67. package/dist/chunk-6RXVEXF3.js +0 -23
  68. package/dist/chunk-6RXVEXF3.js.map +0 -1
  69. package/dist/chunk-FQEBWOZR.js.map +0 -1
  70. package/dist/chunk-GJOY37U7.js +0 -265
  71. package/dist/chunk-GJOY37U7.js.map +0 -1
  72. package/dist/chunk-HVBNCPAY.js +0 -71
  73. package/dist/chunk-HVBNCPAY.js.map +0 -1
  74. package/dist/chunk-I3CGU5W7.js +0 -134
  75. package/dist/chunk-I3CGU5W7.js.map +0 -1
  76. package/dist/chunk-L7YNNBI5.js.map +0 -1
  77. package/dist/chunk-MTSDOSXS.js +0 -219
  78. package/dist/chunk-MTSDOSXS.js.map +0 -1
  79. package/dist/chunk-NAM4ERUW.js +0 -203
  80. package/dist/chunk-NAM4ERUW.js.map +0 -1
  81. package/dist/chunk-NBFIBGAT.js.map +0 -1
  82. package/dist/chunk-O5RG4YZY.js +0 -122
  83. package/dist/chunk-O5RG4YZY.js.map +0 -1
  84. package/dist/chunk-Q6ZXJTZB.js.map +0 -1
  85. package/dist/chunk-QSDZDHNS.js +0 -145
  86. package/dist/chunk-QSDZDHNS.js.map +0 -1
  87. package/dist/chunk-RKB2ZK6S.js.map +0 -1
  88. package/dist/chunk-UNJUWWQO.js.map +0 -1
  89. package/dist/chunk-V2M243KZ.js.map +0 -1
  90. package/dist/chunk-WAAD23KY.js +0 -222
  91. package/dist/chunk-WAAD23KY.js.map +0 -1
  92. package/dist/chunk-WVLDNYOJ.js +0 -150
  93. package/dist/chunk-WVLDNYOJ.js.map +0 -1
  94. package/dist/dev-loader-RDC5E2CW.js.map +0 -1
  95. package/dist/discord-NOJQ5PZO.js +0 -8
  96. package/dist/doctor-RF6BHMCC.js +0 -15
  97. package/dist/doctor-RF6BHMCC.js.map +0 -1
  98. package/dist/integrate-5C6KSU6D.js.map +0 -1
  99. package/dist/main-T5WVCCFN.js.map +0 -1
  100. package/dist/new-session-AVQCNXRG.js +0 -17
  101. package/dist/new-session-AVQCNXRG.js.map +0 -1
  102. package/dist/plugin-create-AQ3B22BZ.js +0 -334
  103. package/dist/plugin-create-AQ3B22BZ.js.map +0 -1
  104. package/dist/session-KZFA6Z26.js +0 -20
  105. package/dist/session-KZFA6Z26.js.map +0 -1
  106. package/dist/settings-MFYM7CZO.js +0 -14
  107. package/dist/settings-MFYM7CZO.js.map +0 -1
  108. package/dist/setup-BAI2F24H.js.map +0 -1
  109. package/dist/slack-KH7E3VBS.js.map +0 -1
  110. package/dist/telegram-ZDC3JQF2.js.map +0 -1
  111. package/dist/tunnel-M47I7H4B.js.map +0 -1
  112. package/dist/tunnel-service-WADYHREX.js.map +0 -1
  113. package/dist/usage-WYNK6ZC5.js +0 -10
  114. package/dist/usage-WYNK6ZC5.js.map +0 -1
  115. package/dist/validators-6CLEZUBD.js +0 -8
  116. package/dist/validators-6CLEZUBD.js.map +0 -1
  117. /package/dist/{action-detect-QPA775HB.js.map → adapter-LC2QSDAS.js.map} +0 -0
  118. /package/dist/{adapter-PQGHVG4K.js.map → adapter-Y55NXX6I.js.map} +0 -0
  119. /package/dist/{adapter-6ANPBSVU.js.map → api-server-7G3ZUZRM.js.map} +0 -0
  120. /package/dist/{admin-GBPZFFAU.js.map → api-server-CAYNPUF2.js.map} +0 -0
  121. /package/dist/{chunk-Y64XWMJ4.js.map → chunk-36YQ44D7.js.map} +0 -0
  122. /package/dist/{chunk-UB2QB6DE.js.map → chunk-3ASUU6WW.js.map} +0 -0
  123. /package/dist/{chunk-V5JT5TPD.js.map → chunk-4GMLGCF2.js.map} +0 -0
  124. /package/dist/{chunk-P4SNGQNI.js.map → chunk-KMMEFXIE.js.map} +0 -0
  125. /package/dist/{agents-BWU4MRRD.js.map → config-editor-3IKBPZA7.js.map} +0 -0
  126. /package/dist/{api-server-3PYLRBCN.js.map → core-plugins-ROU4GPLT.js.map} +0 -0
  127. /package/dist/{api-server-CHVSUDBX.js.map → doctor-QZQAP46W.js.map} +0 -0
  128. /package/dist/{post-upgrade-XLHZ6ZB7.js.map → post-upgrade-3ADZRMYJ.js.map} +0 -0
  129. /package/dist/{config-editor-HNEKXRLQ.js.map → registry-client-AVGRE4CF.js.map} +0 -0
  130. /package/dist/{core-plugins-VEUNFTMB.js.map → slack-37ZWBDUI.js.map} +0 -0
  131. /package/dist/{discord-NOJQ5PZO.js.map → telegram-2ZCCCZIY.js.map} +0 -0
  132. /package/dist/{doctor-H72BZOPA.js.map → tunnel-45HA72MB.js.map} +0 -0
@@ -1,334 +0,0 @@
1
- import {
2
- getCurrentVersion
3
- } from "./chunk-S64CB6J3.js";
4
- import "./chunk-VUNV25KB.js";
5
-
6
- // src/cli/commands/plugin-create.ts
7
- import * as p from "@clack/prompts";
8
- import fs from "fs";
9
- import path from "path";
10
- async function cmdPluginCreate() {
11
- p.intro("Create a new OpenACP plugin");
12
- const result = await p.group(
13
- {
14
- name: () => p.text({
15
- message: "Plugin name (e.g., @myorg/adapter-matrix)",
16
- placeholder: "@myorg/my-plugin",
17
- validate: (value) => {
18
- if (!value || !value.trim()) return "Plugin name is required";
19
- if (!/^(@[a-z0-9-]+\/)?[a-z0-9-]+$/.test(value.trim())) {
20
- return "Must be a valid npm package name (lowercase, hyphens, optional @scope/)";
21
- }
22
- return void 0;
23
- }
24
- }),
25
- description: () => p.text({
26
- message: "Description",
27
- placeholder: "A short description of your plugin"
28
- }),
29
- author: () => p.text({
30
- message: "Author",
31
- placeholder: "Your Name <email@example.com>"
32
- }),
33
- license: () => p.select({
34
- message: "License",
35
- options: [
36
- { value: "MIT", label: "MIT" },
37
- { value: "Apache-2.0", label: "Apache 2.0" },
38
- { value: "ISC", label: "ISC" },
39
- { value: "UNLICENSED", label: "Unlicensed (private)" }
40
- ]
41
- })
42
- },
43
- {
44
- onCancel: () => {
45
- p.cancel("Plugin creation cancelled.");
46
- process.exit(0);
47
- }
48
- }
49
- );
50
- const pluginName = result.name.trim();
51
- const dirName = pluginName.replace(/^@[^/]+\//, "");
52
- const targetDir = path.resolve(process.cwd(), dirName);
53
- if (fs.existsSync(targetDir)) {
54
- p.cancel(`Directory "${dirName}" already exists.`);
55
- process.exit(1);
56
- }
57
- const spinner2 = p.spinner();
58
- spinner2.start("Scaffolding plugin...");
59
- fs.mkdirSync(path.join(targetDir, "src", "__tests__"), { recursive: true });
60
- const cliVersion = getCurrentVersion();
61
- const packageJson = {
62
- name: pluginName,
63
- version: "0.1.0",
64
- description: result.description || "",
65
- type: "module",
66
- main: "dist/index.js",
67
- types: "dist/index.d.ts",
68
- scripts: {
69
- build: "tsc",
70
- dev: "tsc --watch",
71
- test: "vitest",
72
- prepublishOnly: "npm run build"
73
- },
74
- author: result.author || "",
75
- license: result.license,
76
- keywords: ["openacp", "openacp-plugin"],
77
- peerDependencies: {
78
- "@openacp/cli": `>=${cliVersion}`
79
- },
80
- devDependencies: {
81
- "@openacp/plugin-sdk": cliVersion,
82
- typescript: "^5.4.0",
83
- vitest: "^3.0.0"
84
- }
85
- };
86
- fs.writeFileSync(
87
- path.join(targetDir, "package.json"),
88
- JSON.stringify(packageJson, null, 2) + "\n"
89
- );
90
- const tsconfig = {
91
- compilerOptions: {
92
- target: "ES2022",
93
- module: "NodeNext",
94
- moduleResolution: "NodeNext",
95
- declaration: true,
96
- outDir: "dist",
97
- rootDir: "src",
98
- strict: true,
99
- esModuleInterop: true,
100
- skipLibCheck: true,
101
- forceConsistentCasingInFileNames: true
102
- },
103
- include: ["src"],
104
- exclude: ["node_modules", "dist", "src/**/__tests__"]
105
- };
106
- fs.writeFileSync(
107
- path.join(targetDir, "tsconfig.json"),
108
- JSON.stringify(tsconfig, null, 2) + "\n"
109
- );
110
- fs.writeFileSync(
111
- path.join(targetDir, ".gitignore"),
112
- ["node_modules/", "dist/", "*.tsbuildinfo", ".DS_Store", ""].join("\n")
113
- );
114
- fs.writeFileSync(
115
- path.join(targetDir, ".npmignore"),
116
- ["src/", "tsconfig.json", ".editorconfig", ".gitignore", "*.test.ts", "__tests__/", ""].join("\n")
117
- );
118
- fs.writeFileSync(
119
- path.join(targetDir, ".editorconfig"),
120
- [
121
- "root = true",
122
- "",
123
- "[*]",
124
- "indent_style = space",
125
- "indent_size = 2",
126
- "end_of_line = lf",
127
- "charset = utf-8",
128
- "trim_trailing_whitespace = true",
129
- "insert_final_newline = true",
130
- ""
131
- ].join("\n")
132
- );
133
- fs.writeFileSync(
134
- path.join(targetDir, "README.md"),
135
- [
136
- `# ${pluginName}`,
137
- "",
138
- result.description || "An OpenACP plugin.",
139
- "",
140
- "## Installation",
141
- "",
142
- "```bash",
143
- `openacp plugin add ${pluginName}`,
144
- "```",
145
- "",
146
- "## Development",
147
- "",
148
- "```bash",
149
- "npm install",
150
- "npm run build",
151
- "npm test",
152
- "",
153
- "# Live development with hot-reload:",
154
- `openacp dev .`,
155
- "```",
156
- "",
157
- "## License",
158
- "",
159
- result.license,
160
- ""
161
- ].join("\n")
162
- );
163
- const pluginVarName = dirName.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
164
- fs.writeFileSync(
165
- path.join(targetDir, "src", "index.ts"),
166
- `import type { OpenACPPlugin, PluginContext, InstallContext, MigrateContext } from '@openacp/plugin-sdk'
167
-
168
- const plugin: OpenACPPlugin = {
169
- name: '${pluginName}',
170
- version: '0.1.0',
171
- description: '${(result.description || "").replace(/'/g, "\\'")}',
172
-
173
- // Declare which permissions your plugin needs.
174
- // Available: events:read, events:emit, services:register, services:use,
175
- // middleware:register, commands:register, storage:read, storage:write, kernel:access
176
- permissions: ['events:read', 'services:register'],
177
-
178
- // Dependencies on other plugins (loaded before this one).
179
- // pluginDependencies: { '@openacp/security': '>=1.0.0' },
180
-
181
- // Optional dependencies (used if available, gracefully degrade if not).
182
- // optionalPluginDependencies: { '@openacp/usage': '>=1.0.0' },
183
-
184
- /**
185
- * Called during server startup in dependency order.
186
- * Register services, middleware, commands, and event listeners here.
187
- */
188
- async setup(ctx: PluginContext): Promise<void> {
189
- ctx.log.info('Plugin setup started')
190
-
191
- // Example: register a service
192
- // ctx.registerService('my-service', myServiceImpl)
193
-
194
- // Example: listen to events
195
- // ctx.on('session:created', (event) => { ... })
196
-
197
- // Example: register a slash command
198
- // ctx.registerCommand({
199
- // name: 'mycommand',
200
- // description: 'Does something useful',
201
- // category: 'plugin',
202
- // async handler(args) {
203
- // return { type: 'text', text: 'Hello from ${pluginName}!' }
204
- // },
205
- // })
206
-
207
- ctx.log.info('Plugin setup complete')
208
- },
209
-
210
- /**
211
- * Called during server shutdown in reverse dependency order.
212
- * Clean up resources, close connections, stop timers here.
213
- * Has a 10-second timeout.
214
- */
215
- async teardown(): Promise<void> {
216
- // Clean up resources here
217
- },
218
-
219
- /**
220
- * Called when user runs \`openacp plugin add ${pluginName}\`.
221
- * Use ctx.terminal for interactive prompts to gather configuration.
222
- */
223
- async install(ctx: InstallContext): Promise<void> {
224
- ctx.terminal.log.info('Installing ${pluginName}...')
225
-
226
- // Example: prompt for configuration
227
- // const apiKey = await ctx.terminal.text({
228
- // message: 'Enter your API key',
229
- // validate: (v) => v.length === 0 ? 'Required' : undefined,
230
- // })
231
- // await ctx.settings.set('apiKey', apiKey)
232
-
233
- ctx.terminal.log.success('Installation complete!')
234
- },
235
-
236
- /**
237
- * Called when user runs \`openacp plugin configure ${pluginName}\`.
238
- * Re-run configuration prompts to update settings.
239
- */
240
- async configure(ctx: InstallContext): Promise<void> {
241
- ctx.terminal.log.info('Configuring ${pluginName}...')
242
-
243
- // Re-run configuration prompts, pre-filling with current values
244
- // const current = await ctx.settings.getAll()
245
- // ...
246
-
247
- ctx.terminal.log.success('Configuration updated!')
248
- },
249
-
250
- /**
251
- * Called during boot when the plugin version has changed.
252
- * Migrate settings from the old format to the new format.
253
- */
254
- async migrate(ctx: MigrateContext, oldSettings: unknown, oldVersion: string): Promise<unknown> {
255
- ctx.log.info(\`Migrating from v\${oldVersion}\`)
256
- // Return the migrated settings object
257
- return oldSettings
258
- },
259
-
260
- /**
261
- * Called when user runs \`openacp plugin remove ${pluginName}\`.
262
- * Clean up any external resources. If opts.purge is true, delete all data.
263
- */
264
- async uninstall(ctx: InstallContext, opts: { purge: boolean }): Promise<void> {
265
- ctx.terminal.log.info('Uninstalling ${pluginName}...')
266
- if (opts.purge) {
267
- await ctx.settings.clear()
268
- }
269
- ctx.terminal.log.success('Uninstalled!')
270
- },
271
- }
272
-
273
- export default plugin
274
- `
275
- );
276
- fs.writeFileSync(
277
- path.join(targetDir, "src", "__tests__", "index.test.ts"),
278
- `import { describe, it, expect } from 'vitest'
279
- import { createTestContext, createTestInstallContext } from '@openacp/plugin-sdk/testing'
280
- import plugin from '../index.js'
281
-
282
- describe('${pluginName}', () => {
283
- it('has correct metadata', () => {
284
- expect(plugin.name).toBe('${pluginName}')
285
- expect(plugin.version).toBeDefined()
286
- expect(plugin.setup).toBeInstanceOf(Function)
287
- })
288
-
289
- it('sets up without errors', async () => {
290
- const ctx = createTestContext({
291
- pluginName: '${pluginName}',
292
- pluginConfig: { enabled: true },
293
- permissions: plugin.permissions,
294
- })
295
- await expect(plugin.setup(ctx)).resolves.not.toThrow()
296
- })
297
-
298
- it('tears down without errors', async () => {
299
- if (plugin.teardown) {
300
- await expect(plugin.teardown()).resolves.not.toThrow()
301
- }
302
- })
303
-
304
- it('installs without errors', async () => {
305
- if (plugin.install) {
306
- const ctx = createTestInstallContext({
307
- pluginName: '${pluginName}',
308
- terminalResponses: { password: [''], confirm: [true], select: ['apiKey'] },
309
- })
310
- await expect(plugin.install(ctx)).resolves.not.toThrow()
311
- }
312
- })
313
- })
314
- `
315
- );
316
- spinner2.stop("Plugin scaffolded!");
317
- p.note(
318
- [
319
- `cd ${dirName}`,
320
- "npm install",
321
- "npm run build",
322
- "npm test",
323
- "",
324
- "# Start development with hot-reload:",
325
- `openacp dev .`
326
- ].join("\n"),
327
- "Next steps"
328
- );
329
- p.outro(`Plugin ${pluginName} created in ./${dirName}`);
330
- }
331
- export {
332
- cmdPluginCreate
333
- };
334
- //# sourceMappingURL=plugin-create-AQ3B22BZ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/cli/commands/plugin-create.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { getCurrentVersion } from '../version.js'\n\nexport async function cmdPluginCreate(): Promise<void> {\n p.intro('Create a new OpenACP plugin')\n\n const result = await p.group(\n {\n name: () =>\n p.text({\n message: 'Plugin name (e.g., @myorg/adapter-matrix)',\n placeholder: '@myorg/my-plugin',\n validate: (value: string | undefined) => {\n if (!value || !value.trim()) return 'Plugin name is required'\n if (!/^(@[a-z0-9-]+\\/)?[a-z0-9-]+$/.test(value.trim())) {\n return 'Must be a valid npm package name (lowercase, hyphens, optional @scope/)'\n }\n return undefined\n },\n }),\n description: () =>\n p.text({\n message: 'Description',\n placeholder: 'A short description of your plugin',\n }),\n author: () =>\n p.text({\n message: 'Author',\n placeholder: 'Your Name <email@example.com>',\n }),\n license: () =>\n p.select({\n message: 'License',\n options: [\n { value: 'MIT', label: 'MIT' },\n { value: 'Apache-2.0', label: 'Apache 2.0' },\n { value: 'ISC', label: 'ISC' },\n { value: 'UNLICENSED', label: 'Unlicensed (private)' },\n ],\n }),\n },\n {\n onCancel: () => {\n p.cancel('Plugin creation cancelled.')\n process.exit(0)\n },\n },\n )\n\n const pluginName = result.name.trim()\n const dirName = pluginName.replace(/^@[^/]+\\//, '') // strip scope for directory name\n const targetDir = path.resolve(process.cwd(), dirName)\n\n if (fs.existsSync(targetDir)) {\n p.cancel(`Directory \"${dirName}\" already exists.`)\n process.exit(1)\n }\n\n const spinner = p.spinner()\n spinner.start('Scaffolding plugin...')\n\n // Create directory structure\n fs.mkdirSync(path.join(targetDir, 'src', '__tests__'), { recursive: true })\n\n // Detect CLI version for dependency pinning\n const cliVersion = getCurrentVersion()\n\n // package.json\n const packageJson = {\n name: pluginName,\n version: '0.1.0',\n description: result.description || '',\n type: 'module',\n main: 'dist/index.js',\n types: 'dist/index.d.ts',\n scripts: {\n build: 'tsc',\n dev: 'tsc --watch',\n test: 'vitest',\n prepublishOnly: 'npm run build',\n },\n author: result.author || '',\n license: result.license as string,\n keywords: ['openacp', 'openacp-plugin'],\n peerDependencies: {\n '@openacp/cli': `>=${cliVersion}`,\n },\n devDependencies: {\n '@openacp/plugin-sdk': cliVersion,\n typescript: '^5.4.0',\n vitest: '^3.0.0',\n },\n }\n fs.writeFileSync(\n path.join(targetDir, 'package.json'),\n JSON.stringify(packageJson, null, 2) + '\\n',\n )\n\n // tsconfig.json\n const tsconfig = {\n compilerOptions: {\n target: 'ES2022',\n module: 'NodeNext',\n moduleResolution: 'NodeNext',\n declaration: true,\n outDir: 'dist',\n rootDir: 'src',\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n forceConsistentCasingInFileNames: true,\n },\n include: ['src'],\n exclude: ['node_modules', 'dist', 'src/**/__tests__'],\n }\n fs.writeFileSync(\n path.join(targetDir, 'tsconfig.json'),\n JSON.stringify(tsconfig, null, 2) + '\\n',\n )\n\n // .gitignore\n fs.writeFileSync(\n path.join(targetDir, '.gitignore'),\n ['node_modules/', 'dist/', '*.tsbuildinfo', '.DS_Store', ''].join('\\n'),\n )\n\n // .npmignore\n fs.writeFileSync(\n path.join(targetDir, '.npmignore'),\n ['src/', 'tsconfig.json', '.editorconfig', '.gitignore', '*.test.ts', '__tests__/', ''].join('\\n'),\n )\n\n // .editorconfig\n fs.writeFileSync(\n path.join(targetDir, '.editorconfig'),\n [\n 'root = true',\n '',\n '[*]',\n 'indent_style = space',\n 'indent_size = 2',\n 'end_of_line = lf',\n 'charset = utf-8',\n 'trim_trailing_whitespace = true',\n 'insert_final_newline = true',\n '',\n ].join('\\n'),\n )\n\n // README.md\n fs.writeFileSync(\n path.join(targetDir, 'README.md'),\n [\n `# ${pluginName}`,\n '',\n result.description || 'An OpenACP plugin.',\n '',\n '## Installation',\n '',\n '```bash',\n `openacp plugin add ${pluginName}`,\n '```',\n '',\n '## Development',\n '',\n '```bash',\n 'npm install',\n 'npm run build',\n 'npm test',\n '',\n '# Live development with hot-reload:',\n `openacp dev .`,\n '```',\n '',\n '## License',\n '',\n result.license as string,\n '',\n ].join('\\n'),\n )\n\n // src/index.ts — full plugin template with all hooks\n const pluginVarName = dirName.replace(/-([a-z])/g, (_, c) => c.toUpperCase())\n fs.writeFileSync(\n path.join(targetDir, 'src', 'index.ts'),\n `import type { OpenACPPlugin, PluginContext, InstallContext, MigrateContext } from '@openacp/plugin-sdk'\n\nconst plugin: OpenACPPlugin = {\n name: '${pluginName}',\n version: '0.1.0',\n description: '${(result.description || '').replace(/'/g, \"\\\\'\")}',\n\n // Declare which permissions your plugin needs.\n // Available: events:read, events:emit, services:register, services:use,\n // middleware:register, commands:register, storage:read, storage:write, kernel:access\n permissions: ['events:read', 'services:register'],\n\n // Dependencies on other plugins (loaded before this one).\n // pluginDependencies: { '@openacp/security': '>=1.0.0' },\n\n // Optional dependencies (used if available, gracefully degrade if not).\n // optionalPluginDependencies: { '@openacp/usage': '>=1.0.0' },\n\n /**\n * Called during server startup in dependency order.\n * Register services, middleware, commands, and event listeners here.\n */\n async setup(ctx: PluginContext): Promise<void> {\n ctx.log.info('Plugin setup started')\n\n // Example: register a service\n // ctx.registerService('my-service', myServiceImpl)\n\n // Example: listen to events\n // ctx.on('session:created', (event) => { ... })\n\n // Example: register a slash command\n // ctx.registerCommand({\n // name: 'mycommand',\n // description: 'Does something useful',\n // category: 'plugin',\n // async handler(args) {\n // return { type: 'text', text: 'Hello from ${pluginName}!' }\n // },\n // })\n\n ctx.log.info('Plugin setup complete')\n },\n\n /**\n * Called during server shutdown in reverse dependency order.\n * Clean up resources, close connections, stop timers here.\n * Has a 10-second timeout.\n */\n async teardown(): Promise<void> {\n // Clean up resources here\n },\n\n /**\n * Called when user runs \\`openacp plugin add ${pluginName}\\`.\n * Use ctx.terminal for interactive prompts to gather configuration.\n */\n async install(ctx: InstallContext): Promise<void> {\n ctx.terminal.log.info('Installing ${pluginName}...')\n\n // Example: prompt for configuration\n // const apiKey = await ctx.terminal.text({\n // message: 'Enter your API key',\n // validate: (v) => v.length === 0 ? 'Required' : undefined,\n // })\n // await ctx.settings.set('apiKey', apiKey)\n\n ctx.terminal.log.success('Installation complete!')\n },\n\n /**\n * Called when user runs \\`openacp plugin configure ${pluginName}\\`.\n * Re-run configuration prompts to update settings.\n */\n async configure(ctx: InstallContext): Promise<void> {\n ctx.terminal.log.info('Configuring ${pluginName}...')\n\n // Re-run configuration prompts, pre-filling with current values\n // const current = await ctx.settings.getAll()\n // ...\n\n ctx.terminal.log.success('Configuration updated!')\n },\n\n /**\n * Called during boot when the plugin version has changed.\n * Migrate settings from the old format to the new format.\n */\n async migrate(ctx: MigrateContext, oldSettings: unknown, oldVersion: string): Promise<unknown> {\n ctx.log.info(\\`Migrating from v\\${oldVersion}\\`)\n // Return the migrated settings object\n return oldSettings\n },\n\n /**\n * Called when user runs \\`openacp plugin remove ${pluginName}\\`.\n * Clean up any external resources. If opts.purge is true, delete all data.\n */\n async uninstall(ctx: InstallContext, opts: { purge: boolean }): Promise<void> {\n ctx.terminal.log.info('Uninstalling ${pluginName}...')\n if (opts.purge) {\n await ctx.settings.clear()\n }\n ctx.terminal.log.success('Uninstalled!')\n },\n}\n\nexport default plugin\n`,\n )\n\n // src/__tests__/index.test.ts\n fs.writeFileSync(\n path.join(targetDir, 'src', '__tests__', 'index.test.ts'),\n `import { describe, it, expect } from 'vitest'\nimport { createTestContext, createTestInstallContext } from '@openacp/plugin-sdk/testing'\nimport plugin from '../index.js'\n\ndescribe('${pluginName}', () => {\n it('has correct metadata', () => {\n expect(plugin.name).toBe('${pluginName}')\n expect(plugin.version).toBeDefined()\n expect(plugin.setup).toBeInstanceOf(Function)\n })\n\n it('sets up without errors', async () => {\n const ctx = createTestContext({\n pluginName: '${pluginName}',\n pluginConfig: { enabled: true },\n permissions: plugin.permissions,\n })\n await expect(plugin.setup(ctx)).resolves.not.toThrow()\n })\n\n it('tears down without errors', async () => {\n if (plugin.teardown) {\n await expect(plugin.teardown()).resolves.not.toThrow()\n }\n })\n\n it('installs without errors', async () => {\n if (plugin.install) {\n const ctx = createTestInstallContext({\n pluginName: '${pluginName}',\n terminalResponses: { password: [''], confirm: [true], select: ['apiKey'] },\n })\n await expect(plugin.install(ctx)).resolves.not.toThrow()\n }\n })\n})\n`,\n )\n\n spinner.stop('Plugin scaffolded!')\n\n p.note(\n [\n `cd ${dirName}`,\n 'npm install',\n 'npm run build',\n 'npm test',\n '',\n '# Start development with hot-reload:',\n `openacp dev .`,\n ].join('\\n'),\n 'Next steps',\n )\n\n p.outro(`Plugin ${pluginName} created in ./${dirName}`)\n}\n"],"mappings":"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","names":["spinner"]}
@@ -1,20 +0,0 @@
1
- import {
2
- executeCancelSession,
3
- handleCancel,
4
- handleCleanupButton,
5
- handleHandoff,
6
- handleSessions,
7
- handleStatus
8
- } from "./chunk-GJOY37U7.js";
9
- import "./chunk-O5RG4YZY.js";
10
- import "./chunk-XMMAGAT4.js";
11
- import "./chunk-VUNV25KB.js";
12
- export {
13
- executeCancelSession,
14
- handleCancel,
15
- handleCleanupButton,
16
- handleHandoff,
17
- handleSessions,
18
- handleStatus
19
- };
20
- //# sourceMappingURL=session-KZFA6Z26.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,14 +0,0 @@
1
- import {
2
- handleSettings,
3
- handleSettingsButton,
4
- showSettingsInfo
5
- } from "./chunk-4KGLKKQK.js";
6
- import "./chunk-ODUM3D6X.js";
7
- import "./chunk-XMMAGAT4.js";
8
- import "./chunk-VUNV25KB.js";
9
- export {
10
- handleSettings,
11
- handleSettingsButton,
12
- showSettingsInfo
13
- };
14
- //# sourceMappingURL=settings-MFYM7CZO.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/core/setup/wizard.ts","../../src/core/setup/types.ts","../../src/core/setup/helpers.ts","../../src/core/setup/setup-agents.ts","../../src/core/setup/setup-workspace.ts","../../src/core/setup/setup-run-mode.ts","../../src/core/setup/setup-integrations.ts","../../src/core/setup/setup-channels.ts"],"sourcesContent":["import * as clack from \"@clack/prompts\";\nimport type { Config, ConfigManager } from \"../config/config.js\";\nimport type { OnboardSection } from \"./types.js\";\nimport { ONBOARD_SECTION_OPTIONS } from \"./types.js\";\nimport { guardCancel, ok, fail, printStartBanner, summarizeConfig } from \"./helpers.js\";\nimport { setupAgents } from \"./setup-agents.js\";\nimport { setupWorkspace } from \"./setup-workspace.js\";\nimport { setupRunMode } from \"./setup-run-mode.js\";\nimport { setupIntegrations } from \"./setup-integrations.js\";\nimport { configureChannels } from \"./setup-channels.js\";\nimport type { SettingsManager } from \"../plugin/settings-manager.js\";\nimport type { PluginRegistry } from \"../plugin/plugin-registry.js\";\n\n// ─── First-run setup ───\n\nexport async function runSetup(\n configManager: ConfigManager,\n opts?: { skipRunMode?: boolean; settingsManager?: SettingsManager; pluginRegistry?: PluginRegistry },\n): Promise<boolean> {\n await printStartBanner();\n clack.intro(\"Let's set up OpenACP\");\n\n const { settingsManager, pluginRegistry } = opts ?? {};\n\n try {\n const channelChoice = guardCancel(\n await clack.select({\n message: 'Which messaging platform do you want to use?',\n options: [\n { label: 'Telegram', value: 'telegram' },\n { label: 'Discord', value: 'discord' },\n { label: 'Both', value: 'both' },\n ],\n }),\n );\n\n // Calculate total steps dynamically: channel(s) + workspace + run mode\n const channelSteps = channelChoice === 'both' ? 2 : 1;\n const runModeSteps = opts?.skipRunMode ? 0 : 1;\n const totalSteps = channelSteps + 1 + runModeSteps; // + workspace + optional run mode\n\n let currentStep = 0;\n\n if (channelChoice === 'telegram' || channelChoice === 'both') {\n currentStep++;\n if (settingsManager && pluginRegistry) {\n // Delegate to Telegram plugin's install() via InstallContext\n const { createInstallContext } = await import('../plugin/install-context.js');\n const telegramPlugin = (await import('../../plugins/telegram/index.js')).default;\n const ctx = createInstallContext({\n pluginName: telegramPlugin.name,\n settingsManager,\n basePath: settingsManager.getBasePath(),\n });\n await telegramPlugin.install!(ctx);\n pluginRegistry.register(telegramPlugin.name, {\n version: telegramPlugin.version,\n source: 'builtin',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(telegramPlugin.name),\n description: telegramPlugin.description,\n });\n } else {\n // Plugin system not available — inform user\n console.log(fail('Plugin system not initialized. Cannot set up Telegram.'));\n return false;\n }\n }\n if (channelChoice === 'discord' || channelChoice === 'both') {\n currentStep++;\n if (settingsManager && pluginRegistry) {\n // Delegate to Discord plugin's install() via InstallContext\n const { createInstallContext } = await import('../plugin/install-context.js');\n const discordPlugin = (await import('../../plugins/discord/index.js')).default;\n const ctx = createInstallContext({\n pluginName: discordPlugin.name,\n settingsManager,\n basePath: settingsManager.getBasePath(),\n });\n await discordPlugin.install!(ctx);\n pluginRegistry.register(discordPlugin.name, {\n version: discordPlugin.version,\n source: 'builtin',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(discordPlugin.name),\n description: discordPlugin.description,\n });\n } else {\n // Plugin system not available — inform user\n console.log(fail('Plugin system not initialized. Cannot set up Discord.'));\n return false;\n }\n }\n\n const { defaultAgent } = await setupAgents();\n\n // Offer Claude CLI integration\n await setupIntegrations();\n\n currentStep++;\n const workspace = await setupWorkspace({ stepNum: currentStep, totalSteps });\n\n let runMode: 'foreground' | 'daemon' = 'foreground';\n let autoStart = false;\n if (!opts?.skipRunMode) {\n currentStep++;\n const result = await setupRunMode({ stepNum: currentStep, totalSteps });\n runMode = result.runMode;\n autoStart = result.autoStart;\n }\n\n const security = {\n allowedUserIds: [] as string[],\n maxConcurrentSessions: 20,\n sessionTimeoutMinutes: 60,\n };\n\n const config: Config = {\n channels: {},\n agents: {},\n defaultAgent,\n workspace,\n security,\n logging: {\n level: \"info\",\n logDir: \"~/.openacp/logs\",\n maxFileSize: \"10m\",\n maxFiles: 7,\n sessionLogRetentionDays: 30,\n },\n runMode,\n autoStart,\n api: {\n port: 21420,\n host: '127.0.0.1',\n },\n sessionStore: { ttlDays: 30 },\n tunnel: {\n enabled: true,\n port: 3100,\n provider: \"cloudflare\",\n options: {},\n maxUserTunnels: 5,\n storeTtlMinutes: 60,\n auth: { enabled: false },\n },\n usage: {\n enabled: true,\n warningThreshold: 0.8,\n currency: \"USD\",\n retentionDays: 90,\n },\n integrations: {},\n speech: {\n stt: { provider: null, providers: {} },\n tts: { provider: null, providers: {} },\n },\n };\n\n try {\n await configManager.writeNew(config);\n } catch (writeErr) {\n console.log(\n fail(`Could not save config: ${(writeErr as Error).message}`),\n );\n return false;\n }\n\n // Auto-register remaining built-in plugins in the registry\n if (settingsManager && pluginRegistry) {\n await registerBuiltinPlugins(settingsManager, pluginRegistry);\n await pluginRegistry.save();\n }\n\n clack.outro(`Config saved to ${configManager.getConfigPath()}`);\n\n if (!opts?.skipRunMode) {\n console.log(ok(\"Starting OpenACP...\"));\n console.log(\"\");\n }\n\n return true;\n } catch (err) {\n if ((err as Error).name === \"ExitPromptError\") {\n clack.cancel(\"Setup cancelled.\");\n return false;\n }\n throw err;\n }\n}\n\n/**\n * Register all built-in plugins that haven't been registered yet.\n * Called after first-run setup to populate the registry with defaults.\n */\nasync function registerBuiltinPlugins(\n settingsManager: SettingsManager,\n pluginRegistry: PluginRegistry,\n): Promise<void> {\n const builtinPlugins = [\n { name: '@openacp/security', version: '1.0.0', description: 'User access control and session limits' },\n { name: '@openacp/file-service', version: '1.0.0', description: 'File storage and management' },\n { name: '@openacp/context', version: '1.0.0', description: 'Conversation context management' },\n { name: '@openacp/usage', version: '1.0.0', description: 'Token usage tracking and budget enforcement' },\n { name: '@openacp/speech', version: '1.0.0', description: 'Text-to-speech and speech-to-text' },\n { name: '@openacp/notifications', version: '1.0.0', description: 'Cross-session notification routing' },\n { name: '@openacp/tunnel', version: '1.0.0', description: 'Expose local services via tunnel' },\n { name: '@openacp/api-server', version: '1.0.0', description: 'REST API + SSE streaming server' },\n ];\n\n for (const p of builtinPlugins) {\n if (!pluginRegistry.get(p.name)) {\n pluginRegistry.register(p.name, {\n version: p.version,\n source: 'builtin',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(p.name),\n description: p.description,\n });\n }\n }\n}\n\n// ─── Reconfigure (section-based, for existing config) ───\n\ntype ReconfigureSection = OnboardSection | \"__continue\";\n\nasync function selectSection(hasSelection: boolean): Promise<ReconfigureSection> {\n return guardCancel(\n await clack.select({\n message: \"Select sections to configure\",\n options: [\n ...ONBOARD_SECTION_OPTIONS,\n {\n value: \"__continue\" as const,\n label: \"Continue\",\n hint: hasSelection ? \"Done\" : \"Skip for now\",\n },\n ],\n initialValue: ONBOARD_SECTION_OPTIONS[0].value,\n }),\n ) as ReconfigureSection;\n}\n\nexport async function runReconfigure(configManager: ConfigManager): Promise<void> {\n await printStartBanner();\n clack.intro(\"OpenACP — Reconfigure\");\n\n try {\n await configManager.load();\n let config = configManager.get();\n\n // Show current config summary\n clack.note(summarizeConfig(config), \"Current configuration\");\n\n let ranSection = false;\n\n while (true) {\n const choice = await selectSection(ranSection);\n if (choice === \"__continue\") break;\n ranSection = true;\n\n if (choice === \"channels\") {\n const result = await configureChannels(config);\n if (result.changed) {\n // IMPORTANT: Use writeNew() instead of save() because save() uses deepMerge\n // which cannot delete keys. Channel deletion (delete next.channels.telegram)\n // would be silently ignored by deepMerge. writeNew() overwrites the full config.\n config = { ...config, channels: result.config.channels };\n await configManager.writeNew(config);\n }\n }\n\n if (choice === \"agents\") {\n const { defaultAgent } = await setupAgents();\n await configManager.save({ defaultAgent });\n config = configManager.get();\n }\n\n if (choice === \"workspace\") {\n const { baseDir } = await setupWorkspace({\n existing: config.workspace.baseDir,\n });\n await configManager.save({ workspace: { baseDir } });\n config = configManager.get();\n }\n\n if (choice === \"runMode\") {\n const result = await setupRunMode({\n existing: { runMode: config.runMode, autoStart: config.autoStart },\n });\n await configManager.save({\n runMode: result.runMode,\n autoStart: result.autoStart,\n });\n config = configManager.get();\n }\n\n if (choice === \"integrations\") {\n await setupIntegrations(config);\n }\n }\n\n if (!ranSection) {\n clack.outro(\"No changes made.\");\n return;\n }\n\n clack.outro(`Config saved to ${configManager.getConfigPath()}`);\n } catch (err) {\n if ((err as Error).name === \"ExitPromptError\") {\n clack.cancel(\"Setup cancelled.\");\n return;\n }\n throw err;\n }\n}\n","export type OnboardSection =\n | \"channels\"\n | \"agents\"\n | \"workspace\"\n | \"runMode\"\n | \"integrations\";\n\nexport type ConfiguredChannelAction = \"modify\" | \"disable\" | \"delete\" | \"skip\";\n\nexport type ChannelId = \"telegram\" | \"discord\";\n\nexport type ChannelStatus = {\n id: ChannelId;\n label: string;\n configured: boolean;\n enabled: boolean;\n hint?: string;\n};\n\nexport const ONBOARD_SECTION_OPTIONS: Array<{\n value: OnboardSection;\n label: string;\n hint: string;\n}> = [\n { value: \"channels\", label: \"Channels\", hint: \"Link/update messaging platforms\" },\n { value: \"agents\", label: \"Agents\", hint: \"Install agents, change default\" },\n { value: \"workspace\", label: \"Workspace\", hint: \"Set workspace directory\" },\n { value: \"runMode\", label: \"Run mode\", hint: \"Foreground/daemon, auto-start\" },\n { value: \"integrations\", label: \"Integrations\", hint: \"Claude CLI session transfer\" },\n];\n\nexport const CHANNEL_META: Record<ChannelId, { label: string; method: string }> = {\n telegram: { label: \"Telegram\", method: \"Bot API\" },\n discord: { label: \"Discord\", method: \"Bot API\" },\n};\n\n","import * as clack from \"@clack/prompts\";\nimport type { Config } from \"../config/config.js\";\n\n// --- ANSI colors ---\n\nexport const c = {\n reset: \"\\x1b[0m\",\n bold: \"\\x1b[1m\",\n dim: \"\\x1b[2m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n red: \"\\x1b[31m\",\n cyan: \"\\x1b[36m\",\n white: \"\\x1b[37m\",\n};\n\nexport const ok = (msg: string) =>\n `${c.green}${c.bold}✓${c.reset} ${c.green}${msg}${c.reset}`;\nexport const warn = (msg: string) => `${c.yellow}⚠ ${msg}${c.reset}`;\nexport const fail = (msg: string) => `${c.red}✗ ${msg}${c.reset}`;\nexport const step = (n: number, total: number, title: string) =>\n `\\n${c.cyan}${c.bold}[${n}/${total}]${c.reset} ${c.bold}${title}${c.reset}\\n`;\nexport const dim = (msg: string) => `${c.dim}${msg}${c.reset}`;\n\nexport function guardCancel<T>(value: T | symbol): T {\n if (clack.isCancel(value)) {\n clack.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n return value as T;\n}\n\n// --- Banner ---\n\nfunction applyGradient(text: string): string {\n const colors = [135, 99, 63, 33, 39, 44, 44];\n const lines = text.split(\"\\n\");\n return lines\n .map((line, i) => {\n const colorIdx = Math.min(i, colors.length - 1);\n return `\\x1b[38;5;${colors[colorIdx]}m${line}\\x1b[0m`;\n })\n .join(\"\\n\");\n}\n\nconst BANNER = `\n ██████╗ ██████╗ ███████╗███╗ ██╗ █████╗ ██████╗██████╗\n ██╔═══██╗██╔══██╗██╔════╝████╗ ██║██╔══██╗██╔════╝██╔══██╗\n ██║ ██║██████╔╝█████╗ ██╔██╗ ██║███████║██║ ██████╔╝\n ██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║██╔══██║██║ ██╔═══╝\n ╚██████╔╝██║ ███████╗██║ ╚████║██║ ██║╚██████╗██║\n ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═════╝╚═╝\n`;\n\nexport async function printStartBanner(): Promise<void> {\n let version = \"0.0.0\";\n try {\n const { getCurrentVersion } = await import(\"../../cli/version.js\");\n version = getCurrentVersion();\n } catch {\n // ignore\n }\n console.log(applyGradient(BANNER));\n console.log(`${c.dim} AI coding agents, anywhere. v${version}${c.reset}\\n`);\n}\n\n// --- Config summary ---\n\nexport function summarizeConfig(config: Config): string {\n const lines: string[] = [];\n\n // Channels\n const channelStatuses: string[] = [];\n for (const [id, meta] of Object.entries({\n telegram: \"Telegram\",\n discord: \"Discord\",\n })) {\n const ch = config.channels[id] as { enabled?: boolean } | undefined;\n if (ch?.enabled) {\n channelStatuses.push(`${meta} (enabled)`);\n } else if (ch && Object.keys(ch).length > 1) {\n channelStatuses.push(`${meta} (disabled)`);\n } else {\n channelStatuses.push(`${meta} (not configured)`);\n }\n }\n lines.push(`Channels: ${channelStatuses.join(\", \")}`);\n\n // Default agent\n lines.push(`Default agent: ${config.defaultAgent}`);\n\n // Workspace\n lines.push(`Workspace: ${config.workspace.baseDir}`);\n\n // Run mode\n lines.push(`Run mode: ${config.runMode}${config.autoStart ? \" (auto-start)\" : \"\"}`);\n\n return lines.join(\"\\n\");\n}\n","import { execFileSync } from \"node:child_process\";\nimport * as clack from \"@clack/prompts\";\nimport { commandExists } from \"../agents/agent-dependencies.js\";\nimport { guardCancel, ok, warn, c } from \"./helpers.js\";\n\nconst KNOWN_AGENTS: Array<{ name: string; commands: string[] }> = [\n // claude-agent-acp is bundled as a dependency — no detection needed, but\n // kept here so detectAgents() still returns it for display purposes.\n { name: \"claude\", commands: [\"claude-agent-acp\"] },\n { name: \"codex\", commands: [\"codex\"] },\n];\n\nexport async function detectAgents(): Promise<\n Array<{ name: string; command: string }>\n> {\n const found: Array<{ name: string; command: string }> = [];\n for (const agent of KNOWN_AGENTS) {\n // Find all available commands for this agent (PATH + node_modules/.bin)\n const available: string[] = [];\n for (const cmd of agent.commands) {\n if (commandExists(cmd)) {\n available.push(cmd);\n }\n }\n if (available.length > 0) {\n // Prefer claude-agent-acp over claude/claude-code (priority order)\n found.push({ name: agent.name, command: available[0] });\n }\n }\n return found;\n}\n\nexport async function validateAgentCommand(command: string): Promise<boolean> {\n try {\n execFileSync(\"which\", [command], { stdio: \"pipe\" });\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function setupAgents(): Promise<{\n defaultAgent: string;\n}> {\n const { AgentCatalog } = await import(\"../agents/agent-catalog.js\");\n const { muteLogger, unmuteLogger } = await import(\"../utils/log.js\");\n\n muteLogger();\n const catalog = new AgentCatalog();\n catalog.load();\n\n const s = clack.spinner();\n s.start(\"Checking available agents...\");\n await catalog.refreshRegistryIfStale();\n\n // Claude is always pre-installed (bundled dependency)\n if (!catalog.getInstalledAgent(\"claude\")) {\n const claudeRegistry = catalog.findRegistryAgent(\"claude-acp\");\n if (claudeRegistry) {\n await catalog.install(\"claude-acp\");\n } else {\n // Fallback: register bundled claude-agent-acp directly\n const { AgentStore } = await import(\"../agents/agent-store.js\");\n const store = new AgentStore();\n store.load();\n store.addAgent(\"claude\", {\n registryId: \"claude-acp\",\n name: \"Claude Agent\",\n version: \"bundled\",\n distribution: \"npx\",\n command: \"npx\",\n args: [\"@zed-industries/claude-agent-acp\"],\n env: {},\n installedAt: new Date().toISOString(),\n binaryPath: null,\n });\n }\n }\n s.stop(ok(\"Claude Agent ready\"));\n unmuteLogger();\n\n const available = catalog.getAvailable();\n const installed = available.filter((a) => a.installed);\n const installable = available.filter((a) => !a.installed && a.available);\n\n // Offer agent selection — show installed agents as pre-checked + installable agents\n if (installed.length > 0 || installable.length > 0) {\n // Deduplicate by key AND name\n const seen = new Set<string>();\n const options: Array<{ label: string; value: string }> = [];\n\n for (const a of installed) {\n const dedupeKey = `${a.key}::${a.name}`;\n if (seen.has(dedupeKey)) continue;\n seen.add(dedupeKey);\n options.push({\n label: `${a.name} (installed)`,\n value: a.key,\n });\n }\n for (const a of installable) {\n const dedupeKey = `${a.key}::${a.name}`;\n if (seen.has(dedupeKey)) continue;\n seen.add(dedupeKey);\n options.push({\n label: `${a.name} (${a.distribution})`,\n value: a.key,\n });\n }\n\n const installedKeys = installed.map(a => a.key);\n const selected = guardCancel(\n await clack.autocompleteMultiselect({\n message: \"Install additional agents? (type to search, Space to select)\",\n options,\n initialValues: installedKeys,\n required: false,\n }),\n ) as string[];\n\n for (const key of selected) {\n const regAgent = catalog.findRegistryAgent(key);\n if (regAgent) {\n const installSpinner = clack.spinner();\n installSpinner.start(`Installing ${regAgent.name}...`);\n muteLogger();\n const result = await catalog.install(key);\n unmuteLogger();\n if (result.ok) {\n installSpinner.stop(ok(\"done\"));\n } else {\n installSpinner.stop(warn(`skipped: ${result.error}`));\n }\n }\n }\n }\n\n // Choose default agent\n const installedAgents = Object.keys(catalog.getInstalledEntries());\n let defaultAgent = \"claude\";\n\n if (installedAgents.length > 1) {\n defaultAgent = guardCancel(\n await clack.select({\n message: \"Which agent should be the default?\",\n options: installedAgents.map((key) => {\n const agent = catalog.getInstalledAgent(key)!;\n return { label: `${agent.name} (${key})`, value: key };\n }),\n initialValue: \"claude\",\n }),\n ) as string;\n }\n\n console.log(ok(`Default agent: ${c.bold}${defaultAgent}${c.reset}`));\n return { defaultAgent };\n}\n","import * as clack from \"@clack/prompts\";\nimport { guardCancel, step } from \"./helpers.js\";\n\nexport async function setupWorkspace(opts?: {\n existing?: string;\n stepNum?: number;\n totalSteps?: number;\n}): Promise<{ baseDir: string }> {\n const { existing, stepNum, totalSteps } = opts ?? {};\n if (stepNum != null && totalSteps != null) {\n console.log(step(stepNum, totalSteps, \"Workspace\"));\n }\n\n const baseDir = guardCancel(\n await clack.text({\n message: \"Base directory for workspaces:\",\n initialValue: existing ?? \"~/openacp-workspace\",\n validate: (val) =>\n (val ?? \"\").toString().trim().length > 0 ? undefined : \"Path cannot be empty\",\n }),\n ) as string;\n\n return { baseDir: baseDir.trim().replace(/^['\"]|['\"]$/g, \"\") };\n}\n","import * as clack from \"@clack/prompts\";\nimport { expandHome } from \"../config/config.js\";\nimport { guardCancel, ok, warn, dim, step } from \"./helpers.js\";\n\nexport async function setupRunMode(opts?: {\n existing?: { runMode: string; autoStart: boolean };\n stepNum?: number;\n totalSteps?: number;\n}): Promise<{ runMode: 'foreground' | 'daemon'; autoStart: boolean }> {\n const { existing, stepNum, totalSteps } = opts ?? {};\n if (stepNum != null && totalSteps != null) {\n console.log(step(stepNum, totalSteps, 'Run Mode'));\n }\n\n // Don't show daemon option on Windows\n if (process.platform === 'win32') {\n console.log(dim(' (Daemon mode not available on Windows)'));\n return { runMode: 'foreground', autoStart: false };\n }\n\n const initialValue = (existing?.runMode === 'daemon' ? 'daemon' : 'foreground') as 'foreground' | 'daemon';\n\n const mode = guardCancel(\n await clack.select({\n message: 'How would you like to run OpenACP?',\n options: [\n {\n label: 'Background (daemon)',\n value: 'daemon' as const,\n hint: 'Runs silently, auto-starts on boot. Manage with: openacp status | stop | logs',\n },\n {\n label: 'Foreground (terminal)',\n value: 'foreground' as const,\n hint: 'Runs in current terminal session. Start with: openacp',\n },\n ],\n initialValue,\n }),\n );\n\n const wasDaemon = existing?.runMode === 'daemon';\n\n if (mode === 'daemon') {\n const { installAutoStart, isAutoStartSupported } = await import('../../cli/autostart.js');\n const { muteLogger, unmuteLogger } = await import('../utils/log.js');\n const autoStart = isAutoStartSupported();\n if (autoStart) {\n muteLogger();\n const result = installAutoStart(expandHome('~/.openacp/logs'));\n unmuteLogger();\n if (result.success) {\n console.log(ok('Auto-start on boot enabled'));\n } else {\n console.log(warn(`Auto-start failed: ${result.error}`));\n }\n }\n return { runMode: 'daemon', autoStart };\n }\n\n // Switching from daemon → foreground: stop daemon + uninstall autostart\n if (wasDaemon) {\n const { muteLogger, unmuteLogger } = await import('../utils/log.js');\n muteLogger();\n try {\n const { stopDaemon } = await import('../../cli/daemon.js');\n const result = await stopDaemon();\n unmuteLogger();\n if (result.stopped) {\n console.log(ok(`Daemon stopped (was PID ${result.pid})`));\n }\n } catch {\n unmuteLogger();\n // Daemon may not be running\n }\n muteLogger();\n try {\n const { uninstallAutoStart } = await import('../../cli/autostart.js');\n uninstallAutoStart();\n unmuteLogger();\n } catch {\n unmuteLogger();\n // ignore\n }\n }\n\n return { runMode: 'foreground', autoStart: false };\n}\n","import * as clack from \"@clack/prompts\";\nimport type { Config } from \"../config/config.js\";\nimport { guardCancel } from \"./helpers.js\";\n\nexport async function setupIntegrations(config?: Config): Promise<void> {\n const claudeIntegration = (config?.integrations as Record<string, unknown> | undefined)?.claude as { installed?: boolean } | undefined;\n const isInstalled = claudeIntegration?.installed === true;\n\n const installClaude = guardCancel(\n await clack.confirm({\n message: isInstalled\n ? \"Claude CLI integration is installed. Reinstall?\"\n : \"Install session transfer for Claude? (enables /openacp:handoff in your terminal)\",\n initialValue: !isInstalled,\n }),\n );\n\n if (installClaude) {\n try {\n const { getIntegration } = await import(\"../../cli/integrate.js\");\n const integration = getIntegration(\"claude\");\n if (integration) {\n for (const item of integration.items) {\n const result = await item.install();\n for (const log of result.logs) console.log(` ${log}`);\n }\n }\n console.log(\"Claude CLI integration installed.\\n\");\n } catch (err) {\n console.log(`Could not install Claude CLI integration: ${err instanceof Error ? err.message : err}`);\n console.log(\" You can install it later with: openacp integrate claude\\n\");\n }\n }\n}\n","import * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport * as clack from \"@clack/prompts\";\nimport type { Config } from \"../config/config.js\";\nimport type { ConfiguredChannelAction, ChannelId, ChannelStatus } from \"./types.js\";\nimport { CHANNEL_META } from \"./types.js\";\nimport { guardCancel, ok, c } from \"./helpers.js\";\n\nexport function getChannelStatuses(config: Config): ChannelStatus[] {\n const statuses: ChannelStatus[] = [];\n\n for (const [id, meta] of Object.entries(CHANNEL_META) as [ChannelId, typeof CHANNEL_META[ChannelId]][]) {\n const ch = config.channels[id] as Record<string, unknown> | undefined;\n const enabled = ch?.enabled === true;\n const configured = !!ch && Object.keys(ch).length > 1;\n\n let hint: string | undefined;\n if (id === \"telegram\" && ch?.botToken && typeof ch.botToken === \"string\" && ch.botToken !== \"YOUR_BOT_TOKEN_HERE\") {\n hint = `Chat ID: ${ch.chatId}`;\n }\n if (id === \"discord\" && ch?.guildId) {\n hint = `Guild: ${ch.guildId}`;\n }\n\n statuses.push({ id, label: meta.label, configured, enabled, hint });\n }\n\n return statuses;\n}\n\nexport function noteChannelStatus(config: Config): void {\n const statuses = getChannelStatuses(config);\n const lines = statuses.map((s) => {\n const status = s.enabled ? \"enabled\" : s.configured ? \"disabled\" : \"not configured\";\n const hintStr = s.hint ? ` — ${s.hint}` : \"\";\n return ` ${s.label}: ${status}${hintStr}`;\n });\n\n console.log(\"\");\n console.log(`${c.bold} Channel status${c.reset}`);\n for (const line of lines) console.log(line);\n console.log(\"\");\n}\n\nasync function promptConfiguredAction(label: string): Promise<ConfiguredChannelAction> {\n return guardCancel(\n await clack.select({\n message: `${label} already configured. What do you want to do?`,\n options: [\n { value: \"modify\" as const, label: \"Modify settings\" },\n { value: \"disable\" as const, label: \"Disable bot\" },\n { value: \"delete\" as const, label: \"Delete config\" },\n { value: \"skip\" as const, label: \"Skip (leave as-is)\" },\n ],\n initialValue: \"modify\" as const,\n }),\n );\n}\n\nasync function configureViaPlugin(channelId: ChannelId): Promise<void> {\n const pluginMap: Record<ChannelId, { importPath: string; name: string }> = {\n telegram: { importPath: '../../plugins/telegram/index.js', name: '@openacp/telegram' },\n discord: { importPath: '../../plugins/discord/index.js', name: '@openacp/discord' },\n };\n\n const pluginInfo = pluginMap[channelId];\n if (!pluginInfo) return;\n\n const { SettingsManager } = await import('../plugin/settings-manager.js');\n const { createInstallContext } = await import('../plugin/install-context.js');\n const basePath = path.join(os.homedir(), '.openacp', 'plugins');\n const settingsManager = new SettingsManager(basePath);\n\n const pluginModule = await import(pluginInfo.importPath);\n const plugin = pluginModule.default;\n\n if (plugin?.configure) {\n const ctx = createInstallContext({\n pluginName: plugin.name,\n settingsManager,\n basePath,\n });\n await plugin.configure(ctx);\n }\n}\n\nexport async function configureChannels(config: Config): Promise<{ config: Config; changed: boolean }> {\n const next = structuredClone(config);\n let changed = false;\n\n noteChannelStatus(next);\n\n while (true) {\n const statuses = getChannelStatuses(next);\n const options = statuses.map((s) => {\n const status = s.enabled ? \"enabled\" : s.configured ? \"disabled\" : \"not configured\";\n return {\n value: s.id,\n label: `${s.label} (${CHANNEL_META[s.id].method})`,\n hint: status + (s.hint ? ` · ${s.hint}` : \"\"),\n };\n });\n\n const choice = guardCancel(\n await clack.select({\n message: \"Select a channel\",\n options: [\n ...options,\n { value: \"__done__\" as const, label: \"Finished\" },\n ],\n }),\n );\n\n if (choice === \"__done__\") break;\n\n const channelId = choice as ChannelId;\n const meta = CHANNEL_META[channelId];\n const existing = next.channels[channelId] as Record<string, unknown> | undefined;\n const isConfigured = !!existing && Object.keys(existing).length > 1;\n\n if (isConfigured) {\n const action = await promptConfiguredAction(meta.label);\n\n if (action === \"skip\") continue;\n if (action === \"disable\") {\n (next.channels[channelId] as Record<string, unknown>).enabled = false;\n changed = true;\n console.log(ok(`${meta.label} disabled`));\n continue;\n }\n if (action === \"delete\") {\n const confirmed = guardCancel(\n await clack.confirm({\n message: `Delete ${meta.label} config? This cannot be undone.`,\n initialValue: false,\n }),\n );\n if (confirmed) {\n delete next.channels[channelId];\n changed = true;\n console.log(ok(`${meta.label} config deleted`));\n }\n continue;\n }\n // action === \"modify\" — fall through to plugin configure\n }\n\n // Run channel configuration via plugin configure()\n await configureViaPlugin(channelId);\n changed = true;\n }\n\n return { config: next, changed };\n}\n"],"mappings":"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","names":["clack","text","clack","clack","clack","clack","clack"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}