@xopcai/xopc 0.0.6 → 0.0.11

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 (412) hide show
  1. package/dist/extensions/weixin/src/api/api.js +1 -1
  2. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  3. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  4. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  5. package/dist/gateway/static/root/assets/{agents-B6s2BvpH.js → agents-BdC4Y-HX.js} +2 -2
  6. package/dist/gateway/static/root/assets/agents-BdC4Y-HX.js.map +1 -0
  7. package/dist/gateway/static/root/assets/{apps-page-BtsZ5ZPx.js → apps-page-C-oaSHkm.js} +2 -2
  8. package/dist/gateway/static/root/assets/{apps-page-BtsZ5ZPx.js.map → apps-page-C-oaSHkm.js.map} +1 -1
  9. package/dist/gateway/static/root/assets/attachment-load-BDDlItdE.js +1 -0
  10. package/dist/gateway/static/root/assets/{channels-settings-BUfWBEVU.js → channels-settings-BqEUppPO.js} +2 -2
  11. package/dist/gateway/static/root/assets/{channels-settings-BUfWBEVU.js.map → channels-settings-BqEUppPO.js.map} +1 -1
  12. package/dist/gateway/static/root/assets/{chat-agents-api-BR30M2YQ.js → chat-agents-api-BhqjQ7iL.js} +2 -2
  13. package/dist/gateway/static/root/assets/{chat-agents-api-BR30M2YQ.js.map → chat-agents-api-BhqjQ7iL.js.map} +1 -1
  14. package/dist/gateway/static/root/assets/{cron-page-CMTx0Mjz.js → cron-page-Cli49RKR.js} +2 -2
  15. package/dist/gateway/static/root/assets/{cron-page-CMTx0Mjz.js.map → cron-page-Cli49RKR.js.map} +1 -1
  16. package/dist/gateway/static/root/assets/{cron-utils-BJma9IcD.js → cron-utils-Dkj-Ldpf.js} +2 -2
  17. package/dist/gateway/static/root/assets/{cron-utils-BJma9IcD.js.map → cron-utils-Dkj-Ldpf.js.map} +1 -1
  18. package/dist/gateway/static/root/assets/electron-env-BDtJw9AY.js +2 -0
  19. package/dist/gateway/static/root/assets/electron-env-BDtJw9AY.js.map +1 -0
  20. package/dist/gateway/static/root/assets/{extension-debug-page-BCVoNSo6.js → extension-debug-page-BMcZlaxF.js} +2 -2
  21. package/dist/gateway/static/root/assets/{extension-debug-page-BCVoNSo6.js.map → extension-debug-page-BMcZlaxF.js.map} +1 -1
  22. package/dist/gateway/static/root/assets/{extension-iframe-host-PWB-Pw2d.js → extension-iframe-host-D5HEF0KR.js} +2 -2
  23. package/dist/gateway/static/root/assets/{extension-iframe-host-PWB-Pw2d.js.map → extension-iframe-host-D5HEF0KR.js.map} +1 -1
  24. package/dist/gateway/static/root/assets/{extension-page-D2tTklsD.js → extension-page-CXdCSSPl.js} +2 -2
  25. package/dist/gateway/static/root/assets/{extension-page-D2tTklsD.js.map → extension-page-CXdCSSPl.js.map} +1 -1
  26. package/dist/gateway/static/root/assets/{extension-provider-BpHodVRj.js → extension-provider-DZCZgQE2.js} +2 -2
  27. package/dist/gateway/static/root/assets/{extension-provider-BpHodVRj.js.map → extension-provider-DZCZgQE2.js.map} +1 -1
  28. package/dist/gateway/static/root/assets/{extension-settings-page-BEu6Xw1Z.js → extension-settings-page-CX6STpx3.js} +2 -2
  29. package/dist/gateway/static/root/assets/{extension-settings-page-BEu6Xw1Z.js.map → extension-settings-page-CX6STpx3.js.map} +1 -1
  30. package/dist/gateway/static/root/assets/{gateway-config-swr-C7ZFPhNj.js → gateway-config-swr-Cph02QZn.js} +2 -2
  31. package/dist/gateway/static/root/assets/{gateway-config-swr-C7ZFPhNj.js.map → gateway-config-swr-Cph02QZn.js.map} +1 -1
  32. package/dist/gateway/static/root/assets/index-Bty3m0mS.css +2 -0
  33. package/dist/gateway/static/root/assets/index-iTUyfzNr.js +16 -0
  34. package/dist/gateway/static/root/assets/index-iTUyfzNr.js.map +1 -0
  35. package/dist/gateway/static/root/assets/{logs-page-BpsxYdcL.js → logs-page-B9O5l3I8.js} +2 -2
  36. package/dist/gateway/static/root/assets/{logs-page-BpsxYdcL.js.map → logs-page-B9O5l3I8.js.map} +1 -1
  37. package/dist/gateway/static/root/assets/{model-selector-BiiDq8Pk.js → model-selector-BLiY_O25.js} +2 -2
  38. package/dist/gateway/static/root/assets/{model-selector-BiiDq8Pk.js.map → model-selector-BLiY_O25.js.map} +1 -1
  39. package/dist/gateway/static/root/assets/navigation-DB9S-C6S.js +2 -0
  40. package/dist/gateway/static/root/assets/navigation-DB9S-C6S.js.map +1 -0
  41. package/dist/gateway/static/root/assets/page-header-store-BFpnFTed.js +2 -0
  42. package/dist/gateway/static/root/assets/{page-header-store-HcRZK5CZ.js.map → page-header-store-BFpnFTed.js.map} +1 -1
  43. package/dist/gateway/static/root/assets/{session-api-DxNaAkmX.js → session-api-DEhQXWJg.js} +2 -2
  44. package/dist/gateway/static/root/assets/{session-api-DxNaAkmX.js.map → session-api-DEhQXWJg.js.map} +1 -1
  45. package/dist/gateway/static/root/assets/{session-working-directory-control-CDH-Wk4E.js → session-working-directory-control-DKOtWs3-.js} +3 -3
  46. package/dist/gateway/static/root/assets/{session-working-directory-control-CDH-Wk4E.js.map → session-working-directory-control-DKOtWs3-.js.map} +1 -1
  47. package/dist/gateway/static/root/assets/{sessions-page-5PK75r1n.js → sessions-page-BYlWP1ep.js} +2 -2
  48. package/dist/gateway/static/root/assets/{sessions-page-5PK75r1n.js.map → sessions-page-BYlWP1ep.js.map} +1 -1
  49. package/dist/gateway/static/root/assets/settings-page-oCnIavdg.js +2 -0
  50. package/dist/gateway/static/root/assets/settings-page-oCnIavdg.js.map +1 -0
  51. package/dist/gateway/static/root/assets/{skill-api-CxbNlOD_.js → skill-api-DWrn8Az0.js} +2 -2
  52. package/dist/gateway/static/root/assets/{skill-api-CxbNlOD_.js.map → skill-api-DWrn8Az0.js.map} +1 -1
  53. package/dist/gateway/static/root/assets/{skills-page-Dd8ZzYJb.js → skills-page-C59WQpM1.js} +2 -2
  54. package/dist/gateway/static/root/assets/{skills-page-Dd8ZzYJb.js.map → skills-page-C59WQpM1.js.map} +1 -1
  55. package/dist/gateway/static/root/assets/{theme-store-CPTH77BE.js → theme-store-CywXkKml.js} +2 -2
  56. package/dist/gateway/static/root/assets/{theme-store-CPTH77BE.js.map → theme-store-CywXkKml.js.map} +1 -1
  57. package/dist/gateway/static/root/assets/url-D7yWllI8.js +2 -0
  58. package/dist/gateway/static/root/assets/url-D7yWllI8.js.map +1 -0
  59. package/dist/gateway/static/root/assets/{useTranslation-BEUWOMuh.js → useTranslation-CACj0DBJ.js} +2 -2
  60. package/dist/gateway/static/root/assets/{useTranslation-BEUWOMuh.js.map → useTranslation-CACj0DBJ.js.map} +1 -1
  61. package/dist/gateway/static/root/index.html +16 -16
  62. package/dist/package.js +1 -1
  63. package/dist/src/agent/agent-manager.d.ts +1 -0
  64. package/dist/src/agent/agent-manager.js +17 -9
  65. package/dist/src/agent/agent-manager.js.map +1 -1
  66. package/dist/src/agent/background-review/run-background-review.js +2 -0
  67. package/dist/src/agent/background-review/run-background-review.js.map +1 -1
  68. package/dist/src/agent/child-agent-factory.js +2 -0
  69. package/dist/src/agent/child-agent-factory.js.map +1 -1
  70. package/dist/src/agent/context/expand-at-file-mentions.d.ts +4 -0
  71. package/dist/src/agent/context/expand-at-file-mentions.js +69 -0
  72. package/dist/src/agent/context/expand-at-file-mentions.js.map +1 -0
  73. package/dist/src/agent/context/workspace-seed.js +1 -1
  74. package/dist/src/agent/image/index.d.ts +0 -1
  75. package/dist/src/agent/image/index.js +1 -2
  76. package/dist/src/agent/image/understanding/pi-ai-provider.js.map +1 -1
  77. package/dist/src/agent/ipc/inbox.js +1 -1
  78. package/dist/src/agent/ipc/socket.js +1 -1
  79. package/dist/src/agent/memory/compaction.d.ts +1 -1
  80. package/dist/src/agent/memory/compaction.js +38 -11
  81. package/dist/src/agent/memory/compaction.js.map +1 -1
  82. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  83. package/dist/src/agent/messaging/command-handler.d.ts +13 -0
  84. package/dist/src/agent/messaging/command-handler.js +14 -2
  85. package/dist/src/agent/messaging/command-handler.js.map +1 -1
  86. package/dist/src/agent/orchestration/agent-orchestrator.js +6 -1
  87. package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
  88. package/dist/src/agent/service.d.ts +16 -1
  89. package/dist/src/agent/service.js +175 -17
  90. package/dist/src/agent/service.js.map +1 -1
  91. package/dist/src/agent/skills/format-skills-prompt.js.map +1 -1
  92. package/dist/src/agent/skills/hub-hash.js +1 -1
  93. package/dist/src/agent/skills/hub-pull.js +1 -1
  94. package/dist/src/agent/skills/scanner.js +1 -1
  95. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  96. package/dist/src/agent/skills/skill-manage-ops.js.map +1 -1
  97. package/dist/src/agent/tools/browser/tools.js +2 -2
  98. package/dist/src/agent/tools/browser/tools.js.map +1 -1
  99. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  100. package/dist/src/agent/tools/image-tool.js +2 -2
  101. package/dist/src/agent/tools/image-tool.js.map +1 -1
  102. package/dist/src/agent/tools/index.d.ts +1 -1
  103. package/dist/src/agent/tools/index.js +2 -2
  104. package/dist/src/agent/tools/read.d.ts +0 -2
  105. package/dist/src/agent/tools/read.js +1 -3
  106. package/dist/src/agent/tools/read.js.map +1 -1
  107. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  108. package/dist/src/agent/tools/write.js +1 -1
  109. package/dist/src/auth/credentials.js +2 -2
  110. package/dist/src/channels/attachments/inbound-persist.js +1 -1
  111. package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
  112. package/dist/src/channels/index.d.ts +1 -1
  113. package/dist/src/channels/index.js +2 -2
  114. package/dist/src/channels/pipeline.d.ts +8 -1
  115. package/dist/src/channels/pipeline.js +49 -4
  116. package/dist/src/channels/pipeline.js.map +1 -1
  117. package/dist/src/channels/plugin-types.d.ts +14 -0
  118. package/dist/src/chat-commands/builtins/config.d.ts +4 -0
  119. package/dist/src/chat-commands/builtins/config.js +197 -0
  120. package/dist/src/chat-commands/builtins/config.js.map +1 -0
  121. package/dist/src/chat-commands/builtins/context.d.ts +4 -0
  122. package/dist/src/chat-commands/builtins/context.js +44 -0
  123. package/dist/src/chat-commands/builtins/context.js.map +1 -0
  124. package/dist/src/chat-commands/builtins/session.js +111 -0
  125. package/dist/src/chat-commands/builtins/session.js.map +1 -1
  126. package/dist/src/chat-commands/builtins/thinking.js +49 -21
  127. package/dist/src/chat-commands/builtins/thinking.js.map +1 -1
  128. package/dist/src/chat-commands/config-paths.d.ts +10 -0
  129. package/dist/src/chat-commands/config-paths.js +45 -0
  130. package/dist/src/chat-commands/config-paths.js.map +1 -0
  131. package/dist/src/chat-commands/config-value.d.ts +12 -0
  132. package/dist/src/chat-commands/config-value.js +53 -0
  133. package/dist/src/chat-commands/config-value.js.map +1 -0
  134. package/dist/src/chat-commands/context.d.ts +24 -1
  135. package/dist/src/chat-commands/context.js +41 -0
  136. package/dist/src/chat-commands/context.js.map +1 -1
  137. package/dist/src/chat-commands/index.d.ts +2 -0
  138. package/dist/src/chat-commands/index.js +5 -1
  139. package/dist/src/chat-commands/index.js.map +1 -1
  140. package/dist/src/chat-commands/types.d.ts +33 -1
  141. package/dist/src/cli/commands/agent/interactive.js +1 -1
  142. package/dist/src/cli/commands/agent/interactive.js.map +1 -1
  143. package/dist/src/cli/commands/agent.js +21 -9
  144. package/dist/src/cli/commands/agent.js.map +1 -1
  145. package/dist/src/cli/commands/auth.js.map +1 -1
  146. package/dist/src/cli/commands/doctor/checks/channel-config.d.ts +2 -0
  147. package/dist/src/cli/commands/doctor/checks/channel-config.js +113 -0
  148. package/dist/src/cli/commands/doctor/checks/channel-config.js.map +1 -0
  149. package/dist/src/cli/commands/doctor/checks/channel-plugins.d.ts +2 -0
  150. package/dist/src/cli/commands/doctor/checks/channel-plugins.js +47 -0
  151. package/dist/src/cli/commands/doctor/checks/channel-plugins.js.map +1 -0
  152. package/dist/src/cli/commands/doctor/checks/config-health.d.ts +2 -0
  153. package/dist/src/cli/commands/doctor/checks/config-health.js +82 -0
  154. package/dist/src/cli/commands/doctor/checks/config-health.js.map +1 -0
  155. package/dist/src/cli/commands/doctor/checks/cron-health.d.ts +2 -0
  156. package/dist/src/cli/commands/doctor/checks/cron-health.js +116 -0
  157. package/dist/src/cli/commands/doctor/checks/cron-health.js.map +1 -0
  158. package/dist/src/cli/commands/doctor/checks/gateway-health.d.ts +2 -0
  159. package/dist/src/cli/commands/doctor/checks/gateway-health.js +64 -0
  160. package/dist/src/cli/commands/doctor/checks/gateway-health.js.map +1 -0
  161. package/dist/src/cli/commands/doctor/checks/gateway-service.d.ts +2 -0
  162. package/dist/src/cli/commands/doctor/checks/gateway-service.js +64 -0
  163. package/dist/src/cli/commands/doctor/checks/gateway-service.js.map +1 -0
  164. package/dist/src/cli/commands/doctor/checks/node-version.d.ts +2 -0
  165. package/dist/src/cli/commands/doctor/checks/node-version.js +33 -0
  166. package/dist/src/cli/commands/doctor/checks/node-version.js.map +1 -0
  167. package/dist/src/cli/commands/doctor/checks/provider-auth.d.ts +2 -0
  168. package/dist/src/cli/commands/doctor/checks/provider-auth.js +91 -0
  169. package/dist/src/cli/commands/doctor/checks/provider-auth.js.map +1 -0
  170. package/dist/src/cli/commands/doctor/checks/security-audit.d.ts +2 -0
  171. package/dist/src/cli/commands/doctor/checks/security-audit.js +85 -0
  172. package/dist/src/cli/commands/doctor/checks/security-audit.js.map +1 -0
  173. package/dist/src/cli/commands/doctor/checks/session-integrity.d.ts +2 -0
  174. package/dist/src/cli/commands/doctor/checks/session-integrity.js +118 -0
  175. package/dist/src/cli/commands/doctor/checks/session-integrity.js.map +1 -0
  176. package/dist/src/cli/commands/doctor/checks/state-integrity.d.ts +2 -0
  177. package/dist/src/cli/commands/doctor/checks/state-integrity.js +99 -0
  178. package/dist/src/cli/commands/doctor/checks/state-integrity.js.map +1 -0
  179. package/dist/src/cli/commands/doctor/checks/version-check.d.ts +2 -0
  180. package/dist/src/cli/commands/doctor/checks/version-check.js +71 -0
  181. package/dist/src/cli/commands/doctor/checks/version-check.js.map +1 -0
  182. package/dist/src/cli/commands/doctor/checks/workspace-status.d.ts +2 -0
  183. package/dist/src/cli/commands/doctor/checks/workspace-status.js +73 -0
  184. package/dist/src/cli/commands/doctor/checks/workspace-status.js.map +1 -0
  185. package/dist/src/cli/commands/doctor/flow.d.ts +9 -0
  186. package/dist/src/cli/commands/doctor/flow.js +51 -0
  187. package/dist/src/cli/commands/doctor/flow.js.map +1 -0
  188. package/dist/src/cli/commands/doctor/format.d.ts +6 -0
  189. package/dist/src/cli/commands/doctor/format.js +61 -0
  190. package/dist/src/cli/commands/doctor/format.js.map +1 -0
  191. package/dist/src/cli/commands/doctor/index.js +44 -0
  192. package/dist/src/cli/commands/doctor/index.js.map +1 -0
  193. package/dist/src/cli/commands/doctor/types.d.ts +20 -0
  194. package/dist/src/cli/commands/doctor/types.js +1 -0
  195. package/dist/src/cli/commands/extension.js +10 -0
  196. package/dist/src/cli/commands/extension.js.map +1 -1
  197. package/dist/src/cli/commands/init.js +1 -2
  198. package/dist/src/cli/commands/init.js.map +1 -1
  199. package/dist/src/cli/commands/session/utils.js.map +1 -1
  200. package/dist/src/cli/commands/update.d.ts +1 -0
  201. package/dist/src/cli/commands/update.js +171 -0
  202. package/dist/src/cli/commands/update.js.map +1 -0
  203. package/dist/src/cli/index.d.ts +2 -2
  204. package/dist/src/cli/index.js +4 -2
  205. package/dist/src/cli/index.js.map +1 -1
  206. package/dist/src/cli/utils/init-workspace.js +1 -1
  207. package/dist/src/config/index.d.ts +1 -0
  208. package/dist/src/config/index.js +4 -3
  209. package/dist/src/config/index.js.map +1 -1
  210. package/dist/src/config/loader.js +1 -1
  211. package/dist/src/config/models-json.d.ts +15 -15
  212. package/dist/src/config/paths.js.map +1 -1
  213. package/dist/src/config/profile.js +1 -1
  214. package/dist/src/config/runtime-overrides.d.ts +8 -0
  215. package/dist/src/config/runtime-overrides.js +40 -0
  216. package/dist/src/config/runtime-overrides.js.map +1 -0
  217. package/dist/src/config/schema.d.ts +34 -104
  218. package/dist/src/config/schema.js +18 -39
  219. package/dist/src/config/schema.js.map +1 -1
  220. package/dist/src/cron/persistence.js +1 -1
  221. package/dist/src/cron/run-log-store.js +1 -1
  222. package/dist/src/daemon/launchd.js +2 -2
  223. package/dist/src/daemon/launchd.js.map +1 -1
  224. package/dist/src/daemon/systemd.js +2 -2
  225. package/dist/src/daemon/systemd.js.map +1 -1
  226. package/dist/src/extensions/health.js +1 -1
  227. package/dist/src/extensions/loader.d.ts +1 -1
  228. package/dist/src/extensions/loader.js +5 -8
  229. package/dist/src/extensions/loader.js.map +1 -1
  230. package/dist/src/extensions/lockfile.js +1 -1
  231. package/dist/src/extensions/sdk/index.js +6 -1
  232. package/dist/src/extensions/sdk/index.js.map +1 -0
  233. package/dist/src/gateway/agents-admin.js +1 -1
  234. package/dist/src/gateway/agents-admin.js.map +1 -1
  235. package/dist/src/gateway/hono/lib/static-ui.js +1 -1
  236. package/dist/src/gateway/hono/oauth.js +1 -1
  237. package/dist/src/gateway/hono/routes/config.js +1 -1
  238. package/dist/src/gateway/hono/routes/doctor.d.ts +3 -0
  239. package/dist/src/gateway/hono/routes/doctor.js +35 -0
  240. package/dist/src/gateway/hono/routes/doctor.js.map +1 -0
  241. package/dist/src/gateway/hono/routes/index.js +4 -0
  242. package/dist/src/gateway/hono/routes/index.js.map +1 -1
  243. package/dist/src/gateway/hono/routes/models.js +64 -11
  244. package/dist/src/gateway/hono/routes/models.js.map +1 -1
  245. package/dist/src/gateway/hono/routes/public-gateway.js +10 -0
  246. package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
  247. package/dist/src/gateway/hono/routes/update.d.ts +3 -0
  248. package/dist/src/gateway/hono/routes/update.js +141 -0
  249. package/dist/src/gateway/hono/routes/update.js.map +1 -0
  250. package/dist/src/gateway/hono/routes/workspace.js +82 -2
  251. package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
  252. package/dist/src/gateway/lock.js +1 -1
  253. package/dist/src/gateway/ports.js +98 -3
  254. package/dist/src/gateway/ports.js.map +1 -1
  255. package/dist/src/gateway/service.d.ts +1 -4
  256. package/dist/src/gateway/service.js +13 -20
  257. package/dist/src/gateway/service.js.map +1 -1
  258. package/dist/src/gateway/workspace-fs-file-list.d.ts +5 -0
  259. package/dist/src/gateway/workspace-fs-file-list.js +56 -0
  260. package/dist/src/gateway/workspace-fs-file-list.js.map +1 -0
  261. package/dist/src/gateway/workspace-heartbeat-path.js +1 -1
  262. package/dist/src/gateway/workspace-ripgrep.d.ts +5 -0
  263. package/dist/src/gateway/workspace-ripgrep.js +88 -4
  264. package/dist/src/gateway/workspace-ripgrep.js.map +1 -1
  265. package/dist/src/infra/update-channels.d.ts +14 -0
  266. package/dist/src/infra/update-channels.js +30 -0
  267. package/dist/src/infra/update-channels.js.map +1 -0
  268. package/dist/src/infra/update-check.d.ts +53 -0
  269. package/dist/src/infra/update-check.js +155 -0
  270. package/dist/src/infra/update-check.js.map +1 -0
  271. package/dist/src/infra/update-runner.d.ts +18 -0
  272. package/dist/src/infra/update-runner.js +112 -0
  273. package/dist/src/infra/update-runner.js.map +1 -0
  274. package/dist/src/infra/update-startup.d.ts +20 -0
  275. package/dist/src/infra/update-startup.js +246 -0
  276. package/dist/src/infra/update-startup.js.map +1 -0
  277. package/dist/src/providers/extension-stream-bridge.d.ts +3 -0
  278. package/dist/src/providers/extension-stream-bridge.js +239 -0
  279. package/dist/src/providers/extension-stream-bridge.js.map +1 -0
  280. package/dist/src/providers/index.d.ts +7 -2
  281. package/dist/src/providers/index.js +77 -14
  282. package/dist/src/providers/index.js.map +1 -1
  283. package/dist/src/providers/model-registry.js +1 -1
  284. package/dist/src/providers/plugin-registry.js +92 -87
  285. package/dist/src/providers/plugin-registry.js.map +1 -1
  286. package/dist/src/routing/bindings.js +1 -1
  287. package/dist/src/routing/index.d.ts +1 -1
  288. package/dist/src/routing/index.js +2 -2
  289. package/dist/src/routing/index.js.map +1 -1
  290. package/dist/src/routing/resolve-route.js +1 -1
  291. package/dist/src/routing/session-key.d.ts +0 -5
  292. package/dist/src/routing/session-key.js +1 -27
  293. package/dist/src/routing/session-key.js.map +1 -1
  294. package/dist/src/session/chat-export.d.ts +5 -0
  295. package/dist/src/session/chat-export.js +35 -0
  296. package/dist/src/session/chat-export.js.map +1 -0
  297. package/dist/src/session/config-store.js +1 -1
  298. package/dist/src/session/manager.d.ts +1 -1
  299. package/dist/src/session/manager.js +2 -2
  300. package/dist/src/session/manager.js.map +1 -1
  301. package/dist/src/session/store.d.ts +1 -1
  302. package/dist/src/session/store.js +3 -7
  303. package/dist/src/session/store.js.map +1 -1
  304. package/dist/src/session/types.d.ts +0 -10
  305. package/dist/src/session/types.js.map +1 -1
  306. package/dist/src/utils/logger/audit.js +1 -1
  307. package/dist/src/utils/logger/log-store.js +1 -1
  308. package/dist/src/utils/logger/rotation.js +1 -1
  309. package/dist/src/voice/tts/audio.js +1 -1
  310. package/package.json +2 -2
  311. package/dist/gateway/static/root/assets/agents-B6s2BvpH.js.map +0 -1
  312. package/dist/gateway/static/root/assets/attachment-load-6pRlDPZ8.js +0 -1
  313. package/dist/gateway/static/root/assets/index-DBZ5eXW5.js +0 -16
  314. package/dist/gateway/static/root/assets/index-DBZ5eXW5.js.map +0 -1
  315. package/dist/gateway/static/root/assets/index-KsVMH-Jo.css +0 -2
  316. package/dist/gateway/static/root/assets/navigation-BpLKd2Ca.js +0 -2
  317. package/dist/gateway/static/root/assets/navigation-BpLKd2Ca.js.map +0 -1
  318. package/dist/gateway/static/root/assets/page-header-store-HcRZK5CZ.js +0 -2
  319. package/dist/gateway/static/root/assets/preference-select-fields-B4AJBqUY.js +0 -2
  320. package/dist/gateway/static/root/assets/preference-select-fields-B4AJBqUY.js.map +0 -1
  321. package/dist/gateway/static/root/assets/settings-page-BvSj0JqX.js +0 -2
  322. package/dist/gateway/static/root/assets/settings-page-BvSj0JqX.js.map +0 -1
  323. package/dist/gateway/static/root/assets/url-QmwQTJ-j.js +0 -2
  324. package/dist/gateway/static/root/assets/url-QmwQTJ-j.js.map +0 -1
  325. package/dist/src/acp/commands.d.ts +0 -11
  326. package/dist/src/acp/commands.js +0 -17
  327. package/dist/src/acp/commands.js.map +0 -1
  328. package/dist/src/acp/control-plane/identity-reconcile.d.ts +0 -36
  329. package/dist/src/acp/control-plane/identity-reconcile.js +0 -124
  330. package/dist/src/acp/control-plane/identity-reconcile.js.map +0 -1
  331. package/dist/src/acp/control-plane/index.d.ts +0 -10
  332. package/dist/src/acp/control-plane/index.js +0 -6
  333. package/dist/src/acp/control-plane/manager.d.ts +0 -86
  334. package/dist/src/acp/control-plane/manager.js +0 -502
  335. package/dist/src/acp/control-plane/manager.js.map +0 -1
  336. package/dist/src/acp/control-plane/manager.types.d.ts +0 -125
  337. package/dist/src/acp/control-plane/manager.types.js +0 -14
  338. package/dist/src/acp/control-plane/manager.types.js.map +0 -1
  339. package/dist/src/acp/control-plane/manager.utils.d.ts +0 -29
  340. package/dist/src/acp/control-plane/manager.utils.js +0 -46
  341. package/dist/src/acp/control-plane/manager.utils.js.map +0 -1
  342. package/dist/src/acp/control-plane/runtime-cache-manager.d.ts +0 -49
  343. package/dist/src/acp/control-plane/runtime-cache-manager.js +0 -155
  344. package/dist/src/acp/control-plane/runtime-cache-manager.js.map +0 -1
  345. package/dist/src/acp/control-plane/runtime-cache.d.ts +0 -45
  346. package/dist/src/acp/control-plane/runtime-cache.js +0 -58
  347. package/dist/src/acp/control-plane/runtime-cache.js.map +0 -1
  348. package/dist/src/acp/control-plane/runtime-options.d.ts +0 -30
  349. package/dist/src/acp/control-plane/runtime-options.js +0 -92
  350. package/dist/src/acp/control-plane/runtime-options.js.map +0 -1
  351. package/dist/src/acp/control-plane/session-actor-queue.d.ts +0 -22
  352. package/dist/src/acp/control-plane/session-actor-queue.js +0 -70
  353. package/dist/src/acp/control-plane/session-actor-queue.js.map +0 -1
  354. package/dist/src/acp/control-plane/session-lifecycle-manager.d.ts +0 -59
  355. package/dist/src/acp/control-plane/session-lifecycle-manager.js +0 -209
  356. package/dist/src/acp/control-plane/session-lifecycle-manager.js.map +0 -1
  357. package/dist/src/acp/control-plane/session-store.d.ts +0 -39
  358. package/dist/src/acp/control-plane/session-store.js +0 -149
  359. package/dist/src/acp/control-plane/session-store.js.map +0 -1
  360. package/dist/src/acp/control-plane/turn-manager.d.ts +0 -40
  361. package/dist/src/acp/control-plane/turn-manager.js +0 -134
  362. package/dist/src/acp/control-plane/turn-manager.js.map +0 -1
  363. package/dist/src/acp/event-mapper.d.ts +0 -48
  364. package/dist/src/acp/event-mapper.js +0 -94
  365. package/dist/src/acp/event-mapper.js.map +0 -1
  366. package/dist/src/acp/index.d.ts +0 -10
  367. package/dist/src/acp/index.js +0 -5
  368. package/dist/src/acp/meta.d.ts +0 -15
  369. package/dist/src/acp/meta.js +0 -36
  370. package/dist/src/acp/meta.js.map +0 -1
  371. package/dist/src/acp/routing-integration.d.ts +0 -37
  372. package/dist/src/acp/routing-integration.js +0 -58
  373. package/dist/src/acp/routing-integration.js.map +0 -1
  374. package/dist/src/acp/runtime/backends/index.d.ts +0 -4
  375. package/dist/src/acp/runtime/backends/index.js +0 -2
  376. package/dist/src/acp/runtime/backends/local.d.ts +0 -136
  377. package/dist/src/acp/runtime/backends/local.js +0 -603
  378. package/dist/src/acp/runtime/backends/local.js.map +0 -1
  379. package/dist/src/acp/runtime/error-text.d.ts +0 -16
  380. package/dist/src/acp/runtime/error-text.js +0 -40
  381. package/dist/src/acp/runtime/error-text.js.map +0 -1
  382. package/dist/src/acp/runtime/errors.d.ts +0 -31
  383. package/dist/src/acp/runtime/errors.js +0 -47
  384. package/dist/src/acp/runtime/errors.js.map +0 -1
  385. package/dist/src/acp/runtime/index.d.ts +0 -7
  386. package/dist/src/acp/runtime/index.js +0 -4
  387. package/dist/src/acp/runtime/registry.d.ts +0 -35
  388. package/dist/src/acp/runtime/registry.js +0 -85
  389. package/dist/src/acp/runtime/registry.js.map +0 -1
  390. package/dist/src/acp/runtime/session-identity.d.ts +0 -35
  391. package/dist/src/acp/runtime/session-identity.js +0 -134
  392. package/dist/src/acp/runtime/session-identity.js.map +0 -1
  393. package/dist/src/acp/runtime/types.d.ts +0 -214
  394. package/dist/src/acp/secret-file.d.ts +0 -7
  395. package/dist/src/acp/secret-file.js +0 -19
  396. package/dist/src/acp/secret-file.js.map +0 -1
  397. package/dist/src/acp/server.d.ts +0 -48
  398. package/dist/src/acp/server.js +0 -300
  399. package/dist/src/acp/server.js.map +0 -1
  400. package/dist/src/acp/session.d.ts +0 -29
  401. package/dist/src/acp/session.js +0 -30
  402. package/dist/src/acp/session.js.map +0 -1
  403. package/dist/src/acp/types.d.ts +0 -39
  404. package/dist/src/acp/types.js +0 -13
  405. package/dist/src/acp/types.js.map +0 -1
  406. package/dist/src/agent/image/describe-images.d.ts +0 -18
  407. package/dist/src/agent/image/describe-images.js +0 -19
  408. package/dist/src/agent/image/describe-images.js.map +0 -1
  409. package/dist/src/cli/commands/acp.d.ts +0 -4
  410. package/dist/src/cli/commands/acp.js +0 -200
  411. package/dist/src/cli/commands/acp.js.map +0 -1
  412. /package/dist/src/{acp/runtime/types.js → cli/commands/doctor/index.d.ts} +0 -0
@@ -0,0 +1,197 @@
1
+ import { createLogger } from "../../utils/logger/index.js";
2
+ import { init_logger } from "../../utils/logger.js";
3
+ import { init_paths, resolveConfigPath } from "../../config/paths.js";
4
+ import { ConfigSchema, init_schema } from "../../config/schema.js";
5
+ import { init_loader, loadConfig, saveConfig } from "../../config/loader.js";
6
+ import { init_session_key, parseSessionKey } from "../../routing/session-key.js";
7
+ import { resolveAllowlistMatchSimple } from "../../channels/security.js";
8
+ import { commandRegistry } from "../registry.js";
9
+ import { parseConfigValue } from "../config-value.js";
10
+ import { getConfigValueAtPath, parseConfigPath, setConfigValueAtPath, unsetConfigValueAtPath } from "../config-paths.js";
11
+ //#region src/chat-commands/builtins/config.ts
12
+ init_schema();
13
+ init_loader();
14
+ init_paths();
15
+ init_logger();
16
+ init_session_key();
17
+ const log = createLogger("ConfigCommand");
18
+ const BLOCKED_WRITE_PATHS = new Set(["gateway.auth.token", "providers"]);
19
+ function isBlockedPath(path) {
20
+ const joined = path.join(".");
21
+ for (const blocked of BLOCKED_WRITE_PATHS) if (joined === blocked || joined.startsWith(`${blocked}.`)) return true;
22
+ return false;
23
+ }
24
+ function redactConfigForDisplay(plain) {
25
+ if (plain.gateway && typeof plain.gateway === "object") {
26
+ const gw = plain.gateway;
27
+ if (gw.auth && typeof gw.auth === "object") gw.auth.token = "[redacted]";
28
+ }
29
+ if (plain.providers !== void 0) plain.providers = "[redacted]";
30
+ }
31
+ function senderMayWritePersistentConfig(ctx) {
32
+ const { source, senderId, isGroup, sessionKey } = ctx;
33
+ if (source !== "telegram" && source !== "weixin") return true;
34
+ const cfg = ctx.getConfig?.() ?? ctx.config;
35
+ if (source === "weixin") {
36
+ const wx = cfg.channels?.weixin;
37
+ if (!wx?.enabled) return false;
38
+ const accountId = parseSessionKey(sessionKey)?.accountId ?? "default";
39
+ let allowFrom = [];
40
+ if (wx.accounts && Object.keys(wx.accounts).length > 0) {
41
+ const acc = wx.accounts[accountId] ?? wx.accounts["default"];
42
+ if (!acc || acc.enabled === false) return false;
43
+ allowFrom = [...acc.allowFrom ?? []];
44
+ } else allowFrom = [...wx.allowFrom ?? []];
45
+ if (allowFrom.length === 0) return false;
46
+ return resolveAllowlistMatchSimple({
47
+ allowFrom,
48
+ senderId
49
+ }).allowed;
50
+ }
51
+ const tg = cfg.channels?.telegram;
52
+ if (!tg?.enabled) return false;
53
+ const accountId = parseSessionKey(sessionKey)?.accountId ?? "default";
54
+ let allowFrom = [];
55
+ let groupAllowFrom = [];
56
+ if (tg.accounts && Object.keys(tg.accounts).length > 0) {
57
+ const acc = tg.accounts[accountId] ?? tg.accounts["default"];
58
+ if (!acc || acc.enabled === false) return false;
59
+ allowFrom = [...acc.allowFrom ?? []];
60
+ groupAllowFrom = [...acc.groupAllowFrom ?? []];
61
+ } else {
62
+ allowFrom = [...tg.allowFrom ?? []];
63
+ groupAllowFrom = [...tg.groupAllowFrom ?? []];
64
+ }
65
+ const list = isGroup && groupAllowFrom.length > 0 ? groupAllowFrom : allowFrom;
66
+ if (list.length === 0) return false;
67
+ return resolveAllowlistMatchSimple({
68
+ allowFrom: list,
69
+ senderId
70
+ }).allowed;
71
+ }
72
+ const configCommand = {
73
+ id: "system.config",
74
+ name: "config",
75
+ aliases: ["cfg"],
76
+ description: "Show or update configuration. Usage: /config show [path] | /config set path=value | /config unset path",
77
+ category: "system",
78
+ scope: [
79
+ "global",
80
+ "private",
81
+ "group"
82
+ ],
83
+ acceptsArgs: true,
84
+ examples: [
85
+ "/config show",
86
+ "/config show agents.defaults.model",
87
+ "/config set agents.defaults.model=anthropic/claude-opus-4-5",
88
+ "/config set agents.defaults.temperature=0.5",
89
+ "/config unset tts"
90
+ ],
91
+ handler: async (ctx, args) => {
92
+ const parts = args.trim().split(/\s+/);
93
+ const action = parts[0]?.toLowerCase();
94
+ const rest = parts.slice(1).join(" ").trim();
95
+ if (!action || action === "show" || action === "get") {
96
+ const config = ctx.getConfig?.() ?? loadConfig(resolveConfigPath());
97
+ const plain = JSON.parse(JSON.stringify(config));
98
+ redactConfigForDisplay(plain);
99
+ if (rest) {
100
+ const parsed = parseConfigPath(rest);
101
+ if (!parsed.ok || !parsed.path) return {
102
+ content: `⚠️ ${parsed.error ?? "Invalid path."}`,
103
+ success: false
104
+ };
105
+ const value = getConfigValueAtPath(plain, parsed.path);
106
+ return { content: `⚙️ \`${rest}\`:\n\`\`\`json\n${JSON.stringify(value ?? null, null, 2)}\n\`\`\`` };
107
+ }
108
+ return { content: `⚙️ Current config:\n\`\`\`json\n${JSON.stringify(plain, null, 2)}\n\`\`\`` };
109
+ }
110
+ if (action === "set") {
111
+ if (!senderMayWritePersistentConfig(ctx)) return {
112
+ content: "⚠️ You are not allowed to change config from this chat surface.",
113
+ success: false
114
+ };
115
+ const eqIndex = rest.indexOf("=");
116
+ if (eqIndex <= 0) return {
117
+ content: "⚠️ Usage: /config set path=value",
118
+ success: false
119
+ };
120
+ const pathRaw = rest.slice(0, eqIndex).trim();
121
+ const valueRaw = rest.slice(eqIndex + 1);
122
+ const parsedPath = parseConfigPath(pathRaw);
123
+ if (!parsedPath.ok || !parsedPath.path) return {
124
+ content: `⚠️ ${parsedPath.error}`,
125
+ success: false
126
+ };
127
+ if (isBlockedPath(parsedPath.path)) return {
128
+ content: `⚠️ Path \`${pathRaw}\` cannot be modified via chat for security reasons.`,
129
+ success: false
130
+ };
131
+ const parsedValue = parseConfigValue(valueRaw);
132
+ if (parsedValue.ok === false) return {
133
+ content: `⚠️ ${parsedValue.error}`,
134
+ success: false
135
+ };
136
+ const currentConfig = loadConfig(resolveConfigPath());
137
+ setConfigValueAtPath(currentConfig, parsedPath.path, parsedValue.value);
138
+ const validated = ConfigSchema.safeParse(currentConfig);
139
+ if (!validated.success) {
140
+ const firstIssue = validated.error.issues[0];
141
+ return {
142
+ content: `⚠️ Config invalid after set (${firstIssue.path.join(".")}: ${firstIssue.message}). Change not saved.`,
143
+ success: false
144
+ };
145
+ }
146
+ await saveConfig(validated.data);
147
+ log.info({
148
+ path: pathRaw,
149
+ value: parsedValue.value
150
+ }, "Config updated via /config set");
151
+ return { content: `⚙️ Config updated: \`${pathRaw}\` = ${typeof parsedValue.value === "string" ? `"${parsedValue.value}"` : JSON.stringify(parsedValue.value)}` };
152
+ }
153
+ if (action === "unset") {
154
+ if (!senderMayWritePersistentConfig(ctx)) return {
155
+ content: "⚠️ You are not allowed to change config from this chat surface.",
156
+ success: false
157
+ };
158
+ if (!rest) return {
159
+ content: "⚠️ Usage: /config unset path",
160
+ success: false
161
+ };
162
+ const parsedPath = parseConfigPath(rest);
163
+ if (!parsedPath.ok || !parsedPath.path) return {
164
+ content: `⚠️ ${parsedPath.error}`,
165
+ success: false
166
+ };
167
+ if (isBlockedPath(parsedPath.path)) return {
168
+ content: `⚠️ Path \`${rest}\` cannot be modified via chat for security reasons.`,
169
+ success: false
170
+ };
171
+ const currentConfig = loadConfig(resolveConfigPath());
172
+ if (!unsetConfigValueAtPath(currentConfig, parsedPath.path)) return {
173
+ content: `⚙️ No config value found at \`${rest}\`.`,
174
+ success: false
175
+ };
176
+ const validated = ConfigSchema.safeParse(currentConfig);
177
+ if (!validated.success) {
178
+ const firstIssue = validated.error.issues[0];
179
+ return {
180
+ content: `⚠️ Config invalid after unset (${firstIssue.path.join(".")}: ${firstIssue.message}). Change not saved.`,
181
+ success: false
182
+ };
183
+ }
184
+ await saveConfig(validated.data);
185
+ log.info({ path: rest }, "Config key removed via /config unset");
186
+ return { content: `⚙️ Config updated: \`${rest}\` removed.` };
187
+ }
188
+ return { content: "⚙️ *Config Command*\n\n`/config show [path]` — view config (or a specific path)\n`/config set path=value` — update a config value\n`/config unset path` — remove a config key\n\nExamples:\n`/config show agents.defaults.model`\n`/config set agents.defaults.temperature=0.5`\n`/config set agents.defaults.thinkingDefault=medium`\n`/config unset tts`" };
189
+ }
190
+ };
191
+ function registerConfigCommand() {
192
+ commandRegistry.register(configCommand);
193
+ }
194
+ //#endregion
195
+ export { registerConfigCommand };
196
+
197
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","names":[],"sources":["../../../../src/chat-commands/builtins/config.ts"],"sourcesContent":["/**\n * /config — read and write persistent config (~/.xopc/xopc.json) from chat.\n */\n\nimport type { CommandDefinition, CommandContext } from '../types.js';\nimport { commandRegistry } from '../registry.js';\nimport { parseConfigValue } from '../config-value.js';\nimport {\n parseConfigPath,\n getConfigValueAtPath,\n setConfigValueAtPath,\n unsetConfigValueAtPath,\n} from '../config-paths.js';\nimport { ConfigSchema, type TelegramConfig, type WeixinConfig } from '../../config/schema.js';\nimport { loadConfig, saveConfig } from '../../config/loader.js';\nimport { resolveConfigPath } from '../../config/paths.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { parseSessionKey } from '../../routing/session-key.js';\nimport { resolveAllowlistMatchSimple } from '../../channels/security.js';\n\nconst log = createLogger('ConfigCommand');\n\nconst BLOCKED_WRITE_PATHS = new Set(['gateway.auth.token', 'providers']);\n\nfunction isBlockedPath(path: string[]): boolean {\n const joined = path.join('.');\n for (const blocked of BLOCKED_WRITE_PATHS) {\n if (joined === blocked || joined.startsWith(`${blocked}.`)) return true;\n }\n return false;\n}\n\nfunction redactConfigForDisplay(plain: Record<string, unknown>): void {\n if (plain.gateway && typeof plain.gateway === 'object') {\n const gw = plain.gateway as Record<string, unknown>;\n if (gw.auth && typeof gw.auth === 'object') {\n (gw.auth as Record<string, unknown>).token = '[redacted]';\n }\n }\n if (plain.providers !== undefined) plain.providers = '[redacted]';\n}\n\nfunction senderMayWritePersistentConfig(ctx: CommandContext): boolean {\n const { source, senderId, isGroup, sessionKey } = ctx;\n if (source !== 'telegram' && source !== 'weixin') {\n return true;\n }\n\n const cfg = ctx.getConfig?.() ?? ctx.config;\n\n if (source === 'weixin') {\n const wx = cfg.channels?.weixin as WeixinConfig | undefined;\n if (!wx?.enabled) return false;\n const parsed = parseSessionKey(sessionKey);\n const accountId = parsed?.accountId ?? 'default';\n let allowFrom: Array<string | number> = [];\n if (wx.accounts && Object.keys(wx.accounts).length > 0) {\n const acc = wx.accounts[accountId] ?? wx.accounts['default'];\n if (!acc || acc.enabled === false) return false;\n allowFrom = [...(acc.allowFrom ?? [])];\n } else {\n allowFrom = [...(wx.allowFrom ?? [])];\n }\n if (allowFrom.length === 0) return false;\n return resolveAllowlistMatchSimple({ allowFrom, senderId }).allowed;\n }\n\n const tg = cfg.channels?.telegram as TelegramConfig | undefined;\n if (!tg?.enabled) return false;\n const parsed = parseSessionKey(sessionKey);\n const accountId = parsed?.accountId ?? 'default';\n let allowFrom: Array<string | number> = [];\n let groupAllowFrom: Array<string | number> = [];\n if (tg.accounts && Object.keys(tg.accounts).length > 0) {\n const acc = tg.accounts[accountId] ?? tg.accounts['default'];\n if (!acc || acc.enabled === false) return false;\n allowFrom = [...(acc.allowFrom ?? [])];\n groupAllowFrom = [...(acc.groupAllowFrom ?? [])];\n } else {\n allowFrom = [...(tg.allowFrom ?? [])];\n groupAllowFrom = [...(tg.groupAllowFrom ?? [])];\n }\n const list = isGroup && groupAllowFrom.length > 0 ? groupAllowFrom : allowFrom;\n if (list.length === 0) return false;\n return resolveAllowlistMatchSimple({ allowFrom: list, senderId }).allowed;\n}\n\nconst configCommand: CommandDefinition = {\n id: 'system.config',\n name: 'config',\n aliases: ['cfg'],\n description:\n 'Show or update configuration. Usage: /config show [path] | /config set path=value | /config unset path',\n category: 'system',\n scope: ['global', 'private', 'group'],\n acceptsArgs: true,\n examples: [\n '/config show',\n '/config show agents.defaults.model',\n '/config set agents.defaults.model=anthropic/claude-opus-4-5',\n '/config set agents.defaults.temperature=0.5',\n '/config unset tts',\n ],\n handler: async (ctx: CommandContext, args: string) => {\n const parts = args.trim().split(/\\s+/);\n const action = parts[0]?.toLowerCase();\n const rest = parts.slice(1).join(' ').trim();\n\n if (!action || action === 'show' || action === 'get') {\n const config = ctx.getConfig?.() ?? loadConfig(resolveConfigPath());\n const plain = JSON.parse(JSON.stringify(config)) as Record<string, unknown>;\n redactConfigForDisplay(plain);\n\n if (rest) {\n const parsed = parseConfigPath(rest);\n if (!parsed.ok || !parsed.path) {\n return { content: `⚠️ ${parsed.error ?? 'Invalid path.'}`, success: false };\n }\n const value = getConfigValueAtPath(plain, parsed.path);\n const rendered = JSON.stringify(value ?? null, null, 2);\n return { content: `⚙️ \\`${rest}\\`:\\n\\`\\`\\`json\\n${rendered}\\n\\`\\`\\`` };\n }\n\n const json = JSON.stringify(plain, null, 2);\n return { content: `⚙️ Current config:\\n\\`\\`\\`json\\n${json}\\n\\`\\`\\`` };\n }\n\n if (action === 'set') {\n if (!senderMayWritePersistentConfig(ctx)) {\n return {\n content: '⚠️ You are not allowed to change config from this chat surface.',\n success: false,\n };\n }\n const eqIndex = rest.indexOf('=');\n if (eqIndex <= 0) {\n return { content: '⚠️ Usage: /config set path=value', success: false };\n }\n const pathRaw = rest.slice(0, eqIndex).trim();\n const valueRaw = rest.slice(eqIndex + 1);\n\n const parsedPath = parseConfigPath(pathRaw);\n if (!parsedPath.ok || !parsedPath.path) {\n return { content: `⚠️ ${parsedPath.error}`, success: false };\n }\n if (isBlockedPath(parsedPath.path)) {\n return {\n content: `⚠️ Path \\`${pathRaw}\\` cannot be modified via chat for security reasons.`,\n success: false,\n };\n }\n\n const parsedValue = parseConfigValue(valueRaw);\n if (parsedValue.ok === false) {\n return { content: `⚠️ ${parsedValue.error}`, success: false };\n }\n\n const configPath = resolveConfigPath();\n const currentConfig = loadConfig(configPath) as Record<string, unknown>;\n setConfigValueAtPath(currentConfig, parsedPath.path, parsedValue.value);\n\n const validated = ConfigSchema.safeParse(currentConfig);\n if (!validated.success) {\n const firstIssue = validated.error.issues[0];\n const fieldPath = firstIssue.path.join('.');\n return {\n content: `⚠️ Config invalid after set (${fieldPath}: ${firstIssue.message}). Change not saved.`,\n success: false,\n };\n }\n\n await saveConfig(validated.data);\n log.info({ path: pathRaw, value: parsedValue.value }, 'Config updated via /config set');\n\n const valueLabel =\n typeof parsedValue.value === 'string'\n ? `\"${parsedValue.value}\"`\n : JSON.stringify(parsedValue.value);\n return { content: `⚙️ Config updated: \\`${pathRaw}\\` = ${valueLabel}` };\n }\n\n if (action === 'unset') {\n if (!senderMayWritePersistentConfig(ctx)) {\n return {\n content: '⚠️ You are not allowed to change config from this chat surface.',\n success: false,\n };\n }\n if (!rest) {\n return { content: '⚠️ Usage: /config unset path', success: false };\n }\n const parsedPath = parseConfigPath(rest);\n if (!parsedPath.ok || !parsedPath.path) {\n return { content: `⚠️ ${parsedPath.error}`, success: false };\n }\n if (isBlockedPath(parsedPath.path)) {\n return {\n content: `⚠️ Path \\`${rest}\\` cannot be modified via chat for security reasons.`,\n success: false,\n };\n }\n\n const configPath = resolveConfigPath();\n const currentConfig = loadConfig(configPath) as Record<string, unknown>;\n const removed = unsetConfigValueAtPath(currentConfig, parsedPath.path);\n if (!removed) {\n return { content: `⚙️ No config value found at \\`${rest}\\`.`, success: false };\n }\n\n const validated = ConfigSchema.safeParse(currentConfig);\n if (!validated.success) {\n const firstIssue = validated.error.issues[0];\n const fieldPath = firstIssue.path.join('.');\n return {\n content: `⚠️ Config invalid after unset (${fieldPath}: ${firstIssue.message}). Change not saved.`,\n success: false,\n };\n }\n\n await saveConfig(validated.data);\n log.info({ path: rest }, 'Config key removed via /config unset');\n return { content: `⚙️ Config updated: \\`${rest}\\` removed.` };\n }\n\n return {\n content:\n '⚙️ *Config Command*\\n\\n' +\n '`/config show [path]` — view config (or a specific path)\\n' +\n '`/config set path=value` — update a config value\\n' +\n '`/config unset path` — remove a config key\\n\\n' +\n 'Examples:\\n' +\n '`/config show agents.defaults.model`\\n' +\n '`/config set agents.defaults.temperature=0.5`\\n' +\n '`/config set agents.defaults.thinkingDefault=medium`\\n' +\n '`/config unset tts`',\n };\n },\n};\n\nexport function registerConfigCommand(): void {\n commandRegistry.register(configCommand);\n}\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * /context — inspect approximate prompt/context budget (config + transcript stats).
3
+ */
4
+ export declare function registerContextCommands(): void;
@@ -0,0 +1,44 @@
1
+ import { commandRegistry } from "../registry.js";
2
+ //#region src/chat-commands/builtins/context.ts
3
+ function parseMode(args) {
4
+ const w = args.trim().split(/\s+/)[0]?.toLowerCase();
5
+ if (w === "detail" || w === "json" || w === "list") return w;
6
+ return "list";
7
+ }
8
+ const contextCommand = {
9
+ id: "session.context",
10
+ name: "context",
11
+ description: "Show context budget and config snapshot (list | detail | json)",
12
+ category: "session",
13
+ scope: [
14
+ "global",
15
+ "private",
16
+ "group"
17
+ ],
18
+ acceptsArgs: true,
19
+ examples: [
20
+ "/context",
21
+ "/context detail",
22
+ "/context json"
23
+ ],
24
+ handler: async (ctx, args) => {
25
+ await ctx.setTyping(true);
26
+ const mode = parseMode(args);
27
+ const text = await ctx.agentContextReport?.(mode);
28
+ if (text === void 0) return {
29
+ content: "⚠️ Context report is not available here.",
30
+ success: false
31
+ };
32
+ return {
33
+ content: text,
34
+ success: true
35
+ };
36
+ }
37
+ };
38
+ function registerContextCommands() {
39
+ commandRegistry.register(contextCommand);
40
+ }
41
+ //#endregion
42
+ export { registerContextCommands };
43
+
44
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","names":[],"sources":["../../../../src/chat-commands/builtins/context.ts"],"sourcesContent":["/**\n * /context — inspect approximate prompt/context budget (config + transcript stats).\n */\n\nimport type { CommandDefinition, CommandContext } from '../types.js';\nimport { commandRegistry } from '../registry.js';\n\nfunction parseMode(args: string): 'list' | 'detail' | 'json' {\n const w = args.trim().split(/\\s+/)[0]?.toLowerCase();\n if (w === 'detail' || w === 'json' || w === 'list') return w;\n return 'list';\n}\n\nconst contextCommand: CommandDefinition = {\n id: 'session.context',\n name: 'context',\n description: 'Show context budget and config snapshot (list | detail | json)',\n category: 'session',\n scope: ['global', 'private', 'group'],\n acceptsArgs: true,\n examples: ['/context', '/context detail', '/context json'],\n handler: async (ctx: CommandContext, args: string) => {\n await ctx.setTyping(true);\n const mode = parseMode(args);\n const text = await ctx.agentContextReport?.(mode);\n if (text === undefined) {\n return { content: '⚠️ Context report is not available here.', success: false };\n }\n return { content: text, success: true };\n },\n};\n\nexport function registerContextCommands(): void {\n commandRegistry.register(contextCommand);\n}\n"],"mappings":";;AAOA,SAAS,UAAU,MAA0C;CAC3D,MAAM,IAAI,KAAK,MAAM,CAAC,MAAM,MAAM,CAAC,IAAI,aAAa;AACpD,KAAI,MAAM,YAAY,MAAM,UAAU,MAAM,OAAQ,QAAO;AAC3D,QAAO;;AAGT,MAAM,iBAAoC;CACxC,IAAI;CACJ,MAAM;CACN,aAAa;CACb,UAAU;CACV,OAAO;EAAC;EAAU;EAAW;EAAQ;CACrC,aAAa;CACb,UAAU;EAAC;EAAY;EAAmB;EAAgB;CAC1D,SAAS,OAAO,KAAqB,SAAiB;AACpD,QAAM,IAAI,UAAU,KAAK;EACzB,MAAM,OAAO,UAAU,KAAK;EAC5B,MAAM,OAAO,MAAM,IAAI,qBAAqB,KAAK;AACjD,MAAI,SAAS,KAAA,EACX,QAAO;GAAE,SAAS;GAA4C,SAAS;GAAO;AAEhF,SAAO;GAAE,SAAS;GAAM,SAAS;GAAM;;CAE1C;AAED,SAAgB,0BAAgC;AAC9C,iBAAgB,SAAS,eAAe"}
@@ -107,6 +107,114 @@ const abortCommand = {
107
107
  };
108
108
  }
109
109
  };
110
+ const compactCommand = {
111
+ id: "session.compact",
112
+ name: "compact",
113
+ description: "Compact session history (LLM summary + keep recent turns) to save context",
114
+ category: "session",
115
+ scope: [
116
+ "global",
117
+ "private",
118
+ "group"
119
+ ],
120
+ acceptsArgs: true,
121
+ examples: ["/compact", "/compact focus on API design"],
122
+ handler: async (ctx, args) => {
123
+ await ctx.setTyping(true);
124
+ const instructions = args.trim() || void 0;
125
+ const result = await ctx.compactSession?.({
126
+ instructions,
127
+ force: true
128
+ });
129
+ if (result === null || result === void 0) return {
130
+ content: "⚠️ Session compaction is not available in this environment.",
131
+ success: false
132
+ };
133
+ if (!result.compacted) return {
134
+ content: "ℹ️ Nothing to compact yet. Need at least two messages, or the session is already small.\nTip: add optional focus text, e.g. `/compact emphasize decisions about auth`.",
135
+ success: true
136
+ };
137
+ const preview = result.summary && result.summary.length > 600 ? `${result.summary.slice(0, 600)}…` : result.summary || "";
138
+ return {
139
+ content: `🗜️ *Session compacted*\n\nTokens (approx): ${result.tokensBefore} → ${result.tokensAfter}\n\n` + (preview ? `*Summary:*\n${preview}` : ""),
140
+ success: true
141
+ };
142
+ }
143
+ };
144
+ const btwCommand = {
145
+ id: "session.btw",
146
+ name: "btw",
147
+ aliases: ["aside"],
148
+ description: "Ask a side question without adding to the session transcript",
149
+ category: "session",
150
+ scope: [
151
+ "global",
152
+ "private",
153
+ "group"
154
+ ],
155
+ acceptsArgs: true,
156
+ examples: ["/btw What does that error code mean?", "/aside Summarize the last topic in one line"],
157
+ handler: async (ctx, args) => {
158
+ await ctx.setTyping(true);
159
+ const q = args.trim();
160
+ if (!q) return {
161
+ content: "💬 *Side question*\n\nUsage: `/btw <question>`\nAnswers use your current chat as background only; the reply is not saved to the session.",
162
+ success: true
163
+ };
164
+ const out = await ctx.btwQuery?.(q);
165
+ if (!out) return {
166
+ content: "⚠️ /btw is not available here.",
167
+ success: false
168
+ };
169
+ if (out.error) return {
170
+ content: `⚠️ ${out.error}`,
171
+ success: false
172
+ };
173
+ return {
174
+ content: `💬 *BTW*\n\n${out.text}`,
175
+ success: true
176
+ };
177
+ }
178
+ };
179
+ const exportSessionCommand = {
180
+ id: "session.export",
181
+ name: "export-session",
182
+ aliases: ["export"],
183
+ description: "Export this session to workspace exports/ (markdown, html, or json)",
184
+ category: "session",
185
+ scope: [
186
+ "global",
187
+ "private",
188
+ "group"
189
+ ],
190
+ acceptsArgs: true,
191
+ examples: [
192
+ "/export-session",
193
+ "/export-session html",
194
+ "/export json"
195
+ ],
196
+ handler: async (ctx, args) => {
197
+ await ctx.setTyping(true);
198
+ const raw = args.trim().toLowerCase();
199
+ const fmt = raw === "json" || raw === "html" || raw === "markdown" ? raw : "markdown";
200
+ if (!ctx.exportSessionToWorkspace) return {
201
+ content: "⚠️ Export is not available in this environment.",
202
+ success: false
203
+ };
204
+ try {
205
+ const { path } = await ctx.exportSessionToWorkspace(fmt);
206
+ return {
207
+ content: `📄 Exported (${fmt}) to:\n\`${path}\``,
208
+ success: true
209
+ };
210
+ } catch (e) {
211
+ return {
212
+ content: `⚠️ Export failed: ${e instanceof Error ? e.message : String(e)}`,
213
+ success: false
214
+ };
215
+ }
216
+ }
217
+ };
110
218
  const archiveCommand = {
111
219
  id: "session.archive",
112
220
  name: "archive",
@@ -131,6 +239,9 @@ function registerSessionCommands() {
131
239
  commandRegistry.register(listCommand);
132
240
  commandRegistry.register(clearCommand);
133
241
  commandRegistry.register(abortCommand);
242
+ commandRegistry.register(compactCommand);
243
+ commandRegistry.register(btwCommand);
244
+ commandRegistry.register(exportSessionCommand);
134
245
  commandRegistry.register(archiveCommand);
135
246
  }
136
247
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","names":[],"sources":["../../../../src/chat-commands/builtins/session.ts"],"sourcesContent":["/**\n * Session Commands\n * \n * Built-in commands for session management:\n * - /new - Start a new session\n * - /list - List all sessions\n * - /switch - Switch to a different session\n * - /clear - Clear current session without archiving\n * - /abort - Cancel in-flight assistant reply (generation / streaming)\n */\n\nimport type { CommandDefinition, CommandContext, UIComponent } from '../types.js';\nimport { commandRegistry } from '../registry.js';\nimport { getSessionDisplayName } from '../session-key.js';\n\nconst newCommand: CommandDefinition = {\n id: 'session.new',\n name: 'new',\n aliases: ['reset', 'restart'],\n description: 'Start a new session (archive current)',\n category: 'session',\n scope: ['global', 'private', 'group'],\n handler: async (ctx: CommandContext) => {\n await ctx.setTyping(true);\n \n await ctx.clearSession();\n \n // Note: clearSession already sends confirmation message\n return {\n content: '',\n success: true,\n };\n },\n};\n\nconst listCommand: CommandDefinition = {\n id: 'session.list',\n name: 'list',\n aliases: ['sessions'],\n description: 'List all your sessions',\n category: 'session',\n scope: ['global', 'private', 'group'],\n handler: async (ctx: CommandContext) => {\n await ctx.setTyping(true);\n \n const sessions = await ctx.listSessions();\n \n if (sessions.length === 0) {\n return {\n content: '📋 No sessions found.',\n success: true,\n };\n }\n \n // Sort by updatedAt desc\n sessions.sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime());\n \n // Build text response\n const lines = sessions.slice(0, 10).map(s => {\n const indicator = s.isActive ? '▶️' : ' ';\n const name = getSessionDisplayName(s.key);\n const date = s.updatedAt.toLocaleDateString();\n return `${indicator} ${name}\\n ${s.messageCount} messages · ${date}`;\n });\n \n const content = '📋 Your Sessions:\\n\\n' + lines.join('\\n\\n');\n \n // Create UI component if supported\n if (ctx.supports('buttons')) {\n const component: UIComponent = {\n type: 'session-list',\n sessions: sessions.slice(0, 5).map(s => ({\n ...s,\n name: getSessionDisplayName(s.key),\n })),\n currentSession: ctx.sessionKey,\n };\n \n return {\n content,\n success: true,\n components: [component],\n };\n }\n \n return {\n content,\n success: true,\n };\n },\n};\n\nconst clearCommand: CommandDefinition = {\n id: 'session.clear',\n name: 'clear',\n description: 'Clear current session without archiving',\n category: 'session',\n scope: ['global', 'private', 'group'],\n handler: async (ctx: CommandContext) => {\n await ctx.setTyping(true);\n \n // Just delete without archiving\n const messages = await ctx.getSession();\n await ctx.clearSession();\n \n return {\n content: `🗑️ Session cleared. ${messages.length} messages deleted.`,\n success: true,\n };\n },\n};\n\nconst abortCommand: CommandDefinition = {\n id: 'session.abort',\n name: 'abort',\n aliases: ['stop', 'cancel'],\n description: 'Stop the current assistant reply (in-flight generation or stream)',\n category: 'session',\n scope: ['global', 'private', 'group'],\n handler: async (ctx: CommandContext) => {\n if (!ctx.abortCurrentTurn) {\n return {\n content: 'Abort is not available in this environment.',\n success: false,\n };\n }\n await ctx.abortCurrentTurn();\n return {\n content: '⏹️ Current reply cancelled.',\n success: true,\n };\n },\n};\n\nconst archiveCommand: CommandDefinition = {\n id: 'session.archive',\n name: 'archive',\n description: 'Archive current session',\n category: 'session',\n scope: ['global', 'private', 'group'],\n handler: async (ctx: CommandContext) => {\n await ctx.setTyping(true);\n \n await ctx.archiveSession();\n \n return {\n content: '📦 Current session has been archived.',\n success: true,\n };\n },\n};\n\n// Register all session commands\nexport function registerSessionCommands(): void {\n commandRegistry.register(newCommand);\n commandRegistry.register(listCommand);\n commandRegistry.register(clearCommand);\n commandRegistry.register(abortCommand);\n commandRegistry.register(archiveCommand);\n}\n"],"mappings":";;;AAeA,MAAM,aAAgC;CACpC,IAAI;CACJ,MAAM;CACN,SAAS,CAAC,SAAS,UAAU;CAC7B,aAAa;CACb,UAAU;CACV,OAAO;EAAC;EAAU;EAAW;EAAQ;CACrC,SAAS,OAAO,QAAwB;AACtC,QAAM,IAAI,UAAU,KAAK;AAEzB,QAAM,IAAI,cAAc;AAGxB,SAAO;GACL,SAAS;GACT,SAAS;GACV;;CAEJ;AAED,MAAM,cAAiC;CACrC,IAAI;CACJ,MAAM;CACN,SAAS,CAAC,WAAW;CACrB,aAAa;CACb,UAAU;CACV,OAAO;EAAC;EAAU;EAAW;EAAQ;CACrC,SAAS,OAAO,QAAwB;AACtC,QAAM,IAAI,UAAU,KAAK;EAEzB,MAAM,WAAW,MAAM,IAAI,cAAc;AAEzC,MAAI,SAAS,WAAW,EACtB,QAAO;GACL,SAAS;GACT,SAAS;GACV;AAIH,WAAS,MAAM,GAAG,MAAM,EAAE,UAAU,SAAS,GAAG,EAAE,UAAU,SAAS,CAAC;EAUtE,MAAM,UAAU,0BAPF,SAAS,MAAM,GAAG,GAAG,CAAC,KAAI,MAAK;GAC3C,MAAM,YAAY,EAAE,WAAW,OAAO;GACtC,MAAM,OAAO,sBAAsB,EAAE,IAAI;GACzC,MAAM,OAAO,EAAE,UAAU,oBAAoB;AAC7C,UAAO,GAAG,UAAU,GAAG,KAAK,OAAO,EAAE,aAAa,cAAc;IAChE,CAE8C,KAAK,OAAO;AAG5D,MAAI,IAAI,SAAS,UAAU,CAUzB,QAAO;GACL;GACA,SAAS;GACT,YAAY,CAZiB;IAC7B,MAAM;IACN,UAAU,SAAS,MAAM,GAAG,EAAE,CAAC,KAAI,OAAM;KACvC,GAAG;KACH,MAAM,sBAAsB,EAAE,IAAI;KACnC,EAAE;IACH,gBAAgB,IAAI;IACrB,CAKwB;GACxB;AAGH,SAAO;GACL;GACA,SAAS;GACV;;CAEJ;AAED,MAAM,eAAkC;CACtC,IAAI;CACJ,MAAM;CACN,aAAa;CACb,UAAU;CACV,OAAO;EAAC;EAAU;EAAW;EAAQ;CACrC,SAAS,OAAO,QAAwB;AACtC,QAAM,IAAI,UAAU,KAAK;EAGzB,MAAM,WAAW,MAAM,IAAI,YAAY;AACvC,QAAM,IAAI,cAAc;AAExB,SAAO;GACL,SAAS,wBAAwB,SAAS,OAAO;GACjD,SAAS;GACV;;CAEJ;AAED,MAAM,eAAkC;CACtC,IAAI;CACJ,MAAM;CACN,SAAS,CAAC,QAAQ,SAAS;CAC3B,aAAa;CACb,UAAU;CACV,OAAO;EAAC;EAAU;EAAW;EAAQ;CACrC,SAAS,OAAO,QAAwB;AACtC,MAAI,CAAC,IAAI,iBACP,QAAO;GACL,SAAS;GACT,SAAS;GACV;AAEH,QAAM,IAAI,kBAAkB;AAC5B,SAAO;GACL,SAAS;GACT,SAAS;GACV;;CAEJ;AAED,MAAM,iBAAoC;CACxC,IAAI;CACJ,MAAM;CACN,aAAa;CACb,UAAU;CACV,OAAO;EAAC;EAAU;EAAW;EAAQ;CACrC,SAAS,OAAO,QAAwB;AACtC,QAAM,IAAI,UAAU,KAAK;AAEzB,QAAM,IAAI,gBAAgB;AAE1B,SAAO;GACL,SAAS;GACT,SAAS;GACV;;CAEJ;AAGD,SAAgB,0BAAgC;AAC9C,iBAAgB,SAAS,WAAW;AACpC,iBAAgB,SAAS,YAAY;AACrC,iBAAgB,SAAS,aAAa;AACtC,iBAAgB,SAAS,aAAa;AACtC,iBAAgB,SAAS,eAAe"}
1
+ {"version":3,"file":"session.js","names":[],"sources":["../../../../src/chat-commands/builtins/session.ts"],"sourcesContent":["/**\n * Session Commands\n * \n * Built-in commands for session management:\n * - /new - Start a new session\n * - /list - List all sessions\n * - /switch - Switch to a different session\n * - /clear - Clear current session without archiving\n * - /abort - Cancel in-flight assistant reply (generation / streaming)\n */\n\nimport type { CommandDefinition, CommandContext, UIComponent } from '../types.js';\nimport { commandRegistry } from '../registry.js';\nimport { getSessionDisplayName } from '../session-key.js';\n\nconst newCommand: CommandDefinition = {\n id: 'session.new',\n name: 'new',\n aliases: ['reset', 'restart'],\n description: 'Start a new session (archive current)',\n category: 'session',\n scope: ['global', 'private', 'group'],\n handler: async (ctx: CommandContext) => {\n await ctx.setTyping(true);\n \n await ctx.clearSession();\n \n // Note: clearSession already sends confirmation message\n return {\n content: '',\n success: true,\n };\n },\n};\n\nconst listCommand: CommandDefinition = {\n id: 'session.list',\n name: 'list',\n aliases: ['sessions'],\n description: 'List all your sessions',\n category: 'session',\n scope: ['global', 'private', 'group'],\n handler: async (ctx: CommandContext) => {\n await ctx.setTyping(true);\n \n const sessions = await ctx.listSessions();\n \n if (sessions.length === 0) {\n return {\n content: '📋 No sessions found.',\n success: true,\n };\n }\n \n // Sort by updatedAt desc\n sessions.sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime());\n \n // Build text response\n const lines = sessions.slice(0, 10).map(s => {\n const indicator = s.isActive ? '▶️' : ' ';\n const name = getSessionDisplayName(s.key);\n const date = s.updatedAt.toLocaleDateString();\n return `${indicator} ${name}\\n ${s.messageCount} messages · ${date}`;\n });\n \n const content = '📋 Your Sessions:\\n\\n' + lines.join('\\n\\n');\n \n // Create UI component if supported\n if (ctx.supports('buttons')) {\n const component: UIComponent = {\n type: 'session-list',\n sessions: sessions.slice(0, 5).map(s => ({\n ...s,\n name: getSessionDisplayName(s.key),\n })),\n currentSession: ctx.sessionKey,\n };\n \n return {\n content,\n success: true,\n components: [component],\n };\n }\n \n return {\n content,\n success: true,\n };\n },\n};\n\nconst clearCommand: CommandDefinition = {\n id: 'session.clear',\n name: 'clear',\n description: 'Clear current session without archiving',\n category: 'session',\n scope: ['global', 'private', 'group'],\n handler: async (ctx: CommandContext) => {\n await ctx.setTyping(true);\n \n // Just delete without archiving\n const messages = await ctx.getSession();\n await ctx.clearSession();\n \n return {\n content: `🗑️ Session cleared. ${messages.length} messages deleted.`,\n success: true,\n };\n },\n};\n\nconst abortCommand: CommandDefinition = {\n id: 'session.abort',\n name: 'abort',\n aliases: ['stop', 'cancel'],\n description: 'Stop the current assistant reply (in-flight generation or stream)',\n category: 'session',\n scope: ['global', 'private', 'group'],\n handler: async (ctx: CommandContext) => {\n if (!ctx.abortCurrentTurn) {\n return {\n content: 'Abort is not available in this environment.',\n success: false,\n };\n }\n await ctx.abortCurrentTurn();\n return {\n content: '⏹️ Current reply cancelled.',\n success: true,\n };\n },\n};\n\nconst compactCommand: CommandDefinition = {\n id: 'session.compact',\n name: 'compact',\n description: 'Compact session history (LLM summary + keep recent turns) to save context',\n category: 'session',\n scope: ['global', 'private', 'group'],\n acceptsArgs: true,\n examples: ['/compact', '/compact focus on API design'],\n handler: async (ctx: CommandContext, args: string) => {\n await ctx.setTyping(true);\n const instructions = args.trim() || undefined;\n const result = await ctx.compactSession?.({ instructions, force: true });\n if (result === null || result === undefined) {\n return {\n content: '⚠️ Session compaction is not available in this environment.',\n success: false,\n };\n }\n if (!result.compacted) {\n return {\n content:\n 'ℹ️ Nothing to compact yet. Need at least two messages, or the session is already small.\\n' +\n 'Tip: add optional focus text, e.g. `/compact emphasize decisions about auth`.',\n success: true,\n };\n }\n const preview =\n result.summary && result.summary.length > 600\n ? `${result.summary.slice(0, 600)}…`\n : result.summary || '';\n return {\n content:\n `🗜️ *Session compacted*\\n\\n` +\n `Tokens (approx): ${result.tokensBefore} → ${result.tokensAfter}\\n\\n` +\n (preview ? `*Summary:*\\n${preview}` : ''),\n success: true,\n };\n },\n};\n\nconst btwCommand: CommandDefinition = {\n id: 'session.btw',\n name: 'btw',\n aliases: ['aside'],\n description: 'Ask a side question without adding to the session transcript',\n category: 'session',\n scope: ['global', 'private', 'group'],\n acceptsArgs: true,\n examples: ['/btw What does that error code mean?', '/aside Summarize the last topic in one line'],\n handler: async (ctx: CommandContext, args: string) => {\n await ctx.setTyping(true);\n const q = args.trim();\n if (!q) {\n return {\n content:\n '💬 *Side question*\\n\\n' +\n 'Usage: `/btw <question>`\\n' +\n 'Answers use your current chat as background only; the reply is not saved to the session.',\n success: true,\n };\n }\n const out = await ctx.btwQuery?.(q);\n if (!out) {\n return { content: '⚠️ /btw is not available here.', success: false };\n }\n if (out.error) {\n return { content: `⚠️ ${out.error}`, success: false };\n }\n return { content: `💬 *BTW*\\n\\n${out.text}`, success: true };\n },\n};\n\nconst exportSessionCommand: CommandDefinition = {\n id: 'session.export',\n name: 'export-session',\n aliases: ['export'],\n description: 'Export this session to workspace exports/ (markdown, html, or json)',\n category: 'session',\n scope: ['global', 'private', 'group'],\n acceptsArgs: true,\n examples: ['/export-session', '/export-session html', '/export json'],\n handler: async (ctx: CommandContext, args: string) => {\n await ctx.setTyping(true);\n const raw = args.trim().toLowerCase();\n const fmt =\n raw === 'json' || raw === 'html' || raw === 'markdown'\n ? (raw as 'json' | 'html' | 'markdown')\n : 'markdown';\n if (!ctx.exportSessionToWorkspace) {\n return { content: '⚠️ Export is not available in this environment.', success: false };\n }\n try {\n const { path } = await ctx.exportSessionToWorkspace(fmt);\n return {\n content: `📄 Exported (${fmt}) to:\\n\\`${path}\\``,\n success: true,\n };\n } catch (e) {\n const em = e instanceof Error ? e.message : String(e);\n return { content: `⚠️ Export failed: ${em}`, success: false };\n }\n },\n};\n\nconst archiveCommand: CommandDefinition = {\n id: 'session.archive',\n name: 'archive',\n description: 'Archive current session',\n category: 'session',\n scope: ['global', 'private', 'group'],\n handler: async (ctx: CommandContext) => {\n await ctx.setTyping(true);\n \n await ctx.archiveSession();\n \n return {\n content: '📦 Current session has been archived.',\n success: true,\n };\n },\n};\n\n// Register all session commands\nexport function registerSessionCommands(): void {\n commandRegistry.register(newCommand);\n commandRegistry.register(listCommand);\n commandRegistry.register(clearCommand);\n commandRegistry.register(abortCommand);\n commandRegistry.register(compactCommand);\n commandRegistry.register(btwCommand);\n commandRegistry.register(exportSessionCommand);\n commandRegistry.register(archiveCommand);\n}\n"],"mappings":"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"}
@@ -1,6 +1,19 @@
1
+ import { applyConfigOverrides, setConfigOverride } from "../../config/runtime-overrides.js";
1
2
  import { formatThinkingLevels, normalizeReasoningLevel, normalizeThinkLevel, normalizeVerboseLevel } from "../../agent/transcript/thinking-types.js";
2
3
  import { commandRegistry } from "../registry.js";
3
4
  //#region src/chat-commands/builtins/thinking.ts
5
+ function effectiveAgentDefaults(ctx) {
6
+ return applyConfigOverrides(ctx.getConfig?.() ?? ctx.config).agents?.defaults;
7
+ }
8
+ async function stripSessionAgentFields(store, sessionKey, fields) {
9
+ if (!store) return;
10
+ const existing = await store.get(sessionKey);
11
+ if (!existing) return;
12
+ const next = { ...existing };
13
+ for (const f of fields) delete next[f];
14
+ if (Object.keys(next).filter((k) => k !== "updatedAt").length === 0) await store.delete(sessionKey);
15
+ else await store.set(sessionKey, next);
16
+ }
4
17
  const thinkCommand = {
5
18
  id: "agent.think",
6
19
  name: "think",
@@ -20,9 +33,8 @@ const thinkCommand = {
20
33
  ],
21
34
  handler: async (ctx, args) => {
22
35
  await ctx.setTyping(true);
23
- const extendedCtx = ctx;
24
36
  if (!args.trim()) return {
25
- content: `🧠 *Thinking Level*\n\nCurrent: *${await extendedCtx.getThinkingLevel?.() || ctx.getConfig()?.agents?.defaults?.thinkingDefault || "default"}*\n\nAvailable levels:\n• off - No thinking\n• minimal - Minimal thinking\n• low - Low thinking\n• medium - Medium thinking (default)\n• high - High thinking\n• xhigh - Extra high (certain models)\n• adaptive - Auto-adjust based on task\n\nUsage: /think <level>\nExample: /think high`,
37
+ content: `🧠 *Thinking Level*\n\nCurrent: *${(await ctx.getThinkingLevel?.() ?? effectiveAgentDefaults(ctx)?.thinkingDefault) || "default"}*\n\nAvailable levels:\n• off - No thinking\n• minimal - Minimal thinking\n• low - Low thinking\n• medium - Medium thinking (default)\n• high - High thinking\n• xhigh - Extra high (certain models)\n• adaptive - Auto-adjust based on task\n\nUsage: /think <level>\nExample: /think high`,
26
38
  success: true
27
39
  };
28
40
  const level = normalizeThinkLevel(args.trim());
@@ -30,7 +42,13 @@ const thinkCommand = {
30
42
  content: `❌ Invalid thinking level: ${args}\n\nAvailable levels: ${formatThinkingLevels()}\n\nUsage: /think <level>\nExample: /think high`,
31
43
  success: false
32
44
  };
33
- if (ctx.setThinkingLevel) await ctx.setThinkingLevel(level);
45
+ setConfigOverride([
46
+ "agents",
47
+ "defaults",
48
+ "thinkingDefault"
49
+ ], level);
50
+ await stripSessionAgentFields(ctx.getSessionConfigStore?.(), ctx.sessionKey, ["thinkingLevel"]);
51
+ ctx.syncAgentThinkingLevel?.(level);
34
52
  return {
35
53
  content: `🧠 *Thinking Level Set*\n\nLevel: *${level}*\n${{
36
54
  off: "No thinking",
@@ -40,7 +58,7 @@ const thinkCommand = {
40
58
  high: "High thinking effort",
41
59
  xhigh: "Extra high thinking effort",
42
60
  adaptive: "Auto-adjust based on task complexity"
43
- }[level]}\n\nThis setting will apply to your next message.`,
61
+ }[level]}\n\nApplies for this gateway process (until restart). Persists only if you use /config set.`,
44
62
  success: true
45
63
  };
46
64
  }
@@ -64,10 +82,8 @@ const reasoningCommand = {
64
82
  ],
65
83
  handler: async (ctx, args) => {
66
84
  await ctx.setTyping(true);
67
- const extendedCtx = ctx;
68
- const configStore = extendedCtx.getSessionConfigStore?.();
69
85
  if (!args.trim()) return {
70
- content: `💭 *Reasoning Visibility*\n\nCurrent: *${await extendedCtx.getReasoningLevel?.() || ctx.getConfig()?.agents?.defaults?.reasoningDefault || "default"}*\n\nAvailable modes:\n• off - Hide reasoning\n• on - Show reasoning after completion\n• stream - Stream reasoning in real-time\n\nUsage: /reasoning <mode>\nExample: /reasoning stream`,
86
+ content: `💭 *Reasoning Visibility*\n\nCurrent: *${(await ctx.getReasoningLevel?.() ?? effectiveAgentDefaults(ctx)?.reasoningDefault) || "default"}*\n\nAvailable modes:\n• off - Hide reasoning\n• on - Show reasoning after completion\n• stream - Stream reasoning in real-time\n\nUsage: /reasoning <mode>\nExample: /reasoning stream`,
71
87
  success: true
72
88
  };
73
89
  const level = normalizeReasoningLevel(args.trim());
@@ -75,13 +91,18 @@ const reasoningCommand = {
75
91
  content: `❌ Invalid reasoning mode: ${args}\n\nAvailable modes: off, on, stream\n\nUsage: /reasoning <mode>\nExample: /reasoning stream`,
76
92
  success: false
77
93
  };
78
- if (configStore) await configStore.update(ctx.sessionKey, { reasoningLevel: level });
94
+ setConfigOverride([
95
+ "agents",
96
+ "defaults",
97
+ "reasoningDefault"
98
+ ], level);
99
+ await stripSessionAgentFields(ctx.getSessionConfigStore?.(), ctx.sessionKey, ["reasoningLevel"]);
79
100
  return {
80
101
  content: `💭 *Reasoning Visibility Set*\n\nMode: *${level}*\n${{
81
102
  off: "Hide reasoning from user",
82
103
  on: "Show reasoning after completion",
83
104
  stream: "Stream reasoning in real-time"
84
- }[level]}\n\nThis setting will apply to your next message.`,
105
+ }[level]}\n\nApplies for this gateway process (until restart). Persists only if you use /config set.`,
85
106
  success: true
86
107
  };
87
108
  }
@@ -105,13 +126,16 @@ const verboseCommand = {
105
126
  ],
106
127
  handler: async (ctx, args) => {
107
128
  await ctx.setTyping(true);
108
- const extendedCtx = ctx;
109
- const configStore = extendedCtx.getSessionConfigStore?.();
110
129
  if (!args.trim()) {
111
- const newLevel = (await extendedCtx.getVerboseLevel?.() || ctx.getConfig()?.agents?.defaults?.verboseDefault) === "on" ? "off" : "on";
112
- if (configStore) await configStore.update(ctx.sessionKey, { verboseLevel: newLevel });
130
+ const newLevel = (await ctx.getVerboseLevel?.() ?? effectiveAgentDefaults(ctx)?.verboseDefault) === "on" ? "off" : "on";
131
+ setConfigOverride([
132
+ "agents",
133
+ "defaults",
134
+ "verboseDefault"
135
+ ], newLevel);
136
+ await stripSessionAgentFields(ctx.getSessionConfigStore?.(), ctx.sessionKey, ["verboseLevel"]);
113
137
  return {
114
- content: `📝 *Verbose Mode*\n\nMode: *${newLevel}*\n\n${newLevel === "on" ? "Verbose output enabled for next message." : "Verbose output disabled."}`,
138
+ content: `📝 *Verbose Mode*\n\nMode: *${newLevel}*\n\n${newLevel === "on" ? "Verbose output enabled (process lifetime)." : "Verbose output disabled (process lifetime)."}`,
115
139
  success: true
116
140
  };
117
141
  }
@@ -120,13 +144,18 @@ const verboseCommand = {
120
144
  content: `❌ Invalid verbose mode: ${args}\n\nAvailable modes: off, on, full\n\nUsage: /verbose [mode]\nExample: /verbose on`,
121
145
  success: false
122
146
  };
123
- if (configStore) await configStore.update(ctx.sessionKey, { verboseLevel: level });
147
+ setConfigOverride([
148
+ "agents",
149
+ "defaults",
150
+ "verboseDefault"
151
+ ], level);
152
+ await stripSessionAgentFields(ctx.getSessionConfigStore?.(), ctx.sessionKey, ["verboseLevel"]);
124
153
  return {
125
154
  content: `📝 *Verbose Mode Set*\n\nMode: *${level}*\n${{
126
155
  off: "Minimal output",
127
156
  on: "Normal verbose output",
128
157
  full: "Full verbose output with all details"
129
- }[level]}`,
158
+ }[level]}\n\nApplies for this gateway process (until restart). Persists only if you use /config set.`,
130
159
  success: true
131
160
  };
132
161
  }
@@ -143,12 +172,11 @@ const enhancedStatusCommand = {
143
172
  ],
144
173
  handler: async (ctx) => {
145
174
  await ctx.setTyping(true);
146
- const extendedCtx = ctx;
147
- const config = ctx.getConfig();
175
+ const defaults = effectiveAgentDefaults(ctx);
148
176
  const currentModel = ctx.getCurrentModel();
149
- const thinkingLevel = await extendedCtx.getThinkingLevel?.() || config.agents?.defaults?.thinkingDefault;
150
- const reasoningLevel = await extendedCtx.getReasoningLevel?.() || config.agents?.defaults?.reasoningDefault;
151
- const verboseLevel = await extendedCtx.getVerboseLevel?.() || config.agents?.defaults?.verboseDefault;
177
+ const thinkingLevel = await ctx.getThinkingLevel?.() ?? defaults?.thinkingDefault;
178
+ const reasoningLevel = await ctx.getReasoningLevel?.() ?? defaults?.reasoningDefault;
179
+ const verboseLevel = await ctx.getVerboseLevel?.() ?? defaults?.verboseDefault;
152
180
  const usage = await ctx.getUsage();
153
181
  return {
154
182
  content: [