@caupulican/pi-adaptative 0.81.38 → 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 +79 -0
- 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 +446 -89
- 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-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-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 +20 -0
- 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 +6 -5
- 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 +95 -16
- 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/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/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/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 +23 -2
- 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 +21 -6
- 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/process-matrix.md +120 -0
- package/docs/settings.md +3 -0
- 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
|
@@ -12,11 +12,20 @@
|
|
|
12
12
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
13
13
|
import { join } from "node:path";
|
|
14
14
|
import { runAgentLoop, } from "@caupulican/pi-agent-core";
|
|
15
|
+
import { computeLaneAffinityKey, DEFAULT_ISOLATED_LANE_KIND, } from "./agent-session.js";
|
|
15
16
|
import { AUTONOMY_TELEMETRY_EVENT_TYPES } from "./autonomy/telemetry-events.js";
|
|
16
17
|
import { APPLY_WRITE_REFUSED_REASON_CODE, appendLearningAuditSnapshot, contradictionsForReflectionWrite, getLearningAuditSnapshots, proposalFromReflectionWrite, rollbackPlanForReflectionWrite, } from "./learning/learning-audit.js";
|
|
17
18
|
import { evaluateLearningDecision } from "./learning/learning-gate.js";
|
|
18
19
|
import { ObservationStore, observationKey } from "./learning/observation-store.js";
|
|
19
20
|
import { decideDemand, ReflectionEngine, } from "./learning/reflection-engine.js";
|
|
21
|
+
import { registerInFlightWork } from "./reload-blockers.js";
|
|
22
|
+
import { runSkillAudit } from "./tools/skill-audit.js";
|
|
23
|
+
// reasonCode when an automatic skill promotion is blocked by an overlap with an existing skill
|
|
24
|
+
// (skill_audit's similarity threshold) and routed to a consolidation proposal instead of a blind write.
|
|
25
|
+
export const SKILL_OVERLAP_CONSOLIDATION_REASON_CODE = "skill_overlap_consolidation_proposed";
|
|
26
|
+
// reasonCode when the overlap audit itself fails — the promotion is held (not written unaudited)
|
|
27
|
+
// rather than silently skipping the check.
|
|
28
|
+
export const SKILL_AUDIT_UNAVAILABLE_REASON_CODE = "skill_audit_unavailable";
|
|
20
29
|
export class ReflectionController {
|
|
21
30
|
deps;
|
|
22
31
|
constructor(deps) {
|
|
@@ -27,9 +36,11 @@ export class ReflectionController {
|
|
|
27
36
|
* reflection and bounded child lanes (adaptive-agent design §6c/§7).
|
|
28
37
|
*
|
|
29
38
|
* Isolation invariants (audited by codex): builds fresh context (no main history), defaults to no
|
|
30
|
-
* tools, and passes **no `sessionId
|
|
31
|
-
*
|
|
32
|
-
*
|
|
39
|
+
* tools, and passes **no real `sessionId`** — only a deterministic SYNTHETIC cache-affinity key
|
|
40
|
+
* (see {@link computeLaneAffinityKey}) derived from `(laneKind, model, systemPrompt)`, which can never
|
|
41
|
+
* equal or embed the real session id. A tool-enabled call receives only caller-owned tools and hooks,
|
|
42
|
+
* and is turn-bounded. It cannot mutate `agent.state.messages`, append session entries, or touch the
|
|
43
|
+
* foreground tool registry. Mirrors `generateSummary()`'s one-shot mechanics otherwise.
|
|
33
44
|
*
|
|
34
45
|
* Returns the result even on an error/aborted stop reason (callers — e.g. a background reflection
|
|
35
46
|
* microtask — decide whether to act); it does not throw on a model-level error.
|
|
@@ -41,136 +52,156 @@ export class ReflectionController {
|
|
|
41
52
|
}
|
|
42
53
|
await this.deps.ensureModelReady(model);
|
|
43
54
|
const thinkingLevel = opts.thinkingLevel ?? "off";
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
signal: opts.signal,
|
|
55
|
-
cacheRetention: opts.cacheRetention ?? "none",
|
|
56
|
-
reasoning: thinkingLevel,
|
|
57
|
-
};
|
|
58
|
-
// When streamFn is the raw streamSimple (e.g. in tests), auth must be injected explicitly.
|
|
59
|
-
// Throw only when auth genuinely fails — providers that authenticate without an API key
|
|
60
|
-
// (OAuth, local no-key) legitimately return ok with an undefined apiKey.
|
|
61
|
-
if (this.deps.isRawStreamSimple()) {
|
|
62
|
-
const auth = await this.deps.getModelRegistry().getApiKeyAndHeaders(model);
|
|
63
|
-
if (!auth.ok) {
|
|
64
|
-
throw new Error(auth.error);
|
|
65
|
-
}
|
|
66
|
-
options.apiKey = auth.apiKey;
|
|
67
|
-
options.headers = auth.headers;
|
|
68
|
-
}
|
|
69
|
-
if (opts.tools && opts.tools.length > 0) {
|
|
70
|
-
const agent = this.deps.getAgent();
|
|
71
|
-
const foregroundModel = agent.state.model;
|
|
72
|
-
const usesForegroundModel = foregroundModel?.provider === model.provider && foregroundModel.id === model.id;
|
|
73
|
-
const textToolCallProtocol = this.deps.resolveTextToolCallProtocol(model);
|
|
74
|
-
const requestedMaxTurns = typeof opts.maxTurns === "number" && Number.isFinite(opts.maxTurns) ? Math.floor(opts.maxTurns) : 6;
|
|
75
|
-
const maxTurns = Math.max(1, Math.min(12, requestedMaxTurns));
|
|
76
|
-
let completedTurns = 0;
|
|
77
|
-
const childContext = {
|
|
55
|
+
// Registered for the full isolated-completion call (one-shot or child-loop) so the
|
|
56
|
+
// reload gate waits it out — this is the SINGLE choke point every isolated completion in the
|
|
57
|
+
// codebase runs through (reflection, research/worker/fitness lanes, context-pipeline curation,
|
|
58
|
+
// model-router judge calls). registerInFlightWork is a pure sync map op (cannot throw), so
|
|
59
|
+
// placing it as the last statement before `try` still guarantees the matching finally always
|
|
60
|
+
// runs, on every return path below and on any thrown error.
|
|
61
|
+
const deregisterInFlight = registerInFlightWork(this.deps.getAgentDir(), "isolated-completion", opts.laneKind ?? DEFAULT_ISOLATED_LANE_KIND);
|
|
62
|
+
try {
|
|
63
|
+
// Fresh, isolated context: explicit messages, caller-owned tools only, nothing from the main session.
|
|
64
|
+
const context = {
|
|
78
65
|
systemPrompt: opts.systemPrompt,
|
|
79
|
-
messages:
|
|
80
|
-
tools:
|
|
66
|
+
messages: opts.messages,
|
|
67
|
+
tools: opts.tools ?? [],
|
|
81
68
|
};
|
|
82
|
-
|
|
83
|
-
|
|
69
|
+
// Isolate the prompt cache from the main session by DELIBERATELY never sending the real
|
|
70
|
+
// sessionId. In its place, a deterministic SYNTHETIC affinity key lets providers with
|
|
71
|
+
// session-affinity headers / prompt_cache_key route repeat calls from the SAME lane (same
|
|
72
|
+
// laneKind+model+systemPrompt) to the same cache-warm backend, without entangling this call
|
|
73
|
+
// with — or leaking any identity of — the main session.
|
|
74
|
+
const affinityKey = computeLaneAffinityKey(opts.laneKind ?? DEFAULT_ISOLATED_LANE_KIND, model, opts.systemPrompt);
|
|
75
|
+
const options = {
|
|
84
76
|
maxTokens: opts.maxTokens,
|
|
85
|
-
|
|
77
|
+
signal: opts.signal,
|
|
78
|
+
cacheRetention: opts.cacheRetention,
|
|
86
79
|
reasoning: thinkingLevel,
|
|
87
|
-
|
|
88
|
-
...(options.headers !== undefined ? { headers: options.headers } : {}),
|
|
89
|
-
temperature: textToolCallProtocol ? 0 : undefined,
|
|
90
|
-
textToolCallProtocol,
|
|
91
|
-
onTextToolProtocolParse: usesForegroundModel ? agent.onTextToolProtocolParse : undefined,
|
|
92
|
-
transport: agent.transport,
|
|
93
|
-
thinkingBudgets: agent.thinkingBudgets,
|
|
94
|
-
maxRetryDelayMs: agent.maxRetryDelayMs,
|
|
95
|
-
maxStallTurns: Math.max(2, Math.min(maxTurns, agent.maxStallTurns ?? maxTurns)),
|
|
96
|
-
toolExecution: "sequential",
|
|
97
|
-
toolArgumentTeachEnabled: agent.toolArgumentTeachEnabled,
|
|
98
|
-
onToolArgumentValidation: usesForegroundModel ? agent.onToolArgumentValidation : undefined,
|
|
99
|
-
toolValidationEscalationThreshold: agent.toolValidationEscalationThreshold,
|
|
100
|
-
onToolValidationEscalation: usesForegroundModel ? agent.onToolValidationEscalation : undefined,
|
|
101
|
-
beforeToolCall: opts.beforeToolCall,
|
|
102
|
-
afterToolCall: opts.afterToolCall,
|
|
103
|
-
shouldStopAfterTurn: () => {
|
|
104
|
-
completedTurns += 1;
|
|
105
|
-
return completedTurns >= maxTurns;
|
|
106
|
-
},
|
|
107
|
-
convertToLlm: agent.convertToLlm,
|
|
80
|
+
sessionId: affinityKey,
|
|
108
81
|
};
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (
|
|
113
|
-
|
|
82
|
+
// When streamFn is the raw streamSimple (e.g. in tests), auth must be injected explicitly.
|
|
83
|
+
// Throw only when auth genuinely fails — providers that authenticate without an API key
|
|
84
|
+
// (OAuth, local no-key) legitimately return ok with an undefined apiKey.
|
|
85
|
+
if (this.deps.isRawStreamSimple()) {
|
|
86
|
+
const auth = await this.deps.getModelRegistry().getApiKeyAndHeaders(model);
|
|
87
|
+
if (!auth.ok) {
|
|
88
|
+
throw new Error(auth.error);
|
|
89
|
+
}
|
|
90
|
+
options.apiKey = auth.apiKey;
|
|
91
|
+
options.headers = auth.headers;
|
|
114
92
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const
|
|
121
|
-
const
|
|
93
|
+
if (opts.tools && opts.tools.length > 0) {
|
|
94
|
+
const agent = this.deps.getAgent();
|
|
95
|
+
const foregroundModel = agent.state.model;
|
|
96
|
+
const usesForegroundModel = foregroundModel?.provider === model.provider && foregroundModel.id === model.id;
|
|
97
|
+
const textToolCallProtocol = this.deps.resolveTextToolCallProtocol(model);
|
|
98
|
+
const requestedMaxTurns = typeof opts.maxTurns === "number" && Number.isFinite(opts.maxTurns) ? Math.floor(opts.maxTurns) : 6;
|
|
99
|
+
const maxTurns = Math.max(1, Math.min(12, requestedMaxTurns));
|
|
100
|
+
let completedTurns = 0;
|
|
101
|
+
const childContext = {
|
|
122
102
|
systemPrompt: opts.systemPrompt,
|
|
123
|
-
messages: [
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
103
|
+
messages: [],
|
|
104
|
+
tools: [...opts.tools],
|
|
105
|
+
};
|
|
106
|
+
const loopConfig = {
|
|
107
|
+
model,
|
|
108
|
+
maxTokens: opts.maxTokens,
|
|
109
|
+
cacheRetention: opts.cacheRetention,
|
|
110
|
+
reasoning: thinkingLevel,
|
|
111
|
+
// Same synthetic per-lane affinity key as the one-shot path above — never the real sessionId.
|
|
112
|
+
sessionId: affinityKey,
|
|
113
|
+
...(options.apiKey !== undefined ? { apiKey: options.apiKey } : {}),
|
|
114
|
+
...(options.headers !== undefined ? { headers: options.headers } : {}),
|
|
115
|
+
temperature: textToolCallProtocol ? 0 : undefined,
|
|
116
|
+
textToolCallProtocol,
|
|
117
|
+
onTextToolProtocolParse: usesForegroundModel ? agent.onTextToolProtocolParse : undefined,
|
|
118
|
+
transport: agent.transport,
|
|
119
|
+
thinkingBudgets: agent.thinkingBudgets,
|
|
120
|
+
maxRetryDelayMs: agent.maxRetryDelayMs,
|
|
121
|
+
maxStallTurns: Math.max(2, Math.min(maxTurns, agent.maxStallTurns ?? maxTurns)),
|
|
122
|
+
onRunawayStop: usesForegroundModel ? agent.onRunawayStop : undefined,
|
|
123
|
+
toolExecution: "sequential",
|
|
124
|
+
toolArgumentTeachEnabled: agent.toolArgumentTeachEnabled,
|
|
125
|
+
onToolArgumentValidation: usesForegroundModel ? agent.onToolArgumentValidation : undefined,
|
|
126
|
+
toolValidationEscalationThreshold: agent.toolValidationEscalationThreshold,
|
|
127
|
+
onToolValidationEscalation: usesForegroundModel ? agent.onToolValidationEscalation : undefined,
|
|
128
|
+
beforeToolCall: opts.beforeToolCall,
|
|
129
|
+
afterToolCall: opts.afterToolCall,
|
|
130
|
+
shouldStopAfterTurn: () => {
|
|
131
|
+
completedTurns += 1;
|
|
132
|
+
return completedTurns >= maxTurns;
|
|
133
|
+
},
|
|
134
|
+
convertToLlm: agent.convertToLlm,
|
|
135
|
+
};
|
|
136
|
+
const messages = await runAgentLoop(opts.messages, childContext, loopConfig, () => { }, opts.signal, agent.streamFn);
|
|
137
|
+
const assistantMessages = messages.filter((message) => message.role === "assistant");
|
|
138
|
+
let finalAssistant = assistantMessages.at(-1);
|
|
139
|
+
if (!finalAssistant) {
|
|
140
|
+
throw new Error("runIsolatedCompletion: child loop produced no assistant message");
|
|
141
|
+
}
|
|
142
|
+
const hasFinalText = finalAssistant.content.some((content) => content.type === "text" && content.text.trim().length > 0);
|
|
143
|
+
const endedOnToolCall = finalAssistant.content.some((content) => content.type === "toolCall");
|
|
144
|
+
if (opts.finalTextPrompt && !hasFinalText && endedOnToolCall && !opts.signal?.aborted) {
|
|
145
|
+
// A hard turn bound may stop immediately after successful tool execution. Preserve that bound,
|
|
146
|
+
// then allow exactly one tool-free synthesis call so the gathered work is not thrown away.
|
|
147
|
+
const finalizationMessages = await agent.convertToLlm(messages);
|
|
148
|
+
const finalizationStream = await agent.streamFn(model, {
|
|
149
|
+
systemPrompt: opts.systemPrompt,
|
|
150
|
+
messages: [
|
|
151
|
+
...finalizationMessages,
|
|
152
|
+
{ role: "user", content: opts.finalTextPrompt, timestamp: Date.now() },
|
|
153
|
+
],
|
|
154
|
+
tools: [],
|
|
155
|
+
}, options);
|
|
156
|
+
finalAssistant = await finalizationStream.result();
|
|
157
|
+
assistantMessages.push(finalAssistant);
|
|
158
|
+
}
|
|
159
|
+
const usage = assistantMessages.reduce((total, message) => ({
|
|
160
|
+
input: total.input + message.usage.input,
|
|
161
|
+
output: total.output + message.usage.output,
|
|
162
|
+
cacheRead: total.cacheRead + message.usage.cacheRead,
|
|
163
|
+
cacheWrite: total.cacheWrite + message.usage.cacheWrite,
|
|
164
|
+
totalTokens: total.totalTokens + message.usage.totalTokens,
|
|
165
|
+
cost: {
|
|
166
|
+
input: total.cost.input + message.usage.cost.input,
|
|
167
|
+
output: total.cost.output + message.usage.cost.output,
|
|
168
|
+
cacheRead: total.cost.cacheRead + message.usage.cost.cacheRead,
|
|
169
|
+
cacheWrite: total.cost.cacheWrite + message.usage.cost.cacheWrite,
|
|
170
|
+
total: total.cost.total + message.usage.cost.total,
|
|
171
|
+
},
|
|
172
|
+
}), {
|
|
173
|
+
input: 0,
|
|
174
|
+
output: 0,
|
|
175
|
+
cacheRead: 0,
|
|
176
|
+
cacheWrite: 0,
|
|
177
|
+
totalTokens: 0,
|
|
178
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
179
|
+
});
|
|
180
|
+
const text = finalAssistant.content
|
|
181
|
+
.filter((content) => content.type === "text")
|
|
182
|
+
.map((content) => content.text)
|
|
183
|
+
.join("");
|
|
184
|
+
return { text, usage, stopReason: finalAssistant.stopReason };
|
|
131
185
|
}
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
input: total.cost.input + message.usage.cost.input,
|
|
140
|
-
output: total.cost.output + message.usage.cost.output,
|
|
141
|
-
cacheRead: total.cost.cacheRead + message.usage.cost.cacheRead,
|
|
142
|
-
cacheWrite: total.cost.cacheWrite + message.usage.cost.cacheWrite,
|
|
143
|
-
total: total.cost.total + message.usage.cost.total,
|
|
144
|
-
},
|
|
145
|
-
}), {
|
|
186
|
+
const stream = await this.deps.getAgent().streamFn(model, context, options);
|
|
187
|
+
const result = await stream.result();
|
|
188
|
+
const text = result.content
|
|
189
|
+
.filter((c) => c.type === "text")
|
|
190
|
+
.map((c) => c.text)
|
|
191
|
+
.join("");
|
|
192
|
+
const usage = result.usage ?? {
|
|
146
193
|
input: 0,
|
|
147
194
|
output: 0,
|
|
148
195
|
cacheRead: 0,
|
|
149
196
|
cacheWrite: 0,
|
|
150
197
|
totalTokens: 0,
|
|
151
198
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
return { text, usage, stopReason: finalAssistant.stopReason };
|
|
199
|
+
};
|
|
200
|
+
return { text, usage, stopReason: result.stopReason };
|
|
201
|
+
}
|
|
202
|
+
finally {
|
|
203
|
+
deregisterInFlight();
|
|
158
204
|
}
|
|
159
|
-
const stream = await this.deps.getAgent().streamFn(model, context, options);
|
|
160
|
-
const result = await stream.result();
|
|
161
|
-
const text = result.content
|
|
162
|
-
.filter((c) => c.type === "text")
|
|
163
|
-
.map((c) => c.text)
|
|
164
|
-
.join("");
|
|
165
|
-
const usage = result.usage ?? {
|
|
166
|
-
input: 0,
|
|
167
|
-
output: 0,
|
|
168
|
-
cacheRead: 0,
|
|
169
|
-
cacheWrite: 0,
|
|
170
|
-
totalTokens: 0,
|
|
171
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
172
|
-
};
|
|
173
|
-
return { text, usage, stopReason: result.stopReason };
|
|
174
205
|
}
|
|
175
206
|
/**
|
|
176
207
|
* Native end-of-loop reflection pass (R2). Demand-gates (zero-I/O), and when warranted runs the
|
|
@@ -202,6 +233,7 @@ export class ReflectionController {
|
|
|
202
233
|
// The reflection system prompt is static (#33) — let the provider cache the prefix so
|
|
203
234
|
// repeated passes only pay for the variable tail.
|
|
204
235
|
cacheRetention: "short",
|
|
236
|
+
laneKind: "reflection",
|
|
205
237
|
});
|
|
206
238
|
const result = await new ReflectionEngine().reflect({
|
|
207
239
|
recentTurnText: input.recentTurnText,
|
|
@@ -296,25 +328,43 @@ export class ReflectionController {
|
|
|
296
328
|
},
|
|
297
329
|
});
|
|
298
330
|
}
|
|
331
|
+
// An automatic skill promotion the gate would otherwise apply must still clear the same
|
|
332
|
+
// skill_audit overlap check the model-invoked `skillify` tool enforces — otherwise reflection
|
|
333
|
+
// can silently write a near-duplicate SKILL.md. A non-overlapping skill is unaffected
|
|
334
|
+
// (skillPromotionBlock stays undefined) and promotes exactly as before.
|
|
335
|
+
const skillPromotionBlock = write.kind === "promote_skill" && decision.kind === "apply"
|
|
336
|
+
? this._checkSkillPromotionOverlap(write)
|
|
337
|
+
: undefined;
|
|
299
338
|
// The gate's decision and the write's actual outcome are two different questions: the memory
|
|
300
339
|
// tool can refuse a write (budget exceeded, drift, threat) via details.success:false without
|
|
301
340
|
// throwing. Capture that outcome instead of assuming "decision.kind === apply" means it landed
|
|
302
341
|
// — otherwise a refused write leaves a phantom "apply" audit whose rollback later fails
|
|
303
342
|
// not-found (or, worse, misfires against whatever now occupies that text).
|
|
304
|
-
const applied = decision.kind === "apply" ? await this._applyReflectionWrite(write, signal) : false;
|
|
305
|
-
const writeFailed = decision.kind === "apply" && !applied;
|
|
343
|
+
const applied = decision.kind === "apply" && !skillPromotionBlock ? await this._applyReflectionWrite(write, signal) : false;
|
|
344
|
+
const writeFailed = decision.kind === "apply" && !skillPromotionBlock && !applied;
|
|
306
345
|
if (decision.kind !== "no-op") {
|
|
307
346
|
auditSequence += 1;
|
|
308
347
|
appendLearningAuditSnapshot(this.deps.getSessionManager(), {
|
|
309
348
|
id: `audit-${auditSequence}`,
|
|
310
349
|
proposalId,
|
|
311
350
|
layer: proposal.layer,
|
|
312
|
-
action:
|
|
313
|
-
|
|
314
|
-
|
|
351
|
+
action: skillPromotionBlock
|
|
352
|
+
? "propose"
|
|
353
|
+
: writeFailed
|
|
354
|
+
? "apply_failed"
|
|
355
|
+
: decision.kind === "apply"
|
|
356
|
+
? "apply"
|
|
357
|
+
: "propose",
|
|
358
|
+
summary: skillPromotionBlock ? `${proposal.summary} — ${skillPromotionBlock.note}` : proposal.summary,
|
|
359
|
+
reasonCode: skillPromotionBlock
|
|
360
|
+
? skillPromotionBlock.reasonCode
|
|
361
|
+
: writeFailed
|
|
362
|
+
? APPLY_WRITE_REFUSED_REASON_CODE
|
|
363
|
+
: decision.reasonCode,
|
|
315
364
|
decision,
|
|
316
|
-
// No rollback plan on a failed apply
|
|
317
|
-
|
|
365
|
+
// No rollback plan on a failed apply or a held/proposed promotion — nothing durable
|
|
366
|
+
// landed in either case, so there is nothing to undo.
|
|
367
|
+
rollback: skillPromotionBlock || writeFailed ? undefined : rollback,
|
|
318
368
|
createdAt: new Date().toISOString(),
|
|
319
369
|
});
|
|
320
370
|
}
|
|
@@ -466,9 +516,48 @@ export class ReflectionController {
|
|
|
466
516
|
}
|
|
467
517
|
return false;
|
|
468
518
|
}
|
|
519
|
+
/**
|
|
520
|
+
* The same skill_audit overlap check the model-invoked `skillify` tool enforces
|
|
521
|
+
* (tools/skillify.ts → tools/skill-audit.ts's `runSkillAudit`), run before an AUTOMATIC promotion
|
|
522
|
+
* so the reflection engine can never silently write a near-duplicate SKILL.md. Reuses the audit
|
|
523
|
+
* seam unchanged (never duplicated) against the same already-loaded skills universe skillify
|
|
524
|
+
* compares a draft against. Returns a block reason when the draft overlaps an existing skill above
|
|
525
|
+
* the audit's own similarity threshold, or when the audit itself fails (the promotion is held, not
|
|
526
|
+
* written unaudited); undefined when clear to promote. Never throws — mirrors every other
|
|
527
|
+
* best-effort check in this file.
|
|
528
|
+
*/
|
|
529
|
+
_checkSkillPromotionOverlap(write) {
|
|
530
|
+
try {
|
|
531
|
+
const cwd = this.deps.getCwd?.() ?? process.cwd();
|
|
532
|
+
const audit = runSkillAudit(cwd, write);
|
|
533
|
+
const overlap = audit.nearDuplicates.find((d) => d.a === "[draft]" || d.b === "[draft]");
|
|
534
|
+
if (!overlap)
|
|
535
|
+
return undefined;
|
|
536
|
+
const otherPath = overlap.a === "[draft]" ? overlap.b : overlap.a;
|
|
537
|
+
// Every skill file is named "SKILL.md" — unlike skillify's own display formatter (which takes
|
|
538
|
+
// the path's last segment and always shows that literal filename), look up the declared
|
|
539
|
+
// frontmatter name so the proposal actually names the skill it overlaps with.
|
|
540
|
+
const otherName = audit.skills.find((s) => s.path === otherPath)?.name ?? otherPath;
|
|
541
|
+
return {
|
|
542
|
+
reasonCode: SKILL_OVERLAP_CONSOLIDATION_REASON_CODE,
|
|
543
|
+
note: `overlaps existing skill "${otherName}" (${(overlap.similarity * 100).toFixed(0)}% similar) — consolidation proposed instead of a duplicate write`,
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
catch {
|
|
547
|
+
// Bounded, observable degradation via the promote path's existing error-reporting shape: an
|
|
548
|
+
// audit failure must never throw into the reflection pass, but it also must not silently
|
|
549
|
+
// fall through to an unaudited write — hold the promotion and record why.
|
|
550
|
+
return {
|
|
551
|
+
reasonCode: SKILL_AUDIT_UNAVAILABLE_REASON_CODE,
|
|
552
|
+
note: "skill overlap audit failed; promotion held rather than written unaudited",
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
}
|
|
469
556
|
/**
|
|
470
557
|
* R7: write a reflection-promoted skill as `<agentDir>/skills/<name>/SKILL.md` so it loads like any
|
|
471
|
-
* user skill. Best-effort; never clobbers an existing (hand-authored) skill of the same name.
|
|
558
|
+
* user skill. Best-effort; never clobbers an existing (hand-authored) skill of the same name. The
|
|
559
|
+
* overlap audit runs at the call site in {@link runReflectionPass} — a write only reaches here
|
|
560
|
+
* once the draft has already cleared it.
|
|
472
561
|
*/
|
|
473
562
|
_promoteReflectionSkill(rawName, description, body) {
|
|
474
563
|
const name = rawName
|