@prestyj/cli 5.8.0 → 5.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/assets/skills/evidence-led-ui/LICENSES.md +12 -0
- package/assets/skills/evidence-led-ui/SKILL.md +15 -7
- package/assets/skills/evidence-led-ui/references/anti-defaults.md +9 -1
- package/assets/skills/evidence-led-ui/references/craft-rulings.md +33 -0
- package/assets/skills/evidence-led-ui/references/production-contract.md +41 -21
- package/assets/skills/evidence-led-ui/references/provenance.md +7 -5
- package/assets/skills/evidence-led-ui/references/quality-rubric.md +10 -10
- package/dist/app-sidecar-sessions.d.ts +8 -0
- package/dist/app-sidecar-sessions.d.ts.map +1 -0
- package/dist/app-sidecar-sessions.js +31 -0
- package/dist/app-sidecar-sessions.js.map +1 -0
- package/dist/app-sidecar-sessions.test.d.ts +2 -0
- package/dist/app-sidecar-sessions.test.d.ts.map +1 -0
- package/dist/app-sidecar-sessions.test.js +83 -0
- package/dist/app-sidecar-sessions.test.js.map +1 -0
- package/dist/app-sidecar.js +623 -120
- package/dist/app-sidecar.js.map +1 -1
- package/dist/chat-agents/general.test.js +5 -3
- package/dist/chat-agents/general.test.js.map +1 -1
- package/dist/chat-agents/memory.d.ts.map +1 -1
- package/dist/chat-agents/memory.js +14 -5
- package/dist/chat-agents/memory.js.map +1 -1
- package/dist/chat-agents/memory.test.js +11 -1
- package/dist/chat-agents/memory.test.js.map +1 -1
- package/dist/chat-agents/shared.js +1 -1
- package/dist/chat-agents/shared.js.map +1 -1
- package/dist/chat-agents/specialists.test.js +3 -2
- package/dist/chat-agents/specialists.test.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +59 -30
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +18 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +50 -2
- package/dist/config.js.map +1 -1
- package/dist/config.test.js +61 -1
- package/dist/config.test.js.map +1 -1
- package/dist/core/agent-mcp-passthrough.test.d.ts +2 -0
- package/dist/core/agent-mcp-passthrough.test.d.ts.map +1 -0
- package/dist/core/agent-mcp-passthrough.test.js +61 -0
- package/dist/core/agent-mcp-passthrough.test.js.map +1 -0
- package/dist/core/agent-session-add-dir.test.d.ts +2 -0
- package/dist/core/agent-session-add-dir.test.d.ts.map +1 -0
- package/dist/core/agent-session-add-dir.test.js +110 -0
- package/dist/core/agent-session-add-dir.test.js.map +1 -0
- package/dist/core/agent-session-compaction.test.js +23 -7
- package/dist/core/agent-session-compaction.test.js.map +1 -1
- package/dist/core/agent-session-marker-anchors.test.d.ts +2 -0
- package/dist/core/agent-session-marker-anchors.test.d.ts.map +1 -0
- package/dist/core/agent-session-marker-anchors.test.js +147 -0
- package/dist/core/agent-session-marker-anchors.test.js.map +1 -0
- package/dist/core/agent-session-memory-tail.test.js +4 -7
- package/dist/core/agent-session-memory-tail.test.js.map +1 -1
- package/dist/core/agent-session-queue.test.js +4 -7
- package/dist/core/agent-session-queue.test.js.map +1 -1
- package/dist/core/agent-session-subagent-policy.test.js +7 -3
- package/dist/core/agent-session-subagent-policy.test.js.map +1 -1
- package/dist/core/agent-session.d.ts +46 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +177 -19
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/agent-tools-allowlist.test.js +5 -3
- package/dist/core/agent-tools-allowlist.test.js.map +1 -1
- package/dist/core/agents.d.ts +12 -1
- package/dist/core/agents.d.ts.map +1 -1
- package/dist/core/agents.js +25 -1
- package/dist/core/agents.js.map +1 -1
- package/dist/core/agents.test.d.ts +2 -0
- package/dist/core/agents.test.d.ts.map +1 -0
- package/dist/core/agents.test.js +67 -0
- package/dist/core/agents.test.js.map +1 -0
- package/dist/core/auth-providers.js +1 -1
- package/dist/core/auth-providers.js.map +1 -1
- package/dist/core/auth-storage.d.ts +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +1 -1
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/compaction/compactor.d.ts.map +1 -1
- package/dist/core/compaction/compactor.js +20 -11
- package/dist/core/compaction/compactor.js.map +1 -1
- package/dist/core/compaction/compactor.test.js +17 -4
- package/dist/core/compaction/compactor.test.js.map +1 -1
- package/dist/core/compaction/token-estimator.test.js +1 -1
- package/dist/core/compaction/token-estimator.test.js.map +1 -1
- package/dist/core/encode-cwd.d.ts +17 -0
- package/dist/core/encode-cwd.d.ts.map +1 -1
- package/dist/core/encode-cwd.js +20 -7
- package/dist/core/encode-cwd.js.map +1 -1
- package/dist/core/encode-cwd.test.js +20 -1
- package/dist/core/encode-cwd.test.js.map +1 -1
- package/dist/core/event-bus.d.ts +5 -0
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js +6 -0
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/goal-controller.test.js +3 -3
- package/dist/core/goal-controller.test.js.map +1 -1
- package/dist/core/ideal-review.d.ts.map +1 -1
- package/dist/core/ideal-review.js +6 -1
- package/dist/core/ideal-review.js.map +1 -1
- package/dist/core/ideal-review.test.js +7 -2
- package/dist/core/ideal-review.test.js.map +1 -1
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/input-normalization.test.d.ts +2 -0
- package/dist/core/input-normalization.test.d.ts.map +1 -0
- package/dist/core/input-normalization.test.js +75 -0
- package/dist/core/input-normalization.test.js.map +1 -0
- package/dist/core/local-endpoint-store.d.ts +50 -0
- package/dist/core/local-endpoint-store.d.ts.map +1 -0
- package/dist/core/local-endpoint-store.js +201 -0
- package/dist/core/local-endpoint-store.js.map +1 -0
- package/dist/core/local-endpoint-store.test.d.ts +2 -0
- package/dist/core/local-endpoint-store.test.d.ts.map +1 -0
- package/dist/core/local-endpoint-store.test.js +131 -0
- package/dist/core/local-endpoint-store.test.js.map +1 -0
- package/dist/core/loop-breaker.d.ts +38 -1
- package/dist/core/loop-breaker.d.ts.map +1 -1
- package/dist/core/loop-breaker.js +84 -2
- package/dist/core/loop-breaker.js.map +1 -1
- package/dist/core/loop-breaker.test.js +108 -1
- package/dist/core/loop-breaker.test.js.map +1 -1
- package/dist/core/lsp/client.d.ts +50 -0
- package/dist/core/lsp/client.d.ts.map +1 -1
- package/dist/core/lsp/client.js +158 -13
- package/dist/core/lsp/client.js.map +1 -1
- package/dist/core/lsp/jsonrpc.d.ts +38 -1
- package/dist/core/lsp/jsonrpc.d.ts.map +1 -1
- package/dist/core/lsp/jsonrpc.js +13 -1
- package/dist/core/lsp/jsonrpc.js.map +1 -1
- package/dist/core/lsp/manager.d.ts.map +1 -1
- package/dist/core/lsp/manager.js +23 -2
- package/dist/core/lsp/manager.js.map +1 -1
- package/dist/core/lsp/manager.test.js +32 -1
- package/dist/core/lsp/manager.test.js.map +1 -1
- package/dist/core/lsp/test-support.d.ts +18 -0
- package/dist/core/lsp/test-support.d.ts.map +1 -0
- package/dist/core/lsp/test-support.js +27 -0
- package/dist/core/lsp/test-support.js.map +1 -0
- package/dist/core/lsp/uri.test.d.ts +2 -0
- package/dist/core/lsp/uri.test.d.ts.map +1 -0
- package/dist/core/lsp/uri.test.js +56 -0
- package/dist/core/lsp/uri.test.js.map +1 -0
- package/dist/core/lsp/windows.test.d.ts +2 -0
- package/dist/core/lsp/windows.test.d.ts.map +1 -0
- package/dist/core/lsp/windows.test.js +251 -0
- package/dist/core/lsp/windows.test.js.map +1 -0
- package/dist/core/mcp/resolve-stdio.d.ts +35 -0
- package/dist/core/mcp/resolve-stdio.d.ts.map +1 -1
- package/dist/core/mcp/resolve-stdio.js +80 -1
- package/dist/core/mcp/resolve-stdio.js.map +1 -1
- package/dist/core/mcp/resolve-stdio.test.js +99 -4
- package/dist/core/mcp/resolve-stdio.test.js.map +1 -1
- package/dist/core/message-images.d.ts +12 -0
- package/dist/core/message-images.d.ts.map +1 -0
- package/dist/core/message-images.js +52 -0
- package/dist/core/message-images.js.map +1 -0
- package/dist/core/message-images.test.d.ts +2 -0
- package/dist/core/message-images.test.d.ts.map +1 -0
- package/dist/core/message-images.test.js +62 -0
- package/dist/core/message-images.test.js.map +1 -0
- package/dist/core/network-guard.d.ts +47 -0
- package/dist/core/network-guard.d.ts.map +1 -0
- package/dist/core/network-guard.js +208 -0
- package/dist/core/network-guard.js.map +1 -0
- package/dist/core/network-guard.test.d.ts +2 -0
- package/dist/core/network-guard.test.d.ts.map +1 -0
- package/dist/core/network-guard.test.js +72 -0
- package/dist/core/network-guard.test.js.map +1 -0
- package/dist/core/persistent-shell.d.ts +3 -1
- package/dist/core/persistent-shell.d.ts.map +1 -1
- package/dist/core/persistent-shell.js +13 -3
- package/dist/core/persistent-shell.js.map +1 -1
- package/dist/core/process-manager-dev-server-repro.test.js +34 -12
- package/dist/core/process-manager-dev-server-repro.test.js.map +1 -1
- package/dist/core/process-manager.d.ts +1 -1
- package/dist/core/process-manager.d.ts.map +1 -1
- package/dist/core/process-manager.js +23 -13
- package/dist/core/process-manager.js.map +1 -1
- package/dist/core/project-discovery.d.ts +8 -1
- package/dist/core/project-discovery.d.ts.map +1 -1
- package/dist/core/project-discovery.js +145 -62
- package/dist/core/project-discovery.js.map +1 -1
- package/dist/core/project-discovery.test.js +131 -1
- package/dist/core/project-discovery.test.js.map +1 -1
- package/dist/core/prompt-commands.d.ts.map +1 -1
- package/dist/core/prompt-commands.js +89 -156
- package/dist/core/prompt-commands.js.map +1 -1
- package/dist/core/prompt-commands.test.js +4 -10
- package/dist/core/prompt-commands.test.js.map +1 -1
- package/dist/core/radio.test.js +4 -1
- package/dist/core/radio.test.js.map +1 -1
- package/dist/core/runtime-mode.d.ts +2 -0
- package/dist/core/runtime-mode.d.ts.map +1 -1
- package/dist/core/runtime-mode.js +4 -0
- package/dist/core/runtime-mode.js.map +1 -1
- package/dist/core/session-export.d.ts +98 -0
- package/dist/core/session-export.d.ts.map +1 -0
- package/dist/core/session-export.js +356 -0
- package/dist/core/session-export.js.map +1 -0
- package/dist/core/session-export.test.d.ts +2 -0
- package/dist/core/session-export.test.d.ts.map +1 -0
- package/dist/core/session-export.test.js +353 -0
- package/dist/core/session-export.test.js.map +1 -0
- package/dist/core/session-manager.d.ts +27 -7
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +257 -124
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-storage.d.ts +57 -0
- package/dist/core/session-storage.d.ts.map +1 -0
- package/dist/core/session-storage.js +592 -0
- package/dist/core/session-storage.js.map +1 -0
- package/dist/core/session-storage.test.d.ts +2 -0
- package/dist/core/session-storage.test.d.ts.map +1 -0
- package/dist/core/session-storage.test.js +272 -0
- package/dist/core/session-storage.test.js.map +1 -0
- package/dist/core/settings-manager.d.ts +7 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +17 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/setup-history.d.ts +0 -6
- package/dist/core/setup-history.d.ts.map +1 -1
- package/dist/core/setup-history.js +2 -18
- package/dist/core/setup-history.js.map +1 -1
- package/dist/core/setup-history.test.js +11 -26
- package/dist/core/setup-history.test.js.map +1 -1
- package/dist/core/sidecar-error-reporter.d.ts +12 -0
- package/dist/core/sidecar-error-reporter.d.ts.map +1 -0
- package/dist/core/sidecar-error-reporter.js +57 -0
- package/dist/core/sidecar-error-reporter.js.map +1 -0
- package/dist/core/sidecar-error-reporter.test.d.ts +2 -0
- package/dist/core/sidecar-error-reporter.test.d.ts.map +1 -0
- package/dist/core/sidecar-error-reporter.test.js +61 -0
- package/dist/core/sidecar-error-reporter.test.js.map +1 -0
- package/dist/core/skills-routing.test.js +3 -1
- package/dist/core/skills-routing.test.js.map +1 -1
- package/dist/core/skills.d.ts +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +4 -1
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts +18 -0
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +42 -10
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/slash-commands.test.d.ts +2 -0
- package/dist/core/slash-commands.test.d.ts.map +1 -0
- package/dist/core/slash-commands.test.js +59 -0
- package/dist/core/slash-commands.test.js.map +1 -0
- package/dist/core/speed-benchmark.test.js +9 -3
- package/dist/core/speed-benchmark.test.js.map +1 -1
- package/dist/core/subagent-manager.d.ts +8 -1
- package/dist/core/subagent-manager.d.ts.map +1 -1
- package/dist/core/subagent-manager.js +35 -2
- package/dist/core/subagent-manager.js.map +1 -1
- package/dist/core/subagent-manager.test.js +34 -0
- package/dist/core/subagent-manager.test.js.map +1 -1
- package/dist/core/subagent-store.test.js +14 -2
- package/dist/core/subagent-store.test.js.map +1 -1
- package/dist/core/verify-commands.d.ts.map +1 -1
- package/dist/core/verify-commands.js +1 -6
- package/dist/core/verify-commands.js.map +1 -1
- package/dist/core/verify-commands.test.js +1 -5
- package/dist/core/verify-commands.test.js.map +1 -1
- package/dist/core/workspace-guard.d.ts +40 -0
- package/dist/core/workspace-guard.d.ts.map +1 -0
- package/dist/core/workspace-guard.js +115 -0
- package/dist/core/workspace-guard.js.map +1 -0
- package/dist/core/workspace-guard.test.d.ts +2 -0
- package/dist/core/workspace-guard.test.d.ts.map +1 -0
- package/dist/core/workspace-guard.test.js +107 -0
- package/dist/core/workspace-guard.test.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/json-mode.d.ts +7 -0
- package/dist/modes/json-mode.d.ts.map +1 -1
- package/dist/modes/json-mode.js +10 -0
- package/dist/modes/json-mode.js.map +1 -1
- package/dist/modes/subagent-worker-mode.d.ts +2 -0
- package/dist/modes/subagent-worker-mode.d.ts.map +1 -1
- package/dist/modes/subagent-worker-mode.js +11 -0
- package/dist/modes/subagent-worker-mode.js.map +1 -1
- package/dist/session.d.ts +4 -4
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +38 -101
- package/dist/session.js.map +1 -1
- package/dist/session.test.d.ts +2 -0
- package/dist/session.test.d.ts.map +1 -0
- package/dist/session.test.js +35 -0
- package/dist/session.test.js.map +1 -0
- package/dist/system-prompt.d.ts +23 -1
- package/dist/system-prompt.d.ts.map +1 -1
- package/dist/system-prompt.js +119 -31
- package/dist/system-prompt.js.map +1 -1
- package/dist/system-prompt.test.js +154 -14
- package/dist/system-prompt.test.js.map +1 -1
- package/dist/test-support/fake-home.d.ts +20 -0
- package/dist/test-support/fake-home.d.ts.map +1 -0
- package/dist/test-support/fake-home.js +37 -0
- package/dist/test-support/fake-home.js.map +1 -0
- package/dist/tools/bash.d.ts +4 -2
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +57 -9
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/bash.test.js +156 -8
- package/dist/tools/bash.test.js.map +1 -1
- package/dist/tools/edit-robustness.test.js +3 -1
- package/dist/tools/edit-robustness.test.js.map +1 -1
- package/dist/tools/edit.d.ts +2 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +7 -1
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/edit.test.js +7 -0
- package/dist/tools/edit.test.js.map +1 -1
- package/dist/tools/exit-plan.d.ts.map +1 -1
- package/dist/tools/exit-plan.js +15 -4
- package/dist/tools/exit-plan.js.map +1 -1
- package/dist/tools/exit-plan.test.d.ts +2 -0
- package/dist/tools/exit-plan.test.d.ts.map +1 -0
- package/dist/tools/exit-plan.test.js +72 -0
- package/dist/tools/exit-plan.test.js.map +1 -0
- package/dist/tools/find.d.ts.map +1 -1
- package/dist/tools/find.js +4 -1
- package/dist/tools/find.js.map +1 -1
- package/dist/tools/grep.d.ts +3 -1
- package/dist/tools/grep.d.ts.map +1 -1
- package/dist/tools/grep.js +143 -14
- package/dist/tools/grep.js.map +1 -1
- package/dist/tools/grep.test.js +59 -0
- package/dist/tools/grep.test.js.map +1 -1
- package/dist/tools/index.d.ts +14 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +6 -5
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/overflow.test.js +4 -7
- package/dist/tools/overflow.test.js.map +1 -1
- package/dist/tools/path-utils.d.ts +15 -0
- package/dist/tools/path-utils.d.ts.map +1 -1
- package/dist/tools/path-utils.js +17 -0
- package/dist/tools/path-utils.js.map +1 -1
- package/dist/tools/path-utils.test.js +7 -2
- package/dist/tools/path-utils.test.js.map +1 -1
- package/dist/tools/prompt-hints.js +1 -1
- package/dist/tools/prompt-hints.js.map +1 -1
- package/dist/tools/screenshot.js +1 -1
- package/dist/tools/screenshot.js.map +1 -1
- package/dist/tools/search-code.d.ts.map +1 -1
- package/dist/tools/search-code.js +6 -4
- package/dist/tools/search-code.js.map +1 -1
- package/dist/tools/skill.d.ts.map +1 -1
- package/dist/tools/skill.js +4 -2
- package/dist/tools/skill.js.map +1 -1
- package/dist/tools/source-path.d.ts.map +1 -1
- package/dist/tools/source-path.js +9 -0
- package/dist/tools/source-path.js.map +1 -1
- package/dist/tools/subagent-shared.d.ts +1 -1
- package/dist/tools/subagent-shared.d.ts.map +1 -1
- package/dist/tools/subagent-shared.js +4 -1
- package/dist/tools/subagent-shared.js.map +1 -1
- package/dist/tools/subagent-shared.test.js +21 -1
- package/dist/tools/subagent-shared.test.js.map +1 -1
- package/dist/tools/subagent.d.ts +1 -1
- package/dist/tools/subagent.d.ts.map +1 -1
- package/dist/tools/subagent.js +8 -0
- package/dist/tools/subagent.js.map +1 -1
- package/dist/tools/web-fetch.d.ts +2 -1
- package/dist/tools/web-fetch.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +17 -6
- package/dist/tools/web-fetch.js.map +1 -1
- package/dist/tools/web-fetch.test.js +34 -0
- package/dist/tools/web-fetch.test.js.map +1 -1
- package/dist/tools/web-search.d.ts +2 -1
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +34 -7
- package/dist/tools/web-search.js.map +1 -1
- package/dist/tools/write.d.ts +2 -1
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/tools/write.js +7 -1
- package/dist/tools/write.js.map +1 -1
- package/dist/tools/write.test.js +12 -0
- package/dist/tools/write.test.js.map +1 -1
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +22 -85
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/app-items.d.ts +11 -12
- package/dist/ui/app-items.d.ts.map +1 -1
- package/dist/ui/app-items.js +10 -0
- package/dist/ui/app-items.js.map +1 -1
- package/dist/ui/components/ActivityIndicator.d.ts.map +1 -1
- package/dist/ui/components/ActivityIndicator.js +1 -0
- package/dist/ui/components/ActivityIndicator.js.map +1 -1
- package/dist/ui/components/Footer.d.ts +1 -1
- package/dist/ui/components/Footer.js +2 -2
- package/dist/ui/components/Footer.js.map +1 -1
- package/dist/ui/components/Footer.test.js +1 -1
- package/dist/ui/hooks/useAgentLoop.d.ts +5 -2
- package/dist/ui/hooks/useAgentLoop.d.ts.map +1 -1
- package/dist/ui/hooks/useAgentLoop.js +49 -8
- package/dist/ui/hooks/useAgentLoop.js.map +1 -1
- package/dist/ui/hooks/usePixelFixFlow.d.ts +1 -2
- package/dist/ui/hooks/usePixelFixFlow.d.ts.map +1 -1
- package/dist/ui/hooks/usePixelFixFlow.js +2 -5
- package/dist/ui/hooks/usePixelFixFlow.js.map +1 -1
- package/dist/ui/hooks/useTranscriptHistory.d.ts +8 -5
- package/dist/ui/hooks/useTranscriptHistory.d.ts.map +1 -1
- package/dist/ui/hooks/useTranscriptHistory.js +2 -30
- package/dist/ui/hooks/useTranscriptHistory.js.map +1 -1
- package/dist/ui/login.js +1 -1
- package/dist/ui/login.js.map +1 -1
- package/dist/ui/terminal-history-status-renderers.d.ts +1 -2
- package/dist/ui/terminal-history-status-renderers.d.ts.map +1 -1
- package/dist/ui/terminal-history-status-renderers.js +2 -15
- package/dist/ui/terminal-history-status-renderers.js.map +1 -1
- package/dist/ui/terminal-history.d.ts.map +1 -1
- package/dist/ui/terminal-history.js +2 -4
- package/dist/ui/terminal-history.js.map +1 -1
- package/dist/ui/thinking-level-cycle.test.js +8 -8
- package/dist/ui/thinking-level-cycle.test.js.map +1 -1
- package/dist/ui/transcript/MiscRows.d.ts +1 -4
- package/dist/ui/transcript/MiscRows.d.ts.map +1 -1
- package/dist/ui/transcript/MiscRows.js +2 -7
- package/dist/ui/transcript/MiscRows.js.map +1 -1
- package/dist/ui/transcript/TranscriptRenderer.d.ts.map +1 -1
- package/dist/ui/transcript/TranscriptRenderer.js +1 -3
- package/dist/ui/transcript/TranscriptRenderer.js.map +1 -1
- package/dist/ui/transcript/presentation.d.ts +1 -9
- package/dist/ui/transcript/presentation.d.ts.map +1 -1
- package/dist/ui/transcript/presentation.js +0 -9
- package/dist/ui/transcript/presentation.js.map +1 -1
- package/dist/ui/transcript/spacing.d.ts +2 -2
- package/dist/ui/transcript/spacing.d.ts.map +1 -1
- package/dist/ui/transcript/spacing.js +0 -1
- package/dist/ui/transcript/spacing.js.map +1 -1
- package/dist/ui/transcript/spacing.test.js +1 -3
- package/dist/ui/transcript/spacing.test.js.map +1 -1
- package/dist/ui/tui-history-parity.test.js +2 -9
- package/dist/ui/tui-history-parity.test.js.map +1 -1
- package/dist/utils/github.d.ts +20 -0
- package/dist/utils/github.d.ts.map +1 -0
- package/dist/utils/github.js +65 -0
- package/dist/utils/github.js.map +1 -0
- package/dist/utils/github.test.d.ts +2 -0
- package/dist/utils/github.test.d.ts.map +1 -0
- package/dist/utils/github.test.js +23 -0
- package/dist/utils/github.test.js.map +1 -0
- package/dist/utils/http-body.d.ts +19 -0
- package/dist/utils/http-body.d.ts.map +1 -0
- package/dist/utils/http-body.js +58 -0
- package/dist/utils/http-body.js.map +1 -0
- package/dist/utils/http-body.test.d.ts +2 -0
- package/dist/utils/http-body.test.d.ts.map +1 -0
- package/dist/utils/http-body.test.js +68 -0
- package/dist/utils/http-body.test.js.map +1 -0
- package/dist/utils/process.d.ts +26 -3
- package/dist/utils/process.d.ts.map +1 -1
- package/dist/utils/process.js +68 -10
- package/dist/utils/process.js.map +1 -1
- package/dist/utils/process.test.d.ts +2 -0
- package/dist/utils/process.test.d.ts.map +1 -0
- package/dist/utils/process.test.js +42 -0
- package/dist/utils/process.test.js.map +1 -0
- package/dist/utils/text.d.ts +9 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +11 -0
- package/dist/utils/text.js.map +1 -0
- package/package.json +4 -4
|
@@ -17,20 +17,24 @@ async function systemPrompt(model, thinkingLevel) {
|
|
|
17
17
|
afterEach(async () => {
|
|
18
18
|
await Promise.all(sessions.splice(0).map((session) => session.dispose()));
|
|
19
19
|
});
|
|
20
|
+
// `AgentSession.initialize()` does real startup work (project scan, prompt
|
|
21
|
+
// assembly) and lands ~4s per case — close enough to vitest's 5s default that
|
|
22
|
+
// these flaked intermittently on a busy machine. Give them honest headroom.
|
|
23
|
+
const INIT_TIMEOUT_MS = 30_000;
|
|
20
24
|
describe("Sol/Terra async orchestration policy", () => {
|
|
21
25
|
it("injects proactive named-tool guidance only at Ultra", async () => {
|
|
22
26
|
const prompt = await systemPrompt("gpt-5.6-sol", "ultra");
|
|
23
27
|
expect(prompt).toContain("Proactively use spawn_agent");
|
|
24
28
|
expect(prompt).toContain("Start every independent child before calling wait_agent");
|
|
25
29
|
expect(prompt).toContain("disjoint files or subsystems");
|
|
26
|
-
});
|
|
30
|
+
}, INIT_TIMEOUT_MS);
|
|
27
31
|
it("injects explicit-request-only guidance below Ultra", async () => {
|
|
28
32
|
const prompt = await systemPrompt("gpt-5.6-terra", "high");
|
|
29
33
|
expect(prompt).toContain("only when the user or applicable project/skill instructions explicitly request");
|
|
30
34
|
expect(prompt).not.toContain("Proactively use spawn_agent");
|
|
31
|
-
});
|
|
35
|
+
}, INIT_TIMEOUT_MS);
|
|
32
36
|
it("leaves other models unchanged", async () => {
|
|
33
37
|
await expect(systemPrompt("gpt-5.5-codex", "ultra")).resolves.toBe("base prompt");
|
|
34
|
-
});
|
|
38
|
+
}, INIT_TIMEOUT_MS);
|
|
35
39
|
});
|
|
36
40
|
//# sourceMappingURL=agent-session-subagent-policy.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-session-subagent-policy.test.js","sourceRoot":"","sources":["../../src/core/agent-session-subagent-policy.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,QAAQ,GAAmB,EAAE,CAAC;AAEpC,KAAK,UAAU,YAAY,CAAC,KAAa,EAAE,aAA+B;IACxE,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC;QAC/B,QAAQ,EAAE,QAAQ;QAClB,KAAK;QACL,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,YAAY,EAAE,aAAa;QAC3B,aAAa;QACb,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;IACH,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvB,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAC3B,OAAO,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAC5E,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;IACpD,EAAE,
|
|
1
|
+
{"version":3,"file":"agent-session-subagent-policy.test.js","sourceRoot":"","sources":["../../src/core/agent-session-subagent-policy.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,QAAQ,GAAmB,EAAE,CAAC;AAEpC,KAAK,UAAU,YAAY,CAAC,KAAa,EAAE,aAA+B;IACxE,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC;QAC/B,QAAQ,EAAE,QAAQ;QAClB,KAAK;QACL,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,YAAY,EAAE,aAAa;QAC3B,aAAa;QACb,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;IACH,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvB,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAC3B,OAAO,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAC5E,CAAC,CAAC,CAAC;AAEH,2EAA2E;AAC3E,8EAA8E;AAC9E,4EAA4E;AAC5E,MAAM,eAAe,GAAG,MAAM,CAAC;AAE/B,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;IACpD,EAAE,CACA,qDAAqD,EACrD,KAAK,IAAI,EAAE;QACT,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,yDAAyD,CAAC,CAAC;QACpF,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAAC;IAC3D,CAAC,EACD,eAAe,CAChB,CAAC;IAEF,EAAE,CACA,oDAAoD,EACpD,KAAK,IAAI,EAAE;QACT,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CACtB,gFAAgF,CACjF,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC;IAC9D,CAAC,EACD,eAAe,CAChB,CAAC;IAEF,EAAE,CACA,+BAA+B,EAC/B,KAAK,IAAI,EAAE;QACT,MAAM,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACpF,CAAC,EACD,eAAe,CAChB,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -176,12 +176,15 @@ export declare class AgentSession {
|
|
|
176
176
|
private hookConsecutiveFailures;
|
|
177
177
|
private hookRepeatedNoProgressCalls;
|
|
178
178
|
private hookProgressTracker;
|
|
179
|
+
private hookCycleDetector;
|
|
180
|
+
private hookCyclicPattern;
|
|
179
181
|
private hookFileEditCounts;
|
|
180
182
|
private hookToolCalls;
|
|
181
183
|
private idealReviewPhase;
|
|
182
184
|
/** Runtime-only suppression while Nolan owns verification in autopilot mode. */
|
|
183
185
|
private idealReviewSuppressed;
|
|
184
186
|
private readonly reviewCoverage;
|
|
187
|
+
/** 0 = none; 1 = first nudge sent; 2 = final stop-and-report injected. */
|
|
185
188
|
private loopBreakInjected;
|
|
186
189
|
private regroundingInjected;
|
|
187
190
|
private compactionOccurred;
|
|
@@ -219,6 +222,8 @@ export declare class AgentSession {
|
|
|
219
222
|
* set, the system prompt carries the `[DONE:n]` progress contract so the
|
|
220
223
|
* model emits step-completion markers the UI's plan-progress widget reads. */
|
|
221
224
|
private approvedPlanPath?;
|
|
225
|
+
/** Extra workspace roots added with `/add-dir` (resolved, de-duplicated). */
|
|
226
|
+
private additionalRoots;
|
|
222
227
|
private sessionId;
|
|
223
228
|
/** Stable identity shared by compaction and approved-plan checkpoint files. */
|
|
224
229
|
private conversationId;
|
|
@@ -229,6 +234,19 @@ export declare class AgentSession {
|
|
|
229
234
|
private readonly transportSessionId;
|
|
230
235
|
private sessionPath;
|
|
231
236
|
private lastPersistedIndex;
|
|
237
|
+
/**
|
|
238
|
+
* Number of non-system messages guaranteed to be in the session file — the
|
|
239
|
+
* anchor base for transcript markers (Nolan turns, autopilot verdicts, app
|
|
240
|
+
* markers). `this.messages` can run ahead of the file: the agent loop
|
|
241
|
+
* appends assistant/tool/steering messages in place but they are only
|
|
242
|
+
* persisted when the run SUCCEEDS, so after a failed run the in-memory list
|
|
243
|
+
* carries an unpersisted tail. Markers anchored against that tail point past
|
|
244
|
+
* their real position on resume — the row (notably an error) renders lower
|
|
245
|
+
* in the transcript than it happened, bunching at the bottom, or gets
|
|
246
|
+
* dropped as out-of-range. Anchoring to the persisted prefix keeps resume
|
|
247
|
+
* placement 1:1 with where the row appeared live.
|
|
248
|
+
*/
|
|
249
|
+
private persistedTranscriptCount;
|
|
232
250
|
/** Current leaf entry ID in the session DAG — used to chain parentIds for branching. */
|
|
233
251
|
private currentLeafId;
|
|
234
252
|
private opts;
|
|
@@ -387,6 +405,33 @@ export declare class AgentSession {
|
|
|
387
405
|
* custom system prompt is in force (the host owns the prompt then).
|
|
388
406
|
*/
|
|
389
407
|
setApprovedPlan(approvedPlanPath: string | undefined): Promise<void>;
|
|
408
|
+
/** Extra workspace roots added with `/add-dir`, in the order added. */
|
|
409
|
+
getAdditionalRoots(): string[];
|
|
410
|
+
/**
|
|
411
|
+
* Add another workspace root. Tools already accept absolute paths, so this
|
|
412
|
+
* only widens the write guard and tells the model the root exists. Rebuilding
|
|
413
|
+
* the system prompt costs one cache-miss turn — the alternative (an uncached
|
|
414
|
+
* suffix) would drift from the tool behaviour it describes.
|
|
415
|
+
*
|
|
416
|
+
* @returns the resolved root, or an error message for the user.
|
|
417
|
+
*/
|
|
418
|
+
addDirectory(dir: string): Promise<{
|
|
419
|
+
ok: true;
|
|
420
|
+
root: string;
|
|
421
|
+
} | {
|
|
422
|
+
ok: false;
|
|
423
|
+
error: string;
|
|
424
|
+
}>;
|
|
425
|
+
/** Remove an exact root previously added with `/add-dir`. */
|
|
426
|
+
removeDirectory(dir: string): Promise<{
|
|
427
|
+
ok: true;
|
|
428
|
+
root: string;
|
|
429
|
+
} | {
|
|
430
|
+
ok: false;
|
|
431
|
+
error: string;
|
|
432
|
+
}>;
|
|
433
|
+
/** Environment facts that vary per session rather than per host. */
|
|
434
|
+
private promptEnvironment;
|
|
390
435
|
/** Rebuild messages[0] from current plan-mode + approved-plan state. */
|
|
391
436
|
private rebuildSystemPromptInPlace;
|
|
392
437
|
private withSystemPromptTail;
|
|
@@ -486,6 +531,7 @@ export declare class AgentSession {
|
|
|
486
531
|
/** Stable cache-routing key for downstream sub-agent processes. */
|
|
487
532
|
getCurrentCacheKey(): string | undefined;
|
|
488
533
|
dispose(): Promise<void>;
|
|
534
|
+
private setSessionPath;
|
|
489
535
|
private createNewSession;
|
|
490
536
|
private loadExistingSession;
|
|
491
537
|
private prepareDynamicContext;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-session.d.ts","sourceRoot":"","sources":["../../src/core/agent-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,SAAS,EAEf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAEL,KAAK,OAAO,EACZ,KAAK,QAAQ,EAEb,KAAK,aAAa,EAInB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EACL,oBAAoB,EAGrB,MAAM,qBAAqB,CAAC;AAQ7B,OAAO,EAML,KAAK,UAAU,EAEf,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACvB,MAAM,sBAAsB,CAAC;AAoB9B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAW9D,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-session.d.ts","sourceRoot":"","sources":["../../src/core/agent-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,12 +30,14 @@ import { discoverAgents } from "./agents.js";
|
|
|
30
30
|
import { enhancePrompt } from "../utils/prompt-enhancer.js";
|
|
31
31
|
import { detectProjectStack } from "./language-detector.js";
|
|
32
32
|
import { evaluateIdealReview, buildIdealReviewMessage, buildReviewCoverageMessage, withReviewCoverageRequirements, detectTestDrift, ReviewCoverageTracker, } from "./ideal-review.js";
|
|
33
|
-
import { evaluateLoopBreak, buildLoopBreakMessage, ToolCallProgressTracker, detectTextRepetition, } from "./loop-breaker.js";
|
|
33
|
+
import { evaluateLoopBreak, buildLoopBreakMessage, CycleDetector, ToolCallProgressTracker, detectTextRepetition, } from "./loop-breaker.js";
|
|
34
34
|
import { buildRegroundingMessage } from "./regrounding.js";
|
|
35
35
|
import { wrapSteeringText, STEERING_PREFIX } from "./steering.js";
|
|
36
36
|
import { findUserSessionPrompt, getUserSessionPrompt } from "./session-preview.js";
|
|
37
|
+
import { normalizeMessageImages } from "./message-images.js";
|
|
37
38
|
import crypto from "node:crypto";
|
|
38
39
|
import fs from "node:fs/promises";
|
|
40
|
+
import os from "node:os";
|
|
39
41
|
import path from "node:path";
|
|
40
42
|
// ── Tool-result policy ─────────────────────────────────────
|
|
41
43
|
/** Resolve the per-result cap passed to the agent loop for the active transport. */
|
|
@@ -105,13 +107,16 @@ export class AgentSession {
|
|
|
105
107
|
hookConsecutiveFailures = 0;
|
|
106
108
|
hookRepeatedNoProgressCalls = 0;
|
|
107
109
|
hookProgressTracker = new ToolCallProgressTracker();
|
|
110
|
+
hookCycleDetector = new CycleDetector();
|
|
111
|
+
hookCyclicPattern = null;
|
|
108
112
|
hookFileEditCounts = new Map();
|
|
109
113
|
hookToolCalls = new Map();
|
|
110
114
|
idealReviewPhase = "idle";
|
|
111
115
|
/** Runtime-only suppression while Nolan owns verification in autopilot mode. */
|
|
112
116
|
idealReviewSuppressed = false;
|
|
113
117
|
reviewCoverage;
|
|
114
|
-
|
|
118
|
+
/** 0 = none; 1 = first nudge sent; 2 = final stop-and-report injected. */
|
|
119
|
+
loopBreakInjected = 0;
|
|
115
120
|
regroundingInjected = false;
|
|
116
121
|
compactionOccurred = false;
|
|
117
122
|
lastCompactionCompacted = false;
|
|
@@ -154,6 +159,8 @@ export class AgentSession {
|
|
|
154
159
|
* set, the system prompt carries the `[DONE:n]` progress contract so the
|
|
155
160
|
* model emits step-completion markers the UI's plan-progress widget reads. */
|
|
156
161
|
approvedPlanPath;
|
|
162
|
+
/** Extra workspace roots added with `/add-dir` (resolved, de-duplicated). */
|
|
163
|
+
additionalRoots = [];
|
|
157
164
|
sessionId = "";
|
|
158
165
|
/** Stable identity shared by compaction and approved-plan checkpoint files. */
|
|
159
166
|
conversationId = "";
|
|
@@ -164,6 +171,22 @@ export class AgentSession {
|
|
|
164
171
|
transportSessionId = crypto.randomUUID();
|
|
165
172
|
sessionPath = "";
|
|
166
173
|
lastPersistedIndex = 0;
|
|
174
|
+
/**
|
|
175
|
+
* Number of non-system messages guaranteed to be in the session file — the
|
|
176
|
+
* anchor base for transcript markers (Nolan turns, autopilot verdicts, app
|
|
177
|
+
* markers). `this.messages` can run ahead of the file: the agent loop
|
|
178
|
+
* appends assistant/tool/steering messages in place but they are only
|
|
179
|
+
* persisted when the run SUCCEEDS, so after a failed run the in-memory list
|
|
180
|
+
* carries an unpersisted tail. Markers anchored against that tail point past
|
|
181
|
+
* their real position on resume — the row (notably an error) renders lower
|
|
182
|
+
* in the transcript than it happened, bunching at the bottom, or gets
|
|
183
|
+
* dropped as out-of-range. Anchoring to the persisted prefix keeps resume
|
|
184
|
+
* placement 1:1 with where the row appeared live.
|
|
185
|
+
*/
|
|
186
|
+
persistedTranscriptCount() {
|
|
187
|
+
return this.messages.slice(0, this.lastPersistedIndex).filter((m) => m.role !== "system")
|
|
188
|
+
.length;
|
|
189
|
+
}
|
|
167
190
|
/** Current leaf entry ID in the session DAG — used to chain parentIds for branching. */
|
|
168
191
|
currentLeafId = null;
|
|
169
192
|
opts;
|
|
@@ -237,6 +260,14 @@ export class AgentSession {
|
|
|
237
260
|
provider: this.provider,
|
|
238
261
|
model: this.model,
|
|
239
262
|
lspDiagnostics: this.settingsManager.get("lspDiagnostics"),
|
|
263
|
+
getWriteGuardSettings: () => ({
|
|
264
|
+
allowOutsideWorkspaceWrites: this.settingsManager.get("allowOutsideWorkspaceWrites"),
|
|
265
|
+
additionalRoots: this.additionalRoots,
|
|
266
|
+
}),
|
|
267
|
+
getNetworkPolicy: () => ({
|
|
268
|
+
mode: this.settingsManager.get("networkMode"),
|
|
269
|
+
allow: this.settingsManager.get("networkAllow"),
|
|
270
|
+
}),
|
|
240
271
|
authStorage: this.authStorage,
|
|
241
272
|
onFileRead: (filePath) => this.reviewCoverage.recordRead(filePath),
|
|
242
273
|
onFileMutated: (filePath) => {
|
|
@@ -251,6 +282,7 @@ export class AgentSession {
|
|
|
251
282
|
getThinkingLevel: () => this.thinkingLevel,
|
|
252
283
|
getBaseUrl: () => this.baseUrl,
|
|
253
284
|
getCacheKey: () => this.getPromptCacheKey(),
|
|
285
|
+
getMaxPerModel: () => this.settingsManager.get("subagentMaxPerModel"),
|
|
254
286
|
disableAsyncSubagents: this.opts.subagentWorker,
|
|
255
287
|
onSubAgentState: (snapshot) => this.eventBus.emit("subagent_state", snapshot),
|
|
256
288
|
// Plan mode: only wired when the host supplies callbacks. The ref is
|
|
@@ -298,7 +330,7 @@ export class AgentSession {
|
|
|
298
330
|
await this.connectMcpServers();
|
|
299
331
|
}
|
|
300
332
|
const basePrompt = this.customSystemPrompt ??
|
|
301
|
-
(await buildSystemPrompt(this.cwd, this.skills, false, undefined, this.tools.map((tool) => tool.name), undefined, this.provider));
|
|
333
|
+
(await buildSystemPrompt(this.cwd, this.skills, false, undefined, this.tools.map((tool) => tool.name), undefined, this.provider, this.promptEnvironment()));
|
|
302
334
|
this.baseSystemPrompt = basePrompt;
|
|
303
335
|
this.messages = [{ role: "system", content: this.withSystemPromptTail(basePrompt) }];
|
|
304
336
|
this.syncUltraOrchestrationPrompt();
|
|
@@ -325,6 +357,32 @@ export class AgentSession {
|
|
|
325
357
|
}
|
|
326
358
|
if (this.sessionId)
|
|
327
359
|
await this.subAgentManager?.hydrate(this.sessionId);
|
|
360
|
+
// Maintenance is deliberately queued after initialization work and never
|
|
361
|
+
// awaited, so retention/compression cannot delay sidecar or CLI readiness.
|
|
362
|
+
if (!this.opts.transient) {
|
|
363
|
+
const retentionDays = this.settingsManager.get("sessionRetentionDays");
|
|
364
|
+
void Promise.resolve()
|
|
365
|
+
.then(() => this.sessionManager.runMaintenance({
|
|
366
|
+
retentionDays,
|
|
367
|
+
keepPaths: this.sessionPath ? [this.sessionPath] : [],
|
|
368
|
+
}))
|
|
369
|
+
.then((metrics) => {
|
|
370
|
+
if (metrics.deletedFiles > 0 || metrics.archivedFiles > 0 || metrics.failures > 0) {
|
|
371
|
+
log("INFO", "session", "Session maintenance complete", {
|
|
372
|
+
deletedFiles: String(metrics.deletedFiles),
|
|
373
|
+
deletedMB: (metrics.deletedBytes / 1024 / 1024).toFixed(1),
|
|
374
|
+
archivedFiles: String(metrics.archivedFiles),
|
|
375
|
+
savedMB: (metrics.bytesSaved / 1024 / 1024).toFixed(1),
|
|
376
|
+
failures: String(metrics.failures),
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
})
|
|
380
|
+
.catch((error) => {
|
|
381
|
+
log("WARN", "session", "Session maintenance failed", {
|
|
382
|
+
message: error instanceof Error ? error.message : String(error),
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
}
|
|
328
386
|
// EZ Coder owns its command registry. Other agents start with an isolated
|
|
329
387
|
// empty registry and can register their own commands in their own file.
|
|
330
388
|
if (this.opts.coderSlashCommands !== false) {
|
|
@@ -617,11 +675,13 @@ export class AgentSession {
|
|
|
617
675
|
this.hookConsecutiveFailures = 0;
|
|
618
676
|
this.hookRepeatedNoProgressCalls = 0;
|
|
619
677
|
this.hookProgressTracker.reset();
|
|
678
|
+
this.hookCycleDetector.reset();
|
|
679
|
+
this.hookCyclicPattern = null;
|
|
620
680
|
this.hookFileEditCounts.clear();
|
|
621
681
|
this.hookToolCalls.clear();
|
|
622
682
|
this.reviewCoverage.reset();
|
|
623
683
|
this.idealReviewPhase = "idle";
|
|
624
|
-
this.loopBreakInjected =
|
|
684
|
+
this.loopBreakInjected = 0;
|
|
625
685
|
this.regroundingInjected = false;
|
|
626
686
|
this.compactionOccurred = false;
|
|
627
687
|
this.originalRequest = originalRequest;
|
|
@@ -654,6 +714,7 @@ export class AgentSession {
|
|
|
654
714
|
this.hookStats.bashCalls += 1;
|
|
655
715
|
this.hookConsecutiveFailures = event.isError ? this.hookConsecutiveFailures + 1 : 0;
|
|
656
716
|
this.hookRepeatedNoProgressCalls = this.hookProgressTracker.record(name, args, event.result, event.isError);
|
|
717
|
+
this.hookCyclicPattern = this.hookCycleDetector.record(name, args, event.result, event.isError);
|
|
657
718
|
if (name === "edit" && !event.isError) {
|
|
658
719
|
const diff = event.details?.diff ?? event.result;
|
|
659
720
|
const added = (diff.match(/^\+[^+]/gm) ?? []).length;
|
|
@@ -708,19 +769,34 @@ export class AgentSession {
|
|
|
708
769
|
return null;
|
|
709
770
|
if (!this.settingsManager.get("idealReviewEnabled"))
|
|
710
771
|
return null;
|
|
711
|
-
|
|
772
|
+
// Two-stage loop-breaker: stage 1 nudges; a FRESH detection after that
|
|
773
|
+
// injects the harsher final stop-and-report prompt. Signals reset after
|
|
774
|
+
// each injection so stage 2 only fires on new evidence.
|
|
775
|
+
if (this.loopBreakInjected < 2) {
|
|
712
776
|
const decision = evaluateLoopBreak({
|
|
713
777
|
consecutiveFailures: this.hookConsecutiveFailures,
|
|
714
778
|
repeatedNoProgressCalls: this.hookRepeatedNoProgressCalls,
|
|
715
779
|
textRepetitionDetected: detectTextRepetition(this.hookText),
|
|
780
|
+
...(this.hookCyclicPattern ? { cyclicPattern: this.hookCyclicPattern } : {}),
|
|
716
781
|
});
|
|
717
782
|
if (decision.shouldBreak) {
|
|
718
|
-
this.loopBreakInjected
|
|
783
|
+
const stage = this.loopBreakInjected === 0 ? 1 : 2;
|
|
784
|
+
this.loopBreakInjected = stage;
|
|
785
|
+
this.hookProgressTracker.reset();
|
|
786
|
+
this.hookCycleDetector.reset();
|
|
787
|
+
this.hookCyclicPattern = null;
|
|
788
|
+
this.hookConsecutiveFailures = 0;
|
|
789
|
+
this.hookRepeatedNoProgressCalls = 0;
|
|
790
|
+
// Clear the text buffer too — otherwise a stage-1 text-repetition
|
|
791
|
+
// trigger still sees the same repeated tail on the next check and
|
|
792
|
+
// escalates to stage 2 on stale evidence.
|
|
793
|
+
this.hookText = "";
|
|
719
794
|
log("INFO", "loop-break", "Injecting loop-break nudge", {
|
|
795
|
+
stage: String(stage),
|
|
720
796
|
reasons: decision.reasons.join(", "),
|
|
721
797
|
});
|
|
722
798
|
this.eventBus.emit("hook", { kind: "loop_break" });
|
|
723
|
-
return [buildLoopBreakMessage(decision.reasons)];
|
|
799
|
+
return [buildLoopBreakMessage(decision.reasons, stage === 2)];
|
|
724
800
|
}
|
|
725
801
|
}
|
|
726
802
|
if (!this.regroundingInjected && this.compactionOccurred) {
|
|
@@ -1141,7 +1217,10 @@ export class AgentSession {
|
|
|
1141
1217
|
}
|
|
1142
1218
|
else if (this.provider !== "anthropic" && !hasWebSearch) {
|
|
1143
1219
|
// Switching FROM anthropic — add client-side web_search
|
|
1144
|
-
this.tools.push(createWebSearchTool()
|
|
1220
|
+
this.tools.push(createWebSearchTool(() => ({
|
|
1221
|
+
mode: this.settingsManager.get("networkMode"),
|
|
1222
|
+
allow: this.settingsManager.get("networkAllow"),
|
|
1223
|
+
})));
|
|
1145
1224
|
}
|
|
1146
1225
|
// Reconnect MCP servers ONLY when GLM is involved on either side — GLM
|
|
1147
1226
|
// is the only provider with a different server set (Z.AI tools), so a
|
|
@@ -1206,6 +1285,7 @@ export class AgentSession {
|
|
|
1206
1285
|
this.lastCompactionCompacted = result.result.compacted;
|
|
1207
1286
|
if (!result.result.compacted) {
|
|
1208
1287
|
this.eventBus.emit("compaction_end", {
|
|
1288
|
+
compacted: false,
|
|
1209
1289
|
originalCount: result.result.originalCount,
|
|
1210
1290
|
newCount: result.result.newCount,
|
|
1211
1291
|
});
|
|
@@ -1230,7 +1310,7 @@ export class AgentSession {
|
|
|
1230
1310
|
});
|
|
1231
1311
|
this.sessionId = session.id;
|
|
1232
1312
|
this.conversationId = session.header.conversationId ?? session.id;
|
|
1233
|
-
this.
|
|
1313
|
+
this.setSessionPath(session.path);
|
|
1234
1314
|
await this.subAgentManager?.rebindParentSession(this.sessionId);
|
|
1235
1315
|
// Write compacted messages (skip system — it's rebuilt on load)
|
|
1236
1316
|
for (const msg of this.messages) {
|
|
@@ -1252,6 +1332,7 @@ export class AgentSession {
|
|
|
1252
1332
|
});
|
|
1253
1333
|
}
|
|
1254
1334
|
this.eventBus.emit("compaction_end", {
|
|
1335
|
+
compacted: true,
|
|
1255
1336
|
originalCount: result.result.originalCount,
|
|
1256
1337
|
newCount: result.result.newCount,
|
|
1257
1338
|
});
|
|
@@ -1275,7 +1356,7 @@ export class AgentSession {
|
|
|
1275
1356
|
this.appMarkers = [];
|
|
1276
1357
|
this.turnMetrics = [];
|
|
1277
1358
|
const basePrompt = this.customSystemPrompt ??
|
|
1278
|
-
(await buildSystemPrompt(this.cwd, this.skills, false, undefined, this.tools.map((tool) => tool.name), undefined, this.provider));
|
|
1359
|
+
(await buildSystemPrompt(this.cwd, this.skills, false, undefined, this.tools.map((tool) => tool.name), undefined, this.provider, this.promptEnvironment()));
|
|
1279
1360
|
this.baseSystemPrompt = basePrompt;
|
|
1280
1361
|
this.messages = [{ role: "system", content: this.withSystemPromptTail(basePrompt) }];
|
|
1281
1362
|
this.syncUltraOrchestrationPrompt();
|
|
@@ -1290,7 +1371,7 @@ export class AgentSession {
|
|
|
1290
1371
|
this.sessionId = "";
|
|
1291
1372
|
this.conversationId = "";
|
|
1292
1373
|
this.sessionPreview = "";
|
|
1293
|
-
this.
|
|
1374
|
+
this.setSessionPath("");
|
|
1294
1375
|
this.lastPersistedIndex = this.messages.length;
|
|
1295
1376
|
}
|
|
1296
1377
|
else {
|
|
@@ -1315,6 +1396,7 @@ export class AgentSession {
|
|
|
1315
1396
|
async branch(stepsBack = 2) {
|
|
1316
1397
|
// Load the full session to access the DAG
|
|
1317
1398
|
const loaded = await this.sessionManager.load(this.sessionPath);
|
|
1399
|
+
this.setSessionPath(loaded.path);
|
|
1318
1400
|
const branch = this.sessionManager.getBranch(loaded.entries, this.currentLeafId);
|
|
1319
1401
|
// Walk back stepsBack message entries
|
|
1320
1402
|
const messageEntries = branch.filter((e) => e.type === "message");
|
|
@@ -1345,6 +1427,7 @@ export class AgentSession {
|
|
|
1345
1427
|
*/
|
|
1346
1428
|
async listBranches() {
|
|
1347
1429
|
const loaded = await this.sessionManager.load(this.sessionPath);
|
|
1430
|
+
this.setSessionPath(loaded.path);
|
|
1348
1431
|
return this.sessionManager.listBranches(loaded.entries);
|
|
1349
1432
|
}
|
|
1350
1433
|
getState() {
|
|
@@ -1450,11 +1533,67 @@ export class AgentSession {
|
|
|
1450
1533
|
this.approvedPlanPath = approvedPlanPath;
|
|
1451
1534
|
await this.rebuildSystemPromptInPlace();
|
|
1452
1535
|
}
|
|
1536
|
+
/** Extra workspace roots added with `/add-dir`, in the order added. */
|
|
1537
|
+
getAdditionalRoots() {
|
|
1538
|
+
return [...this.additionalRoots];
|
|
1539
|
+
}
|
|
1540
|
+
/**
|
|
1541
|
+
* Add another workspace root. Tools already accept absolute paths, so this
|
|
1542
|
+
* only widens the write guard and tells the model the root exists. Rebuilding
|
|
1543
|
+
* the system prompt costs one cache-miss turn — the alternative (an uncached
|
|
1544
|
+
* suffix) would drift from the tool behaviour it describes.
|
|
1545
|
+
*
|
|
1546
|
+
* @returns the resolved root, or an error message for the user.
|
|
1547
|
+
*/
|
|
1548
|
+
async addDirectory(dir) {
|
|
1549
|
+
const resolved = path.resolve(this.cwd, dir.replace(/^~(?=[/\\]|$)/, os.homedir()));
|
|
1550
|
+
let stat;
|
|
1551
|
+
try {
|
|
1552
|
+
stat = await fs.stat(resolved);
|
|
1553
|
+
}
|
|
1554
|
+
catch {
|
|
1555
|
+
return { ok: false, error: `Not found: ${resolved}` };
|
|
1556
|
+
}
|
|
1557
|
+
if (!stat.isDirectory())
|
|
1558
|
+
return { ok: false, error: `Not a directory: ${resolved}` };
|
|
1559
|
+
const covered = [this.cwd, ...this.additionalRoots].some((root) => {
|
|
1560
|
+
const relative = path.relative(path.resolve(root), resolved);
|
|
1561
|
+
return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative));
|
|
1562
|
+
});
|
|
1563
|
+
if (covered)
|
|
1564
|
+
return { ok: false, error: `Already in the workspace: ${resolved}` };
|
|
1565
|
+
// Drop roots the new one subsumes so the list stays minimal.
|
|
1566
|
+
this.additionalRoots = this.additionalRoots.filter((root) => {
|
|
1567
|
+
const relative = path.relative(resolved, path.resolve(root));
|
|
1568
|
+
return relative.startsWith("..") || path.isAbsolute(relative);
|
|
1569
|
+
});
|
|
1570
|
+
this.additionalRoots.push(resolved);
|
|
1571
|
+
await this.rebuildSystemPromptInPlace();
|
|
1572
|
+
return { ok: true, root: resolved };
|
|
1573
|
+
}
|
|
1574
|
+
/** Remove an exact root previously added with `/add-dir`. */
|
|
1575
|
+
async removeDirectory(dir) {
|
|
1576
|
+
const resolved = path.resolve(this.cwd, dir.replace(/^~(?=[/\\]|$)/, os.homedir()));
|
|
1577
|
+
const index = this.additionalRoots.findIndex((root) => path.resolve(root) === resolved);
|
|
1578
|
+
if (index === -1) {
|
|
1579
|
+
return { ok: false, error: `Not an additional workspace root: ${resolved}` };
|
|
1580
|
+
}
|
|
1581
|
+
this.additionalRoots.splice(index, 1);
|
|
1582
|
+
await this.rebuildSystemPromptInPlace();
|
|
1583
|
+
return { ok: true, root: resolved };
|
|
1584
|
+
}
|
|
1585
|
+
/** Environment facts that vary per session rather than per host. */
|
|
1586
|
+
promptEnvironment() {
|
|
1587
|
+
const networkAllow = this.settingsManager.get("networkMode") === "allowlist"
|
|
1588
|
+
? this.settingsManager.get("networkAllow")
|
|
1589
|
+
: [];
|
|
1590
|
+
return { additionalRoots: this.additionalRoots, networkAllow };
|
|
1591
|
+
}
|
|
1453
1592
|
/** Rebuild messages[0] from current plan-mode + approved-plan state. */
|
|
1454
1593
|
async rebuildSystemPromptInPlace() {
|
|
1455
1594
|
if (this.customSystemPrompt)
|
|
1456
1595
|
return;
|
|
1457
|
-
const rebuilt = await buildSystemPrompt(this.cwd, this.skills, this.planModeRef.current, this.approvedPlanPath, this.tools.map((tool) => tool.name), undefined, this.provider);
|
|
1596
|
+
const rebuilt = await buildSystemPrompt(this.cwd, this.skills, this.planModeRef.current, this.approvedPlanPath, this.tools.map((tool) => tool.name), undefined, this.provider, this.promptEnvironment());
|
|
1458
1597
|
this.baseSystemPrompt = rebuilt;
|
|
1459
1598
|
const content = this.withSystemPromptTail(rebuilt);
|
|
1460
1599
|
if (this.messages[0]?.role === "system") {
|
|
@@ -1540,7 +1679,7 @@ export class AgentSession {
|
|
|
1540
1679
|
* appendEntry's own handling.
|
|
1541
1680
|
*/
|
|
1542
1681
|
async persistNolanTurn(question, reply) {
|
|
1543
|
-
const afterMessageCount = this.
|
|
1682
|
+
const afterMessageCount = this.persistedTranscriptCount();
|
|
1544
1683
|
const payload = { version: 1, question, reply, afterMessageCount };
|
|
1545
1684
|
this.nolanTurns.push(payload);
|
|
1546
1685
|
if (!this.sessionPath)
|
|
@@ -1583,7 +1722,7 @@ export class AgentSession {
|
|
|
1583
1722
|
* No-op persistence for transient sessions (kept in memory only).
|
|
1584
1723
|
*/
|
|
1585
1724
|
async persistAutopilotMarker(phase, extra) {
|
|
1586
|
-
const afterMessageCount = this.
|
|
1725
|
+
const afterMessageCount = this.persistedTranscriptCount();
|
|
1587
1726
|
const payload = {
|
|
1588
1727
|
version: 1,
|
|
1589
1728
|
phase,
|
|
@@ -1638,7 +1777,7 @@ export class AgentSession {
|
|
|
1638
1777
|
* No-op persistence for transient sessions.
|
|
1639
1778
|
*/
|
|
1640
1779
|
async persistAppMarker(kind, data, anchorOffset = 0) {
|
|
1641
|
-
const afterMessageCount = this.
|
|
1780
|
+
const afterMessageCount = this.persistedTranscriptCount() + anchorOffset;
|
|
1642
1781
|
const payload = { version: 1, kind, afterMessageCount, data };
|
|
1643
1782
|
this.appMarkers.push(payload);
|
|
1644
1783
|
if (!this.sessionPath)
|
|
@@ -1768,11 +1907,21 @@ export class AgentSession {
|
|
|
1768
1907
|
this.lspManager?.shutdownAll();
|
|
1769
1908
|
await Promise.all([this.subAgentManager?.shutdownAll(), this.mcpManager?.dispose()]);
|
|
1770
1909
|
await this.extensionLoader.deactivateAll();
|
|
1910
|
+
this.setSessionPath("");
|
|
1771
1911
|
this.eventBus.removeAllListeners();
|
|
1772
1912
|
this.messages = [];
|
|
1773
1913
|
this.tools = [];
|
|
1774
1914
|
}
|
|
1775
1915
|
// ── Private ────────────────────────────────────────────
|
|
1916
|
+
setSessionPath(nextPath) {
|
|
1917
|
+
if (this.sessionPath === nextPath)
|
|
1918
|
+
return;
|
|
1919
|
+
if (this.sessionPath)
|
|
1920
|
+
this.sessionManager.unregisterActivePath(this.sessionPath);
|
|
1921
|
+
this.sessionPath = nextPath;
|
|
1922
|
+
if (nextPath)
|
|
1923
|
+
this.sessionManager.registerActivePath(nextPath);
|
|
1924
|
+
}
|
|
1776
1925
|
async createNewSession() {
|
|
1777
1926
|
const session = await this.sessionManager.create(this.cwd, this.provider, this.model, {
|
|
1778
1927
|
conversationId: this.conversationId || undefined,
|
|
@@ -1780,7 +1929,7 @@ export class AgentSession {
|
|
|
1780
1929
|
});
|
|
1781
1930
|
this.sessionId = session.id;
|
|
1782
1931
|
this.conversationId = session.header.conversationId ?? session.id;
|
|
1783
|
-
this.
|
|
1932
|
+
this.setSessionPath(session.path);
|
|
1784
1933
|
this.lastPersistedIndex = this.messages.length;
|
|
1785
1934
|
}
|
|
1786
1935
|
async loadExistingSession(sessionPath) {
|
|
@@ -1806,9 +1955,15 @@ export class AgentSession {
|
|
|
1806
1955
|
this.turnMetrics = this.sessionManager.getTurnMetrics(loaded.entries);
|
|
1807
1956
|
// Track the current leaf for subsequent entries
|
|
1808
1957
|
this.currentLeafId = loaded.header.leafId;
|
|
1809
|
-
// Rebuild messages: keep system, add loaded
|
|
1958
|
+
// Rebuild messages: keep system, add loaded. Older ezcoder-app sessions may
|
|
1959
|
+
// contain full-resolution attachments; repair them once on load so they do
|
|
1960
|
+
// not fail when Anthropic's stricter many-image limit activates later.
|
|
1810
1961
|
const systemMsg = this.messages[0]; // Already built
|
|
1811
1962
|
this.messages = [systemMsg, ...loadedMessages];
|
|
1963
|
+
const normalizedImageCount = await normalizeMessageImages(this.messages);
|
|
1964
|
+
if (normalizedImageCount > 0) {
|
|
1965
|
+
log("INFO", "session", `Resized ${normalizedImageCount} restored session image(s)`);
|
|
1966
|
+
}
|
|
1812
1967
|
// Auto-compact on load if the restored session exceeds the context window.
|
|
1813
1968
|
// Without this, huge sessions (1M+ tokens) get loaded into memory and OOM.
|
|
1814
1969
|
const creds = await this.authStorage.resolveCredentials(this.provider, {
|
|
@@ -1858,7 +2013,7 @@ export class AgentSession {
|
|
|
1858
2013
|
});
|
|
1859
2014
|
this.sessionId = session.id;
|
|
1860
2015
|
this.conversationId = session.header.conversationId ?? session.id;
|
|
1861
|
-
this.
|
|
2016
|
+
this.setSessionPath(session.path);
|
|
1862
2017
|
await this.subAgentManager?.rebindParentSession(this.sessionId);
|
|
1863
2018
|
this.currentLeafId = null;
|
|
1864
2019
|
// Re-persist (compacted) messages — skip system, it's rebuilt on load
|
|
@@ -1886,7 +2041,7 @@ export class AgentSession {
|
|
|
1886
2041
|
// session was merely reopened (e.g. app/window restart) with zero new
|
|
1887
2042
|
// messages in between — the duplicate entries seen in the session list.
|
|
1888
2043
|
this.sessionId = loaded.header.id;
|
|
1889
|
-
this.
|
|
2044
|
+
this.setSessionPath(loaded.path);
|
|
1890
2045
|
this.lastPersistedIndex = this.messages.length;
|
|
1891
2046
|
}
|
|
1892
2047
|
async prepareDynamicContext(_latestUserPrompt) {
|
|
@@ -1947,6 +2102,9 @@ export class AgentSession {
|
|
|
1947
2102
|
const lines = branches.map((b, i) => ` ${i + 1}. ${b.leafId.slice(0, 8)} — ${b.entryCount} entries (${b.leafId === this.currentLeafId ? "active" : "inactive"})`);
|
|
1948
2103
|
return `${branches.length} branch(es):\n${lines.join("\n")}`;
|
|
1949
2104
|
},
|
|
2105
|
+
addDirectory: (dir) => this.addDirectory(dir),
|
|
2106
|
+
removeDirectory: (dir) => this.removeDirectory(dir),
|
|
2107
|
+
getAdditionalRoots: () => this.getAdditionalRoots(),
|
|
1950
2108
|
};
|
|
1951
2109
|
}
|
|
1952
2110
|
}
|