@kenkaiiii/ggcoder 4.3.231 → 4.3.233
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 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +10 -89
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -1
- package/dist/config.js.map +1 -1
- package/dist/config.test.d.ts +2 -0
- package/dist/config.test.d.ts.map +1 -0
- package/dist/config.test.js +29 -0
- package/dist/config.test.js.map +1 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +2 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/ideal-review.d.ts +20 -0
- package/dist/core/ideal-review.d.ts.map +1 -0
- package/dist/core/ideal-review.js +55 -0
- package/dist/core/ideal-review.js.map +1 -0
- package/dist/core/ideal-review.test.d.ts +2 -0
- package/dist/core/ideal-review.test.d.ts.map +1 -0
- package/dist/core/ideal-review.test.js +59 -0
- package/dist/core/ideal-review.test.js.map +1 -0
- package/dist/core/prompt-commands.d.ts.map +1 -1
- package/dist/core/prompt-commands.js +8 -16
- package/dist/core/prompt-commands.js.map +1 -1
- package/dist/core/prompt-commands.test.js +14 -44
- package/dist/core/prompt-commands.test.js.map +1 -1
- package/dist/core/runtime-mode.d.ts +0 -11
- package/dist/core/runtime-mode.d.ts.map +1 -1
- package/dist/core/runtime-mode.js +0 -9
- package/dist/core/runtime-mode.js.map +1 -1
- package/dist/core/session-restore-display.test.js +4 -110
- package/dist/core/session-restore-display.test.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +2 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/interactive.d.ts.map +1 -1
- package/dist/interactive.js +1 -1
- package/dist/interactive.js.map +1 -1
- package/dist/system-prompt.d.ts +1 -2
- package/dist/system-prompt.d.ts.map +1 -1
- package/dist/system-prompt.js +11 -58
- package/dist/system-prompt.js.map +1 -1
- package/dist/system-prompt.test.js +3 -158
- package/dist/system-prompt.test.js.map +1 -1
- package/dist/tools/bash.d.ts +1 -4
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +3 -12
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/checkpoint-hook.test.js +3 -3
- package/dist/tools/checkpoint-hook.test.js.map +1 -1
- package/dist/tools/edit.d.ts +1 -4
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +5 -13
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/enter-plan.js +1 -1
- package/dist/tools/enter-plan.js.map +1 -1
- package/dist/tools/html-extract.d.ts +58 -0
- package/dist/tools/html-extract.d.ts.map +1 -0
- package/dist/tools/html-extract.js +130 -0
- package/dist/tools/html-extract.js.map +1 -0
- package/dist/tools/html-extract.test.d.ts +2 -0
- package/dist/tools/html-extract.test.d.ts.map +1 -0
- package/dist/tools/html-extract.test.js +60 -0
- package/dist/tools/html-extract.test.js.map +1 -0
- package/dist/tools/index.d.ts +0 -9
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +4 -8
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/pdf-extract.d.ts +18 -0
- package/dist/tools/pdf-extract.d.ts.map +1 -0
- package/dist/tools/pdf-extract.js +43 -0
- package/dist/tools/pdf-extract.js.map +1 -0
- package/dist/tools/pdf-extract.test.d.ts +2 -0
- package/dist/tools/pdf-extract.test.d.ts.map +1 -0
- package/dist/tools/pdf-extract.test.js +15 -0
- package/dist/tools/pdf-extract.test.js.map +1 -0
- package/dist/tools/prompt-hints.d.ts.map +1 -1
- package/dist/tools/prompt-hints.js +2 -3
- package/dist/tools/prompt-hints.js.map +1 -1
- package/dist/tools/screenshot.d.ts +1 -1
- package/dist/tools/subagent.d.ts +1 -4
- package/dist/tools/subagent.d.ts.map +1 -1
- package/dist/tools/subagent.js +2 -5
- package/dist/tools/subagent.js.map +1 -1
- package/dist/tools/web-fetch.d.ts +16 -1
- package/dist/tools/web-fetch.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +357 -45
- package/dist/tools/web-fetch.js.map +1 -1
- package/dist/tools/web-fetch.test.js +263 -2
- package/dist/tools/web-fetch.test.js.map +1 -1
- package/dist/tools/web-search.d.ts +14 -0
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +321 -35
- package/dist/tools/web-search.js.map +1 -1
- package/dist/tools/web-search.test.js +144 -1
- package/dist/tools/web-search.test.js.map +1 -1
- package/dist/tools/write.d.ts +1 -4
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/tools/write.js +5 -13
- package/dist/tools/write.js.map +1 -1
- package/dist/ui/App.d.ts +7 -20
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +124 -309
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/app-items.d.ts +36 -25
- package/dist/ui/app-items.d.ts.map +1 -1
- package/dist/ui/app-items.js +39 -0
- package/dist/ui/app-items.js.map +1 -1
- package/dist/ui/app-items.test.d.ts +2 -0
- package/dist/ui/app-items.test.d.ts.map +1 -0
- package/dist/ui/app-items.test.js +38 -0
- package/dist/ui/app-items.test.js.map +1 -0
- package/dist/ui/app-state-persistence.test.js +14 -318
- package/dist/ui/app-state-persistence.test.js.map +1 -1
- package/dist/ui/chat-layout-pinning.test.js +74 -4
- package/dist/ui/chat-layout-pinning.test.js.map +1 -1
- package/dist/ui/components/AssistantMessage.test.js +6 -9
- package/dist/ui/components/AssistantMessage.test.js.map +1 -1
- package/dist/ui/components/Banner.js +1 -1
- package/dist/ui/components/Banner.js.map +1 -1
- package/dist/ui/components/ChatFooterPane.d.ts +1 -5
- package/dist/ui/components/ChatFooterPane.d.ts.map +1 -1
- package/dist/ui/components/ChatFooterPane.js +3 -4
- package/dist/ui/components/ChatFooterPane.js.map +1 -1
- package/dist/ui/components/ChatInputStack.d.ts +3 -1
- package/dist/ui/components/ChatInputStack.d.ts.map +1 -1
- package/dist/ui/components/ChatInputStack.js +4 -3
- package/dist/ui/components/ChatInputStack.js.map +1 -1
- package/dist/ui/components/ChatScreen.d.ts +3 -16
- package/dist/ui/components/ChatScreen.d.ts.map +1 -1
- package/dist/ui/components/ChatScreen.js +2 -3
- package/dist/ui/components/ChatScreen.js.map +1 -1
- package/dist/ui/components/Footer.d.ts +3 -8
- package/dist/ui/components/Footer.d.ts.map +1 -1
- package/dist/ui/components/Footer.js +5 -25
- package/dist/ui/components/Footer.js.map +1 -1
- package/dist/ui/components/IdealHookMessage.d.ts +12 -0
- package/dist/ui/components/IdealHookMessage.d.ts.map +1 -0
- package/dist/ui/components/IdealHookMessage.js +24 -0
- package/dist/ui/components/IdealHookMessage.js.map +1 -0
- package/dist/ui/components/InputArea.d.ts +1 -9
- package/dist/ui/components/InputArea.d.ts.map +1 -1
- package/dist/ui/components/InputArea.js +2 -44
- package/dist/ui/components/InputArea.js.map +1 -1
- package/dist/ui/components/LiveToolPanel.d.ts +30 -0
- package/dist/ui/components/LiveToolPanel.d.ts.map +1 -0
- package/dist/ui/components/LiveToolPanel.js +66 -0
- package/dist/ui/components/LiveToolPanel.js.map +1 -0
- package/dist/ui/components/ToolExecution.js +0 -2
- package/dist/ui/components/ToolExecution.js.map +1 -1
- package/dist/ui/components/TranscriptViewport.d.ts +1 -1
- package/dist/ui/components/TranscriptViewport.js +1 -1
- package/dist/ui/footer-jump-regression.test.js +12 -2
- package/dist/ui/footer-jump-regression.test.js.map +1 -1
- package/dist/ui/footer-status-layout.test.js +4 -12
- package/dist/ui/footer-status-layout.test.js.map +1 -1
- package/dist/ui/hooks/useAgentLoop.d.ts +2 -0
- package/dist/ui/hooks/useAgentLoop.d.ts.map +1 -1
- package/dist/ui/hooks/useAgentLoop.js +45 -1
- package/dist/ui/hooks/useAgentLoop.js.map +1 -1
- package/dist/ui/hooks/useChatLayoutMeasurements.d.ts +3 -4
- package/dist/ui/hooks/useChatLayoutMeasurements.d.ts.map +1 -1
- package/dist/ui/hooks/useChatLayoutMeasurements.js +26 -4
- package/dist/ui/hooks/useChatLayoutMeasurements.js.map +1 -1
- package/dist/ui/hooks/useModeState.d.ts +4 -19
- package/dist/ui/hooks/useModeState.d.ts.map +1 -1
- package/dist/ui/hooks/useModeState.js +5 -45
- package/dist/ui/hooks/useModeState.js.map +1 -1
- package/dist/ui/hooks/usePixelFixFlow.js +2 -2
- package/dist/ui/layout-decisions.d.ts +11 -34
- package/dist/ui/layout-decisions.d.ts.map +1 -1
- package/dist/ui/layout-decisions.js +15 -42
- package/dist/ui/layout-decisions.js.map +1 -1
- package/dist/ui/live-area-height.d.ts.map +1 -1
- package/dist/ui/live-area-height.js +6 -1
- package/dist/ui/live-area-height.js.map +1 -1
- package/dist/ui/live-frame-height.test.js +26 -1
- package/dist/ui/live-frame-height.test.js.map +1 -1
- package/dist/ui/plan-overlay.test.js +1 -1
- package/dist/ui/plan-overlay.test.js.map +1 -1
- package/dist/ui/prompt-routing.d.ts +1 -19
- package/dist/ui/prompt-routing.d.ts.map +1 -1
- package/dist/ui/prompt-routing.js +1 -79
- package/dist/ui/prompt-routing.js.map +1 -1
- package/dist/ui/render.d.ts +6 -18
- package/dist/ui/render.d.ts.map +1 -1
- package/dist/ui/render.js +2 -10
- package/dist/ui/render.js.map +1 -1
- package/dist/ui/scroll-stabilization.test.js +1 -7
- package/dist/ui/scroll-stabilization.test.js.map +1 -1
- package/dist/ui/slash-command-images.test.js +11 -86
- package/dist/ui/slash-command-images.test.js.map +1 -1
- package/dist/ui/streaming-flush-bounce.test.d.ts +2 -0
- package/dist/ui/streaming-flush-bounce.test.d.ts.map +1 -0
- package/dist/ui/streaming-flush-bounce.test.js +156 -0
- package/dist/ui/streaming-flush-bounce.test.js.map +1 -0
- package/dist/ui/submit-prompt-command.d.ts +1 -16
- package/dist/ui/submit-prompt-command.d.ts.map +1 -1
- package/dist/ui/submit-prompt-command.js +4 -54
- package/dist/ui/submit-prompt-command.js.map +1 -1
- package/dist/ui/submit-slash-commands.d.ts +0 -1
- package/dist/ui/submit-slash-commands.d.ts.map +1 -1
- package/dist/ui/submit-slash-commands.js +0 -4
- package/dist/ui/submit-slash-commands.js.map +1 -1
- package/dist/ui/terminal-history-status-renderers.d.ts +0 -1
- package/dist/ui/terminal-history-status-renderers.d.ts.map +1 -1
- package/dist/ui/terminal-history-status-renderers.js +0 -3
- 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 +19 -56
- package/dist/ui/terminal-history.js.map +1 -1
- package/dist/ui/terminal-history.test.js +6 -33
- package/dist/ui/terminal-history.test.js.map +1 -1
- package/dist/ui/tool-line-summary.d.ts +29 -0
- package/dist/ui/tool-line-summary.d.ts.map +1 -0
- package/dist/ui/tool-line-summary.js +153 -0
- package/dist/ui/tool-line-summary.js.map +1 -0
- package/dist/ui/transcript/TranscriptRenderer.d.ts +1 -1
- package/dist/ui/transcript/TranscriptRenderer.d.ts.map +1 -1
- package/dist/ui/transcript/TranscriptRenderer.js +21 -12
- package/dist/ui/transcript/TranscriptRenderer.js.map +1 -1
- package/dist/ui/transcript/presentation.d.ts +1 -17
- package/dist/ui/transcript/presentation.d.ts.map +1 -1
- package/dist/ui/transcript/presentation.js +0 -26
- 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 +15 -9
- package/dist/ui/transcript/spacing.js.map +1 -1
- package/dist/ui/transcript/spacing.test.js +7 -8
- package/dist/ui/transcript/spacing.test.js.map +1 -1
- package/dist/ui/transcript/tool-presentation.js +1 -1
- package/dist/ui/transcript/tool-presentation.js.map +1 -1
- package/dist/ui/transcript/transcript-lines.d.ts.map +1 -1
- package/dist/ui/transcript/transcript-lines.js +4 -0
- package/dist/ui/transcript/transcript-lines.js.map +1 -1
- package/dist/ui/tui-history-parity.test.js +8 -47
- package/dist/ui/tui-history-parity.test.js.map +1 -1
- package/dist/ui/tui-simulation.test.js +2 -1
- package/dist/ui/tui-simulation.test.js.map +1 -1
- package/dist/utils/format.js +7 -0
- package/dist/utils/format.js.map +1 -1
- package/package.json +11 -5
- package/dist/core/goal-controller.d.ts +0 -82
- package/dist/core/goal-controller.d.ts.map +0 -1
- package/dist/core/goal-controller.js +0 -838
- package/dist/core/goal-controller.js.map +0 -1
- package/dist/core/goal-controller.test.d.ts +0 -2
- package/dist/core/goal-controller.test.d.ts.map +0 -1
- package/dist/core/goal-controller.test.js +0 -1279
- package/dist/core/goal-controller.test.js.map +0 -1
- package/dist/core/goal-engine.d.ts +0 -61
- package/dist/core/goal-engine.d.ts.map +0 -1
- package/dist/core/goal-engine.js +0 -123
- package/dist/core/goal-engine.js.map +0 -1
- package/dist/core/goal-engine.test.d.ts +0 -2
- package/dist/core/goal-engine.test.d.ts.map +0 -1
- package/dist/core/goal-engine.test.js +0 -295
- package/dist/core/goal-engine.test.js.map +0 -1
- package/dist/core/goal-integration.d.ts +0 -80
- package/dist/core/goal-integration.d.ts.map +0 -1
- package/dist/core/goal-integration.js +0 -296
- package/dist/core/goal-integration.js.map +0 -1
- package/dist/core/goal-integration.test.d.ts +0 -2
- package/dist/core/goal-integration.test.d.ts.map +0 -1
- package/dist/core/goal-integration.test.js +0 -369
- package/dist/core/goal-integration.test.js.map +0 -1
- package/dist/core/goal-lifecycle-smoke.test.d.ts +0 -2
- package/dist/core/goal-lifecycle-smoke.test.d.ts.map +0 -1
- package/dist/core/goal-lifecycle-smoke.test.js +0 -248
- package/dist/core/goal-lifecycle-smoke.test.js.map +0 -1
- package/dist/core/goal-overhead-harness.d.ts +0 -33
- package/dist/core/goal-overhead-harness.d.ts.map +0 -1
- package/dist/core/goal-overhead-harness.js +0 -268
- package/dist/core/goal-overhead-harness.js.map +0 -1
- package/dist/core/goal-prerequisites.d.ts +0 -23
- package/dist/core/goal-prerequisites.d.ts.map +0 -1
- package/dist/core/goal-prerequisites.js +0 -114
- package/dist/core/goal-prerequisites.js.map +0 -1
- package/dist/core/goal-prerequisites.test.d.ts +0 -2
- package/dist/core/goal-prerequisites.test.d.ts.map +0 -1
- package/dist/core/goal-prerequisites.test.js +0 -154
- package/dist/core/goal-prerequisites.test.js.map +0 -1
- package/dist/core/goal-references.d.ts +0 -14
- package/dist/core/goal-references.d.ts.map +0 -1
- package/dist/core/goal-references.js +0 -153
- package/dist/core/goal-references.js.map +0 -1
- package/dist/core/goal-references.test.d.ts +0 -2
- package/dist/core/goal-references.test.d.ts.map +0 -1
- package/dist/core/goal-references.test.js +0 -77
- package/dist/core/goal-references.test.js.map +0 -1
- package/dist/core/goal-store.d.ts +0 -289
- package/dist/core/goal-store.d.ts.map +0 -1
- package/dist/core/goal-store.js +0 -1156
- package/dist/core/goal-store.js.map +0 -1
- package/dist/core/goal-store.test.d.ts +0 -2
- package/dist/core/goal-store.test.d.ts.map +0 -1
- package/dist/core/goal-store.test.js +0 -530
- package/dist/core/goal-store.test.js.map +0 -1
- package/dist/core/goal-verifier.d.ts +0 -17
- package/dist/core/goal-verifier.d.ts.map +0 -1
- package/dist/core/goal-verifier.js +0 -87
- package/dist/core/goal-verifier.js.map +0 -1
- package/dist/core/goal-verifier.test.d.ts +0 -2
- package/dist/core/goal-verifier.test.d.ts.map +0 -1
- package/dist/core/goal-verifier.test.js +0 -131
- package/dist/core/goal-verifier.test.js.map +0 -1
- package/dist/core/goal-worker-dev-server-lifecycle.test.d.ts +0 -2
- package/dist/core/goal-worker-dev-server-lifecycle.test.d.ts.map +0 -1
- package/dist/core/goal-worker-dev-server-lifecycle.test.js +0 -68
- package/dist/core/goal-worker-dev-server-lifecycle.test.js.map +0 -1
- package/dist/core/goal-worker.d.ts +0 -61
- package/dist/core/goal-worker.d.ts.map +0 -1
- package/dist/core/goal-worker.js +0 -467
- package/dist/core/goal-worker.js.map +0 -1
- package/dist/core/goal-worker.test.d.ts +0 -2
- package/dist/core/goal-worker.test.d.ts.map +0 -1
- package/dist/core/goal-worker.test.js +0 -493
- package/dist/core/goal-worker.test.js.map +0 -1
- package/dist/core/goal-worktree.d.ts +0 -108
- package/dist/core/goal-worktree.d.ts.map +0 -1
- package/dist/core/goal-worktree.js +0 -300
- package/dist/core/goal-worktree.js.map +0 -1
- package/dist/core/goal-worktree.test.d.ts +0 -2
- package/dist/core/goal-worktree.test.d.ts.map +0 -1
- package/dist/core/goal-worktree.test.js +0 -448
- package/dist/core/goal-worktree.test.js.map +0 -1
- package/dist/tools/goal-mode.test.d.ts +0 -2
- package/dist/tools/goal-mode.test.d.ts.map +0 -1
- package/dist/tools/goal-mode.test.js +0 -121
- package/dist/tools/goal-mode.test.js.map +0 -1
- package/dist/tools/goals.d.ts +0 -143
- package/dist/tools/goals.d.ts.map +0 -1
- package/dist/tools/goals.js +0 -1038
- package/dist/tools/goals.js.map +0 -1
- package/dist/tools/goals.test.d.ts +0 -2
- package/dist/tools/goals.test.d.ts.map +0 -1
- package/dist/tools/goals.test.js +0 -1444
- package/dist/tools/goals.test.js.map +0 -1
- package/dist/ui/components/GoalOverlay.d.ts +0 -83
- package/dist/ui/components/GoalOverlay.d.ts.map +0 -1
- package/dist/ui/components/GoalOverlay.js +0 -710
- package/dist/ui/components/GoalOverlay.js.map +0 -1
- package/dist/ui/components/GoalPickerMenu.d.ts +0 -9
- package/dist/ui/components/GoalPickerMenu.d.ts.map +0 -1
- package/dist/ui/components/GoalPickerMenu.js +0 -37
- package/dist/ui/components/GoalPickerMenu.js.map +0 -1
- package/dist/ui/components/GoalStatusBar.d.ts +0 -26
- package/dist/ui/components/GoalStatusBar.d.ts.map +0 -1
- package/dist/ui/components/GoalStatusBar.js +0 -130
- package/dist/ui/components/GoalStatusBar.js.map +0 -1
- package/dist/ui/components/GoalStatusBar.test.d.ts +0 -2
- package/dist/ui/components/GoalStatusBar.test.d.ts.map +0 -1
- package/dist/ui/components/GoalStatusBar.test.js +0 -17
- package/dist/ui/components/GoalStatusBar.test.js.map +0 -1
- package/dist/ui/goal-events.d.ts +0 -125
- package/dist/ui/goal-events.d.ts.map +0 -1
- package/dist/ui/goal-events.js +0 -407
- package/dist/ui/goal-events.js.map +0 -1
- package/dist/ui/goal-events.test.d.ts +0 -2
- package/dist/ui/goal-events.test.d.ts.map +0 -1
- package/dist/ui/goal-events.test.js +0 -416
- package/dist/ui/goal-events.test.js.map +0 -1
- package/dist/ui/goal-lifecycle-orchestration.test.d.ts +0 -2
- package/dist/ui/goal-lifecycle-orchestration.test.d.ts.map +0 -1
- package/dist/ui/goal-lifecycle-orchestration.test.js +0 -555
- package/dist/ui/goal-lifecycle-orchestration.test.js.map +0 -1
- package/dist/ui/goal-overlay.test.d.ts +0 -2
- package/dist/ui/goal-overlay.test.d.ts.map +0 -1
- package/dist/ui/goal-overlay.test.js +0 -384
- package/dist/ui/goal-overlay.test.js.map +0 -1
- package/dist/ui/goal-progress.d.ts +0 -31
- package/dist/ui/goal-progress.d.ts.map +0 -1
- package/dist/ui/goal-progress.js +0 -149
- package/dist/ui/goal-progress.js.map +0 -1
- package/dist/ui/goal-run-helpers.d.ts +0 -12
- package/dist/ui/goal-run-helpers.d.ts.map +0 -1
- package/dist/ui/goal-run-helpers.js +0 -42
- package/dist/ui/goal-run-helpers.js.map +0 -1
- package/dist/ui/goal-status-bar.test.d.ts +0 -2
- package/dist/ui/goal-status-bar.test.d.ts.map +0 -1
- package/dist/ui/goal-status-bar.test.js +0 -174
- package/dist/ui/goal-status-bar.test.js.map +0 -1
- package/dist/ui/goal-summary.d.ts +0 -14
- package/dist/ui/goal-summary.d.ts.map +0 -1
- package/dist/ui/goal-summary.js +0 -194
- package/dist/ui/goal-summary.js.map +0 -1
- package/dist/ui/hooks/useGoalOrchestration.d.ts +0 -82
- package/dist/ui/hooks/useGoalOrchestration.d.ts.map +0 -1
- package/dist/ui/hooks/useGoalOrchestration.js +0 -863
- package/dist/ui/hooks/useGoalOrchestration.js.map +0 -1
- package/dist/ui/hooks/useGoalPickerController.d.ts +0 -22
- package/dist/ui/hooks/useGoalPickerController.d.ts.map +0 -1
- package/dist/ui/hooks/useGoalPickerController.js +0 -35
- package/dist/ui/hooks/useGoalPickerController.js.map +0 -1
- package/dist/ui/prompt-routing.test.d.ts +0 -2
- package/dist/ui/prompt-routing.test.d.ts.map +0 -1
- package/dist/ui/prompt-routing.test.js +0 -48
- package/dist/ui/prompt-routing.test.js.map +0 -1
- package/dist/ui/transcript/GoalRows.d.ts +0 -10
- package/dist/ui/transcript/GoalRows.d.ts.map +0 -1
- package/dist/ui/transcript/GoalRows.js +0 -35
- package/dist/ui/transcript/GoalRows.js.map +0 -1
package/dist/ui/App.js
CHANGED
|
@@ -4,12 +4,10 @@ import { Box, useStdout } from "ink";
|
|
|
4
4
|
import { useTerminalSize } from "./hooks/useTerminalSize.js";
|
|
5
5
|
import { useChatLayoutMeasurements } from "./hooks/useChatLayoutMeasurements.js";
|
|
6
6
|
import { useTaskPickerController } from "./hooks/useTaskPickerController.js";
|
|
7
|
-
import { useGoalPickerController } from "./hooks/useGoalPickerController.js";
|
|
8
7
|
import { useModeState } from "./hooks/useModeState.js";
|
|
9
8
|
import { useSessionPersistence } from "./hooks/useSessionPersistence.js";
|
|
10
9
|
import { useContextCompaction } from "./hooks/useContextCompaction.js";
|
|
11
10
|
import { usePixelFixFlow } from "./hooks/usePixelFixFlow.js";
|
|
12
|
-
import { useGoalOrchestration } from "./hooks/useGoalOrchestration.js";
|
|
13
11
|
import { useDoublePress } from "./hooks/useDoublePress.js";
|
|
14
12
|
import { useTaskBarStore, useTaskBarPolling, focusTaskBar, exitTaskBar, expandTaskBar, collapseTaskBar, navigateTaskBar, killTask, } from "./stores/taskbar-store.js";
|
|
15
13
|
import { playNotificationSound } from "../utils/sound.js";
|
|
@@ -19,9 +17,9 @@ import { useAgentLoop } from "./hooks/useAgentLoop.js";
|
|
|
19
17
|
import { useTranscriptHistory } from "./hooks/useTranscriptHistory.js";
|
|
20
18
|
import { createWebSearchTool } from "../tools/web-search.js";
|
|
21
19
|
import { ChatScreen } from "./components/ChatScreen.js";
|
|
20
|
+
import { LIVE_TOOL_PANEL_ROWS } from "./components/LiveToolPanel.js";
|
|
22
21
|
import { FullScreenOverlayRouter } from "./components/FullScreenOverlayRouter.js";
|
|
23
22
|
import { SessionSummaryDisplay } from "./components/SessionSummary.js";
|
|
24
|
-
import { reconcileGoalStatusEntriesWithRuns, removeGoalStatusEntry, syncGoalStatusEntries, } from "./components/GoalStatusBar.js";
|
|
25
23
|
import { useTheme, useSetTheme } from "./theme/theme.js";
|
|
26
24
|
import { useTerminalTitle } from "./hooks/useTerminalTitle.js";
|
|
27
25
|
import { getGitBranch } from "../utils/git.js";
|
|
@@ -41,16 +39,13 @@ import { extractPlanSteps, findCompletedMarkers, markStepsCompleted, segmentDisp
|
|
|
41
39
|
import { getMCPServers } from "../core/mcp/index.js";
|
|
42
40
|
import { trimFlushedItems, flushOnTurnText, flushOnTurnEnd, flushOverflow, } from "./live-item-flush.js";
|
|
43
41
|
import { splitAssistantStreamingText } from "./utils/assistant-stream-split.js";
|
|
44
|
-
import { goalHasBlockingPrerequisites, loadGoalRuns, reconcileActiveGoalRuns, upsertGoalRun, } from "../core/goal-store.js";
|
|
45
42
|
import { getNextPendingTask, markTaskInProgress } from "../core/tasks-store.js";
|
|
46
|
-
import { listGoalWorkers, stopGoalWorker } from "../core/goal-worker.js";
|
|
47
|
-
import { isGoalSyntheticEvent, parseGoalSyntheticEvent } from "./goal-events.js";
|
|
48
43
|
import { buildUserContentWithAttachments } from "./prompt-routing.js";
|
|
49
44
|
import { submitPromptCommand } from "./submit-prompt-command.js";
|
|
50
45
|
import { handleUiSlashCommand } from "./submit-slash-commands.js";
|
|
46
|
+
import { buildIdealReviewMessage, evaluateIdealReview } from "../core/ideal-review.js";
|
|
51
47
|
import { getNextThinkingLevel, isThinkingLevelSupported } from "./thinking-level.js";
|
|
52
|
-
import {
|
|
53
|
-
import { getDoneFlushDecision, nextGoalModeAfterAgentDone, shouldTopSpaceAfterPrintedAgentBoundary, shouldTopSpaceStreamingAssistant, } from "./layout-decisions.js";
|
|
48
|
+
import { getDoneFlushDecision, shouldTopSpaceAfterPrintedAgentBoundary, shouldTopSpaceStreamingAssistant, } from "./layout-decisions.js";
|
|
54
49
|
import { isTranscriptSpacingItem } from "./transcript/spacing.js";
|
|
55
50
|
import { buildTranscriptLines } from "./transcript/transcript-lines.js";
|
|
56
51
|
import { useTranscriptScroll } from "./hooks/useTranscriptScroll.js";
|
|
@@ -61,12 +56,11 @@ import { pickDurationVerb } from "./duration-summary.js";
|
|
|
61
56
|
import { toErrorItem } from "./error-item.js";
|
|
62
57
|
import { addLinesChanged, buildSessionSummary, createSessionStats, recordServerToolCall, recordToolEnd, recordTurnEnd, } from "./session-summary.js";
|
|
63
58
|
import { compactHistory, getNextGeneratedItemId, isActiveItem, isSameAssistantText, normalizeAssistantText, partitionCompleted, pinStreamingTextBeforeToolBoundary, removeItemsWithIds, uniqueItemsById, } from "./item-helpers.js";
|
|
64
|
-
|
|
59
|
+
import { IDEAL_HOOK_NOTICE_TEXT, lastVisibleTranscriptItem } from "./app-items.js";
|
|
60
|
+
export { buildUserContentWithAttachments, routePromptCommandInput } from "./prompt-routing.js";
|
|
65
61
|
export { getNextThinkingLevel } from "./thinking-level.js";
|
|
66
|
-
export {
|
|
67
|
-
export { getChatControlsLayoutDecision, getDoneFlushDecision, getGoalActivationPaneTransition, getGoalSetupFinishedPaneTransition, getGoalSetupPaneTransitionAfterRun, getScrollStabilizationDecision, getStaticHistoryKey, hasParagraphBreakLiveUserMessage, isTallLiveUserMessage, nextGoalModeAfterAgentDone, shouldHideHistoryForOverlayView, shouldHideStaticItemsForOverlayView, shouldResetUIForGoalSetupPaneTransition, shouldStabilizeOverlayPaneRerender, shouldTopSpaceAfterPrintedAgentBoundary, shouldTopSpaceAssistantAfterToolBoundary, shouldTopSpaceStreamingAssistant, } from "./layout-decisions.js";
|
|
62
|
+
export { getChatControlsLayoutDecision, getDoneFlushDecision, getScrollStabilizationDecision, getStaticHistoryKey, hasParagraphBreakLiveUserMessage, isTallLiveUserMessage, shouldHideHistoryForOverlayView, shouldHideStaticItemsForOverlayView, shouldStabilizeOverlayPaneRerender, shouldTopSpaceAfterPrintedAgentBoundary, shouldTopSpaceAssistantAfterToolBoundary, shouldTopSpaceStreamingAssistant, } from "./layout-decisions.js";
|
|
68
63
|
export { getNextGeneratedItemId, isActiveItem, partitionCompleted, pinStreamingTextBeforeToolBoundary, } from "./item-helpers.js";
|
|
69
|
-
export { buildGoalUserPauseRun, goalRunNeedsExplicitContinuationAfterWorker, shouldKeepGoalRunTrackedAfterDecision, shouldRunGoalTaskInMainCheckout, } from "./goal-run-helpers.js";
|
|
70
64
|
/** Tools that get aggregated into a single compact group when possible. */
|
|
71
65
|
const AGGREGATABLE_TOOLS = new Set([
|
|
72
66
|
"read",
|
|
@@ -131,29 +125,26 @@ export function App(props) {
|
|
|
131
125
|
return [{ kind: "banner", id: "banner" }];
|
|
132
126
|
});
|
|
133
127
|
// Items from the current/last turn — rendered in the live area so they stay visible.
|
|
134
|
-
// Seed from sessionStore so
|
|
135
|
-
//
|
|
128
|
+
// Seed from sessionStore so live output
|
|
129
|
+
// survives pane/overlay/resize remounts before it is finalized.
|
|
136
130
|
const [liveItems, setLiveItems] = useState(() => {
|
|
137
131
|
const restoredLiveItems = uniqueItemsById(props.sessionStore?.liveItems ?? []);
|
|
138
132
|
const restoredHistoryIds = new Set(history.map((item) => item.id));
|
|
139
133
|
return removeItemsWithIds(restoredLiveItems, restoredHistoryIds);
|
|
140
134
|
});
|
|
135
|
+
// Rolling feed of recent tool actions for the pinned LiveToolPanel. Kept
|
|
136
|
+
// separate from `liveItems` (the scrollback record) so tool calls mutate in
|
|
137
|
+
// place above the activity bar instead of spamming the transcript.
|
|
138
|
+
const [liveToolFeed, setLiveToolFeed] = useState([]);
|
|
141
139
|
// overlay seeded from sessionStore (lives across remount). Falls back to
|
|
142
140
|
// props.initialOverlay (CLI launched with one), then null.
|
|
143
141
|
const [overlay, setOverlay] = useState(props.sessionStore?.overlay ?? props.initialOverlay ?? null);
|
|
144
|
-
const [goalStatusEntries, setGoalStatusEntries] = useState(props.sessionStore?.goalStatusEntries ?? []);
|
|
145
142
|
const [updatePending, setUpdatePending] = useState(() => getPendingUpdate(props.version) !== null);
|
|
146
143
|
// Signal that pushes text into the InputArea composer (e.g. restoring queued
|
|
147
144
|
// messages after an interrupt). Bumping `nonce` triggers the injection even
|
|
148
145
|
// when the text is identical to a prior restore.
|
|
149
146
|
const [composerInject, setComposerInject] = useState(null);
|
|
150
147
|
const agentRunningRef = useRef(false);
|
|
151
|
-
const runningGoalIdsRef = useRef(new Set());
|
|
152
|
-
const activeVerifierRunIdsRef = useRef(new Set());
|
|
153
|
-
const queuedGoalSyntheticEventsRef = useRef(0);
|
|
154
|
-
const goalContinuationFlightsRef = useRef(new Set());
|
|
155
|
-
const goalContinuationRecentChoicesRef = useRef(new Map());
|
|
156
|
-
const startGoalRunRef = useRef(() => { });
|
|
157
148
|
const [runAllTasks, setRunAllTasks] = useState(props.sessionStore?.runAllTasks ?? false);
|
|
158
149
|
const runAllTasksRef = useRef(props.sessionStore?.runAllTasks ?? false);
|
|
159
150
|
const startTaskRef = useRef(() => { });
|
|
@@ -174,7 +165,6 @@ export function App(props) {
|
|
|
174
165
|
const [doneStatus, setDoneStatus] = useState(props.sessionStore?.doneStatus ?? null);
|
|
175
166
|
// Suppress "done" status when a plan overlay is about to open
|
|
176
167
|
const planOverlayPendingRef = useRef(false);
|
|
177
|
-
const goalSetupPanePendingRef = useRef(false);
|
|
178
168
|
const [gitBranch, setGitBranch] = useState(null);
|
|
179
169
|
const [currentModel, setCurrentModel] = useState(props.model);
|
|
180
170
|
const [currentProvider, setCurrentProvider] = useState(props.provider);
|
|
@@ -185,8 +175,6 @@ export function App(props) {
|
|
|
185
175
|
const [renderMarkdown, setRenderMarkdown] = useState(true);
|
|
186
176
|
const messagesRef = useRef(props.sessionStore?.messages ?? props.messages);
|
|
187
177
|
const [planAutoExpand, setPlanAutoExpand] = useState(props.sessionStore?.planAutoExpand ?? false);
|
|
188
|
-
const [goalAutoExpand, setGoalAutoExpand] = useState(props.sessionStore?.goalAutoExpand ?? false);
|
|
189
|
-
const goalAutoExpandRef = useRef(props.sessionStore?.goalAutoExpand ?? false);
|
|
190
178
|
const approvedPlanPathRef = useRef(props.sessionStore?.approvedPlanPath);
|
|
191
179
|
const planStepsRef = useRef(props.sessionStore?.planSteps ?? []);
|
|
192
180
|
const [planSteps, setPlanSteps] = useState(props.sessionStore?.planSteps ?? []);
|
|
@@ -197,7 +185,7 @@ export function App(props) {
|
|
|
197
185
|
const followUpNudgesRef = useRef({ step: 0, count: 0 });
|
|
198
186
|
// Seed the per-item ID counter so it doesn't collide with IDs already in
|
|
199
187
|
// sessionStore.history (which survives remount). Without this, a remount
|
|
200
|
-
// (resize, overlay toggle,
|
|
188
|
+
// (resize, overlay toggle, task pane open, etc.) starts the counter at 0
|
|
201
189
|
// and new items generate ids "ui-0", "ui-1", "ui-2"… that collide with
|
|
202
190
|
// the same ids from the previous mount, triggering React's duplicate-key
|
|
203
191
|
// warning and causing duplicate/omitted renders.
|
|
@@ -210,6 +198,8 @@ export function App(props) {
|
|
|
210
198
|
const persistedIndexRef = useRef(messagesRef.current.length);
|
|
211
199
|
const sessionStatsRef = useRef(props.sessionStore?.sessionStats ??
|
|
212
200
|
createSessionStats({ sessionId: props.sessionStore?.sessionId ?? props.sessionId }));
|
|
201
|
+
const [idealReviewEnabled, setIdealReviewEnabled] = useState(props.sessionStore?.idealReviewEnabled ?? props.idealReviewEnabled ?? true);
|
|
202
|
+
const idealReviewEnabledRef = useRef(idealReviewEnabled);
|
|
213
203
|
/** Last actual API-reported input token count (from turn_end). */
|
|
214
204
|
const lastActualTokensRef = useRef(0);
|
|
215
205
|
/** Timestamp (ms) when lastActualTokensRef was last updated by turn_end. */
|
|
@@ -235,35 +225,15 @@ export function App(props) {
|
|
|
235
225
|
*/
|
|
236
226
|
const triggerAutoSetupRef = useRef(async () => { });
|
|
237
227
|
const getId = () => `ui-${nextIdRef.current++}`;
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}, []);
|
|
244
|
-
const goalNumberForRun = useCallback((runId) => Math.max(1, goalStatusEntries.findIndex((entry) => entry.runId === runId) + 1), [goalStatusEntries]);
|
|
245
|
-
const clearGoalStatusEntry = useCallback((runId) => {
|
|
246
|
-
setGoalStatusEntries((prev) => {
|
|
247
|
-
const next = removeGoalStatusEntry(prev, runId);
|
|
248
|
-
if (props.sessionStore)
|
|
249
|
-
props.sessionStore.goalStatusEntries = next;
|
|
250
|
-
return next;
|
|
251
|
-
});
|
|
252
|
-
}, [props.sessionStore]);
|
|
253
|
-
const upsertGoalStatusEntry = useCallback((entry) => {
|
|
254
|
-
setGoalStatusEntries((prev) => {
|
|
255
|
-
const next = syncGoalStatusEntries(prev, entry);
|
|
256
|
-
if (props.sessionStore)
|
|
257
|
-
props.sessionStore.goalStatusEntries = next;
|
|
258
|
-
return next;
|
|
259
|
-
});
|
|
260
|
-
}, [props.sessionStore]);
|
|
228
|
+
useEffect(() => {
|
|
229
|
+
idealReviewEnabledRef.current = idealReviewEnabled;
|
|
230
|
+
if (props.sessionStore)
|
|
231
|
+
props.sessionStore.idealReviewEnabled = idealReviewEnabled;
|
|
232
|
+
}, [idealReviewEnabled, props.sessionStore]);
|
|
261
233
|
const sessionStore = props.sessionStore;
|
|
262
|
-
const {
|
|
263
|
-
initialGoalMode: props.sessionStore?.goalMode ?? props.goalModeRef?.current ?? "off",
|
|
234
|
+
const { planMode, rebuildSystemPrompt, replaceSystemPrompt, setPlanModeAndPrompt } = useModeState({
|
|
264
235
|
initialPlanMode: props.sessionStore?.planMode ?? props.planModeRef?.current ?? false,
|
|
265
236
|
skills: props.skills,
|
|
266
|
-
goalModeRef: props.goalModeRef,
|
|
267
237
|
planModeRef: props.planModeRef,
|
|
268
238
|
sessionStore: props.sessionStore,
|
|
269
239
|
cwdRef,
|
|
@@ -272,9 +242,6 @@ export function App(props) {
|
|
|
272
242
|
approvedPlanPathRef,
|
|
273
243
|
injectedLanguagesRef,
|
|
274
244
|
messagesRef,
|
|
275
|
-
runningGoalIdsRef,
|
|
276
|
-
activeVerifierRunIdsRef,
|
|
277
|
-
queuedGoalSyntheticEventsRef,
|
|
278
245
|
});
|
|
279
246
|
const { pendingHistoryFlushRef, streamedAssistantFlushRef, queueFlush, finalizeSubmittedUserItem, clearPendingHistory, } = useTranscriptHistory({
|
|
280
247
|
// In fullscreen alt-screen mode the transcript renders inside Ink (the
|
|
@@ -350,19 +317,6 @@ export function App(props) {
|
|
|
350
317
|
if (sessionStore)
|
|
351
318
|
sessionStore.overlay = overlay;
|
|
352
319
|
}, [overlay, sessionStore]);
|
|
353
|
-
useEffect(() => {
|
|
354
|
-
goalAutoExpandRef.current = goalAutoExpand;
|
|
355
|
-
if (sessionStore)
|
|
356
|
-
sessionStore.goalAutoExpand = goalAutoExpand;
|
|
357
|
-
}, [goalAutoExpand, sessionStore]);
|
|
358
|
-
useEffect(() => {
|
|
359
|
-
if (sessionStore)
|
|
360
|
-
sessionStore.goalStatusEntries = goalStatusEntries;
|
|
361
|
-
}, [goalStatusEntries, sessionStore]);
|
|
362
|
-
useEffect(() => {
|
|
363
|
-
if (sessionStore)
|
|
364
|
-
sessionStore.goalMode = goalMode;
|
|
365
|
-
}, [goalMode, sessionStore]);
|
|
366
320
|
useEffect(() => {
|
|
367
321
|
if (sessionStore)
|
|
368
322
|
sessionStore.planMode = planMode;
|
|
@@ -386,35 +340,6 @@ export function App(props) {
|
|
|
386
340
|
useEffect(() => {
|
|
387
341
|
getGitBranch(displayedCwd).then(setGitBranch);
|
|
388
342
|
}, [displayedCwd]);
|
|
389
|
-
useEffect(() => {
|
|
390
|
-
let cancelled = false;
|
|
391
|
-
const refreshGoalCount = () => {
|
|
392
|
-
void reconcileActiveGoalRuns(props.cwd, {
|
|
393
|
-
isWorkerActive: (workerId) => listGoalWorkers(props.cwd).some((worker) => worker.id === workerId && worker.status === "running"),
|
|
394
|
-
}).then(({ runs }) => {
|
|
395
|
-
if (cancelled)
|
|
396
|
-
return;
|
|
397
|
-
setHistory((prev) => completedItemsWithDurableGoalTerminalProgress(prev, runs));
|
|
398
|
-
setGoalStatusEntries((prev) => {
|
|
399
|
-
const next = reconcileGoalStatusEntriesWithRuns(prev, runs, {
|
|
400
|
-
isWorkerActive: (workerId, run) => listGoalWorkers(props.cwd).some((worker) => worker.id === workerId &&
|
|
401
|
-
worker.goalRunId === run.id &&
|
|
402
|
-
worker.status === "running"),
|
|
403
|
-
isVerifierActive: (run) => activeVerifierRunIdsRef.current.has(run.id),
|
|
404
|
-
});
|
|
405
|
-
if (props.sessionStore)
|
|
406
|
-
props.sessionStore.goalStatusEntries = next;
|
|
407
|
-
return next;
|
|
408
|
-
});
|
|
409
|
-
});
|
|
410
|
-
};
|
|
411
|
-
refreshGoalCount();
|
|
412
|
-
const interval = setInterval(refreshGoalCount, 1000);
|
|
413
|
-
return () => {
|
|
414
|
-
cancelled = true;
|
|
415
|
-
clearInterval(interval);
|
|
416
|
-
};
|
|
417
|
-
}, [props.cwd]);
|
|
418
343
|
// Periodic update check during long sessions
|
|
419
344
|
useEffect(() => {
|
|
420
345
|
startPeriodicUpdateCheck(props.version, (msg) => {
|
|
@@ -434,10 +359,6 @@ export function App(props) {
|
|
|
434
359
|
useEffect(() => {
|
|
435
360
|
currentToolsRef.current = currentTools;
|
|
436
361
|
}, [currentTools]);
|
|
437
|
-
const setActiveGoalReferences = useCallback((references) => {
|
|
438
|
-
if (props.goalReferencesRef)
|
|
439
|
-
props.goalReferencesRef.current = references;
|
|
440
|
-
}, [props.goalReferencesRef]);
|
|
441
362
|
useEffect(() => {
|
|
442
363
|
if (!props.connectInitialMcpTools)
|
|
443
364
|
return;
|
|
@@ -647,6 +568,22 @@ export function App(props) {
|
|
|
647
568
|
projectId: activeProjectId,
|
|
648
569
|
resolveCredentials,
|
|
649
570
|
transformContext,
|
|
571
|
+
getIdealReviewMessage: (stats) => {
|
|
572
|
+
if (!idealReviewEnabledRef.current)
|
|
573
|
+
return null;
|
|
574
|
+
const decision = evaluateIdealReview(stats);
|
|
575
|
+
if (!decision.shouldReview)
|
|
576
|
+
return null;
|
|
577
|
+
log("INFO", "ideal", "Injecting ideal review before final response", {
|
|
578
|
+
score: String(decision.score),
|
|
579
|
+
reasons: decision.reasons.join(", "),
|
|
580
|
+
});
|
|
581
|
+
setLiveItems((prev) => [
|
|
582
|
+
...prev,
|
|
583
|
+
{ kind: "ideal_hook", text: IDEAL_HOOK_NOTICE_TEXT, id: getId() },
|
|
584
|
+
]);
|
|
585
|
+
return buildIdealReviewMessage(decision.reasons);
|
|
586
|
+
},
|
|
650
587
|
}, {
|
|
651
588
|
onComplete: useCallback(() => {
|
|
652
589
|
persistNewMessages();
|
|
@@ -710,9 +647,6 @@ export function App(props) {
|
|
|
710
647
|
resolveCredentials,
|
|
711
648
|
]),
|
|
712
649
|
onTurnText: useCallback((text, thinking, thinkingMs) => {
|
|
713
|
-
if (goalModeStateRef.current === "planner") {
|
|
714
|
-
return;
|
|
715
|
-
}
|
|
716
650
|
const hadStreamedAssistantFlush = streamedAssistantFlushRef.current.flushedChars > 0;
|
|
717
651
|
const unflushedAssistantText = text.slice(streamedAssistantFlushRef.current.flushedChars);
|
|
718
652
|
// Track [DONE:n] markers for plan step progress
|
|
@@ -797,6 +731,9 @@ export function App(props) {
|
|
|
797
731
|
log("INFO", "tool", `Tool call started: ${name}`, { id: toolCallId });
|
|
798
732
|
const startedAt = Date.now();
|
|
799
733
|
const animateUntil = startedAt + RUNNING_INDICATOR_ANIMATION_MS;
|
|
734
|
+
// Feed the pinned LiveToolPanel. Keep a small tail (panel shows the
|
|
735
|
+
// last few rows) so memory stays bounded across long sessions.
|
|
736
|
+
setLiveToolFeed((prev) => [...prev, { id: toolCallId, name, args, status: "running" }].slice(-(LIVE_TOOL_PANEL_ROWS * 2)));
|
|
800
737
|
const appendToolStart = (prev) => {
|
|
801
738
|
const visible = pinStreamingTextBeforeToolBoundary({
|
|
802
739
|
items: prev,
|
|
@@ -920,6 +857,9 @@ export function App(props) {
|
|
|
920
857
|
}, []),
|
|
921
858
|
onToolEnd: useCallback((toolCallId, name, result, isError, durationMs, details) => {
|
|
922
859
|
recordToolEnd(sessionStatsRef.current, name, isError, durationMs);
|
|
860
|
+
setLiveToolFeed((prev) => prev.map((entry) => entry.id === toolCallId
|
|
861
|
+
? { ...entry, status: "done", isError, result, details }
|
|
862
|
+
: entry));
|
|
923
863
|
if (name === "edit" && !isError) {
|
|
924
864
|
const diff = details?.diff ?? result;
|
|
925
865
|
addLinesChanged(sessionStatsRef.current, {
|
|
@@ -1155,10 +1095,8 @@ export function App(props) {
|
|
|
1155
1095
|
});
|
|
1156
1096
|
const doneDecision = getDoneFlushDecision({
|
|
1157
1097
|
planOverlayPending: planOverlayPendingRef.current,
|
|
1158
|
-
goalMode: goalModeStateRef.current,
|
|
1159
|
-
goalAutoExpand: goalAutoExpandRef.current,
|
|
1160
1098
|
});
|
|
1161
|
-
// Don't show "done" status when plan
|
|
1099
|
+
// Don't show "done" status when the plan review pane is about to open —
|
|
1162
1100
|
// the agent loop finished but we're waiting for user approval/review.
|
|
1163
1101
|
// Still flush live transcript rows before the pane remounts; otherwise
|
|
1164
1102
|
// setup output remains in ephemeral liveItems and appears to vanish.
|
|
@@ -1171,7 +1109,7 @@ export function App(props) {
|
|
|
1171
1109
|
// history at this moment writes many scrollback rows while the footer is
|
|
1172
1110
|
// still mounted, which visibly pushes the input/footer upward. The final
|
|
1173
1111
|
// response is flushed on the next submit before the new prompt is shown.
|
|
1174
|
-
// Non-chat overlay transitions still flush so setup/plan
|
|
1112
|
+
// Non-chat overlay transitions still flush so setup/plan output
|
|
1175
1113
|
// does not vanish during remounts.
|
|
1176
1114
|
if (doneDecision.flushLiveItems && !doneDecision.showDoneStatus) {
|
|
1177
1115
|
setLiveItems((prev) => {
|
|
@@ -1180,15 +1118,6 @@ export function App(props) {
|
|
|
1180
1118
|
return prev;
|
|
1181
1119
|
});
|
|
1182
1120
|
}
|
|
1183
|
-
const nextGoalMode = nextGoalModeAfterAgentDone({
|
|
1184
|
-
currentMode: goalModeStateRef.current,
|
|
1185
|
-
runningGoalIds: runningGoalIdsRef.current.size,
|
|
1186
|
-
queuedSyntheticEvents: queuedGoalSyntheticEventsRef.current,
|
|
1187
|
-
activeContinuationFlights: goalContinuationFlightsRef.current.size,
|
|
1188
|
-
});
|
|
1189
|
-
if (nextGoalMode !== goalModeStateRef.current) {
|
|
1190
|
-
void setGoalModeAndPrompt(nextGoalMode);
|
|
1191
|
-
}
|
|
1192
1121
|
// Run-all: auto-start next pending task after a short delay.
|
|
1193
1122
|
if (runAllTasksRef.current) {
|
|
1194
1123
|
setTimeout(() => {
|
|
@@ -1204,11 +1133,6 @@ export function App(props) {
|
|
|
1204
1133
|
}
|
|
1205
1134
|
}, 500);
|
|
1206
1135
|
}
|
|
1207
|
-
// Goal loop: after the orchestrator handles a worker/verifier event,
|
|
1208
|
-
// continue the same Goal automatically until it reaches a terminal state.
|
|
1209
|
-
for (const runId of [...runningGoalIdsRef.current]) {
|
|
1210
|
-
setTimeout(() => continueGoalRun(runId), 500);
|
|
1211
|
-
}
|
|
1212
1136
|
// Pixel fix: observe branch + commits, patch status, optionally pick
|
|
1213
1137
|
// up the next open error if run-all is active.
|
|
1214
1138
|
const pendingFix = currentPixelFixRef.current;
|
|
@@ -1244,16 +1168,11 @@ export function App(props) {
|
|
|
1244
1168
|
}
|
|
1245
1169
|
})();
|
|
1246
1170
|
}
|
|
1247
|
-
}, [
|
|
1171
|
+
}, []),
|
|
1248
1172
|
onAborted: useCallback(() => {
|
|
1249
1173
|
log("WARN", "agent", "Agent run aborted by user");
|
|
1250
1174
|
setRunAllPixel(false);
|
|
1251
1175
|
currentPixelFixRef.current = null;
|
|
1252
|
-
queuedGoalSyntheticEventsRef.current = 0;
|
|
1253
|
-
goalSetupPanePendingRef.current = false;
|
|
1254
|
-
setActiveGoalReferences(undefined);
|
|
1255
|
-
if (goalModeStateRef.current !== "off")
|
|
1256
|
-
void setGoalModeAndPrompt("off");
|
|
1257
1176
|
setDoneStatus(null);
|
|
1258
1177
|
setLiveItems((prev) => {
|
|
1259
1178
|
const next = prev.map((item) => {
|
|
@@ -1296,42 +1215,16 @@ export function App(props) {
|
|
|
1296
1215
|
});
|
|
1297
1216
|
return [...next, { kind: "stopped", text: "Request was stopped.", id: getId() }];
|
|
1298
1217
|
});
|
|
1299
|
-
}, [
|
|
1218
|
+
}, []),
|
|
1300
1219
|
onQueuedStart: useCallback((content) => {
|
|
1301
1220
|
// When a queued message starts processing, show it as a UserItem
|
|
1302
|
-
// and flush prior items to history.
|
|
1303
|
-
// from the transcript but still routed through the main agent context.
|
|
1221
|
+
// and flush prior items to history.
|
|
1304
1222
|
const displayText = typeof content === "string"
|
|
1305
1223
|
? content
|
|
1306
1224
|
: content
|
|
1307
1225
|
.filter((c) => c.type === "text")
|
|
1308
1226
|
.map((c) => c.text)
|
|
1309
1227
|
.join("\n");
|
|
1310
|
-
if (isGoalSyntheticEvent(displayText)) {
|
|
1311
|
-
queuedGoalSyntheticEventsRef.current = Math.max(0, queuedGoalSyntheticEventsRef.current - 1);
|
|
1312
|
-
void setGoalModeAndPrompt("coordinator");
|
|
1313
|
-
const eventInfo = parseGoalSyntheticEvent(displayText);
|
|
1314
|
-
// Write-then-clear: keep the rows mounted and let the flush drain
|
|
1315
|
-
// print them to scrollback before removing them, so they don't blink
|
|
1316
|
-
// out of the live area a frame before reappearing in scrollback.
|
|
1317
|
-
setLiveItems((prev) => {
|
|
1318
|
-
if (prev.length > 0)
|
|
1319
|
-
queueFlush(prev);
|
|
1320
|
-
return prev;
|
|
1321
|
-
});
|
|
1322
|
-
setDoneStatus(null);
|
|
1323
|
-
appendGoalProgress({
|
|
1324
|
-
kind: "goal_progress",
|
|
1325
|
-
phase: "orchestrator_reviewing",
|
|
1326
|
-
title: "Orchestrator reviewing Goal update",
|
|
1327
|
-
detail: eventInfo?.kind === "worker"
|
|
1328
|
-
? `Worker ${eventInfo.worker ?? "finished"} reported back${eventInfo.task ? ` on ${eventInfo.task}` : ""}. Inspecting Goal state.`
|
|
1329
|
-
: `Verifier reported ${eventInfo?.status ?? "status"}. Inspecting evidence and next action.`,
|
|
1330
|
-
workerId: eventInfo?.worker,
|
|
1331
|
-
status: eventInfo?.status,
|
|
1332
|
-
});
|
|
1333
|
-
return;
|
|
1334
|
-
}
|
|
1335
1228
|
const imageCount = typeof content === "string"
|
|
1336
1229
|
? undefined
|
|
1337
1230
|
: content.filter((c) => c.type === "image").length || undefined;
|
|
@@ -1344,7 +1237,7 @@ export function App(props) {
|
|
|
1344
1237
|
setLastUserMessage(displayText);
|
|
1345
1238
|
setDoneStatus(null);
|
|
1346
1239
|
finalizeSubmittedUserItem(userItem);
|
|
1347
|
-
}, [
|
|
1240
|
+
}, [finalizeSubmittedUserItem]),
|
|
1348
1241
|
// Inject a "continue with the next step" follow-up when the agent
|
|
1349
1242
|
// would otherwise stop mid-plan. The prompt-only instruction wasn't
|
|
1350
1243
|
// enough — some models (notably Opus) treat each [DONE:n] as a
|
|
@@ -1461,27 +1354,19 @@ export function App(props) {
|
|
|
1461
1354
|
}, [currentModel, currentProvider, displayedCwd, writeStdout]);
|
|
1462
1355
|
// Consume pending post-remount work once on mount. Set by resetUI options
|
|
1463
1356
|
// for paths that remount AND immediately drive work (plan accept/reject,
|
|
1464
|
-
// pixel fix,
|
|
1357
|
+
// pixel fix, plan accept/reject). The work survives the unmount because
|
|
1465
1358
|
// it lives in renderApp's closure (sessionStore), not React state.
|
|
1466
1359
|
useEffect(() => {
|
|
1467
1360
|
if (pendingActionConsumedRef.current)
|
|
1468
1361
|
return;
|
|
1469
1362
|
const action = sessionStore?.pendingAction;
|
|
1470
|
-
|
|
1471
|
-
if (!action && !pendingGoalRun)
|
|
1363
|
+
if (!action)
|
|
1472
1364
|
return;
|
|
1473
1365
|
pendingActionConsumedRef.current = true;
|
|
1474
1366
|
if (sessionStore) {
|
|
1475
1367
|
sessionStore.pendingAction = undefined;
|
|
1476
|
-
sessionStore.pendingGoalRun = undefined;
|
|
1477
1368
|
}
|
|
1478
1369
|
setDoneStatus(null);
|
|
1479
|
-
if (pendingGoalRun) {
|
|
1480
|
-
startGoalRunRef.current(pendingGoalRun);
|
|
1481
|
-
return;
|
|
1482
|
-
}
|
|
1483
|
-
if (!action)
|
|
1484
|
-
return;
|
|
1485
1370
|
if (action.planEvent) {
|
|
1486
1371
|
const ev = action.planEvent;
|
|
1487
1372
|
setLiveItems((prev) => [
|
|
@@ -1516,6 +1401,26 @@ export function App(props) {
|
|
|
1516
1401
|
// has not grown.
|
|
1517
1402
|
await applyLanguageDetectionRef.current("input");
|
|
1518
1403
|
}
|
|
1404
|
+
if (trimmed === "/ideal-on" || trimmed === "/ideal-off") {
|
|
1405
|
+
const next = trimmed === "/ideal-on";
|
|
1406
|
+
setIdealReviewEnabled(next);
|
|
1407
|
+
if (props.settingsFile) {
|
|
1408
|
+
const sm = new SettingsManager(props.settingsFile);
|
|
1409
|
+
await sm.load();
|
|
1410
|
+
await sm.set("idealReviewEnabled", next);
|
|
1411
|
+
}
|
|
1412
|
+
setLiveItems((prev) => [
|
|
1413
|
+
...prev,
|
|
1414
|
+
{
|
|
1415
|
+
kind: "info",
|
|
1416
|
+
text: next
|
|
1417
|
+
? "Ideal review enabled. Use /ideal-off to disable it."
|
|
1418
|
+
: "Ideal review disabled. Use /ideal-on to enable it.",
|
|
1419
|
+
id: getId(),
|
|
1420
|
+
},
|
|
1421
|
+
]);
|
|
1422
|
+
return;
|
|
1423
|
+
}
|
|
1519
1424
|
// /rewind — open the checkpoint picker (needs React state + the store).
|
|
1520
1425
|
if (trimmed === "/rewind") {
|
|
1521
1426
|
const store = props.checkpointStore;
|
|
@@ -1604,36 +1509,20 @@ export function App(props) {
|
|
|
1604
1509
|
void replaceSystemPrompt({ clearApprovedPlan: true });
|
|
1605
1510
|
setLiveItems([{ kind: "plan_event", event: "dismissed", id: getId() }]);
|
|
1606
1511
|
},
|
|
1607
|
-
openGoalsPicker: () => {
|
|
1608
|
-
taskPicker.close();
|
|
1609
|
-
goalPicker.openPicker();
|
|
1610
|
-
},
|
|
1611
1512
|
})) {
|
|
1612
1513
|
return;
|
|
1613
1514
|
}
|
|
1614
1515
|
if (await submitPromptCommand({
|
|
1615
1516
|
trimmed,
|
|
1616
1517
|
inputImages,
|
|
1617
|
-
cwd: props.cwd,
|
|
1618
1518
|
currentModel,
|
|
1619
1519
|
customCommands,
|
|
1620
|
-
messagesRef,
|
|
1621
|
-
goalSetupPanePendingRef,
|
|
1622
|
-
goalModeStateRef,
|
|
1623
|
-
goalAutoExpandRef,
|
|
1624
|
-
setActiveGoalReferences,
|
|
1625
1520
|
setLastUserMessage,
|
|
1626
1521
|
setDoneStatus,
|
|
1627
1522
|
finalizeSubmittedUserItem,
|
|
1628
|
-
setGoalModeAndPrompt,
|
|
1629
1523
|
runAgent: (content) => agentLoop.run(content),
|
|
1630
|
-
appendGoalAgentTransition,
|
|
1631
1524
|
setLiveItems,
|
|
1632
1525
|
getId,
|
|
1633
|
-
setGoalAutoExpand,
|
|
1634
|
-
setPlanAutoExpand,
|
|
1635
|
-
closeTaskPicker: taskPicker.close,
|
|
1636
|
-
openGoalPicker: goalPicker.openPicker,
|
|
1637
1526
|
reloadCustomCommands,
|
|
1638
1527
|
})) {
|
|
1639
1528
|
return;
|
|
@@ -1731,7 +1620,6 @@ export function App(props) {
|
|
|
1731
1620
|
}
|
|
1732
1621
|
}, [
|
|
1733
1622
|
agentLoop,
|
|
1734
|
-
appendGoalAgentTransition,
|
|
1735
1623
|
compactConversation,
|
|
1736
1624
|
currentModel,
|
|
1737
1625
|
finalizeSubmittedUserItem,
|
|
@@ -1744,8 +1632,6 @@ export function App(props) {
|
|
|
1744
1632
|
showSessionSummaryAndExit,
|
|
1745
1633
|
reloadCustomCommands,
|
|
1746
1634
|
replaceSystemPrompt,
|
|
1747
|
-
setActiveGoalReferences,
|
|
1748
|
-
setGoalModeAndPrompt,
|
|
1749
1635
|
]);
|
|
1750
1636
|
const handleDoubleExit = useDoublePress(setExitPending, showSessionSummaryAndExit);
|
|
1751
1637
|
const handleAbort = useCallback(() => {
|
|
@@ -1902,7 +1788,6 @@ export function App(props) {
|
|
|
1902
1788
|
};
|
|
1903
1789
|
const promptOrder = [
|
|
1904
1790
|
// Project audits / one-shot analysis
|
|
1905
|
-
"goal",
|
|
1906
1791
|
"init",
|
|
1907
1792
|
"expand",
|
|
1908
1793
|
"bullet-proof",
|
|
@@ -1927,6 +1812,14 @@ export function App(props) {
|
|
|
1927
1812
|
{ name: "compact", aliases: ["c"], description: "Compact context", sectionTitle: "built-in" },
|
|
1928
1813
|
{ name: "clear", aliases: [], description: "Clear session", sectionTitle: "built-in" },
|
|
1929
1814
|
{ name: "theme", aliases: ["t"], description: "Switch theme", sectionTitle: "built-in" },
|
|
1815
|
+
{
|
|
1816
|
+
name: idealReviewEnabled ? "ideal-off" : "ideal-on",
|
|
1817
|
+
aliases: [],
|
|
1818
|
+
description: idealReviewEnabled
|
|
1819
|
+
? "Disable pre-final ideal review"
|
|
1820
|
+
: "Enable pre-final ideal review",
|
|
1821
|
+
sectionTitle: "built-in",
|
|
1822
|
+
},
|
|
1930
1823
|
{
|
|
1931
1824
|
name: "rewind",
|
|
1932
1825
|
aliases: [],
|
|
@@ -1948,13 +1841,13 @@ export function App(props) {
|
|
|
1948
1841
|
sectionTitle: "built-in",
|
|
1949
1842
|
},
|
|
1950
1843
|
];
|
|
1951
|
-
}, [customCommands]);
|
|
1844
|
+
}, [customCommands, idealReviewEnabled]);
|
|
1952
1845
|
const renderItem = (item, index, items) => renderTranscriptItem({
|
|
1953
1846
|
item,
|
|
1954
1847
|
index,
|
|
1955
1848
|
items,
|
|
1956
|
-
pendingHistoryFlushLastItem: index === 0 ? pendingHistoryFlushRef.current
|
|
1957
|
-
historyLastItem: index === 0 ? history
|
|
1849
|
+
pendingHistoryFlushLastItem: index === 0 ? lastVisibleTranscriptItem(pendingHistoryFlushRef.current) : undefined,
|
|
1850
|
+
historyLastItem: index === 0 ? lastVisibleTranscriptItem(history) : undefined,
|
|
1958
1851
|
version: props.version,
|
|
1959
1852
|
currentModel,
|
|
1960
1853
|
currentProvider,
|
|
@@ -1969,8 +1862,6 @@ export function App(props) {
|
|
|
1969
1862
|
props.sessionStore.overlay = kind;
|
|
1970
1863
|
if (kind !== "plan")
|
|
1971
1864
|
props.sessionStore.planAutoExpand = false;
|
|
1972
|
-
if (kind !== "goal")
|
|
1973
|
-
props.sessionStore.goalAutoExpand = false;
|
|
1974
1865
|
props.resetUI();
|
|
1975
1866
|
}
|
|
1976
1867
|
else {
|
|
@@ -1978,53 +1869,15 @@ export function App(props) {
|
|
|
1978
1869
|
props.sessionStore.overlay = kind;
|
|
1979
1870
|
if (kind !== "plan")
|
|
1980
1871
|
props.sessionStore.planAutoExpand = false;
|
|
1981
|
-
if (kind !== "
|
|
1982
|
-
props.sessionStore.goalAutoExpand = false;
|
|
1983
|
-
if (agentLoop.isRunning && kind !== "goal" && kind !== "plan") {
|
|
1872
|
+
if (agentLoop.isRunning && kind !== "plan") {
|
|
1984
1873
|
props.sessionStore.pendingResetUI = true;
|
|
1985
1874
|
}
|
|
1986
1875
|
}
|
|
1987
1876
|
if (kind !== "plan")
|
|
1988
1877
|
setPlanAutoExpand(false);
|
|
1989
|
-
if (kind !== "goal")
|
|
1990
|
-
setGoalAutoExpand(false);
|
|
1991
1878
|
setOverlay(kind);
|
|
1992
1879
|
}
|
|
1993
1880
|
}, [agentLoop.isRunning, props]);
|
|
1994
|
-
const { continueGoalRun, startGoalRun, pauseGoalRun } = useGoalOrchestration({
|
|
1995
|
-
cwd: props.cwd,
|
|
1996
|
-
resetUI: props.resetUI,
|
|
1997
|
-
sessionStore: props.sessionStore,
|
|
1998
|
-
currentProvider,
|
|
1999
|
-
currentModel,
|
|
2000
|
-
thinkingLevel,
|
|
2001
|
-
agentLoop,
|
|
2002
|
-
appendGoalProgress,
|
|
2003
|
-
goalNumberForRun,
|
|
2004
|
-
clearGoalStatusEntry,
|
|
2005
|
-
upsertGoalStatusEntry,
|
|
2006
|
-
setGoalModeAndPrompt,
|
|
2007
|
-
clearGoalModeIfIdle,
|
|
2008
|
-
agentRunningRef,
|
|
2009
|
-
runningGoalIdsRef,
|
|
2010
|
-
activeVerifierRunIdsRef,
|
|
2011
|
-
queuedGoalSyntheticEventsRef,
|
|
2012
|
-
goalContinuationFlightsRef,
|
|
2013
|
-
goalContinuationRecentChoicesRef,
|
|
2014
|
-
startGoalRunRef,
|
|
2015
|
-
startTaskRef,
|
|
2016
|
-
messagesRef,
|
|
2017
|
-
persistedIndexRef,
|
|
2018
|
-
sessionManagerRef,
|
|
2019
|
-
sessionPathRef,
|
|
2020
|
-
cwdRef,
|
|
2021
|
-
setLiveItems,
|
|
2022
|
-
setHistory,
|
|
2023
|
-
setLastUserMessage,
|
|
2024
|
-
setDoneStatus,
|
|
2025
|
-
getId,
|
|
2026
|
-
clearPendingHistory,
|
|
2027
|
-
});
|
|
2028
1881
|
useEffect(() => {
|
|
2029
1882
|
runAllTasksRef.current = runAllTasks;
|
|
2030
1883
|
if (props.sessionStore)
|
|
@@ -2062,6 +1915,15 @@ export function App(props) {
|
|
|
2062
1915
|
getId,
|
|
2063
1916
|
initialRunAllPixel: props.sessionStore?.runAllPixel ?? false,
|
|
2064
1917
|
});
|
|
1918
|
+
// Reset the live tool feed at the start of each run so the pinned panel only
|
|
1919
|
+
// ever reflects the current turn's activity, not the previous one's.
|
|
1920
|
+
const wasRunningRef = useRef(false);
|
|
1921
|
+
useEffect(() => {
|
|
1922
|
+
if (agentLoop.isRunning && !wasRunningRef.current) {
|
|
1923
|
+
setLiveToolFeed([]);
|
|
1924
|
+
}
|
|
1925
|
+
wasRunningRef.current = agentLoop.isRunning;
|
|
1926
|
+
}, [agentLoop.isRunning]);
|
|
2065
1927
|
const isSkillsView = overlay === "skills";
|
|
2066
1928
|
const isPlanView = overlay === "plan";
|
|
2067
1929
|
const { footerStatusLayout, activityVisible, stallStatusVisible, statusSlotVisible, mainControlsRef, measuredLiveAreaRows, viewportRows, } = useChatLayoutMeasurements({
|
|
@@ -2079,14 +1941,26 @@ export function App(props) {
|
|
|
2079
1941
|
displayedCwd,
|
|
2080
1942
|
gitBranch,
|
|
2081
1943
|
thinkingLevel,
|
|
2082
|
-
goalMode,
|
|
2083
1944
|
exitPending,
|
|
2084
1945
|
taskBarExpanded,
|
|
2085
|
-
|
|
1946
|
+
liveToolFeedCount: liveToolFeed.length,
|
|
2086
1947
|
});
|
|
2087
1948
|
const isPixelView = overlay === "pixel";
|
|
2088
1949
|
const hasLiveAssistantItem = liveItems.some((item) => item.kind === "assistant");
|
|
2089
|
-
const rawVisibleStreamingText =
|
|
1950
|
+
const rawVisibleStreamingText = hasLiveAssistantItem ? "" : agentLoop.streamingText;
|
|
1951
|
+
// Compute the prospective paragraph flush DURING render so the live frame
|
|
1952
|
+
// immediately drops the prefix that is about to be written to scrollback.
|
|
1953
|
+
// The queueFlush below runs in an effect (after paint), so if the live text
|
|
1954
|
+
// were sliced only by the already-committed `flushedChars`, the just-flushed
|
|
1955
|
+
// paragraph would render BOTH in scrollback and live for one frame — that
|
|
1956
|
+
// transient extra height is what shoves the footer up and then back down on
|
|
1957
|
+
// every chunk boundary. Slicing by the prospective flush here keeps the live
|
|
1958
|
+
// frame height monotonic, so the footer never bounces.
|
|
1959
|
+
const alreadyFlushedChars = streamedAssistantFlushRef.current.flushedChars;
|
|
1960
|
+
const pendingFlushChars = rawVisibleStreamingText
|
|
1961
|
+
? splitAssistantStreamingText(rawVisibleStreamingText.slice(alreadyFlushedChars)).flushedText
|
|
1962
|
+
.length
|
|
1963
|
+
: 0;
|
|
2090
1964
|
useEffect(() => {
|
|
2091
1965
|
if (!rawVisibleStreamingText) {
|
|
2092
1966
|
streamedAssistantFlushRef.current = { flushedChars: 0, text: "" };
|
|
@@ -2117,10 +1991,20 @@ export function App(props) {
|
|
|
2117
1991
|
text: rawVisibleStreamingText,
|
|
2118
1992
|
};
|
|
2119
1993
|
}, [rawVisibleStreamingText, queueFlush]);
|
|
2120
|
-
const visibleStreamingText = stripDoneMarkers(rawVisibleStreamingText.slice(
|
|
1994
|
+
const visibleStreamingText = stripDoneMarkers(rawVisibleStreamingText.slice(alreadyFlushedChars + pendingFlushChars));
|
|
2121
1995
|
const lastLiveItem = liveItems.at(-1);
|
|
1996
|
+
// For spacing decisions, the previous row is the last item that actually
|
|
1997
|
+
// RENDERS. Panel-replaced tool items (now shown only in the LiveToolPanel)
|
|
1998
|
+
// render null, so counting them as the boundary inserts a blank separator
|
|
1999
|
+
// above the streamed response with nothing visible above it.
|
|
2000
|
+
const lastVisibleLiveItem = lastVisibleTranscriptItem(liveItems);
|
|
2122
2001
|
const lastPendingHistoryItem = pendingHistoryFlushRef.current.at(-1);
|
|
2123
2002
|
const lastHistoryItem = history.at(-1);
|
|
2003
|
+
// Spacing variants: flushed tool rows render null (LiveToolPanel owns them), so
|
|
2004
|
+
// the streamed/first-live boundary must look past them to the last row that
|
|
2005
|
+
// actually printed — otherwise a tool→assistant separator leaves a phantom gap.
|
|
2006
|
+
const lastVisiblePendingHistoryItem = lastVisibleTranscriptItem(pendingHistoryFlushRef.current);
|
|
2007
|
+
const lastVisibleHistoryItem = lastVisibleTranscriptItem(history);
|
|
2124
2008
|
const previousTranscriptItem = lastPendingHistoryItem ?? lastHistoryItem;
|
|
2125
2009
|
const isAwaitingAssistantAfterUser = agentLoop.isRunning &&
|
|
2126
2010
|
!hasLiveAssistantItem &&
|
|
@@ -2133,14 +2017,14 @@ export function App(props) {
|
|
|
2133
2017
|
isAwaitingAssistantAfterUser);
|
|
2134
2018
|
const shouldTopSpaceStreamingText = shouldTopSpaceStreamingAssistant({
|
|
2135
2019
|
visibleStreamingText,
|
|
2136
|
-
lastLiveItem,
|
|
2137
|
-
lastPendingHistoryItem,
|
|
2138
|
-
lastHistoryItem,
|
|
2020
|
+
lastLiveItem: lastVisibleLiveItem,
|
|
2021
|
+
lastPendingHistoryItem: lastVisiblePendingHistoryItem,
|
|
2022
|
+
lastHistoryItem: lastVisibleHistoryItem,
|
|
2139
2023
|
});
|
|
2140
2024
|
// When earlier paragraphs of THIS response were already flushed to scrollback
|
|
2141
2025
|
// mid-stream, the live remainder is the next paragraph — re-insert the blank
|
|
2142
2026
|
// line that separated them so the live tail lines up with the flushed history.
|
|
2143
|
-
const streamingContinuesFlushed =
|
|
2027
|
+
const streamingContinuesFlushed = alreadyFlushedChars + pendingFlushChars > 0;
|
|
2144
2028
|
// ── Fullscreen alt-screen transcript ───────────────────
|
|
2145
2029
|
// Flatten history + live items + in-flight streaming into the flat ANSI line
|
|
2146
2030
|
// buffer the viewport renders. Reuses the same serializer the legacy
|
|
@@ -2413,70 +2297,9 @@ export function App(props) {
|
|
|
2413
2297
|
setLiveItems((prev) => [...prev, toErrorItem(err, getId())]);
|
|
2414
2298
|
});
|
|
2415
2299
|
};
|
|
2416
|
-
const handleRunGoalFromPicker = (run) => {
|
|
2417
|
-
setDoneStatus(null);
|
|
2418
|
-
appendGoalProgress({
|
|
2419
|
-
kind: "goal_progress",
|
|
2420
|
-
phase: "continuing",
|
|
2421
|
-
title: `Goal run requested: ${run.title}`,
|
|
2422
|
-
detail: "Enter pressed in Ctrl+G; starting the Goal orchestrator.",
|
|
2423
|
-
status: run.status,
|
|
2424
|
-
});
|
|
2425
|
-
log("INFO", "goal", `Goal run requested from Ctrl+G: ${run.title}`, { id: run.id });
|
|
2426
|
-
void (async () => {
|
|
2427
|
-
const latestRun = (await loadGoalRuns(props.cwd)).find((item) => item.id === run.id) ?? run;
|
|
2428
|
-
const requestedAt = new Date().toISOString();
|
|
2429
|
-
const runWithContinuation = await upsertGoalRun(props.cwd, {
|
|
2430
|
-
...latestRun,
|
|
2431
|
-
status: latestRun.status === "running" || latestRun.status === "verifying"
|
|
2432
|
-
? latestRun.status
|
|
2433
|
-
: "ready",
|
|
2434
|
-
continueRequestedAt: requestedAt,
|
|
2435
|
-
blockers: goalHasBlockingPrerequisites(latestRun) ? latestRun.blockers : [],
|
|
2436
|
-
evidence: [
|
|
2437
|
-
...latestRun.evidence,
|
|
2438
|
-
{
|
|
2439
|
-
id: `goal-rerun-${requestedAt}`,
|
|
2440
|
-
kind: "summary",
|
|
2441
|
-
label: "Goal rerun requested",
|
|
2442
|
-
content: "Continuation requested from Ctrl+G; the orchestrator will choose the next eligible Goal action.",
|
|
2443
|
-
createdAt: requestedAt,
|
|
2444
|
-
},
|
|
2445
|
-
],
|
|
2446
|
-
});
|
|
2447
|
-
startGoalRun(runWithContinuation);
|
|
2448
|
-
})().catch((err) => {
|
|
2449
|
-
log("ERROR", "goal", err instanceof Error ? err.message : String(err));
|
|
2450
|
-
setLiveItems((prev) => [...prev, toErrorItem(err, getId(), "Goal")]);
|
|
2451
|
-
});
|
|
2452
|
-
};
|
|
2453
|
-
const handleDeleteGoalSideEffects = async (run) => {
|
|
2454
|
-
runningGoalIdsRef.current.delete(run.id);
|
|
2455
|
-
const latestRun = (await loadGoalRuns(props.cwd)).find((item) => item.id === run.id) ?? run;
|
|
2456
|
-
if (latestRun.activeWorkerId)
|
|
2457
|
-
await stopGoalWorker(latestRun.activeWorkerId);
|
|
2458
|
-
clearGoalStatusEntry(run.id);
|
|
2459
|
-
clearGoalModeIfIdle();
|
|
2460
|
-
};
|
|
2461
|
-
const handleGoalPickerError = (err) => {
|
|
2462
|
-
log("ERROR", "goal", err instanceof Error ? err.message : String(err));
|
|
2463
|
-
setLiveItems((prev) => [...prev, toErrorItem(err, getId(), "Goal")]);
|
|
2464
|
-
};
|
|
2465
|
-
const goalPicker = useGoalPickerController({
|
|
2466
|
-
cwd: props.cwd,
|
|
2467
|
-
onRunGoal: handleRunGoalFromPicker,
|
|
2468
|
-
onDeleteGoalSideEffects: handleDeleteGoalSideEffects,
|
|
2469
|
-
onPauseGoal: pauseGoalRun,
|
|
2470
|
-
onError: handleGoalPickerError,
|
|
2471
|
-
});
|
|
2472
2300
|
const handleToggleTasks = () => {
|
|
2473
|
-
goalPicker.close();
|
|
2474
2301
|
taskPicker.toggle();
|
|
2475
2302
|
};
|
|
2476
|
-
const handleToggleGoalPicker = () => {
|
|
2477
|
-
taskPicker.close();
|
|
2478
|
-
goalPicker.toggle();
|
|
2479
|
-
};
|
|
2480
2303
|
const fullScreenOverlay = isPixelView
|
|
2481
2304
|
? "pixel"
|
|
2482
2305
|
: isSkillsView
|
|
@@ -2487,7 +2310,7 @@ export function App(props) {
|
|
|
2487
2310
|
if (quittingSummary) {
|
|
2488
2311
|
return (_jsx(Box, { flexDirection: "column", width: columns, flexShrink: 0, flexGrow: 0, children: _jsx(SessionSummaryDisplay, { summary: quittingSummary }) }));
|
|
2489
2312
|
}
|
|
2490
|
-
return (_jsx(Box, { flexDirection: "column", width: columns, flexShrink: 0, flexGrow: 0, children: rewindCheckpoints ? (_jsx(RewindOverlay, { checkpoints: rewindCheckpoints, onRestore: handleRewindRestore, onCancel: handleRewindCancel })) : fullScreenOverlay ? (_jsx(FullScreenOverlayRouter, { overlay: fullScreenOverlay, version: props.version, cwd: props.cwd, agentRunning: agentLoop.isRunning, planAutoExpand: planAutoExpand, onClosePixel: handleCloseRemountableOverlay, onPixelFixOne: handlePixelFixOne, onPixelFixAll: handlePixelFixAll, onCloseSkills: handleCloseRemountableOverlay, onClosePlan: handleClosePlanOverlay, onApprovePlan: handleApprovePlan, onRejectPlan: handleRejectPlan })) : (_jsx(ChatScreen, { columns: columns, liveItems: uniqueItemsById(liveItems), renderItem: renderItem, isRunning: agentLoop.isRunning, visibleStreamingText: visibleStreamingText, streamingThinking: agentLoop.streamingThinking, thinkingMs: agentLoop.thinkingMs, reserveStreamingSpacing: shouldReserveStreamingSpacing, renderMarkdown: renderMarkdown, measuredLiveAreaRows: measuredLiveAreaRows, fullscreen: props.fullscreen, rows: rows, transcriptLines: transcriptLines, viewportRows: viewportRows, assistantMarginTop: shouldTopSpaceStreamingText || streamingContinuesFlushed ? 1 : 0, streamingContinuation: streamingContinuesFlushed, controlsRef: mainControlsRef, hiddenQueuedCount: hiddenQueuedCount, queueIndicatorMarginTop: shouldTopSpaceQueueIndicator ? 2 : 1, theme: theme, statusSlotVisible: statusSlotVisible, activityVisible: activityVisible, stallStatusVisible: stallStatusVisible, doneStatus: doneStatus, activityPhase: agentLoop.activityPhase, elapsedMs: agentLoop.elapsedMs, runStartRef: agentLoop.runStartRef, isThinking: agentLoop.isThinking, thinkingLevel: thinkingLevel, tokenEstimate: agentLoop.streamedTokenEstimate, charCountRef: agentLoop.charCountRef, realTokensAccumRef: agentLoop.realTokensAccumRef, lastUserMessage: lastUserMessage, activeToolNames: agentLoop.activeToolCalls.map((tc) => tc.name), retryInfo: agentLoop.retryInfo, planDone: planSteps.filter((s) => s.completed).length, planTotal: planSteps.length, formatDuration: formatDuration, inputControls: {
|
|
2313
|
+
return (_jsx(Box, { flexDirection: "column", width: columns, flexShrink: 0, flexGrow: 0, children: rewindCheckpoints ? (_jsx(RewindOverlay, { checkpoints: rewindCheckpoints, onRestore: handleRewindRestore, onCancel: handleRewindCancel })) : fullScreenOverlay ? (_jsx(FullScreenOverlayRouter, { overlay: fullScreenOverlay, version: props.version, cwd: props.cwd, agentRunning: agentLoop.isRunning, planAutoExpand: planAutoExpand, onClosePixel: handleCloseRemountableOverlay, onPixelFixOne: handlePixelFixOne, onPixelFixAll: handlePixelFixAll, onCloseSkills: handleCloseRemountableOverlay, onClosePlan: handleClosePlanOverlay, onApprovePlan: handleApprovePlan, onRejectPlan: handleRejectPlan })) : (_jsx(ChatScreen, { columns: columns, liveItems: uniqueItemsById(liveItems), renderItem: renderItem, isRunning: agentLoop.isRunning, visibleStreamingText: visibleStreamingText, streamingThinking: agentLoop.streamingThinking, thinkingMs: agentLoop.thinkingMs, reserveStreamingSpacing: shouldReserveStreamingSpacing, renderMarkdown: renderMarkdown, measuredLiveAreaRows: measuredLiveAreaRows, fullscreen: props.fullscreen, rows: rows, transcriptLines: transcriptLines, viewportRows: viewportRows, assistantMarginTop: shouldTopSpaceStreamingText || streamingContinuesFlushed ? 1 : 0, streamingContinuation: streamingContinuesFlushed, controlsRef: mainControlsRef, hiddenQueuedCount: hiddenQueuedCount, queueIndicatorMarginTop: shouldTopSpaceQueueIndicator ? 2 : 1, theme: theme, statusSlotVisible: statusSlotVisible, activityVisible: activityVisible, stallStatusVisible: stallStatusVisible, liveToolFeed: liveToolFeed, doneStatus: doneStatus, activityPhase: agentLoop.activityPhase, elapsedMs: agentLoop.elapsedMs, runStartRef: agentLoop.runStartRef, isThinking: agentLoop.isThinking, thinkingLevel: thinkingLevel, tokenEstimate: agentLoop.streamedTokenEstimate, charCountRef: agentLoop.charCountRef, realTokensAccumRef: agentLoop.realTokensAccumRef, lastUserMessage: lastUserMessage, activeToolNames: agentLoop.activeToolCalls.map((tc) => tc.name), retryInfo: agentLoop.retryInfo, planDone: planSteps.filter((s) => s.completed).length, planTotal: planSteps.length, formatDuration: formatDuration, inputControls: {
|
|
2491
2314
|
onSubmit: handleSubmit,
|
|
2492
2315
|
onAbort: handleAbort,
|
|
2493
2316
|
injectText: composerInject,
|
|
@@ -2495,7 +2318,6 @@ export function App(props) {
|
|
|
2495
2318
|
onDownAtEnd: handleFocusTaskBar,
|
|
2496
2319
|
onShiftTab: handleToggleThinking,
|
|
2497
2320
|
onToggleTasks: handleToggleTasks,
|
|
2498
|
-
onToggleGoal: handleToggleGoalPicker,
|
|
2499
2321
|
onToggleSkills: () => openOverlay("skills"),
|
|
2500
2322
|
onTogglePixel: () => openOverlay("pixel"),
|
|
2501
2323
|
onToggleMarkdown: () => setRenderMarkdown((prev) => !prev),
|
|
@@ -2510,13 +2332,6 @@ export function App(props) {
|
|
|
2510
2332
|
onStart: taskPicker.start,
|
|
2511
2333
|
onRunAll: taskPicker.runAll,
|
|
2512
2334
|
onDelete: taskPicker.deleteTask,
|
|
2513
|
-
},
|
|
2514
|
-
open: goalPicker.open,
|
|
2515
|
-
goals: goalPicker.goals,
|
|
2516
|
-
onClose: goalPicker.close,
|
|
2517
|
-
onRun: goalPicker.run,
|
|
2518
|
-
onDelete: goalPicker.deleteGoal,
|
|
2519
|
-
onPause: goalPicker.pause,
|
|
2520
|
-
}, overlay: overlay, onModelSelect: handleModelSelect, onModelCancel: () => setOverlay(null), loggedInProviders: props.loggedInProviders ?? [currentProvider], currentModel: currentModel, currentProvider: currentProvider, onThemeSelect: handleThemeSelect, onThemeCancel: () => setOverlay(null), currentTheme: theme.name, contextUsed: agentLoop.contextUsed, contextWindowOptions: contextWindowOptions, displayedCwd: displayedCwd, gitBranch: gitBranch, goalMode: goalMode, planMode: planMode, exitPending: exitPending, goalStatusEntries: goalStatusEntries, footerStatusLayout: footerStatusLayout, backgroundTasks: bgTasks, taskBarFocused: taskBarFocused, taskBarExpanded: taskBarExpanded, selectedTaskIndex: selectedTaskIndex, onTaskBarExpand: handleTaskBarExpand, onTaskBarCollapse: handleTaskBarCollapse, onTaskKill: handleTaskKill, onTaskBarExit: handleTaskBarExit, onTaskNavigate: handleTaskNavigate })) }));
|
|
2335
|
+
}, overlay: overlay, onModelSelect: handleModelSelect, onModelCancel: () => setOverlay(null), loggedInProviders: props.loggedInProviders ?? [currentProvider], currentModel: currentModel, currentProvider: currentProvider, onThemeSelect: handleThemeSelect, onThemeCancel: () => setOverlay(null), currentTheme: theme.name, contextUsed: agentLoop.contextUsed, contextWindowOptions: contextWindowOptions, displayedCwd: displayedCwd, gitBranch: gitBranch, planMode: planMode, exitPending: exitPending, footerStatusLayout: footerStatusLayout, backgroundTasks: bgTasks, taskBarFocused: taskBarFocused, taskBarExpanded: taskBarExpanded, selectedTaskIndex: selectedTaskIndex, onTaskBarExpand: handleTaskBarExpand, onTaskBarCollapse: handleTaskBarCollapse, onTaskKill: handleTaskKill, onTaskBarExit: handleTaskBarExit, onTaskNavigate: handleTaskNavigate })) }));
|
|
2521
2336
|
}
|
|
2522
2337
|
//# sourceMappingURL=App.js.map
|