@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.
- package/README.md +2 -1
- package/README.zh-CN.md +2 -1
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-dzUrQoeZ.js → agent-avatar-dicebear-CU8J6zou.js} +1 -1
- package/dist/gateway/static/root/assets/agents-B0hkpLhP.js +2 -0
- package/dist/gateway/static/root/assets/app-management-settings-panel-B9vfYoEr.js +1 -0
- package/dist/gateway/static/root/assets/appearance-settings-ClOzIO24.js +1 -0
- package/dist/gateway/static/root/assets/{apps-page--wMEL00f.js → apps-page-DU0dz9Zo.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-Cki4SfU2.js → archive-plugin-BkVIgZzA.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-D-KnS2Do.js → attachment-load-CaCMWh1D.js} +1 -1
- package/dist/gateway/static/root/assets/automation-suggestion-card-DhGDpKP3.js +1 -0
- package/dist/gateway/static/root/assets/automations-page-CTedroVo.js +1 -0
- package/dist/gateway/static/root/assets/{binary-plugins-D2sgvJja.js → binary-plugins-B4TO_bsn.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-DIq-4Gvb.js → block-editor-DJRWwWNI.js} +28 -28
- package/dist/gateway/static/root/assets/browser-settings-page-FCDwOOBK.js +8 -0
- package/dist/gateway/static/root/assets/capability-presets-api-Befi89CL.js +1 -0
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-_G8eb2vJ.js +1 -0
- package/dist/gateway/static/root/assets/channel-recipient-api-BNSuJb5f.js +1 -0
- package/dist/gateway/static/root/assets/channels-settings-C3d5JBJX.js +1 -0
- package/dist/gateway/static/root/assets/cn-BQ_8x0bT.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-yaUNvt5u.js +2 -0
- package/dist/gateway/static/root/assets/cron-expression-B3B1eqnr.js +2 -0
- package/dist/gateway/static/root/assets/dreaming-settings-DNrdg1Ve.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-DYu1KaFQ.js → extension-debug-page-DYh402XV.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-B3W6QwlZ.js → extension-page-Cr_TizrN.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-D7VQ-cxE.js → extension-settings-page-BU1KoKRj.js} +1 -1
- package/dist/gateway/static/root/assets/{fetch-B7xDPu-R.js → fetch-Y7AEX4H3.js} +1 -1
- package/dist/gateway/static/root/assets/format-cron-label-arqgGlVV.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-config-api-BTBLSeUu.js → gateway-config-api-RbMmAOpX.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-C79wkXef.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-CYj9FWCp.js → gateway-startup-retry-DiD_Tx4N.js} +1 -1
- package/dist/gateway/static/root/assets/goal-detail-page-9paXuHdo.js +1 -0
- package/dist/gateway/static/root/assets/{goals-config-api-CQQgzPr3.js → goals-config-api-DqxVi0p5.js} +1 -1
- package/dist/gateway/static/root/assets/{goals-page-BHitvJAv.js → goals-page-CS0R-Af2.js} +2 -2
- package/dist/gateway/static/root/assets/goals-settings-CSuzZ8Ae.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-settings-DXPaYJm3.js +1 -0
- package/dist/gateway/static/root/assets/index-BoKafJIZ.js +191 -0
- package/dist/gateway/static/root/assets/index-CArhCcYn.css +1 -0
- package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-Dvg53qnd.js +1 -0
- package/dist/gateway/static/root/assets/{logs-page-C2Uqvae9.js → logs-page-DLXPcksQ.js} +2 -2
- package/dist/gateway/static/root/assets/{markdown-split-BwOFrJ2E.js → markdown-split-CpHxbtWJ.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-Cnz6Q5G6.js → media-plugins-SFPQRSxq.js} +1 -1
- package/dist/gateway/static/root/assets/messages-CrDHEbss.js +3 -0
- package/dist/gateway/static/root/assets/models-hub-panel-BDF2iyRk.js +2 -0
- package/dist/gateway/static/root/assets/note-detail-page-CSb_hwig.js +2 -0
- package/dist/gateway/static/root/assets/{note-image-lightbox-B-Svpmza.js → note-image-lightbox-BUYURRgn.js} +1 -1
- package/dist/gateway/static/root/assets/notes-page-BsIBSFyZ.js +1 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-Bss4TiwP.js → preview-open-alternatives-BHz9iWYA.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CwzSovcS.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-BRNjdgKq.js → save-bar-controls-CefkOlRg.js} +1 -1
- package/dist/gateway/static/root/assets/schedule-field-CmTRoOcE.js +1 -0
- package/dist/gateway/static/root/assets/{schema-form-Dub9sy8r.js → schema-form-FMKv1vGu.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-PHmX-NmA.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-BRAeKJN4.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-BeFLavGi.js → settings-collapsible-section-BouO6JTi.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-dmyaPOTG.js → settings-form-section-D-4lBl6X.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-KKrbFjy8.js +1 -0
- package/dist/gateway/static/root/assets/settings-page-layout-BJ4Gsef5.js +1 -0
- package/dist/gateway/static/root/assets/setup-status-panel-CrUjHPQo.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-C8glrdqe.js → share-preview-page-BDy2btRN.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-B18OBmH5.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-C28-2uKQ.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-Bm2ebkwl.js +2 -0
- package/dist/gateway/static/root/assets/system-settings-panel-CRngrlnZ.js +1 -0
- package/dist/gateway/static/root/assets/typed-models-lib-BltBc0b-.js +1 -0
- package/dist/gateway/static/root/assets/{use-channel-catalog-DqlWTsDb.js → use-channel-catalog-CjN-51e6.js} +1 -1
- package/dist/gateway/static/root/assets/user-profile-settings-panel-DJ1dKwZy.js +1 -0
- package/dist/gateway/static/root/assets/utils-B5M5-YvK.js +1 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-C73IVZeC.js → voice-api-key-field-CeEevm7z.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-player-store-C_ArLJPM.js → voice-player-store-B7ykUlHM.js} +1 -1
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-C4PzUQjB.js +3 -0
- package/dist/gateway/static/root/assets/workflows-page-BL84_-Ky.js +18 -0
- package/dist/gateway/static/root/index.html +6 -7
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +4 -5
- package/dist/src/agent/agent-manager.js +4 -8
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/embedded/run-for-session.js +102 -14
- package/dist/src/agent/embedded/run-for-session.js.map +1 -1
- package/dist/src/agent/fallback/candidates.d.ts +0 -8
- package/dist/src/agent/fallback/candidates.js.map +1 -1
- package/dist/src/agent/index.js +1 -1
- package/dist/src/agent/lifecycle/handlers/compaction.d.ts +1 -3
- package/dist/src/agent/lifecycle/handlers/compaction.js +1 -16
- package/dist/src/agent/lifecycle/handlers/compaction.js.map +1 -1
- package/dist/src/agent/lifecycle/progress.d.ts +0 -1
- package/dist/src/agent/lifecycle/progress.js +1 -6
- package/dist/src/agent/lifecycle/progress.js.map +1 -1
- package/dist/src/agent/lifecycle/timeout-wrapper.d.ts +1 -2
- package/dist/src/agent/lifecycle/timeout-wrapper.js +1 -7
- package/dist/src/agent/lifecycle/timeout-wrapper.js.map +1 -1
- package/dist/src/agent/middleware/self-verify.d.ts +0 -1
- package/dist/src/agent/middleware/self-verify.js +0 -2
- package/dist/src/agent/middleware/self-verify.js.map +1 -1
- package/dist/src/agent/models/index.d.ts +1 -1
- package/dist/src/agent/models/manager.d.ts +4 -20
- package/dist/src/agent/models/manager.js +9 -126
- package/dist/src/agent/models/manager.js.map +1 -1
- package/dist/src/agent/orchestration/agent-orchestrator.d.ts +0 -4
- package/dist/src/agent/orchestration/agent-orchestrator.js +1 -9
- package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
- package/dist/src/agent/prompt/sections/tooling.js +2 -2
- package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.d.ts +0 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +0 -12
- package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
- package/dist/src/agent/prompt/subagent-context.js +1 -1
- package/dist/src/agent/prompt/subagent-context.js.map +1 -1
- package/dist/src/agent/prompt/types.d.ts +1 -1
- package/dist/src/agent/service.d.ts +1 -9
- package/dist/src/agent/service.js +3 -40
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/service.types.d.ts +2 -2
- package/dist/src/agent/session/session-config-service.d.ts +11 -11
- package/dist/src/agent/session/session-config-service.js +14 -14
- package/dist/src/agent/session/session-config-service.js.map +1 -1
- package/dist/src/agent/session/session-inspector.js +3 -2
- package/dist/src/agent/session/session-inspector.js.map +1 -1
- package/dist/src/agent/starter-agents.js +12 -12
- package/dist/src/agent/starter-agents.js.map +1 -1
- package/dist/src/agent/tools/automation-tool.d.ts +14 -0
- package/dist/src/agent/tools/automation-tool.js +102 -0
- package/dist/src/agent/tools/automation-tool.js.map +1 -0
- package/dist/src/agent/tools/delegate-tool.js +1 -1
- package/dist/src/agent/tools/delegate-tool.js.map +1 -1
- package/dist/src/agent/tools/factory.d.ts +3 -3
- package/dist/src/agent/tools/factory.js +2 -2
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/index.d.ts +1 -1
- package/dist/src/agent/tools/index.js +2 -2
- package/dist/src/agent-manifest/resolver.d.ts +1 -0
- package/dist/src/agent-manifest/resolver.js +1 -0
- package/dist/src/agent-manifest/resolver.js.map +1 -1
- package/dist/src/agent-manifest/schema.d.ts +6 -0
- package/dist/src/agent-manifest/schema.js +12 -3
- package/dist/src/agent-manifest/schema.js.map +1 -1
- package/dist/src/ai-assist/text-assist.d.ts +1 -1
- package/dist/src/ai-assist/text-assist.js +56 -0
- package/dist/src/ai-assist/text-assist.js.map +1 -1
- package/dist/src/auth/profiles/store.js.map +1 -1
- package/dist/src/automations/api/routes.d.ts +3 -0
- package/dist/src/automations/api/routes.js +193 -0
- package/dist/src/automations/api/routes.js.map +1 -0
- package/dist/src/automations/domain/index.d.ts +3 -0
- package/dist/src/automations/domain/index.js +3 -0
- package/dist/src/automations/domain/schedule.d.ts +4 -0
- package/dist/src/automations/domain/schedule.js +37 -0
- package/dist/src/automations/domain/schedule.js.map +1 -0
- package/dist/src/automations/domain/types.d.ts +160 -0
- package/dist/src/automations/domain/validation.d.ts +370 -0
- package/dist/src/automations/domain/validation.js +149 -0
- package/dist/src/automations/domain/validation.js.map +1 -0
- package/dist/src/automations/draft/automation-draft-prompt.d.ts +26 -0
- package/dist/src/automations/draft/automation-draft-prompt.js +127 -0
- package/dist/src/automations/draft/automation-draft-prompt.js.map +1 -0
- package/dist/src/automations/draft/automation-draft-service.d.ts +12 -0
- package/dist/src/automations/draft/automation-draft-service.js +135 -0
- package/dist/src/automations/draft/automation-draft-service.js.map +1 -0
- package/dist/src/automations/draft/automation-draft-validator.d.ts +99 -0
- package/dist/src/automations/draft/automation-draft-validator.js +105 -0
- package/dist/src/automations/draft/automation-draft-validator.js.map +1 -0
- package/dist/src/automations/draft/automation-draft.types.d.ts +40 -0
- package/dist/src/automations/draft/index.d.ts +3 -0
- package/dist/src/automations/draft/index.js +3 -0
- package/dist/src/automations/index.d.ts +3 -0
- package/dist/src/automations/index.js +8 -0
- package/dist/src/automations/product-events.d.ts +5 -0
- package/dist/src/automations/product-events.js +21 -0
- package/dist/src/automations/product-events.js.map +1 -0
- package/dist/src/automations/service/action-executor.d.ts +9 -0
- package/dist/src/automations/service/action-executor.js +157 -0
- package/dist/src/automations/service/action-executor.js.map +1 -0
- package/dist/src/automations/service/automation-service.d.ts +54 -0
- package/dist/src/automations/service/automation-service.js +404 -0
- package/dist/src/automations/service/automation-service.js.map +1 -0
- package/dist/src/automations/service/index.d.ts +2 -0
- package/dist/src/automations/service/index.js +3 -0
- package/dist/src/automations/storage/automation-repository.d.ts +6 -0
- package/dist/src/automations/storage/automation-repository.js +61 -0
- package/dist/src/automations/storage/automation-repository.js.map +1 -0
- package/dist/src/automations/storage/automation-run-repository.d.ts +17 -0
- package/dist/src/automations/storage/automation-run-repository.js +130 -0
- package/dist/src/automations/storage/automation-run-repository.js.map +1 -0
- package/dist/src/automations/storage/index.d.ts +2 -0
- package/dist/src/automations/storage/index.js +3 -0
- package/dist/src/channels/plugin-types.d.ts +3 -0
- package/dist/src/chat-commands/builtins/thinking.js.map +1 -1
- package/dist/src/cli/command-catalog.js +0 -39
- package/dist/src/cli/command-catalog.js.map +1 -1
- package/dist/src/cli/command-loaders.js +0 -1
- package/dist/src/cli/command-loaders.js.map +1 -1
- package/dist/src/cli/command-manifest.js +0 -4
- package/dist/src/cli/command-manifest.js.map +1 -1
- package/dist/src/cli/commands/agents.js +7 -6
- package/dist/src/cli/commands/agents.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/{cron-health.d.ts → migrations.d.ts} +1 -1
- package/dist/src/cli/commands/doctor/checks/migrations.js +40 -0
- package/dist/src/cli/commands/doctor/checks/migrations.js.map +1 -0
- package/dist/src/cli/commands/doctor/flow.js +2 -2
- package/dist/src/cli/commands/doctor/flow.js.map +1 -1
- package/dist/src/cli/commands/gateway/call.js +2 -2
- package/dist/src/cli/commands/gateway/call.js.map +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
- package/dist/src/cli/commands/gateway/run-foreground.js +4 -2
- package/dist/src/cli/commands/gateway/run-foreground.js.map +1 -1
- package/dist/src/cli/commands/init.js +26 -8
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/tui.js +24 -2
- package/dist/src/cli/commands/tui.js.map +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +2 -0
- package/dist/src/cli/utils/init-workspace-core.js.map +1 -1
- package/dist/src/commands/agents.config.d.ts +9 -0
- package/dist/src/commands/agents.config.js +40 -2
- package/dist/src/commands/agents.config.js.map +1 -1
- package/dist/src/config/agent-profile.js +4 -3
- package/dist/src/config/agent-profile.js.map +1 -1
- package/dist/src/config/agent-typed-models.js.map +1 -1
- package/dist/src/config/config-surface.d.ts +3 -0
- package/dist/src/config/index.d.ts +0 -1
- package/dist/src/config/index.js +3 -3
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/config/paths.d.ts +0 -9
- package/dist/src/config/paths.js +1 -14
- package/dist/src/config/paths.js.map +1 -1
- package/dist/src/config/profile.js +0 -1
- package/dist/src/config/profile.js.map +1 -1
- package/dist/src/config/rules.js +0 -5
- package/dist/src/config/rules.js.map +1 -1
- package/dist/src/config/schema.d.ts +13 -12
- package/dist/src/config/schema.js +22 -26
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/web-patch.d.ts +0 -12
- package/dist/src/config/web-patch.js +2 -29
- package/dist/src/config/web-patch.js.map +1 -1
- package/dist/src/extensions/api.d.ts +2 -0
- package/dist/src/extensions/api.js +10 -0
- package/dist/src/extensions/api.js.map +1 -1
- package/dist/src/extensions/extension-registry-impl.d.ts +4 -1
- package/dist/src/extensions/extension-registry-impl.js +8 -0
- package/dist/src/extensions/extension-registry-impl.js.map +1 -1
- package/dist/src/extensions/loader.d.ts +3 -3
- package/dist/src/extensions/loader.js +3 -3
- package/dist/src/extensions/loader.js.map +1 -1
- package/dist/src/extensions/sdk/testing.d.ts +2 -0
- package/dist/src/extensions/sdk/testing.js +7 -0
- package/dist/src/extensions/sdk/testing.js.map +1 -1
- package/dist/src/extensions/types/core.d.ts +10 -1
- package/dist/src/extensions/types/index.d.ts +1 -1
- package/dist/src/extensions/types/{phase4.d.ts → registration.d.ts} +2 -2
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/agent-builtin-tools.js +1 -1
- package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
- package/dist/src/gateway/agents-admin.d.ts +1 -0
- package/dist/src/gateway/agents-admin.js +13 -15
- package/dist/src/gateway/agents-admin.js.map +1 -1
- package/dist/src/gateway/capability-presets-admin.d.ts +1 -0
- package/dist/src/gateway/capability-presets-admin.js +19 -10
- package/dist/src/gateway/capability-presets-admin.js.map +1 -1
- package/dist/src/gateway/dreaming-automation-reconciler.d.ts +11 -0
- package/dist/src/gateway/dreaming-automation-reconciler.js +105 -0
- package/dist/src/gateway/dreaming-automation-reconciler.js.map +1 -0
- package/dist/src/gateway/heartbeat/service.d.ts +0 -2
- package/dist/src/gateway/heartbeat/service.js +0 -7
- package/dist/src/gateway/heartbeat/service.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +5 -6
- package/dist/src/gateway/hono/lib/config-payload.js +2 -2
- package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
- package/dist/src/gateway/hono/routes/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.d.ts +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +12 -6
- package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +27 -37
- package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
- package/dist/src/gateway/hono/routes/home.d.ts +2 -2
- package/dist/src/gateway/hono/routes/home.js +34 -25
- package/dist/src/gateway/hono/routes/home.js.map +1 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +10 -6
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/migrations.d.ts +3 -0
- package/dist/src/gateway/hono/routes/migrations.js +35 -0
- package/dist/src/gateway/hono/routes/migrations.js.map +1 -0
- package/dist/src/gateway/hono/routes/public-gateway.js +2 -1
- package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +14 -0
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/run-loop.js +2 -0
- package/dist/src/gateway/run-loop.js.map +1 -1
- package/dist/src/gateway/security/operator-scopes.js +5 -1
- package/dist/src/gateway/security/operator-scopes.js.map +1 -1
- package/dist/src/gateway/service/config-coordinator.d.ts +4 -4
- package/dist/src/gateway/service/config-coordinator.js +14 -8
- package/dist/src/gateway/service/config-coordinator.js.map +1 -1
- package/dist/src/gateway/service/sessions-api.d.ts +2 -1
- package/dist/src/gateway/service/sessions-api.js +6 -1
- package/dist/src/gateway/service/sessions-api.js.map +1 -1
- package/dist/src/gateway/service.d.ts +7 -3
- package/dist/src/gateway/service.js +61 -27
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/goals/goal-service.js +45 -4
- package/dist/src/goals/goal-service.js.map +1 -1
- package/dist/src/infra/update-restart.js +1 -1
- package/dist/src/migrations/config/default-capability-preset.d.ts +10 -0
- package/dist/src/migrations/config/default-capability-preset.js +135 -0
- package/dist/src/migrations/config/default-capability-preset.js.map +1 -0
- package/dist/src/migrations/index.d.ts +4 -0
- package/dist/src/migrations/index.js +4 -0
- package/dist/src/migrations/registry.d.ts +8 -0
- package/dist/src/migrations/registry.js +18 -0
- package/dist/src/migrations/registry.js.map +1 -0
- package/dist/src/migrations/runner.d.ts +17 -0
- package/dist/src/migrations/runner.js +191 -0
- package/dist/src/migrations/runner.js.map +1 -0
- package/dist/src/migrations/types.d.ts +34 -0
- package/dist/src/notes/service.js +24 -1
- package/dist/src/notes/service.js.map +1 -1
- package/dist/src/providers/model-registry.d.ts +0 -1
- package/dist/src/providers/model-registry.js +0 -3
- package/dist/src/providers/model-registry.js.map +1 -1
- package/dist/src/routing/resolve-tui-session-key.d.ts +3 -0
- package/dist/src/routing/resolve-tui-session-key.js +14 -3
- package/dist/src/routing/resolve-tui-session-key.js.map +1 -1
- package/dist/src/session/transcript-outline.d.ts +47 -0
- package/dist/src/session/transcript-outline.js +481 -0
- package/dist/src/session/transcript-outline.js.map +1 -0
- package/dist/src/storage/sqlite/index.d.ts +0 -2
- package/dist/src/storage/sqlite/index.js +1 -3
- package/dist/src/storage/sqlite/migrations/016_automations.sql +47 -0
- package/dist/src/storage/sqlite/migrations/017_automation_run_events.sql +14 -0
- package/dist/src/storage/sqlite/migrations/018_automation_safety.sql +1 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/schema.sql +56 -46
- package/dist/src/tui/backends/embedded-backend.d.ts +6 -0
- package/dist/src/tui/backends/embedded-backend.js +18 -7
- package/dist/src/tui/backends/embedded-backend.js.map +1 -1
- package/dist/src/tui/backends/gateway-sse-backend.d.ts +3 -0
- package/dist/src/tui/backends/gateway-sse-backend.js +14 -0
- package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
- package/dist/src/tui/tui-backend.d.ts +4 -0
- package/dist/src/tui/tui-commands.d.ts +5 -0
- package/dist/src/tui/tui-commands.js +43 -0
- package/dist/src/tui/tui-commands.js.map +1 -1
- package/dist/src/tui/tui-transcript-tree.d.ts +1 -1
- package/dist/src/tui/tui-transcript-tree.js +17 -257
- package/dist/src/tui/tui-transcript-tree.js.map +1 -1
- package/dist/src/tui/tui-types.d.ts +2 -0
- package/dist/src/tui/tui-types.js.map +1 -1
- package/dist/src/tui/tui.js +7 -2
- package/dist/src/tui/tui.js.map +1 -1
- package/dist/src/workflows/domain/index.js +1 -1
- package/dist/src/workflows/domain/run.d.ts +7 -7
- package/dist/src/workflows/domain/run.js.map +1 -1
- package/dist/src/workflows/index.js +2 -2
- package/dist/src/workflows/service/workflow-run-service.d.ts +2 -0
- package/dist/src/workflows/service/workflow-run-service.js +31 -9
- package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
- package/dist/src/workflows/service/workflow-run-service.types.d.ts +1 -1
- package/package.json +4 -2
- package/dist/gateway/static/root/assets/agents-BCxZbkOw.js +0 -2
- package/dist/gateway/static/root/assets/app-management-settings-panel-bxYJVJpx.js +0 -1
- package/dist/gateway/static/root/assets/appearance-settings-BCIykXlI.js +0 -1
- package/dist/gateway/static/root/assets/browser-settings-page-DRhKdn81.js +0 -8
- package/dist/gateway/static/root/assets/capability-presets-api-CorhiHlg.js +0 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-qFx9Jtce.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-BAwAkqIA.js +0 -1
- package/dist/gateway/static/root/assets/cn-JdwAhgNB.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-BQLcfitM.js +0 -2
- package/dist/gateway/static/root/assets/createLucideIcon-DPHK1VkS.js +0 -1
- package/dist/gateway/static/root/assets/cron-api-qGwmL-24.js +0 -1
- package/dist/gateway/static/root/assets/cron-dreaming-jobs-nCMWCf0p.js +0 -1
- package/dist/gateway/static/root/assets/cron-page-BBWMAj8-.js +0 -3
- package/dist/gateway/static/root/assets/dreaming-settings-Dw89Obml.js +0 -1
- package/dist/gateway/static/root/assets/format-cron-label-BsotZDO5.js +0 -2
- package/dist/gateway/static/root/assets/format-interval-label-BzxafKxR.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-Cmwy58rS.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-l7mu5GWX.js +0 -1
- package/dist/gateway/static/root/assets/goals-settings-CYVY4NGp.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-config-api-DriO_CN9.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-CUQTKxg7.js +0 -1
- package/dist/gateway/static/root/assets/index-C17Tsd_b.css +0 -1
- package/dist/gateway/static/root/assets/index-Cc41r16l.js +0 -191
- package/dist/gateway/static/root/assets/interval-presets-DFPCKW_W.js +0 -1
- package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-CcVcqstx.js +0 -1
- package/dist/gateway/static/root/assets/messages-B1iSKjiw.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-panel-BfLfcta8.js +0 -2
- package/dist/gateway/static/root/assets/note-detail-page-BjwOQBfT.js +0 -2
- package/dist/gateway/static/root/assets/notes-page-DktdBiwB.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-rfVx96fq.js +0 -1
- package/dist/gateway/static/root/assets/schedule-field-CUCKODde.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-DbtMFuuH.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-5re5gAnP.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-D-WMyLlj.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-Cl-DEJAU.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-CyPVvbLt.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-CleTH1oz.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-Ck8hdXqR.js +0 -2
- package/dist/gateway/static/root/assets/system-settings-panel-DI-LN_8G.js +0 -1
- package/dist/gateway/static/root/assets/typed-models-lib-kX9duch4.js +0 -1
- package/dist/gateway/static/root/assets/user-profile-settings-panel-B-UFPMXy.js +0 -1
- package/dist/gateway/static/root/assets/utils-Dm0hKalR.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-BtFGp2y_.js +0 -18
- package/dist/src/agent/fallback/error.d.ts +0 -22
- package/dist/src/agent/fallback/error.js +0 -32
- package/dist/src/agent/fallback/error.js.map +0 -1
- package/dist/src/agent/fallback/index.d.ts +0 -5
- package/dist/src/agent/fallback/index.js +0 -9
- package/dist/src/agent/fallback/index.js.map +0 -1
- package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.d.ts +0 -29
- package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js +0 -76
- package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js.map +0 -1
- package/dist/src/agent/service/reconcile-dreaming-cron.d.ts +0 -6
- package/dist/src/agent/service/reconcile-dreaming-cron.js +0 -84
- package/dist/src/agent/service/reconcile-dreaming-cron.js.map +0 -1
- package/dist/src/agent/tools/cronjob-tool.d.ts +0 -29
- package/dist/src/agent/tools/cronjob-tool.js +0 -274
- package/dist/src/agent/tools/cronjob-tool.js.map +0 -1
- package/dist/src/cli/commands/cron-cli.d.ts +0 -2
- package/dist/src/cli/commands/cron-cli.js +0 -15
- package/dist/src/cli/commands/cron-cli.js.map +0 -1
- package/dist/src/cli/commands/cron.d.ts +0 -4
- package/dist/src/cli/commands/cron.js +0 -188
- package/dist/src/cli/commands/cron.js.map +0 -1
- package/dist/src/cli/commands/doctor/checks/cron-health.js +0 -35
- package/dist/src/cli/commands/doctor/checks/cron-health.js.map +0 -1
- package/dist/src/cron/execution-types.d.ts +0 -42
- package/dist/src/cron/executor.d.ts +0 -67
- package/dist/src/cron/executor.js +0 -669
- package/dist/src/cron/executor.js.map +0 -1
- package/dist/src/cron/index.d.ts +0 -7
- package/dist/src/cron/index.js +0 -7
- package/dist/src/cron/job-content.d.ts +0 -5
- package/dist/src/cron/job-content.js +0 -15
- package/dist/src/cron/job-content.js.map +0 -1
- package/dist/src/cron/run-log-store.d.ts +0 -12
- package/dist/src/cron/run-log-store.js +0 -58
- package/dist/src/cron/run-log-store.js.map +0 -1
- package/dist/src/cron/schedule.d.ts +0 -10
- package/dist/src/cron/schedule.js +0 -85
- package/dist/src/cron/schedule.js.map +0 -1
- package/dist/src/cron/service.d.ts +0 -58
- package/dist/src/cron/service.js +0 -419
- package/dist/src/cron/service.js.map +0 -1
- package/dist/src/cron/types.d.ts +0 -183
- package/dist/src/cron/validation.d.ts +0 -500
- package/dist/src/cron/validation.js +0 -192
- package/dist/src/cron/validation.js.map +0 -1
- package/dist/src/cron/workflow-run-completion.d.ts +0 -23
- package/dist/src/cron/workflow-run-completion.js +0 -72
- package/dist/src/cron/workflow-run-completion.js.map +0 -1
- package/dist/src/extensions/types/phase4.js +0 -1
- package/dist/src/gateway/hono/routes/cron.d.ts +0 -3
- package/dist/src/gateway/hono/routes/cron.js +0 -109
- package/dist/src/gateway/hono/routes/cron.js.map +0 -1
- package/dist/src/storage/sqlite/cron-job-repository.d.ts +0 -6
- package/dist/src/storage/sqlite/cron-job-repository.js +0 -70
- package/dist/src/storage/sqlite/cron-job-repository.js.map +0 -1
- package/dist/src/storage/sqlite/cron-run-repository.d.ts +0 -5
- package/dist/src/storage/sqlite/cron-run-repository.js +0 -96
- package/dist/src/storage/sqlite/cron-run-repository.js.map +0 -1
- /package/dist/src/{cron → automations/domain}/types.js +0 -0
- /package/dist/src/{config/defaults.d.ts → automations/draft/automation-draft.types.js} +0 -0
- /package/dist/src/{config/defaults.js → extensions/types/registration.js} +0 -0
- /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
|
+
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":"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"}
|
|
@@ -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
|
-
|
|
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);
|