@prestyj/cli 5.16.2 → 5.19.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 +2 -1
- package/assets/skills/refactoring/SKILL.md +64 -0
- package/assets/skills/refactoring/references/agent-pitfalls.md +43 -0
- package/assets/skills/refactoring/references/legacy.md +49 -0
- package/assets/skills/refactoring/references/smells.md +71 -0
- package/dist/app-sidecar-sessions.d.ts +0 -1
- package/dist/app-sidecar.d.ts +0 -1
- package/dist/app-sidecar.js +40 -9
- package/dist/app-sidecar.js.map +1 -1
- package/dist/chat-agents/general.d.ts +0 -1
- package/dist/chat-agents/index.d.ts +0 -1
- package/dist/chat-agents/jiwa.d.ts +0 -1
- package/dist/chat-agents/memory.d.ts +0 -1
- package/dist/chat-agents/research.d.ts +0 -1
- package/dist/chat-agents/shared.d.ts +0 -1
- package/dist/chat-agents/therapist.d.ts +0 -1
- package/dist/chat-agents/types.d.ts +0 -1
- package/dist/cli/auth.d.ts +0 -1
- package/dist/cli/command-routing.d.ts +0 -1
- package/dist/cli/mcp.d.ts +0 -1
- package/dist/cli/mcp.js.map +1 -1
- package/dist/cli/pixel.d.ts +0 -1
- package/dist/cli/shared.d.ts +0 -1
- package/dist/cli.d.ts +0 -1
- package/dist/config.d.ts +0 -1
- package/dist/core/agent-notifications.d.ts +0 -1
- package/dist/core/agent-session.d.ts +45 -2
- package/dist/core/agent-session.js +521 -41
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/agents.d.ts +0 -1
- package/dist/core/api-benchmark.d.ts +0 -1
- package/dist/core/ask-user.d.ts +0 -1
- package/dist/core/auth/index.d.ts +0 -1
- package/dist/core/auth-providers.d.ts +0 -1
- package/dist/core/auth-storage.d.ts +0 -1
- package/dist/core/auto-update.d.ts +0 -1
- package/dist/core/autopilot-cycle.d.ts +7 -4
- package/dist/core/autopilot-cycle.js +43 -6
- package/dist/core/autopilot-cycle.js.map +1 -1
- package/dist/core/autopilot-gate.d.ts +0 -1
- package/dist/core/autopilot-gate.js.map +1 -1
- package/dist/core/autopilot-verdict.d.ts +2 -1
- package/dist/core/autopilot-verdict.js +25 -0
- package/dist/core/autopilot-verdict.js.map +1 -1
- package/dist/core/bash-spawn-benchmark.d.ts +0 -1
- package/dist/core/bundled-agents.d.ts +0 -1
- package/dist/core/cache-warm-benchmark.d.ts +0 -1
- package/dist/core/checkpoint-store.d.ts +0 -1
- package/dist/core/claude-code-version.d.ts +0 -1
- package/dist/core/code-retrieval-chunkers.d.ts +0 -1
- package/dist/core/code-retrieval.d.ts +0 -1
- package/dist/core/compaction/active-context.d.ts +0 -1
- package/dist/core/compaction/compactor.d.ts +34 -1
- package/dist/core/compaction/compactor.js +161 -2
- package/dist/core/compaction/compactor.js.map +1 -1
- package/dist/core/compaction/policy.d.ts +0 -1
- package/dist/core/compaction/query-aware-selector.d.ts +0 -1
- package/dist/core/compaction/token-estimator.d.ts +0 -1
- package/dist/core/compaction/tool-result-pruner.d.ts +0 -1
- package/dist/core/context-limits.d.ts +0 -1
- package/dist/core/custom-commands.d.ts +0 -1
- package/dist/core/encode-cwd.d.ts +0 -1
- package/dist/core/env-delta.d.ts +0 -1
- package/dist/core/event-bus.d.ts +5 -1
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +0 -1
- package/dist/core/extensions/plugin-bundles.d.ts +0 -1
- package/dist/core/extensions/types.d.ts +0 -1
- package/dist/core/fast-apply-benchmark.d.ts +0 -1
- package/dist/core/file-lock.d.ts +0 -1
- package/dist/core/foreign-session-import.d.ts +0 -1
- package/dist/core/foreign-transcript-blocks.d.ts +0 -1
- package/dist/core/goal-controller.d.ts +0 -1
- package/dist/core/goal-prerequisites.d.ts +0 -1
- package/dist/core/goal-store.d.ts +0 -1
- package/dist/core/goal-store.js.map +1 -1
- package/dist/core/goal-verifier.d.ts +0 -1
- package/dist/core/goal-verifier.js.map +1 -1
- package/dist/core/goal-worker.d.ts +0 -1
- package/dist/core/goal-worker.js.map +1 -1
- package/dist/core/hashline-edit-benchmark.d.ts +0 -1
- package/dist/core/hashline.d.ts +0 -1
- package/dist/core/ideal-review-subagent.d.ts +42 -0
- package/dist/core/ideal-review-subagent.js +95 -0
- package/dist/core/ideal-review-subagent.js.map +1 -0
- package/dist/core/ideal-review.d.ts +0 -1
- package/dist/core/ideal-review.js +18 -5
- package/dist/core/ideal-review.js.map +1 -1
- package/dist/core/index.d.ts +0 -1
- package/dist/core/internal-diagnostics.d.ts +142 -0
- package/dist/core/internal-diagnostics.js +450 -0
- package/dist/core/internal-diagnostics.js.map +1 -0
- package/dist/core/language-detector.d.ts +0 -1
- package/dist/core/local-endpoint-store.d.ts +0 -1
- package/dist/core/logger.d.ts +0 -1
- package/dist/core/loop-breaker.d.ts +0 -1
- package/dist/core/lsp/client.d.ts +8 -6
- package/dist/core/lsp/client.js +68 -18
- package/dist/core/lsp/client.js.map +1 -1
- package/dist/core/lsp/edit-telemetry.d.ts +0 -1
- package/dist/core/lsp/format.d.ts +0 -1
- package/dist/core/lsp/jsonrpc.d.ts +0 -1
- package/dist/core/lsp/manager.d.ts +16 -2
- package/dist/core/lsp/manager.js +170 -9
- package/dist/core/lsp/manager.js.map +1 -1
- package/dist/core/lsp/pool.d.ts +0 -1
- package/dist/core/lsp/pool.js.map +1 -1
- package/dist/core/lsp/servers.d.ts +0 -1
- package/dist/core/lsp/test-support.d.ts +0 -1
- package/dist/core/mcp/catalog-cache.d.ts +0 -1
- package/dist/core/mcp/client.d.ts +0 -1
- package/dist/core/mcp/content.d.ts +0 -1
- package/dist/core/mcp/defaults.d.ts +0 -1
- package/dist/core/mcp/deferred-catalog.d.ts +0 -1
- package/dist/core/mcp/elicitation-bridge.d.ts +0 -1
- package/dist/core/mcp/index.d.ts +0 -1
- package/dist/core/mcp/loopback.d.ts +0 -1
- package/dist/core/mcp/oauth-provider.d.ts +0 -1
- package/dist/core/mcp/oauth-store.d.ts +0 -1
- package/dist/core/mcp/parse-add-command.d.ts +0 -1
- package/dist/core/mcp/resolve-stdio.d.ts +0 -1
- package/dist/core/mcp/shared-pool.d.ts +0 -1
- package/dist/core/mcp/store.d.ts +0 -1
- package/dist/core/mcp/types.d.ts +0 -1
- package/dist/core/message-images.d.ts +0 -1
- package/dist/core/model-registry.d.ts +0 -1
- package/dist/core/network-guard.d.ts +0 -1
- package/dist/core/nolan-context.d.ts +5 -1
- package/dist/core/nolan-context.js +9 -2
- package/dist/core/nolan-context.js.map +1 -1
- package/dist/core/nolan-model.d.ts +0 -1
- package/dist/core/nolan-prompt.d.ts +0 -1
- package/dist/core/nolan-prompt.js +32 -14
- package/dist/core/nolan-prompt.js.map +1 -1
- package/dist/core/oauth/anthropic.d.ts +0 -1
- package/dist/core/oauth/gemini.d.ts +0 -1
- package/dist/core/oauth/kimi.d.ts +0 -1
- package/dist/core/oauth/openai.d.ts +0 -1
- package/dist/core/oauth/pkce.d.ts +0 -1
- package/dist/core/oauth/types.d.ts +0 -1
- package/dist/core/oauth/xai.d.ts +0 -1
- package/dist/core/parked-requests.d.ts +0 -1
- package/dist/core/persistent-shell.d.ts +0 -1
- package/dist/core/persistent-shell.js +3 -1
- package/dist/core/persistent-shell.js.map +1 -1
- package/dist/core/pixel-fix-agent.d.ts +0 -1
- package/dist/core/pixel-fix.d.ts +0 -1
- package/dist/core/pixel.d.ts +0 -1
- package/dist/core/platform-clis.d.ts +0 -1
- package/dist/core/process-gate.d.ts +0 -1
- package/dist/core/process-manager.d.ts +7 -4
- package/dist/core/process-manager.js +23 -7
- package/dist/core/process-manager.js.map +1 -1
- package/dist/core/progress/engine.d.ts +0 -1
- package/dist/core/progress/git-xp.d.ts +0 -1
- package/dist/core/progress/ranks.d.ts +0 -1
- package/dist/core/progress/rebuild.d.ts +0 -1
- package/dist/core/progress/store.d.ts +0 -1
- package/dist/core/progress/types.d.ts +0 -1
- package/dist/core/project-discovery.d.ts +0 -1
- package/dist/core/prompt-commands.d.ts +0 -1
- package/dist/core/radio.d.ts +0 -1
- package/dist/core/regrounding.d.ts +0 -1
- package/dist/core/resolve-start.d.ts +0 -1
- package/dist/core/run-claim.d.ts +0 -1
- package/dist/core/run-lifecycle.d.ts +0 -1
- package/dist/core/runtime-mode.d.ts +0 -1
- package/dist/core/sandbox-domains.d.ts +0 -1
- package/dist/core/sandbox-feedback.d.ts +0 -1
- package/dist/core/sandbox.d.ts +0 -1
- package/dist/core/semantic-loop-check.d.ts +58 -0
- package/dist/core/semantic-loop-check.js +103 -0
- package/dist/core/semantic-loop-check.js.map +1 -0
- package/dist/core/semantic-search-benchmark.d.ts +0 -1
- package/dist/core/session-compaction.d.ts +0 -1
- package/dist/core/session-export.d.ts +0 -1
- package/dist/core/session-history.d.ts +0 -1
- package/dist/core/session-manager.d.ts +1 -2
- package/dist/core/session-preview.d.ts +0 -1
- package/dist/core/session-storage.d.ts +0 -1
- package/dist/core/settings-manager.d.ts +0 -1
- package/dist/core/setup-history.d.ts +0 -1
- package/dist/core/shell-path.d.ts +0 -1
- package/dist/core/shell.d.ts +0 -1
- package/dist/core/shell.js +6 -3
- package/dist/core/shell.js.map +1 -1
- package/dist/core/shutdown.d.ts +0 -1
- package/dist/core/skills.d.ts +0 -1
- package/dist/core/slash-commands.d.ts +3 -2
- package/dist/core/slash-commands.js +6 -4
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/source-maps.d.ts +0 -1
- package/dist/core/speed-benchmark.d.ts +0 -1
- package/dist/core/steering.d.ts +0 -1
- package/dist/core/steroids.d.ts +0 -1
- package/dist/core/style-packs/index.d.ts +0 -1
- package/dist/core/style-packs/packs.d.ts +0 -1
- package/dist/core/subagent-manager.d.ts +7 -2
- package/dist/core/subagent-manager.js +15 -5
- package/dist/core/subagent-manager.js.map +1 -1
- package/dist/core/subagent-policy.d.ts +0 -1
- package/dist/core/subagent-store.d.ts +0 -1
- package/dist/core/subagent-turn-record.d.ts +0 -1
- package/dist/core/task-store.d.ts +0 -1
- package/dist/core/telegram-config.d.ts +0 -1
- package/dist/core/telegram.d.ts +0 -1
- package/dist/core/thinking-level.d.ts +0 -1
- package/dist/core/verification-evidence.d.ts +11 -2
- package/dist/core/verification-evidence.js +96 -22
- package/dist/core/verification-evidence.js.map +1 -1
- package/dist/core/verification-gate.d.ts +75 -36
- package/dist/core/verification-gate.js +301 -37
- package/dist/core/verification-gate.js.map +1 -1
- package/dist/core/verification-snapshot.d.ts +7 -0
- package/dist/core/verification-snapshot.js +111 -0
- package/dist/core/verification-snapshot.js.map +1 -0
- package/dist/core/verify-commands.d.ts +0 -1
- package/dist/core/voice-transcriber.d.ts +0 -1
- package/dist/core/workspace-guard.d.ts +0 -1
- package/dist/hf-pull.d.ts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/interactive.d.ts +0 -1
- package/dist/modes/acp-mode.d.ts +0 -1
- package/dist/modes/agent-home-mode.d.ts +0 -1
- package/dist/modes/index.d.ts +0 -1
- package/dist/modes/json-mode.d.ts +0 -1
- package/dist/modes/print-mode.d.ts +0 -1
- package/dist/modes/rpc-mode.d.ts +0 -1
- package/dist/modes/serve-mode.d.ts +0 -1
- package/dist/modes/subagent-worker-mode.d.ts +0 -1
- package/dist/session.d.ts +0 -1
- package/dist/system-prompt.d.ts +0 -1
- package/dist/system-prompt.js +53 -124
- package/dist/system-prompt.js.map +1 -1
- package/dist/test-support/fake-home.d.ts +0 -1
- package/dist/tools/ask-user.d.ts +0 -1
- package/dist/tools/bash.d.ts +0 -1
- package/dist/tools/bash.js +9 -4
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/code-nav.d.ts +0 -1
- package/dist/tools/code-skeleton.d.ts +0 -1
- package/dist/tools/compress.d.ts +0 -1
- package/dist/tools/edit-diff.d.ts +19 -2
- package/dist/tools/edit-diff.js +16 -3
- package/dist/tools/edit-diff.js.map +1 -1
- package/dist/tools/edit.d.ts +1 -2
- package/dist/tools/edit.js +36 -12
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/enter-plan.d.ts +0 -1
- package/dist/tools/exit-plan.d.ts +0 -1
- package/dist/tools/find.d.ts +0 -1
- package/dist/tools/generate-image.d.ts +5 -1
- package/dist/tools/generate-image.js +25 -7
- package/dist/tools/generate-image.js.map +1 -1
- package/dist/tools/goals.d.ts +0 -1
- package/dist/tools/grep.d.ts +0 -1
- package/dist/tools/html-extract.d.ts +0 -1
- package/dist/tools/index.d.ts +3 -2
- package/dist/tools/index.js +3 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/ls.d.ts +0 -1
- package/dist/tools/operations.d.ts +0 -1
- package/dist/tools/overflow.d.ts +0 -1
- package/dist/tools/path-utils.d.ts +0 -1
- package/dist/tools/pdf-extract.d.ts +0 -1
- package/dist/tools/prompt-hints.d.ts +0 -1
- package/dist/tools/prompt-hints.js +1 -1
- package/dist/tools/prompt-hints.js.map +1 -1
- package/dist/tools/read-only-bash.d.ts +0 -1
- package/dist/tools/read-tracker.d.ts +0 -1
- package/dist/tools/read.d.ts +0 -1
- package/dist/tools/safe-env.d.ts +0 -1
- package/dist/tools/screenshot.d.ts +0 -1
- package/dist/tools/search-code.d.ts +0 -1
- package/dist/tools/session-stats.d.ts +26 -0
- package/dist/tools/session-stats.js +51 -0
- package/dist/tools/session-stats.js.map +1 -0
- package/dist/tools/skill.d.ts +0 -1
- package/dist/tools/skill.js +3 -5
- package/dist/tools/skill.js.map +1 -1
- package/dist/tools/source-path.d.ts +0 -1
- package/dist/tools/steroids.d.ts +0 -1
- package/dist/tools/steroids.js +1 -1
- package/dist/tools/subagent-control.d.ts +0 -1
- package/dist/tools/subagent-shared.d.ts +0 -1
- package/dist/tools/subagent.d.ts +0 -1
- package/dist/tools/task-output.d.ts +0 -1
- package/dist/tools/task-output.js +13 -6
- package/dist/tools/task-output.js.map +1 -1
- package/dist/tools/task-send.d.ts +0 -1
- package/dist/tools/task-stop.d.ts +0 -1
- package/dist/tools/tasks.d.ts +0 -1
- package/dist/tools/tool-search.d.ts +0 -1
- package/dist/tools/tool-tiers.d.ts +0 -1
- package/dist/tools/truncate.d.ts +0 -1
- package/dist/tools/web-fetch.d.ts +0 -1
- package/dist/tools/web-search.d.ts +0 -1
- package/dist/tools/write.d.ts +0 -1
- package/dist/types.d.ts +0 -1
- package/dist/ui/App.d.ts +0 -1
- package/dist/ui/App.js +6 -1
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/activity-phrases.d.ts +0 -1
- package/dist/ui/app-items.d.ts +0 -1
- package/dist/ui/components/ActivityIndicator.d.ts +0 -1
- package/dist/ui/components/AnimationContext.d.ts +0 -1
- package/dist/ui/components/AssistantMessage.d.ts +0 -1
- package/dist/ui/components/BackgroundTasksBar.d.ts +0 -1
- package/dist/ui/components/Banner.d.ts +0 -1
- package/dist/ui/components/ChatFooterPane.d.ts +0 -1
- package/dist/ui/components/ChatInputStack.d.ts +0 -1
- package/dist/ui/components/ChatLayout.d.ts +0 -1
- package/dist/ui/components/ChatLivePane.d.ts +0 -1
- package/dist/ui/components/ChatScreen.d.ts +0 -1
- package/dist/ui/components/ChatStatusRow.d.ts +0 -1
- package/dist/ui/components/CompactionNotice.d.ts +0 -1
- package/dist/ui/components/DiffFrame.d.ts +0 -1
- package/dist/ui/components/DiffView.d.ts +0 -1
- package/dist/ui/components/Footer.d.ts +0 -1
- package/dist/ui/components/FooterStatusRow.d.ts +0 -1
- package/dist/ui/components/FullScreenOverlayRouter.d.ts +0 -1
- package/dist/ui/components/GoalOverlay.d.ts +0 -1
- package/dist/ui/components/GoalStatusBar.d.ts +0 -1
- package/dist/ui/components/IdealHookMessage.d.ts +0 -1
- package/dist/ui/components/InputArea.d.ts +0 -1
- package/dist/ui/components/LiveToolPanel.d.ts +0 -1
- package/dist/ui/components/Markdown.d.ts +0 -1
- package/dist/ui/components/MessageResponse.d.ts +0 -1
- package/dist/ui/components/ModelSelector.d.ts +0 -1
- package/dist/ui/components/NoSelect.d.ts +0 -1
- package/dist/ui/components/Overlay.d.ts +0 -1
- package/dist/ui/components/PixelOverlay.d.ts +0 -1
- package/dist/ui/components/PlanApproval.d.ts +0 -1
- package/dist/ui/components/PlanBanner.d.ts +0 -1
- package/dist/ui/components/PlanModeLogo.d.ts +0 -1
- package/dist/ui/components/PlanOverlay.d.ts +0 -1
- package/dist/ui/components/PlanProgress.d.ts +0 -1
- package/dist/ui/components/QueueIndicator.d.ts +0 -1
- package/dist/ui/components/Ratchet.d.ts +0 -1
- package/dist/ui/components/RewindOverlay.d.ts +0 -1
- package/dist/ui/components/SelectList.d.ts +0 -1
- package/dist/ui/components/ServerToolExecution.d.ts +0 -1
- package/dist/ui/components/SessionSelector.d.ts +0 -1
- package/dist/ui/components/SessionSummary.d.ts +0 -1
- package/dist/ui/components/SettingsSelector.d.ts +0 -1
- package/dist/ui/components/SkillsOverlay.d.ts +0 -1
- package/dist/ui/components/SlashCommandMenu.d.ts +0 -1
- package/dist/ui/components/SlashStyledSelectList.d.ts +0 -1
- package/dist/ui/components/Spinner.d.ts +0 -1
- package/dist/ui/components/StreamingArea.d.ts +0 -1
- package/dist/ui/components/SubAgentPanel.d.ts +0 -1
- package/dist/ui/components/TaskOverlay.d.ts +0 -1
- package/dist/ui/components/TaskPickerMenu.d.ts +0 -1
- package/dist/ui/components/ThemeSelector.d.ts +0 -1
- package/dist/ui/components/ThinkingBlock.d.ts +0 -1
- package/dist/ui/components/ToolExecution.d.ts +0 -1
- package/dist/ui/components/ToolGroupExecution.d.ts +0 -1
- package/dist/ui/components/ToolUseLoader.d.ts +0 -1
- package/dist/ui/components/TranscriptViewport.d.ts +0 -1
- package/dist/ui/components/UserMessage.d.ts +0 -1
- package/dist/ui/components/force-color.d.ts +0 -1
- package/dist/ui/components/index.d.ts +0 -1
- package/dist/ui/constants/figures.d.ts +0 -1
- package/dist/ui/duration-format.d.ts +0 -1
- package/dist/ui/duration-summary.d.ts +0 -1
- package/dist/ui/error-item.d.ts +0 -1
- package/dist/ui/goal-events.d.ts +0 -1
- package/dist/ui/goal-events.js.map +1 -1
- package/dist/ui/goal-summary.d.ts +0 -1
- package/dist/ui/hooks/useAgentLoop.d.ts +0 -1
- package/dist/ui/hooks/useBlink.d.ts +0 -1
- package/dist/ui/hooks/useChatLayoutMeasurements.d.ts +0 -1
- package/dist/ui/hooks/useContextCompaction.d.ts +0 -1
- package/dist/ui/hooks/useDoublePress.d.ts +0 -1
- package/dist/ui/hooks/useMinDisplayTime.d.ts +0 -1
- package/dist/ui/hooks/useModeState.d.ts +0 -1
- package/dist/ui/hooks/usePixelFixFlow.d.ts +0 -1
- package/dist/ui/hooks/useSessionManager.d.ts +0 -1
- package/dist/ui/hooks/useSessionPersistence.d.ts +0 -1
- package/dist/ui/hooks/useSlashCommands.d.ts +0 -1
- package/dist/ui/hooks/useTaskPickerController.d.ts +0 -1
- package/dist/ui/hooks/useTerminalSize.d.ts +0 -1
- package/dist/ui/hooks/useTerminalTitle.d.ts +0 -1
- package/dist/ui/hooks/useTranscriptHistory.d.ts +0 -1
- package/dist/ui/hooks/useTranscriptScroll.d.ts +0 -1
- package/dist/ui/item-helpers.d.ts +0 -1
- package/dist/ui/layout-decisions.d.ts +0 -1
- package/dist/ui/live-area-height.d.ts +0 -1
- package/dist/ui/live-item-flush.d.ts +0 -1
- package/dist/ui/login.d.ts +0 -1
- package/dist/ui/mcp.d.ts +0 -1
- package/dist/ui/pixel.d.ts +0 -1
- package/dist/ui/prompt-routing.d.ts +0 -1
- package/dist/ui/render.d.ts +0 -1
- package/dist/ui/session-summary.d.ts +0 -1
- package/dist/ui/sessions.d.ts +0 -1
- package/dist/ui/spinner-frames.d.ts +0 -1
- package/dist/ui/stores/create-store.d.ts +0 -1
- package/dist/ui/stores/index.d.ts +0 -1
- package/dist/ui/stores/taskbar-store.d.ts +0 -1
- package/dist/ui/stores/transcript-scroll-store.d.ts +0 -1
- package/dist/ui/submit-prompt-command.d.ts +0 -1
- package/dist/ui/submit-slash-commands.d.ts +0 -1
- package/dist/ui/terminal-history-format.d.ts +0 -1
- package/dist/ui/terminal-history-spacing.d.ts +0 -1
- package/dist/ui/terminal-history-status-renderers.d.ts +0 -1
- package/dist/ui/terminal-history.d.ts +0 -1
- package/dist/ui/testing/screen-recorder.d.ts +0 -1
- package/dist/ui/theme/detect-theme.d.ts +0 -1
- package/dist/ui/theme/theme.d.ts +0 -1
- package/dist/ui/theme/theme.js.map +1 -1
- package/dist/ui/thinking-level.d.ts +0 -1
- package/dist/ui/tool-group-summary.d.ts +0 -1
- package/dist/ui/tool-line-summary.d.ts +0 -1
- package/dist/ui/transcript/MiscRows.d.ts +0 -1
- package/dist/ui/transcript/StatusRow.d.ts +0 -1
- package/dist/ui/transcript/ToolRows.d.ts +0 -1
- package/dist/ui/transcript/TranscriptItemFrame.d.ts +0 -1
- package/dist/ui/transcript/TranscriptRenderer.d.ts +0 -1
- package/dist/ui/transcript/presentation.d.ts +0 -1
- package/dist/ui/transcript/spacing.d.ts +0 -1
- package/dist/ui/transcript/tool-presentation.d.ts +0 -1
- package/dist/ui/transcript/tool-presentation.js.map +1 -1
- package/dist/ui/transcript/transcript-lines.d.ts +0 -1
- package/dist/ui/utils/assistant-stream-split.d.ts +0 -1
- package/dist/ui/utils/highlight.d.ts +0 -1
- package/dist/ui/utils/hyperlink.d.ts +0 -1
- package/dist/ui/utils/latex-to-unicode.d.ts +0 -1
- package/dist/ui/utils/markdown-cache.d.ts +0 -1
- package/dist/ui/utils/markdown-renderer.d.ts +0 -1
- package/dist/ui/utils/markdown-table.d.ts +0 -1
- package/dist/ui/utils/signal.d.ts +0 -1
- package/dist/ui/utils/supports-hyperlinks.d.ts +0 -1
- package/dist/ui/utils/table-text.d.ts +0 -1
- package/dist/ui/utils/terminal-graphics.d.ts +0 -1
- package/dist/ui/utils/terminal-input.d.ts +0 -1
- package/dist/ui/utils/text-utils.d.ts +0 -1
- package/dist/ui/utils/token-to-ansi.d.ts +0 -1
- package/dist/ui/utils/user-message-display.d.ts +0 -1
- package/dist/ui/utils/word-diff.d.ts +0 -1
- package/dist/utils/error-handler.d.ts +0 -1
- package/dist/utils/format.d.ts +0 -1
- package/dist/utils/git.d.ts +0 -1
- package/dist/utils/github-ci.d.ts +18 -0
- package/dist/utils/github-ci.js +137 -0
- package/dist/utils/github-ci.js.map +1 -0
- package/dist/utils/github.d.ts +0 -1
- package/dist/utils/http-body.d.ts +0 -1
- package/dist/utils/image.d.ts +0 -1
- package/dist/utils/open-browser.d.ts +0 -1
- package/dist/utils/plan-steps.d.ts +0 -1
- package/dist/utils/plan-steps.js.map +1 -1
- package/dist/utils/process.d.ts +0 -1
- package/dist/utils/prompt-enhancer.d.ts +6 -3
- package/dist/utils/prompt-enhancer.js +61 -13
- package/dist/utils/prompt-enhancer.js.map +1 -1
- package/dist/utils/shell.d.ts +0 -1
- package/dist/utils/sound.d.ts +0 -1
- package/dist/utils/text.d.ts +0 -1
- package/package.json +8 -8
- package/dist/app-sidecar-sessions.d.ts.map +0 -1
- package/dist/app-sidecar.d.ts.map +0 -1
- package/dist/chat-agents/general.d.ts.map +0 -1
- package/dist/chat-agents/index.d.ts.map +0 -1
- package/dist/chat-agents/jiwa.d.ts.map +0 -1
- package/dist/chat-agents/memory.d.ts.map +0 -1
- package/dist/chat-agents/research.d.ts.map +0 -1
- package/dist/chat-agents/shared.d.ts.map +0 -1
- package/dist/chat-agents/therapist.d.ts.map +0 -1
- package/dist/chat-agents/types.d.ts.map +0 -1
- package/dist/cli/auth.d.ts.map +0 -1
- package/dist/cli/command-routing.d.ts.map +0 -1
- package/dist/cli/mcp.d.ts.map +0 -1
- package/dist/cli/pixel.d.ts.map +0 -1
- package/dist/cli/shared.d.ts.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/core/agent-notifications.d.ts.map +0 -1
- package/dist/core/agent-session.d.ts.map +0 -1
- package/dist/core/agents.d.ts.map +0 -1
- package/dist/core/api-benchmark.d.ts.map +0 -1
- package/dist/core/ask-user.d.ts.map +0 -1
- package/dist/core/auth/index.d.ts.map +0 -1
- package/dist/core/auth-providers.d.ts.map +0 -1
- package/dist/core/auth-storage.d.ts.map +0 -1
- package/dist/core/auto-update.d.ts.map +0 -1
- package/dist/core/autopilot-cycle.d.ts.map +0 -1
- package/dist/core/autopilot-gate.d.ts.map +0 -1
- package/dist/core/autopilot-verdict.d.ts.map +0 -1
- package/dist/core/bash-spawn-benchmark.d.ts.map +0 -1
- package/dist/core/bundled-agents.d.ts.map +0 -1
- package/dist/core/cache-warm-benchmark.d.ts.map +0 -1
- package/dist/core/checkpoint-store.d.ts.map +0 -1
- package/dist/core/claude-code-version.d.ts.map +0 -1
- package/dist/core/code-retrieval-chunkers.d.ts.map +0 -1
- package/dist/core/code-retrieval.d.ts.map +0 -1
- package/dist/core/compaction/active-context.d.ts.map +0 -1
- package/dist/core/compaction/compactor.d.ts.map +0 -1
- package/dist/core/compaction/policy.d.ts.map +0 -1
- package/dist/core/compaction/query-aware-selector.d.ts.map +0 -1
- package/dist/core/compaction/token-estimator.d.ts.map +0 -1
- package/dist/core/compaction/tool-result-pruner.d.ts.map +0 -1
- package/dist/core/context-limits.d.ts.map +0 -1
- package/dist/core/custom-commands.d.ts.map +0 -1
- package/dist/core/encode-cwd.d.ts.map +0 -1
- package/dist/core/env-delta.d.ts.map +0 -1
- package/dist/core/event-bus.d.ts.map +0 -1
- package/dist/core/extensions/loader.d.ts.map +0 -1
- package/dist/core/extensions/plugin-bundles.d.ts.map +0 -1
- package/dist/core/extensions/types.d.ts.map +0 -1
- package/dist/core/fast-apply-benchmark.d.ts.map +0 -1
- package/dist/core/file-lock.d.ts.map +0 -1
- package/dist/core/foreign-session-import.d.ts.map +0 -1
- package/dist/core/foreign-transcript-blocks.d.ts.map +0 -1
- package/dist/core/goal-controller.d.ts.map +0 -1
- package/dist/core/goal-prerequisites.d.ts.map +0 -1
- package/dist/core/goal-store.d.ts.map +0 -1
- package/dist/core/goal-verifier.d.ts.map +0 -1
- package/dist/core/goal-worker.d.ts.map +0 -1
- package/dist/core/hashline-edit-benchmark.d.ts.map +0 -1
- package/dist/core/hashline.d.ts.map +0 -1
- package/dist/core/ideal-review.d.ts.map +0 -1
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/language-detector.d.ts.map +0 -1
- package/dist/core/local-endpoint-store.d.ts.map +0 -1
- package/dist/core/logger.d.ts.map +0 -1
- package/dist/core/loop-breaker.d.ts.map +0 -1
- package/dist/core/lsp/client.d.ts.map +0 -1
- package/dist/core/lsp/edit-telemetry.d.ts.map +0 -1
- package/dist/core/lsp/format.d.ts.map +0 -1
- package/dist/core/lsp/jsonrpc.d.ts.map +0 -1
- package/dist/core/lsp/manager.d.ts.map +0 -1
- package/dist/core/lsp/pool.d.ts.map +0 -1
- package/dist/core/lsp/servers.d.ts.map +0 -1
- package/dist/core/lsp/test-support.d.ts.map +0 -1
- package/dist/core/mcp/catalog-cache.d.ts.map +0 -1
- package/dist/core/mcp/client.d.ts.map +0 -1
- package/dist/core/mcp/content.d.ts.map +0 -1
- package/dist/core/mcp/defaults.d.ts.map +0 -1
- package/dist/core/mcp/deferred-catalog.d.ts.map +0 -1
- package/dist/core/mcp/elicitation-bridge.d.ts.map +0 -1
- package/dist/core/mcp/index.d.ts.map +0 -1
- package/dist/core/mcp/loopback.d.ts.map +0 -1
- package/dist/core/mcp/oauth-provider.d.ts.map +0 -1
- package/dist/core/mcp/oauth-store.d.ts.map +0 -1
- package/dist/core/mcp/parse-add-command.d.ts.map +0 -1
- package/dist/core/mcp/resolve-stdio.d.ts.map +0 -1
- package/dist/core/mcp/shared-pool.d.ts.map +0 -1
- package/dist/core/mcp/store.d.ts.map +0 -1
- package/dist/core/mcp/types.d.ts.map +0 -1
- package/dist/core/message-images.d.ts.map +0 -1
- package/dist/core/model-registry.d.ts.map +0 -1
- package/dist/core/network-guard.d.ts.map +0 -1
- package/dist/core/nolan-context.d.ts.map +0 -1
- package/dist/core/nolan-model.d.ts.map +0 -1
- package/dist/core/nolan-prompt.d.ts.map +0 -1
- package/dist/core/oauth/anthropic.d.ts.map +0 -1
- package/dist/core/oauth/gemini.d.ts.map +0 -1
- package/dist/core/oauth/kimi.d.ts.map +0 -1
- package/dist/core/oauth/openai.d.ts.map +0 -1
- package/dist/core/oauth/pkce.d.ts.map +0 -1
- package/dist/core/oauth/types.d.ts.map +0 -1
- package/dist/core/oauth/xai.d.ts.map +0 -1
- package/dist/core/parked-requests.d.ts.map +0 -1
- package/dist/core/persistent-shell.d.ts.map +0 -1
- package/dist/core/pixel-fix-agent.d.ts.map +0 -1
- package/dist/core/pixel-fix.d.ts.map +0 -1
- package/dist/core/pixel.d.ts.map +0 -1
- package/dist/core/platform-clis.d.ts.map +0 -1
- package/dist/core/process-gate.d.ts.map +0 -1
- package/dist/core/process-manager.d.ts.map +0 -1
- package/dist/core/progress/engine.d.ts.map +0 -1
- package/dist/core/progress/git-xp.d.ts.map +0 -1
- package/dist/core/progress/ranks.d.ts.map +0 -1
- package/dist/core/progress/rebuild.d.ts.map +0 -1
- package/dist/core/progress/store.d.ts.map +0 -1
- package/dist/core/progress/types.d.ts.map +0 -1
- package/dist/core/project-discovery.d.ts.map +0 -1
- package/dist/core/prompt-commands.d.ts.map +0 -1
- package/dist/core/radio.d.ts.map +0 -1
- package/dist/core/regrounding.d.ts.map +0 -1
- package/dist/core/resolve-start.d.ts.map +0 -1
- package/dist/core/run-claim.d.ts.map +0 -1
- package/dist/core/run-lifecycle.d.ts.map +0 -1
- package/dist/core/runtime-mode.d.ts.map +0 -1
- package/dist/core/sandbox-domains.d.ts.map +0 -1
- package/dist/core/sandbox-feedback.d.ts.map +0 -1
- package/dist/core/sandbox.d.ts.map +0 -1
- package/dist/core/semantic-search-benchmark.d.ts.map +0 -1
- package/dist/core/session-compaction.d.ts.map +0 -1
- package/dist/core/session-export.d.ts.map +0 -1
- package/dist/core/session-history.d.ts.map +0 -1
- package/dist/core/session-manager.d.ts.map +0 -1
- package/dist/core/session-preview.d.ts.map +0 -1
- package/dist/core/session-storage.d.ts.map +0 -1
- package/dist/core/settings-manager.d.ts.map +0 -1
- package/dist/core/setup-history.d.ts.map +0 -1
- package/dist/core/shell-path.d.ts.map +0 -1
- package/dist/core/shell.d.ts.map +0 -1
- package/dist/core/shutdown.d.ts.map +0 -1
- package/dist/core/skills.d.ts.map +0 -1
- package/dist/core/slash-commands.d.ts.map +0 -1
- package/dist/core/source-maps.d.ts.map +0 -1
- package/dist/core/speed-benchmark.d.ts.map +0 -1
- package/dist/core/steering.d.ts.map +0 -1
- package/dist/core/steroids.d.ts.map +0 -1
- package/dist/core/style-packs/index.d.ts.map +0 -1
- package/dist/core/style-packs/packs.d.ts.map +0 -1
- package/dist/core/subagent-manager.d.ts.map +0 -1
- package/dist/core/subagent-policy.d.ts.map +0 -1
- package/dist/core/subagent-store.d.ts.map +0 -1
- package/dist/core/subagent-turn-record.d.ts.map +0 -1
- package/dist/core/task-store.d.ts.map +0 -1
- package/dist/core/telegram-config.d.ts.map +0 -1
- package/dist/core/telegram.d.ts.map +0 -1
- package/dist/core/thinking-level.d.ts.map +0 -1
- package/dist/core/verification-evidence.d.ts.map +0 -1
- package/dist/core/verification-gate.d.ts.map +0 -1
- package/dist/core/verify-commands.d.ts.map +0 -1
- package/dist/core/voice-transcriber.d.ts.map +0 -1
- package/dist/core/workspace-guard.d.ts.map +0 -1
- package/dist/hf-pull.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/interactive.d.ts.map +0 -1
- package/dist/modes/acp-mode.d.ts.map +0 -1
- package/dist/modes/agent-home-mode.d.ts.map +0 -1
- package/dist/modes/index.d.ts.map +0 -1
- package/dist/modes/json-mode.d.ts.map +0 -1
- package/dist/modes/print-mode.d.ts.map +0 -1
- package/dist/modes/rpc-mode.d.ts.map +0 -1
- package/dist/modes/serve-mode.d.ts.map +0 -1
- package/dist/modes/subagent-worker-mode.d.ts.map +0 -1
- package/dist/session.d.ts.map +0 -1
- package/dist/system-prompt.d.ts.map +0 -1
- package/dist/test-support/fake-home.d.ts.map +0 -1
- package/dist/tools/ask-user.d.ts.map +0 -1
- package/dist/tools/bash.d.ts.map +0 -1
- package/dist/tools/code-nav.d.ts.map +0 -1
- package/dist/tools/code-skeleton.d.ts.map +0 -1
- package/dist/tools/compress.d.ts.map +0 -1
- package/dist/tools/edit-diff.d.ts.map +0 -1
- package/dist/tools/edit.d.ts.map +0 -1
- package/dist/tools/enter-plan.d.ts.map +0 -1
- package/dist/tools/exit-plan.d.ts.map +0 -1
- package/dist/tools/find.d.ts.map +0 -1
- package/dist/tools/generate-image.d.ts.map +0 -1
- package/dist/tools/goals.d.ts.map +0 -1
- package/dist/tools/grep.d.ts.map +0 -1
- package/dist/tools/html-extract.d.ts.map +0 -1
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/ls.d.ts.map +0 -1
- package/dist/tools/operations.d.ts.map +0 -1
- package/dist/tools/overflow.d.ts.map +0 -1
- package/dist/tools/path-utils.d.ts.map +0 -1
- package/dist/tools/pdf-extract.d.ts.map +0 -1
- package/dist/tools/prompt-hints.d.ts.map +0 -1
- package/dist/tools/read-only-bash.d.ts.map +0 -1
- package/dist/tools/read-tracker.d.ts.map +0 -1
- package/dist/tools/read.d.ts.map +0 -1
- package/dist/tools/safe-env.d.ts.map +0 -1
- package/dist/tools/screenshot.d.ts.map +0 -1
- package/dist/tools/search-code.d.ts.map +0 -1
- package/dist/tools/skill.d.ts.map +0 -1
- package/dist/tools/source-path.d.ts.map +0 -1
- package/dist/tools/steroids.d.ts.map +0 -1
- package/dist/tools/subagent-control.d.ts.map +0 -1
- package/dist/tools/subagent-shared.d.ts.map +0 -1
- package/dist/tools/subagent.d.ts.map +0 -1
- package/dist/tools/task-output.d.ts.map +0 -1
- package/dist/tools/task-send.d.ts.map +0 -1
- package/dist/tools/task-stop.d.ts.map +0 -1
- package/dist/tools/tasks.d.ts.map +0 -1
- package/dist/tools/tool-search.d.ts.map +0 -1
- package/dist/tools/tool-tiers.d.ts.map +0 -1
- package/dist/tools/truncate.d.ts.map +0 -1
- package/dist/tools/web-fetch.d.ts.map +0 -1
- package/dist/tools/web-search.d.ts.map +0 -1
- package/dist/tools/write.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/ui/App.d.ts.map +0 -1
- package/dist/ui/activity-phrases.d.ts.map +0 -1
- package/dist/ui/app-items.d.ts.map +0 -1
- package/dist/ui/components/ActivityIndicator.d.ts.map +0 -1
- package/dist/ui/components/AnimationContext.d.ts.map +0 -1
- package/dist/ui/components/AssistantMessage.d.ts.map +0 -1
- package/dist/ui/components/BackgroundTasksBar.d.ts.map +0 -1
- package/dist/ui/components/Banner.d.ts.map +0 -1
- package/dist/ui/components/ChatFooterPane.d.ts.map +0 -1
- package/dist/ui/components/ChatInputStack.d.ts.map +0 -1
- package/dist/ui/components/ChatLayout.d.ts.map +0 -1
- package/dist/ui/components/ChatLivePane.d.ts.map +0 -1
- package/dist/ui/components/ChatScreen.d.ts.map +0 -1
- package/dist/ui/components/ChatStatusRow.d.ts.map +0 -1
- package/dist/ui/components/CompactionNotice.d.ts.map +0 -1
- package/dist/ui/components/DiffFrame.d.ts.map +0 -1
- package/dist/ui/components/DiffView.d.ts.map +0 -1
- package/dist/ui/components/Footer.d.ts.map +0 -1
- package/dist/ui/components/FooterStatusRow.d.ts.map +0 -1
- package/dist/ui/components/FullScreenOverlayRouter.d.ts.map +0 -1
- package/dist/ui/components/GoalOverlay.d.ts.map +0 -1
- package/dist/ui/components/GoalStatusBar.d.ts.map +0 -1
- package/dist/ui/components/IdealHookMessage.d.ts.map +0 -1
- package/dist/ui/components/InputArea.d.ts.map +0 -1
- package/dist/ui/components/LiveToolPanel.d.ts.map +0 -1
- package/dist/ui/components/Markdown.d.ts.map +0 -1
- package/dist/ui/components/MessageResponse.d.ts.map +0 -1
- package/dist/ui/components/ModelSelector.d.ts.map +0 -1
- package/dist/ui/components/NoSelect.d.ts.map +0 -1
- package/dist/ui/components/Overlay.d.ts.map +0 -1
- package/dist/ui/components/PixelOverlay.d.ts.map +0 -1
- package/dist/ui/components/PlanApproval.d.ts.map +0 -1
- package/dist/ui/components/PlanBanner.d.ts.map +0 -1
- package/dist/ui/components/PlanModeLogo.d.ts.map +0 -1
- package/dist/ui/components/PlanOverlay.d.ts.map +0 -1
- package/dist/ui/components/PlanProgress.d.ts.map +0 -1
- package/dist/ui/components/QueueIndicator.d.ts.map +0 -1
- package/dist/ui/components/Ratchet.d.ts.map +0 -1
- package/dist/ui/components/RewindOverlay.d.ts.map +0 -1
- package/dist/ui/components/SelectList.d.ts.map +0 -1
- package/dist/ui/components/ServerToolExecution.d.ts.map +0 -1
- package/dist/ui/components/SessionSelector.d.ts.map +0 -1
- package/dist/ui/components/SessionSummary.d.ts.map +0 -1
- package/dist/ui/components/SettingsSelector.d.ts.map +0 -1
- package/dist/ui/components/SkillsOverlay.d.ts.map +0 -1
- package/dist/ui/components/SlashCommandMenu.d.ts.map +0 -1
- package/dist/ui/components/SlashStyledSelectList.d.ts.map +0 -1
- package/dist/ui/components/Spinner.d.ts.map +0 -1
- package/dist/ui/components/StreamingArea.d.ts.map +0 -1
- package/dist/ui/components/SubAgentPanel.d.ts.map +0 -1
- package/dist/ui/components/TaskOverlay.d.ts.map +0 -1
- package/dist/ui/components/TaskPickerMenu.d.ts.map +0 -1
- package/dist/ui/components/ThemeSelector.d.ts.map +0 -1
- package/dist/ui/components/ThinkingBlock.d.ts.map +0 -1
- package/dist/ui/components/ToolExecution.d.ts.map +0 -1
- package/dist/ui/components/ToolGroupExecution.d.ts.map +0 -1
- package/dist/ui/components/ToolUseLoader.d.ts.map +0 -1
- package/dist/ui/components/TranscriptViewport.d.ts.map +0 -1
- package/dist/ui/components/UserMessage.d.ts.map +0 -1
- package/dist/ui/components/force-color.d.ts.map +0 -1
- package/dist/ui/components/index.d.ts.map +0 -1
- package/dist/ui/constants/figures.d.ts.map +0 -1
- package/dist/ui/duration-format.d.ts.map +0 -1
- package/dist/ui/duration-summary.d.ts.map +0 -1
- package/dist/ui/error-item.d.ts.map +0 -1
- package/dist/ui/goal-events.d.ts.map +0 -1
- package/dist/ui/goal-summary.d.ts.map +0 -1
- package/dist/ui/hooks/useAgentLoop.d.ts.map +0 -1
- package/dist/ui/hooks/useBlink.d.ts.map +0 -1
- package/dist/ui/hooks/useChatLayoutMeasurements.d.ts.map +0 -1
- package/dist/ui/hooks/useContextCompaction.d.ts.map +0 -1
- package/dist/ui/hooks/useDoublePress.d.ts.map +0 -1
- package/dist/ui/hooks/useMinDisplayTime.d.ts.map +0 -1
- package/dist/ui/hooks/useModeState.d.ts.map +0 -1
- package/dist/ui/hooks/usePixelFixFlow.d.ts.map +0 -1
- package/dist/ui/hooks/useSessionManager.d.ts.map +0 -1
- package/dist/ui/hooks/useSessionPersistence.d.ts.map +0 -1
- package/dist/ui/hooks/useSlashCommands.d.ts.map +0 -1
- package/dist/ui/hooks/useTaskPickerController.d.ts.map +0 -1
- package/dist/ui/hooks/useTerminalSize.d.ts.map +0 -1
- package/dist/ui/hooks/useTerminalTitle.d.ts.map +0 -1
- package/dist/ui/hooks/useTranscriptHistory.d.ts.map +0 -1
- package/dist/ui/hooks/useTranscriptScroll.d.ts.map +0 -1
- package/dist/ui/item-helpers.d.ts.map +0 -1
- package/dist/ui/layout-decisions.d.ts.map +0 -1
- package/dist/ui/live-area-height.d.ts.map +0 -1
- package/dist/ui/live-item-flush.d.ts.map +0 -1
- package/dist/ui/login.d.ts.map +0 -1
- package/dist/ui/mcp.d.ts.map +0 -1
- package/dist/ui/pixel.d.ts.map +0 -1
- package/dist/ui/prompt-routing.d.ts.map +0 -1
- package/dist/ui/render.d.ts.map +0 -1
- package/dist/ui/session-summary.d.ts.map +0 -1
- package/dist/ui/sessions.d.ts.map +0 -1
- package/dist/ui/spinner-frames.d.ts.map +0 -1
- package/dist/ui/stores/create-store.d.ts.map +0 -1
- package/dist/ui/stores/index.d.ts.map +0 -1
- package/dist/ui/stores/taskbar-store.d.ts.map +0 -1
- package/dist/ui/stores/transcript-scroll-store.d.ts.map +0 -1
- package/dist/ui/submit-prompt-command.d.ts.map +0 -1
- package/dist/ui/submit-slash-commands.d.ts.map +0 -1
- package/dist/ui/terminal-history-format.d.ts.map +0 -1
- package/dist/ui/terminal-history-spacing.d.ts.map +0 -1
- package/dist/ui/terminal-history-status-renderers.d.ts.map +0 -1
- package/dist/ui/terminal-history.d.ts.map +0 -1
- package/dist/ui/testing/screen-recorder.d.ts.map +0 -1
- package/dist/ui/theme/detect-theme.d.ts.map +0 -1
- package/dist/ui/theme/theme.d.ts.map +0 -1
- package/dist/ui/thinking-level.d.ts.map +0 -1
- package/dist/ui/tool-group-summary.d.ts.map +0 -1
- package/dist/ui/tool-line-summary.d.ts.map +0 -1
- package/dist/ui/transcript/MiscRows.d.ts.map +0 -1
- package/dist/ui/transcript/StatusRow.d.ts.map +0 -1
- package/dist/ui/transcript/ToolRows.d.ts.map +0 -1
- package/dist/ui/transcript/TranscriptItemFrame.d.ts.map +0 -1
- package/dist/ui/transcript/TranscriptRenderer.d.ts.map +0 -1
- package/dist/ui/transcript/presentation.d.ts.map +0 -1
- package/dist/ui/transcript/spacing.d.ts.map +0 -1
- package/dist/ui/transcript/tool-presentation.d.ts.map +0 -1
- package/dist/ui/transcript/transcript-lines.d.ts.map +0 -1
- package/dist/ui/utils/assistant-stream-split.d.ts.map +0 -1
- package/dist/ui/utils/highlight.d.ts.map +0 -1
- package/dist/ui/utils/hyperlink.d.ts.map +0 -1
- package/dist/ui/utils/latex-to-unicode.d.ts.map +0 -1
- package/dist/ui/utils/markdown-cache.d.ts.map +0 -1
- package/dist/ui/utils/markdown-renderer.d.ts.map +0 -1
- package/dist/ui/utils/markdown-table.d.ts.map +0 -1
- package/dist/ui/utils/signal.d.ts.map +0 -1
- package/dist/ui/utils/supports-hyperlinks.d.ts.map +0 -1
- package/dist/ui/utils/table-text.d.ts.map +0 -1
- package/dist/ui/utils/terminal-graphics.d.ts.map +0 -1
- package/dist/ui/utils/terminal-input.d.ts.map +0 -1
- package/dist/ui/utils/text-utils.d.ts.map +0 -1
- package/dist/ui/utils/token-to-ansi.d.ts.map +0 -1
- package/dist/ui/utils/user-message-display.d.ts.map +0 -1
- package/dist/ui/utils/word-diff.d.ts.map +0 -1
- package/dist/utils/error-handler.d.ts.map +0 -1
- package/dist/utils/format.d.ts.map +0 -1
- package/dist/utils/git.d.ts.map +0 -1
- package/dist/utils/github.d.ts.map +0 -1
- package/dist/utils/http-body.d.ts.map +0 -1
- package/dist/utils/image.d.ts.map +0 -1
- package/dist/utils/open-browser.d.ts.map +0 -1
- package/dist/utils/plan-steps.d.ts.map +0 -1
- package/dist/utils/process.d.ts.map +0 -1
- package/dist/utils/prompt-enhancer.d.ts.map +0 -1
- package/dist/utils/shell.d.ts.map +0 -1
- package/dist/utils/sound.d.ts.map +0 -1
- package/dist/utils/text.d.ts.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { agentLoop, isAbortError, isUsageLimitError, } from "@prestyj/agent";
|
|
2
|
-
import { ProviderError, } from "@prestyj/ai";
|
|
2
|
+
import { ProviderError, stream, } from "@prestyj/ai";
|
|
3
3
|
import { EventBus } from "./event-bus.js";
|
|
4
4
|
import { SlashCommandRegistry, createBuiltinCommands, } from "./slash-commands.js";
|
|
5
5
|
import { PROMPT_COMMANDS, getPromptCommand } from "./prompt-commands.js";
|
|
@@ -22,7 +22,7 @@ import { buildSubAgentSystemPrompt, buildSystemPrompt, } from "../system-prompt.
|
|
|
22
22
|
import { createTools, createWebSearchTool, } from "../tools/index.js";
|
|
23
23
|
import { partitionToolsByTier } from "../tools/tool-tiers.js";
|
|
24
24
|
import { buildProcessCompletionFollowUp } from "./process-gate.js";
|
|
25
|
-
import { buildSubAgentCompletionFollowUp } from "./subagent-manager.js";
|
|
25
|
+
import { buildSubAgentCompletionFollowUp, } from "./subagent-manager.js";
|
|
26
26
|
import { applyAsyncSubagentPolicy } from "./subagent-policy.js";
|
|
27
27
|
import { z } from "zod";
|
|
28
28
|
import { MCPClientManager, getAllMcpServers } from "./mcp/index.js";
|
|
@@ -31,6 +31,8 @@ import { CONTEXT_LIMITS, resolveContextLimits } from "./context-limits.js";
|
|
|
31
31
|
import { McpCatalogCache } from "./mcp/catalog-cache.js";
|
|
32
32
|
import { describeDropped, importForeignSession, } from "./foreign-session-import.js";
|
|
33
33
|
import { createToolSearchTool } from "../tools/tool-search.js";
|
|
34
|
+
import { createSessionStatsTool } from "../tools/session-stats.js";
|
|
35
|
+
import { createDiagnoseCommand, isInternalDiagnosticsEnabled, SessionDiagnosticsRecorder, } from "./internal-diagnostics.js";
|
|
34
36
|
import { log } from "./logger.js";
|
|
35
37
|
import { setEstimatorModel, calibrateEstimatorFromUsage } from "./compaction/token-estimator.js";
|
|
36
38
|
import { calculateActiveContextTokens } from "./compaction/active-context.js";
|
|
@@ -42,10 +44,14 @@ import { detectProjectStack } from "./language-detector.js";
|
|
|
42
44
|
import { evaluateIdealReview, buildIdealReviewMessage, buildReviewCoverageEscalationMessage, buildReviewCoverageMessage, MAX_REVIEW_COVERAGE_INJECTIONS, withReviewCoverageRequirements, detectTestDrift, ReviewCoverageTracker, } from "./ideal-review.js";
|
|
43
45
|
import { evaluateLoopBreak, buildLoopBreakMessage, CycleDetector, ToolCallProgressTracker, detectTextRepetition, } from "./loop-breaker.js";
|
|
44
46
|
import { buildRegroundingMessage } from "./regrounding.js";
|
|
47
|
+
import { buildSemanticLoopJudgePrompt, buildSemanticLoopMessage, MAX_SEMANTIC_LOOP_CALLS, parseSemanticLoopVerdict, shouldRunSemanticLoopCheck, SEMANTIC_LOOP_JUDGE_TIMEOUT_MS, withJudgeTimeout, } from "./semantic-loop-check.js";
|
|
48
|
+
import { buildIndependentReviewMessage, buildReviewerTask, INDEPENDENT_REVIEW_SCORE_THRESHOLD, parseReviewerFindings, REVIEWER_TOOLS, REVIEWER_WAIT_MS, } from "./ideal-review-subagent.js";
|
|
45
49
|
import { buildEnvDeltaMessage } from "./env-delta.js";
|
|
46
50
|
import { wrapSteeringText, buildNotificationSteeringText, STEERING_PREFIX } from "./steering.js";
|
|
47
51
|
import { AgentNotificationQueue } from "./agent-notifications.js";
|
|
48
|
-
import { VerificationGate, extractAddedLines, isCheckOwnFile, isCodeFilePath, isVerificationCommand, } from "./verification-gate.js";
|
|
52
|
+
import { VerificationGate, extractAddedLines, isCheckOwnFile, isCodeFilePath, VERIFICATION_STATE_KIND, isVerificationCommand, } from "./verification-gate.js";
|
|
53
|
+
import { classifyVerificationCommand } from "./verification-evidence.js";
|
|
54
|
+
import { captureVerificationSnapshot } from "./verification-snapshot.js";
|
|
49
55
|
import { findUserSessionPrompt, getUserSessionPrompt } from "./session-preview.js";
|
|
50
56
|
import { normalizeMessageImages } from "./message-images.js";
|
|
51
57
|
import crypto from "node:crypto";
|
|
@@ -57,6 +63,14 @@ import path from "node:path";
|
|
|
57
63
|
* progressing — refuse to extend its turn budget.
|
|
58
64
|
*/
|
|
59
65
|
const TURN_EXTENSION_MAX_FAILURE_RATIO = 0.5;
|
|
66
|
+
/** Terminal subagent states — mirrors SubAgentManager's private isTerminal. */
|
|
67
|
+
function isTerminalSubAgentState(state) {
|
|
68
|
+
return (state === "completed" ||
|
|
69
|
+
state === "failed" ||
|
|
70
|
+
state === "interrupted" ||
|
|
71
|
+
state === "closed" ||
|
|
72
|
+
state === "reaped");
|
|
73
|
+
}
|
|
60
74
|
// ── Tool-result policy ─────────────────────────────────────
|
|
61
75
|
/** Resolve the per-result cap passed to the agent loop for the active transport. */
|
|
62
76
|
export function resolveSessionToolResultCharLimit(model, provider, accountId) {
|
|
@@ -113,6 +127,9 @@ export class AgentSession {
|
|
|
113
127
|
// transcript rows the live run showed.
|
|
114
128
|
appMarkers = [];
|
|
115
129
|
turnMetrics = [];
|
|
130
|
+
/** Internal-only (EZ_INTERNAL): live per-session cost/reliability recorder.
|
|
131
|
+
* Absent entirely in public builds — see core/internal-diagnostics.ts. */
|
|
132
|
+
diagnosticsRecorder;
|
|
116
133
|
tools = [];
|
|
117
134
|
/** Rebuilds the read tool for a new model (video byte cap is baked in at
|
|
118
135
|
* creation). Called from switchModel so video-capable models get the
|
|
@@ -140,6 +157,7 @@ export class AgentSession {
|
|
|
140
157
|
hookCyclicPattern = null;
|
|
141
158
|
hookFileEditCounts = new Map();
|
|
142
159
|
hookToolCalls = new Map();
|
|
160
|
+
backgroundVerification = new Map();
|
|
143
161
|
idealReviewPhase = "idle";
|
|
144
162
|
/** Runtime-only suppression while Nolan owns verification in autopilot mode. */
|
|
145
163
|
idealReviewSuppressed = false;
|
|
@@ -157,6 +175,14 @@ export class AgentSession {
|
|
|
157
175
|
/** 0 = none; 1 = first nudge sent; 2 = final stop-and-report injected. */
|
|
158
176
|
loopBreakInjected = 0;
|
|
159
177
|
regroundingInjected = false;
|
|
178
|
+
/** Recent tool-call digests for the semantic loop judge — bounded ring. */
|
|
179
|
+
hookRecentCalls = [];
|
|
180
|
+
/** LLM-judged loop detection state. `verdict` holds a LOOP verdict awaiting
|
|
181
|
+
* injection at the next steering poll; judge failures fail open (no
|
|
182
|
+
* injection) and still consume budget + cooldown. */
|
|
183
|
+
semanticLoop = { checksUsed: 0, lastCheckTurn: 0, pending: false, verdict: null, injected: false };
|
|
184
|
+
/** Independent Ideal reviewer spawned once per run (score-gated). */
|
|
185
|
+
independentReviewStarted = false;
|
|
160
186
|
/**
|
|
161
187
|
* The environment as the cached system prompt currently describes it.
|
|
162
188
|
* Re-recorded on every prompt build, so a rebuild (e.g. `/add-dir`) needs no
|
|
@@ -201,6 +227,7 @@ export class AgentSession {
|
|
|
201
227
|
notifications = new AgentNotificationQueue();
|
|
202
228
|
managerAbortSignal;
|
|
203
229
|
managerAbortHandler = () => {
|
|
230
|
+
this.lspManager?.clearPendingDiagnostics();
|
|
204
231
|
void this.subAgentManager?.interruptAll();
|
|
205
232
|
};
|
|
206
233
|
mcpManager;
|
|
@@ -355,6 +382,7 @@ export class AgentSession {
|
|
|
355
382
|
provider: this.provider,
|
|
356
383
|
model: this.model,
|
|
357
384
|
lspDiagnostics: this.settingsManager.get("lspDiagnostics"),
|
|
385
|
+
deferLspDiagnostics: true,
|
|
358
386
|
getWriteGuardSettings: () => ({
|
|
359
387
|
allowOutsideWorkspaceWrites: this.settingsManager.get("allowOutsideWorkspaceWrites"),
|
|
360
388
|
additionalRoots: this.additionalRoots,
|
|
@@ -409,6 +437,11 @@ export class AgentSession {
|
|
|
409
437
|
: {}),
|
|
410
438
|
});
|
|
411
439
|
const tools = [...builtInTools, ...(this.opts.additionalTools ?? [])];
|
|
440
|
+
// Internal-only tool, appended last so public sessions keep a
|
|
441
|
+
// byte-identical tool block (prefix-cache stability).
|
|
442
|
+
if (isInternalDiagnosticsEnabled()) {
|
|
443
|
+
tools.push(createSessionStatsTool(() => this.diagnosticsRecorder));
|
|
444
|
+
}
|
|
412
445
|
// Apply the optional tool allow-list (read-only advisory sessions). Filtering
|
|
413
446
|
// here means the excluded tools are never registered with the agent loop, so
|
|
414
447
|
// a hallucinated call can't mutate the repo — and buildSystemPrompt below is
|
|
@@ -508,6 +541,20 @@ export class AgentSession {
|
|
|
508
541
|
const builtins = createBuiltinCommands();
|
|
509
542
|
for (const cmd of builtins)
|
|
510
543
|
this.slashCommands.register(cmd);
|
|
544
|
+
// Internal-only diagnostics: recorder + /diagnose exist exclusively when
|
|
545
|
+
// the internal flag is on. Public sessions never see either, so the
|
|
546
|
+
// command list and prompt stay identical to a build without this code.
|
|
547
|
+
if (isInternalDiagnosticsEnabled()) {
|
|
548
|
+
this.diagnosticsRecorder = new SessionDiagnosticsRecorder({
|
|
549
|
+
// Lazy: the session id is assigned at first prompt, not init.
|
|
550
|
+
sessionId: () => this.sessionId,
|
|
551
|
+
cwd: this.cwd,
|
|
552
|
+
provider: this.provider,
|
|
553
|
+
model: this.model,
|
|
554
|
+
});
|
|
555
|
+
this.diagnosticsRecorder.attach(this.eventBus);
|
|
556
|
+
this.slashCommands.register(createDiagnoseCommand());
|
|
557
|
+
}
|
|
511
558
|
// Wire up /help to show all registered + prompt + custom commands.
|
|
512
559
|
const helpCmd = this.slashCommands.get("help");
|
|
513
560
|
if (helpCmd) {
|
|
@@ -971,6 +1018,7 @@ export class AgentSession {
|
|
|
971
1018
|
* is the verbatim user ask, pinned for post-compaction re-grounding.
|
|
972
1019
|
*/
|
|
973
1020
|
resetHookState(originalRequest) {
|
|
1021
|
+
this.lspManager?.clearPendingDiagnostics();
|
|
974
1022
|
this.hookStats = {
|
|
975
1023
|
changedLines: 0,
|
|
976
1024
|
toolCalls: 0,
|
|
@@ -997,9 +1045,23 @@ export class AgentSession {
|
|
|
997
1045
|
this.idealDriftProbe = null;
|
|
998
1046
|
this.loopBreakInjected = 0;
|
|
999
1047
|
this.regroundingInjected = false;
|
|
1048
|
+
this.hookRecentCalls = [];
|
|
1049
|
+
this.semanticLoop = {
|
|
1050
|
+
checksUsed: 0,
|
|
1051
|
+
lastCheckTurn: 0,
|
|
1052
|
+
pending: false,
|
|
1053
|
+
verdict: null,
|
|
1054
|
+
injected: false,
|
|
1055
|
+
};
|
|
1056
|
+
this.independentReviewStarted = false;
|
|
1000
1057
|
this.runStartedAt = Date.now();
|
|
1001
1058
|
this.processGateInjected = 0;
|
|
1002
|
-
this.verificationGate.
|
|
1059
|
+
this.verificationGate.beginRun();
|
|
1060
|
+
const processes = new Set(this.processManager?.list().map((p) => p.id) ?? []);
|
|
1061
|
+
for (const id of this.backgroundVerification.keys()) {
|
|
1062
|
+
if (!processes.has(id))
|
|
1063
|
+
this.backgroundVerification.delete(id);
|
|
1064
|
+
}
|
|
1003
1065
|
this.compactionOccurred = false;
|
|
1004
1066
|
this.originalRequest = originalRequest;
|
|
1005
1067
|
}
|
|
@@ -1014,7 +1076,35 @@ export class AgentSession {
|
|
|
1014
1076
|
this.hookText += event.text;
|
|
1015
1077
|
break;
|
|
1016
1078
|
case "tool_call_start":
|
|
1017
|
-
this.hookToolCalls.set(event.toolCallId, {
|
|
1079
|
+
this.hookToolCalls.set(event.toolCallId, {
|
|
1080
|
+
name: event.name,
|
|
1081
|
+
args: event.args ?? {},
|
|
1082
|
+
revision: this.verificationGate.revision,
|
|
1083
|
+
});
|
|
1084
|
+
if (event.name === "bash" &&
|
|
1085
|
+
typeof event.args?.command === "string" &&
|
|
1086
|
+
(isVerificationCommand(event.args.command) ||
|
|
1087
|
+
classifyVerificationCommand(event.args.command).accepted)) {
|
|
1088
|
+
// A check that can rewrite files (--fix, build scripts, emitters)
|
|
1089
|
+
// invalidates earlier in-flight evidence AND marks the run as
|
|
1090
|
+
// touched. A check that is merely UNRECOGNIZED (`make test`, `deno
|
|
1091
|
+
// test`) rewrites nothing we can point to: bumping the revision for
|
|
1092
|
+
// it poisoned the gate on green output and re-armed the hook into
|
|
1093
|
+
// every later question turn.
|
|
1094
|
+
const classification = classifyVerificationCommand(event.args.command);
|
|
1095
|
+
if (classification.snapshotEligible && event.args.persist !== true) {
|
|
1096
|
+
const call = this.hookToolCalls.get(event.toolCallId);
|
|
1097
|
+
call.sourceSnapshot = await captureVerificationSnapshot(this.opts.cwd, [
|
|
1098
|
+
...this.hookFileEditCounts.keys(),
|
|
1099
|
+
]);
|
|
1100
|
+
if (call.sourceSnapshot === null)
|
|
1101
|
+
this.verificationGate.requireFreshVerification(true, event.args.command);
|
|
1102
|
+
}
|
|
1103
|
+
else {
|
|
1104
|
+
this.verificationGate.requireFreshVerification(!classification.accepted && classification.mayMutate, event.args.command);
|
|
1105
|
+
}
|
|
1106
|
+
await this.persistVerificationState();
|
|
1107
|
+
}
|
|
1018
1108
|
break;
|
|
1019
1109
|
case "tool_call_end": {
|
|
1020
1110
|
const call = this.hookToolCalls.get(event.toolCallId);
|
|
@@ -1032,14 +1122,28 @@ export class AgentSession {
|
|
|
1032
1122
|
this.hookConsecutiveFailures = event.isError ? this.hookConsecutiveFailures + 1 : 0;
|
|
1033
1123
|
this.hookRepeatedNoProgressCalls = this.hookProgressTracker.record(name, args, event.result, event.isError);
|
|
1034
1124
|
this.hookCyclicPattern = this.hookCycleDetector.record(name, args, event.result, event.isError);
|
|
1125
|
+
// Semantic-loop judge input: a bounded digest of WHAT was attempted and
|
|
1126
|
+
// HOW it came out. Args/results are sliced AT RECORD TIME — a write with
|
|
1127
|
+
// a 50 KiB payload or a bash dump must never inflate the ring, and the
|
|
1128
|
+
// judge needs shapes, not payloads.
|
|
1129
|
+
this.hookRecentCalls.push({
|
|
1130
|
+
tool: name,
|
|
1131
|
+
args: args === undefined ? "" : JSON.stringify(args).slice(0, 300),
|
|
1132
|
+
ok: !event.isError,
|
|
1133
|
+
result: event.result.slice(0, 400),
|
|
1134
|
+
});
|
|
1135
|
+
if (this.hookRecentCalls.length > MAX_SEMANTIC_LOOP_CALLS) {
|
|
1136
|
+
this.hookRecentCalls.splice(0, this.hookRecentCalls.length - MAX_SEMANTIC_LOOP_CALLS);
|
|
1137
|
+
}
|
|
1035
1138
|
if (name === "edit" && !event.isError) {
|
|
1036
1139
|
const diff = event.details?.diff ?? event.result;
|
|
1037
1140
|
const added = (diff.match(/^\+[^+]/gm) ?? []).length;
|
|
1038
1141
|
const removed = (diff.match(/^-[^-]/gm) ?? []).length;
|
|
1039
1142
|
this.hookStats.changedLines += added + removed;
|
|
1040
1143
|
}
|
|
1041
|
-
//
|
|
1042
|
-
//
|
|
1144
|
+
// Only host-observed successful mutations and trustworthy check results
|
|
1145
|
+
// affect approval. The model's text is never evidence.
|
|
1146
|
+
let verificationChanged = false;
|
|
1043
1147
|
if (!event.isError && args) {
|
|
1044
1148
|
if (name === "edit" || name === "write") {
|
|
1045
1149
|
const filePath = String(args.file_path ?? "");
|
|
@@ -1051,26 +1155,62 @@ export class AgentSession {
|
|
|
1051
1155
|
? String(args.content ?? "")
|
|
1052
1156
|
: extractAddedLines(event.details?.diff ?? event.result);
|
|
1053
1157
|
this.verificationGate.recordMutation(filePath, addedText);
|
|
1158
|
+
verificationChanged = true;
|
|
1054
1159
|
}
|
|
1055
1160
|
}
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1161
|
+
}
|
|
1162
|
+
if (args && call && name === "bash") {
|
|
1163
|
+
const command = typeof args.command === "string" ? args.command : "";
|
|
1164
|
+
const classification = classifyVerificationCommand(command);
|
|
1165
|
+
if (classification.accepted || classification.snapshotEligible) {
|
|
1166
|
+
if (args.run_in_background === true && !event.isError && args.persist !== true) {
|
|
1167
|
+
const id = /^ID:\s*(\S+)/m.exec(event.result)?.[1];
|
|
1168
|
+
// No parseable ID means the check cannot be tracked to a real exit
|
|
1169
|
+
// code — no evidence either way. Recording a FAILURE here made
|
|
1170
|
+
// every later green run of a different spelling look owed.
|
|
1171
|
+
if (id)
|
|
1172
|
+
this.backgroundVerification.set(id, {
|
|
1173
|
+
revision: call.revision,
|
|
1174
|
+
command,
|
|
1175
|
+
...(classification.snapshotEligible
|
|
1176
|
+
? { sourceSnapshot: call.sourceSnapshot ?? null }
|
|
1177
|
+
: {}),
|
|
1178
|
+
});
|
|
1179
|
+
else if (classification.snapshotEligible)
|
|
1180
|
+
this.verificationGate.requireFreshVerification(true, command);
|
|
1071
1181
|
}
|
|
1182
|
+
else if (args.persist === true) {
|
|
1183
|
+
// Persistent-shell checks are not bounded evidence (steering can
|
|
1184
|
+
// interleave): neither a pass nor a failure. A recorded failure
|
|
1185
|
+
// here blocked approval for sessions that prefer the shell.
|
|
1186
|
+
}
|
|
1187
|
+
else if (classification.snapshotEligible) {
|
|
1188
|
+
await this.finishSnapshotVerification({ command, revision: call.revision, sourceSnapshot: call.sourceSnapshot ?? null }, !event.isError && /^Exit code:\s*0(?:\s|$)/i.test(event.result.trim()));
|
|
1189
|
+
verificationChanged = true;
|
|
1190
|
+
}
|
|
1191
|
+
else {
|
|
1192
|
+
if (!event.isError && /^Exit code:\s*0(?:\s|$)/i.test(event.result.trim())) {
|
|
1193
|
+
this.verificationGate.recordVerification(call.revision, command);
|
|
1194
|
+
}
|
|
1195
|
+
else {
|
|
1196
|
+
this.verificationGate.recordFailedVerification(command, call.revision);
|
|
1197
|
+
}
|
|
1198
|
+
verificationChanged = true;
|
|
1199
|
+
}
|
|
1200
|
+
delete call.sourceSnapshot;
|
|
1072
1201
|
}
|
|
1202
|
+
else if (classification.candidate) {
|
|
1203
|
+
// Green but untrusted: remember WHY so the demand can tell the
|
|
1204
|
+
// agent which command shape actually clears the gate.
|
|
1205
|
+
this.verificationGate.recordRejectedCheck(command, classification.reason);
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
if (!event.isError && args && name === "task_output" && typeof args.id === "string") {
|
|
1209
|
+
verificationChanged =
|
|
1210
|
+
(await this.recordFinishedBackgroundVerification(args.id)) || verificationChanged;
|
|
1073
1211
|
}
|
|
1212
|
+
if (verificationChanged)
|
|
1213
|
+
await this.persistVerificationState();
|
|
1074
1214
|
// Tool results are what push the run over the review gate, and they all
|
|
1075
1215
|
// land before the model writes its candidate final answer — so this is
|
|
1076
1216
|
// the point where arming still beats the draft's first token.
|
|
@@ -1158,11 +1298,18 @@ export class AgentSession {
|
|
|
1158
1298
|
// it in the very next turn instead of discovering it at the pre-stop
|
|
1159
1299
|
// completion gate — but it never displaces user steering, which rides out
|
|
1160
1300
|
// in the same batch when both are pending.
|
|
1301
|
+
const diagnosticText = this.lspManager?.drainDiagnostics(this.getVerificationProblem() !== null, { deferUnverified: true });
|
|
1302
|
+
if (diagnosticText)
|
|
1303
|
+
this.eventBus.emit("diagnostics", { text: diagnosticText });
|
|
1304
|
+
this.refreshVerificationArmed();
|
|
1161
1305
|
const notified = this.notifications.drain();
|
|
1162
|
-
const notificationMessage = notified.length > 0
|
|
1306
|
+
const notificationMessage = notified.length > 0 || diagnosticText
|
|
1163
1307
|
? {
|
|
1164
1308
|
role: "user",
|
|
1165
|
-
content: buildNotificationSteeringText(
|
|
1309
|
+
content: buildNotificationSteeringText([
|
|
1310
|
+
...notified.map((entry) => entry.text),
|
|
1311
|
+
...(diagnosticText ? [diagnosticText] : []),
|
|
1312
|
+
]),
|
|
1166
1313
|
provenance: { source: "runtime", kind: "notification", visibility: "hidden" },
|
|
1167
1314
|
}
|
|
1168
1315
|
: null;
|
|
@@ -1219,16 +1366,21 @@ export class AgentSession {
|
|
|
1219
1366
|
return null;
|
|
1220
1367
|
if (!this.settingsManager.get("idealReviewEnabled"))
|
|
1221
1368
|
return null;
|
|
1369
|
+
// Deterministic stuck verdict, computed once and shared: the semantic
|
|
1370
|
+
// judge must not spend tokens on a burst the deterministic breaker is
|
|
1371
|
+
// about to correct itself.
|
|
1372
|
+
const deterministicDecision = evaluateLoopBreak({
|
|
1373
|
+
consecutiveFailures: this.hookConsecutiveFailures,
|
|
1374
|
+
repeatedNoProgressCalls: this.hookRepeatedNoProgressCalls,
|
|
1375
|
+
textRepetitionDetected: detectTextRepetition(this.hookText),
|
|
1376
|
+
...(this.hookCyclicPattern ? { cyclicPattern: this.hookCyclicPattern } : {}),
|
|
1377
|
+
});
|
|
1378
|
+
this.maybeStartSemanticLoopCheck(deterministicDecision.shouldBreak);
|
|
1222
1379
|
// Two-stage loop-breaker: stage 1 nudges; a FRESH detection after that
|
|
1223
1380
|
// injects the harsher final stop-and-report prompt. Signals reset after
|
|
1224
1381
|
// each injection so stage 2 only fires on new evidence.
|
|
1225
1382
|
if (this.loopBreakInjected < 2) {
|
|
1226
|
-
const decision =
|
|
1227
|
-
consecutiveFailures: this.hookConsecutiveFailures,
|
|
1228
|
-
repeatedNoProgressCalls: this.hookRepeatedNoProgressCalls,
|
|
1229
|
-
textRepetitionDetected: detectTextRepetition(this.hookText),
|
|
1230
|
-
...(this.hookCyclicPattern ? { cyclicPattern: this.hookCyclicPattern } : {}),
|
|
1231
|
-
});
|
|
1383
|
+
const decision = deterministicDecision;
|
|
1232
1384
|
if (decision.shouldBreak) {
|
|
1233
1385
|
const stage = this.loopBreakInjected === 0 ? 1 : 2;
|
|
1234
1386
|
this.loopBreakInjected = stage;
|
|
@@ -1237,6 +1389,9 @@ export class AgentSession {
|
|
|
1237
1389
|
this.hookCyclicPattern = null;
|
|
1238
1390
|
this.hookConsecutiveFailures = 0;
|
|
1239
1391
|
this.hookRepeatedNoProgressCalls = 0;
|
|
1392
|
+
// The deterministic breaker owns this burst — a semantic verdict from
|
|
1393
|
+
// the same burst must not double-correct on the next poll.
|
|
1394
|
+
this.semanticLoop.verdict = null;
|
|
1240
1395
|
// Clear the text buffer too — otherwise a stage-1 text-repetition
|
|
1241
1396
|
// trigger still sees the same repeated tail on the next check and
|
|
1242
1397
|
// escalates to stage 2 on stale evidence.
|
|
@@ -1249,6 +1404,22 @@ export class AgentSession {
|
|
|
1249
1404
|
return [buildLoopBreakMessage(decision.reasons, stage === 2)];
|
|
1250
1405
|
}
|
|
1251
1406
|
}
|
|
1407
|
+
// Semantic loop-break: an LLM verdict (started by maybeStartSemanticLoopCheck
|
|
1408
|
+
// on a suspicious-but-syntactically-quiet burst) is consumed here, exactly
|
|
1409
|
+
// once, with the deterministic breaker getting priority above. Fail-open:
|
|
1410
|
+
// no verdict or no-loop verdict injects nothing.
|
|
1411
|
+
if (this.semanticLoop.verdict && !this.semanticLoop.injected) {
|
|
1412
|
+
const verdict = this.semanticLoop.verdict;
|
|
1413
|
+
this.semanticLoop.injected = true;
|
|
1414
|
+
this.semanticLoop.verdict = null;
|
|
1415
|
+
// The judged burst has been addressed; a fresh burst must re-accumulate.
|
|
1416
|
+
this.hookConsecutiveFailures = 0;
|
|
1417
|
+
log("INFO", "loop-break", "Injecting semantic loop-break steering", {
|
|
1418
|
+
reason: verdict.reason,
|
|
1419
|
+
});
|
|
1420
|
+
this.eventBus.emit("hook", { kind: "loop_break" });
|
|
1421
|
+
return [buildSemanticLoopMessage(verdict)];
|
|
1422
|
+
}
|
|
1252
1423
|
if (!this.regroundingInjected && this.compactionOccurred) {
|
|
1253
1424
|
this.regroundingInjected = true;
|
|
1254
1425
|
this.eventBus.emit("hook", { kind: "regrounding" });
|
|
@@ -1256,6 +1427,159 @@ export class AgentSession {
|
|
|
1256
1427
|
}
|
|
1257
1428
|
return null;
|
|
1258
1429
|
}
|
|
1430
|
+
/** Fire the semantic loop judge when deterministic evidence is suspicious but
|
|
1431
|
+
* the deterministic breaker stayed quiet — the syntactic blind spot where
|
|
1432
|
+
* every retry differs slightly and the run still makes no progress.
|
|
1433
|
+
* Fire-and-forget: the call runs while the next turn streams, and a finished
|
|
1434
|
+
* verdict is consumed by the NEXT steering poll — never blocking a turn. */
|
|
1435
|
+
maybeStartSemanticLoopCheck(deterministicBreak) {
|
|
1436
|
+
if (!shouldRunSemanticLoopCheck({
|
|
1437
|
+
consecutiveFailures: this.hookConsecutiveFailures,
|
|
1438
|
+
totalFailures: this.hookStats.toolFailures,
|
|
1439
|
+
turns: this.hookStats.turns,
|
|
1440
|
+
lastCheckTurn: this.semanticLoop.lastCheckTurn,
|
|
1441
|
+
checksUsed: this.semanticLoop.checksUsed,
|
|
1442
|
+
checkPending: this.semanticLoop.pending,
|
|
1443
|
+
deterministicBreak,
|
|
1444
|
+
})) {
|
|
1445
|
+
return;
|
|
1446
|
+
}
|
|
1447
|
+
// resetHookState replaces this object on every prompt. A late judge must
|
|
1448
|
+
// not publish a verdict or consume the next run's budget/cooldown.
|
|
1449
|
+
const runState = this.semanticLoop;
|
|
1450
|
+
runState.pending = true;
|
|
1451
|
+
log("INFO", "loop-break", "Starting semantic loop judge", {
|
|
1452
|
+
turn: String(this.hookStats.turns),
|
|
1453
|
+
consecutiveFailures: String(this.hookConsecutiveFailures),
|
|
1454
|
+
recentCalls: String(this.hookRecentCalls.length),
|
|
1455
|
+
});
|
|
1456
|
+
void (async () => {
|
|
1457
|
+
try {
|
|
1458
|
+
const prompt = buildSemanticLoopJudgePrompt(this.hookRecentCalls, this.originalRequest);
|
|
1459
|
+
const raw = await (this.opts.semanticLoopJudge?.(prompt) ??
|
|
1460
|
+
this.callSemanticLoopJudge(prompt));
|
|
1461
|
+
const verdict = parseSemanticLoopVerdict(raw);
|
|
1462
|
+
if (this.semanticLoop === runState && verdict?.loop)
|
|
1463
|
+
runState.verdict = verdict;
|
|
1464
|
+
}
|
|
1465
|
+
catch (error) {
|
|
1466
|
+
// Fail open: judge errors never stop a run. Budget and cooldown are
|
|
1467
|
+
// still consumed in `finally` so a flaky judge cannot retry-loop.
|
|
1468
|
+
log("WARN", "loop-break", "Semantic loop judge failed", {
|
|
1469
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1470
|
+
});
|
|
1471
|
+
}
|
|
1472
|
+
finally {
|
|
1473
|
+
if (this.semanticLoop === runState) {
|
|
1474
|
+
runState.pending = false;
|
|
1475
|
+
runState.checksUsed += 1;
|
|
1476
|
+
runState.lastCheckTurn = this.hookStats.turns;
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
})();
|
|
1480
|
+
}
|
|
1481
|
+
/** One-shot judge call on the session's ACTIVE model — deliberately not a
|
|
1482
|
+
* cheaper routing: judging a model's own failure patterns with a weaker
|
|
1483
|
+
* model swaps false negatives for false positives. */
|
|
1484
|
+
async callSemanticLoopJudge(prompt) {
|
|
1485
|
+
const creds = await this.authStorage.resolveCredentials(this.provider, {
|
|
1486
|
+
storageKeys: this.currentAuthStorageKeys(),
|
|
1487
|
+
});
|
|
1488
|
+
const result = stream({
|
|
1489
|
+
provider: this.provider,
|
|
1490
|
+
model: this.model,
|
|
1491
|
+
messages: [{ role: "user", content: prompt }],
|
|
1492
|
+
maxTokens: 500,
|
|
1493
|
+
apiKey: creds.accessToken,
|
|
1494
|
+
accountId: creds.accountId,
|
|
1495
|
+
projectId: creds.projectId,
|
|
1496
|
+
baseUrl: this.baseUrl ?? creds.baseUrl,
|
|
1497
|
+
signal: this.opts.signal,
|
|
1498
|
+
});
|
|
1499
|
+
const response = await withJudgeTimeout(result.response, SEMANTIC_LOOP_JUDGE_TIMEOUT_MS);
|
|
1500
|
+
// Providers differ in reply shape: some return a bare string, others an
|
|
1501
|
+
// array of parts (glm-5.3 among them) — joining text parts covers both,
|
|
1502
|
+
// where the string-only branch silently dropped the whole verdict.
|
|
1503
|
+
const content = response.message.content;
|
|
1504
|
+
if (typeof content === "string")
|
|
1505
|
+
return content;
|
|
1506
|
+
return Array.isArray(content)
|
|
1507
|
+
? content
|
|
1508
|
+
.filter((part) => part.type === "text")
|
|
1509
|
+
.map((part) => part.text)
|
|
1510
|
+
.join("\n")
|
|
1511
|
+
: "";
|
|
1512
|
+
}
|
|
1513
|
+
/** Independent fresh-context review of the finished work (Codex Guardian
|
|
1514
|
+
* pattern). Spawns a READ-ONLY child on the ACTIVE model, waits bounded,
|
|
1515
|
+
* and returns findings for the acting agent to address — or nothing when
|
|
1516
|
+
* the review passes, is unavailable, or fails (in-thread review remains the
|
|
1517
|
+
* fallback; the feature degrades, never blocks).
|
|
1518
|
+
*
|
|
1519
|
+
* Runs inside the pre-stop poll, so the candidate final answer is already
|
|
1520
|
+
* held by arming and this wait cannot race a streamed answer. */
|
|
1521
|
+
async runIndependentReview(decision) {
|
|
1522
|
+
if (!this.subAgentManager)
|
|
1523
|
+
return [];
|
|
1524
|
+
if (this.independentReviewStarted)
|
|
1525
|
+
return [];
|
|
1526
|
+
// An allow-listed session (a subagent worker itself) must not spawn
|
|
1527
|
+
// harness-owned grandchildren the tool policy never granted.
|
|
1528
|
+
if (this.opts.allowedTools && !this.opts.allowedTools.includes("spawn_agent"))
|
|
1529
|
+
return [];
|
|
1530
|
+
if (decision.score < INDEPENDENT_REVIEW_SCORE_THRESHOLD)
|
|
1531
|
+
return [];
|
|
1532
|
+
this.independentReviewStarted = true;
|
|
1533
|
+
const taskName = `ideal-reviewer-${Math.random().toString(36).slice(2, 8)}`;
|
|
1534
|
+
let agentId;
|
|
1535
|
+
try {
|
|
1536
|
+
const task = buildReviewerTask({
|
|
1537
|
+
originalRequest: this.originalRequest,
|
|
1538
|
+
changedFiles: [...this.hookFileEditCounts.keys()],
|
|
1539
|
+
stats: this.hookStats,
|
|
1540
|
+
triggerReasons: decision.reasons,
|
|
1541
|
+
});
|
|
1542
|
+
// Active model forced at spawn time — never routed to a fast/review model.
|
|
1543
|
+
const snapshot = await this.subAgentManager.spawn(taskName, task, undefined, {
|
|
1544
|
+
model: this.model,
|
|
1545
|
+
tools: REVIEWER_TOOLS,
|
|
1546
|
+
});
|
|
1547
|
+
agentId = snapshot.agent_id;
|
|
1548
|
+
const waited = await this.subAgentManager.wait([agentId], "all", REVIEWER_WAIT_MS);
|
|
1549
|
+
const agent = waited.agents[0];
|
|
1550
|
+
if (!agent || !isTerminalSubAgentState(agent.state)) {
|
|
1551
|
+
// Timeout: collect the straggler so the completion gate cannot fire on
|
|
1552
|
+
// it later, then fall back to the in-thread review.
|
|
1553
|
+
await this.subAgentManager.interrupt(agentId, true).catch(() => { });
|
|
1554
|
+
log("WARN", "ideal", "Independent reviewer timed out; falling back to in-thread review", {
|
|
1555
|
+
agentId,
|
|
1556
|
+
});
|
|
1557
|
+
return [];
|
|
1558
|
+
}
|
|
1559
|
+
const findings = parseReviewerFindings(agent.output ?? "");
|
|
1560
|
+
if (!findings) {
|
|
1561
|
+
log("WARN", "ideal", "Independent reviewer output unparseable; falling back", { agentId });
|
|
1562
|
+
return [];
|
|
1563
|
+
}
|
|
1564
|
+
if (findings.clean) {
|
|
1565
|
+
log("INFO", "ideal", "Independent reviewer verdict: clean", { agentId });
|
|
1566
|
+
return [];
|
|
1567
|
+
}
|
|
1568
|
+
log("INFO", "ideal", "Independent reviewer flagged findings", {
|
|
1569
|
+
agentId,
|
|
1570
|
+
count: String(findings.findings.length),
|
|
1571
|
+
});
|
|
1572
|
+
return [buildIndependentReviewMessage(findings.findings)];
|
|
1573
|
+
}
|
|
1574
|
+
catch (error) {
|
|
1575
|
+
if (agentId)
|
|
1576
|
+
await this.subAgentManager.interrupt(agentId, true).catch(() => { });
|
|
1577
|
+
log("WARN", "ideal", "Independent reviewer failed; falling back to in-thread review", {
|
|
1578
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1579
|
+
});
|
|
1580
|
+
return [];
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1259
1583
|
/**
|
|
1260
1584
|
* Turn-budget extension gate. The loop consults this instead of stopping
|
|
1261
1585
|
* mid-task when it exhausts `maxTurns`. Grant ONLY on evidence of progress —
|
|
@@ -1335,6 +1659,8 @@ export class AgentSession {
|
|
|
1335
1659
|
/** Would a stop right now inject the verification gate? Same conditions as
|
|
1336
1660
|
* the pre-stop branch below, so arming and injection cannot disagree. */
|
|
1337
1661
|
wouldInjectVerification() {
|
|
1662
|
+
if (this.lspManager?.hasQueuedDiagnostics())
|
|
1663
|
+
return true;
|
|
1338
1664
|
if (this.opts.selfCorrectionHooks === false)
|
|
1339
1665
|
return false;
|
|
1340
1666
|
if (!this.settingsManager.get("verificationGateEnabled"))
|
|
@@ -1356,6 +1682,11 @@ export class AgentSession {
|
|
|
1356
1682
|
if (!this.settingsManager)
|
|
1357
1683
|
return;
|
|
1358
1684
|
this.refreshIdealReviewArmed();
|
|
1685
|
+
this.refreshVerificationArmed();
|
|
1686
|
+
}
|
|
1687
|
+
refreshVerificationArmed() {
|
|
1688
|
+
if (!this.settingsManager)
|
|
1689
|
+
return;
|
|
1359
1690
|
const armed = this.wouldInjectVerification();
|
|
1360
1691
|
if (armed === this.verificationArmed)
|
|
1361
1692
|
return;
|
|
@@ -1373,10 +1704,37 @@ export class AgentSession {
|
|
|
1373
1704
|
* Pre-stop Ideal review phase machine. Once review starts, completion is
|
|
1374
1705
|
* blocked until harness-owned post-injection reads cover every changed file.
|
|
1375
1706
|
*/
|
|
1376
|
-
getHookFollowUpMessages() {
|
|
1707
|
+
async getHookFollowUpMessages() {
|
|
1708
|
+
// Exit notifications and task_output refer to the same host process record.
|
|
1709
|
+
// Do not force an extra polling tool/turn merely to acknowledge a known exit.
|
|
1710
|
+
let backgroundChanged = false;
|
|
1711
|
+
for (const id of this.backgroundVerification.keys()) {
|
|
1712
|
+
backgroundChanged =
|
|
1713
|
+
(await this.recordFinishedBackgroundVerification(id)) || backgroundChanged;
|
|
1714
|
+
}
|
|
1715
|
+
if (backgroundChanged)
|
|
1716
|
+
await this.persistVerificationState();
|
|
1717
|
+
// Edits return immediately; only the completion boundary waits for remaining
|
|
1718
|
+
// checks. Queued timeouts stay explicitly unverified, never a false all-clear.
|
|
1719
|
+
await this.lspManager?.flushDiagnostics(this.opts.signal);
|
|
1720
|
+
if (this.opts.signal?.aborted)
|
|
1721
|
+
return null;
|
|
1722
|
+
const diagnosticText = this.lspManager?.drainDiagnostics(this.getVerificationProblem() !== null);
|
|
1723
|
+
if (diagnosticText)
|
|
1724
|
+
this.eventBus.emit("diagnostics", { text: diagnosticText });
|
|
1725
|
+
this.refreshVerificationArmed();
|
|
1726
|
+
const diagnosticMessages = diagnosticText
|
|
1727
|
+
? [
|
|
1728
|
+
{
|
|
1729
|
+
role: "user",
|
|
1730
|
+
content: buildNotificationSteeringText([diagnosticText]),
|
|
1731
|
+
provenance: { source: "runtime", kind: "notification", visibility: "hidden" },
|
|
1732
|
+
},
|
|
1733
|
+
]
|
|
1734
|
+
: [];
|
|
1377
1735
|
const childCompletionFollowUp = buildSubAgentCompletionFollowUp(this.subAgentManager);
|
|
1378
1736
|
if (childCompletionFollowUp)
|
|
1379
|
-
return childCompletionFollowUp;
|
|
1737
|
+
return [...diagnosticMessages, ...childCompletionFollowUp];
|
|
1380
1738
|
// Background processes started this run and never read block completion:
|
|
1381
1739
|
// their progress/exit checkpoints only land on the steering path, which an
|
|
1382
1740
|
// agent about to stop never reaches.
|
|
@@ -1386,7 +1744,7 @@ export class AgentSession {
|
|
|
1386
1744
|
log("INFO", "process-gate", "Injecting background-process completion gate", {
|
|
1387
1745
|
injected: String(this.processGateInjected),
|
|
1388
1746
|
});
|
|
1389
|
-
return processFollowUp;
|
|
1747
|
+
return [...diagnosticMessages, ...processFollowUp];
|
|
1390
1748
|
}
|
|
1391
1749
|
// Verification gate: code was edited but nothing verified since the last
|
|
1392
1750
|
// edit. Above the Ideal review so checks RUN before the read-based review
|
|
@@ -1394,17 +1752,29 @@ export class AgentSession {
|
|
|
1394
1752
|
if (this.opts.selfCorrectionHooks !== false &&
|
|
1395
1753
|
this.settingsManager.get("verificationGateEnabled") &&
|
|
1396
1754
|
(!this.opts.allowedTools || this.opts.allowedTools.includes("bash"))) {
|
|
1755
|
+
const verificationReason = this.verificationGate.pendingReason();
|
|
1397
1756
|
const verificationFollowUp = this.verificationGate.followUp();
|
|
1398
1757
|
if (verificationFollowUp) {
|
|
1399
1758
|
log("INFO", "verification-gate", "Injecting verification follow-up", {});
|
|
1400
1759
|
// Announce, THEN disarm: clients release held text on disarm, so the
|
|
1401
1760
|
// reverse order paints the draft and immediately deletes it — the exact
|
|
1402
1761
|
// flash arming exists to prevent.
|
|
1403
|
-
this.eventBus.emit("hook", {
|
|
1762
|
+
this.eventBus.emit("hook", {
|
|
1763
|
+
kind: "verification",
|
|
1764
|
+
...(verificationReason === "tamper"
|
|
1765
|
+
? { verificationReason: "check_review" }
|
|
1766
|
+
: verificationReason === "recheck"
|
|
1767
|
+
? { verificationReason }
|
|
1768
|
+
: {}),
|
|
1769
|
+
});
|
|
1404
1770
|
this.refreshHookArming();
|
|
1405
|
-
return verificationFollowUp;
|
|
1771
|
+
return [...diagnosticMessages, ...verificationFollowUp];
|
|
1406
1772
|
}
|
|
1407
1773
|
}
|
|
1774
|
+
// Address real errors before review; unavailable checks share the existing
|
|
1775
|
+
// verification demand above instead of manufacturing a separate hook.
|
|
1776
|
+
if (diagnosticMessages.length > 0)
|
|
1777
|
+
return diagnosticMessages;
|
|
1408
1778
|
if (this.opts.selfCorrectionHooks === false || this.idealReviewSuppressed)
|
|
1409
1779
|
return null;
|
|
1410
1780
|
if (this.idealReviewPhase === "reviewing") {
|
|
@@ -1460,6 +1830,9 @@ export class AgentSession {
|
|
|
1460
1830
|
const driftedFiles = detectTestDrift(this.hookFileEditCounts.keys(), this.cwd).slice(0, 5);
|
|
1461
1831
|
if (!decision.shouldReview && driftedFiles.length === 0)
|
|
1462
1832
|
return null;
|
|
1833
|
+
// Independent reviewer first (async, bounded): its findings ride in the
|
|
1834
|
+
// SAME follow-up batch as the in-thread review + coverage requirements, so
|
|
1835
|
+
// addressing everything still costs one extra turn.
|
|
1463
1836
|
this.reviewCoverage.start(this.hookFileEditCounts.keys());
|
|
1464
1837
|
this.idealReviewPhase = "reviewing";
|
|
1465
1838
|
const coverage = this.reviewCoverage.evidence();
|
|
@@ -1476,6 +1849,8 @@ export class AgentSession {
|
|
|
1476
1849
|
// coverage is outstanding injects again. Disarm lands later, on the read
|
|
1477
1850
|
// that closes the last gap (or when the retry budget escalates).
|
|
1478
1851
|
this.refreshIdealReviewArmed();
|
|
1852
|
+
// Announce the phase before the reviewer starts, not after its bounded wait.
|
|
1853
|
+
const independentMessages = await this.runIndependentReview(decision);
|
|
1479
1854
|
log("INFO", "ideal", "Injecting ideal review before final response", {
|
|
1480
1855
|
coverageExpected: coverage.expected,
|
|
1481
1856
|
coverageMissing: coverage.missing,
|
|
@@ -1483,6 +1858,7 @@ export class AgentSession {
|
|
|
1483
1858
|
lspMissing: lspEvidence.missing,
|
|
1484
1859
|
});
|
|
1485
1860
|
return [
|
|
1861
|
+
...independentMessages,
|
|
1486
1862
|
this.withReviewLspEvidence(withReviewCoverageRequirements(buildIdealReviewMessage(decision.reasons, driftedFiles), coverage.missing), lspEvidence),
|
|
1487
1863
|
];
|
|
1488
1864
|
}
|
|
@@ -2083,12 +2459,15 @@ export class AgentSession {
|
|
|
2083
2459
|
await this.rePersistNolanTurns();
|
|
2084
2460
|
await this.rePersistAutopilotMarkers();
|
|
2085
2461
|
await this.rePersistAppMarkers();
|
|
2462
|
+
await this.persistVerificationState();
|
|
2086
2463
|
await this.persistAppMarker("compaction", {
|
|
2087
2464
|
originalCount: result.originalCount,
|
|
2088
2465
|
newCount: result.newCount,
|
|
2089
2466
|
});
|
|
2090
2467
|
}
|
|
2091
|
-
async compact(existingCredentials, mode = "manual"
|
|
2468
|
+
async compact(existingCredentials, mode = "manual",
|
|
2469
|
+
/** User-stated focus (`/compact <focus>`): what must survive verbatim. */
|
|
2470
|
+
focus) {
|
|
2092
2471
|
this.lastCompactionCompacted = false;
|
|
2093
2472
|
const creds = existingCredentials ??
|
|
2094
2473
|
(await this.authStorage.resolveCredentials(this.provider, {
|
|
@@ -2121,6 +2500,7 @@ export class AgentSession {
|
|
|
2121
2500
|
targetTokens: policy.targetTokens,
|
|
2122
2501
|
signal: this.opts.signal,
|
|
2123
2502
|
approvedPlanPath: this.approvedPlanPath,
|
|
2503
|
+
focus,
|
|
2124
2504
|
});
|
|
2125
2505
|
contextSelection = output.result.contextSelection;
|
|
2126
2506
|
return output;
|
|
@@ -2239,6 +2619,8 @@ export class AgentSession {
|
|
|
2239
2619
|
// Approved-plan execution is a clean checkpoint of the same conversation;
|
|
2240
2620
|
// explicit new sessions reset the conversation identity.
|
|
2241
2621
|
if (!preserveConversation) {
|
|
2622
|
+
this.verificationGate.reset();
|
|
2623
|
+
this.backgroundVerification.clear();
|
|
2242
2624
|
this.conversationId = "";
|
|
2243
2625
|
this.checkpointGeneration = 0;
|
|
2244
2626
|
this.sessionPreview = "";
|
|
@@ -2680,6 +3062,9 @@ export class AgentSession {
|
|
|
2680
3062
|
},
|
|
2681
3063
|
};
|
|
2682
3064
|
this.turnMetrics.push(payload);
|
|
3065
|
+
// Internal diagnostics piggyback on the authoritative per-turn metric —
|
|
3066
|
+
// one source of truth, and the record flushes to disk every turn.
|
|
3067
|
+
this.diagnosticsRecorder?.recordTurnMetric(payload);
|
|
2683
3068
|
if (this.sessionPath)
|
|
2684
3069
|
await this.sessionManager.appendTurnMetric(this.sessionPath, payload);
|
|
2685
3070
|
}
|
|
@@ -2778,6 +3163,76 @@ export class AgentSession {
|
|
|
2778
3163
|
* instead of dropping the marker or falling back to a raw verdict string.
|
|
2779
3164
|
* No-op persistence for transient sessions (kept in memory only).
|
|
2780
3165
|
*/
|
|
3166
|
+
async recordFinishedBackgroundVerification(id) {
|
|
3167
|
+
const started = this.backgroundVerification.get(id);
|
|
3168
|
+
const proc = this.processManager?.list().find((entry) => entry.id === id);
|
|
3169
|
+
if (!started || !proc || proc.exitCode === null)
|
|
3170
|
+
return false;
|
|
3171
|
+
if (started.sourceSnapshot !== undefined) {
|
|
3172
|
+
await this.finishSnapshotVerification(started, proc.exitCode === 0);
|
|
3173
|
+
}
|
|
3174
|
+
else if (proc.exitCode === 0) {
|
|
3175
|
+
this.verificationGate.recordVerification(started.revision, started.command);
|
|
3176
|
+
}
|
|
3177
|
+
else {
|
|
3178
|
+
this.verificationGate.recordFailedVerification(started.command, started.revision);
|
|
3179
|
+
}
|
|
3180
|
+
this.backgroundVerification.delete(id);
|
|
3181
|
+
return true;
|
|
3182
|
+
}
|
|
3183
|
+
getVerificationEvidence() {
|
|
3184
|
+
return this.verificationGate.evidence();
|
|
3185
|
+
}
|
|
3186
|
+
async finishSnapshotVerification(check, passed) {
|
|
3187
|
+
const after = check.sourceSnapshot
|
|
3188
|
+
? await captureVerificationSnapshot(this.opts.cwd, [...this.hookFileEditCounts.keys()])
|
|
3189
|
+
: null;
|
|
3190
|
+
if (after === null || after !== check.sourceSnapshot) {
|
|
3191
|
+
this.verificationGate.requireFreshVerification(true, check.command);
|
|
3192
|
+
this.verificationGate.recordRejectedCheck(check.command, after === null
|
|
3193
|
+
? "Workspace inputs could not be compared; run a read-only check after the command"
|
|
3194
|
+
: "Command changed workspace inputs; run checks against the changed source");
|
|
3195
|
+
if (!passed)
|
|
3196
|
+
this.verificationGate.recordFailedVerification(check.command);
|
|
3197
|
+
}
|
|
3198
|
+
else if (passed) {
|
|
3199
|
+
const classification = classifyVerificationCommand(check.command);
|
|
3200
|
+
if (classification.snapshotPreserveOnly) {
|
|
3201
|
+
this.verificationGate.recordRejectedCheck(check.command, classification.reason);
|
|
3202
|
+
}
|
|
3203
|
+
else {
|
|
3204
|
+
this.verificationGate.recordVerification(check.revision, check.command);
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
else {
|
|
3208
|
+
this.verificationGate.recordFailedVerification(check.command, check.revision);
|
|
3209
|
+
}
|
|
3210
|
+
}
|
|
3211
|
+
getVerificationProblem() {
|
|
3212
|
+
if ([...this.hookToolCalls.values()].some((call) => call.sourceSnapshot !== undefined)) {
|
|
3213
|
+
return "Unverified: a build is still running or its workspace comparison is pending.";
|
|
3214
|
+
}
|
|
3215
|
+
return (this.verificationGate.verificationProblem() ??
|
|
3216
|
+
(this.backgroundVerification.size > 0
|
|
3217
|
+
? "Unverified: a background check is still running or its result has not been confirmed."
|
|
3218
|
+
: null));
|
|
3219
|
+
}
|
|
3220
|
+
async persistVerificationState() {
|
|
3221
|
+
if (!this.sessionPath)
|
|
3222
|
+
return;
|
|
3223
|
+
const entry = {
|
|
3224
|
+
type: "custom",
|
|
3225
|
+
kind: VERIFICATION_STATE_KIND,
|
|
3226
|
+
id: crypto.randomUUID(),
|
|
3227
|
+
parentId: null,
|
|
3228
|
+
timestamp: new Date().toISOString(),
|
|
3229
|
+
data: {
|
|
3230
|
+
...this.verificationGate.snapshot(),
|
|
3231
|
+
unknown: this.getVerificationProblem() !== null,
|
|
3232
|
+
},
|
|
3233
|
+
};
|
|
3234
|
+
await this.sessionManager.appendEntry(this.sessionPath, entry);
|
|
3235
|
+
}
|
|
2781
3236
|
async persistAutopilotMarker(phase, extra) {
|
|
2782
3237
|
const afterMessageCount = this.persistedTranscriptCount();
|
|
2783
3238
|
const payload = {
|
|
@@ -2904,7 +3359,10 @@ export class AgentSession {
|
|
|
2904
3359
|
async enhancePrompt(text) {
|
|
2905
3360
|
if (!text.trim())
|
|
2906
3361
|
return { enhanced: text, segments: [{ kind: "text", text }] };
|
|
2907
|
-
|
|
3362
|
+
// Keep credentials and settings on the model selected at click time, even
|
|
3363
|
+
// if the user switches models while credential resolution is pending.
|
|
3364
|
+
const { provider, model, thinkingLevel, maxTokens, baseUrl } = this;
|
|
3365
|
+
const creds = await this.authStorage.resolveCredentials(provider, {
|
|
2908
3366
|
storageKeys: this.currentAuthStorageKeys(),
|
|
2909
3367
|
});
|
|
2910
3368
|
// Cheap, best-effort stack detection from the project root so terminology is
|
|
@@ -2917,12 +3375,16 @@ export class AgentSession {
|
|
|
2917
3375
|
/* detection is best-effort — fall back to no stack hint */
|
|
2918
3376
|
}
|
|
2919
3377
|
return enhancePrompt({
|
|
2920
|
-
provider
|
|
2921
|
-
model
|
|
3378
|
+
provider,
|
|
3379
|
+
model,
|
|
3380
|
+
thinking: thinkingLevel,
|
|
3381
|
+
maxTokens,
|
|
3382
|
+
userAgent: provider === "anthropic" ? await getClaudeCliUserAgent() : undefined,
|
|
3383
|
+
projectId: creds.projectId,
|
|
2922
3384
|
prompt: text,
|
|
2923
3385
|
stack,
|
|
2924
3386
|
apiKey: creds.accessToken,
|
|
2925
|
-
baseUrl:
|
|
3387
|
+
baseUrl: baseUrl ?? creds.baseUrl,
|
|
2926
3388
|
accountId: creds.accountId,
|
|
2927
3389
|
signal: this.opts.signal,
|
|
2928
3390
|
});
|
|
@@ -2977,6 +3439,7 @@ export class AgentSession {
|
|
|
2977
3439
|
return this.getPromptCacheKey();
|
|
2978
3440
|
}
|
|
2979
3441
|
async dispose() {
|
|
3442
|
+
this.diagnosticsRecorder?.finalize();
|
|
2980
3443
|
this.managerAbortSignal?.removeEventListener("abort", this.managerAbortHandler);
|
|
2981
3444
|
this.processManager?.shutdownAll();
|
|
2982
3445
|
this.lspManager?.shutdownAll();
|
|
@@ -3019,6 +3482,23 @@ export class AgentSession {
|
|
|
3019
3482
|
const loaded = await this.sessionManager.load(canonicalPath);
|
|
3020
3483
|
// Use the leaf from the header to walk the correct branch
|
|
3021
3484
|
const loadedMessages = this.sessionManager.getMessages(loaded.entries, loaded.header.leafId);
|
|
3485
|
+
this.backgroundVerification.clear();
|
|
3486
|
+
const savedVerification = [...loaded.entries]
|
|
3487
|
+
.reverse()
|
|
3488
|
+
.find((entry) => entry.type === "custom" && entry.kind === VERIFICATION_STATE_KIND);
|
|
3489
|
+
if (savedVerification?.type === "custom") {
|
|
3490
|
+
this.verificationGate.restore(savedVerification.data);
|
|
3491
|
+
}
|
|
3492
|
+
else {
|
|
3493
|
+
this.verificationGate.reset();
|
|
3494
|
+
// Legacy sessions have no host checkpoint. Tool-authored code history is
|
|
3495
|
+
// not proof of today's files; require fresh evidence before approval.
|
|
3496
|
+
if (loadedMessages.some((message) => message.role === "assistant" &&
|
|
3497
|
+
Array.isArray(message.content) &&
|
|
3498
|
+
message.content.some((part) => part.type === "tool_call" && (part.name === "edit" || part.name === "write")))) {
|
|
3499
|
+
this.verificationGate.requireFreshVerification();
|
|
3500
|
+
}
|
|
3501
|
+
}
|
|
3022
3502
|
this.checkpointGeneration = loaded.header.generation ?? 0;
|
|
3023
3503
|
this.conversationId = loaded.header.conversationId ?? loaded.header.id;
|
|
3024
3504
|
const legacyLabel = [...loaded.entries]
|
|
@@ -3162,7 +3642,7 @@ export class AgentSession {
|
|
|
3162
3642
|
createSlashCommandContext() {
|
|
3163
3643
|
return {
|
|
3164
3644
|
switchModel: (provider, model) => this.switchModel(provider, model),
|
|
3165
|
-
compact: () => this.compact(undefined, "manual"),
|
|
3645
|
+
compact: (focus) => this.compact(undefined, "manual", focus),
|
|
3166
3646
|
newSession: () => this.newSession(),
|
|
3167
3647
|
listSessions: async () => {
|
|
3168
3648
|
const sessions = await this.sessionManager.list(this.cwd);
|