@openacp/cli 0.6.10 → 2026.326.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 (256) hide show
  1. package/dist/{action-detect-P7ZE4NEM.js → action-detect-QPA775HB.js} +2 -2
  2. package/dist/adapter-6ANPBSVU.js +16 -0
  3. package/dist/{discord-OMC52Y54.js → adapter-77ZCVABT.js} +520 -365
  4. package/dist/adapter-77ZCVABT.js.map +1 -0
  5. package/dist/{adapter-ZOANORGM.js → adapter-PQGHVG4K.js} +300 -93
  6. package/dist/adapter-PQGHVG4K.js.map +1 -0
  7. package/dist/{admin-6SYB6XCZ.js → admin-GBPZFFAU.js} +3 -3
  8. package/dist/agent-catalog-YHBFERYO.js +11 -0
  9. package/dist/{agent-dependencies-4OWBMZWZ.js → agent-dependencies-WS7Z2DFW.js} +2 -2
  10. package/dist/agent-registry-5LZT7CUB.js +9 -0
  11. package/dist/agent-store-VSHNY5GT.js +9 -0
  12. package/dist/{agents-QO7DKARJ.js → agents-BWU4MRRD.js} +3 -3
  13. package/dist/{api-client-CFQT5U7D.js → api-client-AQPNKXI2.js} +2 -2
  14. package/dist/api-server-3PYLRBCN.js +8 -0
  15. package/dist/api-server-CHVSUDBX.js +11 -0
  16. package/dist/{autostart-X33OGMX6.js → autostart-6JS565RY.js} +3 -3
  17. package/dist/chunk-2CX4IEEC.js +124 -0
  18. package/dist/chunk-2CX4IEEC.js.map +1 -0
  19. package/dist/{chunk-O7CPGUAI.js → chunk-4KGLKKQK.js} +4 -4
  20. package/dist/chunk-4KGLKKQK.js.map +1 -0
  21. package/dist/{chunk-W3EYKZNQ.js → chunk-4WXALZA3.js} +2 -2
  22. package/dist/chunk-4WXALZA3.js.map +1 -0
  23. package/dist/chunk-5OCGO27U.js +125 -0
  24. package/dist/chunk-5OCGO27U.js.map +1 -0
  25. package/dist/{chunk-OWP7RZ62.js → chunk-5ZOFBTOR.js} +118 -262
  26. package/dist/chunk-5ZOFBTOR.js.map +1 -0
  27. package/dist/chunk-6RXVEXF3.js +23 -0
  28. package/dist/chunk-6RXVEXF3.js.map +1 -0
  29. package/dist/{chunk-34M4OS5P.js → chunk-A6Y4GZM3.js} +3 -3
  30. package/dist/chunk-A6Y4GZM3.js.map +1 -0
  31. package/dist/chunk-AD3X6DGK.js +166 -0
  32. package/dist/chunk-AD3X6DGK.js.map +1 -0
  33. package/dist/{chunk-7QJS2XBD.js → chunk-AFKX424Q.js} +2 -2
  34. package/dist/chunk-AFKX424Q.js.map +1 -0
  35. package/dist/chunk-APS6UEFU.js +259 -0
  36. package/dist/chunk-APS6UEFU.js.map +1 -0
  37. package/dist/chunk-BLQUXO7S.js +113 -0
  38. package/dist/chunk-BLQUXO7S.js.map +1 -0
  39. package/dist/{chunk-WTZDAYZX.js → chunk-BQ6FR32N.js} +3 -3
  40. package/dist/chunk-BQ6FR32N.js.map +1 -0
  41. package/dist/chunk-FNRSWA2K.js +1 -0
  42. package/dist/chunk-FQEBWOZR.js +3557 -0
  43. package/dist/chunk-FQEBWOZR.js.map +1 -0
  44. package/dist/{chunk-4CTX774K.js → chunk-GJOY37U7.js} +4 -4
  45. package/dist/chunk-GJOY37U7.js.map +1 -0
  46. package/dist/{chunk-I7WC6E5S.js → chunk-HVBNCPAY.js} +2 -2
  47. package/dist/chunk-HVBNCPAY.js.map +1 -0
  48. package/dist/{chunk-2HMQOC7N.js → chunk-I3CGU5W7.js} +4 -4
  49. package/dist/chunk-I3CGU5W7.js.map +1 -0
  50. package/dist/{chunk-NVPG6JCL.js → chunk-L7YNNBI5.js} +3 -3
  51. package/dist/chunk-L7YNNBI5.js.map +1 -0
  52. package/dist/chunk-LGFWH3AE.js +26 -0
  53. package/dist/chunk-LGFWH3AE.js.map +1 -0
  54. package/dist/chunk-MLF4W5R6.js +101 -0
  55. package/dist/chunk-MLF4W5R6.js.map +1 -0
  56. package/dist/{chunk-KIRH7TUJ.js → chunk-MTSDOSXS.js} +3 -3
  57. package/dist/chunk-MTSDOSXS.js.map +1 -0
  58. package/dist/{chunk-J4SJTKIK.js → chunk-NAM4ERUW.js} +3 -3
  59. package/dist/chunk-NAM4ERUW.js.map +1 -0
  60. package/dist/{chunk-MKHUZLII.js → chunk-NBFIBGAT.js} +39 -25
  61. package/dist/chunk-NBFIBGAT.js.map +1 -0
  62. package/dist/{chunk-BNLGTZ34.js → chunk-O5RG4YZY.js} +3 -3
  63. package/dist/chunk-O5RG4YZY.js.map +1 -0
  64. package/dist/{chunk-JHYXKVV2.js → chunk-ODUM3D6X.js} +2 -2
  65. package/dist/chunk-ODUM3D6X.js.map +1 -0
  66. package/dist/chunk-OYSAN7UX.js +15 -0
  67. package/dist/chunk-OYSAN7UX.js.map +1 -0
  68. package/dist/chunk-P4SNGQNI.js +158 -0
  69. package/dist/chunk-P4SNGQNI.js.map +1 -0
  70. package/dist/{chunk-2CJ46J3C.js → chunk-PPSMUECX.js} +3 -3
  71. package/dist/chunk-PPSMUECX.js.map +1 -0
  72. package/dist/chunk-Q6ZXJTZB.js +56 -0
  73. package/dist/chunk-Q6ZXJTZB.js.map +1 -0
  74. package/dist/{chunk-XANPHG7W.js → chunk-QSDZDHNS.js} +7 -7
  75. package/dist/chunk-QSDZDHNS.js.map +1 -0
  76. package/dist/{chunk-33RP6K2O.js → chunk-QVMEF6FB.js} +6 -6
  77. package/dist/chunk-QVMEF6FB.js.map +1 -0
  78. package/dist/chunk-QWP76EBW.js +536 -0
  79. package/dist/chunk-QWP76EBW.js.map +1 -0
  80. package/dist/{chunk-V5GZQEIY.js → chunk-RBYBSSGO.js} +4 -4
  81. package/dist/chunk-RBYBSSGO.js.map +1 -0
  82. package/dist/{chunk-CS3KCJ5D.js → chunk-RKB2ZK6S.js} +555 -383
  83. package/dist/chunk-RKB2ZK6S.js.map +1 -0
  84. package/dist/{chunk-UKT3G5IA.js → chunk-SHTGQGAU.js} +7 -7
  85. package/dist/chunk-SHTGQGAU.js.map +1 -0
  86. package/dist/chunk-SNPYTMPR.js +51 -0
  87. package/dist/chunk-SNPYTMPR.js.map +1 -0
  88. package/dist/chunk-UB2QB6DE.js +124 -0
  89. package/dist/chunk-UB2QB6DE.js.map +1 -0
  90. package/dist/chunk-UNJUWWQO.js +1108 -0
  91. package/dist/chunk-UNJUWWQO.js.map +1 -0
  92. package/dist/chunk-V2M243KZ.js +445 -0
  93. package/dist/chunk-V2M243KZ.js.map +1 -0
  94. package/dist/chunk-V5JT5TPD.js +97 -0
  95. package/dist/chunk-V5JT5TPD.js.map +1 -0
  96. package/dist/chunk-W26AUH5B.js +61 -0
  97. package/dist/chunk-W26AUH5B.js.map +1 -0
  98. package/dist/chunk-WAAD23KY.js +222 -0
  99. package/dist/chunk-WAAD23KY.js.map +1 -0
  100. package/dist/chunk-WIIZNPCR.js +150 -0
  101. package/dist/chunk-WIIZNPCR.js.map +1 -0
  102. package/dist/chunk-WQCJTU2C.js +84 -0
  103. package/dist/chunk-WQCJTU2C.js.map +1 -0
  104. package/dist/chunk-WVLDNYOJ.js +150 -0
  105. package/dist/chunk-WVLDNYOJ.js.map +1 -0
  106. package/dist/chunk-WXVT3AOY.js +22 -0
  107. package/dist/chunk-WXVT3AOY.js.map +1 -0
  108. package/dist/{chunk-GAK6PIBW.js → chunk-XMMAGAT4.js} +2 -2
  109. package/dist/chunk-XMMAGAT4.js.map +1 -0
  110. package/dist/chunk-Y64XWMJ4.js +212 -0
  111. package/dist/chunk-Y64XWMJ4.js.map +1 -0
  112. package/dist/chunk-YEULD3SG.js +62 -0
  113. package/dist/chunk-YEULD3SG.js.map +1 -0
  114. package/dist/chunk-ZHGPZBS4.js +49 -0
  115. package/dist/chunk-ZHGPZBS4.js.map +1 -0
  116. package/dist/{chunk-JKBFUAJK.js → chunk-ZSLHHQPQ.js} +2 -2
  117. package/dist/chunk-ZSLHHQPQ.js.map +1 -0
  118. package/dist/cli.js +496 -150
  119. package/dist/cli.js.map +1 -1
  120. package/dist/{config-6S355X75.js → config-I4FMCJGZ.js} +3 -3
  121. package/dist/config-editor-HNEKXRLQ.js +11 -0
  122. package/dist/{config-registry-AHYI4MYL.js → config-registry-CUMNXFGK.js} +2 -2
  123. package/dist/context-XM6E22LM.js +10 -0
  124. package/dist/core-plugins-VEUNFTMB.js +27 -0
  125. package/dist/{daemon-4CS6HMB5.js → daemon-PXO5QPCR.js} +4 -4
  126. package/dist/dev-loader-RDC5E2CW.js +50 -0
  127. package/dist/dev-loader-RDC5E2CW.js.map +1 -0
  128. package/dist/discord-NOJQ5PZO.js +8 -0
  129. package/dist/doctor-H72BZOPA.js +10 -0
  130. package/dist/{doctor-OLYBO3V3.js → doctor-RF6BHMCC.js} +5 -5
  131. package/dist/file-service-EUODJAIT.js +9 -0
  132. package/dist/file-service-EUODJAIT.js.map +1 -0
  133. package/dist/index.d.ts +1293 -188
  134. package/dist/index.js +387 -48
  135. package/dist/index.js.map +1 -1
  136. package/dist/{install-cloudflared-Z7VCGOVG.js → install-cloudflared-AN24L4DP.js} +5 -5
  137. package/dist/install-cloudflared-AN24L4DP.js.map +1 -0
  138. package/dist/install-context-XPWTFT3J.js +78 -0
  139. package/dist/install-context-XPWTFT3J.js.map +1 -0
  140. package/dist/{install-jq-HUYSQWKR.js → install-jq-CRVDJGF3.js} +5 -5
  141. package/dist/install-jq-CRVDJGF3.js.map +1 -0
  142. package/dist/{integrate-PNEHRY2I.js → integrate-5C6KSU6D.js} +2 -2
  143. package/dist/integrate-5C6KSU6D.js.map +1 -0
  144. package/dist/{log-NXABYJTT.js → log-LZ7FTRKG.js} +2 -2
  145. package/dist/log-LZ7FTRKG.js.map +1 -0
  146. package/dist/main-T5WVCCFN.js +715 -0
  147. package/dist/main-T5WVCCFN.js.map +1 -0
  148. package/dist/{menu-YY5MKHEK.js → menu-YDQ2LWAR.js} +2 -2
  149. package/dist/menu-YDQ2LWAR.js.map +1 -0
  150. package/dist/{new-session-FEO4J4VU.js → new-session-AVQCNXRG.js} +5 -5
  151. package/dist/new-session-AVQCNXRG.js.map +1 -0
  152. package/dist/notifications-D5BRDNSU.js +9 -0
  153. package/dist/notifications-D5BRDNSU.js.map +1 -0
  154. package/dist/plugin-create-JVCVUG6V.js +331 -0
  155. package/dist/plugin-create-JVCVUG6V.js.map +1 -0
  156. package/dist/plugin-registry-WB3DR67H.js +8 -0
  157. package/dist/plugin-registry-WB3DR67H.js.map +1 -0
  158. package/dist/{post-upgrade-CJG5I7M2.js → post-upgrade-XLHZ6ZB7.js} +8 -8
  159. package/dist/post-upgrade-XLHZ6ZB7.js.map +1 -0
  160. package/dist/read-text-file-IRZM3QLM.js +8 -0
  161. package/dist/read-text-file-IRZM3QLM.js.map +1 -0
  162. package/dist/security-YNRBW6S7.js +9 -0
  163. package/dist/security-YNRBW6S7.js.map +1 -0
  164. package/dist/{session-IUSI7P5S.js → session-KZFA6Z26.js} +4 -4
  165. package/dist/session-KZFA6Z26.js.map +1 -0
  166. package/dist/{settings-RQPAM4KC.js → settings-MFYM7CZO.js} +4 -4
  167. package/dist/settings-MFYM7CZO.js.map +1 -0
  168. package/dist/settings-manager-MD2U4ZV2.js +8 -0
  169. package/dist/settings-manager-MD2U4ZV2.js.map +1 -0
  170. package/dist/{chunk-LCRLAV4G.js → setup-BAI2F24H.js} +154 -492
  171. package/dist/setup-BAI2F24H.js.map +1 -0
  172. package/dist/slack-KH7E3VBS.js +8 -0
  173. package/dist/slack-KH7E3VBS.js.map +1 -0
  174. package/dist/speech-2GHQNRIO.js +9 -0
  175. package/dist/speech-2GHQNRIO.js.map +1 -0
  176. package/dist/telegram-ZDC3JQF2.js +8 -0
  177. package/dist/telegram-ZDC3JQF2.js.map +1 -0
  178. package/dist/tunnel-M47I7H4B.js +8 -0
  179. package/dist/tunnel-M47I7H4B.js.map +1 -0
  180. package/dist/{tunnel-service-CJLUH6SZ.js → tunnel-service-WADYHREX.js} +17 -17
  181. package/dist/tunnel-service-WADYHREX.js.map +1 -0
  182. package/dist/usage-WYNK6ZC5.js +10 -0
  183. package/dist/usage-WYNK6ZC5.js.map +1 -0
  184. package/dist/validators-6CLEZUBD.js +8 -0
  185. package/dist/validators-6CLEZUBD.js.map +1 -0
  186. package/dist/validators-WSTBNKRW.js +12 -0
  187. package/dist/validators-WSTBNKRW.js.map +1 -0
  188. package/package.json +1 -1
  189. package/dist/adapter-ZOANORGM.js.map +0 -1
  190. package/dist/agent-catalog-FC3HGDEQ.js +0 -11
  191. package/dist/agent-registry-WT4NXPYG.js +0 -9
  192. package/dist/agent-store-VZLFPTZU.js +0 -9
  193. package/dist/chunk-2CJ46J3C.js.map +0 -1
  194. package/dist/chunk-2HMQOC7N.js.map +0 -1
  195. package/dist/chunk-33RP6K2O.js.map +0 -1
  196. package/dist/chunk-34M4OS5P.js.map +0 -1
  197. package/dist/chunk-4CTX774K.js.map +0 -1
  198. package/dist/chunk-7QJS2XBD.js.map +0 -1
  199. package/dist/chunk-BNLGTZ34.js.map +0 -1
  200. package/dist/chunk-CS3KCJ5D.js.map +0 -1
  201. package/dist/chunk-GAK6PIBW.js.map +0 -1
  202. package/dist/chunk-I7WC6E5S.js.map +0 -1
  203. package/dist/chunk-J4SJTKIK.js.map +0 -1
  204. package/dist/chunk-JHYXKVV2.js.map +0 -1
  205. package/dist/chunk-JKBFUAJK.js.map +0 -1
  206. package/dist/chunk-KIRH7TUJ.js.map +0 -1
  207. package/dist/chunk-LBIKITQT.js +0 -22
  208. package/dist/chunk-LBIKITQT.js.map +0 -1
  209. package/dist/chunk-LCRLAV4G.js.map +0 -1
  210. package/dist/chunk-LGP2YGRL.js +0 -4880
  211. package/dist/chunk-LGP2YGRL.js.map +0 -1
  212. package/dist/chunk-MKHUZLII.js.map +0 -1
  213. package/dist/chunk-NAMYZIS5.js +0 -1
  214. package/dist/chunk-NVPG6JCL.js.map +0 -1
  215. package/dist/chunk-O7CPGUAI.js.map +0 -1
  216. package/dist/chunk-OWP7RZ62.js.map +0 -1
  217. package/dist/chunk-UKT3G5IA.js.map +0 -1
  218. package/dist/chunk-V5GZQEIY.js.map +0 -1
  219. package/dist/chunk-VOIJ6OY4.js +0 -63
  220. package/dist/chunk-VOIJ6OY4.js.map +0 -1
  221. package/dist/chunk-W3EYKZNQ.js.map +0 -1
  222. package/dist/chunk-WTZDAYZX.js.map +0 -1
  223. package/dist/chunk-XANPHG7W.js.map +0 -1
  224. package/dist/config-editor-QQTZMWGD.js +0 -13
  225. package/dist/discord-OMC52Y54.js.map +0 -1
  226. package/dist/doctor-HZZ5BSHB.js +0 -10
  227. package/dist/install-cloudflared-Z7VCGOVG.js.map +0 -1
  228. package/dist/install-jq-HUYSQWKR.js.map +0 -1
  229. package/dist/integrate-PNEHRY2I.js.map +0 -1
  230. package/dist/main-XOZCLFUK.js +0 -238
  231. package/dist/main-XOZCLFUK.js.map +0 -1
  232. package/dist/post-upgrade-CJG5I7M2.js.map +0 -1
  233. package/dist/setup-XHS4OMPM.js +0 -37
  234. package/dist/tunnel-service-CJLUH6SZ.js.map +0 -1
  235. /package/dist/{action-detect-P7ZE4NEM.js.map → action-detect-QPA775HB.js.map} +0 -0
  236. /package/dist/{admin-6SYB6XCZ.js.map → adapter-6ANPBSVU.js.map} +0 -0
  237. /package/dist/{agent-catalog-FC3HGDEQ.js.map → admin-GBPZFFAU.js.map} +0 -0
  238. /package/dist/{agent-dependencies-4OWBMZWZ.js.map → agent-catalog-YHBFERYO.js.map} +0 -0
  239. /package/dist/{agent-registry-WT4NXPYG.js.map → agent-dependencies-WS7Z2DFW.js.map} +0 -0
  240. /package/dist/{agent-store-VZLFPTZU.js.map → agent-registry-5LZT7CUB.js.map} +0 -0
  241. /package/dist/{agents-QO7DKARJ.js.map → agent-store-VSHNY5GT.js.map} +0 -0
  242. /package/dist/{api-client-CFQT5U7D.js.map → agents-BWU4MRRD.js.map} +0 -0
  243. /package/dist/{autostart-X33OGMX6.js.map → api-client-AQPNKXI2.js.map} +0 -0
  244. /package/dist/{chunk-NAMYZIS5.js.map → api-server-3PYLRBCN.js.map} +0 -0
  245. /package/dist/{config-6S355X75.js.map → api-server-CHVSUDBX.js.map} +0 -0
  246. /package/dist/{config-editor-QQTZMWGD.js.map → autostart-6JS565RY.js.map} +0 -0
  247. /package/dist/{config-registry-AHYI4MYL.js.map → chunk-FNRSWA2K.js.map} +0 -0
  248. /package/dist/{daemon-4CS6HMB5.js.map → config-I4FMCJGZ.js.map} +0 -0
  249. /package/dist/{doctor-HZZ5BSHB.js.map → config-editor-HNEKXRLQ.js.map} +0 -0
  250. /package/dist/{doctor-OLYBO3V3.js.map → config-registry-CUMNXFGK.js.map} +0 -0
  251. /package/dist/{log-NXABYJTT.js.map → context-XM6E22LM.js.map} +0 -0
  252. /package/dist/{menu-YY5MKHEK.js.map → core-plugins-VEUNFTMB.js.map} +0 -0
  253. /package/dist/{new-session-FEO4J4VU.js.map → daemon-PXO5QPCR.js.map} +0 -0
  254. /package/dist/{session-IUSI7P5S.js.map → discord-NOJQ5PZO.js.map} +0 -0
  255. /package/dist/{settings-RQPAM4KC.js.map → doctor-H72BZOPA.js.map} +0 -0
  256. /package/dist/{setup-XHS4OMPM.js.map → doctor-RF6BHMCC.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/command-registry.ts","../../src/core/commands/session.ts","../../src/core/commands/agents.ts","../../src/core/commands/admin.ts","../../src/core/commands/help.ts","../../src/core/commands/menu.ts","../../src/core/commands/index.ts","../../src/main.ts"],"sourcesContent":["import type { CommandDef, CommandArgs, CommandResponse } from './plugin/types.js'\n\ninterface RegisteredCommand extends CommandDef {\n /** Scope extracted from pluginName, e.g. '@openacp/speech' → 'speech' */\n scope?: string\n}\n\n/**\n * Central command registry with namespace resolution and adapter-specific overrides.\n *\n * Namespace rules:\n * - System commands always own the short name.\n * - Among plugins, the first to register wins the short name.\n * - Every plugin command also gets a qualified name: `scope:name`.\n * - Adapter plugins (@openacp/telegram, @openacp/discord, @openacp/slack)\n * registering a command that already exists → stored as an override\n * keyed by `channelId:commandName`, used when channelId matches.\n */\nexport class CommandRegistry {\n /** Main registry: short names + qualified names → RegisteredCommand */\n private commands = new Map<string, RegisteredCommand>()\n\n /** Adapter-specific overrides: `channelId:commandName` → RegisteredCommand */\n private overrides = new Map<string, RegisteredCommand>()\n\n private static ADAPTER_SCOPES = new Set(['telegram', 'discord', 'slack'])\n\n /**\n * Register a command definition.\n * @param def - Command definition\n * @param pluginName - Plugin that owns the command (set automatically by PluginContext)\n */\n register(def: CommandDef, pluginName?: string): void {\n const cmd: RegisteredCommand = {\n ...def,\n pluginName: pluginName ?? def.pluginName,\n }\n\n if (pluginName) {\n cmd.scope = CommandRegistry.extractScope(pluginName)\n }\n\n const qualifiedName = cmd.scope ? `${cmd.scope}:${cmd.name}` : undefined\n\n // Check if this is an adapter plugin overriding an existing command\n if (cmd.scope && CommandRegistry.ADAPTER_SCOPES.has(cmd.scope) && this.commands.has(cmd.name)) {\n // Store as adapter override\n this.overrides.set(`${cmd.scope}:${cmd.name}`, cmd)\n return\n }\n\n // Always register qualified name if available\n if (qualifiedName) {\n this.commands.set(qualifiedName, cmd)\n }\n\n // Short name logic\n if (this.commands.has(cmd.name)) {\n const existing = this.commands.get(cmd.name)!\n // System commands always win the short name\n if (existing.category === 'system') {\n // Plugin gets qualified name only (already registered above)\n return\n }\n // First plugin wins short name; later plugins get qualified only\n return\n }\n\n // No conflict — register short name\n this.commands.set(cmd.name, cmd)\n }\n\n /** Retrieve a command by name (short or qualified). */\n get(name: string): RegisteredCommand | undefined {\n return this.commands.get(name)\n }\n\n /** Remove a command by short name. Also removes its qualified name entry. */\n unregister(name: string): void {\n const cmd = this.commands.get(name)\n if (cmd) {\n this.commands.delete(name)\n // Also remove qualified name\n if (cmd.scope) {\n this.commands.delete(`${cmd.scope}:${name}`)\n }\n }\n // Also try removing as qualified name\n if (!cmd) {\n this.commands.delete(name)\n }\n }\n\n /** Remove all commands registered by a given plugin. */\n unregisterByPlugin(pluginName: string): void {\n const scope = CommandRegistry.extractScope(pluginName)\n const toDelete: string[] = []\n\n for (const [key, cmd] of this.commands) {\n if (cmd.pluginName === pluginName) {\n toDelete.push(key)\n }\n }\n\n for (const key of toDelete) {\n this.commands.delete(key)\n }\n\n // Also remove adapter overrides\n for (const [key, cmd] of this.overrides) {\n if (cmd.pluginName === pluginName) {\n this.overrides.delete(key)\n }\n }\n }\n\n /** Return all unique commands (deduplicated — each command appears once). */\n getAll(): RegisteredCommand[] {\n const seen = new Set<RegisteredCommand>()\n for (const cmd of this.commands.values()) {\n seen.add(cmd)\n }\n return [...seen]\n }\n\n /** Filter commands by category. */\n getByCategory(category: 'system' | 'plugin'): RegisteredCommand[] {\n return this.getAll().filter((cmd) => cmd.category === category)\n }\n\n /**\n * Parse and execute a command string.\n * @param commandString - Full command string, e.g. \"/greet hello world\"\n * @param baseArgs - Base arguments (channelId, userId, etc.)\n * @returns CommandResponse\n */\n async execute(commandString: string, baseArgs: CommandArgs): Promise<CommandResponse> {\n // Parse command name and raw args\n const trimmed = commandString.trim()\n const spaceIdx = trimmed.indexOf(' ')\n const cmdName = spaceIdx === -1 ? trimmed.slice(1) : trimmed.slice(1, spaceIdx)\n const rawArgs = spaceIdx === -1 ? '' : trimmed.slice(spaceIdx + 1)\n\n // Check for adapter-specific override first\n const overrideKey = `${baseArgs.channelId}:${cmdName}`\n const override = this.overrides.get(overrideKey)\n\n const cmd = override ?? this.commands.get(cmdName)\n\n if (!cmd) {\n return { type: 'error', message: `Unknown command: /${cmdName}` }\n }\n\n const args: CommandArgs = {\n ...baseArgs,\n raw: rawArgs,\n }\n\n try {\n const result = await cmd.handler(args)\n if (result === undefined || result === null) {\n return { type: 'silent' }\n }\n return result\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { type: 'error', message: `Command /${cmdName} failed: ${message}` }\n }\n }\n\n /** Extract scope from plugin name: '@openacp/speech' → 'speech', 'my-plugin' → 'my-plugin' */\n static extractScope(pluginName: string): string {\n const slashIdx = pluginName.lastIndexOf('/')\n if (slashIdx !== -1) {\n return pluginName.slice(slashIdx + 1)\n }\n return pluginName\n }\n}\n","import type { CommandRegistry } from '../command-registry.js'\nimport type { CommandResponse } from '../plugin/types.js'\n\nexport function registerSessionCommands(registry: CommandRegistry, _core: unknown): void {\n registry.register({\n name: 'new',\n description: 'Start a new session',\n usage: '[agent-name]',\n category: 'system',\n handler: async (args) => {\n const agent = args.raw.trim()\n if (agent) {\n return { type: 'text', text: `Starting new session with agent: ${agent}` } satisfies CommandResponse\n }\n return { type: 'text', text: 'Starting new session...' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'cancel',\n description: 'Cancel the current agent turn',\n category: 'system',\n handler: async () => {\n return { type: 'silent' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'status',\n description: 'Show current session status',\n category: 'system',\n handler: async () => {\n return { type: 'text', text: 'No active session.' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'sessions',\n description: 'List all active sessions',\n category: 'system',\n handler: async () => {\n return { type: 'text', text: 'No active sessions.' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'clear',\n description: 'Clear session history',\n category: 'system',\n handler: async () => {\n return { type: 'silent' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'newchat',\n description: 'End current session and start a new one',\n category: 'system',\n handler: async () => {\n return { type: 'text', text: 'Ending session and starting a new one...' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'resume',\n description: 'Resume a previous session',\n usage: '<session-number>',\n category: 'system',\n handler: async (args) => {\n const id = args.raw.trim()\n if (!id) {\n return { type: 'error', message: 'Usage: /resume <session-number>' } satisfies CommandResponse\n }\n return { type: 'text', text: `Resuming session ${id}...` } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'summary',\n description: 'Show session summary',\n category: 'system',\n handler: async () => {\n return { type: 'text', text: 'No session summary available.' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'handoff',\n description: 'Hand off session to another agent',\n usage: '<agent-name>',\n category: 'system',\n handler: async (args) => {\n const agent = args.raw.trim()\n if (!agent) {\n return { type: 'error', message: 'Usage: /handoff <agent-name>' } satisfies CommandResponse\n }\n return { type: 'text', text: `Handing off to ${agent}...` } satisfies CommandResponse\n },\n })\n}\n","import type { CommandRegistry } from '../command-registry.js'\nimport type { CommandResponse } from '../plugin/types.js'\n\nexport function registerAgentCommands(registry: CommandRegistry, _core: unknown): void {\n registry.register({\n name: 'agents',\n description: 'List available agents',\n category: 'system',\n handler: async () => {\n return { type: 'text', text: 'No agents configured.' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'install',\n description: 'Install a plugin',\n usage: '<plugin-name>',\n category: 'system',\n handler: async (args) => {\n const plugin = args.raw.trim()\n if (!plugin) {\n return { type: 'error', message: 'Usage: /install <plugin-name>' } satisfies CommandResponse\n }\n return { type: 'text', text: `Installing plugin: ${plugin}...` } satisfies CommandResponse\n },\n })\n}\n","import type { CommandRegistry } from '../command-registry.js'\nimport type { CommandResponse } from '../plugin/types.js'\n\nexport function registerAdminCommands(registry: CommandRegistry, _core: unknown): void {\n registry.register({\n name: 'restart',\n description: 'Restart the server',\n category: 'system',\n handler: async () => {\n return { type: 'silent' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'update',\n description: 'Check for and apply updates',\n category: 'system',\n handler: async () => {\n return { type: 'text', text: 'Checking for updates...' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'doctor',\n description: 'Run system diagnostics',\n category: 'system',\n handler: async () => {\n return { type: 'text', text: 'Running diagnostics...' } satisfies CommandResponse\n },\n })\n\n registry.register({\n name: 'integrate',\n description: 'Set up a new channel integration',\n usage: '<channel>',\n category: 'system',\n handler: async (args) => {\n const channel = args.raw.trim()\n if (!channel) {\n return {\n type: 'menu',\n title: 'Available Integrations',\n options: [\n { label: 'Telegram', command: '/integrate telegram' },\n { label: 'Discord', command: '/integrate discord' },\n { label: 'Slack', command: '/integrate slack' },\n ],\n } satisfies CommandResponse\n }\n return { type: 'text', text: `Setting up ${channel} integration...` } satisfies CommandResponse\n },\n })\n}\n","import type { CommandRegistry } from '../command-registry.js'\nimport type { CommandResponse } from '../plugin/types.js'\n\nexport function registerHelpCommand(registry: CommandRegistry, _core: unknown): void {\n registry.register({\n name: 'help',\n description: 'Show available commands',\n usage: '[command]',\n category: 'system',\n handler: async (args) => {\n const query = args.raw.trim()\n\n if (query) {\n const cmd = registry.get(query)\n if (!cmd) {\n return { type: 'error', message: `Unknown command: /${query}` } satisfies CommandResponse\n }\n let text = `/${cmd.name}`\n if (cmd.usage) text += ` ${cmd.usage}`\n text += `\\n${cmd.description}`\n return { type: 'text', text } satisfies CommandResponse\n }\n\n // Auto-generate help from registry at invocation time\n const systemCmds = registry.getByCategory('system')\n const pluginCmds = registry.getByCategory('plugin')\n\n const lines: string[] = []\n\n if (systemCmds.length > 0) {\n lines.push('System Commands:')\n for (const cmd of systemCmds) {\n const usage = cmd.usage ? ` ${cmd.usage}` : ''\n lines.push(` /${cmd.name}${usage} — ${cmd.description}`)\n }\n }\n\n if (pluginCmds.length > 0) {\n if (lines.length > 0) lines.push('')\n lines.push('Plugin Commands:')\n for (const cmd of pluginCmds) {\n const usage = cmd.usage ? ` ${cmd.usage}` : ''\n lines.push(` /${cmd.name}${usage} — ${cmd.description}`)\n }\n }\n\n if (lines.length === 0) {\n return { type: 'text', text: 'No commands registered.' } satisfies CommandResponse\n }\n\n return { type: 'text', text: lines.join('\\n') } satisfies CommandResponse\n },\n })\n}\n","import type { CommandRegistry } from '../command-registry.js'\nimport type { CommandResponse } from '../plugin/types.js'\n\nexport function registerMenuCommand(registry: CommandRegistry, _core: unknown): void {\n registry.register({\n name: 'menu',\n description: 'Show the main menu',\n category: 'system',\n handler: async () => {\n return {\n type: 'menu',\n title: 'Main Menu',\n options: [\n { label: 'New Session', command: '/new' },\n { label: 'Active Sessions', command: '/sessions' },\n { label: 'Available Agents', command: '/agents' },\n { label: 'Usage', command: '/usage' },\n { label: 'Help', command: '/help' },\n ],\n } satisfies CommandResponse\n },\n })\n}\n","import type { CommandRegistry } from '../command-registry.js'\nimport { registerSessionCommands } from './session.js'\nimport { registerAgentCommands } from './agents.js'\nimport { registerAdminCommands } from './admin.js'\nimport { registerHelpCommand } from './help.js'\nimport { registerMenuCommand } from './menu.js'\n\nexport function registerSystemCommands(registry: CommandRegistry, core: unknown): void {\n registerSessionCommands(registry, core)\n registerAgentCommands(registry, core)\n registerAdminCommands(registry, core)\n registerHelpCommand(registry, core)\n registerMenuCommand(registry, core)\n}\n","#!/usr/bin/env node\n\nimport { ConfigManager } from './core/config/config.js'\nimport { OpenACPCore } from './core/core.js'\nimport { initLogger, shutdownLogger, cleanupOldSessionLogs, log, muteLogger, unmuteLogger } from './core/utils/log.js'\nimport { corePlugins } from './plugins/core-plugins.js'\nimport { SettingsManager } from './core/plugin/settings-manager.js'\nimport { PluginRegistry } from './core/plugin/plugin-registry.js'\nimport { CommandRegistry } from './core/command-registry.js'\nimport { registerSystemCommands } from './core/commands/index.js'\nimport type { IChannelAdapter } from './core/channel.js'\nimport type { TunnelService } from './plugins/tunnel/tunnel-service.js'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\n\nexport const RESTART_EXIT_CODE = 75\nlet shuttingDown = false\n\nconst OPENACP_DIR = path.join(os.homedir(), '.openacp')\nconst PLUGINS_DATA_DIR = path.join(OPENACP_DIR, 'plugins', 'data')\nconst REGISTRY_PATH = path.join(OPENACP_DIR, 'plugins.json')\n\nexport interface StartServerOptions {\n devPluginPath?: string\n noWatch?: boolean\n}\n\nexport async function startServer(opts?: StartServerOptions) {\n // 0. If running as daemon child, check state and write PID file\n if (process.argv.includes('--daemon-child')) {\n const { writePidFile, readPidFile, getPidPath, shouldAutoStart } = await import('./cli/daemon.js')\n\n // Only auto-start if the daemon was previously running (user started it)\n if (!shouldAutoStart()) {\n process.exit(0)\n }\n\n const pidPath = getPidPath()\n const existingPid = readPidFile(pidPath)\n if (existingPid !== null && existingPid !== process.pid) {\n try {\n process.kill(existingPid, 0)\n console.error(`Another OpenACP instance is already running (PID ${existingPid}). Exiting.`)\n process.exit(1)\n } catch {\n // Stale PID file — safe to overwrite\n }\n }\n writePidFile(pidPath, process.pid)\n }\n\n // Create SettingsManager and PluginRegistry early (needed by wizard + boot)\n const settingsManager = new SettingsManager(PLUGINS_DATA_DIR)\n const pluginRegistry = new PluginRegistry(REGISTRY_PATH)\n await pluginRegistry.load()\n\n // 1. Check config exists, run setup if not\n const configManager = new ConfigManager()\n const configExists = await configManager.exists()\n\n if (!configExists) {\n const { runSetup } = await import('./core/setup/index.js')\n const shouldStart = await runSetup(configManager, { settingsManager, pluginRegistry })\n if (!shouldStart) process.exit(0)\n }\n\n // 2. Load config (validates with Zod)\n await configManager.load()\n const config = configManager.get()\n initLogger(config.logging)\n log.debug({ configPath: configManager.getConfigPath() }, 'Config loaded')\n\n // First boot: auto-register built-in plugins if registry is empty\n if (pluginRegistry.list().size === 0) {\n await autoRegisterBuiltinPlugins(settingsManager, pluginRegistry, configManager)\n }\n\n // Show banner in foreground TTY mode (not daemon, not piped)\n const isForegroundTTY = !!(process.stdout.isTTY && !process.env.NO_COLOR && config.runMode !== 'daemon')\n if (isForegroundTTY) {\n const { printStartBanner } = await import('./core/setup/index.js')\n await printStartBanner()\n }\n\n // Mute pino during startup, show spinner instead\n let spinner: ReturnType<typeof import('ora').default> | undefined\n if (isForegroundTTY) {\n muteLogger()\n const ora = (await import('ora')).default\n spinner = ora({ text: 'Starting OpenACP...', spinner: 'dots' }).start()\n }\n\n // Post-upgrade dependency check (blocking — must complete before server start)\n try {\n const { runPostUpgradeChecks } = await import('./cli/post-upgrade.js')\n await runPostUpgradeChecks(config)\n } catch (err) {\n log.warn({ err }, 'Post-upgrade check failed')\n }\n\n // Async cleanup of old session logs (non-blocking)\n cleanupOldSessionLogs(config.logging.sessionLogRetentionDays).catch(err =>\n log.warn({ err }, 'Session log cleanup failed')\n )\n\n // 3. Create core\n const core = new OpenACPCore(configManager)\n\n // 3b. Create CommandRegistry and register as service\n const commandRegistry = new CommandRegistry()\n const serviceRegistry = core.lifecycleManager.serviceRegistry\n serviceRegistry.register('command-registry', commandRegistry, 'core')\n\n // 3c. Register system commands\n registerSystemCommands(commandRegistry, core)\n\n // 4. Boot all plugins (services, infrastructure, adapters)\n try {\n // Emit kernel:booted before plugin boot\n core.eventBus.emit('kernel:booted')\n\n // Pass settingsManager and pluginRegistry to LifecycleManager\n ;(core.lifecycleManager as any).settingsManager = settingsManager\n ;(core.lifecycleManager as any).pluginRegistry = pluginRegistry\n\n // Boot all built-in plugins in dependency order\n await core.lifecycleManager.boot(corePlugins)\n\n // Load dev plugin if running in dev mode\n if (opts?.devPluginPath) {\n const { DevPluginLoader } = await import('./core/plugin/dev-loader.js')\n const devLoader = new DevPluginLoader(opts.devPluginPath)\n\n try {\n const devPlugin = await devLoader.load()\n await core.lifecycleManager.boot([devPlugin])\n log.info({ plugin: devPlugin.name, version: devPlugin.version }, 'Dev plugin loaded')\n\n // Watch dist/ directory for changes and hot-reload\n if (!opts.noWatch) {\n const distPath = devLoader.getDistPath()\n let reloadTimer: ReturnType<typeof setTimeout> | null = null\n\n fs.watch(distPath, { recursive: true }, (_eventType, filename) => {\n if (!filename?.endsWith('.js')) return\n\n // Debounce: wait 500ms after last change\n if (reloadTimer) clearTimeout(reloadTimer)\n reloadTimer = setTimeout(async () => {\n try {\n log.info({ filename }, 'Dev plugin changed, reloading...')\n await core.lifecycleManager.unloadPlugin(devPlugin.name)\n const reloaded = await devLoader.load()\n await core.lifecycleManager.boot([reloaded])\n log.info({ plugin: reloaded.name, version: reloaded.version }, 'Dev plugin reloaded')\n } catch (err) {\n log.error({ err }, 'Dev plugin reload failed')\n }\n }, 500)\n })\n\n log.info({ distPath }, 'Watching dev plugin for changes')\n }\n } catch (err) {\n log.error({ err, pluginPath: opts.devPluginPath }, 'Failed to load dev plugin')\n }\n }\n\n // Wire adapters from service registry into core\n for (const adapterName of ['telegram', 'discord', 'slack']) {\n const adapter = serviceRegistry.get<IChannelAdapter>(`adapter:${adapterName}`)\n if (adapter) {\n core.registerAdapter(adapterName, adapter)\n log.info({ adapter: adapterName }, 'Adapter registered')\n }\n }\n\n // Wire tunnel service from service registry into core\n const tunnelSvc = serviceRegistry.get<TunnelService>('tunnel')\n if (tunnelSvc) {\n core.tunnelService = tunnelSvc\n }\n\n // Emit system:commands-ready with all registered commands\n core.eventBus.emit('system:commands-ready', { commands: commandRegistry.getAll() })\n\n core.eventBus.emit('system:ready')\n } catch (err) {\n log.error({ err }, 'Plugin boot failed')\n }\n\n if (core.adapters.size === 0) {\n log.error('No channels enabled. Enable at least one channel in config.')\n process.exit(1)\n }\n\n // 5. Setup shutdown handler\n const shutdown = async (signal: string, exitCode = 0) => {\n if (shuttingDown) return\n shuttingDown = true\n log.info({ signal, exitCode }, 'Signal received, shutting down')\n\n try {\n // Lifecycle teardown stops all plugins (adapters, api-server, tunnel, etc.)\n await core.lifecycleManager.shutdown()\n await core.stop()\n } catch (err) {\n log.error({ err }, 'Error during shutdown')\n }\n\n const isDaemon = process.argv.includes('--daemon-child')\n\n // Clean up PID file if running as daemon\n if (isDaemon) {\n const { removePidFile, getPidPath } = await import('./cli/daemon.js')\n removePidFile(getPidPath())\n }\n\n // Self-respawn on restart\n if (exitCode === RESTART_EXIT_CODE) {\n if (isDaemon) {\n // Daemon mode: spawn detached child writing to log file\n const { spawn: spawnChild } = await import('node:child_process')\n const { expandHome } = await import('./core/config/config.js')\n const fs = await import('node:fs')\n const pathMod = await import('node:path')\n\n const cliPath = pathMod.resolve(process.argv[1])\n const resolvedLogDir = expandHome(config.logging.logDir)\n fs.mkdirSync(resolvedLogDir, { recursive: true })\n const logFile = pathMod.join(resolvedLogDir, 'openacp.log')\n const out = fs.openSync(logFile, 'a')\n const err = fs.openSync(logFile, 'a')\n\n const child = spawnChild(process.execPath, [cliPath, '--daemon-child'], {\n detached: true,\n stdio: ['ignore', out, err],\n env: { ...process.env, OPENACP_SKIP_UPDATE_CHECK: '1' },\n })\n fs.closeSync(out)\n fs.closeSync(err)\n child.unref()\n log.info({ newPid: child.pid }, 'Respawned daemon for restart')\n } else if (!process.env.OPENACP_DEV_LOOP) {\n // Foreground production mode: spawn replacement process with inherited stdio\n const { spawn: spawnChild } = await import('node:child_process')\n const child = spawnChild(process.execPath, process.argv.slice(1), {\n stdio: 'inherit',\n env: { ...process.env, OPENACP_SKIP_UPDATE_CHECK: '1' },\n })\n await shutdownLogger()\n child.on('exit', (code) => process.exit(code ?? 0))\n return\n }\n }\n\n await shutdownLogger()\n process.exit(exitCode)\n }\n\n // Expose restart trigger for adapters (e.g. /restart command)\n core.requestRestart = () => shutdown('restart', RESTART_EXIT_CODE)\n\n process.on('SIGINT', () => shutdown('SIGINT'))\n process.on('SIGTERM', () => shutdown('SIGTERM'))\n\n process.on('uncaughtException', (err) => {\n log.error({ err }, 'Uncaught exception')\n })\n\n process.on('unhandledRejection', (err) => {\n log.error({ err }, 'Unhandled rejection')\n })\n\n await core.start()\n\n // 6. Log ready\n if (isForegroundTTY) {\n if (spinner) spinner.stop()\n const ok = (msg: string) => console.log(`\\x1b[32m✓\\x1b[0m ${msg}`)\n ok('Config loaded')\n ok('Dependencies checked')\n const tunnelSvc = core.lifecycleManager.serviceRegistry.get<TunnelService>('tunnel')\n if (tunnelSvc) ok(`Tunnel ready → ${tunnelSvc.getPublicUrl()}`)\n for (const [name] of core.adapters) ok(`${name.charAt(0).toUpperCase() + name.slice(1)} connected`)\n const apiPort = config.api?.port ?? 21420\n if (core.lifecycleManager.serviceRegistry.get('api-server')) ok(`API server on port ${apiPort}`)\n console.log(`\\nOpenACP is running. Press Ctrl+C to stop.\\n`)\n unmuteLogger()\n }\n log.debug({ agents: Object.keys(config.agents) }, 'OpenACP started')\n}\n\n/**\n * Auto-register all built-in plugins when the registry is empty (first boot with new plugin system,\n * or upgrade from legacy config). Also runs legacy config migration for each plugin.\n */\nasync function autoRegisterBuiltinPlugins(\n settingsManager: SettingsManager,\n pluginRegistry: PluginRegistry,\n configManager: ConfigManager,\n): Promise<void> {\n const allPlugins = [\n { name: '@openacp/security', version: '1.0.0', description: 'User access control and session limits' },\n { name: '@openacp/file-service', version: '1.0.0', description: 'File storage and management' },\n { name: '@openacp/context', version: '1.0.0', description: 'Conversation context management' },\n { name: '@openacp/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 { name: '@openacp/telegram', version: '1.0.0', description: 'Telegram adapter with forum topics' },\n { name: '@openacp/discord', version: '1.0.0', description: 'Discord adapter with forum threads' },\n { name: '@openacp/slack', version: '1.0.0', description: 'Slack adapter with channels and threads' },\n ]\n\n // Try to read legacy config for migration\n let legacyConfig: Record<string, unknown> | undefined\n try {\n const cfg = configManager.get()\n if (cfg && typeof cfg === 'object') {\n legacyConfig = cfg as unknown as Record<string, unknown>\n }\n } catch {\n // No config loaded yet — skip migration\n }\n\n // Run legacy migration for each plugin silently\n if (legacyConfig) {\n const pluginModules = await Promise.allSettled([\n import('./plugins/security/index.js'),\n import('./plugins/file-service/index.js'),\n import('./plugins/context/index.js'),\n import('./plugins/usage/index.js'),\n import('./plugins/speech/index.js'),\n import('./plugins/notifications/index.js'),\n import('./plugins/tunnel/index.js'),\n import('./plugins/api-server/index.js'),\n import('./plugins/telegram/index.js'),\n import('./plugins/discord/index.js'),\n import('./plugins/slack/index.js'),\n ])\n\n for (const result of pluginModules) {\n if (result.status !== 'fulfilled') continue\n const plugin = result.value.default\n if (plugin?.install) {\n try {\n // Check if settings already exist\n const existing = await settingsManager.loadSettings(plugin.name)\n if (Object.keys(existing).length > 0) continue\n\n // Create a silent install context for migration only\n const { createInstallContext } = await import('./core/plugin/install-context.js')\n const ctx = createInstallContext({\n pluginName: plugin.name,\n settingsManager,\n basePath: PLUGINS_DATA_DIR,\n legacyConfig,\n })\n // Override terminal to be silent\n ctx.terminal = createSilentTerminal()\n await plugin.install(ctx)\n } catch {\n // Silently skip — migration is best-effort\n }\n }\n }\n }\n\n for (const p of allPlugins) {\n pluginRegistry.register(p.name, {\n version: p.version,\n source: 'builtin',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(p.name),\n description: p.description,\n })\n }\n await pluginRegistry.save()\n log.info('Built-in plugins registered in plugin registry')\n}\n\n/**\n * Create a no-op terminal for silent migration (no user interaction).\n */\nfunction createSilentTerminal(): import('./core/plugin/types.js').TerminalIO {\n const noop = () => {}\n return {\n text: async () => '',\n select: async () => '' as any,\n confirm: async () => false,\n password: async () => '',\n multiselect: async () => [],\n log: { info: noop, success: noop, warning: noop, error: noop, step: noop },\n spinner: () => ({ start: noop, stop: noop, fail: noop }),\n note: noop,\n cancel: noop,\n }\n}\n\n// Direct execution for dev (node dist/main.js)\nconst isDirectExecution = process.argv[1]?.endsWith('main.js')\nif (isDirectExecution) {\n startServer().catch((err) => {\n log.error({ err }, 'Fatal error')\n process.exit(1)\n })\n}\n"],"mappings":"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","names":["fs"]}
@@ -4,7 +4,7 @@ import {
4
4
  handleClear,
5
5
  handleHelp,
6
6
  handleMenu
7
- } from "./chunk-7QJS2XBD.js";
7
+ } from "./chunk-AFKX424Q.js";
8
8
  import "./chunk-VUNV25KB.js";
9
9
  export {
10
10
  buildMenuKeyboard,
@@ -13,4 +13,4 @@ export {
13
13
  handleHelp,
14
14
  handleMenu
15
15
  };
16
- //# sourceMappingURL=menu-YY5MKHEK.js.map
16
+ //# sourceMappingURL=menu-YDQ2LWAR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -3,10 +3,10 @@ import {
3
3
  handleNew,
4
4
  handleNewChat,
5
5
  handleNewSessionButton
6
- } from "./chunk-XANPHG7W.js";
7
- import "./chunk-KIRH7TUJ.js";
8
- import "./chunk-BNLGTZ34.js";
9
- import "./chunk-GAK6PIBW.js";
6
+ } from "./chunk-QSDZDHNS.js";
7
+ import "./chunk-O5RG4YZY.js";
8
+ import "./chunk-MTSDOSXS.js";
9
+ import "./chunk-XMMAGAT4.js";
10
10
  import "./chunk-VUNV25KB.js";
11
11
  export {
12
12
  executeNewSession,
@@ -14,4 +14,4 @@ export {
14
14
  handleNewChat,
15
15
  handleNewSessionButton
16
16
  };
17
- //# sourceMappingURL=new-session-FEO4J4VU.js.map
17
+ //# sourceMappingURL=new-session-AVQCNXRG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,9 @@
1
+ import {
2
+ notifications_default
3
+ } from "./chunk-SNPYTMPR.js";
4
+ import "./chunk-WXVT3AOY.js";
5
+ import "./chunk-VUNV25KB.js";
6
+ export {
7
+ notifications_default as default
8
+ };
9
+ //# sourceMappingURL=notifications-D5BRDNSU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,331 @@
1
+ import "./chunk-VUNV25KB.js";
2
+
3
+ // src/cli/commands/plugin-create.ts
4
+ import * as p from "@clack/prompts";
5
+ import fs from "fs";
6
+ import path from "path";
7
+ import { createRequire } from "module";
8
+ async function cmdPluginCreate() {
9
+ p.intro("Create a new OpenACP plugin");
10
+ const result = await p.group(
11
+ {
12
+ name: () => p.text({
13
+ message: "Plugin name (e.g., @myorg/adapter-matrix)",
14
+ placeholder: "@myorg/my-plugin",
15
+ validate: (value) => {
16
+ if (!value || !value.trim()) return "Plugin name is required";
17
+ if (!/^(@[a-z0-9-]+\/)?[a-z0-9-]+$/.test(value.trim())) {
18
+ return "Must be a valid npm package name (lowercase, hyphens, optional @scope/)";
19
+ }
20
+ return void 0;
21
+ }
22
+ }),
23
+ description: () => p.text({
24
+ message: "Description",
25
+ placeholder: "A short description of your plugin"
26
+ }),
27
+ author: () => p.text({
28
+ message: "Author",
29
+ placeholder: "Your Name <email@example.com>"
30
+ }),
31
+ license: () => p.select({
32
+ message: "License",
33
+ options: [
34
+ { value: "MIT", label: "MIT" },
35
+ { value: "Apache-2.0", label: "Apache 2.0" },
36
+ { value: "ISC", label: "ISC" },
37
+ { value: "UNLICENSED", label: "Unlicensed (private)" }
38
+ ]
39
+ })
40
+ },
41
+ {
42
+ onCancel: () => {
43
+ p.cancel("Plugin creation cancelled.");
44
+ process.exit(0);
45
+ }
46
+ }
47
+ );
48
+ const pluginName = result.name.trim();
49
+ const dirName = pluginName.replace(/^@[^/]+\//, "");
50
+ const targetDir = path.resolve(process.cwd(), dirName);
51
+ if (fs.existsSync(targetDir)) {
52
+ p.cancel(`Directory "${dirName}" already exists.`);
53
+ process.exit(1);
54
+ }
55
+ const spinner2 = p.spinner();
56
+ spinner2.start("Scaffolding plugin...");
57
+ fs.mkdirSync(path.join(targetDir, "src", "__tests__"), { recursive: true });
58
+ let cliVersion = "0.6.10";
59
+ try {
60
+ const require2 = createRequire(import.meta.url);
61
+ const rootPkg = require2("../../../package.json");
62
+ cliVersion = rootPkg.version ?? cliVersion;
63
+ } catch {
64
+ }
65
+ const packageJson = {
66
+ name: pluginName,
67
+ version: "0.1.0",
68
+ description: result.description || "",
69
+ type: "module",
70
+ main: "dist/index.js",
71
+ types: "dist/index.d.ts",
72
+ scripts: {
73
+ build: "tsc",
74
+ dev: "tsc --watch",
75
+ test: "vitest",
76
+ prepublishOnly: "npm run build"
77
+ },
78
+ author: result.author || "",
79
+ license: result.license,
80
+ keywords: ["openacp", "openacp-plugin"],
81
+ peerDependencies: {
82
+ "@openacp/cli": `>=${cliVersion}`
83
+ },
84
+ devDependencies: {
85
+ "@openacp/plugin-sdk": cliVersion,
86
+ typescript: "^5.4.0",
87
+ vitest: "^3.0.0"
88
+ }
89
+ };
90
+ fs.writeFileSync(
91
+ path.join(targetDir, "package.json"),
92
+ JSON.stringify(packageJson, null, 2) + "\n"
93
+ );
94
+ const tsconfig = {
95
+ compilerOptions: {
96
+ target: "ES2022",
97
+ module: "NodeNext",
98
+ moduleResolution: "NodeNext",
99
+ declaration: true,
100
+ outDir: "dist",
101
+ rootDir: "src",
102
+ strict: true,
103
+ esModuleInterop: true,
104
+ skipLibCheck: true,
105
+ forceConsistentCasingInFileNames: true
106
+ },
107
+ include: ["src"],
108
+ exclude: ["node_modules", "dist", "src/**/__tests__"]
109
+ };
110
+ fs.writeFileSync(
111
+ path.join(targetDir, "tsconfig.json"),
112
+ JSON.stringify(tsconfig, null, 2) + "\n"
113
+ );
114
+ fs.writeFileSync(
115
+ path.join(targetDir, ".gitignore"),
116
+ ["node_modules/", "dist/", "*.tsbuildinfo", ".DS_Store", ""].join("\n")
117
+ );
118
+ fs.writeFileSync(
119
+ path.join(targetDir, ".npmignore"),
120
+ ["src/", "tsconfig.json", ".editorconfig", ".gitignore", "*.test.ts", "__tests__/", ""].join("\n")
121
+ );
122
+ fs.writeFileSync(
123
+ path.join(targetDir, ".editorconfig"),
124
+ [
125
+ "root = true",
126
+ "",
127
+ "[*]",
128
+ "indent_style = space",
129
+ "indent_size = 2",
130
+ "end_of_line = lf",
131
+ "charset = utf-8",
132
+ "trim_trailing_whitespace = true",
133
+ "insert_final_newline = true",
134
+ ""
135
+ ].join("\n")
136
+ );
137
+ fs.writeFileSync(
138
+ path.join(targetDir, "README.md"),
139
+ [
140
+ `# ${pluginName}`,
141
+ "",
142
+ result.description || "An OpenACP plugin.",
143
+ "",
144
+ "## Installation",
145
+ "",
146
+ "```bash",
147
+ `openacp plugin add ${pluginName}`,
148
+ "```",
149
+ "",
150
+ "## Development",
151
+ "",
152
+ "```bash",
153
+ "npm install",
154
+ "npm run build",
155
+ "npm test",
156
+ "",
157
+ "# Live development with hot-reload:",
158
+ `openacp dev .`,
159
+ "```",
160
+ "",
161
+ "## License",
162
+ "",
163
+ result.license,
164
+ ""
165
+ ].join("\n")
166
+ );
167
+ const pluginVarName = dirName.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
168
+ fs.writeFileSync(
169
+ path.join(targetDir, "src", "index.ts"),
170
+ `import type { OpenACPPlugin, PluginContext, InstallContext, MigrateContext } from '@openacp/plugin-sdk'
171
+
172
+ const plugin: OpenACPPlugin = {
173
+ name: '${pluginName}',
174
+ version: '0.1.0',
175
+ description: '${(result.description || "").replace(/'/g, "\\'")}',
176
+
177
+ // Declare which permissions your plugin needs.
178
+ // Available: events:read, events:emit, services:register, services:use,
179
+ // middleware:register, commands:register, storage:read, storage:write, kernel:access
180
+ permissions: ['events:read', 'services:register'],
181
+
182
+ // Dependencies on other plugins (loaded before this one).
183
+ // pluginDependencies: { '@openacp/security': '>=1.0.0' },
184
+
185
+ // Optional dependencies (used if available, gracefully degrade if not).
186
+ // optionalPluginDependencies: { '@openacp/usage': '>=1.0.0' },
187
+
188
+ /**
189
+ * Called during server startup in dependency order.
190
+ * Register services, middleware, commands, and event listeners here.
191
+ */
192
+ async setup(ctx: PluginContext): Promise<void> {
193
+ ctx.log.info('Plugin setup started')
194
+
195
+ // Example: register a service
196
+ // ctx.registerService('my-service', myServiceImpl)
197
+
198
+ // Example: listen to events
199
+ // ctx.on('session:created', (event) => { ... })
200
+
201
+ // Example: register a slash command
202
+ // ctx.registerCommand({
203
+ // name: 'mycommand',
204
+ // description: 'Does something useful',
205
+ // category: 'plugin',
206
+ // async handler(args) {
207
+ // return { type: 'text', text: 'Hello from ${pluginName}!' }
208
+ // },
209
+ // })
210
+
211
+ ctx.log.info('Plugin setup complete')
212
+ },
213
+
214
+ /**
215
+ * Called during server shutdown in reverse dependency order.
216
+ * Clean up resources, close connections, stop timers here.
217
+ * Has a 10-second timeout.
218
+ */
219
+ async teardown(): Promise<void> {
220
+ // Clean up resources here
221
+ },
222
+
223
+ /**
224
+ * Called when user runs \`openacp plugin add ${pluginName}\`.
225
+ * Use ctx.terminal for interactive prompts to gather configuration.
226
+ */
227
+ async install(ctx: InstallContext): Promise<void> {
228
+ ctx.terminal.log.info('Installing ${pluginName}...')
229
+
230
+ // Example: prompt for configuration
231
+ // const apiKey = await ctx.terminal.text({
232
+ // message: 'Enter your API key',
233
+ // validate: (v) => v.length === 0 ? 'Required' : undefined,
234
+ // })
235
+ // await ctx.settings.set('apiKey', apiKey)
236
+
237
+ ctx.terminal.log.success('Installation complete!')
238
+ },
239
+
240
+ /**
241
+ * Called when user runs \`openacp plugin configure ${pluginName}\`.
242
+ * Re-run configuration prompts to update settings.
243
+ */
244
+ async configure(ctx: InstallContext): Promise<void> {
245
+ ctx.terminal.log.info('Configuring ${pluginName}...')
246
+
247
+ // Re-run configuration prompts, pre-filling with current values
248
+ // const current = await ctx.settings.getAll()
249
+ // ...
250
+
251
+ ctx.terminal.log.success('Configuration updated!')
252
+ },
253
+
254
+ /**
255
+ * Called during boot when the plugin version has changed.
256
+ * Migrate settings from the old format to the new format.
257
+ */
258
+ async migrate(ctx: MigrateContext, oldSettings: unknown, oldVersion: string): Promise<unknown> {
259
+ ctx.log.info(\`Migrating from v\${oldVersion}\`)
260
+ // Return the migrated settings object
261
+ return oldSettings
262
+ },
263
+
264
+ /**
265
+ * Called when user runs \`openacp plugin remove ${pluginName}\`.
266
+ * Clean up any external resources. If opts.purge is true, delete all data.
267
+ */
268
+ async uninstall(ctx: InstallContext, opts: { purge: boolean }): Promise<void> {
269
+ ctx.terminal.log.info('Uninstalling ${pluginName}...')
270
+ if (opts.purge) {
271
+ await ctx.settings.clear()
272
+ }
273
+ ctx.terminal.log.success('Uninstalled!')
274
+ },
275
+ }
276
+
277
+ export default plugin
278
+ `
279
+ );
280
+ fs.writeFileSync(
281
+ path.join(targetDir, "src", "__tests__", "index.test.ts"),
282
+ `import { describe, it, expect } from 'vitest'
283
+ import { createTestContext } from '@openacp/plugin-sdk/testing'
284
+ import plugin from '../index.js'
285
+
286
+ describe('${pluginName}', () => {
287
+ it('has correct metadata', () => {
288
+ expect(plugin.name).toBe('${pluginName}')
289
+ expect(plugin.version).toBeDefined()
290
+ expect(plugin.setup).toBeInstanceOf(Function)
291
+ })
292
+
293
+ it('sets up without errors', async () => {
294
+ const ctx = createTestContext({ pluginName: '${pluginName}' })
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 = createTestContext({ pluginName: '${pluginName}' })
307
+ await expect(plugin.install(ctx as any)).resolves.not.toThrow()
308
+ }
309
+ })
310
+ })
311
+ `
312
+ );
313
+ spinner2.stop("Plugin scaffolded!");
314
+ p.note(
315
+ [
316
+ `cd ${dirName}`,
317
+ "npm install",
318
+ "npm run build",
319
+ "npm test",
320
+ "",
321
+ "# Start development with hot-reload:",
322
+ `openacp dev .`
323
+ ].join("\n"),
324
+ "Next steps"
325
+ );
326
+ p.outro(`Plugin ${pluginName} created in ./${dirName}`);
327
+ }
328
+ export {
329
+ cmdPluginCreate
330
+ };
331
+ //# sourceMappingURL=plugin-create-JVCVUG6V.js.map
@@ -0,0 +1 @@
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 { createRequire } from 'node:module'\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 let cliVersion = '0.6.10'\n try {\n const require = createRequire(import.meta.url)\n const rootPkg = require('../../../package.json')\n cliVersion = rootPkg.version ?? cliVersion\n } catch { /* fallback to hardcoded */ }\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 } 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({ pluginName: '${pluginName}' })\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 = createTestContext({ pluginName: '${pluginName}' })\n await expect(plugin.install(ctx as any)).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","require"]}
@@ -0,0 +1,8 @@
1
+ import {
2
+ PluginRegistry
3
+ } from "./chunk-W26AUH5B.js";
4
+ import "./chunk-VUNV25KB.js";
5
+ export {
6
+ PluginRegistry
7
+ };
8
+ //# sourceMappingURL=plugin-registry-WB3DR67H.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  commandExists
3
- } from "./chunk-JKBFUAJK.js";
3
+ } from "./chunk-ZSLHHQPQ.js";
4
4
  import {
5
5
  createChildLogger
6
- } from "./chunk-GAK6PIBW.js";
6
+ } from "./chunk-XMMAGAT4.js";
7
7
  import "./chunk-VUNV25KB.js";
8
8
 
9
- // src/core/post-upgrade.ts
9
+ // src/cli/post-upgrade.ts
10
10
  var log = createChildLogger({ module: "post-upgrade" });
11
11
  async function runPostUpgradeChecks(config) {
12
12
  if (config.tunnel.enabled) {
13
13
  if (config.tunnel.provider === "cloudflare") {
14
14
  try {
15
- const { ensureCloudflared } = await import("./install-cloudflared-Z7VCGOVG.js");
15
+ const { ensureCloudflared } = await import("./install-cloudflared-AN24L4DP.js");
16
16
  await ensureCloudflared();
17
17
  } catch (err) {
18
18
  log.warn(
@@ -29,7 +29,7 @@ async function runPostUpgradeChecks(config) {
29
29
  }
30
30
  }
31
31
  try {
32
- const { getIntegration } = await import("./integrate-PNEHRY2I.js");
32
+ const { getIntegration } = await import("./integrate-5C6KSU6D.js");
33
33
  const integration = getIntegration("claude");
34
34
  if (integration) {
35
35
  const allInstalled = integration.items.every((item) => item.isInstalled());
@@ -41,7 +41,7 @@ async function runPostUpgradeChecks(config) {
41
41
  const handoff = integration.items.find((i) => i.id === "handoff");
42
42
  if (handoff?.isInstalled() && !commandExists("jq")) {
43
43
  try {
44
- const { ensureJq } = await import("./install-jq-HUYSQWKR.js");
44
+ const { ensureJq } = await import("./install-jq-CRVDJGF3.js");
45
45
  await ensureJq();
46
46
  } catch (err) {
47
47
  log.warn(
@@ -59,7 +59,7 @@ async function runPostUpgradeChecks(config) {
59
59
  );
60
60
  }
61
61
  try {
62
- const { AgentStore } = await import("./agent-store-VZLFPTZU.js");
62
+ const { AgentStore } = await import("./agent-store-VSHNY5GT.js");
63
63
  const store = new AgentStore();
64
64
  store.load();
65
65
  const entries = store.getInstalled();
@@ -77,4 +77,4 @@ async function runPostUpgradeChecks(config) {
77
77
  export {
78
78
  runPostUpgradeChecks
79
79
  };
80
- //# sourceMappingURL=post-upgrade-CJG5I7M2.js.map
80
+ //# sourceMappingURL=post-upgrade-XLHZ6ZB7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/cli/post-upgrade.ts"],"sourcesContent":["import { createChildLogger } from \"../core/utils/log.js\";\nimport { commandExists } from \"../core/agents/agent-dependencies.js\";\nimport type { Config } from \"../core/config/config.js\";\n\nconst log = createChildLogger({ module: \"post-upgrade\" });\n\n/**\n * Post-upgrade dependency check — runs on every start.\n * Centralized source of truth for all binary dependency management.\n * Silent if everything is OK.\n */\nexport async function runPostUpgradeChecks(config: Config): Promise<void> {\n // 1. Tunnel provider binary\n if (config.tunnel.enabled) {\n if (config.tunnel.provider === \"cloudflare\") {\n try {\n const { ensureCloudflared } = await import(\n \"../plugins/tunnel/providers/install-cloudflared.js\"\n );\n await ensureCloudflared();\n } catch (err) {\n log.warn(\n { err: (err as Error).message },\n \"Could not install cloudflared. Tunnel may not work.\",\n );\n }\n } else {\n if (!commandExists(config.tunnel.provider)) {\n log.warn(\n `Tunnel provider \"${config.tunnel.provider}\" is not installed. Install it or switch to cloudflare (free, auto-installed).`,\n );\n }\n }\n }\n\n // 2. Claude CLI integration + jq\n try {\n const { getIntegration } = await import(\"./integrate.js\");\n const integration = getIntegration(\"claude\");\n if (integration) {\n const allInstalled = integration.items.every((item) => item.isInstalled());\n if (!allInstalled) {\n log.info(\n 'Claude CLI integration not installed. Run \"openacp integrate claude\" for session transfer + tunnel skill.',\n );\n }\n\n const handoff = integration.items.find((i) => i.id === \"handoff\");\n if (handoff?.isInstalled() && !commandExists(\"jq\")) {\n try {\n const { ensureJq } = await import(\"../core/utils/install-jq.js\");\n await ensureJq();\n } catch (err) {\n log.warn(\n { err: (err as Error).message },\n \"Could not install jq. Handoff hooks may not work.\",\n );\n }\n }\n }\n } catch {\n // integrate module not available — skip\n }\n\n // 3. unzip (needed for binary agent installs)\n if (!commandExists(\"unzip\")) {\n log.warn(\n \"unzip is not installed. Some agent installations (binary distribution) may fail. Install: brew install unzip (macOS) or apt install unzip (Linux)\",\n );\n }\n\n // 4. uvx (needed for Python-based agents)\n try {\n const { AgentStore } = await import(\"../core/agents/agent-store.js\");\n const store = new AgentStore();\n store.load();\n const entries = store.getInstalled();\n const hasUvxAgent = Object.values(entries).some(\n (a: { distribution?: string }) => a.distribution === \"uvx\",\n );\n if (hasUvxAgent && !commandExists(\"uvx\")) {\n log.warn(\n \"uvx is not installed but you have Python-based agents. Install: pip install uv\",\n );\n }\n } catch {\n // skip\n }\n}\n"],"mappings":";;;;;;;;;AAIA,IAAM,MAAM,kBAAkB,EAAE,QAAQ,eAAe,CAAC;AAOxD,eAAsB,qBAAqB,QAA+B;AAExE,MAAI,OAAO,OAAO,SAAS;AACzB,QAAI,OAAO,OAAO,aAAa,cAAc;AAC3C,UAAI;AACF,cAAM,EAAE,kBAAkB,IAAI,MAAM,OAClC,mCACF;AACA,cAAM,kBAAkB;AAAA,MAC1B,SAAS,KAAK;AACZ,YAAI;AAAA,UACF,EAAE,KAAM,IAAc,QAAQ;AAAA,UAC9B;AAAA,QACF;AAAA,MACF;AAAA,IACF,OAAO;AACL,UAAI,CAAC,cAAc,OAAO,OAAO,QAAQ,GAAG;AAC1C,YAAI;AAAA,UACF,oBAAoB,OAAO,OAAO,QAAQ;AAAA,QAC5C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI;AACF,UAAM,EAAE,eAAe,IAAI,MAAM,OAAO,yBAAgB;AACxD,UAAM,cAAc,eAAe,QAAQ;AAC3C,QAAI,aAAa;AACf,YAAM,eAAe,YAAY,MAAM,MAAM,CAAC,SAAS,KAAK,YAAY,CAAC;AACzE,UAAI,CAAC,cAAc;AACjB,YAAI;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,UAAU,YAAY,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,SAAS;AAChE,UAAI,SAAS,YAAY,KAAK,CAAC,cAAc,IAAI,GAAG;AAClD,YAAI;AACF,gBAAM,EAAE,SAAS,IAAI,MAAM,OAAO,0BAA6B;AAC/D,gBAAM,SAAS;AAAA,QACjB,SAAS,KAAK;AACZ,cAAI;AAAA,YACF,EAAE,KAAM,IAAc,QAAQ;AAAA,YAC9B;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AAGA,MAAI,CAAC,cAAc,OAAO,GAAG;AAC3B,QAAI;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI;AACF,UAAM,EAAE,WAAW,IAAI,MAAM,OAAO,2BAA+B;AACnE,UAAM,QAAQ,IAAI,WAAW;AAC7B,UAAM,KAAK;AACX,UAAM,UAAU,MAAM,aAAa;AACnC,UAAM,cAAc,OAAO,OAAO,OAAO,EAAE;AAAA,MACzC,CAAC,MAAiC,EAAE,iBAAiB;AAAA,IACvD;AACA,QAAI,eAAe,CAAC,cAAc,KAAK,GAAG;AACxC,UAAI;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACF;","names":[]}
@@ -0,0 +1,8 @@
1
+ import {
2
+ readTextFileWithRange
3
+ } from "./chunk-OYSAN7UX.js";
4
+ import "./chunk-VUNV25KB.js";
5
+ export {
6
+ readTextFileWithRange
7
+ };
8
+ //# sourceMappingURL=read-text-file-IRZM3QLM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,9 @@
1
+ import {
2
+ security_default
3
+ } from "./chunk-5OCGO27U.js";
4
+ import "./chunk-LGFWH3AE.js";
5
+ import "./chunk-VUNV25KB.js";
6
+ export {
7
+ security_default as default
8
+ };
9
+ //# sourceMappingURL=security-YNRBW6S7.js.map