@ai-agent-forge/agent-forge 0.87.0 → 0.88.1
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/CHANGELOG.md +56 -0
- package/README.md +2 -2
- package/bundled-plugins/agent-loop-policy/agent-forge.json +19 -0
- package/bundled-plugins/agent-loop-policy/dist/entry.d.ts +28 -0
- package/bundled-plugins/agent-loop-policy/dist/entry.d.ts.map +1 -0
- package/bundled-plugins/agent-loop-policy/dist/entry.js +69 -0
- package/bundled-plugins/agent-loop-policy/dist/entry.js.map +1 -0
- package/bundled-plugins/agent-loop-policy/dist/loop-guard.d.ts +199 -0
- package/bundled-plugins/agent-loop-policy/dist/loop-guard.d.ts.map +1 -0
- package/bundled-plugins/agent-loop-policy/dist/loop-guard.js +208 -0
- package/bundled-plugins/agent-loop-policy/dist/loop-guard.js.map +1 -0
- package/bundled-plugins/agent-loop-policy/dist/run-loop-strategy.d.ts +17 -0
- package/bundled-plugins/agent-loop-policy/dist/run-loop-strategy.d.ts.map +1 -0
- package/bundled-plugins/agent-loop-policy/dist/run-loop-strategy.js +18 -0
- package/bundled-plugins/agent-loop-policy/dist/run-loop-strategy.js.map +1 -0
- package/bundled-plugins/agent-loop-policy/plugin.json +7 -0
- package/bundled-plugins/coding-tools/agent-forge.json +19 -0
- package/{dist/core/tools → bundled-plugins/coding-tools/dist}/bash.d.ts +5 -44
- package/bundled-plugins/coding-tools/dist/bash.d.ts.map +1 -0
- package/{dist/core/tools → bundled-plugins/coding-tools/dist}/bash.js +15 -119
- package/bundled-plugins/coding-tools/dist/bash.js.map +1 -0
- package/bundled-plugins/coding-tools/dist/capability.d.ts +25 -0
- package/bundled-plugins/coding-tools/dist/capability.d.ts.map +1 -0
- package/bundled-plugins/coding-tools/dist/capability.js +98 -0
- package/bundled-plugins/coding-tools/dist/capability.js.map +1 -0
- package/bundled-plugins/coding-tools/dist/config.d.ts +8 -0
- package/bundled-plugins/coding-tools/dist/config.d.ts.map +1 -0
- package/bundled-plugins/coding-tools/dist/config.js +8 -0
- package/bundled-plugins/coding-tools/dist/config.js.map +1 -0
- package/{dist/core/tools → bundled-plugins/coding-tools/dist}/edit.d.ts +3 -3
- package/bundled-plugins/coding-tools/dist/edit.d.ts.map +1 -0
- package/{dist/core/tools → bundled-plugins/coding-tools/dist}/edit.js +12 -10
- package/bundled-plugins/coding-tools/dist/edit.js.map +1 -0
- package/bundled-plugins/coding-tools/dist/entry.d.ts +14 -0
- package/bundled-plugins/coding-tools/dist/entry.d.ts.map +1 -0
- package/bundled-plugins/coding-tools/dist/entry.js +23 -0
- package/bundled-plugins/coding-tools/dist/entry.js.map +1 -0
- package/{dist/core/tools → bundled-plugins/coding-tools/dist}/find.d.ts +4 -4
- package/bundled-plugins/coding-tools/dist/find.d.ts.map +1 -0
- package/{dist/core/tools → bundled-plugins/coding-tools/dist}/find.js +10 -8
- package/bundled-plugins/coding-tools/dist/find.js.map +1 -0
- package/{dist/core/tools → bundled-plugins/coding-tools/dist}/grep.d.ts +3 -3
- package/bundled-plugins/coding-tools/dist/grep.d.ts.map +1 -0
- package/{dist/core/tools → bundled-plugins/coding-tools/dist}/grep.js +10 -8
- package/bundled-plugins/coding-tools/dist/grep.js.map +1 -0
- package/bundled-plugins/coding-tools/dist/index.d.ts +17 -0
- package/bundled-plugins/coding-tools/dist/index.d.ts.map +1 -0
- package/bundled-plugins/coding-tools/dist/index.js +17 -0
- package/bundled-plugins/coding-tools/dist/index.js.map +1 -0
- package/{dist/core/tools → bundled-plugins/coding-tools/dist}/ls.d.ts +3 -3
- package/bundled-plugins/coding-tools/dist/ls.d.ts.map +1 -0
- package/{dist/core/tools → bundled-plugins/coding-tools/dist}/ls.js +8 -6
- package/{dist/core/tools → bundled-plugins/coding-tools/dist}/ls.js.map +1 -1
- package/{dist/core/tools → bundled-plugins/coding-tools/dist}/powershell.d.ts +2 -1
- package/bundled-plugins/coding-tools/dist/powershell.d.ts.map +1 -0
- package/{dist/core/tools → bundled-plugins/coding-tools/dist}/powershell.js +6 -3
- package/bundled-plugins/coding-tools/dist/powershell.js.map +1 -0
- package/{dist/core/tools → bundled-plugins/coding-tools/dist}/read.d.ts +3 -3
- package/bundled-plugins/coding-tools/dist/read.d.ts.map +1 -0
- package/{dist/core/tools → bundled-plugins/coding-tools/dist}/read.js +15 -13
- package/bundled-plugins/coding-tools/dist/read.js.map +1 -0
- package/bundled-plugins/coding-tools/dist/types.d.ts +74 -0
- package/bundled-plugins/coding-tools/dist/types.d.ts.map +1 -0
- package/bundled-plugins/coding-tools/dist/types.js +28 -0
- package/bundled-plugins/coding-tools/dist/types.js.map +1 -0
- package/{dist/core/tools → bundled-plugins/coding-tools/dist}/write.d.ts +2 -2
- package/bundled-plugins/coding-tools/dist/write.d.ts.map +1 -0
- package/{dist/core/tools → bundled-plugins/coding-tools/dist}/write.js +11 -9
- package/bundled-plugins/coding-tools/dist/write.js.map +1 -0
- package/bundled-plugins/coding-tools/plugin.json +10 -0
- package/bundled-plugins/compaction-policy/agent-forge.json +19 -0
- package/bundled-plugins/compaction-policy/dist/branch-summary-policy.d.ts +6 -0
- package/bundled-plugins/compaction-policy/dist/branch-summary-policy.d.ts.map +1 -0
- package/bundled-plugins/compaction-policy/dist/branch-summary-policy.js +19 -0
- package/bundled-plugins/compaction-policy/dist/branch-summary-policy.js.map +1 -0
- package/bundled-plugins/compaction-policy/dist/compaction-policy.d.ts +6 -0
- package/bundled-plugins/compaction-policy/dist/compaction-policy.d.ts.map +1 -0
- package/bundled-plugins/compaction-policy/dist/compaction-policy.js +38 -0
- package/bundled-plugins/compaction-policy/dist/compaction-policy.js.map +1 -0
- package/bundled-plugins/compaction-policy/dist/entry.d.ts +13 -0
- package/bundled-plugins/compaction-policy/dist/entry.d.ts.map +1 -0
- package/bundled-plugins/compaction-policy/dist/entry.js +23 -0
- package/bundled-plugins/compaction-policy/dist/entry.js.map +1 -0
- package/bundled-plugins/compaction-policy/plugin.json +10 -0
- package/bundled-plugins/mcp-http/dist/index.d.ts +8 -0
- package/bundled-plugins/mcp-http/dist/index.d.ts.map +1 -0
- package/bundled-plugins/mcp-http/dist/index.js +8 -0
- package/bundled-plugins/mcp-http/dist/index.js.map +1 -0
- package/bundled-plugins/mcp-http/dist/mcp-http.d.ts.map +1 -0
- package/{dist/plugins → bundled-plugins/mcp-http/dist}/mcp-http.js +1 -1
- package/bundled-plugins/mcp-http/dist/mcp-http.js.map +1 -0
- package/bundled-plugins/overflow-policy/agent-forge.json +19 -0
- package/bundled-plugins/overflow-policy/dist/entry.d.ts +16 -0
- package/bundled-plugins/overflow-policy/dist/entry.d.ts.map +1 -0
- package/bundled-plugins/overflow-policy/dist/entry.js +35 -0
- package/bundled-plugins/overflow-policy/dist/entry.js.map +1 -0
- package/bundled-plugins/overflow-policy/plugin.json +10 -0
- package/bundled-plugins/provider-failover/agent-forge.json +19 -0
- package/bundled-plugins/provider-failover/dist/entry.d.ts +8 -0
- package/bundled-plugins/provider-failover/dist/entry.d.ts.map +1 -0
- package/bundled-plugins/provider-failover/dist/entry.js +8 -0
- package/bundled-plugins/provider-failover/dist/entry.js.map +1 -0
- package/bundled-plugins/provider-failover/dist/provider-failover.d.ts +122 -0
- package/bundled-plugins/provider-failover/dist/provider-failover.d.ts.map +1 -0
- package/{dist/core/extensions → bundled-plugins/provider-failover/dist}/provider-failover.js +149 -61
- package/bundled-plugins/provider-failover/dist/provider-failover.js.map +1 -0
- package/bundled-plugins/provider-failover/plugin.json +7 -0
- package/bundled-plugins/retry-policy/agent-forge.json +19 -0
- package/bundled-plugins/retry-policy/dist/entry.d.ts +16 -0
- package/bundled-plugins/retry-policy/dist/entry.d.ts.map +1 -0
- package/bundled-plugins/retry-policy/dist/entry.js +34 -0
- package/bundled-plugins/retry-policy/dist/entry.js.map +1 -0
- package/bundled-plugins/retry-policy/plugin.json +10 -0
- package/dist/bundle/.build-manifest.json +105 -183
- package/dist/bundle/chunks/{anthropic-messages-ALDZBUKI.js → anthropic-messages-PLAKXR73.js} +1 -1
- package/dist/bundle/chunks/{azure-openai-responses-A2WJWZFB.js → azure-openai-responses-OUWQ2AZD.js} +1 -1
- package/dist/bundle/chunks/{chunk-CIX3FSBK.js → chunk-A3JYRWB6.js} +1 -1
- package/dist/bundle/chunks/{chunk-SQFG22WN.js → chunk-AC2FIS4G.js} +1 -1
- package/dist/bundle/chunks/chunk-AQLNTW2B.js +664 -0
- package/dist/bundle/chunks/chunk-D3ARGZFR.js +13 -0
- package/dist/bundle/chunks/{chunk-YJCQVXW5.js → chunk-HTEVUY7F.js} +1 -1
- package/dist/bundle/chunks/{chunk-Y7HXTASS.js → chunk-HV64ASMT.js} +1 -1
- package/dist/bundle/chunks/chunk-LZOEQITZ.js +855 -0
- package/dist/bundle/chunks/{chunk-7ZY7IXZD.js → chunk-TRDNDS6A.js} +1 -1
- package/dist/bundle/chunks/chunk-Z72JWUZ4.js +4 -0
- package/dist/bundle/chunks/{google-generative-ai-NIB4WONV.js → google-generative-ai-DLII6DAT.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-DCPYUEUO.js → google-vertex-G7BZL7GM.js} +1 -1
- package/dist/bundle/chunks/image-resize-worker.js +3 -3
- package/dist/bundle/chunks/{mistral-conversations-OC6LA5XL.js → mistral-conversations-JXUK24ID.js} +1 -1
- package/dist/bundle/chunks/{openai-codex-responses-IO2X4Y7L.js → openai-codex-responses-5GSGFIPG.js} +1 -1
- package/dist/bundle/chunks/{openai-completions-XYQQHETU.js → openai-completions-EI2I6DTG.js} +1 -1
- package/dist/bundle/chunks/{openai-responses-DLIRN3CI.js → openai-responses-AUJQ3NWT.js} +1 -1
- package/dist/bundle/chunks/{pi-messages-E6RRYBO7.js → pi-messages-PWU2VJMR.js} +1 -1
- package/dist/bundle/chunks/virtual-modules-WF6WRHP7.js +5 -0
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/client.js +1 -1
- package/dist/bundle/index.js +3 -3
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/capabilities/builtin.d.ts +1 -1
- package/dist/capabilities/builtin.d.ts.map +1 -1
- package/dist/capabilities/builtin.js +5 -0
- package/dist/capabilities/builtin.js.map +1 -1
- package/dist/cli/auth-check.d.ts.map +1 -1
- package/dist/cli/auth-check.js +14 -2
- package/dist/cli/auth-check.js.map +1 -1
- package/dist/cli/auth-command.d.ts.map +1 -1
- package/dist/cli/auth-command.js +1 -1
- package/dist/cli/auth-command.js.map +1 -1
- package/dist/cli/plugin-command.d.ts.map +1 -1
- package/dist/cli/plugin-command.js +17 -1
- package/dist/cli/plugin-command.js.map +1 -1
- package/dist/config.d.ts +2 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -6
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-bash.d.ts +1 -1
- package/dist/core/agent-session-bash.d.ts.map +1 -1
- package/dist/core/agent-session-bash.js +1 -1
- package/dist/core/agent-session-bash.js.map +1 -1
- package/dist/core/agent-session-compaction.d.ts +6 -10
- package/dist/core/agent-session-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-compaction.js +21 -112
- package/dist/core/agent-session-compaction.js.map +1 -1
- package/dist/core/agent-session-internal.d.ts +1 -7
- package/dist/core/agent-session-internal.d.ts.map +1 -1
- package/dist/core/agent-session-internal.js.map +1 -1
- package/dist/core/agent-session-loop.d.ts +4 -3
- package/dist/core/agent-session-loop.d.ts.map +1 -1
- package/dist/core/agent-session-loop.js +9 -6
- package/dist/core/agent-session-loop.js.map +1 -1
- package/dist/core/agent-session-retry.d.ts +1 -1
- package/dist/core/agent-session-retry.d.ts.map +1 -1
- package/dist/core/agent-session-retry.js +32 -4
- package/dist/core/agent-session-retry.js.map +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +30 -9
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session-tools.d.ts.map +1 -1
- package/dist/core/agent-session-tools.js +5 -1
- package/dist/core/agent-session-tools.js.map +1 -1
- package/dist/core/agent-session.d.ts +12 -33
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +61 -67
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bash-executor.d.ts +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/extensions/bootstrap-agent-loop.d.ts +23 -151
- package/dist/core/extensions/bootstrap-agent-loop.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-agent-loop.js +28 -290
- package/dist/core/extensions/bootstrap-agent-loop.js.map +1 -1
- package/dist/core/extensions/capability-runtime-types.d.ts +5 -3
- package/dist/core/extensions/capability-runtime-types.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime-types.js.map +1 -1
- package/dist/core/extensions/capability-runtime.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime.js +42 -6
- package/dist/core/extensions/capability-runtime.js.map +1 -1
- package/dist/core/extensions/index.d.ts +12 -5
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +12 -5
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/virtual-modules.js +65 -0
- package/dist/core/extensions/virtual-modules.js.map +1 -1
- package/dist/core/facade/coding-agent-facade.d.ts +1 -7
- package/dist/core/facade/coding-agent-facade.d.ts.map +1 -1
- package/dist/core/facade/coding-agent-facade.js +0 -3
- package/dist/core/facade/coding-agent-facade.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/cli.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/cli.js +3 -1
- package/dist/core/i18n/locales/zh-cn/cli.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-contract-core.d.ts +1 -1
- package/dist/core/i18n/locales/zh-cn/core-contract-core.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-contract-core.js +1 -1
- package/dist/core/i18n/locales/zh-cn/core-contract-core.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-contract-extensions.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-contract-extensions.js +2 -4
- package/dist/core/i18n/locales/zh-cn/core-contract-extensions.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-errors.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-errors.js +3 -1
- package/dist/core/i18n/locales/zh-cn/core-errors.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/interactive-mode.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/interactive-mode.js +2 -0
- package/dist/core/i18n/locales/zh-cn/interactive-mode.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/tui-components-selectors.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/tui-components-selectors.js +0 -2
- package/dist/core/i18n/locales/zh-cn/tui-components-selectors.js.map +1 -1
- package/dist/core/model-config.d.ts +0 -1
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +9 -1
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +3 -3
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/provider-composer.d.ts +2 -2
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +7 -8
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/sdk.d.ts +18 -3
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +267 -76
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager.d.ts +9 -20
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +20 -54
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/tools/bash-operations.d.ts +41 -0
- package/dist/core/tools/bash-operations.d.ts.map +1 -0
- package/dist/core/tools/bash-operations.js +113 -0
- package/dist/core/tools/bash-operations.js.map +1 -0
- package/dist/core/tools/index.d.ts +12 -36
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +1 -117
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/readme-path.d.ts +3 -0
- package/dist/core/tools/readme-path.d.ts.map +1 -0
- package/dist/core/tools/readme-path.js +15 -0
- package/dist/core/tools/readme-path.js.map +1 -0
- package/dist/index.d.ts +3 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -39
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +3 -2
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +0 -2
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +2 -7
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +2 -6
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +6 -28
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +0 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +9 -25
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +0 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +23 -36
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +0 -8
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +0 -12
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +0 -9
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +0 -19
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/plugins/ecosystem/cli.d.ts.map +1 -1
- package/dist/plugins/ecosystem/cli.js +14 -2
- package/dist/plugins/ecosystem/cli.js.map +1 -1
- package/dist/plugins/ecosystem/node-npm-registry-source.d.ts +7 -2
- package/dist/plugins/ecosystem/node-npm-registry-source.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-npm-registry-source.js +64 -9
- package/dist/plugins/ecosystem/node-npm-registry-source.js.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-acquisition-host.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-acquisition-host.js +6 -0
- package/dist/plugins/ecosystem/node-plugin-acquisition-host.js.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts +9 -2
- package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-bootstrap.js +23 -0
- package/dist/plugins/ecosystem/node-plugin-bootstrap.js.map +1 -1
- package/dist/plugins/ecosystem/plugin-bootstrap.d.ts +9 -1
- package/dist/plugins/ecosystem/plugin-bootstrap.d.ts.map +1 -1
- package/dist/plugins/ecosystem/plugin-bootstrap.js +5 -0
- package/dist/plugins/ecosystem/plugin-bootstrap.js.map +1 -1
- package/dist/profiles/builtin-suites.d.ts +5 -1
- package/dist/profiles/builtin-suites.d.ts.map +1 -1
- package/dist/profiles/builtin-suites.js +6 -1
- package/dist/profiles/builtin-suites.js.map +1 -1
- package/dist/utils/photon.d.ts +2 -2
- package/dist/utils/photon.d.ts.map +1 -1
- package/dist/utils/photon.js +2 -2
- package/dist/utils/photon.js.map +1 -1
- package/docs/compaction.md +1 -3
- package/docs/docs.json +4 -0
- package/docs/index.md +1 -0
- package/docs/mcp.md +103 -0
- package/docs/models.md +14 -22
- package/docs/providers.md +0 -1
- package/docs/rpc.md +1 -26
- package/docs/sdk.md +4 -6
- package/docs/settings.md +9 -12
- package/docs/skills.md +1 -9
- package/docs/usage.md +1 -1
- package/examples/extensions/bash-spawn-hook/index.ts +7 -2
- package/examples/extensions/built-in-tool-renderer/index.ts +4 -2
- package/examples/extensions/minimal-mode/index.ts +2 -2
- package/examples/extensions/truncated-tool/index.ts +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/extensions/with-deps/plugin.json +1 -1
- package/examples/sdk/10-settings.ts +2 -4
- package/examples/sdk/12-full-control.ts +1 -2
- package/package.json +3 -4
- package/dist/bundle/chunks/chunk-6ZKDNZHA.js +0 -145
- package/dist/bundle/chunks/chunk-BFC2BDVJ.js +0 -13
- package/dist/bundle/chunks/chunk-MOHOLL3F.js +0 -1456
- package/dist/bundle/chunks/virtual-modules-KZ5DRH7Q.js +0 -2
- package/dist/core/extensions/bootstrap-branch-summary-policy.d.ts +0 -7
- package/dist/core/extensions/bootstrap-branch-summary-policy.d.ts.map +0 -1
- package/dist/core/extensions/bootstrap-branch-summary-policy.js +0 -28
- package/dist/core/extensions/bootstrap-branch-summary-policy.js.map +0 -1
- package/dist/core/extensions/bootstrap-compaction-policy.d.ts +0 -7
- package/dist/core/extensions/bootstrap-compaction-policy.d.ts.map +0 -1
- package/dist/core/extensions/bootstrap-compaction-policy.js +0 -82
- package/dist/core/extensions/bootstrap-compaction-policy.js.map +0 -1
- package/dist/core/extensions/bootstrap-overflow-policy.d.ts +0 -7
- package/dist/core/extensions/bootstrap-overflow-policy.d.ts.map +0 -1
- package/dist/core/extensions/bootstrap-overflow-policy.js +0 -30
- package/dist/core/extensions/bootstrap-overflow-policy.js.map +0 -1
- package/dist/core/extensions/bootstrap-retry-policy.d.ts +0 -7
- package/dist/core/extensions/bootstrap-retry-policy.d.ts.map +0 -1
- package/dist/core/extensions/bootstrap-retry-policy.js +0 -29
- package/dist/core/extensions/bootstrap-retry-policy.js.map +0 -1
- package/dist/core/extensions/bootstrap-tools.d.ts +0 -20
- package/dist/core/extensions/bootstrap-tools.d.ts.map +0 -1
- package/dist/core/extensions/bootstrap-tools.js +0 -36
- package/dist/core/extensions/bootstrap-tools.js.map +0 -1
- package/dist/core/extensions/microcompact.d.ts +0 -80
- package/dist/core/extensions/microcompact.d.ts.map +0 -1
- package/dist/core/extensions/microcompact.js +0 -134
- package/dist/core/extensions/microcompact.js.map +0 -1
- package/dist/core/extensions/provider-failover.d.ts +0 -106
- package/dist/core/extensions/provider-failover.d.ts.map +0 -1
- package/dist/core/extensions/provider-failover.js.map +0 -1
- package/dist/core/tools/bash.d.ts.map +0 -1
- package/dist/core/tools/bash.js.map +0 -1
- package/dist/core/tools/edit.d.ts.map +0 -1
- package/dist/core/tools/edit.js.map +0 -1
- package/dist/core/tools/find.d.ts.map +0 -1
- package/dist/core/tools/find.js.map +0 -1
- package/dist/core/tools/grep.d.ts.map +0 -1
- package/dist/core/tools/grep.js.map +0 -1
- package/dist/core/tools/ls.d.ts.map +0 -1
- package/dist/core/tools/powershell.d.ts.map +0 -1
- package/dist/core/tools/powershell.js.map +0 -1
- package/dist/core/tools/read.d.ts.map +0 -1
- package/dist/core/tools/read.js.map +0 -1
- package/dist/core/tools/write.d.ts.map +0 -1
- package/dist/core/tools/write.js.map +0 -1
- package/dist/plugins/mcp-http.d.ts.map +0 -1
- package/dist/plugins/mcp-http.js.map +0 -1
- package/dist/profile/child-facade.d.ts +0 -44
- package/dist/profile/child-facade.d.ts.map +0 -1
- package/dist/profile/child-facade.js +0 -56
- package/dist/profile/child-facade.js.map +0 -1
- package/dist/profile/dependency-wiring.d.ts +0 -48
- package/dist/profile/dependency-wiring.d.ts.map +0 -1
- package/dist/profile/dependency-wiring.js +0 -56
- package/dist/profile/dependency-wiring.js.map +0 -1
- package/dist/profile/domain-recovery.d.ts +0 -60
- package/dist/profile/domain-recovery.d.ts.map +0 -1
- package/dist/profile/domain-recovery.js +0 -94
- package/dist/profile/domain-recovery.js.map +0 -1
- package/dist/profile/first-roles.d.ts +0 -30
- package/dist/profile/first-roles.d.ts.map +0 -1
- package/dist/profile/first-roles.js +0 -83
- package/dist/profile/first-roles.js.map +0 -1
- package/dist/profile/goal-plugin.d.ts +0 -38
- package/dist/profile/goal-plugin.d.ts.map +0 -1
- package/dist/profile/goal-plugin.js +0 -132
- package/dist/profile/goal-plugin.js.map +0 -1
- package/dist/profile/plan-plugin.d.ts +0 -44
- package/dist/profile/plan-plugin.d.ts.map +0 -1
- package/dist/profile/plan-plugin.js +0 -157
- package/dist/profile/plan-plugin.js.map +0 -1
- package/dist/profile/policy-manifest.d.ts +0 -53
- package/dist/profile/policy-manifest.d.ts.map +0 -1
- package/dist/profile/policy-manifest.js +0 -53
- package/dist/profile/policy-manifest.js.map +0 -1
- package/dist/profile/role-assembly.d.ts +0 -47
- package/dist/profile/role-assembly.d.ts.map +0 -1
- package/dist/profile/role-assembly.js +0 -31
- package/dist/profile/role-assembly.js.map +0 -1
- package/dist/profile/role-catalog.d.ts +0 -43
- package/dist/profile/role-catalog.d.ts.map +0 -1
- package/dist/profile/role-catalog.js +0 -132
- package/dist/profile/role-catalog.js.map +0 -1
- package/dist/profile/role-orchestrator.d.ts +0 -123
- package/dist/profile/role-orchestrator.d.ts.map +0 -1
- package/dist/profile/role-orchestrator.js +0 -195
- package/dist/profile/role-orchestrator.js.map +0 -1
- package/dist/profile/role-runner.d.ts +0 -99
- package/dist/profile/role-runner.d.ts.map +0 -1
- package/dist/profile/role-runner.js +0 -79
- package/dist/profile/role-runner.js.map +0 -1
- package/dist/profile/root-facade.d.ts +0 -36
- package/dist/profile/root-facade.d.ts.map +0 -1
- package/dist/profile/root-facade.js +0 -49
- package/dist/profile/root-facade.js.map +0 -1
- package/dist/profile/skill-discovery-wiring.d.ts +0 -58
- package/dist/profile/skill-discovery-wiring.d.ts.map +0 -1
- package/dist/profile/skill-discovery-wiring.js +0 -80
- package/dist/profile/skill-discovery-wiring.js.map +0 -1
- package/dist/profile/state-store.d.ts +0 -62
- package/dist/profile/state-store.d.ts.map +0 -1
- package/dist/profile/state-store.js +0 -144
- package/dist/profile/state-store.js.map +0 -1
- package/dist/profile/todo-plugin.d.ts +0 -37
- package/dist/profile/todo-plugin.d.ts.map +0 -1
- package/dist/profile/todo-plugin.js +0 -137
- package/dist/profile/todo-plugin.js.map +0 -1
- package/dist/server/create-harness.d.ts +0 -26
- package/dist/server/create-harness.d.ts.map +0 -1
- package/dist/server/create-harness.js +0 -106
- package/dist/server/create-harness.js.map +0 -1
- /package/{dist/plugins → bundled-plugins/mcp-http/dist}/mcp-http.d.ts +0 -0
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
const GOAL_TERMINAL = new Set(["achieved", "archived"]);
|
|
2
|
-
const PLAN_TERMINAL = new Set(["completed", "discarded"]);
|
|
3
|
-
const TODO_TERMINAL = new Set(["completed", "cancelled"]);
|
|
4
|
-
/**
|
|
5
|
-
* 5.2a — recovers plans for the current branch. Plans on other branches are
|
|
6
|
-
* reported and left untouched (no scans, no writes). Terminal plans on the
|
|
7
|
-
* current branch are kept as-is; draft/active plans are recovered through
|
|
8
|
-
* the plugin's own ledger-derived state (no shadow writes).
|
|
9
|
-
*/
|
|
10
|
-
export function recoverPlansForBranch(plans, currentBranch) {
|
|
11
|
-
const entries = plans.map((plan) => {
|
|
12
|
-
const terminal = PLAN_TERMINAL.has(plan.status);
|
|
13
|
-
if (plan.branch !== currentBranch) {
|
|
14
|
-
return {
|
|
15
|
-
planId: plan.planId,
|
|
16
|
-
outcome: "skipped_other_branch",
|
|
17
|
-
branch: plan.branch,
|
|
18
|
-
statusBefore: plan.status,
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
return {
|
|
22
|
-
planId: plan.planId,
|
|
23
|
-
outcome: terminal ? "terminal_kept" : "recovered",
|
|
24
|
-
branch: plan.branch,
|
|
25
|
-
statusBefore: plan.status,
|
|
26
|
-
};
|
|
27
|
-
});
|
|
28
|
-
return { currentBranch, entries: Object.freeze(entries) };
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* 5.2b — restores goal/plan/todo state after a restart by replaying each
|
|
32
|
-
* entity's history into a fresh store (the caller performs the replay via
|
|
33
|
-
* the plugin attached to the rebuilt store) and comparing against the
|
|
34
|
-
* pre-restart snapshots.
|
|
35
|
-
*/
|
|
36
|
-
export function buildRestartReport(snapshots, restored, owner) {
|
|
37
|
-
const records = [];
|
|
38
|
-
let identical = true;
|
|
39
|
-
const compare = (domain, entityId, statusAfter, revisionAfter, evidenceCount, terminal, statusBefore, revisionBefore) => {
|
|
40
|
-
if (statusAfter !== statusBefore || revisionAfter !== revisionBefore)
|
|
41
|
-
identical = false;
|
|
42
|
-
records.push({ domain, entityId, statusAfter, revisionAfter, evidenceCount, terminal });
|
|
43
|
-
};
|
|
44
|
-
for (const goal of snapshots.goal ?? []) {
|
|
45
|
-
const after = restored.goals.get(goal.goalId, owner);
|
|
46
|
-
if (!after) {
|
|
47
|
-
identical = false;
|
|
48
|
-
records.push({
|
|
49
|
-
domain: "goal",
|
|
50
|
-
entityId: goal.goalId,
|
|
51
|
-
statusAfter: "missing",
|
|
52
|
-
revisionAfter: 0,
|
|
53
|
-
evidenceCount: 0,
|
|
54
|
-
terminal: false,
|
|
55
|
-
});
|
|
56
|
-
continue;
|
|
57
|
-
}
|
|
58
|
-
compare("goal", goal.goalId, after.status, after.revision, after.evidence.length, GOAL_TERMINAL.has(after.status), goal.status, goal.revision);
|
|
59
|
-
}
|
|
60
|
-
for (const plan of snapshots.plan ?? []) {
|
|
61
|
-
const after = restored.plans.get(plan.planId, owner);
|
|
62
|
-
if (!after) {
|
|
63
|
-
identical = false;
|
|
64
|
-
records.push({
|
|
65
|
-
domain: "plan",
|
|
66
|
-
entityId: plan.planId,
|
|
67
|
-
statusAfter: "missing",
|
|
68
|
-
revisionAfter: 0,
|
|
69
|
-
evidenceCount: 0,
|
|
70
|
-
terminal: false,
|
|
71
|
-
});
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
|
-
compare("plan", plan.planId, after.status, after.revisionNo, after.evidence.length, PLAN_TERMINAL.has(after.status), plan.status, plan.revisionNo);
|
|
75
|
-
}
|
|
76
|
-
for (const todo of snapshots.todo ?? []) {
|
|
77
|
-
const after = restored.todos.get(todo.todoId, owner);
|
|
78
|
-
if (!after) {
|
|
79
|
-
identical = false;
|
|
80
|
-
records.push({
|
|
81
|
-
domain: "todo",
|
|
82
|
-
entityId: todo.todoId,
|
|
83
|
-
statusAfter: "missing",
|
|
84
|
-
revisionAfter: 0,
|
|
85
|
-
evidenceCount: 0,
|
|
86
|
-
terminal: false,
|
|
87
|
-
});
|
|
88
|
-
continue;
|
|
89
|
-
}
|
|
90
|
-
compare("todo", todo.todoId, after.status, after.revision, after.evidence.length, TODO_TERMINAL.has(after.status), todo.status, todo.revision);
|
|
91
|
-
}
|
|
92
|
-
return { records: Object.freeze(records), identical };
|
|
93
|
-
}
|
|
94
|
-
//# sourceMappingURL=domain-recovery.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"domain-recovery.js","sourceRoot":"","sources":["../../src/profile/domain-recovery.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Domain recovery for branches and restarts (5.2a/5.2b).\n *\n * Branch recovery (5.2a): plans are bound to a branch via the 2.3c plugin;\n * recovering a session on branch B must touch ONLY plans whose branch is B\n * — other-branch plans stay ledgered but are reported as skipped and never\n * written to. Restart recovery (5.2b): replaying a domain's history into a\n * fresh store restores revision, evidence, and terminal state exactly; the\n * recovery report records the before/after facts so a restart is auditable.\n * Multi-Agent scheduling is out of scope.\n */\nimport type { GoalPluginV1, GoalV1 } from \"./goal-plugin.ts\";\nimport type { PlanPluginV1, PlanV1 } from \"./plan-plugin.ts\";\nimport type { TodoPluginV1, TodoV1 } from \"./todo-plugin.ts\";\n\nexport interface PlanBranchRecoveryEntryV1 {\n\treadonly planId: string;\n\treadonly outcome: \"recovered\" | \"terminal_kept\" | \"skipped_other_branch\";\n\treadonly branch: string;\n\treadonly statusBefore: string;\n}\n\nexport interface PlanBranchRecoveryReportV1 {\n\treadonly currentBranch: string;\n\treadonly entries: readonly PlanBranchRecoveryEntryV1[];\n}\n\nexport interface DomainRestartRecordV1 {\n\treadonly domain: \"goal\" | \"plan\" | \"todo\";\n\treadonly entityId: string;\n\treadonly statusAfter: string;\n\treadonly revisionAfter: number;\n\treadonly evidenceCount: number;\n\treadonly terminal: boolean;\n}\n\nexport interface DomainRestartReportV1 {\n\treadonly records: readonly DomainRestartRecordV1[];\n\t/** True when every restored entity matches the state it had before the restart. */\n\treadonly identical: boolean;\n}\n\nconst GOAL_TERMINAL = new Set([\"achieved\", \"archived\"]);\nconst PLAN_TERMINAL = new Set([\"completed\", \"discarded\"]);\nconst TODO_TERMINAL = new Set([\"completed\", \"cancelled\"]);\n\n/**\n * 5.2a — recovers plans for the current branch. Plans on other branches are\n * reported and left untouched (no scans, no writes). Terminal plans on the\n * current branch are kept as-is; draft/active plans are recovered through\n * the plugin's own ledger-derived state (no shadow writes).\n */\nexport function recoverPlansForBranch(plans: readonly PlanV1[], currentBranch: string): PlanBranchRecoveryReportV1 {\n\tconst entries = plans.map((plan): PlanBranchRecoveryEntryV1 => {\n\t\tconst terminal = PLAN_TERMINAL.has(plan.status);\n\t\tif (plan.branch !== currentBranch) {\n\t\t\treturn {\n\t\t\t\tplanId: plan.planId,\n\t\t\t\toutcome: \"skipped_other_branch\",\n\t\t\t\tbranch: plan.branch,\n\t\t\t\tstatusBefore: plan.status,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tplanId: plan.planId,\n\t\t\toutcome: terminal ? \"terminal_kept\" : \"recovered\",\n\t\t\tbranch: plan.branch,\n\t\t\tstatusBefore: plan.status,\n\t\t};\n\t});\n\treturn { currentBranch, entries: Object.freeze(entries) };\n}\n\n/**\n * 5.2b — restores goal/plan/todo state after a restart by replaying each\n * entity's history into a fresh store (the caller performs the replay via\n * the plugin attached to the rebuilt store) and comparing against the\n * pre-restart snapshots.\n */\nexport function buildRestartReport(\n\tsnapshots: {\n\t\treadonly goal?: readonly GoalV1[];\n\t\treadonly plan?: readonly PlanV1[];\n\t\treadonly todo?: readonly TodoV1[];\n\t},\n\trestored: {\n\t\treadonly goals: GoalPluginV1;\n\t\treadonly plans: PlanPluginV1;\n\t\treadonly todos: TodoPluginV1;\n\t},\n\towner: string,\n): DomainRestartReportV1 {\n\tconst records: DomainRestartRecordV1[] = [];\n\tlet identical = true;\n\tconst compare = (\n\t\tdomain: \"goal\" | \"plan\" | \"todo\",\n\t\tentityId: string,\n\t\tstatusAfter: string,\n\t\trevisionAfter: number,\n\t\tevidenceCount: number,\n\t\tterminal: boolean,\n\t\tstatusBefore: string,\n\t\trevisionBefore: number,\n\t): void => {\n\t\tif (statusAfter !== statusBefore || revisionAfter !== revisionBefore) identical = false;\n\t\trecords.push({ domain, entityId, statusAfter, revisionAfter, evidenceCount, terminal });\n\t};\n\tfor (const goal of snapshots.goal ?? []) {\n\t\tconst after = restored.goals.get(goal.goalId, owner);\n\t\tif (!after) {\n\t\t\tidentical = false;\n\t\t\trecords.push({\n\t\t\t\tdomain: \"goal\",\n\t\t\t\tentityId: goal.goalId,\n\t\t\t\tstatusAfter: \"missing\",\n\t\t\t\trevisionAfter: 0,\n\t\t\t\tevidenceCount: 0,\n\t\t\t\tterminal: false,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tcompare(\n\t\t\t\"goal\",\n\t\t\tgoal.goalId,\n\t\t\tafter.status,\n\t\t\tafter.revision,\n\t\t\tafter.evidence.length,\n\t\t\tGOAL_TERMINAL.has(after.status),\n\t\t\tgoal.status,\n\t\t\tgoal.revision,\n\t\t);\n\t}\n\tfor (const plan of snapshots.plan ?? []) {\n\t\tconst after = restored.plans.get(plan.planId, owner);\n\t\tif (!after) {\n\t\t\tidentical = false;\n\t\t\trecords.push({\n\t\t\t\tdomain: \"plan\",\n\t\t\t\tentityId: plan.planId,\n\t\t\t\tstatusAfter: \"missing\",\n\t\t\t\trevisionAfter: 0,\n\t\t\t\tevidenceCount: 0,\n\t\t\t\tterminal: false,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tcompare(\n\t\t\t\"plan\",\n\t\t\tplan.planId,\n\t\t\tafter.status,\n\t\t\tafter.revisionNo,\n\t\t\tafter.evidence.length,\n\t\t\tPLAN_TERMINAL.has(after.status),\n\t\t\tplan.status,\n\t\t\tplan.revisionNo,\n\t\t);\n\t}\n\tfor (const todo of snapshots.todo ?? []) {\n\t\tconst after = restored.todos.get(todo.todoId, owner);\n\t\tif (!after) {\n\t\t\tidentical = false;\n\t\t\trecords.push({\n\t\t\t\tdomain: \"todo\",\n\t\t\t\tentityId: todo.todoId,\n\t\t\t\tstatusAfter: \"missing\",\n\t\t\t\trevisionAfter: 0,\n\t\t\t\tevidenceCount: 0,\n\t\t\t\tterminal: false,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tcompare(\n\t\t\t\"todo\",\n\t\t\ttodo.todoId,\n\t\t\tafter.status,\n\t\t\tafter.revision,\n\t\t\tafter.evidence.length,\n\t\t\tTODO_TERMINAL.has(after.status),\n\t\t\ttodo.status,\n\t\t\ttodo.revision,\n\t\t);\n\t}\n\treturn { records: Object.freeze(records), identical };\n}\n"]}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* First-batch role vertical slices (2.2c): 架构/实现/测试.
|
|
3
|
-
*
|
|
4
|
-
* Each role is a `RoleMetadataV1` registered in the role catalog plus a
|
|
5
|
-
* deterministic runner that only consumes the public facade — no private
|
|
6
|
-
* session access. These are the first vertical slices proving that a role can
|
|
7
|
-
* be declared, discovered, and executed end to end.
|
|
8
|
-
*/
|
|
9
|
-
import type { RoleCatalogV1, RoleMetadataV1 } from "./role-catalog.ts";
|
|
10
|
-
export interface FirstBatchRoleV1 {
|
|
11
|
-
readonly metadata: RoleMetadataV1;
|
|
12
|
-
readonly run: (input: {
|
|
13
|
-
readonly spec: string;
|
|
14
|
-
}) => Promise<{
|
|
15
|
-
readonly result: string;
|
|
16
|
-
}>;
|
|
17
|
-
}
|
|
18
|
-
export declare const FIRST_BATCH_ROLES: readonly {
|
|
19
|
-
readonly metadata: RoleMetadataV1;
|
|
20
|
-
readonly run: FirstBatchRoleV1["run"];
|
|
21
|
-
}[];
|
|
22
|
-
/** Registers and returns the first-batch role vertical slices. */
|
|
23
|
-
export declare function createFirstBatchRoleSlices(catalog: RoleCatalogV1): {
|
|
24
|
-
readonly roles: readonly FirstBatchRoleV1[];
|
|
25
|
-
run(roleId: string, spec: string): Promise<{
|
|
26
|
-
readonly roleId: string;
|
|
27
|
-
readonly result: string;
|
|
28
|
-
}>;
|
|
29
|
-
};
|
|
30
|
-
//# sourceMappingURL=first-roles.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"first-roles.d.ts","sourceRoot":"","sources":["../../src/profile/first-roles.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGvE,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzF;AAsCD,eAAO,MAAM,iBAAiB,EAAE,SAAS;IACxC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,GAAG,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC;CACtC,EAmBA,CAAC;AAEF,kEAAkE;AAClE,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,aAAa,GAAG;IACnE,QAAQ,CAAC,KAAK,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC5C,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjG,CAeA","sourcesContent":["/**\n * First-batch role vertical slices (2.2c): 架构/实现/测试.\n *\n * Each role is a `RoleMetadataV1` registered in the role catalog plus a\n * deterministic runner that only consumes the public facade — no private\n * session access. These are the first vertical slices proving that a role can\n * be declared, discovered, and executed end to end.\n */\n\nimport { t } from \"../core/i18n/index.ts\";\nimport type { RoleCatalogV1, RoleMetadataV1 } from \"./role-catalog.ts\";\nimport { validateRoleMetadataV1 } from \"./role-catalog.ts\";\n\nexport interface FirstBatchRoleV1 {\n\treadonly metadata: RoleMetadataV1;\n\treadonly run: (input: { readonly spec: string }) => Promise<{ readonly result: string }>;\n}\n\nconst ARCHITECTURE_ROLE: RoleMetadataV1 = {\n\troleId: \"architecture-analyst\",\n\ttitle: \"Architecture Analyst\",\n\tinput: { schemaId: \"role/architecture-input@1\", schemaVersion: 1 },\n\toutput: { schemaId: \"role/architecture-output@1\", schemaVersion: 1 },\n\tcapabilityDependencies: [{ capabilityId: \"tool.read\", capabilityVersion: 1, required: true }],\n\twritableScopes: [\"session\"],\n\tconcurrency: \"parallel\",\n\tcompletionCriteria: \"module structure findings recorded\",\n};\n\nconst IMPLEMENTER_ROLE: RoleMetadataV1 = {\n\troleId: \"implementer\",\n\ttitle: \"Implementer\",\n\tinput: { schemaId: \"role/implement-input@1\", schemaVersion: 1 },\n\toutput: { schemaId: \"role/implement-output@1\", schemaVersion: 1 },\n\tcapabilityDependencies: [\n\t\t{ capabilityId: \"tool.edit\", capabilityVersion: 1, required: true },\n\t\t{ capabilityId: \"tool.write\", capabilityVersion: 1, required: false },\n\t],\n\twritableScopes: [\"session\", \"cycle\"],\n\tconcurrency: \"single\",\n\tcompletionCriteria: \"patch produced for the requested spec\",\n};\n\nconst TEST_DESIGNER_ROLE: RoleMetadataV1 = {\n\troleId: \"test-designer\",\n\ttitle: \"Test Designer\",\n\tinput: { schemaId: \"role/test-input@1\", schemaVersion: 1 },\n\toutput: { schemaId: \"role/test-output@1\", schemaVersion: 1 },\n\tcapabilityDependencies: [{ capabilityId: \"tool.read\", capabilityVersion: 1, required: true }],\n\twritableScopes: [\"session\"],\n\tconcurrency: \"parallel\",\n\tcompletionCriteria: \"test cases derived from the spec\",\n};\n\nexport const FIRST_BATCH_ROLES: readonly {\n\treadonly metadata: RoleMetadataV1;\n\treadonly run: FirstBatchRoleV1[\"run\"];\n}[] = [\n\t{\n\t\tmetadata: ARCHITECTURE_ROLE,\n\t\trun: async (input) => ({\n\t\t\tresult: `architecture findings for: ${input.spec.slice(0, 64)}`,\n\t\t}),\n\t},\n\t{\n\t\tmetadata: IMPLEMENTER_ROLE,\n\t\trun: async (input) => ({\n\t\t\tresult: `patch for: ${input.spec.slice(0, 64)}`,\n\t\t}),\n\t},\n\t{\n\t\tmetadata: TEST_DESIGNER_ROLE,\n\t\trun: async (input) => ({\n\t\t\tresult: `test cases for: ${input.spec.slice(0, 64)}`,\n\t\t}),\n\t},\n];\n\n/** Registers and returns the first-batch role vertical slices. */\nexport function createFirstBatchRoleSlices(catalog: RoleCatalogV1): {\n\treadonly roles: readonly FirstBatchRoleV1[];\n\trun(roleId: string, spec: string): Promise<{ readonly roleId: string; readonly result: string }>;\n} {\n\tconst roles = FIRST_BATCH_ROLES.map((role) => ({\n\t\tmetadata: validateRoleMetadataV1(role.metadata),\n\t\trun: role.run,\n\t}));\n\tfor (const role of roles) catalog.register(role.metadata);\n\tconst runners = new Map(roles.map((role) => [role.metadata.roleId, role.run]));\n\treturn {\n\t\troles,\n\t\tasync run(roleId, spec) {\n\t\t\tconst run = runners.get(roleId);\n\t\t\tif (!run) throw new Error(t(\"Unknown first-batch role: {roleId}\", { roleId }));\n\t\t\treturn { roleId, result: (await run({ spec })).result };\n\t\t},\n\t};\n}\n"]}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* First-batch role vertical slices (2.2c): 架构/实现/测试.
|
|
3
|
-
*
|
|
4
|
-
* Each role is a `RoleMetadataV1` registered in the role catalog plus a
|
|
5
|
-
* deterministic runner that only consumes the public facade — no private
|
|
6
|
-
* session access. These are the first vertical slices proving that a role can
|
|
7
|
-
* be declared, discovered, and executed end to end.
|
|
8
|
-
*/
|
|
9
|
-
import { t } from "../core/i18n/index.js";
|
|
10
|
-
import { validateRoleMetadataV1 } from "./role-catalog.js";
|
|
11
|
-
const ARCHITECTURE_ROLE = {
|
|
12
|
-
roleId: "architecture-analyst",
|
|
13
|
-
title: "Architecture Analyst",
|
|
14
|
-
input: { schemaId: "role/architecture-input@1", schemaVersion: 1 },
|
|
15
|
-
output: { schemaId: "role/architecture-output@1", schemaVersion: 1 },
|
|
16
|
-
capabilityDependencies: [{ capabilityId: "tool.read", capabilityVersion: 1, required: true }],
|
|
17
|
-
writableScopes: ["session"],
|
|
18
|
-
concurrency: "parallel",
|
|
19
|
-
completionCriteria: "module structure findings recorded",
|
|
20
|
-
};
|
|
21
|
-
const IMPLEMENTER_ROLE = {
|
|
22
|
-
roleId: "implementer",
|
|
23
|
-
title: "Implementer",
|
|
24
|
-
input: { schemaId: "role/implement-input@1", schemaVersion: 1 },
|
|
25
|
-
output: { schemaId: "role/implement-output@1", schemaVersion: 1 },
|
|
26
|
-
capabilityDependencies: [
|
|
27
|
-
{ capabilityId: "tool.edit", capabilityVersion: 1, required: true },
|
|
28
|
-
{ capabilityId: "tool.write", capabilityVersion: 1, required: false },
|
|
29
|
-
],
|
|
30
|
-
writableScopes: ["session", "cycle"],
|
|
31
|
-
concurrency: "single",
|
|
32
|
-
completionCriteria: "patch produced for the requested spec",
|
|
33
|
-
};
|
|
34
|
-
const TEST_DESIGNER_ROLE = {
|
|
35
|
-
roleId: "test-designer",
|
|
36
|
-
title: "Test Designer",
|
|
37
|
-
input: { schemaId: "role/test-input@1", schemaVersion: 1 },
|
|
38
|
-
output: { schemaId: "role/test-output@1", schemaVersion: 1 },
|
|
39
|
-
capabilityDependencies: [{ capabilityId: "tool.read", capabilityVersion: 1, required: true }],
|
|
40
|
-
writableScopes: ["session"],
|
|
41
|
-
concurrency: "parallel",
|
|
42
|
-
completionCriteria: "test cases derived from the spec",
|
|
43
|
-
};
|
|
44
|
-
export const FIRST_BATCH_ROLES = [
|
|
45
|
-
{
|
|
46
|
-
metadata: ARCHITECTURE_ROLE,
|
|
47
|
-
run: async (input) => ({
|
|
48
|
-
result: `architecture findings for: ${input.spec.slice(0, 64)}`,
|
|
49
|
-
}),
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
metadata: IMPLEMENTER_ROLE,
|
|
53
|
-
run: async (input) => ({
|
|
54
|
-
result: `patch for: ${input.spec.slice(0, 64)}`,
|
|
55
|
-
}),
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
metadata: TEST_DESIGNER_ROLE,
|
|
59
|
-
run: async (input) => ({
|
|
60
|
-
result: `test cases for: ${input.spec.slice(0, 64)}`,
|
|
61
|
-
}),
|
|
62
|
-
},
|
|
63
|
-
];
|
|
64
|
-
/** Registers and returns the first-batch role vertical slices. */
|
|
65
|
-
export function createFirstBatchRoleSlices(catalog) {
|
|
66
|
-
const roles = FIRST_BATCH_ROLES.map((role) => ({
|
|
67
|
-
metadata: validateRoleMetadataV1(role.metadata),
|
|
68
|
-
run: role.run,
|
|
69
|
-
}));
|
|
70
|
-
for (const role of roles)
|
|
71
|
-
catalog.register(role.metadata);
|
|
72
|
-
const runners = new Map(roles.map((role) => [role.metadata.roleId, role.run]));
|
|
73
|
-
return {
|
|
74
|
-
roles,
|
|
75
|
-
async run(roleId, spec) {
|
|
76
|
-
const run = runners.get(roleId);
|
|
77
|
-
if (!run)
|
|
78
|
-
throw new Error(t("Unknown first-batch role: {roleId}", { roleId }));
|
|
79
|
-
return { roleId, result: (await run({ spec })).result };
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
//# sourceMappingURL=first-roles.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"first-roles.js","sourceRoot":"","sources":["../../src/profile/first-roles.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * First-batch role vertical slices (2.2c): 架构/实现/测试.\n *\n * Each role is a `RoleMetadataV1` registered in the role catalog plus a\n * deterministic runner that only consumes the public facade — no private\n * session access. These are the first vertical slices proving that a role can\n * be declared, discovered, and executed end to end.\n */\n\nimport { t } from \"../core/i18n/index.ts\";\nimport type { RoleCatalogV1, RoleMetadataV1 } from \"./role-catalog.ts\";\nimport { validateRoleMetadataV1 } from \"./role-catalog.ts\";\n\nexport interface FirstBatchRoleV1 {\n\treadonly metadata: RoleMetadataV1;\n\treadonly run: (input: { readonly spec: string }) => Promise<{ readonly result: string }>;\n}\n\nconst ARCHITECTURE_ROLE: RoleMetadataV1 = {\n\troleId: \"architecture-analyst\",\n\ttitle: \"Architecture Analyst\",\n\tinput: { schemaId: \"role/architecture-input@1\", schemaVersion: 1 },\n\toutput: { schemaId: \"role/architecture-output@1\", schemaVersion: 1 },\n\tcapabilityDependencies: [{ capabilityId: \"tool.read\", capabilityVersion: 1, required: true }],\n\twritableScopes: [\"session\"],\n\tconcurrency: \"parallel\",\n\tcompletionCriteria: \"module structure findings recorded\",\n};\n\nconst IMPLEMENTER_ROLE: RoleMetadataV1 = {\n\troleId: \"implementer\",\n\ttitle: \"Implementer\",\n\tinput: { schemaId: \"role/implement-input@1\", schemaVersion: 1 },\n\toutput: { schemaId: \"role/implement-output@1\", schemaVersion: 1 },\n\tcapabilityDependencies: [\n\t\t{ capabilityId: \"tool.edit\", capabilityVersion: 1, required: true },\n\t\t{ capabilityId: \"tool.write\", capabilityVersion: 1, required: false },\n\t],\n\twritableScopes: [\"session\", \"cycle\"],\n\tconcurrency: \"single\",\n\tcompletionCriteria: \"patch produced for the requested spec\",\n};\n\nconst TEST_DESIGNER_ROLE: RoleMetadataV1 = {\n\troleId: \"test-designer\",\n\ttitle: \"Test Designer\",\n\tinput: { schemaId: \"role/test-input@1\", schemaVersion: 1 },\n\toutput: { schemaId: \"role/test-output@1\", schemaVersion: 1 },\n\tcapabilityDependencies: [{ capabilityId: \"tool.read\", capabilityVersion: 1, required: true }],\n\twritableScopes: [\"session\"],\n\tconcurrency: \"parallel\",\n\tcompletionCriteria: \"test cases derived from the spec\",\n};\n\nexport const FIRST_BATCH_ROLES: readonly {\n\treadonly metadata: RoleMetadataV1;\n\treadonly run: FirstBatchRoleV1[\"run\"];\n}[] = [\n\t{\n\t\tmetadata: ARCHITECTURE_ROLE,\n\t\trun: async (input) => ({\n\t\t\tresult: `architecture findings for: ${input.spec.slice(0, 64)}`,\n\t\t}),\n\t},\n\t{\n\t\tmetadata: IMPLEMENTER_ROLE,\n\t\trun: async (input) => ({\n\t\t\tresult: `patch for: ${input.spec.slice(0, 64)}`,\n\t\t}),\n\t},\n\t{\n\t\tmetadata: TEST_DESIGNER_ROLE,\n\t\trun: async (input) => ({\n\t\t\tresult: `test cases for: ${input.spec.slice(0, 64)}`,\n\t\t}),\n\t},\n];\n\n/** Registers and returns the first-batch role vertical slices. */\nexport function createFirstBatchRoleSlices(catalog: RoleCatalogV1): {\n\treadonly roles: readonly FirstBatchRoleV1[];\n\trun(roleId: string, spec: string): Promise<{ readonly roleId: string; readonly result: string }>;\n} {\n\tconst roles = FIRST_BATCH_ROLES.map((role) => ({\n\t\tmetadata: validateRoleMetadataV1(role.metadata),\n\t\trun: role.run,\n\t}));\n\tfor (const role of roles) catalog.register(role.metadata);\n\tconst runners = new Map(roles.map((role) => [role.metadata.roleId, role.run]));\n\treturn {\n\t\troles,\n\t\tasync run(roleId, spec) {\n\t\t\tconst run = runners.get(roleId);\n\t\t\tif (!run) throw new Error(t(\"Unknown first-batch role: {roleId}\", { roleId }));\n\t\t\treturn { roleId, result: (await run({ spec })).result };\n\t\t},\n\t};\n}\n"]}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Goal plugin (2.3b) — Goal schema, evidence, and recovery on top of the 2.3a
|
|
3
|
-
* transition store.
|
|
4
|
-
*
|
|
5
|
-
* Status graph: null → draft → active → achieved, and draft/active → archived.
|
|
6
|
-
* `achieve` requires at least one evidence reference. The plugin holds NO
|
|
7
|
-
* shadow state: every read derives status, revision, title, and evidence from
|
|
8
|
-
* the transition history, so recovery is exactly a store replay.
|
|
9
|
-
*/
|
|
10
|
-
import type { TransitionEvidenceRefV1, TransitionStoreV1 } from "./state-store.ts";
|
|
11
|
-
export type GoalStatusV1 = "draft" | "active" | "achieved" | "archived";
|
|
12
|
-
export interface GoalV1 {
|
|
13
|
-
readonly goalId: string;
|
|
14
|
-
readonly owner: string;
|
|
15
|
-
readonly title: string;
|
|
16
|
-
readonly status: GoalStatusV1;
|
|
17
|
-
readonly evidence: readonly TransitionEvidenceRefV1[];
|
|
18
|
-
readonly revision: number;
|
|
19
|
-
}
|
|
20
|
-
export interface GoalPluginV1 {
|
|
21
|
-
createGoal(input: {
|
|
22
|
-
readonly goalId: string;
|
|
23
|
-
readonly owner: string;
|
|
24
|
-
readonly title: string;
|
|
25
|
-
}): GoalV1;
|
|
26
|
-
activate(goalId: string, owner: string, options?: {
|
|
27
|
-
readonly operationId?: string;
|
|
28
|
-
}): GoalV1;
|
|
29
|
-
achieve(goalId: string, owner: string, evidence: readonly TransitionEvidenceRefV1[], options?: {
|
|
30
|
-
readonly operationId?: string;
|
|
31
|
-
}): GoalV1;
|
|
32
|
-
archive(goalId: string, owner: string): GoalV1;
|
|
33
|
-
get(goalId: string, owner: string): GoalV1 | undefined;
|
|
34
|
-
}
|
|
35
|
-
export declare function createGoalPlugin(options: {
|
|
36
|
-
readonly transitions: TransitionStoreV1;
|
|
37
|
-
}): GoalPluginV1;
|
|
38
|
-
//# sourceMappingURL=goal-plugin.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"goal-plugin.d.ts","sourceRoot":"","sources":["../../src/profile/goal-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEnF,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC;AAExE,MAAM,WAAW,MAAM;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,uBAAuB,EAAE,CAAC;IACtD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC5B,UAAU,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IACvG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IAC7F,OAAO,CACN,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,SAAS,uBAAuB,EAAE,EAC5C,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GACzC,MAAM,CAAC;IACV,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/C,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACvD;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAA;CAAE,GAAG,YAAY,CA8InG","sourcesContent":["/**\n * Goal plugin (2.3b) — Goal schema, evidence, and recovery on top of the 2.3a\n * transition store.\n *\n * Status graph: null → draft → active → achieved, and draft/active → archived.\n * `achieve` requires at least one evidence reference. The plugin holds NO\n * shadow state: every read derives status, revision, title, and evidence from\n * the transition history, so recovery is exactly a store replay.\n */\n\nimport { t } from \"../core/i18n/index.ts\";\nimport type { TransitionEvidenceRefV1, TransitionStoreV1 } from \"./state-store.ts\";\n\nexport type GoalStatusV1 = \"draft\" | \"active\" | \"achieved\" | \"archived\";\n\nexport interface GoalV1 {\n\treadonly goalId: string;\n\treadonly owner: string;\n\treadonly title: string;\n\treadonly status: GoalStatusV1;\n\treadonly evidence: readonly TransitionEvidenceRefV1[];\n\treadonly revision: number;\n}\n\nexport interface GoalPluginV1 {\n\tcreateGoal(input: { readonly goalId: string; readonly owner: string; readonly title: string }): GoalV1;\n\tactivate(goalId: string, owner: string, options?: { readonly operationId?: string }): GoalV1;\n\tachieve(\n\t\tgoalId: string,\n\t\towner: string,\n\t\tevidence: readonly TransitionEvidenceRefV1[],\n\t\toptions?: { readonly operationId?: string },\n\t): GoalV1;\n\tarchive(goalId: string, owner: string): GoalV1;\n\tget(goalId: string, owner: string): GoalV1 | undefined;\n}\n\nexport function createGoalPlugin(options: { readonly transitions: TransitionStoreV1 }): GoalPluginV1 {\n\tconst transitions = options.transitions;\n\n\tconst goalHistory = (goalId: string, owner: string) =>\n\t\ttransitions.history(goalId).filter((record) => record.domain === \"goal\" && record.owner === owner);\n\n\tconst current = (goalId: string, owner: string): { status: GoalStatusV1; revision: number } | undefined => {\n\t\tconst state = transitions.currentStatus(\"goal\", goalId);\n\t\tif (state === undefined || goalHistory(goalId, owner).length === 0) return undefined;\n\t\treturn { status: state.status as GoalStatusV1, revision: state.revision };\n\t};\n\n\tconst titleOf = (goalId: string, owner: string): string => {\n\t\tfor (const record of goalHistory(goalId, owner)) {\n\t\t\tif (record.fromStatus !== null) continue;\n\t\t\tconst payload = record.payload;\n\t\t\tif (payload !== null && typeof payload === \"object\" && !Array.isArray(payload)) {\n\t\t\t\tconst title = (payload as Record<string, unknown>).title;\n\t\t\t\tif (typeof title === \"string\") return title;\n\t\t\t}\n\t\t}\n\t\treturn goalId;\n\t};\n\n\tconst goalGet = (goalId: string, owner: string): GoalV1 | undefined => {\n\t\tconst state = current(goalId, owner);\n\t\tif (!state) return undefined;\n\t\tconst history = goalHistory(goalId, owner);\n\t\tconst lastEvidence = [...history].reverse().find((record) => record.evidence.length > 0)?.evidence ?? [];\n\t\treturn {\n\t\t\tgoalId,\n\t\t\towner,\n\t\t\ttitle: titleOf(goalId, owner),\n\t\t\tstatus: state.status,\n\t\t\tevidence: lastEvidence,\n\t\t\trevision: state.revision,\n\t\t};\n\t};\n\n\t/** A retried transition with an already-applied operationId returns the existing state instead of conflicting. */\n\tconst replayedGoal = (\n\t\tgoalId: string,\n\t\towner: string,\n\t\ttoStatus: GoalStatusV1,\n\t\toperationId?: string,\n\t): GoalV1 | undefined => {\n\t\tif (!operationId) return undefined;\n\t\tconst applied = goalHistory(goalId, owner).some(\n\t\t\t(record) => record.toStatus === toStatus && record.operationId === operationId,\n\t\t);\n\t\treturn applied ? goalGet(goalId, owner) : undefined;\n\t};\n\n\tconst transitionGoal = (\n\t\tgoalId: string,\n\t\towner: string,\n\t\tfromStatus: GoalStatusV1 | null,\n\t\ttoStatus: GoalStatusV1,\n\t\tgoalOptions: {\n\t\t\treadonly evidence?: readonly TransitionEvidenceRefV1[];\n\t\t\treadonly payload?: { readonly title: string };\n\t\t\treadonly operationId?: string;\n\t\t},\n\t): GoalV1 => {\n\t\ttransitions.transition({\n\t\t\tdomain: \"goal\",\n\t\t\tentityId: goalId,\n\t\t\towner,\n\t\t\tfromStatus,\n\t\t\ttoStatus,\n\t\t\toperationId: goalOptions.operationId ?? `${toStatus}:${goalId}`,\n\t\t\tevidence: goalOptions.evidence,\n\t\t\tpayload: goalOptions.payload,\n\t\t});\n\t\tconst state = transitions.currentStatus(\"goal\", goalId);\n\t\treturn {\n\t\t\tgoalId,\n\t\t\towner,\n\t\t\ttitle: titleOf(goalId, owner),\n\t\t\tstatus: state?.status as GoalStatusV1,\n\t\t\tevidence: goalOptions.evidence ?? [],\n\t\t\t// v8 ignore next -- transition 刚写入 currentStatus,必可读到 revision\n\t\t\trevision: state?.revision ?? 0,\n\t\t};\n\t};\n\n\treturn {\n\t\tcreateGoal({ goalId, owner, title }) {\n\t\t\tif (title.trim().length === 0) throw new Error(t(\"Goal title must be a non-empty string\"));\n\t\t\treturn transitionGoal(goalId, owner, null, \"draft\", {\n\t\t\t\tpayload: { title },\n\t\t\t\toperationId: `create:${goalId}`,\n\t\t\t});\n\t\t},\n\t\tactivate(goalId, owner, activateOptions) {\n\t\t\tconst replayed = replayedGoal(goalId, owner, \"active\", activateOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\tconst existing = current(goalId, owner);\n\t\t\tif (existing?.status !== \"draft\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Goal {goalId} must be in draft status to activate (current: {status})\", {\n\t\t\t\t\t\tgoalId,\n\t\t\t\t\t\tstatus: existing?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn transitionGoal(goalId, owner, \"draft\", \"active\", { operationId: activateOptions?.operationId });\n\t\t},\n\t\tachieve(goalId, owner, evidence, achieveOptions) {\n\t\t\tconst replayed = replayedGoal(goalId, owner, \"achieved\", achieveOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\tconst existing = current(goalId, owner);\n\t\t\tif (existing?.status !== \"active\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Goal {goalId} must be active to achieve (current: {status})\", {\n\t\t\t\t\t\tgoalId,\n\t\t\t\t\t\tstatus: existing?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (evidence.length === 0) throw new Error(t(\"Achieving a goal requires at least one evidence reference\"));\n\t\t\treturn transitionGoal(goalId, owner, \"active\", \"achieved\", {\n\t\t\t\tevidence,\n\t\t\t\toperationId: achieveOptions?.operationId,\n\t\t\t});\n\t\t},\n\t\tarchive(goalId, owner) {\n\t\t\tconst existing = current(goalId, owner);\n\t\t\tif (!existing || existing.status === \"achieved\" || existing.status === \"archived\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Goal {goalId} cannot be archived from status {status}\", {\n\t\t\t\t\t\tgoalId,\n\t\t\t\t\t\tstatus: existing?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn transitionGoal(goalId, owner, existing.status, \"archived\", {});\n\t\t},\n\t\tget(goalId, owner) {\n\t\t\treturn goalGet(goalId, owner);\n\t\t},\n\t};\n}\n"]}
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Goal plugin (2.3b) — Goal schema, evidence, and recovery on top of the 2.3a
|
|
3
|
-
* transition store.
|
|
4
|
-
*
|
|
5
|
-
* Status graph: null → draft → active → achieved, and draft/active → archived.
|
|
6
|
-
* `achieve` requires at least one evidence reference. The plugin holds NO
|
|
7
|
-
* shadow state: every read derives status, revision, title, and evidence from
|
|
8
|
-
* the transition history, so recovery is exactly a store replay.
|
|
9
|
-
*/
|
|
10
|
-
import { t } from "../core/i18n/index.js";
|
|
11
|
-
export function createGoalPlugin(options) {
|
|
12
|
-
const transitions = options.transitions;
|
|
13
|
-
const goalHistory = (goalId, owner) => transitions.history(goalId).filter((record) => record.domain === "goal" && record.owner === owner);
|
|
14
|
-
const current = (goalId, owner) => {
|
|
15
|
-
const state = transitions.currentStatus("goal", goalId);
|
|
16
|
-
if (state === undefined || goalHistory(goalId, owner).length === 0)
|
|
17
|
-
return undefined;
|
|
18
|
-
return { status: state.status, revision: state.revision };
|
|
19
|
-
};
|
|
20
|
-
const titleOf = (goalId, owner) => {
|
|
21
|
-
for (const record of goalHistory(goalId, owner)) {
|
|
22
|
-
if (record.fromStatus !== null)
|
|
23
|
-
continue;
|
|
24
|
-
const payload = record.payload;
|
|
25
|
-
if (payload !== null && typeof payload === "object" && !Array.isArray(payload)) {
|
|
26
|
-
const title = payload.title;
|
|
27
|
-
if (typeof title === "string")
|
|
28
|
-
return title;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return goalId;
|
|
32
|
-
};
|
|
33
|
-
const goalGet = (goalId, owner) => {
|
|
34
|
-
const state = current(goalId, owner);
|
|
35
|
-
if (!state)
|
|
36
|
-
return undefined;
|
|
37
|
-
const history = goalHistory(goalId, owner);
|
|
38
|
-
const lastEvidence = [...history].reverse().find((record) => record.evidence.length > 0)?.evidence ?? [];
|
|
39
|
-
return {
|
|
40
|
-
goalId,
|
|
41
|
-
owner,
|
|
42
|
-
title: titleOf(goalId, owner),
|
|
43
|
-
status: state.status,
|
|
44
|
-
evidence: lastEvidence,
|
|
45
|
-
revision: state.revision,
|
|
46
|
-
};
|
|
47
|
-
};
|
|
48
|
-
/** A retried transition with an already-applied operationId returns the existing state instead of conflicting. */
|
|
49
|
-
const replayedGoal = (goalId, owner, toStatus, operationId) => {
|
|
50
|
-
if (!operationId)
|
|
51
|
-
return undefined;
|
|
52
|
-
const applied = goalHistory(goalId, owner).some((record) => record.toStatus === toStatus && record.operationId === operationId);
|
|
53
|
-
return applied ? goalGet(goalId, owner) : undefined;
|
|
54
|
-
};
|
|
55
|
-
const transitionGoal = (goalId, owner, fromStatus, toStatus, goalOptions) => {
|
|
56
|
-
transitions.transition({
|
|
57
|
-
domain: "goal",
|
|
58
|
-
entityId: goalId,
|
|
59
|
-
owner,
|
|
60
|
-
fromStatus,
|
|
61
|
-
toStatus,
|
|
62
|
-
operationId: goalOptions.operationId ?? `${toStatus}:${goalId}`,
|
|
63
|
-
evidence: goalOptions.evidence,
|
|
64
|
-
payload: goalOptions.payload,
|
|
65
|
-
});
|
|
66
|
-
const state = transitions.currentStatus("goal", goalId);
|
|
67
|
-
return {
|
|
68
|
-
goalId,
|
|
69
|
-
owner,
|
|
70
|
-
title: titleOf(goalId, owner),
|
|
71
|
-
status: state?.status,
|
|
72
|
-
evidence: goalOptions.evidence ?? [],
|
|
73
|
-
// v8 ignore next -- transition 刚写入 currentStatus,必可读到 revision
|
|
74
|
-
revision: state?.revision ?? 0,
|
|
75
|
-
};
|
|
76
|
-
};
|
|
77
|
-
return {
|
|
78
|
-
createGoal({ goalId, owner, title }) {
|
|
79
|
-
if (title.trim().length === 0)
|
|
80
|
-
throw new Error(t("Goal title must be a non-empty string"));
|
|
81
|
-
return transitionGoal(goalId, owner, null, "draft", {
|
|
82
|
-
payload: { title },
|
|
83
|
-
operationId: `create:${goalId}`,
|
|
84
|
-
});
|
|
85
|
-
},
|
|
86
|
-
activate(goalId, owner, activateOptions) {
|
|
87
|
-
const replayed = replayedGoal(goalId, owner, "active", activateOptions?.operationId);
|
|
88
|
-
if (replayed)
|
|
89
|
-
return replayed;
|
|
90
|
-
const existing = current(goalId, owner);
|
|
91
|
-
if (existing?.status !== "draft") {
|
|
92
|
-
throw new Error(t("Goal {goalId} must be in draft status to activate (current: {status})", {
|
|
93
|
-
goalId,
|
|
94
|
-
status: existing?.status ?? "missing",
|
|
95
|
-
}));
|
|
96
|
-
}
|
|
97
|
-
return transitionGoal(goalId, owner, "draft", "active", { operationId: activateOptions?.operationId });
|
|
98
|
-
},
|
|
99
|
-
achieve(goalId, owner, evidence, achieveOptions) {
|
|
100
|
-
const replayed = replayedGoal(goalId, owner, "achieved", achieveOptions?.operationId);
|
|
101
|
-
if (replayed)
|
|
102
|
-
return replayed;
|
|
103
|
-
const existing = current(goalId, owner);
|
|
104
|
-
if (existing?.status !== "active") {
|
|
105
|
-
throw new Error(t("Goal {goalId} must be active to achieve (current: {status})", {
|
|
106
|
-
goalId,
|
|
107
|
-
status: existing?.status ?? "missing",
|
|
108
|
-
}));
|
|
109
|
-
}
|
|
110
|
-
if (evidence.length === 0)
|
|
111
|
-
throw new Error(t("Achieving a goal requires at least one evidence reference"));
|
|
112
|
-
return transitionGoal(goalId, owner, "active", "achieved", {
|
|
113
|
-
evidence,
|
|
114
|
-
operationId: achieveOptions?.operationId,
|
|
115
|
-
});
|
|
116
|
-
},
|
|
117
|
-
archive(goalId, owner) {
|
|
118
|
-
const existing = current(goalId, owner);
|
|
119
|
-
if (!existing || existing.status === "achieved" || existing.status === "archived") {
|
|
120
|
-
throw new Error(t("Goal {goalId} cannot be archived from status {status}", {
|
|
121
|
-
goalId,
|
|
122
|
-
status: existing?.status ?? "missing",
|
|
123
|
-
}));
|
|
124
|
-
}
|
|
125
|
-
return transitionGoal(goalId, owner, existing.status, "archived", {});
|
|
126
|
-
},
|
|
127
|
-
get(goalId, owner) {
|
|
128
|
-
return goalGet(goalId, owner);
|
|
129
|
-
},
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
//# sourceMappingURL=goal-plugin.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"goal-plugin.js","sourceRoot":"","sources":["../../src/profile/goal-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,uBAAuB,CAAC;AA2B1C,MAAM,UAAU,gBAAgB,CAAC,OAAoD,EAAgB;IACpG,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAExC,MAAM,WAAW,GAAG,CAAC,MAAc,EAAE,KAAa,EAAE,EAAE,CACrD,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;IAEpG,MAAM,OAAO,GAAG,CAAC,MAAc,EAAE,KAAa,EAA0D,EAAE,CAAC;QAC1G,MAAM,KAAK,GAAG,WAAW,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACxD,IAAI,KAAK,KAAK,SAAS,IAAI,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACrF,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,MAAsB,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;IAAA,CAC1E,CAAC;IAEF,MAAM,OAAO,GAAG,CAAC,MAAc,EAAE,KAAa,EAAU,EAAE,CAAC;QAC1D,KAAK,MAAM,MAAM,IAAI,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;YACjD,IAAI,MAAM,CAAC,UAAU,KAAK,IAAI;gBAAE,SAAS;YACzC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;YAC/B,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBAChF,MAAM,KAAK,GAAI,OAAmC,CAAC,KAAK,CAAC;gBACzD,IAAI,OAAO,KAAK,KAAK,QAAQ;oBAAE,OAAO,KAAK,CAAC;YAC7C,CAAC;QACF,CAAC;QACD,OAAO,MAAM,CAAC;IAAA,CACd,CAAC;IAEF,MAAM,OAAO,GAAG,CAAC,MAAc,EAAE,KAAa,EAAsB,EAAE,CAAC;QACtE,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAC7B,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC3C,MAAM,YAAY,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,QAAQ,IAAI,EAAE,CAAC;QACzG,OAAO;YACN,MAAM;YACN,KAAK;YACL,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC;YAC7B,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,QAAQ,EAAE,YAAY;YACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;SACxB,CAAC;IAAA,CACF,CAAC;IAEF,kHAAkH;IAClH,MAAM,YAAY,GAAG,CACpB,MAAc,EACd,KAAa,EACb,QAAsB,EACtB,WAAoB,EACC,EAAE,CAAC;QACxB,IAAI,CAAC,WAAW;YAAE,OAAO,SAAS,CAAC;QACnC,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,IAAI,CAC9C,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,WAAW,KAAK,WAAW,CAC9E,CAAC;QACF,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAAA,CACpD,CAAC;IAEF,MAAM,cAAc,GAAG,CACtB,MAAc,EACd,KAAa,EACb,UAA+B,EAC/B,QAAsB,EACtB,WAIC,EACQ,EAAE,CAAC;QACZ,WAAW,CAAC,UAAU,CAAC;YACtB,MAAM,EAAE,MAAM;YACd,QAAQ,EAAE,MAAM;YAChB,KAAK;YACL,UAAU;YACV,QAAQ;YACR,WAAW,EAAE,WAAW,CAAC,WAAW,IAAI,GAAG,QAAQ,IAAI,MAAM,EAAE;YAC/D,QAAQ,EAAE,WAAW,CAAC,QAAQ;YAC9B,OAAO,EAAE,WAAW,CAAC,OAAO;SAC5B,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,WAAW,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACxD,OAAO;YACN,MAAM;YACN,KAAK;YACL,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC;YAC7B,MAAM,EAAE,KAAK,EAAE,MAAsB;YACrC,QAAQ,EAAE,WAAW,CAAC,QAAQ,IAAI,EAAE;YACpC,+EAA+D;YAC/D,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,CAAC;SAC9B,CAAC;IAAA,CACF,CAAC;IAEF,OAAO;QACN,UAAU,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACpC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,uCAAuC,CAAC,CAAC,CAAC;YAC3F,OAAO,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE;gBACnD,OAAO,EAAE,EAAE,KAAK,EAAE;gBAClB,WAAW,EAAE,UAAU,MAAM,EAAE;aAC/B,CAAC,CAAC;QAAA,CACH;QACD,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE;YACxC,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,WAAW,CAAC,CAAC;YACrF,IAAI,QAAQ;gBAAE,OAAO,QAAQ,CAAC;YAC9B,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACxC,IAAI,QAAQ,EAAE,MAAM,KAAK,OAAO,EAAE,CAAC;gBAClC,MAAM,IAAI,KAAK,CACd,CAAC,CAAC,uEAAuE,EAAE;oBAC1E,MAAM;oBACN,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,SAAS;iBACrC,CAAC,CACF,CAAC;YACH,CAAC;YACD,OAAO,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC,CAAC;QAAA,CACvG;QACD,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE;YAChD,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;YACtF,IAAI,QAAQ;gBAAE,OAAO,QAAQ,CAAC;YAC9B,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACxC,IAAI,QAAQ,EAAE,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACnC,MAAM,IAAI,KAAK,CACd,CAAC,CAAC,6DAA6D,EAAE;oBAChE,MAAM;oBACN,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,SAAS;iBACrC,CAAC,CACF,CAAC;YACH,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,2DAA2D,CAAC,CAAC,CAAC;YAC3G,OAAO,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE;gBAC1D,QAAQ;gBACR,WAAW,EAAE,cAAc,EAAE,WAAW;aACxC,CAAC,CAAC;QAAA,CACH;QACD,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE;YACtB,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACxC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,UAAU,IAAI,QAAQ,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;gBACnF,MAAM,IAAI,KAAK,CACd,CAAC,CAAC,uDAAuD,EAAE;oBAC1D,MAAM;oBACN,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,SAAS;iBACrC,CAAC,CACF,CAAC;YACH,CAAC;YACD,OAAO,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;QAAA,CACtE;QACD,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE;YAClB,OAAO,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAAA,CAC9B;KACD,CAAC;AAAA,CACF","sourcesContent":["/**\n * Goal plugin (2.3b) — Goal schema, evidence, and recovery on top of the 2.3a\n * transition store.\n *\n * Status graph: null → draft → active → achieved, and draft/active → archived.\n * `achieve` requires at least one evidence reference. The plugin holds NO\n * shadow state: every read derives status, revision, title, and evidence from\n * the transition history, so recovery is exactly a store replay.\n */\n\nimport { t } from \"../core/i18n/index.ts\";\nimport type { TransitionEvidenceRefV1, TransitionStoreV1 } from \"./state-store.ts\";\n\nexport type GoalStatusV1 = \"draft\" | \"active\" | \"achieved\" | \"archived\";\n\nexport interface GoalV1 {\n\treadonly goalId: string;\n\treadonly owner: string;\n\treadonly title: string;\n\treadonly status: GoalStatusV1;\n\treadonly evidence: readonly TransitionEvidenceRefV1[];\n\treadonly revision: number;\n}\n\nexport interface GoalPluginV1 {\n\tcreateGoal(input: { readonly goalId: string; readonly owner: string; readonly title: string }): GoalV1;\n\tactivate(goalId: string, owner: string, options?: { readonly operationId?: string }): GoalV1;\n\tachieve(\n\t\tgoalId: string,\n\t\towner: string,\n\t\tevidence: readonly TransitionEvidenceRefV1[],\n\t\toptions?: { readonly operationId?: string },\n\t): GoalV1;\n\tarchive(goalId: string, owner: string): GoalV1;\n\tget(goalId: string, owner: string): GoalV1 | undefined;\n}\n\nexport function createGoalPlugin(options: { readonly transitions: TransitionStoreV1 }): GoalPluginV1 {\n\tconst transitions = options.transitions;\n\n\tconst goalHistory = (goalId: string, owner: string) =>\n\t\ttransitions.history(goalId).filter((record) => record.domain === \"goal\" && record.owner === owner);\n\n\tconst current = (goalId: string, owner: string): { status: GoalStatusV1; revision: number } | undefined => {\n\t\tconst state = transitions.currentStatus(\"goal\", goalId);\n\t\tif (state === undefined || goalHistory(goalId, owner).length === 0) return undefined;\n\t\treturn { status: state.status as GoalStatusV1, revision: state.revision };\n\t};\n\n\tconst titleOf = (goalId: string, owner: string): string => {\n\t\tfor (const record of goalHistory(goalId, owner)) {\n\t\t\tif (record.fromStatus !== null) continue;\n\t\t\tconst payload = record.payload;\n\t\t\tif (payload !== null && typeof payload === \"object\" && !Array.isArray(payload)) {\n\t\t\t\tconst title = (payload as Record<string, unknown>).title;\n\t\t\t\tif (typeof title === \"string\") return title;\n\t\t\t}\n\t\t}\n\t\treturn goalId;\n\t};\n\n\tconst goalGet = (goalId: string, owner: string): GoalV1 | undefined => {\n\t\tconst state = current(goalId, owner);\n\t\tif (!state) return undefined;\n\t\tconst history = goalHistory(goalId, owner);\n\t\tconst lastEvidence = [...history].reverse().find((record) => record.evidence.length > 0)?.evidence ?? [];\n\t\treturn {\n\t\t\tgoalId,\n\t\t\towner,\n\t\t\ttitle: titleOf(goalId, owner),\n\t\t\tstatus: state.status,\n\t\t\tevidence: lastEvidence,\n\t\t\trevision: state.revision,\n\t\t};\n\t};\n\n\t/** A retried transition with an already-applied operationId returns the existing state instead of conflicting. */\n\tconst replayedGoal = (\n\t\tgoalId: string,\n\t\towner: string,\n\t\ttoStatus: GoalStatusV1,\n\t\toperationId?: string,\n\t): GoalV1 | undefined => {\n\t\tif (!operationId) return undefined;\n\t\tconst applied = goalHistory(goalId, owner).some(\n\t\t\t(record) => record.toStatus === toStatus && record.operationId === operationId,\n\t\t);\n\t\treturn applied ? goalGet(goalId, owner) : undefined;\n\t};\n\n\tconst transitionGoal = (\n\t\tgoalId: string,\n\t\towner: string,\n\t\tfromStatus: GoalStatusV1 | null,\n\t\ttoStatus: GoalStatusV1,\n\t\tgoalOptions: {\n\t\t\treadonly evidence?: readonly TransitionEvidenceRefV1[];\n\t\t\treadonly payload?: { readonly title: string };\n\t\t\treadonly operationId?: string;\n\t\t},\n\t): GoalV1 => {\n\t\ttransitions.transition({\n\t\t\tdomain: \"goal\",\n\t\t\tentityId: goalId,\n\t\t\towner,\n\t\t\tfromStatus,\n\t\t\ttoStatus,\n\t\t\toperationId: goalOptions.operationId ?? `${toStatus}:${goalId}`,\n\t\t\tevidence: goalOptions.evidence,\n\t\t\tpayload: goalOptions.payload,\n\t\t});\n\t\tconst state = transitions.currentStatus(\"goal\", goalId);\n\t\treturn {\n\t\t\tgoalId,\n\t\t\towner,\n\t\t\ttitle: titleOf(goalId, owner),\n\t\t\tstatus: state?.status as GoalStatusV1,\n\t\t\tevidence: goalOptions.evidence ?? [],\n\t\t\t// v8 ignore next -- transition 刚写入 currentStatus,必可读到 revision\n\t\t\trevision: state?.revision ?? 0,\n\t\t};\n\t};\n\n\treturn {\n\t\tcreateGoal({ goalId, owner, title }) {\n\t\t\tif (title.trim().length === 0) throw new Error(t(\"Goal title must be a non-empty string\"));\n\t\t\treturn transitionGoal(goalId, owner, null, \"draft\", {\n\t\t\t\tpayload: { title },\n\t\t\t\toperationId: `create:${goalId}`,\n\t\t\t});\n\t\t},\n\t\tactivate(goalId, owner, activateOptions) {\n\t\t\tconst replayed = replayedGoal(goalId, owner, \"active\", activateOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\tconst existing = current(goalId, owner);\n\t\t\tif (existing?.status !== \"draft\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Goal {goalId} must be in draft status to activate (current: {status})\", {\n\t\t\t\t\t\tgoalId,\n\t\t\t\t\t\tstatus: existing?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn transitionGoal(goalId, owner, \"draft\", \"active\", { operationId: activateOptions?.operationId });\n\t\t},\n\t\tachieve(goalId, owner, evidence, achieveOptions) {\n\t\t\tconst replayed = replayedGoal(goalId, owner, \"achieved\", achieveOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\tconst existing = current(goalId, owner);\n\t\t\tif (existing?.status !== \"active\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Goal {goalId} must be active to achieve (current: {status})\", {\n\t\t\t\t\t\tgoalId,\n\t\t\t\t\t\tstatus: existing?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (evidence.length === 0) throw new Error(t(\"Achieving a goal requires at least one evidence reference\"));\n\t\t\treturn transitionGoal(goalId, owner, \"active\", \"achieved\", {\n\t\t\t\tevidence,\n\t\t\t\toperationId: achieveOptions?.operationId,\n\t\t\t});\n\t\t},\n\t\tarchive(goalId, owner) {\n\t\t\tconst existing = current(goalId, owner);\n\t\t\tif (!existing || existing.status === \"achieved\" || existing.status === \"archived\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Goal {goalId} cannot be archived from status {status}\", {\n\t\t\t\t\t\tgoalId,\n\t\t\t\t\t\tstatus: existing?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn transitionGoal(goalId, owner, existing.status, \"archived\", {});\n\t\t},\n\t\tget(goalId, owner) {\n\t\t\treturn goalGet(goalId, owner);\n\t\t},\n\t};\n}\n"]}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import type { TransitionEvidenceRefV1, TransitionStoreV1 } from "./state-store.ts";
|
|
2
|
-
export type PlanStatusV1 = "draft" | "active" | "completed" | "discarded";
|
|
3
|
-
export interface PlanStepV1 {
|
|
4
|
-
readonly stepId: string;
|
|
5
|
-
readonly title: string;
|
|
6
|
-
}
|
|
7
|
-
export interface PlanV1 {
|
|
8
|
-
readonly planId: string;
|
|
9
|
-
readonly owner: string;
|
|
10
|
-
readonly title: string;
|
|
11
|
-
readonly branch: string;
|
|
12
|
-
readonly steps: readonly PlanStepV1[];
|
|
13
|
-
readonly status: PlanStatusV1;
|
|
14
|
-
/** The latest revision explicitly linked while active (undefined before the first link). */
|
|
15
|
-
readonly revision?: number;
|
|
16
|
-
readonly evidence: readonly TransitionEvidenceRefV1[];
|
|
17
|
-
readonly revisionNo: number;
|
|
18
|
-
}
|
|
19
|
-
export interface PlanPluginV1 {
|
|
20
|
-
createPlan(input: {
|
|
21
|
-
readonly planId: string;
|
|
22
|
-
readonly owner: string;
|
|
23
|
-
readonly title: string;
|
|
24
|
-
readonly branch: string;
|
|
25
|
-
readonly steps: readonly PlanStepV1[];
|
|
26
|
-
}): PlanV1;
|
|
27
|
-
activate(planId: string, owner: string, options?: {
|
|
28
|
-
readonly operationId?: string;
|
|
29
|
-
}): PlanV1;
|
|
30
|
-
/** Records plan progress against a concrete revision of the bound branch. */
|
|
31
|
-
linkRevision(planId: string, owner: string, revision: number, options?: {
|
|
32
|
-
readonly operationId?: string;
|
|
33
|
-
}): PlanV1;
|
|
34
|
-
complete(planId: string, owner: string, evidence: readonly TransitionEvidenceRefV1[], options?: {
|
|
35
|
-
readonly atRevision?: number;
|
|
36
|
-
readonly operationId?: string;
|
|
37
|
-
}): PlanV1;
|
|
38
|
-
discard(planId: string, owner: string): PlanV1;
|
|
39
|
-
get(planId: string, owner: string): PlanV1 | undefined;
|
|
40
|
-
}
|
|
41
|
-
export declare function createPlanPlugin(options: {
|
|
42
|
-
readonly transitions: TransitionStoreV1;
|
|
43
|
-
}): PlanPluginV1;
|
|
44
|
-
//# sourceMappingURL=plan-plugin.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plan-plugin.d.ts","sourceRoot":"","sources":["../../src/profile/plan-plugin.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEnF,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;AAE1E,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,MAAM;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,4FAA4F;IAC5F,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,SAAS,uBAAuB,EAAE,CAAC;IACtD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC5B,UAAU,CAAC,KAAK,EAAE;QACjB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;KACtC,GAAG,MAAM,CAAC;IACX,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IAC7F,6EAA6E;IAC7E,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IACnH,QAAQ,CACP,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,SAAS,uBAAuB,EAAE,EAC5C,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GACvE,MAAM,CAAC;IACV,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/C,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACvD;AAiBD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAA;CAAE,GAAG,YAAY,CAyKnG","sourcesContent":["/**\n * Plan plugin (2.3c) — Plan semantics bound to a branch/revision over the\n * 2.3a transition store.\n *\n * Status graph: null → draft → active → completed, and draft/active →\n * discarded. A plan is created with its step list and bound to a code branch;\n * while active, `linkRevision` records plan progress against concrete\n * revisions, and `complete` requires evidence plus the final revision. The\n * plugin holds NO shadow state: status, revision, steps, branch, and the\n * latest linked revision are all derived from the transition history, so\n * recovery is exactly a store replay.\n */\nimport type { JsonValue } from \"@agent-forge/ai\";\nimport { t } from \"../core/i18n/index.ts\";\nimport type { TransitionEvidenceRefV1, TransitionStoreV1 } from \"./state-store.ts\";\n\nexport type PlanStatusV1 = \"draft\" | \"active\" | \"completed\" | \"discarded\";\n\nexport interface PlanStepV1 {\n\treadonly stepId: string;\n\treadonly title: string;\n}\n\nexport interface PlanV1 {\n\treadonly planId: string;\n\treadonly owner: string;\n\treadonly title: string;\n\treadonly branch: string;\n\treadonly steps: readonly PlanStepV1[];\n\treadonly status: PlanStatusV1;\n\t/** The latest revision explicitly linked while active (undefined before the first link). */\n\treadonly revision?: number;\n\treadonly evidence: readonly TransitionEvidenceRefV1[];\n\treadonly revisionNo: number;\n}\n\nexport interface PlanPluginV1 {\n\tcreatePlan(input: {\n\t\treadonly planId: string;\n\t\treadonly owner: string;\n\t\treadonly title: string;\n\t\treadonly branch: string;\n\t\treadonly steps: readonly PlanStepV1[];\n\t}): PlanV1;\n\tactivate(planId: string, owner: string, options?: { readonly operationId?: string }): PlanV1;\n\t/** Records plan progress against a concrete revision of the bound branch. */\n\tlinkRevision(planId: string, owner: string, revision: number, options?: { readonly operationId?: string }): PlanV1;\n\tcomplete(\n\t\tplanId: string,\n\t\towner: string,\n\t\tevidence: readonly TransitionEvidenceRefV1[],\n\t\toptions?: { readonly atRevision?: number; readonly operationId?: string },\n\t): PlanV1;\n\tdiscard(planId: string, owner: string): PlanV1;\n\tget(planId: string, owner: string): PlanV1 | undefined;\n}\n\ninterface PlanPayloadV1 {\n\treadonly title: string;\n\treadonly branch: string;\n\treadonly steps: readonly PlanStepV1[];\n\treadonly linkedRevision?: number;\n}\n\nfunction planPayloadOf(record: { readonly payload?: unknown }): Partial<PlanPayloadV1> | undefined {\n\tconst payload = record.payload;\n\tif (payload !== null && typeof payload === \"object\" && !Array.isArray(payload)) {\n\t\treturn payload as Partial<PlanPayloadV1>;\n\t}\n\treturn undefined;\n}\n\nexport function createPlanPlugin(options: { readonly transitions: TransitionStoreV1 }): PlanPluginV1 {\n\tconst transitions = options.transitions;\n\n\tconst planHistory = (planId: string, owner: string) =>\n\t\ttransitions.history(planId).filter((record) => record.domain === \"plan\" && record.owner === owner);\n\n\tconst current = (planId: string, owner: string): { status: PlanStatusV1; revisionNo: number } | undefined => {\n\t\tconst state = transitions.currentStatus(\"plan\", planId);\n\t\tif (state === undefined || planHistory(planId, owner).length === 0) return undefined;\n\t\treturn { status: state.status as PlanStatusV1, revisionNo: state.revision };\n\t};\n\n\tconst planGet = (planId: string, owner: string): PlanV1 | undefined => {\n\t\tconst state = current(planId, owner);\n\t\tif (!state) return undefined;\n\t\tconst history = planHistory(planId, owner);\n\t\t// v8 ignore next -- 因果校验保证每条 plan 历史都以 fromStatus=null 的创建记录开始\n\t\tconst createPayload = planPayloadOf(history.find((record) => record.fromStatus === null) ?? {});\n\t\tconst lastLinked = [...history]\n\t\t\t.reverse()\n\t\t\t.map((record) => planPayloadOf(record)?.linkedRevision)\n\t\t\t.find((revision): revision is number => typeof revision === \"number\");\n\t\tconst lastEvidence = [...history].reverse().find((record) => record.evidence.length > 0)?.evidence ?? [];\n\t\treturn {\n\t\t\tplanId,\n\t\t\towner,\n\t\t\ttitle: createPayload?.title ?? planId,\n\t\t\tbranch: createPayload?.branch ?? \"\",\n\t\t\tsteps: createPayload?.steps ?? [],\n\t\t\tstatus: state.status,\n\t\t\t...(lastLinked === undefined ? {} : { revision: lastLinked }),\n\t\t\tevidence: lastEvidence,\n\t\t\trevisionNo: state.revisionNo,\n\t\t};\n\t};\n\n\t/** A retried transition with an already-applied operationId returns the existing state instead of conflicting. */\n\tconst replayedPlan = (\n\t\tplanId: string,\n\t\towner: string,\n\t\ttoStatus: PlanStatusV1,\n\t\toperationId?: string,\n\t): PlanV1 | undefined => {\n\t\tif (!operationId) return undefined;\n\t\tconst applied = planHistory(planId, owner).some(\n\t\t\t(record) => record.toStatus === toStatus && record.operationId === operationId,\n\t\t);\n\t\treturn applied ? planGet(planId, owner) : undefined;\n\t};\n\n\tconst transitionPlan = (\n\t\tplanId: string,\n\t\towner: string,\n\t\tfromStatus: PlanStatusV1 | null,\n\t\ttoStatus: PlanStatusV1,\n\t\tplanOptions: {\n\t\t\treadonly evidence?: readonly TransitionEvidenceRefV1[];\n\t\t\treadonly payload?: PlanPayloadV1;\n\t\t\treadonly operationId?: string;\n\t\t},\n\t): PlanV1 => {\n\t\ttransitions.transition({\n\t\t\tdomain: \"plan\",\n\t\t\tentityId: planId,\n\t\t\towner,\n\t\t\tfromStatus,\n\t\t\ttoStatus,\n\t\t\toperationId: planOptions.operationId ?? `${toStatus}:${planId}`,\n\t\t\tevidence: planOptions.evidence,\n\t\t\tpayload: planOptions.payload as JsonValue | undefined,\n\t\t});\n\t\treturn planGet(planId, owner)!;\n\t};\n\n\treturn {\n\t\tcreatePlan({ planId, owner, title, branch, steps }) {\n\t\t\tif (title.trim().length === 0) throw new Error(t(\"Plan title must be a non-empty string\"));\n\t\t\tif (branch.trim().length === 0) throw new Error(t(\"Plan branch must be a non-empty string\"));\n\t\t\tif (steps.length === 0) throw new Error(t(\"Plan requires at least one step\"));\n\t\t\tconst stepIds = new Set<string>();\n\t\t\tfor (const step of steps) {\n\t\t\t\tif (typeof step.stepId !== \"string\" || step.stepId.trim().length === 0) {\n\t\t\t\t\tthrow new Error(t(\"Plan stepId must be a non-empty string\"));\n\t\t\t\t}\n\t\t\t\tif (typeof step.title !== \"string\" || step.title.trim().length === 0) {\n\t\t\t\t\tthrow new Error(t(\"Plan step title must be a non-empty string\"));\n\t\t\t\t}\n\t\t\t\tif (stepIds.has(step.stepId))\n\t\t\t\t\tthrow new Error(t(\"Duplicate plan stepId: {stepId}\", { stepId: step.stepId }));\n\t\t\t\tstepIds.add(step.stepId);\n\t\t\t}\n\t\t\treturn transitionPlan(planId, owner, null, \"draft\", {\n\t\t\t\tpayload: { title, branch, steps: [...steps] },\n\t\t\t\toperationId: `create:${planId}`,\n\t\t\t});\n\t\t},\n\t\tactivate(planId, owner, activateOptions) {\n\t\t\tconst replayed = replayedPlan(planId, owner, \"active\", activateOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\tconst plan = planGet(planId, owner);\n\t\t\tif (plan?.status !== \"draft\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Plan {planId} must be in draft status to activate (current: {status})\", {\n\t\t\t\t\t\tplanId,\n\t\t\t\t\t\tstatus: plan?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn transitionPlan(planId, owner, \"draft\", \"active\", { operationId: activateOptions?.operationId });\n\t\t},\n\t\tlinkRevision(planId, owner, revision, linkOptions) {\n\t\t\tconst replayed = replayedPlan(planId, owner, \"active\", linkOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\tconst plan = planGet(planId, owner);\n\t\t\tif (plan?.status !== \"active\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Plan {planId} must be active to link a revision (current: {status})\", {\n\t\t\t\t\t\tplanId,\n\t\t\t\t\t\tstatus: plan?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!Number.isSafeInteger(revision) || revision < 1) {\n\t\t\t\tthrow new Error(t(\"Plan revision must be a positive safe integer, got {revision}\", { revision }));\n\t\t\t}\n\t\t\treturn transitionPlan(planId, owner, \"active\", \"active\", {\n\t\t\t\tpayload: { title: plan.title, branch: plan.branch, steps: plan.steps, linkedRevision: revision },\n\t\t\t\toperationId: linkOptions?.operationId ?? `link:${planId}:${revision}`,\n\t\t\t});\n\t\t},\n\t\tcomplete(planId, owner, evidence, completeOptions) {\n\t\t\tconst replayed = replayedPlan(planId, owner, \"completed\", completeOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\tconst plan = planGet(planId, owner);\n\t\t\tif (plan?.status !== \"active\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Plan {planId} must be active to complete (current: {status})\", {\n\t\t\t\t\t\tplanId,\n\t\t\t\t\t\tstatus: plan?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (evidence.length === 0) throw new Error(t(\"Completing a plan requires at least one evidence reference\"));\n\t\t\tconst target = completeOptions?.atRevision ?? plan.revision;\n\t\t\tif (typeof target !== \"number\") {\n\t\t\t\tthrow new Error(t(\"Plan {planId} requires atRevision or a linked revision to complete\", { planId }));\n\t\t\t}\n\t\t\treturn transitionPlan(planId, owner, \"active\", \"completed\", {\n\t\t\t\tevidence,\n\t\t\t\tpayload: { title: plan.title, branch: plan.branch, steps: plan.steps, linkedRevision: target },\n\t\t\t\toperationId: completeOptions?.operationId,\n\t\t\t});\n\t\t},\n\t\tdiscard(planId, owner) {\n\t\t\tconst plan = planGet(planId, owner);\n\t\t\tif (!plan || plan.status === \"completed\" || plan.status === \"discarded\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Plan {planId} cannot be discarded from status {status}\", {\n\t\t\t\t\t\tplanId,\n\t\t\t\t\t\tstatus: plan?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn transitionPlan(planId, owner, plan.status, \"discarded\", {});\n\t\t},\n\t\tget(planId, owner) {\n\t\t\treturn planGet(planId, owner);\n\t\t},\n\t};\n}\n"]}
|