@caupulican/pi-adaptative 0.81.37 → 0.81.39
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 +91 -0
- package/README.md +1 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/README.md +18 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts +131 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts.map +1 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js +196 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js.map +1 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.ts +308 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts +22 -2
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts.map +1 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.js +585 -24
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.js.map +1 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.ts +749 -27
- package/dist/bundled-resources/runtimes/pi-shell-engine/commands/__init__.py +43 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/commands/fs.py +270 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/commands/search.py +252 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/commands/strings.py +399 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/commands/text.py +575 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/context.py +52 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/errors.py +49 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/exec.py +734 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/expand.py +238 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/main.py +132 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/nodes.py +116 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/parser.py +287 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/proc.py +137 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/state.py +100 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/tokens.py +579 -0
- package/dist/bundled-resources/skills/tool-call-repair/SKILL.md +19 -9
- package/dist/bundled-resources/skills/tool-call-repair/references/failure-grammar.md +22 -5
- package/dist/bundled-resources/skills/tool-call-repair/references/repair-catalogue.md +5 -5
- package/dist/bundled-resources/skills/tool-call-repair/references/text-protocol-grammar.md +28 -7
- package/dist/cli/args.d.ts +3 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +15 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-paths.d.ts +49 -0
- package/dist/core/agent-paths.d.ts.map +1 -0
- package/dist/core/agent-paths.js +107 -0
- package/dist/core/agent-paths.js.map +1 -0
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +3 -3
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +234 -17
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +484 -62
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/autonomy/contracts.d.ts +9 -0
- package/dist/core/autonomy/contracts.d.ts.map +1 -1
- package/dist/core/autonomy/contracts.js.map +1 -1
- package/dist/core/autonomy/lane-tracker.d.ts +10 -1
- package/dist/core/autonomy/lane-tracker.d.ts.map +1 -1
- package/dist/core/autonomy/lane-tracker.js +5 -1
- package/dist/core/autonomy/lane-tracker.js.map +1 -1
- package/dist/core/background-lane-controller.d.ts +122 -6
- package/dist/core/background-lane-controller.d.ts.map +1 -1
- package/dist/core/background-lane-controller.js +447 -90
- package/dist/core/background-lane-controller.js.map +1 -1
- package/dist/core/bash-execution-controller.d.ts +4 -0
- package/dist/core/bash-execution-controller.d.ts.map +1 -1
- package/dist/core/bash-execution-controller.js +7 -1
- package/dist/core/bash-execution-controller.js.map +1 -1
- package/dist/core/compaction-support.d.ts +13 -3
- package/dist/core/compaction-support.d.ts.map +1 -1
- package/dist/core/compaction-support.js +43 -7
- package/dist/core/compaction-support.js.map +1 -1
- package/dist/core/context/context-audit.d.ts +33 -1
- package/dist/core/context/context-audit.d.ts.map +1 -1
- package/dist/core/context/context-audit.js +31 -5
- package/dist/core/context/context-audit.js.map +1 -1
- package/dist/core/context/sqlite-runtime-index.d.ts.map +1 -1
- package/dist/core/context/sqlite-runtime-index.js +13 -7
- package/dist/core/context/sqlite-runtime-index.js.map +1 -1
- package/dist/core/context-gc.d.ts.map +1 -1
- package/dist/core/context-gc.js +16 -1
- package/dist/core/context-gc.js.map +1 -1
- package/dist/core/context-pipeline.d.ts +26 -4
- package/dist/core/context-pipeline.d.ts.map +1 -1
- package/dist/core/context-pipeline.js +137 -14
- package/dist/core/context-pipeline.js.map +1 -1
- package/dist/core/cost-guard.d.ts +19 -3
- package/dist/core/cost-guard.d.ts.map +1 -1
- package/dist/core/cost-guard.js +18 -3
- package/dist/core/cost-guard.js.map +1 -1
- package/dist/core/delegation/session-worker-result.d.ts +34 -4
- package/dist/core/delegation/session-worker-result.d.ts.map +1 -1
- package/dist/core/delegation/session-worker-result.js +64 -4
- package/dist/core/delegation/session-worker-result.js.map +1 -1
- package/dist/core/delegation/worker-actions.d.ts.map +1 -1
- package/dist/core/delegation/worker-actions.js +1 -1
- package/dist/core/delegation/worker-actions.js.map +1 -1
- package/dist/core/delegation/worker-result.d.ts +42 -1
- package/dist/core/delegation/worker-result.d.ts.map +1 -1
- package/dist/core/delegation/worker-result.js +68 -0
- package/dist/core/delegation/worker-result.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +23 -7
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +1 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +51 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/goal-loop-controller.d.ts +17 -1
- package/dist/core/goal-loop-controller.d.ts.map +1 -1
- package/dist/core/goal-loop-controller.js +79 -11
- package/dist/core/goal-loop-controller.js.map +1 -1
- package/dist/core/goals/goal-continuation-controller.d.ts +48 -2
- package/dist/core/goals/goal-continuation-controller.d.ts.map +1 -1
- package/dist/core/goals/goal-continuation-controller.js +77 -0
- package/dist/core/goals/goal-continuation-controller.js.map +1 -1
- package/dist/core/goals/goal-continuation-defaults.d.ts +39 -0
- package/dist/core/goals/goal-continuation-defaults.d.ts.map +1 -1
- package/dist/core/goals/goal-continuation-defaults.js +42 -0
- package/dist/core/goals/goal-continuation-defaults.js.map +1 -1
- package/dist/core/goals/goal-continuation-prompt.d.ts +4 -0
- package/dist/core/goals/goal-continuation-prompt.d.ts.map +1 -1
- package/dist/core/goals/goal-continuation-prompt.js +51 -10
- package/dist/core/goals/goal-continuation-prompt.js.map +1 -1
- package/dist/core/goals/goal-runtime-snapshot.d.ts +101 -2
- package/dist/core/goals/goal-runtime-snapshot.d.ts.map +1 -1
- package/dist/core/goals/goal-runtime-snapshot.js +87 -4
- package/dist/core/goals/goal-runtime-snapshot.js.map +1 -1
- package/dist/core/goals/goal-state.d.ts +89 -1
- package/dist/core/goals/goal-state.d.ts.map +1 -1
- package/dist/core/goals/goal-state.js +71 -5
- package/dist/core/goals/goal-state.js.map +1 -1
- package/dist/core/goals/goal-tool-core.d.ts +56 -2
- package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
- package/dist/core/goals/goal-tool-core.js +111 -5
- package/dist/core/goals/goal-tool-core.js.map +1 -1
- package/dist/core/goals/session-goal-state.d.ts +11 -2
- package/dist/core/goals/session-goal-state.d.ts.map +1 -1
- package/dist/core/goals/session-goal-state.js +32 -17
- package/dist/core/goals/session-goal-state.js.map +1 -1
- package/dist/core/keybindings.d.ts +10 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +10 -2
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/learning/observation-store.d.ts +12 -3
- package/dist/core/learning/observation-store.d.ts.map +1 -1
- package/dist/core/learning/observation-store.js +30 -15
- package/dist/core/learning/observation-store.js.map +1 -1
- package/dist/core/learning/skill-curator.d.ts +5 -1
- package/dist/core/learning/skill-curator.d.ts.map +1 -1
- package/dist/core/learning/skill-curator.js +21 -19
- package/dist/core/learning/skill-curator.js.map +1 -1
- package/dist/core/local-runtime-controller.d.ts +65 -3
- package/dist/core/local-runtime-controller.d.ts.map +1 -1
- package/dist/core/local-runtime-controller.js +186 -26
- package/dist/core/local-runtime-controller.js.map +1 -1
- package/dist/core/memory/providers/file-store.d.ts +1 -1
- package/dist/core/memory/providers/file-store.d.ts.map +1 -1
- package/dist/core/memory/providers/file-store.js +6 -6
- package/dist/core/memory/providers/file-store.js.map +1 -1
- package/dist/core/model-capability.d.ts +34 -0
- package/dist/core/model-capability.d.ts.map +1 -1
- package/dist/core/model-capability.js +42 -1
- package/dist/core/model-capability.js.map +1 -1
- package/dist/core/model-router/tool-escalation.d.ts +15 -0
- package/dist/core/model-router/tool-escalation.d.ts.map +1 -1
- package/dist/core/model-router/tool-escalation.js +23 -1
- package/dist/core/model-router/tool-escalation.js.map +1 -1
- package/dist/core/model-router-controller.d.ts +34 -7
- package/dist/core/model-router-controller.d.ts.map +1 -1
- package/dist/core/model-router-controller.js +95 -16
- package/dist/core/model-router-controller.js.map +1 -1
- package/dist/core/models/adaptation-store.d.ts +7 -0
- package/dist/core/models/adaptation-store.d.ts.map +1 -1
- package/dist/core/models/adaptation-store.js +47 -11
- package/dist/core/models/adaptation-store.js.map +1 -1
- package/dist/core/models/default-model-suggestions.d.ts.map +1 -1
- package/dist/core/models/default-model-suggestions.js +17 -0
- package/dist/core/models/default-model-suggestions.js.map +1 -1
- package/dist/core/models/fitness-store.d.ts +3 -0
- package/dist/core/models/fitness-store.d.ts.map +1 -1
- package/dist/core/models/fitness-store.js +11 -2
- package/dist/core/models/fitness-store.js.map +1 -1
- package/dist/core/models/llamacpp-runtime.d.ts +180 -0
- package/dist/core/models/llamacpp-runtime.d.ts.map +1 -0
- package/dist/core/models/llamacpp-runtime.js +475 -0
- package/dist/core/models/llamacpp-runtime.js.map +1 -0
- package/dist/core/models/local-registration.d.ts +40 -0
- package/dist/core/models/local-registration.d.ts.map +1 -1
- package/dist/core/models/local-registration.js +94 -5
- package/dist/core/models/local-registration.js.map +1 -1
- package/dist/core/models/local-runtime.d.ts.map +1 -1
- package/dist/core/models/local-runtime.js +9 -7
- package/dist/core/models/local-runtime.js.map +1 -1
- package/dist/core/models/model-ref.d.ts +7 -0
- package/dist/core/models/model-ref.d.ts.map +1 -1
- package/dist/core/models/model-ref.js +26 -0
- package/dist/core/models/model-ref.js.map +1 -1
- package/dist/core/models/needle-runtime.d.ts +257 -0
- package/dist/core/models/needle-runtime.d.ts.map +1 -0
- package/dist/core/models/needle-runtime.js +519 -0
- package/dist/core/models/needle-runtime.js.map +1 -0
- package/dist/core/models/prism-llamacpp-lifecycle.d.ts +89 -0
- package/dist/core/models/prism-llamacpp-lifecycle.d.ts.map +1 -0
- package/dist/core/models/prism-llamacpp-lifecycle.js +121 -0
- package/dist/core/models/prism-llamacpp-lifecycle.js.map +1 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +11 -10
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/process-matrix/codes.d.ts +72 -0
- package/dist/core/process-matrix/codes.d.ts.map +1 -0
- package/dist/core/process-matrix/codes.js +15 -0
- package/dist/core/process-matrix/codes.js.map +1 -0
- package/dist/core/process-matrix/runtime.d.ts +63 -0
- package/dist/core/process-matrix/runtime.d.ts.map +1 -0
- package/dist/core/process-matrix/runtime.js +310 -0
- package/dist/core/process-matrix/runtime.js.map +1 -0
- package/dist/core/process-matrix/store.d.ts +22 -0
- package/dist/core/process-matrix/store.d.ts.map +1 -0
- package/dist/core/process-matrix/store.js +80 -0
- package/dist/core/process-matrix/store.js.map +1 -0
- package/dist/core/process-matrix/supervisor.d.ts +72 -0
- package/dist/core/process-matrix/supervisor.d.ts.map +1 -0
- package/dist/core/process-matrix/supervisor.js +130 -0
- package/dist/core/process-matrix/supervisor.js.map +1 -0
- package/dist/core/profile-registry.d.ts +7 -0
- package/dist/core/profile-registry.d.ts.map +1 -1
- package/dist/core/profile-registry.js +20 -0
- package/dist/core/profile-registry.js.map +1 -1
- package/dist/core/python-runtime.d.ts.map +1 -1
- package/dist/core/python-runtime.js +3 -3
- package/dist/core/python-runtime.js.map +1 -1
- package/dist/core/reflection-controller.d.ts +29 -5
- package/dist/core/reflection-controller.d.ts.map +1 -1
- package/dist/core/reflection-controller.js +215 -126
- package/dist/core/reflection-controller.js.map +1 -1
- package/dist/core/reload-blockers.d.ts +36 -0
- package/dist/core/reload-blockers.d.ts.map +1 -1
- package/dist/core/reload-blockers.js +44 -0
- package/dist/core/reload-blockers.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +8 -7
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/runtime-builder.d.ts +58 -5
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +209 -25
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/scout-controller.d.ts +6 -0
- package/dist/core/scout-controller.d.ts.map +1 -1
- package/dist/core/scout-controller.js +66 -52
- package/dist/core/scout-controller.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +3 -3
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-role.d.ts +31 -0
- package/dist/core/session-role.d.ts.map +1 -0
- package/dist/core/session-role.js +52 -0
- package/dist/core/session-role.js.map +1 -0
- package/dist/core/settings-manager.d.ts +42 -3
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +94 -60
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt-builder.d.ts +12 -0
- package/dist/core/system-prompt-builder.d.ts.map +1 -1
- package/dist/core/system-prompt-builder.js +6 -0
- package/dist/core/system-prompt-builder.js.map +1 -1
- package/dist/core/system-prompt.d.ts +14 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +20 -3
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tasks/session-task-state.d.ts +11 -2
- package/dist/core/tasks/session-task-state.d.ts.map +1 -1
- package/dist/core/tasks/session-task-state.js +27 -11
- package/dist/core/tasks/session-task-state.js.map +1 -1
- package/dist/core/tasks/task-contract-monitor.d.ts +45 -0
- package/dist/core/tasks/task-contract-monitor.d.ts.map +1 -0
- package/dist/core/tasks/task-contract-monitor.js +56 -0
- package/dist/core/tasks/task-contract-monitor.js.map +1 -0
- package/dist/core/tasks/task-state.d.ts +8 -0
- package/dist/core/tasks/task-state.d.ts.map +1 -1
- package/dist/core/tasks/task-state.js +28 -1
- package/dist/core/tasks/task-state.js.map +1 -1
- package/dist/core/tool-gate-controller.d.ts.map +1 -1
- package/dist/core/tool-gate-controller.js +5 -0
- package/dist/core/tool-gate-controller.js.map +1 -1
- package/dist/core/tool-recovery-log-records.d.ts +7 -0
- package/dist/core/tool-recovery-log-records.d.ts.map +1 -1
- package/dist/core/tool-recovery-log-records.js +14 -6
- package/dist/core/tool-recovery-log-records.js.map +1 -1
- package/dist/core/tool-selection/promotion.d.ts +54 -0
- package/dist/core/tool-selection/promotion.d.ts.map +1 -0
- package/dist/core/tool-selection/promotion.js +81 -0
- package/dist/core/tool-selection/promotion.js.map +1 -0
- package/dist/core/tool-selection/tool-performance-store.d.ts +37 -0
- package/dist/core/tool-selection/tool-performance-store.d.ts.map +1 -1
- package/dist/core/tool-selection/tool-performance-store.js +87 -3
- package/dist/core/tool-selection/tool-performance-store.js.map +1 -1
- package/dist/core/tool-selection/tool-selection-controller.d.ts +45 -0
- package/dist/core/tool-selection/tool-selection-controller.d.ts.map +1 -1
- package/dist/core/tool-selection/tool-selection-controller.js +96 -0
- package/dist/core/tool-selection/tool-selection-controller.js.map +1 -1
- package/dist/core/tools/bash.d.ts +18 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +97 -18
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/delegate-status.d.ts +14 -0
- package/dist/core/tools/delegate-status.d.ts.map +1 -1
- package/dist/core/tools/delegate-status.js +82 -7
- package/dist/core/tools/delegate-status.js.map +1 -1
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +25 -8
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +52 -44
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/goal.d.ts +94 -3
- package/dist/core/tools/goal.d.ts.map +1 -1
- package/dist/core/tools/goal.js +165 -15
- package/dist/core/tools/goal.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +5 -4
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/model-fitness.d.ts +7 -0
- package/dist/core/tools/model-fitness.d.ts.map +1 -1
- package/dist/core/tools/model-fitness.js +2 -2
- package/dist/core/tools/model-fitness.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +1 -1
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/shell-contract-router.d.ts +6 -1
- package/dist/core/tools/shell-contract-router.d.ts.map +1 -1
- package/dist/core/tools/shell-contract-router.js +69 -13
- package/dist/core/tools/shell-contract-router.js.map +1 -1
- package/dist/core/tools/shell-session.d.ts +89 -0
- package/dist/core/tools/shell-session.d.ts.map +1 -0
- package/dist/core/tools/shell-session.js +432 -0
- package/dist/core/tools/shell-session.js.map +1 -0
- package/dist/core/tools/task-steps.d.ts +4 -0
- package/dist/core/tools/task-steps.d.ts.map +1 -1
- package/dist/core/tools/task-steps.js +63 -8
- package/dist/core/tools/task-steps.js.map +1 -1
- package/dist/core/tools/tmux-dispatch.d.ts +86 -0
- package/dist/core/tools/tmux-dispatch.d.ts.map +1 -0
- package/dist/core/tools/tmux-dispatch.js +91 -0
- package/dist/core/tools/tmux-dispatch.js.map +1 -0
- package/dist/core/tools/windows-shell-engine.d.ts +42 -0
- package/dist/core/tools/windows-shell-engine.d.ts.map +1 -0
- package/dist/core/tools/windows-shell-engine.js +153 -0
- package/dist/core/tools/windows-shell-engine.js.map +1 -0
- package/dist/core/tools/windows-shell-state.d.ts +40 -0
- package/dist/core/tools/windows-shell-state.d.ts.map +1 -0
- package/dist/core/tools/windows-shell-state.js +59 -0
- package/dist/core/tools/windows-shell-state.js.map +1 -0
- package/dist/core/tools/worktree-sync.d.ts +24 -0
- package/dist/core/tools/worktree-sync.d.ts.map +1 -0
- package/dist/core/tools/worktree-sync.js +338 -0
- package/dist/core/tools/worktree-sync.js.map +1 -0
- package/dist/core/trust-manager.d.ts +4 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +20 -2
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/util/atomic-file.d.ts +55 -0
- package/dist/core/util/atomic-file.d.ts.map +1 -0
- package/dist/core/util/atomic-file.js +255 -0
- package/dist/core/util/atomic-file.js.map +1 -0
- package/dist/core/util/minimatch-cache.d.ts +33 -0
- package/dist/core/util/minimatch-cache.d.ts.map +1 -0
- package/dist/core/util/minimatch-cache.js +0 -0
- package/dist/core/util/minimatch-cache.js.map +1 -0
- package/dist/core/worktree-sync/codes.d.ts +227 -0
- package/dist/core/worktree-sync/codes.d.ts.map +1 -0
- package/dist/core/worktree-sync/codes.js +14 -0
- package/dist/core/worktree-sync/codes.js.map +1 -0
- package/dist/core/worktree-sync/git-engine.d.ts +156 -0
- package/dist/core/worktree-sync/git-engine.d.ts.map +1 -0
- package/dist/core/worktree-sync/git-engine.js +1191 -0
- package/dist/core/worktree-sync/git-engine.js.map +1 -0
- package/dist/core/worktree-sync/lane-gate.d.ts +75 -0
- package/dist/core/worktree-sync/lane-gate.d.ts.map +1 -0
- package/dist/core/worktree-sync/lane-gate.js +360 -0
- package/dist/core/worktree-sync/lane-gate.js.map +1 -0
- package/dist/core/worktree-sync/runtime.d.ts +47 -0
- package/dist/core/worktree-sync/runtime.d.ts.map +1 -0
- package/dist/core/worktree-sync/runtime.js +96 -0
- package/dist/core/worktree-sync/runtime.js.map +1 -0
- package/dist/core/worktree-sync/store.d.ts +69 -0
- package/dist/core/worktree-sync/store.d.ts.map +1 -0
- package/dist/core/worktree-sync/store.js +247 -0
- package/dist/core/worktree-sync/store.js.map +1 -0
- package/dist/core/worktree-sync/watcher.d.ts +29 -0
- package/dist/core/worktree-sync/watcher.d.ts.map +1 -0
- package/dist/core/worktree-sync/watcher.js +93 -0
- package/dist/core/worktree-sync/watcher.js.map +1 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +94 -0
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts +9 -0
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +38 -0
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/auto-learn-controller.d.ts +16 -1
- package/dist/modes/interactive/auto-learn-controller.d.ts.map +1 -1
- package/dist/modes/interactive/auto-learn-controller.js +50 -8
- package/dist/modes/interactive/auto-learn-controller.js.map +1 -1
- package/dist/modes/interactive/components/profile-resource-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/profile-resource-editor.js +23 -1
- package/dist/modes/interactive/components/profile-resource-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +4 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/local-model-commands.d.ts +43 -0
- package/dist/modes/interactive/local-model-commands.d.ts.map +1 -1
- package/dist/modes/interactive/local-model-commands.js +290 -3
- package/dist/modes/interactive/local-model-commands.js.map +1 -1
- package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -1
- package/dist/modes/interactive/session-flow-commands.js +24 -4
- package/dist/modes/interactive/session-flow-commands.js.map +1 -1
- package/dist/utils/fs-watch.d.ts +11 -0
- package/dist/utils/fs-watch.d.ts.map +1 -1
- package/dist/utils/fs-watch.js +20 -2
- package/dist/utils/fs-watch.js.map +1 -1
- package/dist/utils/highlight-js-languages.d.ts +4 -0
- package/dist/utils/highlight-js-languages.d.ts.map +1 -0
- package/dist/utils/highlight-js-languages.js +573 -0
- package/dist/utils/highlight-js-languages.js.map +1 -0
- package/dist/utils/shell.d.ts +7 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +39 -9
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +53 -5
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +112 -1
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/development.md +2 -0
- package/docs/packages.md +1 -1
- package/docs/process-matrix.md +120 -0
- package/docs/settings.md +5 -2
- package/docs/tmux-agent-manager.md +85 -2
- package/docs/windows.md +52 -3
- package/docs/work-directory.md +29 -0
- package/docs/worktree-sync.md +250 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +10 -4
- package/docs/integration-sweep-builder-blueprint-2026-07-09.md +0 -365
- package/docs/integration-sweep-resume-2026-07-09.md +0 -407
|
@@ -14,11 +14,22 @@ function isRequirementStatus(value) {
|
|
|
14
14
|
return value === "open" || value === "satisfied" || value === "blocked";
|
|
15
15
|
}
|
|
16
16
|
function isGoalEvidenceKind(value) {
|
|
17
|
-
return value === "file" ||
|
|
17
|
+
return (value === "file" ||
|
|
18
|
+
value === "test" ||
|
|
19
|
+
value === "tool" ||
|
|
20
|
+
value === "user" ||
|
|
21
|
+
value === "finding" ||
|
|
22
|
+
value === "worker");
|
|
18
23
|
}
|
|
19
24
|
function hasOptionalString(record, key) {
|
|
20
25
|
return record[key] === undefined || typeof record[key] === "string";
|
|
21
26
|
}
|
|
27
|
+
function hasOptionalBoolean(record, key) {
|
|
28
|
+
return record[key] === undefined || typeof record[key] === "boolean";
|
|
29
|
+
}
|
|
30
|
+
function hasOptionalFiniteNumber(record, key) {
|
|
31
|
+
return record[key] === undefined || (typeof record[key] === "number" && Number.isFinite(record[key]));
|
|
32
|
+
}
|
|
22
33
|
function isRequirement(value) {
|
|
23
34
|
if (!isRecord(value))
|
|
24
35
|
return false;
|
|
@@ -28,7 +39,9 @@ function isRequirement(value) {
|
|
|
28
39
|
isStringArray(value.evidenceIds) &&
|
|
29
40
|
typeof value.createdAt === "string" &&
|
|
30
41
|
typeof value.updatedAt === "string" &&
|
|
31
|
-
hasOptionalString(value, "blockedReason")
|
|
42
|
+
hasOptionalString(value, "blockedReason") &&
|
|
43
|
+
hasOptionalString(value, "boundLaneId") &&
|
|
44
|
+
hasOptionalString(value, "boundAt"));
|
|
32
45
|
}
|
|
33
46
|
function isGoalEvidenceRef(value) {
|
|
34
47
|
if (!isRecord(value))
|
|
@@ -37,7 +50,8 @@ function isGoalEvidenceRef(value) {
|
|
|
37
50
|
isGoalEvidenceKind(value.kind) &&
|
|
38
51
|
typeof value.summary === "string" &&
|
|
39
52
|
typeof value.createdAt === "string" &&
|
|
40
|
-
hasOptionalString(value, "uri")
|
|
53
|
+
hasOptionalString(value, "uri") &&
|
|
54
|
+
hasOptionalBoolean(value, "verified"));
|
|
41
55
|
}
|
|
42
56
|
function isGoalEvent(value) {
|
|
43
57
|
if (!isRecord(value) || typeof value.type !== "string" || typeof value.now !== "string")
|
|
@@ -51,11 +65,14 @@ function isGoalEvent(value) {
|
|
|
51
65
|
return typeof value.id === "string" && typeof value.blockedReason === "string";
|
|
52
66
|
case "reopen_requirement":
|
|
53
67
|
return typeof value.id === "string";
|
|
68
|
+
case "dispatch_worker":
|
|
69
|
+
return (typeof value.id === "string" && typeof value.instructions === "string" && hasOptionalString(value, "laneId"));
|
|
54
70
|
case "add_evidence":
|
|
55
71
|
return (typeof value.id === "string" &&
|
|
56
72
|
isGoalEvidenceKind(value.kind) &&
|
|
57
73
|
typeof value.summary === "string" &&
|
|
58
|
-
hasOptionalString(value, "uri")
|
|
74
|
+
hasOptionalString(value, "uri") &&
|
|
75
|
+
hasOptionalBoolean(value, "verified"));
|
|
59
76
|
case "progress":
|
|
60
77
|
case "no_progress":
|
|
61
78
|
case "complete_goal":
|
|
@@ -65,6 +82,13 @@ function isGoalEvent(value) {
|
|
|
65
82
|
return true;
|
|
66
83
|
case "block_goal":
|
|
67
84
|
return typeof value.reason === "string";
|
|
85
|
+
case "record_continuation_budget":
|
|
86
|
+
return (typeof value.turns === "number" &&
|
|
87
|
+
Number.isFinite(value.turns) &&
|
|
88
|
+
typeof value.wallClockMs === "number" &&
|
|
89
|
+
Number.isFinite(value.wallClockMs) &&
|
|
90
|
+
typeof value.sessionCostUsd === "number" &&
|
|
91
|
+
Number.isFinite(value.sessionCostUsd));
|
|
68
92
|
default:
|
|
69
93
|
return false;
|
|
70
94
|
}
|
|
@@ -86,7 +110,12 @@ export function isGoalState(value) {
|
|
|
86
110
|
typeof value.lastProgressAt === "string" &&
|
|
87
111
|
typeof value.stallTurns === "number" &&
|
|
88
112
|
Number.isFinite(value.stallTurns) &&
|
|
89
|
-
hasOptionalString(value, "blockedReason")
|
|
113
|
+
hasOptionalString(value, "blockedReason") &&
|
|
114
|
+
hasOptionalFiniteNumber(value, "continuationTurnsUsed") &&
|
|
115
|
+
hasOptionalFiniteNumber(value, "continuationWallClockMs") &&
|
|
116
|
+
hasOptionalFiniteNumber(value, "continuationSpendUsd") &&
|
|
117
|
+
hasOptionalFiniteNumber(value, "continuationSpendCheckpointUsd") &&
|
|
118
|
+
hasOptionalFiniteNumber(value, "continuationWorkerSpendUsd"));
|
|
90
119
|
}
|
|
91
120
|
function cloneRequirement(requirement) {
|
|
92
121
|
return {
|
|
@@ -126,6 +155,10 @@ export function createGoalState(args) {
|
|
|
126
155
|
updatedAt: args.now,
|
|
127
156
|
lastProgressAt: args.now,
|
|
128
157
|
stallTurns: 0,
|
|
158
|
+
continuationTurnsUsed: 0,
|
|
159
|
+
continuationWallClockMs: 0,
|
|
160
|
+
continuationSpendUsd: 0,
|
|
161
|
+
continuationWorkerSpendUsd: 0,
|
|
129
162
|
};
|
|
130
163
|
}
|
|
131
164
|
export function applyGoalEvent(state, event) {
|
|
@@ -207,6 +240,26 @@ export function applyGoalEvent(state, event) {
|
|
|
207
240
|
newState.stallTurns = 0;
|
|
208
241
|
break;
|
|
209
242
|
}
|
|
243
|
+
case "dispatch_worker": {
|
|
244
|
+
// Records the requirement<->lane binding ONLY -- never satisfies the requirement and never
|
|
245
|
+
// touches lastProgressAt/stallTurns. The worker's own completion later populates "worker"
|
|
246
|
+
// evidence and prompts an explicit satisfy_requirement pass through the existing gate.
|
|
247
|
+
const existingIndex = newState.requirements.findIndex((requirement) => requirement.id === event.id);
|
|
248
|
+
if (existingIndex >= 0) {
|
|
249
|
+
const requirement = newState.requirements[existingIndex];
|
|
250
|
+
const updatedRequirements = [...newState.requirements];
|
|
251
|
+
updatedRequirements[existingIndex] = {
|
|
252
|
+
...requirement,
|
|
253
|
+
boundLaneId: event.laneId,
|
|
254
|
+
// Start (or keep) the wait-timeout clock ONLY when this dispatch actually bound a real
|
|
255
|
+
// lane -- a declined dispatch (no laneId) preserves whatever boundAt was already there.
|
|
256
|
+
boundAt: event.laneId ? event.now : requirement.boundAt,
|
|
257
|
+
updatedAt: event.now,
|
|
258
|
+
};
|
|
259
|
+
newState.requirements = updatedRequirements;
|
|
260
|
+
}
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
210
263
|
case "add_evidence": {
|
|
211
264
|
const existingIndex = newState.evidence.findIndex((evidence) => evidence.id === event.id);
|
|
212
265
|
const newEvidence = {
|
|
@@ -214,6 +267,7 @@ export function applyGoalEvent(state, event) {
|
|
|
214
267
|
kind: event.kind,
|
|
215
268
|
summary: event.summary,
|
|
216
269
|
uri: event.uri,
|
|
270
|
+
verified: event.verified,
|
|
217
271
|
createdAt: existingIndex >= 0 ? newState.evidence[existingIndex].createdAt : event.now,
|
|
218
272
|
};
|
|
219
273
|
if (existingIndex >= 0) {
|
|
@@ -235,6 +289,18 @@ export function applyGoalEvent(state, event) {
|
|
|
235
289
|
newState.stallTurns = state.stallTurns + 1;
|
|
236
290
|
break;
|
|
237
291
|
}
|
|
292
|
+
case "record_continuation_budget": {
|
|
293
|
+
const previousCheckpoint = state.continuationSpendCheckpointUsd;
|
|
294
|
+
// No prior checkpoint (first pass ever recorded for this goal): there is no valid "before"
|
|
295
|
+
// reading to diff against, so attribute a zero delta for this one pass rather than mis-count
|
|
296
|
+
// all pre-goal-loop session spend into it. Every subsequent pass gets an accurate delta.
|
|
297
|
+
const spendDelta = previousCheckpoint === undefined ? 0 : Math.max(0, event.sessionCostUsd - previousCheckpoint);
|
|
298
|
+
newState.continuationTurnsUsed = (state.continuationTurnsUsed ?? 0) + event.turns;
|
|
299
|
+
newState.continuationWallClockMs = (state.continuationWallClockMs ?? 0) + event.wallClockMs;
|
|
300
|
+
newState.continuationSpendUsd = (state.continuationSpendUsd ?? 0) + spendDelta;
|
|
301
|
+
newState.continuationSpendCheckpointUsd = event.sessionCostUsd;
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
238
304
|
case "complete_goal": {
|
|
239
305
|
const hasUnsatisfied = newState.requirements.some((requirement) => requirement.status !== "satisfied");
|
|
240
306
|
if (!hasUnsatisfied) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"goal-state.js","sourceRoot":"","sources":["../../../src/core/goals/goal-state.ts"],"names":[],"mappings":"AAyDA,SAAS,QAAQ,CAAC,KAAc,EAAoC;IACnE,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9E,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC/C,OAAO,SAAS,KAAK,MAAM,CAAC,SAAS,IAAI,SAAS,KAAK,IAAI,CAAC;AAAA,CAC5D;AAED,SAAS,aAAa,CAAC,KAAc,EAA8B;IAClE,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC;AAAA,CAC/E;AAED,SAAS,YAAY,CAAC,KAAc,EAAuB;IAC1D,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,WAAW,CAAC;AAAA,CACnG;AAED,SAAS,mBAAmB,CAAC,KAAc,EAA8B;IACxE,OAAO,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,SAAS,CAAC;AAAA,CACxE;AAED,SAAS,kBAAkB,CAAC,KAAc,EAA6B;IACtE,OAAO,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,SAAS,CAAC;AAAA,CAC3G;AAED,SAAS,iBAAiB,CAAC,MAA+B,EAAE,GAAW,EAAW;IACjF,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC;AAAA,CACpE;AAED,SAAS,aAAa,CAAC,KAAc,EAAwB;IAC5D,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,OAAO,CACN,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ;QAC5B,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,mBAAmB,CAAC,KAAK,CAAC,MAAM,CAAC;QACjC,aAAa,CAAC,KAAK,CAAC,WAAW,CAAC;QAChC,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ;QACnC,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ;QACnC,iBAAiB,CAAC,KAAK,EAAE,eAAe,CAAC,CACzC,CAAC;AAAA,CACF;AAED,SAAS,iBAAiB,CAAC,KAAc,EAA4B;IACpE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,OAAO,CACN,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ;QAC5B,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC;QAC9B,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;QACjC,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ;QACnC,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,CAC/B,CAAC;AAAA,CACF;AAED,SAAS,WAAW,CAAC,KAAc,EAAsB;IACxD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtG,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,iBAAiB;YACrB,OAAO,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;QACvE,KAAK,qBAAqB;YACzB,OAAO,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ,IAAI,aAAa,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACzE,KAAK,mBAAmB;YACvB,OAAO,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,aAAa,KAAK,QAAQ,CAAC;QAChF,KAAK,oBAAoB;YACxB,OAAO,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ,CAAC;QACrC,KAAK,cAAc;YAClB,OAAO,CACN,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ;gBAC5B,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC;gBAC9B,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;gBACjC,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,CAC/B,CAAC;QACH,KAAK,UAAU,CAAC;QAChB,KAAK,aAAa,CAAC;QACnB,KAAK,eAAe,CAAC;QACrB,KAAK,wBAAwB,CAAC;QAC9B,KAAK,aAAa,CAAC;QACnB,KAAK,aAAa;YACjB,OAAO,IAAI,CAAC;QACb,KAAK,YAAY;YAChB,OAAO,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC;QACzC;YACC,OAAO,KAAK,CAAC;IACf,CAAC;AAAA,CACD;AAED,MAAM,UAAU,WAAW,CAAC,KAAc,EAAsB;IAC/D,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,OAAO,CACN,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;QAChC,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ;QAClC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC;QAC1B,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC;QACjC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,aAAa,CAAC;QACvC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;QAC7B,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,iBAAiB,CAAC;QACvC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;QAC3B,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC;QAC/B,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ;QACnC,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ;QACnC,OAAO,KAAK,CAAC,cAAc,KAAK,QAAQ;QACxC,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ;QACpC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC;QACjC,iBAAiB,CAAC,KAAK,EAAE,eAAe,CAAC,CACzC,CAAC;AAAA,CACF;AAED,SAAS,gBAAgB,CAAC,WAAwB,EAAe;IAChE,OAAO;QACN,GAAG,WAAW;QACd,WAAW,EAAE,CAAC,GAAG,WAAW,CAAC,WAAW,CAAC;KACzC,CAAC;AAAA,CACF;AAED,SAAS,oBAAoB,CAAC,QAAyB,EAAmB;IACzE,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAC;AAAA,CACvB;AAED,SAAS,cAAc,CAAC,KAAgB,EAAa;IACpD,IAAI,KAAK,CAAC,IAAI,KAAK,qBAAqB,EAAE,CAAC;QAC1C,OAAO,EAAE,GAAG,KAAK,EAAE,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;IAC1D,CAAC;IACD,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;AAAA,CACpB;AAED,SAAS,cAAc,CAAC,KAAgB,EAAa;IACpD,OAAO;QACN,GAAG,KAAK;QACR,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,gBAAgB,CAAC;QACtD,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,oBAAoB,CAAC;QAClD,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC;KACxC,CAAC;AAAA,CACF;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAgB,EAAa;IACrE,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC;AAAA,CAC7B;AAED,MAAM,UAAU,eAAe,CAAC,IAAuD,EAAa;IACnG,OAAO;QACN,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,MAAM,EAAE,QAAQ;QAChB,YAAY,EAAE,EAAE;QAChB,QAAQ,EAAE,EAAE;QACZ,MAAM,EAAE,EAAE;QACV,SAAS,EAAE,IAAI,CAAC,GAAG;QACnB,SAAS,EAAE,IAAI,CAAC,GAAG;QACnB,cAAc,EAAE,IAAI,CAAC,GAAG;QACxB,UAAU,EAAE,CAAC;KACb,CAAC;AAAA,CACF;AAED,MAAM,UAAU,cAAc,CAAC,KAAgB,EAAE,KAAgB,EAAa;IAC7E,MAAM,QAAQ,GAAc;QAC3B,GAAG,KAAK;QACR,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,gBAAgB,CAAC;QACtD,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,oBAAoB,CAAC;QAClD,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC;QACpE,SAAS,EAAE,KAAK,CAAC,GAAG;KACpB,CAAC;IAEF,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,iBAAiB,EAAE,CAAC;YACxB,MAAM,aAAa,GAAG,QAAQ,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC;YACpG,MAAM,cAAc,GAAgB;gBACnC,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,MAAM,EAAE,MAAM;gBACd,WAAW,EAAE,EAAE;gBACf,SAAS,EAAE,aAAa,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG;gBAC1F,SAAS,EAAE,KAAK,CAAC,GAAG;aACpB,CAAC;YACF,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;gBACxB,MAAM,mBAAmB,GAAG,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;gBACvD,mBAAmB,CAAC,aAAa,CAAC,GAAG,cAAc,CAAC;gBACpD,QAAQ,CAAC,YAAY,GAAG,mBAAmB,CAAC;YAC7C,CAAC;iBAAM,CAAC;gBACP,QAAQ,CAAC,YAAY,GAAG,CAAC,GAAG,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;YACpE,CAAC;YACD,MAAM;QACP,CAAC;QAED,KAAK,qBAAqB,EAAE,CAAC;YAC5B,MAAM,aAAa,GAAG,QAAQ,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC;YACpG,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;gBACxB,MAAM,WAAW,GAAG,QAAQ,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;gBACzD,MAAM,mBAAmB,GAAG,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;gBACvD,mBAAmB,CAAC,aAAa,CAAC,GAAG;oBACpC,GAAG,WAAW;oBACd,MAAM,EAAE,WAAW;oBACnB,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC;oBACnC,SAAS,EAAE,KAAK,CAAC,GAAG;oBACpB,aAAa,EAAE,SAAS;iBACxB,CAAC;gBACF,QAAQ,CAAC,YAAY,GAAG,mBAAmB,CAAC;YAC7C,CAAC;YACD,QAAQ,CAAC,cAAc,GAAG,KAAK,CAAC,GAAG,CAAC;YACpC,QAAQ,CAAC,UAAU,GAAG,CAAC,CAAC;YACxB,MAAM;QACP,CAAC;QAED,KAAK,mBAAmB,EAAE,CAAC;YAC1B,MAAM,aAAa,GAAG,QAAQ,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC;YACpG,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;gBACxB,MAAM,WAAW,GAAG,QAAQ,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;gBACzD,MAAM,mBAAmB,GAAG,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;gBACvD,mBAAmB,CAAC,aAAa,CAAC,GAAG;oBACpC,GAAG,WAAW;oBACd,MAAM,EAAE,SAAS;oBACjB,aAAa,EAAE,KAAK,CAAC,aAAa;oBAClC,SAAS,EAAE,KAAK,CAAC,GAAG;iBACpB,CAAC;gBACF,QAAQ,CAAC,YAAY,GAAG,mBAAmB,CAAC;YAC7C,CAAC;YACD,MAAM;QACP,CAAC;QAED,KAAK,oBAAoB,EAAE,CAAC;YAC3B,MAAM,aAAa,GAAG,QAAQ,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC;YACpG,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;gBACxB,MAAM,WAAW,GAAG,QAAQ,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;gBACzD,MAAM,mBAAmB,GAAG,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;gBACvD,mBAAmB,CAAC,aAAa,CAAC,GAAG;oBACpC,GAAG,WAAW;oBACd,MAAM,EAAE,MAAM;oBACd,aAAa,EAAE,SAAS;oBACxB,SAAS,EAAE,KAAK,CAAC,GAAG;iBACpB,CAAC;gBACF,QAAQ,CAAC,YAAY,GAAG,mBAAmB,CAAC;YAC7C,CAAC;YACD,QAAQ,CAAC,cAAc,GAAG,KAAK,CAAC,GAAG,CAAC;YACpC,QAAQ,CAAC,UAAU,GAAG,CAAC,CAAC;YACxB,MAAM;QACP,CAAC;QAED,KAAK,cAAc,EAAE,CAAC;YACrB,MAAM,aAAa,GAAG,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC;YAC1F,MAAM,WAAW,GAAoB;gBACpC,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,SAAS,EAAE,aAAa,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG;aACtF,CAAC;YACF,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;gBACxB,MAAM,eAAe,GAAG,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAC/C,eAAe,CAAC,aAAa,CAAC,GAAG,WAAW,CAAC;gBAC7C,QAAQ,CAAC,QAAQ,GAAG,eAAe,CAAC;YACrC,CAAC;iBAAM,CAAC;gBACP,QAAQ,CAAC,QAAQ,GAAG,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;YACzD,CAAC;YACD,MAAM;QACP,CAAC;QAED,KAAK,UAAU,EAAE,CAAC;YACjB,QAAQ,CAAC,cAAc,GAAG,KAAK,CAAC,GAAG,CAAC;YACpC,QAAQ,CAAC,UAAU,GAAG,CAAC,CAAC;YACxB,MAAM;QACP,CAAC;QAED,KAAK,aAAa,EAAE,CAAC;YACpB,QAAQ,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC;YAC3C,MAAM;QACP,CAAC;QAED,KAAK,eAAe,EAAE,CAAC;YACtB,MAAM,cAAc,GAAG,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC;YACvG,IAAI,CAAC,cAAc,EAAE,CAAC;gBACrB,QAAQ,CAAC,MAAM,GAAG,WAAW,CAAC;gBAC9B,QAAQ,CAAC,aAAa,GAAG,SAAS,CAAC;YACpC,CAAC;YACD,MAAM;QACP,CAAC;QAED,KAAK,wBAAwB,EAAE,CAAC;YAC/B,QAAQ,CAAC,MAAM,GAAG,WAAW,CAAC;YAC9B,QAAQ,CAAC,aAAa,GAAG,SAAS,CAAC;YACnC,QAAQ,CAAC,cAAc,GAAG,KAAK,CAAC,GAAG,CAAC;YACpC,QAAQ,CAAC,UAAU,GAAG,CAAC,CAAC;YACxB,MAAM;QACP,CAAC;QAED,KAAK,YAAY,EAAE,CAAC;YACnB,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC;YAC5B,QAAQ,CAAC,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC;YACtC,MAAM;QACP,CAAC;QAED,KAAK,aAAa,EAAE,CAAC;YACpB,QAAQ,CAAC,MAAM,GAAG,QAAQ,CAAC;YAC3B,QAAQ,CAAC,aAAa,GAAG,SAAS,CAAC;YACnC,QAAQ,CAAC,cAAc,GAAG,KAAK,CAAC,GAAG,CAAC;YACpC,QAAQ,CAAC,UAAU,GAAG,CAAC,CAAC;YACxB,MAAM;QACP,CAAC;QAED,KAAK,aAAa,EAAE,CAAC;YACpB,QAAQ,CAAC,MAAM,GAAG,WAAW,CAAC;YAC9B,QAAQ,CAAC,aAAa,GAAG,SAAS,CAAC;YACnC,MAAM;QACP,CAAC;IACF,CAAC;IAED,OAAO,QAAQ,CAAC;AAAA,CAChB;AAED,MAAM,UAAU,sBAAsB,CAAC,IAA8D,EAAW;IAC/G,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC;IACd,CAAC;IACD,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACjD,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,IAAI,CAAC;AAAA,CACZ;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAgB,EAAU;IAC5D,OAAO,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAAA,CACtD;AAED,MAAM,UAAU,cAAc,CAAC,IAAY,EAAyB;IACnE,IAAI,CAAC;QACJ,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;YAAE,OAAO,SAAS,CAAC;QAC3C,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;AAAA,CACD","sourcesContent":["export type GoalStatus = \"active\" | \"completed\" | \"blocked\" | \"cancelled\";\nexport type RequirementStatus = \"open\" | \"satisfied\" | \"blocked\";\nexport type GoalEvidenceKind = \"file\" | \"test\" | \"tool\" | \"user\" | \"finding\";\n\nexport interface GoalState {\n\tgoalId: string;\n\tuserGoal: string;\n\tstatus: GoalStatus;\n\trequirements: readonly Requirement[];\n\tevidence: readonly GoalEvidenceRef[];\n\tevents: readonly GoalEvent[];\n\tcreatedAt: string;\n\tupdatedAt: string;\n\tlastProgressAt: string;\n\tstallTurns: number;\n\tblockedReason?: string;\n}\n\nexport interface Requirement {\n\tid: string;\n\ttext: string;\n\tstatus: RequirementStatus;\n\tevidenceIds: readonly string[];\n\tblockedReason?: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface GoalEvidenceRef {\n\tid: string;\n\tkind: GoalEvidenceKind;\n\tsummary: string;\n\turi?: string;\n\tcreatedAt: string;\n}\n\nexport type GoalEvent =\n\t| { type: \"add_requirement\"; id: string; text: string; now: string }\n\t| { type: \"satisfy_requirement\"; id: string; evidenceIds: readonly string[]; now: string }\n\t| { type: \"block_requirement\"; id: string; blockedReason: string; now: string }\n\t| { type: \"reopen_requirement\"; id: string; now: string }\n\t| {\n\t\t\ttype: \"add_evidence\";\n\t\t\tid: string;\n\t\t\tkind: GoalEvidenceKind;\n\t\t\tsummary: string;\n\t\t\turi?: string;\n\t\t\tnow: string;\n\t }\n\t| { type: \"progress\"; now: string }\n\t| { type: \"no_progress\"; now: string }\n\t| { type: \"complete_goal\"; now: string }\n\t| { type: \"complete_goal_manually\"; now: string }\n\t| { type: \"block_goal\"; reason: string; now: string }\n\t| { type: \"resume_goal\"; now: string }\n\t| { type: \"cancel_goal\"; now: string };\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst prototype = Object.getPrototypeOf(value);\n\treturn prototype === Object.prototype || prototype === null;\n}\n\nfunction isStringArray(value: unknown): value is readonly string[] {\n\treturn Array.isArray(value) && value.every((item) => typeof item === \"string\");\n}\n\nfunction isGoalStatus(value: unknown): value is GoalStatus {\n\treturn value === \"active\" || value === \"completed\" || value === \"blocked\" || value === \"cancelled\";\n}\n\nfunction isRequirementStatus(value: unknown): value is RequirementStatus {\n\treturn value === \"open\" || value === \"satisfied\" || value === \"blocked\";\n}\n\nfunction isGoalEvidenceKind(value: unknown): value is GoalEvidenceKind {\n\treturn value === \"file\" || value === \"test\" || value === \"tool\" || value === \"user\" || value === \"finding\";\n}\n\nfunction hasOptionalString(record: Record<string, unknown>, key: string): boolean {\n\treturn record[key] === undefined || typeof record[key] === \"string\";\n}\n\nfunction isRequirement(value: unknown): value is Requirement {\n\tif (!isRecord(value)) return false;\n\treturn (\n\t\ttypeof value.id === \"string\" &&\n\t\ttypeof value.text === \"string\" &&\n\t\tisRequirementStatus(value.status) &&\n\t\tisStringArray(value.evidenceIds) &&\n\t\ttypeof value.createdAt === \"string\" &&\n\t\ttypeof value.updatedAt === \"string\" &&\n\t\thasOptionalString(value, \"blockedReason\")\n\t);\n}\n\nfunction isGoalEvidenceRef(value: unknown): value is GoalEvidenceRef {\n\tif (!isRecord(value)) return false;\n\treturn (\n\t\ttypeof value.id === \"string\" &&\n\t\tisGoalEvidenceKind(value.kind) &&\n\t\ttypeof value.summary === \"string\" &&\n\t\ttypeof value.createdAt === \"string\" &&\n\t\thasOptionalString(value, \"uri\")\n\t);\n}\n\nfunction isGoalEvent(value: unknown): value is GoalEvent {\n\tif (!isRecord(value) || typeof value.type !== \"string\" || typeof value.now !== \"string\") return false;\n\tswitch (value.type) {\n\t\tcase \"add_requirement\":\n\t\t\treturn typeof value.id === \"string\" && typeof value.text === \"string\";\n\t\tcase \"satisfy_requirement\":\n\t\t\treturn typeof value.id === \"string\" && isStringArray(value.evidenceIds);\n\t\tcase \"block_requirement\":\n\t\t\treturn typeof value.id === \"string\" && typeof value.blockedReason === \"string\";\n\t\tcase \"reopen_requirement\":\n\t\t\treturn typeof value.id === \"string\";\n\t\tcase \"add_evidence\":\n\t\t\treturn (\n\t\t\t\ttypeof value.id === \"string\" &&\n\t\t\t\tisGoalEvidenceKind(value.kind) &&\n\t\t\t\ttypeof value.summary === \"string\" &&\n\t\t\t\thasOptionalString(value, \"uri\")\n\t\t\t);\n\t\tcase \"progress\":\n\t\tcase \"no_progress\":\n\t\tcase \"complete_goal\":\n\t\tcase \"complete_goal_manually\":\n\t\tcase \"resume_goal\":\n\t\tcase \"cancel_goal\":\n\t\t\treturn true;\n\t\tcase \"block_goal\":\n\t\t\treturn typeof value.reason === \"string\";\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nexport function isGoalState(value: unknown): value is GoalState {\n\tif (!isRecord(value)) return false;\n\treturn (\n\t\ttypeof value.goalId === \"string\" &&\n\t\ttypeof value.userGoal === \"string\" &&\n\t\tisGoalStatus(value.status) &&\n\t\tArray.isArray(value.requirements) &&\n\t\tvalue.requirements.every(isRequirement) &&\n\t\tArray.isArray(value.evidence) &&\n\t\tvalue.evidence.every(isGoalEvidenceRef) &&\n\t\tArray.isArray(value.events) &&\n\t\tvalue.events.every(isGoalEvent) &&\n\t\ttypeof value.createdAt === \"string\" &&\n\t\ttypeof value.updatedAt === \"string\" &&\n\t\ttypeof value.lastProgressAt === \"string\" &&\n\t\ttypeof value.stallTurns === \"number\" &&\n\t\tNumber.isFinite(value.stallTurns) &&\n\t\thasOptionalString(value, \"blockedReason\")\n\t);\n}\n\nfunction cloneRequirement(requirement: Requirement): Requirement {\n\treturn {\n\t\t...requirement,\n\t\tevidenceIds: [...requirement.evidenceIds],\n\t};\n}\n\nfunction cloneGoalEvidenceRef(evidence: GoalEvidenceRef): GoalEvidenceRef {\n\treturn { ...evidence };\n}\n\nfunction cloneGoalEvent(event: GoalEvent): GoalEvent {\n\tif (event.type === \"satisfy_requirement\") {\n\t\treturn { ...event, evidenceIds: [...event.evidenceIds] };\n\t}\n\treturn { ...event };\n}\n\nfunction cloneGoalState(state: GoalState): GoalState {\n\treturn {\n\t\t...state,\n\t\trequirements: state.requirements.map(cloneRequirement),\n\t\tevidence: state.evidence.map(cloneGoalEvidenceRef),\n\t\tevents: state.events.map(cloneGoalEvent),\n\t};\n}\n\nexport function cloneGoalStateForStorage(state: GoalState): GoalState {\n\treturn cloneGoalState(state);\n}\n\nexport function createGoalState(args: { goalId: string; userGoal: string; now: string }): GoalState {\n\treturn {\n\t\tgoalId: args.goalId,\n\t\tuserGoal: args.userGoal,\n\t\tstatus: \"active\",\n\t\trequirements: [],\n\t\tevidence: [],\n\t\tevents: [],\n\t\tcreatedAt: args.now,\n\t\tupdatedAt: args.now,\n\t\tlastProgressAt: args.now,\n\t\tstallTurns: 0,\n\t};\n}\n\nexport function applyGoalEvent(state: GoalState, event: GoalEvent): GoalState {\n\tconst newState: GoalState = {\n\t\t...state,\n\t\trequirements: state.requirements.map(cloneRequirement),\n\t\tevidence: state.evidence.map(cloneGoalEvidenceRef),\n\t\tevents: [...state.events.map(cloneGoalEvent), cloneGoalEvent(event)],\n\t\tupdatedAt: event.now,\n\t};\n\n\tswitch (event.type) {\n\t\tcase \"add_requirement\": {\n\t\t\tconst existingIndex = newState.requirements.findIndex((requirement) => requirement.id === event.id);\n\t\t\tconst newRequirement: Requirement = {\n\t\t\t\tid: event.id,\n\t\t\t\ttext: event.text,\n\t\t\t\tstatus: \"open\",\n\t\t\t\tevidenceIds: [],\n\t\t\t\tcreatedAt: existingIndex >= 0 ? newState.requirements[existingIndex].createdAt : event.now,\n\t\t\t\tupdatedAt: event.now,\n\t\t\t};\n\t\t\tif (existingIndex >= 0) {\n\t\t\t\tconst updatedRequirements = [...newState.requirements];\n\t\t\t\tupdatedRequirements[existingIndex] = newRequirement;\n\t\t\t\tnewState.requirements = updatedRequirements;\n\t\t\t} else {\n\t\t\t\tnewState.requirements = [...newState.requirements, newRequirement];\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"satisfy_requirement\": {\n\t\t\tconst existingIndex = newState.requirements.findIndex((requirement) => requirement.id === event.id);\n\t\t\tif (existingIndex >= 0) {\n\t\t\t\tconst requirement = newState.requirements[existingIndex];\n\t\t\t\tconst updatedRequirements = [...newState.requirements];\n\t\t\t\tupdatedRequirements[existingIndex] = {\n\t\t\t\t\t...requirement,\n\t\t\t\t\tstatus: \"satisfied\",\n\t\t\t\t\tevidenceIds: [...event.evidenceIds],\n\t\t\t\t\tupdatedAt: event.now,\n\t\t\t\t\tblockedReason: undefined,\n\t\t\t\t};\n\t\t\t\tnewState.requirements = updatedRequirements;\n\t\t\t}\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"block_requirement\": {\n\t\t\tconst existingIndex = newState.requirements.findIndex((requirement) => requirement.id === event.id);\n\t\t\tif (existingIndex >= 0) {\n\t\t\t\tconst requirement = newState.requirements[existingIndex];\n\t\t\t\tconst updatedRequirements = [...newState.requirements];\n\t\t\t\tupdatedRequirements[existingIndex] = {\n\t\t\t\t\t...requirement,\n\t\t\t\t\tstatus: \"blocked\",\n\t\t\t\t\tblockedReason: event.blockedReason,\n\t\t\t\t\tupdatedAt: event.now,\n\t\t\t\t};\n\t\t\t\tnewState.requirements = updatedRequirements;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"reopen_requirement\": {\n\t\t\tconst existingIndex = newState.requirements.findIndex((requirement) => requirement.id === event.id);\n\t\t\tif (existingIndex >= 0) {\n\t\t\t\tconst requirement = newState.requirements[existingIndex];\n\t\t\t\tconst updatedRequirements = [...newState.requirements];\n\t\t\t\tupdatedRequirements[existingIndex] = {\n\t\t\t\t\t...requirement,\n\t\t\t\t\tstatus: \"open\",\n\t\t\t\t\tblockedReason: undefined,\n\t\t\t\t\tupdatedAt: event.now,\n\t\t\t\t};\n\t\t\t\tnewState.requirements = updatedRequirements;\n\t\t\t}\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"add_evidence\": {\n\t\t\tconst existingIndex = newState.evidence.findIndex((evidence) => evidence.id === event.id);\n\t\t\tconst newEvidence: GoalEvidenceRef = {\n\t\t\t\tid: event.id,\n\t\t\t\tkind: event.kind,\n\t\t\t\tsummary: event.summary,\n\t\t\t\turi: event.uri,\n\t\t\t\tcreatedAt: existingIndex >= 0 ? newState.evidence[existingIndex].createdAt : event.now,\n\t\t\t};\n\t\t\tif (existingIndex >= 0) {\n\t\t\t\tconst updatedEvidence = [...newState.evidence];\n\t\t\t\tupdatedEvidence[existingIndex] = newEvidence;\n\t\t\t\tnewState.evidence = updatedEvidence;\n\t\t\t} else {\n\t\t\t\tnewState.evidence = [...newState.evidence, newEvidence];\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"progress\": {\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"no_progress\": {\n\t\t\tnewState.stallTurns = state.stallTurns + 1;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"complete_goal\": {\n\t\t\tconst hasUnsatisfied = newState.requirements.some((requirement) => requirement.status !== \"satisfied\");\n\t\t\tif (!hasUnsatisfied) {\n\t\t\t\tnewState.status = \"completed\";\n\t\t\t\tnewState.blockedReason = undefined;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"complete_goal_manually\": {\n\t\t\tnewState.status = \"completed\";\n\t\t\tnewState.blockedReason = undefined;\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"block_goal\": {\n\t\t\tnewState.status = \"blocked\";\n\t\t\tnewState.blockedReason = event.reason;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"resume_goal\": {\n\t\t\tnewState.status = \"active\";\n\t\t\tnewState.blockedReason = undefined;\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"cancel_goal\": {\n\t\t\tnewState.status = \"cancelled\";\n\t\t\tnewState.blockedReason = undefined;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn newState;\n}\n\nexport function shouldContinueGoalLoop(args: { state: GoalState; maxStallTurns: number; now: string }): boolean {\n\tif (args.state.status !== \"active\") {\n\t\treturn false;\n\t}\n\tif (args.state.stallTurns >= args.maxStallTurns) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nexport function serializeGoalState(state: GoalState): string {\n\treturn JSON.stringify(cloneGoalState(state), null, 2);\n}\n\nexport function parseGoalState(text: string): GoalState | undefined {\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(text);\n\t\tif (!isGoalState(parsed)) return undefined;\n\t\treturn cloneGoalState(parsed);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"goal-state.js","sourceRoot":"","sources":["../../../src/core/goals/goal-state.ts"],"names":[],"mappings":"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","sourcesContent":["export type GoalStatus = \"active\" | \"completed\" | \"blocked\" | \"cancelled\";\nexport type RequirementStatus = \"open\" | \"satisfied\" | \"blocked\";\nexport type GoalEvidenceKind = \"file\" | \"test\" | \"tool\" | \"user\" | \"finding\" | \"worker\";\n\nexport interface GoalState {\n\tgoalId: string;\n\tuserGoal: string;\n\tstatus: GoalStatus;\n\trequirements: readonly Requirement[];\n\tevidence: readonly GoalEvidenceRef[];\n\tevents: readonly GoalEvent[];\n\tcreatedAt: string;\n\tupdatedAt: string;\n\tlastProgressAt: string;\n\tstallTurns: number;\n\tblockedReason?: string;\n\t/**\n\t * Cumulative continuation turns submitted for this goal across EVERY `continueGoalLoop`\n\t * invocation for its lifetime (idle-driven auto-continues and manual continues alike) —\n\t * durable via goal-state persistence, so it survives process restarts and idle cycles.\n\t * Optional because snapshots persisted before this field existed carry no value; treat\n\t * `undefined` as `0` everywhere it is read (see `applyGoalEvent`'s `record_continuation_budget`\n\t * case and `goal-loop-controller.ts`'s budget check).\n\t */\n\tcontinuationTurnsUsed?: number;\n\t/**\n\t * Cumulative ACTIVE wall-clock milliseconds spent running continuation passes for this goal —\n\t * the sum of each individual pass's own await duration, NOT wall-clock time elapsed between\n\t * passes or during idle gaps. Same backward-compat/undefined-as-0 note as `continuationTurnsUsed`.\n\t */\n\tcontinuationWallClockMs?: number;\n\t/**\n\t * Cumulative USD attributed to this goal's own continuation passes, derived from the session's\n\t * own model spend (`getCostSummary().ownCost` at the persistence dep) — deliberately excludes\n\t * worker/subagent spend, which is tracked and budgeted separately. Same backward-compat note.\n\t */\n\tcontinuationSpendUsd?: number;\n\t/**\n\t * Bookkeeping only: the session's own cumulative cost reading as of the last recorded pass,\n\t * used to derive the NEXT pass's spend delta (`event.sessionCostUsd - continuationSpendCheckpointUsd`)\n\t * while keeping `applyGoalEvent` pure (it consumes one externally-observed absolute reading per\n\t * call rather than reaching for session state itself). Not meaningful read in isolation; `undefined`\n\t * means no pass has been recorded yet, so the first recorded pass establishes the checkpoint with a\n\t * zero delta rather than mis-attributing all pre-goal-loop session spend to that one pass.\n\t */\n\tcontinuationSpendCheckpointUsd?: number;\n\t/**\n\t * Cumulative USD attributed to WORKER/SUBAGENT spend for this goal's lanes (in-process worker\n\t * usage via `addSpawnedUsage`, out-of-process tmux-worker usage via the advisory\n\t * `reportSpawnedUsage` claim) — the counterpart this goal's OWN model spend excludes (see\n\t * {@link continuationSpendUsd}). Populated by the runtime that sums lane spend by goalId; this\n\t * field is only the durable slot. Same backward-compat/undefined-as-0 note as the other\n\t * continuation budget fields. Advisory for out-of-process (tmux) workers — never a hard cap\n\t * across the process boundary.\n\t */\n\tcontinuationWorkerSpendUsd?: number;\n}\n\nexport interface Requirement {\n\tid: string;\n\ttext: string;\n\tstatus: RequirementStatus;\n\tevidenceIds: readonly string[];\n\tblockedReason?: string;\n\tcreatedAt: string;\n\tupdatedAt: string;\n\t/**\n\t * LaneId of a worker dispatched against this requirement (set by the `dispatch_worker` event).\n\t * Recording a binding never satisfies the requirement by itself -- the worker's own completion\n\t * later populates `\"worker\"`-kind evidence and prompts an explicit `satisfy_requirement` pass.\n\t */\n\tboundLaneId?: string;\n\t/**\n\t * ISO timestamp of the moment `boundLaneId` was most recently bound to a REAL lane -- the clock\n\t * the never-hang wait-timeout (`evaluateGoalContinuation`'s `worker_wait_timeout` reasonCode)\n\t * reads to detect a worker that has hung past `maxWorkerWaitMs`. Stamped ONLY when a\n\t * `dispatch_worker` event carries a lane id; a declined dispatch (no lane) leaves this field\n\t * untouched, so no clock starts for a worker that never actually launched.\n\t */\n\tboundAt?: string;\n}\n\nexport interface GoalEvidenceRef {\n\tid: string;\n\tkind: GoalEvidenceKind;\n\tsummary: string;\n\turi?: string;\n\t/**\n\t * Whether `uri` was checked against session records (\"tool\" evidence, a toolCallId) or the\n\t * filesystem (\"file\" evidence, a path) at add_evidence time. `true`/`false` only when the\n\t * ref was checkable; `undefined` when the evidence kind carries no checkable ref (e.g.\n\t * \"user\"/\"finding\"/\"test\", or a \"tool\"/\"file\" entry with no `uri`).\n\t */\n\tverified?: boolean;\n\tcreatedAt: string;\n}\n\nexport type GoalEvent =\n\t| { type: \"add_requirement\"; id: string; text: string; now: string }\n\t| { type: \"satisfy_requirement\"; id: string; evidenceIds: readonly string[]; now: string }\n\t| { type: \"block_requirement\"; id: string; blockedReason: string; now: string }\n\t| { type: \"reopen_requirement\"; id: string; now: string }\n\t| {\n\t\t\ttype: \"dispatch_worker\";\n\t\t\t/** Requirement id the worker is bound to. */\n\t\t\tid: string;\n\t\t\t/** Instructions the worker was (or will be) dispatched with. */\n\t\t\tinstructions: string;\n\t\t\t/**\n\t\t\t * LaneId returned by the tool-layer dispatch side effect. Undefined when that side effect\n\t\t\t * is unwired/stubbed -- the binding is then recorded with no lane target yet.\n\t\t\t */\n\t\t\tlaneId?: string;\n\t\t\tnow: string;\n\t }\n\t| {\n\t\t\ttype: \"add_evidence\";\n\t\t\tid: string;\n\t\t\tkind: GoalEvidenceKind;\n\t\t\tsummary: string;\n\t\t\turi?: string;\n\t\t\t/** See {@link GoalEvidenceRef.verified}; computed by the tool layer before the event is applied. */\n\t\t\tverified?: boolean;\n\t\t\tnow: string;\n\t }\n\t| { type: \"progress\"; now: string }\n\t| { type: \"no_progress\"; now: string }\n\t| {\n\t\t\ttype: \"record_continuation_budget\";\n\t\t\t/** Turns submitted in this pass (currently always 1 — the loop calls once per submitted pass). */\n\t\t\tturns: number;\n\t\t\t/** This pass's own active wall-clock duration, in milliseconds. */\n\t\t\twallClockMs: number;\n\t\t\t/**\n\t\t\t * The session's own cumulative model spend (`getCostSummary().ownCost`) AT THE TIME this pass\n\t\t\t * was recorded — an absolute reading, not a pre-computed delta. See\n\t\t\t * `GoalState.continuationSpendCheckpointUsd` for how the reducer derives the delta.\n\t\t\t */\n\t\t\tsessionCostUsd: number;\n\t\t\tnow: string;\n\t }\n\t| { type: \"complete_goal\"; now: string }\n\t| { type: \"complete_goal_manually\"; now: string }\n\t| { type: \"block_goal\"; reason: string; now: string }\n\t| { type: \"resume_goal\"; now: string }\n\t| { type: \"cancel_goal\"; now: string };\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst prototype = Object.getPrototypeOf(value);\n\treturn prototype === Object.prototype || prototype === null;\n}\n\nfunction isStringArray(value: unknown): value is readonly string[] {\n\treturn Array.isArray(value) && value.every((item) => typeof item === \"string\");\n}\n\nfunction isGoalStatus(value: unknown): value is GoalStatus {\n\treturn value === \"active\" || value === \"completed\" || value === \"blocked\" || value === \"cancelled\";\n}\n\nfunction isRequirementStatus(value: unknown): value is RequirementStatus {\n\treturn value === \"open\" || value === \"satisfied\" || value === \"blocked\";\n}\n\nfunction isGoalEvidenceKind(value: unknown): value is GoalEvidenceKind {\n\treturn (\n\t\tvalue === \"file\" ||\n\t\tvalue === \"test\" ||\n\t\tvalue === \"tool\" ||\n\t\tvalue === \"user\" ||\n\t\tvalue === \"finding\" ||\n\t\tvalue === \"worker\"\n\t);\n}\n\nfunction hasOptionalString(record: Record<string, unknown>, key: string): boolean {\n\treturn record[key] === undefined || typeof record[key] === \"string\";\n}\n\nfunction hasOptionalBoolean(record: Record<string, unknown>, key: string): boolean {\n\treturn record[key] === undefined || typeof record[key] === \"boolean\";\n}\n\nfunction hasOptionalFiniteNumber(record: Record<string, unknown>, key: string): boolean {\n\treturn record[key] === undefined || (typeof record[key] === \"number\" && Number.isFinite(record[key]));\n}\n\nfunction isRequirement(value: unknown): value is Requirement {\n\tif (!isRecord(value)) return false;\n\treturn (\n\t\ttypeof value.id === \"string\" &&\n\t\ttypeof value.text === \"string\" &&\n\t\tisRequirementStatus(value.status) &&\n\t\tisStringArray(value.evidenceIds) &&\n\t\ttypeof value.createdAt === \"string\" &&\n\t\ttypeof value.updatedAt === \"string\" &&\n\t\thasOptionalString(value, \"blockedReason\") &&\n\t\thasOptionalString(value, \"boundLaneId\") &&\n\t\thasOptionalString(value, \"boundAt\")\n\t);\n}\n\nfunction isGoalEvidenceRef(value: unknown): value is GoalEvidenceRef {\n\tif (!isRecord(value)) return false;\n\treturn (\n\t\ttypeof value.id === \"string\" &&\n\t\tisGoalEvidenceKind(value.kind) &&\n\t\ttypeof value.summary === \"string\" &&\n\t\ttypeof value.createdAt === \"string\" &&\n\t\thasOptionalString(value, \"uri\") &&\n\t\thasOptionalBoolean(value, \"verified\")\n\t);\n}\n\nfunction isGoalEvent(value: unknown): value is GoalEvent {\n\tif (!isRecord(value) || typeof value.type !== \"string\" || typeof value.now !== \"string\") return false;\n\tswitch (value.type) {\n\t\tcase \"add_requirement\":\n\t\t\treturn typeof value.id === \"string\" && typeof value.text === \"string\";\n\t\tcase \"satisfy_requirement\":\n\t\t\treturn typeof value.id === \"string\" && isStringArray(value.evidenceIds);\n\t\tcase \"block_requirement\":\n\t\t\treturn typeof value.id === \"string\" && typeof value.blockedReason === \"string\";\n\t\tcase \"reopen_requirement\":\n\t\t\treturn typeof value.id === \"string\";\n\t\tcase \"dispatch_worker\":\n\t\t\treturn (\n\t\t\t\ttypeof value.id === \"string\" && typeof value.instructions === \"string\" && hasOptionalString(value, \"laneId\")\n\t\t\t);\n\t\tcase \"add_evidence\":\n\t\t\treturn (\n\t\t\t\ttypeof value.id === \"string\" &&\n\t\t\t\tisGoalEvidenceKind(value.kind) &&\n\t\t\t\ttypeof value.summary === \"string\" &&\n\t\t\t\thasOptionalString(value, \"uri\") &&\n\t\t\t\thasOptionalBoolean(value, \"verified\")\n\t\t\t);\n\t\tcase \"progress\":\n\t\tcase \"no_progress\":\n\t\tcase \"complete_goal\":\n\t\tcase \"complete_goal_manually\":\n\t\tcase \"resume_goal\":\n\t\tcase \"cancel_goal\":\n\t\t\treturn true;\n\t\tcase \"block_goal\":\n\t\t\treturn typeof value.reason === \"string\";\n\t\tcase \"record_continuation_budget\":\n\t\t\treturn (\n\t\t\t\ttypeof value.turns === \"number\" &&\n\t\t\t\tNumber.isFinite(value.turns) &&\n\t\t\t\ttypeof value.wallClockMs === \"number\" &&\n\t\t\t\tNumber.isFinite(value.wallClockMs) &&\n\t\t\t\ttypeof value.sessionCostUsd === \"number\" &&\n\t\t\t\tNumber.isFinite(value.sessionCostUsd)\n\t\t\t);\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nexport function isGoalState(value: unknown): value is GoalState {\n\tif (!isRecord(value)) return false;\n\treturn (\n\t\ttypeof value.goalId === \"string\" &&\n\t\ttypeof value.userGoal === \"string\" &&\n\t\tisGoalStatus(value.status) &&\n\t\tArray.isArray(value.requirements) &&\n\t\tvalue.requirements.every(isRequirement) &&\n\t\tArray.isArray(value.evidence) &&\n\t\tvalue.evidence.every(isGoalEvidenceRef) &&\n\t\tArray.isArray(value.events) &&\n\t\tvalue.events.every(isGoalEvent) &&\n\t\ttypeof value.createdAt === \"string\" &&\n\t\ttypeof value.updatedAt === \"string\" &&\n\t\ttypeof value.lastProgressAt === \"string\" &&\n\t\ttypeof value.stallTurns === \"number\" &&\n\t\tNumber.isFinite(value.stallTurns) &&\n\t\thasOptionalString(value, \"blockedReason\") &&\n\t\thasOptionalFiniteNumber(value, \"continuationTurnsUsed\") &&\n\t\thasOptionalFiniteNumber(value, \"continuationWallClockMs\") &&\n\t\thasOptionalFiniteNumber(value, \"continuationSpendUsd\") &&\n\t\thasOptionalFiniteNumber(value, \"continuationSpendCheckpointUsd\") &&\n\t\thasOptionalFiniteNumber(value, \"continuationWorkerSpendUsd\")\n\t);\n}\n\nfunction cloneRequirement(requirement: Requirement): Requirement {\n\treturn {\n\t\t...requirement,\n\t\tevidenceIds: [...requirement.evidenceIds],\n\t};\n}\n\nfunction cloneGoalEvidenceRef(evidence: GoalEvidenceRef): GoalEvidenceRef {\n\treturn { ...evidence };\n}\n\nfunction cloneGoalEvent(event: GoalEvent): GoalEvent {\n\tif (event.type === \"satisfy_requirement\") {\n\t\treturn { ...event, evidenceIds: [...event.evidenceIds] };\n\t}\n\treturn { ...event };\n}\n\nfunction cloneGoalState(state: GoalState): GoalState {\n\treturn {\n\t\t...state,\n\t\trequirements: state.requirements.map(cloneRequirement),\n\t\tevidence: state.evidence.map(cloneGoalEvidenceRef),\n\t\tevents: state.events.map(cloneGoalEvent),\n\t};\n}\n\nexport function cloneGoalStateForStorage(state: GoalState): GoalState {\n\treturn cloneGoalState(state);\n}\n\nexport function createGoalState(args: { goalId: string; userGoal: string; now: string }): GoalState {\n\treturn {\n\t\tgoalId: args.goalId,\n\t\tuserGoal: args.userGoal,\n\t\tstatus: \"active\",\n\t\trequirements: [],\n\t\tevidence: [],\n\t\tevents: [],\n\t\tcreatedAt: args.now,\n\t\tupdatedAt: args.now,\n\t\tlastProgressAt: args.now,\n\t\tstallTurns: 0,\n\t\tcontinuationTurnsUsed: 0,\n\t\tcontinuationWallClockMs: 0,\n\t\tcontinuationSpendUsd: 0,\n\t\tcontinuationWorkerSpendUsd: 0,\n\t};\n}\n\nexport function applyGoalEvent(state: GoalState, event: GoalEvent): GoalState {\n\tconst newState: GoalState = {\n\t\t...state,\n\t\trequirements: state.requirements.map(cloneRequirement),\n\t\tevidence: state.evidence.map(cloneGoalEvidenceRef),\n\t\tevents: [...state.events.map(cloneGoalEvent), cloneGoalEvent(event)],\n\t\tupdatedAt: event.now,\n\t};\n\n\tswitch (event.type) {\n\t\tcase \"add_requirement\": {\n\t\t\tconst existingIndex = newState.requirements.findIndex((requirement) => requirement.id === event.id);\n\t\t\tconst newRequirement: Requirement = {\n\t\t\t\tid: event.id,\n\t\t\t\ttext: event.text,\n\t\t\t\tstatus: \"open\",\n\t\t\t\tevidenceIds: [],\n\t\t\t\tcreatedAt: existingIndex >= 0 ? newState.requirements[existingIndex].createdAt : event.now,\n\t\t\t\tupdatedAt: event.now,\n\t\t\t};\n\t\t\tif (existingIndex >= 0) {\n\t\t\t\tconst updatedRequirements = [...newState.requirements];\n\t\t\t\tupdatedRequirements[existingIndex] = newRequirement;\n\t\t\t\tnewState.requirements = updatedRequirements;\n\t\t\t} else {\n\t\t\t\tnewState.requirements = [...newState.requirements, newRequirement];\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"satisfy_requirement\": {\n\t\t\tconst existingIndex = newState.requirements.findIndex((requirement) => requirement.id === event.id);\n\t\t\tif (existingIndex >= 0) {\n\t\t\t\tconst requirement = newState.requirements[existingIndex];\n\t\t\t\tconst updatedRequirements = [...newState.requirements];\n\t\t\t\tupdatedRequirements[existingIndex] = {\n\t\t\t\t\t...requirement,\n\t\t\t\t\tstatus: \"satisfied\",\n\t\t\t\t\tevidenceIds: [...event.evidenceIds],\n\t\t\t\t\tupdatedAt: event.now,\n\t\t\t\t\tblockedReason: undefined,\n\t\t\t\t};\n\t\t\t\tnewState.requirements = updatedRequirements;\n\t\t\t}\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"block_requirement\": {\n\t\t\tconst existingIndex = newState.requirements.findIndex((requirement) => requirement.id === event.id);\n\t\t\tif (existingIndex >= 0) {\n\t\t\t\tconst requirement = newState.requirements[existingIndex];\n\t\t\t\tconst updatedRequirements = [...newState.requirements];\n\t\t\t\tupdatedRequirements[existingIndex] = {\n\t\t\t\t\t...requirement,\n\t\t\t\t\tstatus: \"blocked\",\n\t\t\t\t\tblockedReason: event.blockedReason,\n\t\t\t\t\tupdatedAt: event.now,\n\t\t\t\t};\n\t\t\t\tnewState.requirements = updatedRequirements;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"reopen_requirement\": {\n\t\t\tconst existingIndex = newState.requirements.findIndex((requirement) => requirement.id === event.id);\n\t\t\tif (existingIndex >= 0) {\n\t\t\t\tconst requirement = newState.requirements[existingIndex];\n\t\t\t\tconst updatedRequirements = [...newState.requirements];\n\t\t\t\tupdatedRequirements[existingIndex] = {\n\t\t\t\t\t...requirement,\n\t\t\t\t\tstatus: \"open\",\n\t\t\t\t\tblockedReason: undefined,\n\t\t\t\t\tupdatedAt: event.now,\n\t\t\t\t};\n\t\t\t\tnewState.requirements = updatedRequirements;\n\t\t\t}\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"dispatch_worker\": {\n\t\t\t// Records the requirement<->lane binding ONLY -- never satisfies the requirement and never\n\t\t\t// touches lastProgressAt/stallTurns. The worker's own completion later populates \"worker\"\n\t\t\t// evidence and prompts an explicit satisfy_requirement pass through the existing gate.\n\t\t\tconst existingIndex = newState.requirements.findIndex((requirement) => requirement.id === event.id);\n\t\t\tif (existingIndex >= 0) {\n\t\t\t\tconst requirement = newState.requirements[existingIndex];\n\t\t\t\tconst updatedRequirements = [...newState.requirements];\n\t\t\t\tupdatedRequirements[existingIndex] = {\n\t\t\t\t\t...requirement,\n\t\t\t\t\tboundLaneId: event.laneId,\n\t\t\t\t\t// Start (or keep) the wait-timeout clock ONLY when this dispatch actually bound a real\n\t\t\t\t\t// lane -- a declined dispatch (no laneId) preserves whatever boundAt was already there.\n\t\t\t\t\tboundAt: event.laneId ? event.now : requirement.boundAt,\n\t\t\t\t\tupdatedAt: event.now,\n\t\t\t\t};\n\t\t\t\tnewState.requirements = updatedRequirements;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"add_evidence\": {\n\t\t\tconst existingIndex = newState.evidence.findIndex((evidence) => evidence.id === event.id);\n\t\t\tconst newEvidence: GoalEvidenceRef = {\n\t\t\t\tid: event.id,\n\t\t\t\tkind: event.kind,\n\t\t\t\tsummary: event.summary,\n\t\t\t\turi: event.uri,\n\t\t\t\tverified: event.verified,\n\t\t\t\tcreatedAt: existingIndex >= 0 ? newState.evidence[existingIndex].createdAt : event.now,\n\t\t\t};\n\t\t\tif (existingIndex >= 0) {\n\t\t\t\tconst updatedEvidence = [...newState.evidence];\n\t\t\t\tupdatedEvidence[existingIndex] = newEvidence;\n\t\t\t\tnewState.evidence = updatedEvidence;\n\t\t\t} else {\n\t\t\t\tnewState.evidence = [...newState.evidence, newEvidence];\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"progress\": {\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"no_progress\": {\n\t\t\tnewState.stallTurns = state.stallTurns + 1;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"record_continuation_budget\": {\n\t\t\tconst previousCheckpoint = state.continuationSpendCheckpointUsd;\n\t\t\t// No prior checkpoint (first pass ever recorded for this goal): there is no valid \"before\"\n\t\t\t// reading to diff against, so attribute a zero delta for this one pass rather than mis-count\n\t\t\t// all pre-goal-loop session spend into it. Every subsequent pass gets an accurate delta.\n\t\t\tconst spendDelta =\n\t\t\t\tpreviousCheckpoint === undefined ? 0 : Math.max(0, event.sessionCostUsd - previousCheckpoint);\n\t\t\tnewState.continuationTurnsUsed = (state.continuationTurnsUsed ?? 0) + event.turns;\n\t\t\tnewState.continuationWallClockMs = (state.continuationWallClockMs ?? 0) + event.wallClockMs;\n\t\t\tnewState.continuationSpendUsd = (state.continuationSpendUsd ?? 0) + spendDelta;\n\t\t\tnewState.continuationSpendCheckpointUsd = event.sessionCostUsd;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"complete_goal\": {\n\t\t\tconst hasUnsatisfied = newState.requirements.some((requirement) => requirement.status !== \"satisfied\");\n\t\t\tif (!hasUnsatisfied) {\n\t\t\t\tnewState.status = \"completed\";\n\t\t\t\tnewState.blockedReason = undefined;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"complete_goal_manually\": {\n\t\t\tnewState.status = \"completed\";\n\t\t\tnewState.blockedReason = undefined;\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"block_goal\": {\n\t\t\tnewState.status = \"blocked\";\n\t\t\tnewState.blockedReason = event.reason;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"resume_goal\": {\n\t\t\tnewState.status = \"active\";\n\t\t\tnewState.blockedReason = undefined;\n\t\t\tnewState.lastProgressAt = event.now;\n\t\t\tnewState.stallTurns = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"cancel_goal\": {\n\t\t\tnewState.status = \"cancelled\";\n\t\t\tnewState.blockedReason = undefined;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn newState;\n}\n\nexport function shouldContinueGoalLoop(args: { state: GoalState; maxStallTurns: number; now: string }): boolean {\n\tif (args.state.status !== \"active\") {\n\t\treturn false;\n\t}\n\tif (args.state.stallTurns >= args.maxStallTurns) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nexport function serializeGoalState(state: GoalState): string {\n\treturn JSON.stringify(cloneGoalState(state), null, 2);\n}\n\nexport function parseGoalState(text: string): GoalState | undefined {\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(text);\n\t\tif (!isGoalState(parsed)) return undefined;\n\t\treturn cloneGoalState(parsed);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"]}
|
|
@@ -28,12 +28,29 @@ export type GoalAction = {
|
|
|
28
28
|
} | {
|
|
29
29
|
action: "reopen_requirement";
|
|
30
30
|
requirementId: string;
|
|
31
|
+
} | {
|
|
32
|
+
action: "dispatch_worker";
|
|
33
|
+
requirementId: string;
|
|
34
|
+
instructions: string;
|
|
35
|
+
/**
|
|
36
|
+
* LaneId returned by the tool layer's dispatch side effect (calling the real worker/tmux
|
|
37
|
+
* dispatch). Computed by the tool layer -- which has session/runtime access -- and merged
|
|
38
|
+
* onto the action before it reaches this pure reducer, exactly like `add_evidence`'s
|
|
39
|
+
* `verified` field. Undefined when the dispatch side effect is unwired/stubbed.
|
|
40
|
+
*/
|
|
41
|
+
laneId?: string;
|
|
31
42
|
} | {
|
|
32
43
|
action: "add_evidence";
|
|
33
44
|
evidenceId: string;
|
|
34
45
|
kind: GoalEvidenceKind;
|
|
35
46
|
summary: string;
|
|
36
47
|
uri?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Whether `uri` was checked against session records/the filesystem. Computed by the
|
|
50
|
+
* tool layer (which has session/filesystem access); `applyGoalAction` stays pure and
|
|
51
|
+
* only carries this value through into the recorded {@link GoalEvidenceRef}.
|
|
52
|
+
*/
|
|
53
|
+
verified?: boolean;
|
|
37
54
|
} | {
|
|
38
55
|
action: "progress";
|
|
39
56
|
} | {
|
|
@@ -58,6 +75,15 @@ export interface GoalActionFailure {
|
|
|
58
75
|
error: string;
|
|
59
76
|
}
|
|
60
77
|
export type GoalActionResult = GoalActionSuccess | GoalActionFailure;
|
|
78
|
+
export interface ApplyGoalActionOptions {
|
|
79
|
+
/**
|
|
80
|
+
* Gate agent-facing 'complete' on at least one satisfied requirement being backed by
|
|
81
|
+
* verified-ref evidence (kind 'tool'/'file' with `verified === true`) or kind 'user'
|
|
82
|
+
* evidence. Defaults to `true` (on) when omitted — the conservative default. Manual
|
|
83
|
+
* completion ({@link completeGoalManually}) is never subject to this gate.
|
|
84
|
+
*/
|
|
85
|
+
requireVerifiedEvidenceForCompletion?: boolean;
|
|
86
|
+
}
|
|
61
87
|
/**
|
|
62
88
|
* Apply one agent-facing goal action to the current ledger state.
|
|
63
89
|
*
|
|
@@ -65,7 +91,7 @@ export type GoalActionResult = GoalActionSuccess | GoalActionFailure;
|
|
|
65
91
|
* action, and returns either the next state or a validation error. Performs no
|
|
66
92
|
* I/O and never mutates its inputs.
|
|
67
93
|
*/
|
|
68
|
-
export declare function applyGoalAction(current: GoalState | undefined, action: GoalAction, now: string): GoalActionResult;
|
|
94
|
+
export declare function applyGoalAction(current: GoalState | undefined, action: GoalAction, now: string, options?: ApplyGoalActionOptions): GoalActionResult;
|
|
69
95
|
/**
|
|
70
96
|
* Complete a goal on explicit user authority, even when requirements remain open or
|
|
71
97
|
* blocked. Agent-facing `complete` stays evidence-gated; this path is reserved for
|
|
@@ -73,5 +99,33 @@ export declare function applyGoalAction(current: GoalState | undefined, action:
|
|
|
73
99
|
*/
|
|
74
100
|
export declare function completeGoalManually(current: GoalState | undefined, now: string): GoalActionResult;
|
|
75
101
|
/** Render a compact human-readable summary of the ledger after an action. */
|
|
76
|
-
export declare function summarizeGoalState(state: GoalState
|
|
102
|
+
export declare function summarizeGoalState(state: GoalState, options?: {
|
|
103
|
+
action?: GoalAction;
|
|
104
|
+
openTaskSteps?: readonly OpenTaskStepRef[];
|
|
105
|
+
}): string;
|
|
106
|
+
/**
|
|
107
|
+
* Read-only goal⇄task cross-visibility (bounded slice — no shared state machine).
|
|
108
|
+
*
|
|
109
|
+
* `goal-tool-core` never reads or mutates task state itself (it stays pure); callers that DO
|
|
110
|
+
* have access to the branch-scoped open task steps (e.g. via `buildGoalRuntimeSnapshot`) may
|
|
111
|
+
* pass them through here to surface a nudge in the tool response when an open task_steps step
|
|
112
|
+
* appears to reference a requirement the agent just satisfied or completed. Task state is never
|
|
113
|
+
* written from goal code — this only reads an already-resolved, caller-supplied summary.
|
|
114
|
+
*/
|
|
115
|
+
export interface OpenTaskStepRef {
|
|
116
|
+
id: string;
|
|
117
|
+
content: string;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Nudge lines for open task steps that reference any of `requirementIds` (deduped per
|
|
121
|
+
* requirement, one line naming every referencing step). Empty when there is nothing to say.
|
|
122
|
+
*/
|
|
123
|
+
export declare function findRequirementCrossReferenceNudges(state: GoalState, requirementIds: readonly string[], openTaskSteps: readonly OpenTaskStepRef[]): string[];
|
|
124
|
+
/**
|
|
125
|
+
* After 'satisfy_requirement' or 'complete', nudge lines for open task steps whose content
|
|
126
|
+
* references a just-satisfied requirement. Returns `[]` for every other action, or when
|
|
127
|
+
* `openTaskSteps` was not supplied (the default -- backward compatible, no behavior change for
|
|
128
|
+
* callers that do not pass task-step context).
|
|
129
|
+
*/
|
|
130
|
+
export declare function buildGoalTaskCrossVisibilityNudges(action: GoalAction, state: GoalState, openTaskSteps: readonly OpenTaskStepRef[] | undefined): string[];
|
|
77
131
|
//# sourceMappingURL=goal-tool-core.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"goal-tool-core.d.ts","sourceRoot":"","sources":["../../../src/core/goals/goal-tool-core.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;;GASG;AACH,MAAM,MAAM,UAAU,GACnB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,MAAM,EAAE,iBAAiB,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAClE;IAAE,MAAM,EAAE,qBAAqB,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GACzF;IAAE,MAAM,EAAE,mBAAmB,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACtE;IAAE,MAAM,EAAE,oBAAoB,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACrG;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,GACtB;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,GACzB;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,GACtB;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,GACzB;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,CAAC;AAExB,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;AAElD,MAAM,WAAW,iBAAiB;IACjC,EAAE,EAAE,IAAI,CAAC;IACT,KAAK,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IACjC,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,GAAG,iBAAiB,CAAC;AAUrE;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,gBAAgB,CA8CjH;AAqGD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAWlG;AAED,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAW3D","sourcesContent":["import {\n\tapplyGoalEvent,\n\tcreateGoalState,\n\ttype GoalEvent,\n\ttype GoalEvidenceKind,\n\ttype GoalState,\n} from \"./goal-state.ts\";\n\n/**\n * Agent-facing goal ledger actions.\n *\n * This is the producer half of the goal continuation pipeline: the agent records\n * what it is trying to achieve and how far it has gotten, and those records become\n * the {@link GoalState} snapshots that the runtime continuation consumer reads.\n *\n * Each action maps onto either {@link createGoalState} or a single\n * {@link GoalEvent}, so the durable state model stays the single source of truth.\n */\nexport type GoalAction =\n\t| { action: \"start\"; goalId: string; userGoal: string }\n\t| { action: \"add_requirement\"; requirementId: string; text: string }\n\t| { action: \"satisfy_requirement\"; requirementId: string; evidenceIds?: readonly string[] }\n\t| { action: \"block_requirement\"; requirementId: string; reason: string }\n\t| { action: \"reopen_requirement\"; requirementId: string }\n\t| { action: \"add_evidence\"; evidenceId: string; kind: GoalEvidenceKind; summary: string; uri?: string }\n\t| { action: \"progress\" }\n\t| { action: \"no_progress\" }\n\t| { action: \"complete\" }\n\t| { action: \"block_goal\"; reason: string }\n\t| { action: \"resume_goal\" }\n\t| { action: \"cancel\" };\n\nexport type GoalActionName = GoalAction[\"action\"];\n\nexport interface GoalActionSuccess {\n\tok: true;\n\tstate: GoalState;\n}\n\nexport interface GoalActionFailure {\n\tok: false;\n\terror: string;\n}\n\nexport type GoalActionResult = GoalActionSuccess | GoalActionFailure;\n\nfunction requirementExists(state: GoalState, requirementId: string): boolean {\n\treturn state.requirements.some((requirement) => requirement.id === requirementId);\n}\n\nfunction evidenceExists(state: GoalState, evidenceId: string): boolean {\n\treturn state.evidence.some((evidence) => evidence.id === evidenceId);\n}\n\n/**\n * Apply one agent-facing goal action to the current ledger state.\n *\n * Pure: takes the current state (or `undefined` when no goal exists yet) and the\n * action, and returns either the next state or a validation error. Performs no\n * I/O and never mutates its inputs.\n */\nexport function applyGoalAction(current: GoalState | undefined, action: GoalAction, now: string): GoalActionResult {\n\tif (action.action === \"start\") {\n\t\tconst goalId = action.goalId.trim();\n\t\tconst userGoal = action.userGoal.trim();\n\t\tif (!goalId) return { ok: false, error: \"start requires a non-empty goalId.\" };\n\t\tif (!userGoal) return { ok: false, error: \"start requires a non-empty userGoal.\" };\n\t\tif (current && current.status === \"active\" && current.goalId !== goalId) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `An active goal '${current.goalId}' already exists. Complete, block, or cancel it before starting '${goalId}'.`,\n\t\t\t};\n\t\t}\n\t\treturn { ok: true, state: createGoalState({ goalId, userGoal, now }) };\n\t}\n\n\tif (!current) {\n\t\treturn { ok: false, error: \"No active goal. Use action 'start' before recording goal updates.\" };\n\t}\n\n\tif (action.action === \"resume_goal\") {\n\t\tif (current.status !== \"blocked\") {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Goal '${current.goalId}' is ${current.status}; only blocked goals can be resumed.`,\n\t\t\t};\n\t\t}\n\t\treturn { ok: true, state: applyGoalEvent(current, { type: \"resume_goal\", now }) };\n\t}\n\n\tif (current.status !== \"active\") {\n\t\tif (current.status === \"blocked\" && action.action === \"cancel\") {\n\t\t\treturn { ok: true, state: applyGoalEvent(current, { type: \"cancel_goal\", now }) };\n\t\t}\n\t\tconst recovery =\n\t\t\tcurrent.status === \"blocked\"\n\t\t\t\t? \"Resume it with action 'resume_goal', cancel it, or start a replacement goal.\"\n\t\t\t\t: \"Start a new goal before recording updates.\";\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: `Goal '${current.goalId}' is ${current.status}. ${recovery}`,\n\t\t};\n\t}\n\n\tconst event = toGoalEvent(current, action, now);\n\tif (!event.ok) return event;\n\treturn { ok: true, state: applyGoalEvent(current, event.event) };\n}\n\ntype ToGoalEventResult = { ok: true; event: GoalEvent } | GoalActionFailure;\n\nfunction toGoalEvent(state: GoalState, action: GoalAction, now: string): ToGoalEventResult {\n\tswitch (action.action) {\n\t\tcase \"add_requirement\": {\n\t\t\tconst id = action.requirementId.trim();\n\t\t\tconst text = action.text.trim();\n\t\t\tif (!id) return { ok: false, error: \"add_requirement requires a non-empty requirementId.\" };\n\t\t\tif (!text) return { ok: false, error: \"add_requirement requires non-empty text.\" };\n\t\t\tif (requirementExists(state, id)) {\n\t\t\t\treturn { ok: false, error: `Requirement '${id}' already exists.` };\n\t\t\t}\n\t\t\treturn { ok: true, event: { type: \"add_requirement\", id, text, now } };\n\t\t}\n\t\tcase \"satisfy_requirement\": {\n\t\t\tconst id = action.requirementId.trim();\n\t\t\tif (!id) return { ok: false, error: \"satisfy_requirement requires a non-empty requirementId.\" };\n\t\t\tif (!requirementExists(state, id)) {\n\t\t\t\treturn { ok: false, error: `Unknown requirement '${id}'.` };\n\t\t\t}\n\t\t\tconst evidenceIds = action.evidenceIds ?? [];\n\t\t\tfor (const evidenceId of evidenceIds) {\n\t\t\t\tif (!evidenceExists(state, evidenceId)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tok: false,\n\t\t\t\t\t\terror: `Unknown evidence '${evidenceId}'. Record it with action 'add_evidence' first.`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn { ok: true, event: { type: \"satisfy_requirement\", id, evidenceIds: [...evidenceIds], now } };\n\t\t}\n\t\tcase \"block_requirement\": {\n\t\t\tconst id = action.requirementId.trim();\n\t\t\tconst reason = action.reason.trim();\n\t\t\tif (!id) return { ok: false, error: \"block_requirement requires a non-empty requirementId.\" };\n\t\t\tif (!reason) return { ok: false, error: \"block_requirement requires a non-empty reason.\" };\n\t\t\tif (!requirementExists(state, id)) {\n\t\t\t\treturn { ok: false, error: `Unknown requirement '${id}'.` };\n\t\t\t}\n\t\t\treturn { ok: true, event: { type: \"block_requirement\", id, blockedReason: reason, now } };\n\t\t}\n\t\tcase \"reopen_requirement\": {\n\t\t\tconst id = action.requirementId.trim();\n\t\t\tif (!id) return { ok: false, error: \"reopen_requirement requires a non-empty requirementId.\" };\n\t\t\tconst requirement = state.requirements.find((candidate) => candidate.id === id);\n\t\t\tif (!requirement) {\n\t\t\t\treturn { ok: false, error: `Unknown requirement '${id}'.` };\n\t\t\t}\n\t\t\tif (requirement.status !== \"blocked\") {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Requirement '${id}' is ${requirement.status}; only blocked requirements can be reopened.`,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn { ok: true, event: { type: \"reopen_requirement\", id, now } };\n\t\t}\n\t\tcase \"add_evidence\": {\n\t\t\tconst id = action.evidenceId.trim();\n\t\t\tconst summary = action.summary.trim();\n\t\t\tif (!id) return { ok: false, error: \"add_evidence requires a non-empty evidenceId.\" };\n\t\t\tif (!summary) return { ok: false, error: \"add_evidence requires a non-empty summary.\" };\n\t\t\tif (evidenceExists(state, id)) {\n\t\t\t\treturn { ok: false, error: `Evidence '${id}' already exists.` };\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\tevent: { type: \"add_evidence\", id, kind: action.kind, summary, uri: action.uri?.trim() || undefined, now },\n\t\t\t};\n\t\t}\n\t\tcase \"progress\":\n\t\t\treturn { ok: true, event: { type: \"progress\", now } };\n\t\tcase \"no_progress\":\n\t\t\treturn { ok: true, event: { type: \"no_progress\", now } };\n\t\tcase \"complete\": {\n\t\t\tconst unsatisfied = state.requirements.filter((requirement) => requirement.status !== \"satisfied\");\n\t\t\tif (unsatisfied.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Cannot complete goal: ${unsatisfied.length} requirement(s) not satisfied (${unsatisfied\n\t\t\t\t\t\t.map((requirement) => requirement.id)\n\t\t\t\t\t\t.join(\", \")}).`,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn { ok: true, event: { type: \"complete_goal\", now } };\n\t\t}\n\t\tcase \"block_goal\": {\n\t\t\tconst reason = action.reason.trim();\n\t\t\tif (!reason) return { ok: false, error: \"block_goal requires a non-empty reason.\" };\n\t\t\treturn { ok: true, event: { type: \"block_goal\", reason, now } };\n\t\t}\n\t\tcase \"resume_goal\":\n\t\t\treturn { ok: true, event: { type: \"resume_goal\", now } };\n\t\tcase \"cancel\":\n\t\t\treturn { ok: true, event: { type: \"cancel_goal\", now } };\n\t\tdefault:\n\t\t\treturn { ok: false, error: \"Unknown goal action.\" };\n\t}\n}\n\n/**\n * Complete a goal on explicit user authority, even when requirements remain open or\n * blocked. Agent-facing `complete` stays evidence-gated; this path is reserved for\n * direct user lifecycle controls.\n */\nexport function completeGoalManually(current: GoalState | undefined, now: string): GoalActionResult {\n\tif (!current) {\n\t\treturn { ok: false, error: \"No goal exists to complete.\" };\n\t}\n\tif (current.status === \"completed\") {\n\t\treturn { ok: false, error: `Goal '${current.goalId}' is already completed.` };\n\t}\n\tif (current.status === \"cancelled\") {\n\t\treturn { ok: false, error: `Goal '${current.goalId}' is cancelled; start or override with a new goal.` };\n\t}\n\treturn { ok: true, state: applyGoalEvent(current, { type: \"complete_goal_manually\", now }) };\n}\n\n/** Render a compact human-readable summary of the ledger after an action. */\nexport function summarizeGoalState(state: GoalState): string {\n\tconst open = state.requirements.filter((requirement) => requirement.status === \"open\").length;\n\tconst satisfied = state.requirements.filter((requirement) => requirement.status === \"satisfied\").length;\n\tconst blocked = state.requirements.filter((requirement) => requirement.status === \"blocked\").length;\n\tconst lines = [\n\t\t`Goal '${state.goalId}' (${state.status}): ${state.userGoal}`,\n\t\t`Requirements: ${state.requirements.length} total — ${open} open, ${satisfied} satisfied, ${blocked} blocked.`,\n\t\t`Evidence: ${state.evidence.length}. Stall turns: ${state.stallTurns}.`,\n\t];\n\tif (state.blockedReason) lines.push(`Blocked reason: ${state.blockedReason}`);\n\treturn lines.join(\"\\n\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"goal-tool-core.d.ts","sourceRoot":"","sources":["../../../src/core/goals/goal-tool-core.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tapplyGoalEvent,\n\tcreateGoalState,\n\ttype GoalEvent,\n\ttype GoalEvidenceKind,\n\ttype GoalState,\n} from \"./goal-state.ts\";\n\n/**\n * Agent-facing goal ledger actions.\n *\n * This is the producer half of the goal continuation pipeline: the agent records\n * what it is trying to achieve and how far it has gotten, and those records become\n * the {@link GoalState} snapshots that the runtime continuation consumer reads.\n *\n * Each action maps onto either {@link createGoalState} or a single\n * {@link GoalEvent}, so the durable state model stays the single source of truth.\n */\nexport type GoalAction =\n\t| { action: \"start\"; goalId: string; userGoal: string }\n\t| { action: \"add_requirement\"; requirementId: string; text: string }\n\t| { action: \"satisfy_requirement\"; requirementId: string; evidenceIds?: readonly string[] }\n\t| { action: \"block_requirement\"; requirementId: string; reason: string }\n\t| { action: \"reopen_requirement\"; requirementId: string }\n\t| {\n\t\t\taction: \"dispatch_worker\";\n\t\t\trequirementId: string;\n\t\t\tinstructions: string;\n\t\t\t/**\n\t\t\t * LaneId returned by the tool layer's dispatch side effect (calling the real worker/tmux\n\t\t\t * dispatch). Computed by the tool layer -- which has session/runtime access -- and merged\n\t\t\t * onto the action before it reaches this pure reducer, exactly like `add_evidence`'s\n\t\t\t * `verified` field. Undefined when the dispatch side effect is unwired/stubbed.\n\t\t\t */\n\t\t\tlaneId?: string;\n\t }\n\t| {\n\t\t\taction: \"add_evidence\";\n\t\t\tevidenceId: string;\n\t\t\tkind: GoalEvidenceKind;\n\t\t\tsummary: string;\n\t\t\turi?: string;\n\t\t\t/**\n\t\t\t * Whether `uri` was checked against session records/the filesystem. Computed by the\n\t\t\t * tool layer (which has session/filesystem access); `applyGoalAction` stays pure and\n\t\t\t * only carries this value through into the recorded {@link GoalEvidenceRef}.\n\t\t\t */\n\t\t\tverified?: boolean;\n\t }\n\t| { action: \"progress\" }\n\t| { action: \"no_progress\" }\n\t| { action: \"complete\" }\n\t| { action: \"block_goal\"; reason: string }\n\t| { action: \"resume_goal\" }\n\t| { action: \"cancel\" };\n\nexport type GoalActionName = GoalAction[\"action\"];\n\nexport interface GoalActionSuccess {\n\tok: true;\n\tstate: GoalState;\n}\n\nexport interface GoalActionFailure {\n\tok: false;\n\terror: string;\n}\n\nexport type GoalActionResult = GoalActionSuccess | GoalActionFailure;\n\nexport interface ApplyGoalActionOptions {\n\t/**\n\t * Gate agent-facing 'complete' on at least one satisfied requirement being backed by\n\t * verified-ref evidence (kind 'tool'/'file' with `verified === true`) or kind 'user'\n\t * evidence. Defaults to `true` (on) when omitted — the conservative default. Manual\n\t * completion ({@link completeGoalManually}) is never subject to this gate.\n\t */\n\trequireVerifiedEvidenceForCompletion?: boolean;\n}\n\nfunction requirementExists(state: GoalState, requirementId: string): boolean {\n\treturn state.requirements.some((requirement) => requirement.id === requirementId);\n}\n\nfunction evidenceExists(state: GoalState, evidenceId: string): boolean {\n\treturn state.evidence.some((evidence) => evidence.id === evidenceId);\n}\n\nfunction isVerifiedOrUserEvidence(evidence: GoalState[\"evidence\"][number]): boolean {\n\treturn evidence.kind === \"user\" || evidence.verified === true;\n}\n\n/** Does at least one SATISFIED requirement cite evidence that is verified-ref or kind:'user'? */\nfunction hasEvidenceBackedSatisfaction(state: GoalState): boolean {\n\treturn state.requirements.some((requirement) => {\n\t\tif (requirement.status !== \"satisfied\") return false;\n\t\treturn requirement.evidenceIds.some((evidenceId) => {\n\t\t\tconst evidence = state.evidence.find((candidate) => candidate.id === evidenceId);\n\t\t\treturn evidence !== undefined && isVerifiedOrUserEvidence(evidence);\n\t\t});\n\t});\n}\n\n/**\n * Apply one agent-facing goal action to the current ledger state.\n *\n * Pure: takes the current state (or `undefined` when no goal exists yet) and the\n * action, and returns either the next state or a validation error. Performs no\n * I/O and never mutates its inputs.\n */\nexport function applyGoalAction(\n\tcurrent: GoalState | undefined,\n\taction: GoalAction,\n\tnow: string,\n\toptions?: ApplyGoalActionOptions,\n): GoalActionResult {\n\tif (action.action === \"start\") {\n\t\tconst goalId = action.goalId.trim();\n\t\tconst userGoal = action.userGoal.trim();\n\t\tif (!goalId) return { ok: false, error: \"start requires a non-empty goalId.\" };\n\t\tif (!userGoal) return { ok: false, error: \"start requires a non-empty userGoal.\" };\n\t\tif (current && current.status === \"active\" && current.goalId !== goalId) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `An active goal '${current.goalId}' already exists. Complete, block, or cancel it before starting '${goalId}'.`,\n\t\t\t};\n\t\t}\n\t\treturn { ok: true, state: createGoalState({ goalId, userGoal, now }) };\n\t}\n\n\tif (!current) {\n\t\treturn { ok: false, error: \"No active goal. Use action 'start' before recording goal updates.\" };\n\t}\n\n\tif (action.action === \"resume_goal\") {\n\t\tif (current.status !== \"blocked\") {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `Goal '${current.goalId}' is ${current.status}; only blocked goals can be resumed.`,\n\t\t\t};\n\t\t}\n\t\treturn { ok: true, state: applyGoalEvent(current, { type: \"resume_goal\", now }) };\n\t}\n\n\tif (current.status !== \"active\") {\n\t\tif (current.status === \"blocked\" && action.action === \"cancel\") {\n\t\t\treturn { ok: true, state: applyGoalEvent(current, { type: \"cancel_goal\", now }) };\n\t\t}\n\t\tconst recovery =\n\t\t\tcurrent.status === \"blocked\"\n\t\t\t\t? \"Resume it with action 'resume_goal', cancel it, or start a replacement goal.\"\n\t\t\t\t: \"Start a new goal before recording updates.\";\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: `Goal '${current.goalId}' is ${current.status}. ${recovery}`,\n\t\t};\n\t}\n\n\tconst event = toGoalEvent(current, action, now, options);\n\tif (!event.ok) return event;\n\treturn { ok: true, state: applyGoalEvent(current, event.event) };\n}\n\ntype ToGoalEventResult = { ok: true; event: GoalEvent } | GoalActionFailure;\n\nfunction toGoalEvent(\n\tstate: GoalState,\n\taction: GoalAction,\n\tnow: string,\n\toptions: ApplyGoalActionOptions | undefined,\n): ToGoalEventResult {\n\tswitch (action.action) {\n\t\tcase \"add_requirement\": {\n\t\t\tconst id = action.requirementId.trim();\n\t\t\tconst text = action.text.trim();\n\t\t\tif (!id) return { ok: false, error: \"add_requirement requires a non-empty requirementId.\" };\n\t\t\tif (!text) return { ok: false, error: \"add_requirement requires non-empty text.\" };\n\t\t\tif (requirementExists(state, id)) {\n\t\t\t\treturn { ok: false, error: `Requirement '${id}' already exists.` };\n\t\t\t}\n\t\t\treturn { ok: true, event: { type: \"add_requirement\", id, text, now } };\n\t\t}\n\t\tcase \"satisfy_requirement\": {\n\t\t\tconst id = action.requirementId.trim();\n\t\t\tif (!id) return { ok: false, error: \"satisfy_requirement requires a non-empty requirementId.\" };\n\t\t\tif (!requirementExists(state, id)) {\n\t\t\t\treturn { ok: false, error: `Unknown requirement '${id}'.` };\n\t\t\t}\n\t\t\tconst evidenceIds = action.evidenceIds ?? [];\n\t\t\tfor (const evidenceId of evidenceIds) {\n\t\t\t\tif (!evidenceExists(state, evidenceId)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tok: false,\n\t\t\t\t\t\terror: `Unknown evidence '${evidenceId}'. Record it with action 'add_evidence' first.`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn { ok: true, event: { type: \"satisfy_requirement\", id, evidenceIds: [...evidenceIds], now } };\n\t\t}\n\t\tcase \"block_requirement\": {\n\t\t\tconst id = action.requirementId.trim();\n\t\t\tconst reason = action.reason.trim();\n\t\t\tif (!id) return { ok: false, error: \"block_requirement requires a non-empty requirementId.\" };\n\t\t\tif (!reason) return { ok: false, error: \"block_requirement requires a non-empty reason.\" };\n\t\t\tif (!requirementExists(state, id)) {\n\t\t\t\treturn { ok: false, error: `Unknown requirement '${id}'.` };\n\t\t\t}\n\t\t\treturn { ok: true, event: { type: \"block_requirement\", id, blockedReason: reason, now } };\n\t\t}\n\t\tcase \"reopen_requirement\": {\n\t\t\tconst id = action.requirementId.trim();\n\t\t\tif (!id) return { ok: false, error: \"reopen_requirement requires a non-empty requirementId.\" };\n\t\t\tconst requirement = state.requirements.find((candidate) => candidate.id === id);\n\t\t\tif (!requirement) {\n\t\t\t\treturn { ok: false, error: `Unknown requirement '${id}'.` };\n\t\t\t}\n\t\t\tif (requirement.status !== \"blocked\") {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Requirement '${id}' is ${requirement.status}; only blocked requirements can be reopened.`,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn { ok: true, event: { type: \"reopen_requirement\", id, now } };\n\t\t}\n\t\tcase \"dispatch_worker\": {\n\t\t\tconst id = action.requirementId.trim();\n\t\t\tconst instructions = action.instructions.trim();\n\t\t\tif (!id) return { ok: false, error: \"dispatch_worker requires a non-empty requirementId.\" };\n\t\t\tif (!instructions) return { ok: false, error: \"dispatch_worker requires non-empty instructions.\" };\n\t\t\tif (!requirementExists(state, id)) {\n\t\t\t\treturn { ok: false, error: `Unknown requirement '${id}'.` };\n\t\t\t}\n\t\t\treturn { ok: true, event: { type: \"dispatch_worker\", id, instructions, laneId: action.laneId, now } };\n\t\t}\n\t\tcase \"add_evidence\": {\n\t\t\tconst id = action.evidenceId.trim();\n\t\t\tconst summary = action.summary.trim();\n\t\t\tif (!id) return { ok: false, error: \"add_evidence requires a non-empty evidenceId.\" };\n\t\t\tif (!summary) return { ok: false, error: \"add_evidence requires a non-empty summary.\" };\n\t\t\tif (evidenceExists(state, id)) {\n\t\t\t\treturn { ok: false, error: `Evidence '${id}' already exists.` };\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\tevent: {\n\t\t\t\t\ttype: \"add_evidence\",\n\t\t\t\t\tid,\n\t\t\t\t\tkind: action.kind,\n\t\t\t\t\tsummary,\n\t\t\t\t\turi: action.uri?.trim() || undefined,\n\t\t\t\t\tverified: action.verified,\n\t\t\t\t\tnow,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tcase \"progress\":\n\t\t\treturn { ok: true, event: { type: \"progress\", now } };\n\t\tcase \"no_progress\":\n\t\t\treturn { ok: true, event: { type: \"no_progress\", now } };\n\t\tcase \"complete\": {\n\t\t\tconst unsatisfied = state.requirements.filter((requirement) => requirement.status !== \"satisfied\");\n\t\t\tif (unsatisfied.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: `Cannot complete goal: ${unsatisfied.length} requirement(s) not satisfied (${unsatisfied\n\t\t\t\t\t\t.map((requirement) => requirement.id)\n\t\t\t\t\t\t.join(\", \")}).`,\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst requireVerifiedEvidence = options?.requireVerifiedEvidenceForCompletion ?? true;\n\t\t\tif (requireVerifiedEvidence && !hasEvidenceBackedSatisfaction(state)) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: \"Cannot complete goal: no satisfied requirement is backed by verified evidence (kind 'tool'/'file' with a validated ref) or kind 'user' evidence. Record such evidence with 'add_evidence' and cite it in 'satisfy_requirement'.\",\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn { ok: true, event: { type: \"complete_goal\", now } };\n\t\t}\n\t\tcase \"block_goal\": {\n\t\t\tconst reason = action.reason.trim();\n\t\t\tif (!reason) return { ok: false, error: \"block_goal requires a non-empty reason.\" };\n\t\t\treturn { ok: true, event: { type: \"block_goal\", reason, now } };\n\t\t}\n\t\tcase \"resume_goal\":\n\t\t\treturn { ok: true, event: { type: \"resume_goal\", now } };\n\t\tcase \"cancel\":\n\t\t\treturn { ok: true, event: { type: \"cancel_goal\", now } };\n\t\tdefault:\n\t\t\treturn { ok: false, error: \"Unknown goal action.\" };\n\t}\n}\n\n/**\n * Complete a goal on explicit user authority, even when requirements remain open or\n * blocked. Agent-facing `complete` stays evidence-gated; this path is reserved for\n * direct user lifecycle controls.\n */\nexport function completeGoalManually(current: GoalState | undefined, now: string): GoalActionResult {\n\tif (!current) {\n\t\treturn { ok: false, error: \"No goal exists to complete.\" };\n\t}\n\tif (current.status === \"completed\") {\n\t\treturn { ok: false, error: `Goal '${current.goalId}' is already completed.` };\n\t}\n\tif (current.status === \"cancelled\") {\n\t\treturn { ok: false, error: `Goal '${current.goalId}' is cancelled; start or override with a new goal.` };\n\t}\n\treturn { ok: true, state: applyGoalEvent(current, { type: \"complete_goal_manually\", now }) };\n}\n\n/** Render a compact human-readable summary of the ledger after an action. */\nexport function summarizeGoalState(\n\tstate: GoalState,\n\toptions?: { action?: GoalAction; openTaskSteps?: readonly OpenTaskStepRef[] },\n): string {\n\tconst open = state.requirements.filter((requirement) => requirement.status === \"open\").length;\n\tconst satisfied = state.requirements.filter((requirement) => requirement.status === \"satisfied\").length;\n\tconst blocked = state.requirements.filter((requirement) => requirement.status === \"blocked\").length;\n\tconst lines = [\n\t\t`Goal '${state.goalId}' (${state.status}): ${state.userGoal}`,\n\t\t`Requirements: ${state.requirements.length} total — ${open} open, ${satisfied} satisfied, ${blocked} blocked.`,\n\t\t`Evidence: ${state.evidence.length}. Stall turns: ${state.stallTurns}.`,\n\t];\n\tif (state.blockedReason) lines.push(`Blocked reason: ${state.blockedReason}`);\n\tif (options?.action) {\n\t\tlines.push(...buildGoalTaskCrossVisibilityNudges(options.action, state, options.openTaskSteps));\n\t}\n\treturn lines.join(\"\\n\");\n}\n\n/**\n * Read-only goal⇄task cross-visibility (bounded slice — no shared state machine).\n *\n * `goal-tool-core` never reads or mutates task state itself (it stays pure); callers that DO\n * have access to the branch-scoped open task steps (e.g. via `buildGoalRuntimeSnapshot`) may\n * pass them through here to surface a nudge in the tool response when an open task_steps step\n * appears to reference a requirement the agent just satisfied or completed. Task state is never\n * written from goal code — this only reads an already-resolved, caller-supplied summary.\n */\nexport interface OpenTaskStepRef {\n\tid: string;\n\tcontent: string;\n}\n\nfunction escapeRegExp(text: string): string {\n\treturn text.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Cheap, conservative cross-reference: an open task step \"references\" a requirement when its\n * content contains the requirement id as a whole token (not a substring of a longer token), or\n * contains the requirement's full text verbatim (case-insensitive). Both conditions are chosen\n * to avoid noisy partial-word matches -- a short common id or a coincidental few-word overlap\n * does not qualify.\n */\nfunction taskStepReferencesRequirement(step: OpenTaskStepRef, requirement: { id: string; text: string }): boolean {\n\tconst idToken = requirement.id.trim();\n\tif (idToken.length >= 2) {\n\t\tconst idPattern = new RegExp(`(^|[^a-z0-9])${escapeRegExp(idToken.toLocaleLowerCase())}([^a-z0-9]|$)`, \"i\");\n\t\tif (idPattern.test(step.content)) return true;\n\t}\n\tconst text = requirement.text.trim();\n\tif (text.length >= 8 && step.content.toLocaleLowerCase().includes(text.toLocaleLowerCase())) return true;\n\treturn false;\n}\n\n/**\n * Nudge lines for open task steps that reference any of `requirementIds` (deduped per\n * requirement, one line naming every referencing step). Empty when there is nothing to say.\n */\nexport function findRequirementCrossReferenceNudges(\n\tstate: GoalState,\n\trequirementIds: readonly string[],\n\topenTaskSteps: readonly OpenTaskStepRef[],\n): string[] {\n\tif (openTaskSteps.length === 0 || requirementIds.length === 0) return [];\n\tconst nudges: string[] = [];\n\tfor (const requirementId of requirementIds) {\n\t\tconst requirement = state.requirements.find((candidate) => candidate.id === requirementId);\n\t\tif (!requirement) continue;\n\t\tconst referencing = openTaskSteps.filter((step) => taskStepReferencesRequirement(step, requirement));\n\t\tif (referencing.length === 0) continue;\n\t\tconst stepList = referencing.map((step) => step.id).join(\", \");\n\t\tnudges.push(\n\t\t\t`Note: open task step(s) ${stepList} appear to reference satisfied requirement '${requirement.id}' -- consider updating them via task_steps once covered.`,\n\t\t);\n\t}\n\treturn nudges;\n}\n\n/**\n * After 'satisfy_requirement' or 'complete', nudge lines for open task steps whose content\n * references a just-satisfied requirement. Returns `[]` for every other action, or when\n * `openTaskSteps` was not supplied (the default -- backward compatible, no behavior change for\n * callers that do not pass task-step context).\n */\nexport function buildGoalTaskCrossVisibilityNudges(\n\taction: GoalAction,\n\tstate: GoalState,\n\topenTaskSteps: readonly OpenTaskStepRef[] | undefined,\n): string[] {\n\tif (!openTaskSteps || openTaskSteps.length === 0) return [];\n\tif (action.action === \"satisfy_requirement\") {\n\t\treturn findRequirementCrossReferenceNudges(state, [action.requirementId.trim()], openTaskSteps);\n\t}\n\tif (action.action === \"complete\") {\n\t\tconst satisfiedIds = state.requirements\n\t\t\t.filter((requirement) => requirement.status === \"satisfied\")\n\t\t\t.map((requirement) => requirement.id);\n\t\treturn findRequirementCrossReferenceNudges(state, satisfiedIds, openTaskSteps);\n\t}\n\treturn [];\n}\n"]}
|
|
@@ -5,6 +5,20 @@ function requirementExists(state, requirementId) {
|
|
|
5
5
|
function evidenceExists(state, evidenceId) {
|
|
6
6
|
return state.evidence.some((evidence) => evidence.id === evidenceId);
|
|
7
7
|
}
|
|
8
|
+
function isVerifiedOrUserEvidence(evidence) {
|
|
9
|
+
return evidence.kind === "user" || evidence.verified === true;
|
|
10
|
+
}
|
|
11
|
+
/** Does at least one SATISFIED requirement cite evidence that is verified-ref or kind:'user'? */
|
|
12
|
+
function hasEvidenceBackedSatisfaction(state) {
|
|
13
|
+
return state.requirements.some((requirement) => {
|
|
14
|
+
if (requirement.status !== "satisfied")
|
|
15
|
+
return false;
|
|
16
|
+
return requirement.evidenceIds.some((evidenceId) => {
|
|
17
|
+
const evidence = state.evidence.find((candidate) => candidate.id === evidenceId);
|
|
18
|
+
return evidence !== undefined && isVerifiedOrUserEvidence(evidence);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
}
|
|
8
22
|
/**
|
|
9
23
|
* Apply one agent-facing goal action to the current ledger state.
|
|
10
24
|
*
|
|
@@ -12,7 +26,7 @@ function evidenceExists(state, evidenceId) {
|
|
|
12
26
|
* action, and returns either the next state or a validation error. Performs no
|
|
13
27
|
* I/O and never mutates its inputs.
|
|
14
28
|
*/
|
|
15
|
-
export function applyGoalAction(current, action, now) {
|
|
29
|
+
export function applyGoalAction(current, action, now, options) {
|
|
16
30
|
if (action.action === "start") {
|
|
17
31
|
const goalId = action.goalId.trim();
|
|
18
32
|
const userGoal = action.userGoal.trim();
|
|
@@ -52,12 +66,12 @@ export function applyGoalAction(current, action, now) {
|
|
|
52
66
|
error: `Goal '${current.goalId}' is ${current.status}. ${recovery}`,
|
|
53
67
|
};
|
|
54
68
|
}
|
|
55
|
-
const event = toGoalEvent(current, action, now);
|
|
69
|
+
const event = toGoalEvent(current, action, now, options);
|
|
56
70
|
if (!event.ok)
|
|
57
71
|
return event;
|
|
58
72
|
return { ok: true, state: applyGoalEvent(current, event.event) };
|
|
59
73
|
}
|
|
60
|
-
function toGoalEvent(state, action, now) {
|
|
74
|
+
function toGoalEvent(state, action, now, options) {
|
|
61
75
|
switch (action.action) {
|
|
62
76
|
case "add_requirement": {
|
|
63
77
|
const id = action.requirementId.trim();
|
|
@@ -117,6 +131,18 @@ function toGoalEvent(state, action, now) {
|
|
|
117
131
|
}
|
|
118
132
|
return { ok: true, event: { type: "reopen_requirement", id, now } };
|
|
119
133
|
}
|
|
134
|
+
case "dispatch_worker": {
|
|
135
|
+
const id = action.requirementId.trim();
|
|
136
|
+
const instructions = action.instructions.trim();
|
|
137
|
+
if (!id)
|
|
138
|
+
return { ok: false, error: "dispatch_worker requires a non-empty requirementId." };
|
|
139
|
+
if (!instructions)
|
|
140
|
+
return { ok: false, error: "dispatch_worker requires non-empty instructions." };
|
|
141
|
+
if (!requirementExists(state, id)) {
|
|
142
|
+
return { ok: false, error: `Unknown requirement '${id}'.` };
|
|
143
|
+
}
|
|
144
|
+
return { ok: true, event: { type: "dispatch_worker", id, instructions, laneId: action.laneId, now } };
|
|
145
|
+
}
|
|
120
146
|
case "add_evidence": {
|
|
121
147
|
const id = action.evidenceId.trim();
|
|
122
148
|
const summary = action.summary.trim();
|
|
@@ -129,7 +155,15 @@ function toGoalEvent(state, action, now) {
|
|
|
129
155
|
}
|
|
130
156
|
return {
|
|
131
157
|
ok: true,
|
|
132
|
-
event: {
|
|
158
|
+
event: {
|
|
159
|
+
type: "add_evidence",
|
|
160
|
+
id,
|
|
161
|
+
kind: action.kind,
|
|
162
|
+
summary,
|
|
163
|
+
uri: action.uri?.trim() || undefined,
|
|
164
|
+
verified: action.verified,
|
|
165
|
+
now,
|
|
166
|
+
},
|
|
133
167
|
};
|
|
134
168
|
}
|
|
135
169
|
case "progress":
|
|
@@ -146,6 +180,13 @@ function toGoalEvent(state, action, now) {
|
|
|
146
180
|
.join(", ")}).`,
|
|
147
181
|
};
|
|
148
182
|
}
|
|
183
|
+
const requireVerifiedEvidence = options?.requireVerifiedEvidenceForCompletion ?? true;
|
|
184
|
+
if (requireVerifiedEvidence && !hasEvidenceBackedSatisfaction(state)) {
|
|
185
|
+
return {
|
|
186
|
+
ok: false,
|
|
187
|
+
error: "Cannot complete goal: no satisfied requirement is backed by verified evidence (kind 'tool'/'file' with a validated ref) or kind 'user' evidence. Record such evidence with 'add_evidence' and cite it in 'satisfy_requirement'.",
|
|
188
|
+
};
|
|
189
|
+
}
|
|
149
190
|
return { ok: true, event: { type: "complete_goal", now } };
|
|
150
191
|
}
|
|
151
192
|
case "block_goal": {
|
|
@@ -180,7 +221,7 @@ export function completeGoalManually(current, now) {
|
|
|
180
221
|
return { ok: true, state: applyGoalEvent(current, { type: "complete_goal_manually", now }) };
|
|
181
222
|
}
|
|
182
223
|
/** Render a compact human-readable summary of the ledger after an action. */
|
|
183
|
-
export function summarizeGoalState(state) {
|
|
224
|
+
export function summarizeGoalState(state, options) {
|
|
184
225
|
const open = state.requirements.filter((requirement) => requirement.status === "open").length;
|
|
185
226
|
const satisfied = state.requirements.filter((requirement) => requirement.status === "satisfied").length;
|
|
186
227
|
const blocked = state.requirements.filter((requirement) => requirement.status === "blocked").length;
|
|
@@ -191,6 +232,71 @@ export function summarizeGoalState(state) {
|
|
|
191
232
|
];
|
|
192
233
|
if (state.blockedReason)
|
|
193
234
|
lines.push(`Blocked reason: ${state.blockedReason}`);
|
|
235
|
+
if (options?.action) {
|
|
236
|
+
lines.push(...buildGoalTaskCrossVisibilityNudges(options.action, state, options.openTaskSteps));
|
|
237
|
+
}
|
|
194
238
|
return lines.join("\n");
|
|
195
239
|
}
|
|
240
|
+
function escapeRegExp(text) {
|
|
241
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Cheap, conservative cross-reference: an open task step "references" a requirement when its
|
|
245
|
+
* content contains the requirement id as a whole token (not a substring of a longer token), or
|
|
246
|
+
* contains the requirement's full text verbatim (case-insensitive). Both conditions are chosen
|
|
247
|
+
* to avoid noisy partial-word matches -- a short common id or a coincidental few-word overlap
|
|
248
|
+
* does not qualify.
|
|
249
|
+
*/
|
|
250
|
+
function taskStepReferencesRequirement(step, requirement) {
|
|
251
|
+
const idToken = requirement.id.trim();
|
|
252
|
+
if (idToken.length >= 2) {
|
|
253
|
+
const idPattern = new RegExp(`(^|[^a-z0-9])${escapeRegExp(idToken.toLocaleLowerCase())}([^a-z0-9]|$)`, "i");
|
|
254
|
+
if (idPattern.test(step.content))
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
257
|
+
const text = requirement.text.trim();
|
|
258
|
+
if (text.length >= 8 && step.content.toLocaleLowerCase().includes(text.toLocaleLowerCase()))
|
|
259
|
+
return true;
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Nudge lines for open task steps that reference any of `requirementIds` (deduped per
|
|
264
|
+
* requirement, one line naming every referencing step). Empty when there is nothing to say.
|
|
265
|
+
*/
|
|
266
|
+
export function findRequirementCrossReferenceNudges(state, requirementIds, openTaskSteps) {
|
|
267
|
+
if (openTaskSteps.length === 0 || requirementIds.length === 0)
|
|
268
|
+
return [];
|
|
269
|
+
const nudges = [];
|
|
270
|
+
for (const requirementId of requirementIds) {
|
|
271
|
+
const requirement = state.requirements.find((candidate) => candidate.id === requirementId);
|
|
272
|
+
if (!requirement)
|
|
273
|
+
continue;
|
|
274
|
+
const referencing = openTaskSteps.filter((step) => taskStepReferencesRequirement(step, requirement));
|
|
275
|
+
if (referencing.length === 0)
|
|
276
|
+
continue;
|
|
277
|
+
const stepList = referencing.map((step) => step.id).join(", ");
|
|
278
|
+
nudges.push(`Note: open task step(s) ${stepList} appear to reference satisfied requirement '${requirement.id}' -- consider updating them via task_steps once covered.`);
|
|
279
|
+
}
|
|
280
|
+
return nudges;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* After 'satisfy_requirement' or 'complete', nudge lines for open task steps whose content
|
|
284
|
+
* references a just-satisfied requirement. Returns `[]` for every other action, or when
|
|
285
|
+
* `openTaskSteps` was not supplied (the default -- backward compatible, no behavior change for
|
|
286
|
+
* callers that do not pass task-step context).
|
|
287
|
+
*/
|
|
288
|
+
export function buildGoalTaskCrossVisibilityNudges(action, state, openTaskSteps) {
|
|
289
|
+
if (!openTaskSteps || openTaskSteps.length === 0)
|
|
290
|
+
return [];
|
|
291
|
+
if (action.action === "satisfy_requirement") {
|
|
292
|
+
return findRequirementCrossReferenceNudges(state, [action.requirementId.trim()], openTaskSteps);
|
|
293
|
+
}
|
|
294
|
+
if (action.action === "complete") {
|
|
295
|
+
const satisfiedIds = state.requirements
|
|
296
|
+
.filter((requirement) => requirement.status === "satisfied")
|
|
297
|
+
.map((requirement) => requirement.id);
|
|
298
|
+
return findRequirementCrossReferenceNudges(state, satisfiedIds, openTaskSteps);
|
|
299
|
+
}
|
|
300
|
+
return [];
|
|
301
|
+
}
|
|
196
302
|
//# sourceMappingURL=goal-tool-core.js.map
|