@xopcai/xopc 0.0.118 → 0.0.119

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 (468) hide show
  1. package/README.md +2 -1
  2. package/README.zh-CN.md +2 -1
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/telegram/xopc.extension.json +1 -1
  5. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-dzUrQoeZ.js → agent-avatar-dicebear-CU8J6zou.js} +1 -1
  6. package/dist/gateway/static/root/assets/agents-B0hkpLhP.js +2 -0
  7. package/dist/gateway/static/root/assets/app-management-settings-panel-B9vfYoEr.js +1 -0
  8. package/dist/gateway/static/root/assets/appearance-settings-ClOzIO24.js +1 -0
  9. package/dist/gateway/static/root/assets/{apps-page--wMEL00f.js → apps-page-DU0dz9Zo.js} +1 -1
  10. package/dist/gateway/static/root/assets/{archive-plugin-Cki4SfU2.js → archive-plugin-BkVIgZzA.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-D-KnS2Do.js → attachment-load-CaCMWh1D.js} +1 -1
  12. package/dist/gateway/static/root/assets/automation-suggestion-card-DhGDpKP3.js +1 -0
  13. package/dist/gateway/static/root/assets/automations-page-CTedroVo.js +1 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-D2sgvJja.js → binary-plugins-B4TO_bsn.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-DIq-4Gvb.js → block-editor-DJRWwWNI.js} +28 -28
  16. package/dist/gateway/static/root/assets/browser-settings-page-FCDwOOBK.js +8 -0
  17. package/dist/gateway/static/root/assets/capability-presets-api-Befi89CL.js +1 -0
  18. package/dist/gateway/static/root/assets/capability-presets-settings-panel-_G8eb2vJ.js +1 -0
  19. package/dist/gateway/static/root/assets/channel-recipient-api-BNSuJb5f.js +1 -0
  20. package/dist/gateway/static/root/assets/channels-settings-C3d5JBJX.js +1 -0
  21. package/dist/gateway/static/root/assets/cn-BQ_8x0bT.js +1 -0
  22. package/dist/gateway/static/root/assets/connectors-page-yaUNvt5u.js +2 -0
  23. package/dist/gateway/static/root/assets/cron-expression-B3B1eqnr.js +2 -0
  24. package/dist/gateway/static/root/assets/dreaming-settings-DNrdg1Ve.js +1 -0
  25. package/dist/gateway/static/root/assets/{extension-debug-page-DYu1KaFQ.js → extension-debug-page-DYh402XV.js} +1 -1
  26. package/dist/gateway/static/root/assets/{extension-page-B3W6QwlZ.js → extension-page-Cr_TizrN.js} +1 -1
  27. package/dist/gateway/static/root/assets/{extension-settings-page-D7VQ-cxE.js → extension-settings-page-BU1KoKRj.js} +1 -1
  28. package/dist/gateway/static/root/assets/{fetch-B7xDPu-R.js → fetch-Y7AEX4H3.js} +1 -1
  29. package/dist/gateway/static/root/assets/format-cron-label-arqgGlVV.js +1 -0
  30. package/dist/gateway/static/root/assets/{gateway-config-api-BTBLSeUu.js → gateway-config-api-RbMmAOpX.js} +1 -1
  31. package/dist/gateway/static/root/assets/gateway-settings-C79wkXef.js +1 -0
  32. package/dist/gateway/static/root/assets/{gateway-startup-retry-CYj9FWCp.js → gateway-startup-retry-DiD_Tx4N.js} +1 -1
  33. package/dist/gateway/static/root/assets/goal-detail-page-9paXuHdo.js +1 -0
  34. package/dist/gateway/static/root/assets/{goals-config-api-CQQgzPr3.js → goals-config-api-DqxVi0p5.js} +1 -1
  35. package/dist/gateway/static/root/assets/{goals-page-BHitvJAv.js → goals-page-CS0R-Af2.js} +2 -2
  36. package/dist/gateway/static/root/assets/goals-settings-CSuzZ8Ae.js +1 -0
  37. package/dist/gateway/static/root/assets/heartbeat-settings-DXPaYJm3.js +1 -0
  38. package/dist/gateway/static/root/assets/index-BoKafJIZ.js +191 -0
  39. package/dist/gateway/static/root/assets/index-CArhCcYn.css +1 -0
  40. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-Dvg53qnd.js +1 -0
  41. package/dist/gateway/static/root/assets/{logs-page-C2Uqvae9.js → logs-page-DLXPcksQ.js} +2 -2
  42. package/dist/gateway/static/root/assets/{markdown-split-BwOFrJ2E.js → markdown-split-CpHxbtWJ.js} +1 -1
  43. package/dist/gateway/static/root/assets/{media-plugins-Cnz6Q5G6.js → media-plugins-SFPQRSxq.js} +1 -1
  44. package/dist/gateway/static/root/assets/messages-CrDHEbss.js +3 -0
  45. package/dist/gateway/static/root/assets/models-hub-panel-BDF2iyRk.js +2 -0
  46. package/dist/gateway/static/root/assets/note-detail-page-CSb_hwig.js +2 -0
  47. package/dist/gateway/static/root/assets/{note-image-lightbox-B-Svpmza.js → note-image-lightbox-BUYURRgn.js} +1 -1
  48. package/dist/gateway/static/root/assets/notes-page-BsIBSFyZ.js +1 -0
  49. package/dist/gateway/static/root/assets/{preview-open-alternatives-Bss4TiwP.js → preview-open-alternatives-BHz9iWYA.js} +1 -1
  50. package/dist/gateway/static/root/assets/remote-access-hub-CwzSovcS.js +1 -0
  51. package/dist/gateway/static/root/assets/{save-bar-controls-BRNjdgKq.js → save-bar-controls-CefkOlRg.js} +1 -1
  52. package/dist/gateway/static/root/assets/schedule-field-CmTRoOcE.js +1 -0
  53. package/dist/gateway/static/root/assets/{schema-form-Dub9sy8r.js → schema-form-FMKv1vGu.js} +1 -1
  54. package/dist/gateway/static/root/assets/sessions-page-PHmX-NmA.js +1 -0
  55. package/dist/gateway/static/root/assets/settings-advanced-gate-BRAeKJN4.js +1 -0
  56. package/dist/gateway/static/root/assets/{settings-collapsible-section-BeFLavGi.js → settings-collapsible-section-BouO6JTi.js} +1 -1
  57. package/dist/gateway/static/root/assets/{settings-form-section-dmyaPOTG.js → settings-form-section-D-4lBl6X.js} +1 -1
  58. package/dist/gateway/static/root/assets/settings-page-KKrbFjy8.js +1 -0
  59. package/dist/gateway/static/root/assets/settings-page-layout-BJ4Gsef5.js +1 -0
  60. package/dist/gateway/static/root/assets/setup-status-panel-CrUjHPQo.js +1 -0
  61. package/dist/gateway/static/root/assets/{share-preview-page-C8glrdqe.js → share-preview-page-BDy2btRN.js} +1 -1
  62. package/dist/gateway/static/root/assets/shares-settings-B18OBmH5.js +1 -0
  63. package/dist/gateway/static/root/assets/skill-reload-api-C28-2uKQ.js +1 -0
  64. package/dist/gateway/static/root/assets/skills-page-Bm2ebkwl.js +2 -0
  65. package/dist/gateway/static/root/assets/system-settings-panel-CRngrlnZ.js +1 -0
  66. package/dist/gateway/static/root/assets/typed-models-lib-BltBc0b-.js +1 -0
  67. package/dist/gateway/static/root/assets/{use-channel-catalog-DqlWTsDb.js → use-channel-catalog-CjN-51e6.js} +1 -1
  68. package/dist/gateway/static/root/assets/user-profile-settings-panel-DJ1dKwZy.js +1 -0
  69. package/dist/gateway/static/root/assets/utils-B5M5-YvK.js +1 -0
  70. package/dist/gateway/static/root/assets/{voice-api-key-field-C73IVZeC.js → voice-api-key-field-CeEevm7z.js} +1 -1
  71. package/dist/gateway/static/root/assets/{voice-player-store-C_ArLJPM.js → voice-player-store-B7ykUlHM.js} +1 -1
  72. package/dist/gateway/static/root/assets/workflow-run-setup-panel-C4PzUQjB.js +3 -0
  73. package/dist/gateway/static/root/assets/workflows-page-BL84_-Ky.js +18 -0
  74. package/dist/gateway/static/root/index.html +6 -7
  75. package/dist/package.js +1 -1
  76. package/dist/src/agent/agent-manager.d.ts +4 -5
  77. package/dist/src/agent/agent-manager.js +4 -8
  78. package/dist/src/agent/agent-manager.js.map +1 -1
  79. package/dist/src/agent/embedded/run-for-session.js +102 -14
  80. package/dist/src/agent/embedded/run-for-session.js.map +1 -1
  81. package/dist/src/agent/fallback/candidates.d.ts +0 -8
  82. package/dist/src/agent/fallback/candidates.js.map +1 -1
  83. package/dist/src/agent/index.js +1 -1
  84. package/dist/src/agent/lifecycle/handlers/compaction.d.ts +1 -3
  85. package/dist/src/agent/lifecycle/handlers/compaction.js +1 -16
  86. package/dist/src/agent/lifecycle/handlers/compaction.js.map +1 -1
  87. package/dist/src/agent/lifecycle/progress.d.ts +0 -1
  88. package/dist/src/agent/lifecycle/progress.js +1 -6
  89. package/dist/src/agent/lifecycle/progress.js.map +1 -1
  90. package/dist/src/agent/lifecycle/timeout-wrapper.d.ts +1 -2
  91. package/dist/src/agent/lifecycle/timeout-wrapper.js +1 -7
  92. package/dist/src/agent/lifecycle/timeout-wrapper.js.map +1 -1
  93. package/dist/src/agent/middleware/self-verify.d.ts +0 -1
  94. package/dist/src/agent/middleware/self-verify.js +0 -2
  95. package/dist/src/agent/middleware/self-verify.js.map +1 -1
  96. package/dist/src/agent/models/index.d.ts +1 -1
  97. package/dist/src/agent/models/manager.d.ts +4 -20
  98. package/dist/src/agent/models/manager.js +9 -126
  99. package/dist/src/agent/models/manager.js.map +1 -1
  100. package/dist/src/agent/orchestration/agent-orchestrator.d.ts +0 -4
  101. package/dist/src/agent/orchestration/agent-orchestrator.js +1 -9
  102. package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
  103. package/dist/src/agent/prompt/sections/tooling.js +2 -2
  104. package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
  105. package/dist/src/agent/prompt/service-prompt-builder.d.ts +0 -1
  106. package/dist/src/agent/prompt/service-prompt-builder.js +0 -12
  107. package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
  108. package/dist/src/agent/prompt/subagent-context.js +1 -1
  109. package/dist/src/agent/prompt/subagent-context.js.map +1 -1
  110. package/dist/src/agent/prompt/types.d.ts +1 -1
  111. package/dist/src/agent/service.d.ts +1 -9
  112. package/dist/src/agent/service.js +3 -40
  113. package/dist/src/agent/service.js.map +1 -1
  114. package/dist/src/agent/service.types.d.ts +2 -2
  115. package/dist/src/agent/session/session-config-service.d.ts +11 -11
  116. package/dist/src/agent/session/session-config-service.js +14 -14
  117. package/dist/src/agent/session/session-config-service.js.map +1 -1
  118. package/dist/src/agent/session/session-inspector.js +3 -2
  119. package/dist/src/agent/session/session-inspector.js.map +1 -1
  120. package/dist/src/agent/starter-agents.js +12 -12
  121. package/dist/src/agent/starter-agents.js.map +1 -1
  122. package/dist/src/agent/tools/automation-tool.d.ts +14 -0
  123. package/dist/src/agent/tools/automation-tool.js +102 -0
  124. package/dist/src/agent/tools/automation-tool.js.map +1 -0
  125. package/dist/src/agent/tools/delegate-tool.js +1 -1
  126. package/dist/src/agent/tools/delegate-tool.js.map +1 -1
  127. package/dist/src/agent/tools/factory.d.ts +3 -3
  128. package/dist/src/agent/tools/factory.js +2 -2
  129. package/dist/src/agent/tools/factory.js.map +1 -1
  130. package/dist/src/agent/tools/index.d.ts +1 -1
  131. package/dist/src/agent/tools/index.js +2 -2
  132. package/dist/src/agent-manifest/resolver.d.ts +1 -0
  133. package/dist/src/agent-manifest/resolver.js +1 -0
  134. package/dist/src/agent-manifest/resolver.js.map +1 -1
  135. package/dist/src/agent-manifest/schema.d.ts +6 -0
  136. package/dist/src/agent-manifest/schema.js +12 -3
  137. package/dist/src/agent-manifest/schema.js.map +1 -1
  138. package/dist/src/ai-assist/text-assist.d.ts +1 -1
  139. package/dist/src/ai-assist/text-assist.js +56 -0
  140. package/dist/src/ai-assist/text-assist.js.map +1 -1
  141. package/dist/src/auth/profiles/store.js.map +1 -1
  142. package/dist/src/automations/api/routes.d.ts +3 -0
  143. package/dist/src/automations/api/routes.js +193 -0
  144. package/dist/src/automations/api/routes.js.map +1 -0
  145. package/dist/src/automations/domain/index.d.ts +3 -0
  146. package/dist/src/automations/domain/index.js +3 -0
  147. package/dist/src/automations/domain/schedule.d.ts +4 -0
  148. package/dist/src/automations/domain/schedule.js +37 -0
  149. package/dist/src/automations/domain/schedule.js.map +1 -0
  150. package/dist/src/automations/domain/types.d.ts +160 -0
  151. package/dist/src/automations/domain/validation.d.ts +370 -0
  152. package/dist/src/automations/domain/validation.js +149 -0
  153. package/dist/src/automations/domain/validation.js.map +1 -0
  154. package/dist/src/automations/draft/automation-draft-prompt.d.ts +26 -0
  155. package/dist/src/automations/draft/automation-draft-prompt.js +127 -0
  156. package/dist/src/automations/draft/automation-draft-prompt.js.map +1 -0
  157. package/dist/src/automations/draft/automation-draft-service.d.ts +12 -0
  158. package/dist/src/automations/draft/automation-draft-service.js +135 -0
  159. package/dist/src/automations/draft/automation-draft-service.js.map +1 -0
  160. package/dist/src/automations/draft/automation-draft-validator.d.ts +99 -0
  161. package/dist/src/automations/draft/automation-draft-validator.js +105 -0
  162. package/dist/src/automations/draft/automation-draft-validator.js.map +1 -0
  163. package/dist/src/automations/draft/automation-draft.types.d.ts +40 -0
  164. package/dist/src/automations/draft/index.d.ts +3 -0
  165. package/dist/src/automations/draft/index.js +3 -0
  166. package/dist/src/automations/index.d.ts +3 -0
  167. package/dist/src/automations/index.js +8 -0
  168. package/dist/src/automations/product-events.d.ts +5 -0
  169. package/dist/src/automations/product-events.js +21 -0
  170. package/dist/src/automations/product-events.js.map +1 -0
  171. package/dist/src/automations/service/action-executor.d.ts +9 -0
  172. package/dist/src/automations/service/action-executor.js +157 -0
  173. package/dist/src/automations/service/action-executor.js.map +1 -0
  174. package/dist/src/automations/service/automation-service.d.ts +54 -0
  175. package/dist/src/automations/service/automation-service.js +404 -0
  176. package/dist/src/automations/service/automation-service.js.map +1 -0
  177. package/dist/src/automations/service/index.d.ts +2 -0
  178. package/dist/src/automations/service/index.js +3 -0
  179. package/dist/src/automations/storage/automation-repository.d.ts +6 -0
  180. package/dist/src/automations/storage/automation-repository.js +61 -0
  181. package/dist/src/automations/storage/automation-repository.js.map +1 -0
  182. package/dist/src/automations/storage/automation-run-repository.d.ts +17 -0
  183. package/dist/src/automations/storage/automation-run-repository.js +130 -0
  184. package/dist/src/automations/storage/automation-run-repository.js.map +1 -0
  185. package/dist/src/automations/storage/index.d.ts +2 -0
  186. package/dist/src/automations/storage/index.js +3 -0
  187. package/dist/src/channels/plugin-types.d.ts +3 -0
  188. package/dist/src/chat-commands/builtins/thinking.js.map +1 -1
  189. package/dist/src/cli/command-catalog.js +0 -39
  190. package/dist/src/cli/command-catalog.js.map +1 -1
  191. package/dist/src/cli/command-loaders.js +0 -1
  192. package/dist/src/cli/command-loaders.js.map +1 -1
  193. package/dist/src/cli/command-manifest.js +0 -4
  194. package/dist/src/cli/command-manifest.js.map +1 -1
  195. package/dist/src/cli/commands/agents.js +7 -6
  196. package/dist/src/cli/commands/agents.js.map +1 -1
  197. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  198. package/dist/src/cli/commands/doctor/checks/{cron-health.d.ts → migrations.d.ts} +1 -1
  199. package/dist/src/cli/commands/doctor/checks/migrations.js +40 -0
  200. package/dist/src/cli/commands/doctor/checks/migrations.js.map +1 -0
  201. package/dist/src/cli/commands/doctor/flow.js +2 -2
  202. package/dist/src/cli/commands/doctor/flow.js.map +1 -1
  203. package/dist/src/cli/commands/gateway/call.js +2 -2
  204. package/dist/src/cli/commands/gateway/call.js.map +1 -1
  205. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  206. package/dist/src/cli/commands/gateway/run-foreground.js +4 -2
  207. package/dist/src/cli/commands/gateway/run-foreground.js.map +1 -1
  208. package/dist/src/cli/commands/init.js +26 -8
  209. package/dist/src/cli/commands/init.js.map +1 -1
  210. package/dist/src/cli/commands/tui.js +24 -2
  211. package/dist/src/cli/commands/tui.js.map +1 -1
  212. package/dist/src/cli/utils/init-workspace-core.js +2 -0
  213. package/dist/src/cli/utils/init-workspace-core.js.map +1 -1
  214. package/dist/src/commands/agents.config.d.ts +9 -0
  215. package/dist/src/commands/agents.config.js +40 -2
  216. package/dist/src/commands/agents.config.js.map +1 -1
  217. package/dist/src/config/agent-profile.js +4 -3
  218. package/dist/src/config/agent-profile.js.map +1 -1
  219. package/dist/src/config/agent-typed-models.js.map +1 -1
  220. package/dist/src/config/config-surface.d.ts +3 -0
  221. package/dist/src/config/index.d.ts +0 -1
  222. package/dist/src/config/index.js +3 -3
  223. package/dist/src/config/index.js.map +1 -1
  224. package/dist/src/config/paths.d.ts +0 -9
  225. package/dist/src/config/paths.js +1 -14
  226. package/dist/src/config/paths.js.map +1 -1
  227. package/dist/src/config/profile.js +0 -1
  228. package/dist/src/config/profile.js.map +1 -1
  229. package/dist/src/config/rules.js +0 -5
  230. package/dist/src/config/rules.js.map +1 -1
  231. package/dist/src/config/schema.d.ts +13 -12
  232. package/dist/src/config/schema.js +22 -26
  233. package/dist/src/config/schema.js.map +1 -1
  234. package/dist/src/config/web-patch.d.ts +0 -12
  235. package/dist/src/config/web-patch.js +2 -29
  236. package/dist/src/config/web-patch.js.map +1 -1
  237. package/dist/src/extensions/api.d.ts +2 -0
  238. package/dist/src/extensions/api.js +10 -0
  239. package/dist/src/extensions/api.js.map +1 -1
  240. package/dist/src/extensions/extension-registry-impl.d.ts +4 -1
  241. package/dist/src/extensions/extension-registry-impl.js +8 -0
  242. package/dist/src/extensions/extension-registry-impl.js.map +1 -1
  243. package/dist/src/extensions/loader.d.ts +3 -3
  244. package/dist/src/extensions/loader.js +3 -3
  245. package/dist/src/extensions/loader.js.map +1 -1
  246. package/dist/src/extensions/sdk/testing.d.ts +2 -0
  247. package/dist/src/extensions/sdk/testing.js +7 -0
  248. package/dist/src/extensions/sdk/testing.js.map +1 -1
  249. package/dist/src/extensions/types/core.d.ts +10 -1
  250. package/dist/src/extensions/types/index.d.ts +1 -1
  251. package/dist/src/extensions/types/{phase4.d.ts → registration.d.ts} +2 -2
  252. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  253. package/dist/src/gateway/agent-builtin-tools.js +1 -1
  254. package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
  255. package/dist/src/gateway/agents-admin.d.ts +1 -0
  256. package/dist/src/gateway/agents-admin.js +13 -15
  257. package/dist/src/gateway/agents-admin.js.map +1 -1
  258. package/dist/src/gateway/capability-presets-admin.d.ts +1 -0
  259. package/dist/src/gateway/capability-presets-admin.js +19 -10
  260. package/dist/src/gateway/capability-presets-admin.js.map +1 -1
  261. package/dist/src/gateway/dreaming-automation-reconciler.d.ts +11 -0
  262. package/dist/src/gateway/dreaming-automation-reconciler.js +105 -0
  263. package/dist/src/gateway/dreaming-automation-reconciler.js.map +1 -0
  264. package/dist/src/gateway/heartbeat/service.d.ts +0 -2
  265. package/dist/src/gateway/heartbeat/service.js +0 -7
  266. package/dist/src/gateway/heartbeat/service.js.map +1 -1
  267. package/dist/src/gateway/hono/lib/config-payload.d.ts +5 -6
  268. package/dist/src/gateway/hono/lib/config-payload.js +2 -2
  269. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  270. package/dist/src/gateway/hono/routes/agents.js.map +1 -1
  271. package/dist/src/gateway/hono/routes/config-patch/misc.d.ts +1 -1
  272. package/dist/src/gateway/hono/routes/config-patch/misc.js +12 -6
  273. package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -1
  274. package/dist/src/gateway/hono/routes/dreaming.js +27 -37
  275. package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
  276. package/dist/src/gateway/hono/routes/home.d.ts +2 -2
  277. package/dist/src/gateway/hono/routes/home.js +34 -25
  278. package/dist/src/gateway/hono/routes/home.js.map +1 -1
  279. package/dist/src/gateway/hono/routes/lazy-bundles.js +10 -6
  280. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  281. package/dist/src/gateway/hono/routes/migrations.d.ts +3 -0
  282. package/dist/src/gateway/hono/routes/migrations.js +35 -0
  283. package/dist/src/gateway/hono/routes/migrations.js.map +1 -0
  284. package/dist/src/gateway/hono/routes/public-gateway.js +2 -1
  285. package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
  286. package/dist/src/gateway/hono/routes/sessions.js +14 -0
  287. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  288. package/dist/src/gateway/run-loop.js +2 -0
  289. package/dist/src/gateway/run-loop.js.map +1 -1
  290. package/dist/src/gateway/security/operator-scopes.js +5 -1
  291. package/dist/src/gateway/security/operator-scopes.js.map +1 -1
  292. package/dist/src/gateway/service/config-coordinator.d.ts +4 -4
  293. package/dist/src/gateway/service/config-coordinator.js +14 -8
  294. package/dist/src/gateway/service/config-coordinator.js.map +1 -1
  295. package/dist/src/gateway/service/sessions-api.d.ts +2 -1
  296. package/dist/src/gateway/service/sessions-api.js +6 -1
  297. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  298. package/dist/src/gateway/service.d.ts +7 -3
  299. package/dist/src/gateway/service.js +61 -27
  300. package/dist/src/gateway/service.js.map +1 -1
  301. package/dist/src/goals/goal-service.js +45 -4
  302. package/dist/src/goals/goal-service.js.map +1 -1
  303. package/dist/src/infra/update-restart.js +1 -1
  304. package/dist/src/migrations/config/default-capability-preset.d.ts +10 -0
  305. package/dist/src/migrations/config/default-capability-preset.js +135 -0
  306. package/dist/src/migrations/config/default-capability-preset.js.map +1 -0
  307. package/dist/src/migrations/index.d.ts +4 -0
  308. package/dist/src/migrations/index.js +4 -0
  309. package/dist/src/migrations/registry.d.ts +8 -0
  310. package/dist/src/migrations/registry.js +18 -0
  311. package/dist/src/migrations/registry.js.map +1 -0
  312. package/dist/src/migrations/runner.d.ts +17 -0
  313. package/dist/src/migrations/runner.js +191 -0
  314. package/dist/src/migrations/runner.js.map +1 -0
  315. package/dist/src/migrations/types.d.ts +34 -0
  316. package/dist/src/notes/service.js +24 -1
  317. package/dist/src/notes/service.js.map +1 -1
  318. package/dist/src/providers/model-registry.d.ts +0 -1
  319. package/dist/src/providers/model-registry.js +0 -3
  320. package/dist/src/providers/model-registry.js.map +1 -1
  321. package/dist/src/routing/resolve-tui-session-key.d.ts +3 -0
  322. package/dist/src/routing/resolve-tui-session-key.js +14 -3
  323. package/dist/src/routing/resolve-tui-session-key.js.map +1 -1
  324. package/dist/src/session/transcript-outline.d.ts +47 -0
  325. package/dist/src/session/transcript-outline.js +481 -0
  326. package/dist/src/session/transcript-outline.js.map +1 -0
  327. package/dist/src/storage/sqlite/index.d.ts +0 -2
  328. package/dist/src/storage/sqlite/index.js +1 -3
  329. package/dist/src/storage/sqlite/migrations/016_automations.sql +47 -0
  330. package/dist/src/storage/sqlite/migrations/017_automation_run_events.sql +14 -0
  331. package/dist/src/storage/sqlite/migrations/018_automation_safety.sql +1 -0
  332. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  333. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  334. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  335. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  336. package/dist/src/storage/sqlite/schema.js +1 -1
  337. package/dist/src/storage/sqlite/schema.sql +56 -46
  338. package/dist/src/tui/backends/embedded-backend.d.ts +6 -0
  339. package/dist/src/tui/backends/embedded-backend.js +18 -7
  340. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  341. package/dist/src/tui/backends/gateway-sse-backend.d.ts +3 -0
  342. package/dist/src/tui/backends/gateway-sse-backend.js +14 -0
  343. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  344. package/dist/src/tui/tui-backend.d.ts +4 -0
  345. package/dist/src/tui/tui-commands.d.ts +5 -0
  346. package/dist/src/tui/tui-commands.js +43 -0
  347. package/dist/src/tui/tui-commands.js.map +1 -1
  348. package/dist/src/tui/tui-transcript-tree.d.ts +1 -1
  349. package/dist/src/tui/tui-transcript-tree.js +17 -257
  350. package/dist/src/tui/tui-transcript-tree.js.map +1 -1
  351. package/dist/src/tui/tui-types.d.ts +2 -0
  352. package/dist/src/tui/tui-types.js.map +1 -1
  353. package/dist/src/tui/tui.js +7 -2
  354. package/dist/src/tui/tui.js.map +1 -1
  355. package/dist/src/workflows/domain/index.js +1 -1
  356. package/dist/src/workflows/domain/run.d.ts +7 -7
  357. package/dist/src/workflows/domain/run.js.map +1 -1
  358. package/dist/src/workflows/index.js +2 -2
  359. package/dist/src/workflows/service/workflow-run-service.d.ts +2 -0
  360. package/dist/src/workflows/service/workflow-run-service.js +31 -9
  361. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  362. package/dist/src/workflows/service/workflow-run-service.types.d.ts +1 -1
  363. package/package.json +4 -2
  364. package/dist/gateway/static/root/assets/agents-BCxZbkOw.js +0 -2
  365. package/dist/gateway/static/root/assets/app-management-settings-panel-bxYJVJpx.js +0 -1
  366. package/dist/gateway/static/root/assets/appearance-settings-BCIykXlI.js +0 -1
  367. package/dist/gateway/static/root/assets/browser-settings-page-DRhKdn81.js +0 -8
  368. package/dist/gateway/static/root/assets/capability-presets-api-CorhiHlg.js +0 -1
  369. package/dist/gateway/static/root/assets/capability-presets-settings-panel-qFx9Jtce.js +0 -1
  370. package/dist/gateway/static/root/assets/channels-settings-BAwAkqIA.js +0 -1
  371. package/dist/gateway/static/root/assets/cn-JdwAhgNB.js +0 -1
  372. package/dist/gateway/static/root/assets/connectors-page-BQLcfitM.js +0 -2
  373. package/dist/gateway/static/root/assets/createLucideIcon-DPHK1VkS.js +0 -1
  374. package/dist/gateway/static/root/assets/cron-api-qGwmL-24.js +0 -1
  375. package/dist/gateway/static/root/assets/cron-dreaming-jobs-nCMWCf0p.js +0 -1
  376. package/dist/gateway/static/root/assets/cron-page-BBWMAj8-.js +0 -3
  377. package/dist/gateway/static/root/assets/dreaming-settings-Dw89Obml.js +0 -1
  378. package/dist/gateway/static/root/assets/format-cron-label-BsotZDO5.js +0 -2
  379. package/dist/gateway/static/root/assets/format-interval-label-BzxafKxR.js +0 -1
  380. package/dist/gateway/static/root/assets/gateway-settings-Cmwy58rS.js +0 -1
  381. package/dist/gateway/static/root/assets/goal-detail-page-l7mu5GWX.js +0 -1
  382. package/dist/gateway/static/root/assets/goals-settings-CYVY4NGp.js +0 -1
  383. package/dist/gateway/static/root/assets/heartbeat-config-api-DriO_CN9.js +0 -1
  384. package/dist/gateway/static/root/assets/heartbeat-settings-CUQTKxg7.js +0 -1
  385. package/dist/gateway/static/root/assets/index-C17Tsd_b.css +0 -1
  386. package/dist/gateway/static/root/assets/index-Cc41r16l.js +0 -191
  387. package/dist/gateway/static/root/assets/interval-presets-DFPCKW_W.js +0 -1
  388. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-CcVcqstx.js +0 -1
  389. package/dist/gateway/static/root/assets/messages-B1iSKjiw.js +0 -3
  390. package/dist/gateway/static/root/assets/models-hub-panel-BfLfcta8.js +0 -2
  391. package/dist/gateway/static/root/assets/note-detail-page-BjwOQBfT.js +0 -2
  392. package/dist/gateway/static/root/assets/notes-page-DktdBiwB.js +0 -1
  393. package/dist/gateway/static/root/assets/remote-access-hub-rfVx96fq.js +0 -1
  394. package/dist/gateway/static/root/assets/schedule-field-CUCKODde.js +0 -1
  395. package/dist/gateway/static/root/assets/sessions-page-DbtMFuuH.js +0 -1
  396. package/dist/gateway/static/root/assets/settings-advanced-gate-5re5gAnP.js +0 -1
  397. package/dist/gateway/static/root/assets/settings-page-D-WMyLlj.js +0 -1
  398. package/dist/gateway/static/root/assets/setup-status-panel-Cl-DEJAU.js +0 -1
  399. package/dist/gateway/static/root/assets/shares-settings-CyPVvbLt.js +0 -1
  400. package/dist/gateway/static/root/assets/skill-reload-api-CleTH1oz.js +0 -1
  401. package/dist/gateway/static/root/assets/skills-page-Ck8hdXqR.js +0 -2
  402. package/dist/gateway/static/root/assets/system-settings-panel-DI-LN_8G.js +0 -1
  403. package/dist/gateway/static/root/assets/typed-models-lib-kX9duch4.js +0 -1
  404. package/dist/gateway/static/root/assets/user-profile-settings-panel-B-UFPMXy.js +0 -1
  405. package/dist/gateway/static/root/assets/utils-Dm0hKalR.js +0 -1
  406. package/dist/gateway/static/root/assets/workflows-page-BtFGp2y_.js +0 -18
  407. package/dist/src/agent/fallback/error.d.ts +0 -22
  408. package/dist/src/agent/fallback/error.js +0 -32
  409. package/dist/src/agent/fallback/error.js.map +0 -1
  410. package/dist/src/agent/fallback/index.d.ts +0 -5
  411. package/dist/src/agent/fallback/index.js +0 -9
  412. package/dist/src/agent/fallback/index.js.map +0 -1
  413. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.d.ts +0 -29
  414. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js +0 -76
  415. package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js.map +0 -1
  416. package/dist/src/agent/service/reconcile-dreaming-cron.d.ts +0 -6
  417. package/dist/src/agent/service/reconcile-dreaming-cron.js +0 -84
  418. package/dist/src/agent/service/reconcile-dreaming-cron.js.map +0 -1
  419. package/dist/src/agent/tools/cronjob-tool.d.ts +0 -29
  420. package/dist/src/agent/tools/cronjob-tool.js +0 -274
  421. package/dist/src/agent/tools/cronjob-tool.js.map +0 -1
  422. package/dist/src/cli/commands/cron-cli.d.ts +0 -2
  423. package/dist/src/cli/commands/cron-cli.js +0 -15
  424. package/dist/src/cli/commands/cron-cli.js.map +0 -1
  425. package/dist/src/cli/commands/cron.d.ts +0 -4
  426. package/dist/src/cli/commands/cron.js +0 -188
  427. package/dist/src/cli/commands/cron.js.map +0 -1
  428. package/dist/src/cli/commands/doctor/checks/cron-health.js +0 -35
  429. package/dist/src/cli/commands/doctor/checks/cron-health.js.map +0 -1
  430. package/dist/src/cron/execution-types.d.ts +0 -42
  431. package/dist/src/cron/executor.d.ts +0 -67
  432. package/dist/src/cron/executor.js +0 -669
  433. package/dist/src/cron/executor.js.map +0 -1
  434. package/dist/src/cron/index.d.ts +0 -7
  435. package/dist/src/cron/index.js +0 -7
  436. package/dist/src/cron/job-content.d.ts +0 -5
  437. package/dist/src/cron/job-content.js +0 -15
  438. package/dist/src/cron/job-content.js.map +0 -1
  439. package/dist/src/cron/run-log-store.d.ts +0 -12
  440. package/dist/src/cron/run-log-store.js +0 -58
  441. package/dist/src/cron/run-log-store.js.map +0 -1
  442. package/dist/src/cron/schedule.d.ts +0 -10
  443. package/dist/src/cron/schedule.js +0 -85
  444. package/dist/src/cron/schedule.js.map +0 -1
  445. package/dist/src/cron/service.d.ts +0 -58
  446. package/dist/src/cron/service.js +0 -419
  447. package/dist/src/cron/service.js.map +0 -1
  448. package/dist/src/cron/types.d.ts +0 -183
  449. package/dist/src/cron/validation.d.ts +0 -500
  450. package/dist/src/cron/validation.js +0 -192
  451. package/dist/src/cron/validation.js.map +0 -1
  452. package/dist/src/cron/workflow-run-completion.d.ts +0 -23
  453. package/dist/src/cron/workflow-run-completion.js +0 -72
  454. package/dist/src/cron/workflow-run-completion.js.map +0 -1
  455. package/dist/src/extensions/types/phase4.js +0 -1
  456. package/dist/src/gateway/hono/routes/cron.d.ts +0 -3
  457. package/dist/src/gateway/hono/routes/cron.js +0 -109
  458. package/dist/src/gateway/hono/routes/cron.js.map +0 -1
  459. package/dist/src/storage/sqlite/cron-job-repository.d.ts +0 -6
  460. package/dist/src/storage/sqlite/cron-job-repository.js +0 -70
  461. package/dist/src/storage/sqlite/cron-job-repository.js.map +0 -1
  462. package/dist/src/storage/sqlite/cron-run-repository.d.ts +0 -5
  463. package/dist/src/storage/sqlite/cron-run-repository.js +0 -96
  464. package/dist/src/storage/sqlite/cron-run-repository.js.map +0 -1
  465. /package/dist/src/{cron → automations/domain}/types.js +0 -0
  466. /package/dist/src/{config/defaults.d.ts → automations/draft/automation-draft.types.js} +0 -0
  467. /package/dist/src/{config/defaults.js → extensions/types/registration.js} +0 -0
  468. /package/dist/src/{cron/execution-types.js → migrations/types.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"goal-service.js","names":[],"sources":["../../../src/goals/goal-service.ts"],"sourcesContent":["import type { Config } from '../config/schema.js';\nimport { defaultMaxTurns } from '../agent/goals/state.js';\nimport { GoalStore } from './goal-store.js';\nimport type {\n CreateGoalInput,\n Goal,\n GoalChecklistAddedBy,\n GoalChecklistStatus,\n GoalContextAttachment,\n GoalJudgeDecision,\n GoalListQuery,\n GoalSource,\n GoalStatus,\n GoalUiLocale,\n GoalWithDetails,\n} from './types.js';\n\nfunction normalizeTitle(title: string): string {\n const t = title.trim();\n if (!t) throw new Error('Goal title is required');\n return t;\n}\n\nfunction toTerminalStatus(verdict: GoalJudgeDecision['verdict']): GoalStatus {\n if (verdict === 'done') return 'done';\n if (verdict === 'blocked') return 'blocked';\n if (verdict === 'needs_input') return 'needs_input';\n return 'active';\n}\n\nexport class GoalService {\n private readonly store: GoalStore;\n\n constructor(store = new GoalStore()) {\n this.store = store;\n }\n\n create(input: Omit<CreateGoalInput, 'maxTurns' | 'agentId'> & {\n maxTurns?: number;\n agentId?: string;\n config?: Config;\n }): Goal {\n const sessionKey = input.sessionKey;\n const cfg = input.config?.goals;\n return this.store.create({\n title: normalizeTitle(input.title),\n description: input.description,\n agentId: input.agentId ?? 'main',\n sessionKey,\n priority: input.priority,\n deadlineAt: input.deadlineAt,\n judgeModelRef: input.judgeModelRef ?? cfg?.judgeModelRef,\n maxTurns: input.maxTurns ?? defaultMaxTurns(cfg),\n uiLocale: input.uiLocale,\n source: input.source,\n });\n }\n\n get(goalId: string): GoalWithDetails | null {\n const goal = this.store.get(goalId);\n if (!goal) return null;\n return {\n ...goal,\n checklist: this.store.listChecklist(goalId),\n latestRun: this.store.listRuns(goalId, 1)[0],\n contextMessage: this.store.getContextMessage(goalId) ?? undefined,\n };\n }\n\n getActiveForSession(sessionKey: string): GoalWithDetails | null {\n const goal = this.store.getActiveForSession(sessionKey);\n return goal ? this.get(goal.id) : null;\n }\n\n list(query: GoalListQuery = {}): GoalWithDetails[] {\n return this.store.list(query).map((goal) => ({\n ...goal,\n checklist: this.store.listChecklist(goal.id),\n latestRun: this.store.listRuns(goal.id, 1)[0],\n contextMessage: this.store.getContextMessage(goal.id) ?? undefined,\n }));\n }\n\n setContextMessage(input: {\n goalId: string;\n text: string;\n attachments?: GoalContextAttachment[];\n }): GoalWithDetails | null {\n if (!this.store.get(input.goalId)) return null;\n this.store.setContextMessage(input);\n return this.get(input.goalId);\n }\n\n update(goalId: string, patch: Partial<Pick<\n Goal,\n | 'title'\n | 'description'\n | 'priority'\n | 'deadlineAt'\n | 'maxTurns'\n | 'judgeModelRef'\n | 'nextAction'\n | 'blockedReason'\n | 'activeSessionKey'\n | 'uiLocale'\n >>): GoalWithDetails | null {\n const normalized: typeof patch = { ...patch };\n if (typeof normalized.title === 'string') {\n normalized.title = normalizeTitle(normalized.title);\n }\n if (typeof normalized.description === 'string') {\n normalized.description = normalized.description.trim() || undefined;\n }\n if (typeof normalized.judgeModelRef === 'string') {\n normalized.judgeModelRef = normalized.judgeModelRef.trim() || undefined;\n }\n if (typeof normalized.nextAction === 'string') {\n normalized.nextAction = normalized.nextAction.trim() || undefined;\n }\n if (typeof normalized.blockedReason === 'string') {\n normalized.blockedReason = normalized.blockedReason.trim() || undefined;\n }\n if (typeof normalized.maxTurns === 'number') {\n normalized.maxTurns = Math.max(1, Math.min(500, Math.floor(normalized.maxTurns)));\n }\n const goal = this.store.update(goalId, normalized);\n return goal ? this.get(goal.id) : null;\n }\n\n setStatus(goalId: string, status: GoalStatus, opts?: { reason?: string }): GoalWithDetails | null {\n const now = Date.now();\n const goal = this.store.update(goalId, {\n status,\n completedAt: status === 'done' ? now : undefined,\n archivedAt: status === 'archived' ? now : undefined,\n blockedReason: status === 'blocked' || status === 'needs_input' ? opts?.reason : undefined,\n });\n return goal ? this.get(goal.id) : null;\n }\n\n pause(goalId: string, reason = 'user-paused'): GoalWithDetails | null {\n const goal = this.store.update(goalId, {\n status: 'paused',\n blockedReason: reason,\n completedAt: undefined,\n archivedAt: undefined,\n });\n return goal ? this.get(goal.id) : null;\n }\n\n resume(goalId: string): GoalWithDetails | null {\n const goal = this.store.update(goalId, {\n status: 'active',\n blockedReason: undefined,\n completedAt: undefined,\n archivedAt: undefined,\n turnsUsed: 0,\n });\n return goal ? this.get(goal.id) : null;\n }\n\n reopen(goalId: string): GoalWithDetails | null {\n const goal = this.store.update(goalId, {\n status: 'active',\n blockedReason: undefined,\n completedAt: undefined,\n archivedAt: undefined,\n turnsUsed: 0,\n });\n return goal ? this.get(goal.id) : null;\n }\n\n complete(goalId: string): GoalWithDetails | null {\n return this.setStatus(goalId, 'done');\n }\n\n archive(goalId: string): GoalWithDetails | null {\n return this.setStatus(goalId, 'archived');\n }\n\n unarchive(goalId: string): GoalWithDetails | null {\n const goal = this.store.update(goalId, {\n status: 'paused',\n archivedAt: undefined,\n completedAt: undefined,\n blockedReason: undefined,\n });\n return goal ? this.get(goal.id) : null;\n }\n\n attachSession(goalId: string, sessionKey: string): GoalWithDetails | null {\n const goal = this.store.update(goalId, { activeSessionKey: sessionKey });\n return goal ? this.get(goal.id) : null;\n }\n\n updateChecklist(goalId: string, op: {\n type: 'add';\n text: string;\n addedBy?: GoalChecklistAddedBy;\n } | {\n type: 'mark';\n itemId: string;\n status: GoalChecklistStatus;\n evidenceSummary?: string;\n } | {\n type: 'remove';\n itemId: string;\n } | {\n type: 'reset';\n }): GoalWithDetails | null {\n if (op.type === 'add') {\n const text = op.text.trim();\n if (!text) throw new Error('Checklist item text is required');\n this.store.addChecklistItem({ goalId, text, addedBy: op.addedBy ?? 'user' });\n } else if (op.type === 'mark') {\n this.store.updateChecklistItem(op.itemId, {\n status: op.status,\n evidenceSummary: op.evidenceSummary,\n });\n } else if (op.type === 'remove') {\n this.store.removeChecklistItem(op.itemId);\n } else {\n this.store.clearChecklist(goalId);\n }\n return this.get(goalId);\n }\n\n recordJudgeDecision(input: {\n goalId: string;\n sessionKey: string;\n source: GoalSource;\n decision: GoalJudgeDecision;\n }): GoalWithDetails | null {\n const goal = this.store.get(input.goalId);\n if (!goal) return null;\n const nextStatus = toTerminalStatus(input.decision.verdict);\n const turnsUsed = goal.turnsUsed + 1;\n const status = turnsUsed >= goal.maxTurns && nextStatus === 'active' ? 'paused' : nextStatus;\n const reason =\n status === 'paused' && turnsUsed >= goal.maxTurns\n ? `turn budget exhausted (${turnsUsed}/${goal.maxTurns})`\n : input.decision.reason;\n\n const run = this.store.appendRun({\n goalId: input.goalId,\n sessionKey: input.sessionKey,\n source: input.source,\n status: 'succeeded',\n finishedAt: Date.now(),\n verdict: input.decision.verdict,\n reason: input.decision.reason,\n nextAction: input.decision.nextAction,\n assistantPreview: input.decision.assistantPreview,\n checklistProgress: input.decision.checklistProgress,\n confidence: input.decision.confidence,\n missingEvidence: input.decision.missingEvidence,\n userQuestion: input.decision.userQuestion,\n completedChecklistItemIds: input.decision.completedChecklistItemIds,\n });\n\n this.store.update(input.goalId, {\n status,\n turnsUsed,\n currentRunId: run.id,\n nextAction: input.decision.nextAction,\n blockedReason: status === 'blocked' || status === 'needs_input' || status === 'paused' ? reason : undefined,\n completedAt: status === 'done' ? Date.now() : undefined,\n });\n\n return this.get(input.goalId);\n }\n\n syncPostTurnState(input: {\n goalId: string;\n sessionKey: string;\n source: GoalSource;\n status: GoalStatus;\n turnsUsed: number;\n maxTurns: number;\n reason?: string;\n nextAction?: string;\n assistantPreview?: string;\n verdict: 'continue' | 'done' | 'blocked' | 'needs_input' | 'decompose';\n confidence?: number;\n missingEvidence?: string[];\n userQuestion?: string;\n completedChecklistItemIds?: string[];\n checklist?: Array<{\n text: string;\n status: 'pending' | 'completed' | 'impossible';\n addedBy: 'user' | 'judge';\n addedAt?: number;\n completedAt?: number;\n evidenceSummary?: string;\n }>;\n }): GoalWithDetails | null {\n const goal = this.store.get(input.goalId);\n if (!goal) return null;\n if (input.checklist) {\n this.store.replaceChecklist(input.goalId, input.checklist);\n }\n const total = input.checklist?.length ?? this.store.listChecklist(input.goalId).length;\n const done = (input.checklist ?? this.store.listChecklist(input.goalId)).filter(\n (it) => it.status === 'completed' || it.status === 'impossible',\n ).length;\n const run = this.store.appendRun({\n goalId: input.goalId,\n sessionKey: input.sessionKey,\n source: input.source,\n status: 'succeeded',\n finishedAt: Date.now(),\n verdict: input.verdict,\n reason: input.reason,\n nextAction: input.nextAction,\n assistantPreview: input.assistantPreview,\n checklistProgress: total > 0 ? { done, total } : undefined,\n confidence: input.confidence,\n missingEvidence: input.missingEvidence,\n userQuestion: input.userQuestion,\n completedChecklistItemIds: input.completedChecklistItemIds,\n });\n for (const item of input.checklist ?? []) {\n if ((item.status === 'completed' || item.status === 'impossible') && item.evidenceSummary?.trim()) {\n this.store.addEvidence({\n goalId: input.goalId,\n runId: run.id,\n kind: 'message',\n title: `Checklist evidence: ${item.text.slice(0, 80)}`,\n summary: item.evidenceSummary.trim(),\n });\n }\n }\n for (const missing of input.missingEvidence ?? []) {\n if (!missing.trim()) continue;\n this.store.addEvidence({\n goalId: input.goalId,\n runId: run.id,\n kind: 'message',\n title: `Missing evidence: ${missing.slice(0, 80)}`,\n summary: missing,\n });\n }\n if (input.userQuestion?.trim()) {\n this.store.addEvidence({\n goalId: input.goalId,\n runId: run.id,\n kind: 'message',\n title: 'User input requested',\n summary: input.userQuestion.trim(),\n });\n }\n this.store.update(input.goalId, {\n status: input.status,\n turnsUsed: input.turnsUsed,\n maxTurns: input.maxTurns,\n currentRunId: run.id,\n nextAction: input.nextAction,\n blockedReason:\n input.status === 'blocked' || input.status === 'needs_input' || input.status === 'paused'\n ? input.reason\n : undefined,\n completedAt: input.status === 'done' ? Date.now() : undefined,\n });\n return this.get(input.goalId);\n }\n\n listRuns(goalId: string, limit?: number) {\n return this.store.listRuns(goalId, limit);\n }\n\n listRunsForSession(sessionKey: string, limit?: number) {\n return this.store.listRunsForSession(sessionKey, limit);\n }\n\n listEvents(goalId: string, limit?: number) {\n return this.store.listEvents(goalId, limit);\n }\n\n addEvidence(input: Parameters<GoalStore['addEvidence']>[0]) {\n return this.store.addEvidence(input);\n }\n\n listEvidence(goalId: string, limit?: number) {\n return this.store.listEvidence(goalId, limit);\n }\n}\n\nexport function normalizeGoalUiLocale(raw: unknown): GoalUiLocale | undefined {\n return raw === 'en' || raw === 'zh' ? raw : undefined;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"goal-service.js","names":[],"sources":["../../../src/goals/goal-service.ts"],"sourcesContent":["import type { Config } from '../config/schema.js';\nimport { defaultMaxTurns } from '../agent/goals/state.js';\nimport { publishAutomationProductEvent } from '../automations/product-events.js';\nimport { GoalStore } from './goal-store.js';\nimport type {\n CreateGoalInput,\n Goal,\n GoalChecklistAddedBy,\n GoalChecklistStatus,\n GoalContextAttachment,\n GoalJudgeDecision,\n GoalListQuery,\n GoalSource,\n GoalStatus,\n GoalUiLocale,\n GoalWithDetails,\n} from './types.js';\n\nfunction normalizeTitle(title: string): string {\n const t = title.trim();\n if (!t) throw new Error('Goal title is required');\n return t;\n}\n\nfunction toTerminalStatus(verdict: GoalJudgeDecision['verdict']): GoalStatus {\n if (verdict === 'done') return 'done';\n if (verdict === 'blocked') return 'blocked';\n if (verdict === 'needs_input') return 'needs_input';\n return 'active';\n}\n\nfunction publishGoalEvent(\n type: 'goal.created' | 'goal.status_changed',\n goal: Goal,\n extra?: Record<string, unknown>,\n): void {\n publishAutomationProductEvent({\n type,\n source: 'goals',\n payload: {\n goalId: goal.id,\n title: goal.title,\n status: goal.status,\n priority: goal.priority,\n sessionKey: goal.activeSessionKey,\n agentId: goal.agentId,\n source: goal.source,\n ...extra,\n },\n });\n}\n\nfunction publishGoalStatusEvent(\n goal: Goal,\n previousStatus?: GoalStatus,\n reason?: string,\n): void {\n if (previousStatus === goal.status) return;\n publishGoalEvent('goal.status_changed', goal, {\n previousStatus,\n reason,\n });\n}\n\nexport class GoalService {\n private readonly store: GoalStore;\n\n constructor(store = new GoalStore()) {\n this.store = store;\n }\n\n create(input: Omit<CreateGoalInput, 'maxTurns' | 'agentId'> & {\n maxTurns?: number;\n agentId?: string;\n config?: Config;\n }): Goal {\n const sessionKey = input.sessionKey;\n const cfg = input.config?.goals;\n const goal = this.store.create({\n title: normalizeTitle(input.title),\n description: input.description,\n agentId: input.agentId ?? 'main',\n sessionKey,\n priority: input.priority,\n deadlineAt: input.deadlineAt,\n judgeModelRef: input.judgeModelRef ?? cfg?.judgeModelRef,\n maxTurns: input.maxTurns ?? defaultMaxTurns(cfg),\n uiLocale: input.uiLocale,\n source: input.source,\n });\n publishGoalEvent('goal.created', goal);\n return goal;\n }\n\n get(goalId: string): GoalWithDetails | null {\n const goal = this.store.get(goalId);\n if (!goal) return null;\n return {\n ...goal,\n checklist: this.store.listChecklist(goalId),\n latestRun: this.store.listRuns(goalId, 1)[0],\n contextMessage: this.store.getContextMessage(goalId) ?? undefined,\n };\n }\n\n getActiveForSession(sessionKey: string): GoalWithDetails | null {\n const goal = this.store.getActiveForSession(sessionKey);\n return goal ? this.get(goal.id) : null;\n }\n\n list(query: GoalListQuery = {}): GoalWithDetails[] {\n return this.store.list(query).map((goal) => ({\n ...goal,\n checklist: this.store.listChecklist(goal.id),\n latestRun: this.store.listRuns(goal.id, 1)[0],\n contextMessage: this.store.getContextMessage(goal.id) ?? undefined,\n }));\n }\n\n setContextMessage(input: {\n goalId: string;\n text: string;\n attachments?: GoalContextAttachment[];\n }): GoalWithDetails | null {\n if (!this.store.get(input.goalId)) return null;\n this.store.setContextMessage(input);\n return this.get(input.goalId);\n }\n\n update(goalId: string, patch: Partial<Pick<\n Goal,\n | 'title'\n | 'description'\n | 'priority'\n | 'deadlineAt'\n | 'maxTurns'\n | 'judgeModelRef'\n | 'nextAction'\n | 'blockedReason'\n | 'activeSessionKey'\n | 'uiLocale'\n >>): GoalWithDetails | null {\n const normalized: typeof patch = { ...patch };\n if (typeof normalized.title === 'string') {\n normalized.title = normalizeTitle(normalized.title);\n }\n if (typeof normalized.description === 'string') {\n normalized.description = normalized.description.trim() || undefined;\n }\n if (typeof normalized.judgeModelRef === 'string') {\n normalized.judgeModelRef = normalized.judgeModelRef.trim() || undefined;\n }\n if (typeof normalized.nextAction === 'string') {\n normalized.nextAction = normalized.nextAction.trim() || undefined;\n }\n if (typeof normalized.blockedReason === 'string') {\n normalized.blockedReason = normalized.blockedReason.trim() || undefined;\n }\n if (typeof normalized.maxTurns === 'number') {\n normalized.maxTurns = Math.max(1, Math.min(500, Math.floor(normalized.maxTurns)));\n }\n const goal = this.store.update(goalId, normalized);\n return goal ? this.get(goal.id) : null;\n }\n\n setStatus(goalId: string, status: GoalStatus, opts?: { reason?: string }): GoalWithDetails | null {\n const previous = this.store.get(goalId);\n const now = Date.now();\n const goal = this.store.update(goalId, {\n status,\n completedAt: status === 'done' ? now : undefined,\n archivedAt: status === 'archived' ? now : undefined,\n blockedReason: status === 'blocked' || status === 'needs_input' ? opts?.reason : undefined,\n });\n if (goal) publishGoalStatusEvent(goal, previous?.status, opts?.reason);\n return goal ? this.get(goal.id) : null;\n }\n\n pause(goalId: string, reason = 'user-paused'): GoalWithDetails | null {\n const previous = this.store.get(goalId);\n const goal = this.store.update(goalId, {\n status: 'paused',\n blockedReason: reason,\n completedAt: undefined,\n archivedAt: undefined,\n });\n if (goal) publishGoalStatusEvent(goal, previous?.status, reason);\n return goal ? this.get(goal.id) : null;\n }\n\n resume(goalId: string): GoalWithDetails | null {\n const previous = this.store.get(goalId);\n const goal = this.store.update(goalId, {\n status: 'active',\n blockedReason: undefined,\n completedAt: undefined,\n archivedAt: undefined,\n turnsUsed: 0,\n });\n if (goal) publishGoalStatusEvent(goal, previous?.status);\n return goal ? this.get(goal.id) : null;\n }\n\n reopen(goalId: string): GoalWithDetails | null {\n const previous = this.store.get(goalId);\n const goal = this.store.update(goalId, {\n status: 'active',\n blockedReason: undefined,\n completedAt: undefined,\n archivedAt: undefined,\n turnsUsed: 0,\n });\n if (goal) publishGoalStatusEvent(goal, previous?.status);\n return goal ? this.get(goal.id) : null;\n }\n\n complete(goalId: string): GoalWithDetails | null {\n return this.setStatus(goalId, 'done');\n }\n\n archive(goalId: string): GoalWithDetails | null {\n return this.setStatus(goalId, 'archived');\n }\n\n unarchive(goalId: string): GoalWithDetails | null {\n const previous = this.store.get(goalId);\n const goal = this.store.update(goalId, {\n status: 'paused',\n archivedAt: undefined,\n completedAt: undefined,\n blockedReason: undefined,\n });\n if (goal) publishGoalStatusEvent(goal, previous?.status);\n return goal ? this.get(goal.id) : null;\n }\n\n attachSession(goalId: string, sessionKey: string): GoalWithDetails | null {\n const goal = this.store.update(goalId, { activeSessionKey: sessionKey });\n return goal ? this.get(goal.id) : null;\n }\n\n updateChecklist(goalId: string, op: {\n type: 'add';\n text: string;\n addedBy?: GoalChecklistAddedBy;\n } | {\n type: 'mark';\n itemId: string;\n status: GoalChecklistStatus;\n evidenceSummary?: string;\n } | {\n type: 'remove';\n itemId: string;\n } | {\n type: 'reset';\n }): GoalWithDetails | null {\n if (op.type === 'add') {\n const text = op.text.trim();\n if (!text) throw new Error('Checklist item text is required');\n this.store.addChecklistItem({ goalId, text, addedBy: op.addedBy ?? 'user' });\n } else if (op.type === 'mark') {\n this.store.updateChecklistItem(op.itemId, {\n status: op.status,\n evidenceSummary: op.evidenceSummary,\n });\n } else if (op.type === 'remove') {\n this.store.removeChecklistItem(op.itemId);\n } else {\n this.store.clearChecklist(goalId);\n }\n return this.get(goalId);\n }\n\n recordJudgeDecision(input: {\n goalId: string;\n sessionKey: string;\n source: GoalSource;\n decision: GoalJudgeDecision;\n }): GoalWithDetails | null {\n const goal = this.store.get(input.goalId);\n if (!goal) return null;\n const previousStatus = goal.status;\n const nextStatus = toTerminalStatus(input.decision.verdict);\n const turnsUsed = goal.turnsUsed + 1;\n const status = turnsUsed >= goal.maxTurns && nextStatus === 'active' ? 'paused' : nextStatus;\n const reason =\n status === 'paused' && turnsUsed >= goal.maxTurns\n ? `turn budget exhausted (${turnsUsed}/${goal.maxTurns})`\n : input.decision.reason;\n\n const run = this.store.appendRun({\n goalId: input.goalId,\n sessionKey: input.sessionKey,\n source: input.source,\n status: 'succeeded',\n finishedAt: Date.now(),\n verdict: input.decision.verdict,\n reason: input.decision.reason,\n nextAction: input.decision.nextAction,\n assistantPreview: input.decision.assistantPreview,\n checklistProgress: input.decision.checklistProgress,\n confidence: input.decision.confidence,\n missingEvidence: input.decision.missingEvidence,\n userQuestion: input.decision.userQuestion,\n completedChecklistItemIds: input.decision.completedChecklistItemIds,\n });\n\n const updated = this.store.update(input.goalId, {\n status,\n turnsUsed,\n currentRunId: run.id,\n nextAction: input.decision.nextAction,\n blockedReason: status === 'blocked' || status === 'needs_input' || status === 'paused' ? reason : undefined,\n completedAt: status === 'done' ? Date.now() : undefined,\n });\n if (updated) publishGoalStatusEvent(updated, previousStatus, reason);\n\n return this.get(input.goalId);\n }\n\n syncPostTurnState(input: {\n goalId: string;\n sessionKey: string;\n source: GoalSource;\n status: GoalStatus;\n turnsUsed: number;\n maxTurns: number;\n reason?: string;\n nextAction?: string;\n assistantPreview?: string;\n verdict: 'continue' | 'done' | 'blocked' | 'needs_input' | 'decompose';\n confidence?: number;\n missingEvidence?: string[];\n userQuestion?: string;\n completedChecklistItemIds?: string[];\n checklist?: Array<{\n text: string;\n status: 'pending' | 'completed' | 'impossible';\n addedBy: 'user' | 'judge';\n addedAt?: number;\n completedAt?: number;\n evidenceSummary?: string;\n }>;\n }): GoalWithDetails | null {\n const goal = this.store.get(input.goalId);\n if (!goal) return null;\n const previousStatus = goal.status;\n if (input.checklist) {\n this.store.replaceChecklist(input.goalId, input.checklist);\n }\n const total = input.checklist?.length ?? this.store.listChecklist(input.goalId).length;\n const done = (input.checklist ?? this.store.listChecklist(input.goalId)).filter(\n (it) => it.status === 'completed' || it.status === 'impossible',\n ).length;\n const run = this.store.appendRun({\n goalId: input.goalId,\n sessionKey: input.sessionKey,\n source: input.source,\n status: 'succeeded',\n finishedAt: Date.now(),\n verdict: input.verdict,\n reason: input.reason,\n nextAction: input.nextAction,\n assistantPreview: input.assistantPreview,\n checklistProgress: total > 0 ? { done, total } : undefined,\n confidence: input.confidence,\n missingEvidence: input.missingEvidence,\n userQuestion: input.userQuestion,\n completedChecklistItemIds: input.completedChecklistItemIds,\n });\n for (const item of input.checklist ?? []) {\n if ((item.status === 'completed' || item.status === 'impossible') && item.evidenceSummary?.trim()) {\n this.store.addEvidence({\n goalId: input.goalId,\n runId: run.id,\n kind: 'message',\n title: `Checklist evidence: ${item.text.slice(0, 80)}`,\n summary: item.evidenceSummary.trim(),\n });\n }\n }\n for (const missing of input.missingEvidence ?? []) {\n if (!missing.trim()) continue;\n this.store.addEvidence({\n goalId: input.goalId,\n runId: run.id,\n kind: 'message',\n title: `Missing evidence: ${missing.slice(0, 80)}`,\n summary: missing,\n });\n }\n if (input.userQuestion?.trim()) {\n this.store.addEvidence({\n goalId: input.goalId,\n runId: run.id,\n kind: 'message',\n title: 'User input requested',\n summary: input.userQuestion.trim(),\n });\n }\n const updated = this.store.update(input.goalId, {\n status: input.status,\n turnsUsed: input.turnsUsed,\n maxTurns: input.maxTurns,\n currentRunId: run.id,\n nextAction: input.nextAction,\n blockedReason:\n input.status === 'blocked' || input.status === 'needs_input' || input.status === 'paused'\n ? input.reason\n : undefined,\n completedAt: input.status === 'done' ? Date.now() : undefined,\n });\n if (updated) publishGoalStatusEvent(updated, previousStatus, input.reason);\n return this.get(input.goalId);\n }\n\n listRuns(goalId: string, limit?: number) {\n return this.store.listRuns(goalId, limit);\n }\n\n listRunsForSession(sessionKey: string, limit?: number) {\n return this.store.listRunsForSession(sessionKey, limit);\n }\n\n listEvents(goalId: string, limit?: number) {\n return this.store.listEvents(goalId, limit);\n }\n\n addEvidence(input: Parameters<GoalStore['addEvidence']>[0]) {\n return this.store.addEvidence(input);\n }\n\n listEvidence(goalId: string, limit?: number) {\n return this.store.listEvidence(goalId, limit);\n }\n}\n\nexport function normalizeGoalUiLocale(raw: unknown): GoalUiLocale | undefined {\n return raw === 'en' || raw === 'zh' ? raw : undefined;\n}\n"],"mappings":"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"}
@@ -2,8 +2,8 @@ import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
3
  import { init_paths, resolveConfigPath } from "../config/paths.js";
4
4
  import { init_loader, loadConfig } from "../config/loader.js";
5
- import { isRestartEnabled } from "../config/commands.flags.js";
6
5
  import { resolveGatewayService } from "../daemon/service.js";
6
+ import { isRestartEnabled } from "../config/commands.flags.js";
7
7
  import { authorizeGatewaySigusr1Restart, writeGatewayRestartIntentSync } from "./restart.js";
8
8
  import { findVerifiedGatewayListenerPidsOnPortSync, signalVerifiedGatewayPidSync } from "./gateway-processes.js";
9
9
  //#region src/infra/update-restart.ts
@@ -0,0 +1,10 @@
1
+ import { type CapabilityPreset } from '../../agent-manifest/schema.js';
2
+ import { type Config } from '../../config/schema.js';
3
+ import type { Migration } from '../types.js';
4
+ export declare const DEFAULT_CAPABILITY_PRESET_MIGRATION_ID = "2026-07-ensure-default-capability-preset";
5
+ export declare function createDefaultCapabilityPreset(): CapabilityPreset;
6
+ export declare function ensureDefaultCapabilityPresetInitialized(config: Config): {
7
+ config: Config;
8
+ changed: boolean;
9
+ };
10
+ export declare const defaultCapabilityPresetMigration: Migration;
@@ -0,0 +1,135 @@
1
+ import { CapabilityPresetSchema, DEFAULT_CAPABILITY_PRESET_ID, init_schema } from "../../agent-manifest/schema.js";
2
+ import { ConfigSchema, init_schema as init_schema$1 } from "../../config/schema.js";
3
+ import { existsSync, readFileSync } from "node:fs";
4
+ //#region src/migrations/config/default-capability-preset.ts
5
+ init_schema();
6
+ init_schema$1();
7
+ const DEFAULT_CAPABILITY_PRESET_MIGRATION_ID = "2026-07-ensure-default-capability-preset";
8
+ function createDefaultCapabilityPreset() {
9
+ return {
10
+ id: DEFAULT_CAPABILITY_PRESET_ID,
11
+ name: "Global defaults",
12
+ description: "Default capabilities inherited by every agent.",
13
+ version: 1,
14
+ models: {
15
+ defaultRole: "deep",
16
+ roles: {}
17
+ }
18
+ };
19
+ }
20
+ function ensureDefaultCapabilityPresetInitialized(config) {
21
+ const agents = config.agents;
22
+ const capabilityPresets = { ...agents.capabilityPresets ?? {} };
23
+ let changed = false;
24
+ if (!capabilityPresets["default"]) {
25
+ capabilityPresets[DEFAULT_CAPABILITY_PRESET_ID] = createDefaultCapabilityPreset();
26
+ changed = true;
27
+ }
28
+ const defaultPreset = agents.defaultPreset?.trim() || "default";
29
+ if (defaultPreset !== agents.defaultPreset) changed = true;
30
+ if (!changed) return {
31
+ config,
32
+ changed: false
33
+ };
34
+ return {
35
+ config: ConfigSchema.parse({
36
+ ...config,
37
+ agents: {
38
+ ...agents,
39
+ defaultPreset,
40
+ capabilityPresets
41
+ }
42
+ }),
43
+ changed: true
44
+ };
45
+ }
46
+ function planned(message, details) {
47
+ return {
48
+ id: DEFAULT_CAPABILITY_PRESET_MIGRATION_ID,
49
+ title: "Initialize global default capability preset",
50
+ kind: "config",
51
+ safety: "auto",
52
+ status: "planned",
53
+ message,
54
+ details
55
+ };
56
+ }
57
+ function conflict(message, details) {
58
+ return {
59
+ id: DEFAULT_CAPABILITY_PRESET_MIGRATION_ID,
60
+ title: "Initialize global default capability preset",
61
+ kind: "config",
62
+ safety: "manual",
63
+ status: "conflict",
64
+ message,
65
+ details
66
+ };
67
+ }
68
+ function readRawConfigObject(configPath) {
69
+ if (!existsSync(configPath)) return null;
70
+ const raw = readFileSync(configPath, "utf8");
71
+ const parsed = JSON.parse(raw);
72
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("Config root must be an object");
73
+ return parsed;
74
+ }
75
+ const defaultCapabilityPresetMigration = {
76
+ id: DEFAULT_CAPABILITY_PRESET_MIGRATION_ID,
77
+ kind: "config",
78
+ safety: "auto",
79
+ detect(ctx) {
80
+ const raw = readRawConfigObject(ctx.configPath);
81
+ if (!raw) return null;
82
+ const rawAgents = raw.agents;
83
+ if (rawAgents !== void 0 && (rawAgents === null || typeof rawAgents !== "object" || Array.isArray(rawAgents))) return conflict("agents config is not an object; cannot initialize global defaults automatically.");
84
+ const agents = rawAgents ?? {};
85
+ const rawPresets = agents.capabilityPresets;
86
+ if (rawPresets !== void 0 && (rawPresets === null || typeof rawPresets !== "object" || Array.isArray(rawPresets))) return conflict("agents.capabilityPresets is not an object; cannot initialize global defaults automatically.");
87
+ const existingDefault = (rawPresets ?? {})[DEFAULT_CAPABILITY_PRESET_ID];
88
+ if (existingDefault !== void 0) {
89
+ const parsedPreset = CapabilityPresetSchema.safeParse(existingDefault);
90
+ if (!parsedPreset.success) return conflict("Existing default capability preset is invalid; please repair it manually.", { issues: parsedPreset.error.issues.slice(0, 5).map((issue) => ({
91
+ path: issue.path.join("."),
92
+ message: issue.message
93
+ })) });
94
+ }
95
+ const needsDefaultPresetPointer = typeof agents.defaultPreset !== "string" || agents.defaultPreset.trim().length === 0;
96
+ const needsDefaultPresetObject = existingDefault === void 0;
97
+ if (!needsDefaultPresetPointer && !needsDefaultPresetObject) return null;
98
+ return planned("Global default capability preset is missing and will be initialized.", {
99
+ addDefaultPresetPointer: needsDefaultPresetPointer,
100
+ addDefaultPresetObject: needsDefaultPresetObject
101
+ });
102
+ },
103
+ apply(ctx) {
104
+ const detected = this.detect(ctx);
105
+ if (!detected) return {
106
+ id: this.id,
107
+ title: "Initialize global default capability preset",
108
+ kind: "config",
109
+ safety: "auto",
110
+ status: "not_needed",
111
+ message: "Global default capability preset is already initialized."
112
+ };
113
+ if (detected.status === "conflict") return detected;
114
+ const raw = readRawConfigObject(ctx.configPath);
115
+ const ensured = ensureDefaultCapabilityPresetInitialized(ConfigSchema.parse(raw ?? void 0));
116
+ if (!ensured.changed) return {
117
+ ...detected,
118
+ status: "not_needed",
119
+ message: "Global default capability preset is already initialized."
120
+ };
121
+ return {
122
+ ...detected,
123
+ status: "applied",
124
+ message: "Initialized global default capability preset.",
125
+ details: {
126
+ ...detected.details,
127
+ config: ensured.config
128
+ }
129
+ };
130
+ }
131
+ };
132
+ //#endregion
133
+ export { DEFAULT_CAPABILITY_PRESET_MIGRATION_ID, createDefaultCapabilityPreset, defaultCapabilityPresetMigration, ensureDefaultCapabilityPresetInitialized };
134
+
135
+ //# sourceMappingURL=default-capability-preset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-capability-preset.js","names":[],"sources":["../../../../src/migrations/config/default-capability-preset.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\n\nimport {\n CapabilityPresetSchema,\n DEFAULT_CAPABILITY_PRESET_ID,\n type CapabilityPreset,\n} from '../../agent-manifest/schema.js';\nimport { ConfigSchema, type Config } from '../../config/schema.js';\nimport type { Migration, MigrationContext, MigrationPlanItem } from '../types.js';\n\nexport const DEFAULT_CAPABILITY_PRESET_MIGRATION_ID = '2026-07-ensure-default-capability-preset';\n\nexport function createDefaultCapabilityPreset(): CapabilityPreset {\n return {\n id: DEFAULT_CAPABILITY_PRESET_ID,\n name: 'Global defaults',\n description: 'Default capabilities inherited by every agent.',\n version: 1,\n models: {\n defaultRole: 'deep',\n roles: {},\n },\n };\n}\n\nexport function ensureDefaultCapabilityPresetInitialized(config: Config): { config: Config; changed: boolean } {\n const agents = config.agents;\n const capabilityPresets = { ...(agents.capabilityPresets ?? {}) };\n let changed = false;\n\n if (!capabilityPresets[DEFAULT_CAPABILITY_PRESET_ID]) {\n capabilityPresets[DEFAULT_CAPABILITY_PRESET_ID] = createDefaultCapabilityPreset();\n changed = true;\n }\n\n const defaultPreset = agents.defaultPreset?.trim() || DEFAULT_CAPABILITY_PRESET_ID;\n if (defaultPreset !== agents.defaultPreset) {\n changed = true;\n }\n\n if (!changed) return { config, changed: false };\n\n return {\n config: ConfigSchema.parse({\n ...config,\n agents: {\n ...agents,\n defaultPreset,\n capabilityPresets,\n },\n }),\n changed: true,\n };\n}\n\nfunction planned(message: string, details?: Record<string, unknown>): MigrationPlanItem {\n return {\n id: DEFAULT_CAPABILITY_PRESET_MIGRATION_ID,\n title: 'Initialize global default capability preset',\n kind: 'config',\n safety: 'auto',\n status: 'planned',\n message,\n details,\n };\n}\n\nfunction conflict(message: string, details?: Record<string, unknown>): MigrationPlanItem {\n return {\n id: DEFAULT_CAPABILITY_PRESET_MIGRATION_ID,\n title: 'Initialize global default capability preset',\n kind: 'config',\n safety: 'manual',\n status: 'conflict',\n message,\n details,\n };\n}\n\nfunction readRawConfigObject(configPath: string): Record<string, unknown> | null {\n if (!existsSync(configPath)) return null;\n const raw = readFileSync(configPath, 'utf8');\n const parsed = JSON.parse(raw) as unknown;\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error('Config root must be an object');\n }\n return parsed as Record<string, unknown>;\n}\n\nexport const defaultCapabilityPresetMigration: Migration = {\n id: DEFAULT_CAPABILITY_PRESET_MIGRATION_ID,\n kind: 'config',\n safety: 'auto',\n\n detect(ctx: MigrationContext): MigrationPlanItem | null {\n const raw = readRawConfigObject(ctx.configPath);\n if (!raw) return null;\n\n const rawAgents = raw.agents;\n if (rawAgents !== undefined && (rawAgents === null || typeof rawAgents !== 'object' || Array.isArray(rawAgents))) {\n return conflict('agents config is not an object; cannot initialize global defaults automatically.');\n }\n\n const agents = (rawAgents ?? {}) as Record<string, unknown>;\n const rawPresets = agents.capabilityPresets;\n if (rawPresets !== undefined && (rawPresets === null || typeof rawPresets !== 'object' || Array.isArray(rawPresets))) {\n return conflict('agents.capabilityPresets is not an object; cannot initialize global defaults automatically.');\n }\n\n const presets = (rawPresets ?? {}) as Record<string, unknown>;\n const existingDefault = presets[DEFAULT_CAPABILITY_PRESET_ID];\n if (existingDefault !== undefined) {\n const parsedPreset = CapabilityPresetSchema.safeParse(existingDefault);\n if (!parsedPreset.success) {\n return conflict('Existing default capability preset is invalid; please repair it manually.', {\n issues: parsedPreset.error.issues.slice(0, 5).map((issue) => ({\n path: issue.path.join('.'),\n message: issue.message,\n })),\n });\n }\n }\n\n const needsDefaultPresetPointer = typeof agents.defaultPreset !== 'string' || agents.defaultPreset.trim().length === 0;\n const needsDefaultPresetObject = existingDefault === undefined;\n if (!needsDefaultPresetPointer && !needsDefaultPresetObject) return null;\n\n return planned('Global default capability preset is missing and will be initialized.', {\n addDefaultPresetPointer: needsDefaultPresetPointer,\n addDefaultPresetObject: needsDefaultPresetObject,\n });\n },\n\n apply(ctx: MigrationContext): MigrationPlanItem {\n const detected = this.detect(ctx);\n if (!detected) {\n return {\n id: this.id,\n title: 'Initialize global default capability preset',\n kind: 'config',\n safety: 'auto',\n status: 'not_needed',\n message: 'Global default capability preset is already initialized.',\n };\n }\n if (detected.status === 'conflict') return detected;\n\n const raw = readRawConfigObject(ctx.configPath);\n const parsed = ConfigSchema.parse(raw ?? undefined);\n const ensured = ensureDefaultCapabilityPresetInitialized(parsed);\n if (!ensured.changed) {\n return { ...detected, status: 'not_needed', message: 'Global default capability preset is already initialized.' };\n }\n\n return {\n ...detected,\n status: 'applied',\n message: 'Initialized global default capability preset.',\n details: { ...detected.details, config: ensured.config },\n };\n },\n};\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from './types.js';
2
+ export * from './runner.js';
3
+ export * from './registry.js';
4
+ export * from './config/default-capability-preset.js';
@@ -0,0 +1,4 @@
1
+ import { listRegisteredMigrations, registerMigration, unregisterMigrationsForSource } from "./registry.js";
2
+ import { DEFAULT_CAPABILITY_PRESET_MIGRATION_ID, createDefaultCapabilityPreset, defaultCapabilityPresetMigration, ensureDefaultCapabilityPresetInitialized } from "./config/default-capability-preset.js";
3
+ import { CORE_MIGRATIONS, applyMigrations, detectMigrations, runBootstrapMigrationsSync } from "./runner.js";
4
+ export { CORE_MIGRATIONS, DEFAULT_CAPABILITY_PRESET_MIGRATION_ID, applyMigrations, createDefaultCapabilityPreset, defaultCapabilityPresetMigration, detectMigrations, ensureDefaultCapabilityPresetInitialized, listRegisteredMigrations, registerMigration, runBootstrapMigrationsSync, unregisterMigrationsForSource };
@@ -0,0 +1,8 @@
1
+ import type { Migration } from './types.js';
2
+ export type RegisteredMigration = {
3
+ source: string;
4
+ migration: Migration;
5
+ };
6
+ export declare function registerMigration(source: string, migration: Migration): void;
7
+ export declare function unregisterMigrationsForSource(source: string): void;
8
+ export declare function listRegisteredMigrations(): RegisteredMigration[];
@@ -0,0 +1,18 @@
1
+ //#region src/migrations/registry.ts
2
+ const registeredMigrations = /* @__PURE__ */ new Map();
3
+ function registerMigration(source, migration) {
4
+ registeredMigrations.set(`${source}:${migration.id}`, {
5
+ source,
6
+ migration
7
+ });
8
+ }
9
+ function unregisterMigrationsForSource(source) {
10
+ for (const [key, value] of registeredMigrations.entries()) if (value.source === source) registeredMigrations.delete(key);
11
+ }
12
+ function listRegisteredMigrations() {
13
+ return [...registeredMigrations.values()];
14
+ }
15
+ //#endregion
16
+ export { listRegisteredMigrations, registerMigration, unregisterMigrationsForSource };
17
+
18
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","names":[],"sources":["../../../src/migrations/registry.ts"],"sourcesContent":["import type { Migration } from './types.js';\n\nexport type RegisteredMigration = {\n source: string;\n migration: Migration;\n};\n\nconst registeredMigrations = new Map<string, RegisteredMigration>();\n\nexport function registerMigration(source: string, migration: Migration): void {\n registeredMigrations.set(`${source}:${migration.id}`, { source, migration });\n}\n\nexport function unregisterMigrationsForSource(source: string): void {\n for (const [key, value] of registeredMigrations.entries()) {\n if (value.source === source) registeredMigrations.delete(key);\n }\n}\n\nexport function listRegisteredMigrations(): RegisteredMigration[] {\n return [...registeredMigrations.values()];\n}\n"],"mappings":";AAOA,MAAM,uCAAuB,IAAI,KAAkC;AAEnE,SAAgB,kBAAkB,QAAgB,WAA4B;AAC5E,sBAAqB,IAAI,GAAG,OAAO,GAAG,UAAU,MAAM;EAAE;EAAQ;EAAW,CAAC;;AAG9E,SAAgB,8BAA8B,QAAsB;AAClE,MAAK,MAAM,CAAC,KAAK,UAAU,qBAAqB,SAAS,CACvD,KAAI,MAAM,WAAW,OAAQ,sBAAqB,OAAO,IAAI;;AAIjE,SAAgB,2BAAkD;AAChE,QAAO,CAAC,GAAG,qBAAqB,QAAQ,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { Migration, MigrationPlanItem } from './types.js';
2
+ export declare const CORE_MIGRATIONS: readonly Migration[];
3
+ export type MigrationApplyMode = 'auto-safe' | 'doctor-fix' | 'manual';
4
+ export interface MigrationApplyResult {
5
+ items: MigrationPlanItem[];
6
+ changed: boolean;
7
+ }
8
+ export declare function detectMigrations(configPath: string, options?: {
9
+ stateDir?: string;
10
+ }): MigrationPlanItem[];
11
+ export declare function applyMigrations(configPath: string, options?: {
12
+ stateDir?: string;
13
+ mode?: MigrationApplyMode;
14
+ }): MigrationApplyResult;
15
+ export declare function runBootstrapMigrationsSync(configPath: string, options?: {
16
+ stateDir?: string;
17
+ }): MigrationApplyResult;
@@ -0,0 +1,191 @@
1
+ import { ConfigSchema, init_schema } from "../config/schema.js";
2
+ import { createLogger } from "../utils/logger/index.js";
3
+ import { init_logger } from "../utils/logger.js";
4
+ import { listRegisteredMigrations } from "./registry.js";
5
+ import { defaultCapabilityPresetMigration } from "./config/default-capability-preset.js";
6
+ import { dirname, join } from "node:path";
7
+ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
8
+ //#region src/migrations/runner.ts
9
+ init_schema();
10
+ init_logger();
11
+ const log = createLogger("Migrations");
12
+ const MIGRATION_LEDGER_FILENAME = "migrations.json";
13
+ const CONFIG_BACKUP_COUNT = 10;
14
+ const CORE_MIGRATIONS = [...[defaultCapabilityPresetMigration]];
15
+ function listAllMigrations() {
16
+ return [...CORE_MIGRATIONS, ...listRegisteredMigrations().map((entry) => entry.migration)];
17
+ }
18
+ function publicItem(item) {
19
+ if (!item.details || !Object.hasOwn(item.details, "config")) return item;
20
+ const { config: _config, ...details } = item.details;
21
+ return {
22
+ ...item,
23
+ details
24
+ };
25
+ }
26
+ function makeContext(configPath, stateDir) {
27
+ return {
28
+ configPath,
29
+ stateDir: stateDir ?? dirname(configPath),
30
+ now: /* @__PURE__ */ new Date()
31
+ };
32
+ }
33
+ function rotateConfigBackupsSync(configPath) {
34
+ const backupBase = `${configPath}.bak`;
35
+ for (let index = CONFIG_BACKUP_COUNT - 1; index >= 1; index--) {
36
+ const source = index === 1 ? backupBase : `${backupBase}.${index - 1}`;
37
+ const target = `${backupBase}.${index}`;
38
+ if (existsSync(source)) try {
39
+ renameSync(source, target);
40
+ } catch {}
41
+ }
42
+ }
43
+ function writeConfigWithBackupSync(configPath, config) {
44
+ const validated = ConfigSchema.parse(config);
45
+ mkdirSync(dirname(configPath), { recursive: true });
46
+ if (existsSync(configPath)) {
47
+ rotateConfigBackupsSync(configPath);
48
+ try {
49
+ writeFileSync(`${configPath}.bak`, readFileSync(configPath, "utf8"), "utf8");
50
+ } catch {}
51
+ }
52
+ const tmp = `${configPath}.tmp-${process.pid}-${Date.now()}`;
53
+ writeFileSync(tmp, `${JSON.stringify(validated, null, 2)}\n`, "utf8");
54
+ renameSync(tmp, configPath);
55
+ }
56
+ function resolveLedgerPath(ctx) {
57
+ if (!ctx.stateDir) return null;
58
+ return join(ctx.stateDir, MIGRATION_LEDGER_FILENAME);
59
+ }
60
+ function readLedger(ctx) {
61
+ const ledgerPath = resolveLedgerPath(ctx);
62
+ if (!ledgerPath || !existsSync(ledgerPath)) return {
63
+ version: 1,
64
+ runs: []
65
+ };
66
+ try {
67
+ const parsed = JSON.parse(readFileSync(ledgerPath, "utf8"));
68
+ if (parsed.version === 1 && Array.isArray(parsed.runs)) return {
69
+ version: 1,
70
+ runs: parsed.runs
71
+ };
72
+ } catch {}
73
+ return {
74
+ version: 1,
75
+ runs: []
76
+ };
77
+ }
78
+ function appendLedgerRun(ctx, item) {
79
+ const ledgerPath = resolveLedgerPath(ctx);
80
+ if (!ledgerPath) return;
81
+ try {
82
+ const ledger = readLedger(ctx);
83
+ ledger.runs.push({
84
+ id: item.id,
85
+ status: item.status,
86
+ appliedAt: (ctx.now ?? /* @__PURE__ */ new Date()).toISOString(),
87
+ message: item.message
88
+ });
89
+ mkdirSync(dirname(ledgerPath), { recursive: true });
90
+ writeFileSync(ledgerPath, `${JSON.stringify(ledger, null, 2)}\n`, "utf8");
91
+ } catch (err) {
92
+ const em = err instanceof Error ? err.message : String(err);
93
+ log.warn({
94
+ err,
95
+ errorMessage: em,
96
+ path: ledgerPath
97
+ }, `Failed to write migration ledger: ${em}`);
98
+ }
99
+ }
100
+ function shouldApply(item, mode) {
101
+ if (item.status !== "planned") return false;
102
+ if (mode === "manual") return true;
103
+ return item.safety === "auto";
104
+ }
105
+ function detectMigrations(configPath, options = {}) {
106
+ const ctx = makeContext(configPath, options.stateDir);
107
+ const items = [];
108
+ for (const migration of listAllMigrations()) try {
109
+ const item = migration.detect(ctx);
110
+ if (item) items.push(publicItem(item));
111
+ } catch (err) {
112
+ const em = err instanceof Error ? err.message : String(err);
113
+ items.push({
114
+ id: migration.id,
115
+ title: migration.id,
116
+ kind: migration.kind,
117
+ safety: migration.safety,
118
+ status: "error",
119
+ message: `Migration detection failed: ${em}`
120
+ });
121
+ }
122
+ return items;
123
+ }
124
+ function applyMigrations(configPath, options = {}) {
125
+ const ctx = makeContext(configPath, options.stateDir);
126
+ const mode = options.mode ?? "auto-safe";
127
+ const results = [];
128
+ let changed = false;
129
+ for (const migration of listAllMigrations()) {
130
+ let detected;
131
+ try {
132
+ detected = migration.detect(ctx);
133
+ } catch (err) {
134
+ const em = err instanceof Error ? err.message : String(err);
135
+ results.push({
136
+ id: migration.id,
137
+ title: migration.id,
138
+ kind: migration.kind,
139
+ safety: migration.safety,
140
+ status: "error",
141
+ message: `Migration detection failed: ${em}`
142
+ });
143
+ continue;
144
+ }
145
+ if (!detected) continue;
146
+ if (!shouldApply(detected, mode)) {
147
+ results.push(publicItem(detected));
148
+ continue;
149
+ }
150
+ try {
151
+ const applied = migration.apply(ctx);
152
+ const nextConfig = applied.details?.config;
153
+ if (applied.status === "applied" && nextConfig) {
154
+ writeConfigWithBackupSync(configPath, ConfigSchema.parse(nextConfig));
155
+ changed = true;
156
+ appendLedgerRun(ctx, applied);
157
+ }
158
+ results.push(publicItem(applied));
159
+ } catch (err) {
160
+ const em = err instanceof Error ? err.message : String(err);
161
+ results.push({
162
+ ...detected,
163
+ status: "error",
164
+ message: `Migration apply failed: ${em}`
165
+ });
166
+ }
167
+ }
168
+ return {
169
+ items: results,
170
+ changed
171
+ };
172
+ }
173
+ function runBootstrapMigrationsSync(configPath, options = {}) {
174
+ if (!existsSync(configPath)) return {
175
+ items: [],
176
+ changed: false
177
+ };
178
+ const result = applyMigrations(configPath, {
179
+ ...options,
180
+ mode: "auto-safe"
181
+ });
182
+ if (result.changed) log.info({
183
+ configPath,
184
+ count: result.items.filter((item) => item.status === "applied").length
185
+ }, "Applied bootstrap migrations");
186
+ return result;
187
+ }
188
+ //#endregion
189
+ export { CORE_MIGRATIONS, applyMigrations, detectMigrations, runBootstrapMigrationsSync };
190
+
191
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","names":[],"sources":["../../../src/migrations/runner.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\n\nimport { ConfigSchema, type Config } from '../config/schema.js';\nimport { createLogger } from '../utils/logger.js';\nimport { defaultCapabilityPresetMigration } from './config/default-capability-preset.js';\nimport { listRegisteredMigrations } from './registry.js';\nimport type { Migration, MigrationContext, MigrationLedger, MigrationPlanItem } from './types.js';\n\nconst log = createLogger('Migrations');\nconst MIGRATION_LEDGER_FILENAME = 'migrations.json';\nconst CONFIG_BACKUP_COUNT = 10;\n\nconst CONFIG_MIGRATIONS: readonly Migration[] = [defaultCapabilityPresetMigration];\nexport const CORE_MIGRATIONS: readonly Migration[] = [...CONFIG_MIGRATIONS];\n\nfunction listAllMigrations(): Migration[] {\n return [...CORE_MIGRATIONS, ...listRegisteredMigrations().map((entry) => entry.migration)];\n}\n\nexport type MigrationApplyMode = 'auto-safe' | 'doctor-fix' | 'manual';\n\nexport interface MigrationApplyResult {\n items: MigrationPlanItem[];\n changed: boolean;\n}\n\nfunction publicItem(item: MigrationPlanItem): MigrationPlanItem {\n if (!item.details || !Object.hasOwn(item.details, 'config')) return item;\n const { config: _config, ...details } = item.details;\n return { ...item, details };\n}\n\nfunction makeContext(configPath: string, stateDir?: string): MigrationContext {\n return { configPath, stateDir: stateDir ?? dirname(configPath), now: new Date() };\n}\n\nfunction rotateConfigBackupsSync(configPath: string): void {\n const backupBase = `${configPath}.bak`;\n for (let index = CONFIG_BACKUP_COUNT - 1; index >= 1; index--) {\n const source = index === 1 ? backupBase : `${backupBase}.${index - 1}`;\n const target = `${backupBase}.${index}`;\n if (existsSync(source)) {\n try { renameSync(source, target); } catch { /* best effort */ }\n }\n }\n}\n\nfunction writeConfigWithBackupSync(configPath: string, config: Config): void {\n const validated = ConfigSchema.parse(config);\n mkdirSync(dirname(configPath), { recursive: true });\n if (existsSync(configPath)) {\n rotateConfigBackupsSync(configPath);\n try {\n writeFileSync(`${configPath}.bak`, readFileSync(configPath, 'utf8'), 'utf8');\n } catch {\n // best-effort backup; atomic write below still proceeds\n }\n }\n const tmp = `${configPath}.tmp-${process.pid}-${Date.now()}`;\n writeFileSync(tmp, `${JSON.stringify(validated, null, 2)}\\n`, 'utf8');\n renameSync(tmp, configPath);\n}\n\nfunction resolveLedgerPath(ctx: MigrationContext): string | null {\n if (!ctx.stateDir) return null;\n return join(ctx.stateDir, MIGRATION_LEDGER_FILENAME);\n}\n\nfunction readLedger(ctx: MigrationContext): MigrationLedger {\n const ledgerPath = resolveLedgerPath(ctx);\n if (!ledgerPath || !existsSync(ledgerPath)) return { version: 1, runs: [] };\n try {\n const parsed = JSON.parse(readFileSync(ledgerPath, 'utf8')) as Partial<MigrationLedger>;\n if (parsed.version === 1 && Array.isArray(parsed.runs)) {\n return { version: 1, runs: parsed.runs as MigrationLedger['runs'] };\n }\n } catch {\n // Corrupt migration ledgers should never block runtime startup.\n }\n return { version: 1, runs: [] };\n}\n\nfunction appendLedgerRun(ctx: MigrationContext, item: MigrationPlanItem): void {\n const ledgerPath = resolveLedgerPath(ctx);\n if (!ledgerPath) return;\n try {\n const ledger = readLedger(ctx);\n ledger.runs.push({\n id: item.id,\n status: item.status,\n appliedAt: (ctx.now ?? new Date()).toISOString(),\n message: item.message,\n });\n mkdirSync(dirname(ledgerPath), { recursive: true });\n writeFileSync(ledgerPath, `${JSON.stringify(ledger, null, 2)}\\n`, 'utf8');\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n log.warn({ err, errorMessage: em, path: ledgerPath }, `Failed to write migration ledger: ${em}`);\n }\n}\n\nfunction shouldApply(item: MigrationPlanItem, mode: MigrationApplyMode): boolean {\n if (item.status !== 'planned') return false;\n if (mode === 'manual') return true;\n return item.safety === 'auto';\n}\n\nexport function detectMigrations(configPath: string, options: { stateDir?: string } = {}): MigrationPlanItem[] {\n const ctx = makeContext(configPath, options.stateDir);\n const items: MigrationPlanItem[] = [];\n for (const migration of listAllMigrations()) {\n try {\n const item = migration.detect(ctx);\n if (item) items.push(publicItem(item));\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n items.push({\n id: migration.id,\n title: migration.id,\n kind: migration.kind,\n safety: migration.safety,\n status: 'error',\n message: `Migration detection failed: ${em}`,\n });\n }\n }\n return items;\n}\n\nexport function applyMigrations(\n configPath: string,\n options: { stateDir?: string; mode?: MigrationApplyMode } = {},\n): MigrationApplyResult {\n const ctx = makeContext(configPath, options.stateDir);\n const mode = options.mode ?? 'auto-safe';\n const results: MigrationPlanItem[] = [];\n let changed = false;\n\n for (const migration of listAllMigrations()) {\n let detected: MigrationPlanItem | null;\n try {\n detected = migration.detect(ctx);\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n results.push({\n id: migration.id,\n title: migration.id,\n kind: migration.kind,\n safety: migration.safety,\n status: 'error',\n message: `Migration detection failed: ${em}`,\n });\n continue;\n }\n\n if (!detected) continue;\n if (!shouldApply(detected, mode)) {\n results.push(publicItem(detected));\n continue;\n }\n\n try {\n const applied = migration.apply(ctx);\n const nextConfig = applied.details?.config;\n if (applied.status === 'applied' && nextConfig) {\n writeConfigWithBackupSync(configPath, ConfigSchema.parse(nextConfig));\n changed = true;\n appendLedgerRun(ctx, applied);\n }\n results.push(publicItem(applied));\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n results.push({\n ...detected,\n status: 'error',\n message: `Migration apply failed: ${em}`,\n });\n }\n }\n\n return { items: results, changed };\n}\n\nexport function runBootstrapMigrationsSync(configPath: string, options: { stateDir?: string } = {}): MigrationApplyResult {\n if (!existsSync(configPath)) return { items: [], changed: false };\n const result = applyMigrations(configPath, { ...options, mode: 'auto-safe' });\n if (result.changed) {\n log.info({ configPath, count: result.items.filter((item) => item.status === 'applied').length }, 'Applied bootstrap migrations');\n }\n return result;\n}\n"],"mappings":";;;;;;;;aAGgE;aACd;AAKlD,MAAM,MAAM,aAAa,aAAa;AACtC,MAAM,4BAA4B;AAClC,MAAM,sBAAsB;AAG5B,MAAa,kBAAwC,CAAC,GAAG,CADR,iCACQ,CAAkB;AAE3E,SAAS,oBAAiC;AACxC,QAAO,CAAC,GAAG,iBAAiB,GAAG,0BAA0B,CAAC,KAAK,UAAU,MAAM,UAAU,CAAC;;AAU5F,SAAS,WAAW,MAA4C;AAC9D,KAAI,CAAC,KAAK,WAAW,CAAC,OAAO,OAAO,KAAK,SAAS,SAAS,CAAE,QAAO;CACpE,MAAM,EAAE,QAAQ,SAAS,GAAG,YAAY,KAAK;AAC7C,QAAO;EAAE,GAAG;EAAM;EAAS;;AAG7B,SAAS,YAAY,YAAoB,UAAqC;AAC5E,QAAO;EAAE;EAAY,UAAU,YAAY,QAAQ,WAAW;EAAE,qBAAK,IAAI,MAAM;EAAE;;AAGnF,SAAS,wBAAwB,YAA0B;CACzD,MAAM,aAAa,GAAG,WAAW;AACjC,MAAK,IAAI,QAAQ,sBAAsB,GAAG,SAAS,GAAG,SAAS;EAC7D,MAAM,SAAS,UAAU,IAAI,aAAa,GAAG,WAAW,GAAG,QAAQ;EACnE,MAAM,SAAS,GAAG,WAAW,GAAG;AAChC,MAAI,WAAW,OAAO,CACpB,KAAI;AAAE,cAAW,QAAQ,OAAO;UAAU;;;AAKhD,SAAS,0BAA0B,YAAoB,QAAsB;CAC3E,MAAM,YAAY,aAAa,MAAM,OAAO;AAC5C,WAAU,QAAQ,WAAW,EAAE,EAAE,WAAW,MAAM,CAAC;AACnD,KAAI,WAAW,WAAW,EAAE;AAC1B,0BAAwB,WAAW;AACnC,MAAI;AACF,iBAAc,GAAG,WAAW,OAAO,aAAa,YAAY,OAAO,EAAE,OAAO;UACtE;;CAIV,MAAM,MAAM,GAAG,WAAW,OAAO,QAAQ,IAAI,GAAG,KAAK,KAAK;AAC1D,eAAc,KAAK,GAAG,KAAK,UAAU,WAAW,MAAM,EAAE,CAAC,KAAK,OAAO;AACrE,YAAW,KAAK,WAAW;;AAG7B,SAAS,kBAAkB,KAAsC;AAC/D,KAAI,CAAC,IAAI,SAAU,QAAO;AAC1B,QAAO,KAAK,IAAI,UAAU,0BAA0B;;AAGtD,SAAS,WAAW,KAAwC;CAC1D,MAAM,aAAa,kBAAkB,IAAI;AACzC,KAAI,CAAC,cAAc,CAAC,WAAW,WAAW,CAAE,QAAO;EAAE,SAAS;EAAG,MAAM,EAAE;EAAE;AAC3E,KAAI;EACF,MAAM,SAAS,KAAK,MAAM,aAAa,YAAY,OAAO,CAAC;AAC3D,MAAI,OAAO,YAAY,KAAK,MAAM,QAAQ,OAAO,KAAK,CACpD,QAAO;GAAE,SAAS;GAAG,MAAM,OAAO;GAAiC;SAE/D;AAGR,QAAO;EAAE,SAAS;EAAG,MAAM,EAAE;EAAE;;AAGjC,SAAS,gBAAgB,KAAuB,MAA+B;CAC7E,MAAM,aAAa,kBAAkB,IAAI;AACzC,KAAI,CAAC,WAAY;AACjB,KAAI;EACF,MAAM,SAAS,WAAW,IAAI;AAC9B,SAAO,KAAK,KAAK;GACf,IAAI,KAAK;GACT,QAAQ,KAAK;GACb,YAAY,IAAI,uBAAO,IAAI,MAAM,EAAE,aAAa;GAChD,SAAS,KAAK;GACf,CAAC;AACF,YAAU,QAAQ,WAAW,EAAE,EAAE,WAAW,MAAM,CAAC;AACnD,gBAAc,YAAY,GAAG,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC,KAAK,OAAO;UAClE,KAAK;EACZ,MAAM,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC3D,MAAI,KAAK;GAAE;GAAK,cAAc;GAAI,MAAM;GAAY,EAAE,qCAAqC,KAAK;;;AAIpG,SAAS,YAAY,MAAyB,MAAmC;AAC/E,KAAI,KAAK,WAAW,UAAW,QAAO;AACtC,KAAI,SAAS,SAAU,QAAO;AAC9B,QAAO,KAAK,WAAW;;AAGzB,SAAgB,iBAAiB,YAAoB,UAAiC,EAAE,EAAuB;CAC7G,MAAM,MAAM,YAAY,YAAY,QAAQ,SAAS;CACrD,MAAM,QAA6B,EAAE;AACrC,MAAK,MAAM,aAAa,mBAAmB,CACzC,KAAI;EACF,MAAM,OAAO,UAAU,OAAO,IAAI;AAClC,MAAI,KAAM,OAAM,KAAK,WAAW,KAAK,CAAC;UAC/B,KAAK;EACZ,MAAM,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC3D,QAAM,KAAK;GACT,IAAI,UAAU;GACd,OAAO,UAAU;GACjB,MAAM,UAAU;GAChB,QAAQ,UAAU;GAClB,QAAQ;GACR,SAAS,+BAA+B;GACzC,CAAC;;AAGN,QAAO;;AAGT,SAAgB,gBACd,YACA,UAA4D,EAAE,EACxC;CACtB,MAAM,MAAM,YAAY,YAAY,QAAQ,SAAS;CACrD,MAAM,OAAO,QAAQ,QAAQ;CAC7B,MAAM,UAA+B,EAAE;CACvC,IAAI,UAAU;AAEd,MAAK,MAAM,aAAa,mBAAmB,EAAE;EAC3C,IAAI;AACJ,MAAI;AACF,cAAW,UAAU,OAAO,IAAI;WACzB,KAAK;GACZ,MAAM,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC3D,WAAQ,KAAK;IACX,IAAI,UAAU;IACd,OAAO,UAAU;IACjB,MAAM,UAAU;IAChB,QAAQ,UAAU;IAClB,QAAQ;IACR,SAAS,+BAA+B;IACzC,CAAC;AACF;;AAGF,MAAI,CAAC,SAAU;AACf,MAAI,CAAC,YAAY,UAAU,KAAK,EAAE;AAChC,WAAQ,KAAK,WAAW,SAAS,CAAC;AAClC;;AAGF,MAAI;GACF,MAAM,UAAU,UAAU,MAAM,IAAI;GACpC,MAAM,aAAa,QAAQ,SAAS;AACpC,OAAI,QAAQ,WAAW,aAAa,YAAY;AAC9C,8BAA0B,YAAY,aAAa,MAAM,WAAW,CAAC;AACrE,cAAU;AACV,oBAAgB,KAAK,QAAQ;;AAE/B,WAAQ,KAAK,WAAW,QAAQ,CAAC;WAC1B,KAAK;GACZ,MAAM,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC3D,WAAQ,KAAK;IACX,GAAG;IACH,QAAQ;IACR,SAAS,2BAA2B;IACrC,CAAC;;;AAIN,QAAO;EAAE,OAAO;EAAS;EAAS;;AAGpC,SAAgB,2BAA2B,YAAoB,UAAiC,EAAE,EAAwB;AACxH,KAAI,CAAC,WAAW,WAAW,CAAE,QAAO;EAAE,OAAO,EAAE;EAAE,SAAS;EAAO;CACjE,MAAM,SAAS,gBAAgB,YAAY;EAAE,GAAG;EAAS,MAAM;EAAa,CAAC;AAC7E,KAAI,OAAO,QACT,KAAI,KAAK;EAAE;EAAY,OAAO,OAAO,MAAM,QAAQ,SAAS,KAAK,WAAW,UAAU,CAAC;EAAQ,EAAE,+BAA+B;AAElI,QAAO"}
@@ -0,0 +1,34 @@
1
+ export type MigrationKind = 'config' | 'state' | 'sqlite' | 'extension';
2
+ export type MigrationSafety = 'auto' | 'manual' | 'blocked';
3
+ export type MigrationStatus = 'not_needed' | 'planned' | 'applied' | 'skipped' | 'conflict' | 'error';
4
+ export interface MigrationPlanItem {
5
+ id: string;
6
+ title: string;
7
+ kind: MigrationKind;
8
+ safety: MigrationSafety;
9
+ status: MigrationStatus;
10
+ message: string;
11
+ details?: Record<string, unknown>;
12
+ }
13
+ export interface MigrationContext {
14
+ configPath: string;
15
+ stateDir?: string;
16
+ now?: Date;
17
+ }
18
+ export interface Migration {
19
+ id: string;
20
+ kind: MigrationKind;
21
+ safety: MigrationSafety;
22
+ detect(ctx: MigrationContext): MigrationPlanItem | null;
23
+ apply(ctx: MigrationContext): MigrationPlanItem;
24
+ }
25
+ export interface MigrationLedgerRun {
26
+ id: string;
27
+ status: MigrationStatus;
28
+ appliedAt: string;
29
+ message: string;
30
+ }
31
+ export interface MigrationLedger {
32
+ version: 1;
33
+ runs: MigrationLedgerRun[];
34
+ }
@@ -1,6 +1,7 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
3
  import { getDefaultModelSync, init_providers, resolveModel } from "../providers/index.js";
4
+ import { publishAutomationProductEvent } from "../automations/product-events.js";
4
5
  import { buildNoteAttachmentRef } from "./attachment-ref.js";
5
6
  import { parseNoteMarkdown } from "./note-markdown.js";
6
7
  import { NotesStore } from "./store.js";
@@ -33,6 +34,22 @@ function splitMeaningfulLines(markdown) {
33
34
  function summarizeIdea(markdown) {
34
35
  return splitMeaningfulLines(markdown).slice(0, 3).join(";").slice(0, 140);
35
36
  }
37
+ function publishNoteEvent(type, note, extra) {
38
+ publishAutomationProductEvent({
39
+ type,
40
+ source: "notes",
41
+ payload: {
42
+ noteId: note.id,
43
+ kind: note.kind,
44
+ status: note.status,
45
+ title: note.title,
46
+ capturedVia: note.capturedVia,
47
+ tagCount: note.tags?.length ?? 0,
48
+ hasAttachments: Boolean(note.attachments?.length),
49
+ ...extra
50
+ }
51
+ });
52
+ }
36
53
  function inferCatalysisStage(note) {
37
54
  const text = `${note.title ?? ""}\n${note.markdown}`;
38
55
  if (/上线|发布|launch|ship/i.test(text)) return "shipped";
@@ -174,6 +191,7 @@ var NotesService = class {
174
191
  localVersion: 1
175
192
  };
176
193
  await this.store.addNote(note);
194
+ publishNoteEvent("note.created", note);
177
195
  log.debug({
178
196
  id: note.id,
179
197
  kind: note.kind
@@ -195,7 +213,12 @@ var NotesService = class {
195
213
  normalizedPatch.localVersion = patch.localVersion ?? (existing.localVersion ?? 1) + 1;
196
214
  }
197
215
  const updatedRaw = await this.store.updateNote(id, normalizedPatch);
198
- return updatedRaw ? this.reconcileAttachments(updatedRaw) : null;
216
+ const updated = updatedRaw ? await this.reconcileAttachments(updatedRaw) : null;
217
+ if (updated) publishNoteEvent("note.updated", updated, {
218
+ contentTouched,
219
+ trigger
220
+ });
221
+ return updated;
199
222
  }
200
223
  async reconcileAttachments(note) {
201
224
  const { kept, removed } = partitionAttachmentsByReference(note);