@pellux/goodvibes-tui 2.0.20 → 2.1.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/CHANGELOG.md +70 -0
- package/README.md +16 -16
- package/docs/README.md +4 -4
- package/docs/foundation-artifacts/operator-contract.json +59 -4
- package/package.json +16 -6
- package/src/cli/management.ts +5 -2
- package/src/cli/tui-startup.ts +34 -39
- package/src/core/agent-view-render.ts +157 -0
- package/src/core/approval-alert.ts +49 -11
- package/src/core/bookmark-navigation.ts +7 -1
- package/src/core/budget-breach-notifier.ts +27 -8
- package/src/core/compaction-receipt.ts +1 -1
- package/src/core/context-usage.ts +1 -1
- package/src/core/conversation-compaction-render.ts +3 -3
- package/src/core/conversation-display-only.ts +86 -0
- package/src/core/conversation-event-navigation.ts +27 -0
- package/src/core/conversation-line-cache.ts +216 -447
- package/src/core/conversation-render-context.ts +20 -27
- package/src/core/conversation-rendering.ts +157 -575
- package/src/core/conversation-splash-state.ts +6 -1
- package/src/core/conversation-types.ts +35 -0
- package/src/core/conversation-usage.ts +12 -0
- package/src/core/conversation.ts +130 -131
- package/src/core/long-task-notifier.ts +100 -31
- package/src/core/notices.ts +75 -0
- package/src/core/pairing-tailscale-gateway.ts +1 -1
- package/src/core/process-output-log.ts +143 -0
- package/src/core/rewind-receipt.ts +1 -1
- package/src/core/session-focus.ts +190 -0
- package/src/core/session-resume-core.ts +23 -81
- package/src/core/stream-event-wiring.ts +31 -5
- package/src/core/system-message-noise.ts +2 -2
- package/src/core/system-message-router.ts +16 -18
- package/src/core/turn-event-wiring.ts +272 -33
- package/src/core/work-tree-focus.ts +290 -0
- package/src/core/work-tree-fold-store.ts +143 -0
- package/src/core/work-tree-model.ts +799 -0
- package/src/core/work-tree-render.ts +384 -0
- package/src/core/work-tree-sources.ts +184 -0
- package/src/core/work-tree-wiring.ts +176 -0
- package/src/core/workstream-notification.ts +36 -6
- package/src/core/wrfc-notice-titles.ts +37 -0
- package/src/input/agents-modal-text.ts +119 -0
- package/src/input/agents-modal.ts +699 -0
- package/src/input/bookmark-modal.ts +33 -9
- package/src/input/changes-git.ts +251 -0
- package/src/input/changes-modal.ts +629 -0
- package/src/input/changes-model.ts +125 -0
- package/src/input/command-palette-types.ts +41 -0
- package/src/input/command-palette.ts +272 -0
- package/src/input/command-registry.ts +77 -35
- package/src/input/commands/acp-runtime.ts +19 -9
- package/src/input/commands/channel-runtime.ts +2 -2
- package/src/input/commands/ci-runtime.ts +1 -1
- package/src/input/commands/codebase-runtime.ts +1 -1
- package/src/input/commands/config.ts +7 -1
- package/src/input/commands/context-window.ts +25 -19
- package/src/input/commands/control-room-runtime.ts +18 -18
- package/src/input/commands/conversation-runtime.ts +0 -1
- package/src/input/commands/cost-runtime.ts +29 -20
- package/src/input/commands/diff-runtime.ts +35 -181
- package/src/input/commands/eval.ts +1 -1
- package/src/input/commands/experience-runtime.ts +3 -7
- package/src/input/commands/fresh-conversation.ts +86 -0
- package/src/input/commands/git-runtime.ts +5 -22
- package/src/input/commands/graph-runtime.ts +1 -1
- package/src/input/commands/guidance-runtime.ts +1 -1
- package/src/input/commands/health-runtime.ts +8 -9
- package/src/input/commands/hooks-runtime.ts +2 -2
- package/src/input/commands/hosted-runtime.ts +3 -3
- package/src/input/commands/incident-runtime.ts +3 -3
- package/src/input/commands/intelligence-runtime.ts +6 -9
- package/src/input/commands/knowledge.ts +2 -2
- package/src/input/commands/legacy-panel-command.ts +57 -0
- package/src/input/commands/local-auth-runtime.ts +8 -9
- package/src/input/commands/local-provider-runtime.ts +7 -4
- package/src/input/commands/local-runtime.ts +12 -15
- package/src/input/commands/local-setup-review.ts +1 -1
- package/src/input/commands/local-setup.ts +13 -19
- package/src/input/commands/memory.ts +1 -1
- package/src/input/commands/notify-runtime.ts +9 -0
- package/src/input/commands/operator-runtime.ts +10 -12
- package/src/input/commands/permissions-provenance.ts +3 -3
- package/src/input/commands/planning-runtime.ts +7 -7
- package/src/input/commands/platform-sandbox-runtime.ts +2 -2
- package/src/input/commands/platform-services-runtime.ts +1 -1
- package/src/input/commands/policy-dispatch.ts +2 -2
- package/src/input/commands/policy.ts +3 -3
- package/src/input/commands/provider.ts +1 -1
- package/src/input/commands/remote-runtime.ts +1 -1
- package/src/input/commands/review-runtime.ts +39 -94
- package/src/input/commands/rewind-runtime.ts +81 -108
- package/src/input/commands/runtime-services.ts +15 -17
- package/src/input/commands/services-runtime.ts +2 -2
- package/src/input/commands/session-content.ts +21 -5
- package/src/input/commands/session-workflow.ts +13 -38
- package/src/input/commands/settings-sync-runtime.ts +2 -2
- package/src/input/commands/shell-core.ts +19 -4
- package/src/input/commands/skills-runtime.ts +2 -2
- package/src/input/commands/status-runtime.ts +13 -0
- package/src/input/commands/subscription-runtime.ts +1 -1
- package/src/input/commands/tasks-runtime.ts +2 -8
- package/src/input/commands/work-plan-runtime.ts +4 -4
- package/src/input/commands/workstream-attempts.ts +24 -47
- package/src/input/commands/workstream-runtime.ts +2 -2
- package/src/input/commands/worktree-runtime.ts +3 -3
- package/src/input/commands.ts +3 -1
- package/src/input/composer-editor.ts +44 -0
- package/src/input/concealed-input.ts +1 -1
- package/src/input/config-modal-types.ts +20 -8
- package/src/input/config-modal.ts +106 -105
- package/src/input/confirm-dialog-types.ts +28 -0
- package/src/input/confirm-dialog.ts +70 -0
- package/src/input/delete-key-policy.ts +3 -3
- package/src/input/feed-context-factory.ts +15 -16
- package/src/input/handler-command-route.ts +7 -42
- package/src/input/handler-content-actions.ts +16 -15
- package/src/input/handler-feed-routes.ts +26 -211
- package/src/input/handler-feed.ts +68 -95
- package/src/input/handler-interactions.ts +5 -3
- package/src/input/handler-modal-routes.ts +215 -216
- package/src/input/handler-modal-stack.ts +81 -11
- package/src/input/handler-modal-token-routes.ts +4 -0
- package/src/input/handler-onboarding.ts +0 -1
- package/src/input/handler-picker-routes.ts +65 -107
- package/src/input/handler-session-view-route.ts +149 -0
- package/src/input/handler-shortcuts.ts +16 -154
- package/src/input/handler-types.ts +4 -2
- package/src/input/handler-ui-state.ts +45 -15
- package/src/input/handler-work-tree-route.ts +123 -0
- package/src/input/handler.ts +25 -70
- package/src/input/keybindings.ts +16 -71
- package/src/input/masked-entry-modal.ts +117 -0
- package/src/input/mcp-workspace.ts +48 -17
- package/src/input/model-picker-filter.ts +8 -0
- package/src/input/model-picker-open.ts +99 -0
- package/src/input/model-picker-types.ts +1 -1
- package/src/input/model-picker.ts +92 -9
- package/src/input/notifications-modal.ts +123 -0
- package/src/input/overlay-filter.ts +26 -0
- package/src/input/profile-picker-modal.ts +37 -8
- package/src/input/search.ts +3 -3
- package/src/input/selection-modal-queue.ts +2 -0
- package/src/input/selection-modal.ts +28 -16
- package/src/input/session-picker-modal.ts +33 -8
- package/src/input/settings-modal-activation.ts +7 -2
- package/src/input/settings-modal-data.ts +11 -6
- package/src/input/settings-modal-types.ts +1 -1
- package/src/input/settings-modal.ts +20 -20
- package/src/input/submission-intent.ts +1 -1
- package/src/input/submission-router.ts +4 -9
- package/src/input/surface-modal-host.ts +110 -0
- package/src/input/theme-settings-actions.ts +82 -0
- package/src/input/usage-modal.ts +183 -0
- package/src/input/views.ts +97 -0
- package/src/main.ts +175 -165
- package/src/permissions/hunk-selection.ts +1 -1
- package/src/permissions/prompt-card.ts +511 -0
- package/src/permissions/prompt.ts +59 -622
- package/src/renderer/agents-modal.ts +310 -0
- package/src/renderer/autocomplete-overlay.ts +42 -220
- package/src/renderer/back-to-bottom.ts +80 -0
- package/src/renderer/block-actions-overlay.ts +30 -48
- package/src/renderer/bookmark-modal.ts +48 -79
- package/src/renderer/changes-modal.ts +325 -0
- package/src/renderer/code-block.ts +184 -106
- package/src/renderer/command-palette.ts +93 -0
- package/src/renderer/composer-fragments.ts +4 -4
- package/src/renderer/composer.ts +146 -0
- package/src/renderer/compositor.ts +26 -160
- package/src/renderer/config-modal.ts +185 -81
- package/src/renderer/confirm-dialog.ts +50 -0
- package/src/renderer/context-inspector.ts +116 -154
- package/src/renderer/context-status-hint.ts +4 -4
- package/src/renderer/conversation-layout.ts +20 -0
- package/src/renderer/conversation-overlays.ts +94 -84
- package/src/renderer/conversation-surface.ts +19 -38
- package/src/renderer/diff-tint.ts +98 -0
- package/src/renderer/file-picker-overlay.ts +63 -90
- package/src/renderer/footer-targets.ts +38 -0
- package/src/renderer/git-status.ts +3 -4
- package/src/renderer/header-line.ts +140 -117
- package/src/renderer/help-overlay.ts +133 -219
- package/src/renderer/history-search-overlay.ts +15 -12
- package/src/renderer/lane-graph/bead.ts +800 -0
- package/src/renderer/lane-graph/glyphs.ts +134 -0
- package/src/renderer/lane-graph/layout.ts +248 -0
- package/src/renderer/lane-graph/paint.ts +537 -0
- package/src/renderer/lane-graph/semantic-memo.ts +77 -0
- package/src/renderer/layout-engine.ts +2 -57
- package/src/renderer/layout.ts +7 -13
- package/src/renderer/markdown-inline.ts +2 -1
- package/src/renderer/markdown-table.ts +17 -12
- package/src/renderer/markdown.ts +92 -34
- package/src/renderer/masked-entry-modal.ts +78 -0
- package/src/renderer/mcp-workspace.ts +166 -203
- package/src/renderer/model-workspace.ts +381 -436
- package/src/renderer/notifications-modal.ts +116 -0
- package/src/renderer/onboarding/onboarding-wizard.ts +178 -588
- package/src/renderer/process-view.ts +192 -0
- package/src/renderer/profile-picker-modal.ts +58 -110
- package/src/renderer/search-overlay.ts +6 -3
- package/src/renderer/selection-modal-overlay.ts +87 -327
- package/src/renderer/semantic-diff.ts +2 -2
- package/src/renderer/session-chips.ts +102 -0
- package/src/renderer/session-picker-modal.ts +177 -297
- package/src/renderer/settings-modal-connections.ts +14 -23
- package/src/renderer/settings-modal-context.ts +367 -0
- package/src/renderer/settings-modal-helpers.ts +6 -11
- package/src/renderer/settings-modal.ts +322 -726
- package/src/renderer/shell-surface.ts +277 -175
- package/src/renderer/shortcuts-overlay.ts +217 -0
- package/src/renderer/status-line.ts +475 -0
- package/src/renderer/surface-compose.ts +174 -0
- package/src/renderer/surface-kit-extra.ts +303 -0
- package/src/renderer/surface-kit-list.ts +366 -0
- package/src/renderer/surface-kit-parts.ts +360 -0
- package/src/renderer/surface-kit.ts +568 -0
- package/src/renderer/syntax-highlighter.ts +280 -197
- package/src/renderer/syntax-theme.ts +51 -0
- package/src/renderer/system-message.ts +0 -1
- package/src/renderer/term-caps.ts +42 -1
- package/src/renderer/terminal-bg-probe.ts +116 -19
- package/src/renderer/terminal-palette-probe.ts +322 -0
- package/src/renderer/terminal-palette-reader.ts +183 -0
- package/src/renderer/terminal-palette.ts +58 -0
- package/src/renderer/theme-mode-config.ts +16 -1
- package/src/renderer/theme.ts +234 -207
- package/src/renderer/thinking.ts +0 -1
- package/src/renderer/throbber.ts +188 -0
- package/src/renderer/toast-center.ts +119 -0
- package/src/renderer/ui-factory.ts +39 -602
- package/src/renderer/ui-primitives.ts +8 -25
- package/src/renderer/usage-modal.ts +353 -0
- package/src/renderer/user-message.ts +58 -0
- package/src/renderer/voice-capture-chip.ts +53 -0
- package/src/runtime/bootstrap-command-context.ts +0 -5
- package/src/runtime/bootstrap-command-parts.ts +38 -89
- package/src/runtime/bootstrap-core.ts +13 -15
- package/src/runtime/bootstrap-hook-bridge.ts +12 -21
- package/src/runtime/bootstrap-notifier-sync.ts +17 -1
- package/src/runtime/bootstrap-shell.ts +16 -50
- package/src/runtime/bootstrap.ts +14 -14
- package/src/runtime/client/fleet-union.ts +5 -5
- package/src/runtime/client/hosted-exit.ts +2 -2
- package/src/runtime/client/hosted-sessions.ts +1 -1
- package/src/runtime/client/spine-adoption.ts +1 -1
- package/src/runtime/context-accounting-source.ts +5 -4
- package/src/runtime/index.ts +1 -0
- package/src/runtime/notification-dispatch.ts +102 -29
- package/src/runtime/recovery-offer-wiring.ts +4 -1
- package/src/runtime/recovery-prompt.ts +31 -15
- package/src/runtime/runtime-services-types.ts +10 -6
- package/src/runtime/services.ts +17 -12
- package/src/runtime/session-continuity-hints.ts +2 -5
- package/src/runtime/session-inbound-inputs.ts +1 -1
- package/src/runtime/session-resume-liveness-confirm.ts +14 -2
- package/src/runtime/startup-typeahead-gate.ts +103 -0
- package/src/runtime/store/domains/domain-read-matrix.ts +0 -1
- package/src/runtime/store/domains/index.ts +0 -8
- package/src/runtime/store/selectors/index.ts +0 -28
- package/src/runtime/store/state.ts +0 -8
- package/src/runtime/ui-services.ts +4 -6
- package/src/runtime/usage-tracker.ts +348 -0
- package/src/runtime/wrfc-persistence.ts +4 -4
- package/src/shell/blocking-input.ts +92 -2
- package/src/shell/recovery-input-helpers.ts +1 -1
- package/src/shell/session-views.ts +539 -0
- package/src/shell/status-report.ts +86 -0
- package/src/shell/transcript-scroll.ts +68 -0
- package/src/shell/ui-openers.ts +84 -172
- package/src/shell/view-openers.ts +205 -0
- package/src/tools/wrfc-agent-guard.ts +22 -2
- package/src/utils/format-duration.ts +4 -8
- package/src/utils/splash-lines.ts +9 -1
- package/src/utils/terminal-width.ts +56 -0
- package/src/verification/verification-ledger.ts +18 -16
- package/src/{panels → views}/agent-inspector-shared.ts +2 -2
- package/src/{panels → views}/builtin-modals.ts +22 -21
- package/src/views/builtin-views.ts +135 -0
- package/src/{panels → views}/confirm-state.ts +9 -9
- package/src/{panels → views}/diff-review-model.ts +10 -3
- package/src/{panels → views}/eval-registry.ts +1 -1
- package/src/{panels → views}/fleet-acts.ts +49 -85
- package/src/{panels/fleet-panel-format.ts → views/fleet-format.ts} +40 -40
- package/src/{panels → views}/fleet-gateway.ts +5 -5
- package/src/{panels → views}/fleet-observed-render.ts +16 -16
- package/src/{panels → views}/fleet-read-model.ts +9 -9
- package/src/{panels/fleet-tabs.ts → views/fleet-session-tabs.ts} +13 -13
- package/src/{panels → views}/fleet-spawn.ts +33 -49
- package/src/{panels → views}/fleet-steer.ts +12 -12
- package/src/{panels → views}/fleet-stop.ts +4 -4
- package/src/{panels → views}/fleet-transcript.ts +26 -27
- package/src/{panels/fleet-panel-worktree-detail.ts → views/fleet-worktree-detail.ts} +7 -7
- package/src/{panels → views}/hosted-session-feed.ts +6 -6
- package/src/views/modal-surface-registry.ts +41 -0
- package/src/{panels → views}/modals/devices-modal.ts +2 -2
- package/src/{panels → views}/modals/hooks-modal.ts +13 -13
- package/src/{panels → views}/modals/keybindings-modal.ts +19 -27
- package/src/{panels → views}/modals/knowledge-modal.ts +6 -5
- package/src/{panels → views}/modals/local-auth-modal.ts +22 -21
- package/src/{panels → views}/modals/marketplace-modal.ts +11 -11
- package/src/{panels → views}/modals/memory-modal.ts +8 -8
- package/src/{panels → views}/modals/modal-surface-helpers.ts +15 -5
- package/src/{panels → views}/modals/pairing-modal.ts +9 -9
- package/src/{panels → views}/modals/planning-modal.ts +15 -20
- package/src/{panels → views}/modals/plugins-modal.ts +6 -6
- package/src/{panels → views}/modals/policy-modal.ts +13 -5
- package/src/{panels → views}/modals/provider-health-modal.ts +4 -4
- package/src/{panels → views}/modals/remote-modal.ts +3 -3
- package/src/{panels → views}/modals/sandbox-modal.ts +4 -4
- package/src/{panels → views}/modals/security-modal.ts +22 -16
- package/src/{panels → views}/modals/services-modal.ts +3 -3
- package/src/{panels → views}/modals/settings-sync-modal.ts +4 -4
- package/src/{panels → views}/modals/skills-modal.ts +9 -9
- package/src/{panels → views}/modals/subscription-modal.ts +3 -3
- package/src/{panels → views}/modals/work-plan-modal.ts +10 -13
- package/src/views/notifications-feed.ts +314 -0
- package/src/{panels → views}/polish-core.ts +38 -36
- package/src/{panels → views}/polish-tables.ts +35 -26
- package/src/{panels → views}/polish.ts +101 -95
- package/src/{panels → views}/project-planning-answer-actions.ts +3 -3
- package/src/{panels → views}/provider-health-routes.ts +14 -14
- package/src/{panels → views}/search-focus.ts +8 -8
- package/src/{panels → views}/session-maintenance.ts +11 -11
- package/src/views/skills-discovery.ts +159 -0
- package/src/views/view-deps.ts +80 -0
- package/src/views/view-panel-adapter.ts +53 -0
- package/src/{panels → views}/workstream-graph-render.ts +1 -1
- package/src/core/conversation-fold.ts +0 -101
- package/src/core/conversation-turn-structure.ts +0 -464
- package/src/core/conversation-user-receipts.ts +0 -42
- package/src/input/commands/operator-panel-runtime.ts +0 -186
- package/src/input/panel-integration-actions.ts +0 -33
- package/src/input/panel-mouse-geometry.ts +0 -97
- package/src/input/panel-paste-flood-guard.ts +0 -86
- package/src/panels/base-panel.ts +0 -301
- package/src/panels/builtin/agent.ts +0 -27
- package/src/panels/builtin/development.ts +0 -92
- package/src/panels/builtin/knowledge.ts +0 -12
- package/src/panels/builtin/operations.ts +0 -177
- package/src/panels/builtin/session.ts +0 -81
- package/src/panels/builtin/shared.ts +0 -357
- package/src/panels/builtin-panels.ts +0 -28
- package/src/panels/cost-tracker-panel.ts +0 -746
- package/src/panels/diff-panel.ts +0 -797
- package/src/panels/diff-review-panel.ts +0 -395
- package/src/panels/expandable-list-panel.ts +0 -189
- package/src/panels/fleet-deep-link.ts +0 -31
- package/src/panels/fleet-panel.ts +0 -799
- package/src/panels/git-panel.ts +0 -800
- package/src/panels/hosted-session-panel.ts +0 -221
- package/src/panels/index.ts +0 -21
- package/src/panels/local-auth-panel.ts +0 -478
- package/src/panels/notifications-feed.ts +0 -127
- package/src/panels/notifications-panel.ts +0 -160
- package/src/panels/panel-confirm-overlay.ts +0 -72
- package/src/panels/panel-manager.ts +0 -791
- package/src/panels/plugins-panel.ts +0 -371
- package/src/panels/scrollable-list-panel.ts +0 -498
- package/src/panels/skills-panel.ts +0 -454
- package/src/panels/token-budget-panel.ts +0 -688
- package/src/panels/types.ts +0 -191
- package/src/panels/wrfc-panel-format.ts +0 -133
- package/src/renderer/diff-view.ts +0 -134
- package/src/renderer/fleet-tab-strip.ts +0 -56
- package/src/renderer/footer-tips.ts +0 -53
- package/src/renderer/fullscreen-primitives.ts +0 -146
- package/src/renderer/fullscreen-workspace.ts +0 -194
- package/src/renderer/hint-grammar.ts +0 -52
- package/src/renderer/modal-factory.ts +0 -480
- package/src/renderer/overlay-box.ts +0 -154
- package/src/renderer/overlay-viewport.ts +0 -104
- package/src/renderer/panel-composite.ts +0 -145
- package/src/renderer/panel-workspace-bar.ts +0 -54
- package/src/renderer/process-indicator.ts +0 -163
- package/src/renderer/tab-strip.ts +0 -222
- package/src/renderer/text-layout.ts +0 -31
- package/src/renderer/tool-call.ts +0 -276
- package/src/renderer/tool-result-expanded-lines.ts +0 -48
- package/src/renderer/tool-result-summary.ts +0 -219
- package/src/runtime/diagnostics/panels/index.ts +0 -21
- package/src/runtime/diagnostics/panels/ops.ts +0 -156
- package/src/runtime/perf/panel-contracts.ts +0 -32
- package/src/runtime/store/domains/panels.ts +0 -117
- /package/src/{panels → views}/memory-consolidation-gateway.ts +0 -0
- /package/src/{panels → views}/modals/modal-theme.ts +0 -0
- /package/src/{panels → views}/provider-health-domains.ts +0 -0
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
* session-resume-core.ts, the ONE resume routine both resume seams call.
|
|
3
3
|
*
|
|
4
4
|
* Two independent call sites used to duplicate (and diverge from) this
|
|
5
|
-
* sequence: `/session resume` (session-workflow.ts) and the
|
|
6
|
-
*
|
|
5
|
+
* sequence: `/session resume` (session-workflow.ts) and the session-browser
|
|
6
|
+
* resume (bootstrap-hook-bridge.ts's `createResumeSessionHandler`).
|
|
7
7
|
* Divergences found by audit:
|
|
8
|
-
* - the
|
|
9
|
-
* silently had no anchors after a
|
|
10
|
-
* - the
|
|
11
|
-
*
|
|
12
|
-
*
|
|
8
|
+
* - the session-browser seam skipped `restoreTurnAnchors` (message-anchored
|
|
9
|
+
* /rewind silently had no anchors after a session-browser resume)
|
|
10
|
+
* - the session-browser seam skipped `conversation.resetAll()` before
|
|
11
|
+
* `fromJSON()`
|
|
12
|
+
* - the session-browser seam skipped the `selectModel` reselection fallback
|
|
13
|
+
* (it set `runtime.model` straight from the saved meta, never re-resolving
|
|
13
14
|
* through the live provider registry)
|
|
14
|
-
* - the
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* - the session-browser seam reopened saved views without the modal
|
|
16
|
+
* redirect, so a saved view id could pop a modal mid-resume (saved views
|
|
17
|
+
* are no longer reopened at all)
|
|
17
18
|
*
|
|
18
|
-
* Both seams now call this module so those
|
|
19
|
-
*
|
|
20
|
-
* not by copy-paste discipline between two files.
|
|
19
|
+
* Both seams now call this module so those behaviors are guaranteed
|
|
20
|
+
* identical by construction, not by copy-paste discipline between two files.
|
|
21
21
|
*
|
|
22
22
|
* Callers own everything ABOVE and AROUND this core sequence: printing or
|
|
23
23
|
* logging the outcome in their own idiom (`ctx.print` vs `conversation.log`),
|
|
@@ -30,6 +30,7 @@ import type { SessionManager, SessionMeta } from '@pellux/goodvibes-sdk/platform
|
|
|
30
30
|
import type { SessionSurface } from '@/runtime/index.ts';
|
|
31
31
|
import type { ConversationManager } from './conversation.ts';
|
|
32
32
|
import { restoreTurnAnchors } from '@pellux/goodvibes-sdk/platform/rewind';
|
|
33
|
+
import { restoreWorkTreeFolds } from './work-tree-wiring.ts';
|
|
33
34
|
import { replayJournalForSession, type ReplayIntoConversationResult } from '@pellux/goodvibes-sdk/platform/runtime/operations';
|
|
34
35
|
|
|
35
36
|
export interface SessionResumeRuntime {
|
|
@@ -38,12 +39,6 @@ export interface SessionResumeRuntime {
|
|
|
38
39
|
provider: string;
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
export interface SessionResumePanelManager {
|
|
42
|
-
open(id: string): unknown;
|
|
43
|
-
show(): void;
|
|
44
|
-
getModalRedirect(id: string): string | undefined;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
42
|
export interface SessionResumeDeps {
|
|
48
43
|
readonly sessionManager: Pick<SessionManager, 'load' | 'save'>;
|
|
49
44
|
readonly conversation: ConversationManager;
|
|
@@ -56,7 +51,6 @@ export interface SessionResumeDeps {
|
|
|
56
51
|
* seam.
|
|
57
52
|
*/
|
|
58
53
|
readonly surface: SessionSurface;
|
|
59
|
-
readonly panelManager: SessionResumePanelManager;
|
|
60
54
|
/**
|
|
61
55
|
* Reselects the saved model through the live provider registry, falling
|
|
62
56
|
* back to the raw saved id on failure (a saved model may no longer exist
|
|
@@ -64,20 +58,6 @@ export interface SessionResumeDeps {
|
|
|
64
58
|
*/
|
|
65
59
|
readonly selectModel?: (model: string) => Promise<{ readonly registryKey: string; readonly providerId: string }>;
|
|
66
60
|
readonly hydrateSessionUsage?: () => void;
|
|
67
|
-
/**
|
|
68
|
-
* Deliberate cap on how many saved panels are reopened at once, resuming
|
|
69
|
-
* into a workspace crowded with every panel that happened to be open is
|
|
70
|
-
* its own kind of surprise. Overflow beyond the cap is reported in the
|
|
71
|
-
* outcome (`panels.notReopened`), never silently dropped. Defaults to 4.
|
|
72
|
-
*/
|
|
73
|
-
readonly panelReopenLimit?: number;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export interface PanelReopenOutcome {
|
|
77
|
-
readonly reopened: readonly string[];
|
|
78
|
-
readonly movedToModal: readonly string[];
|
|
79
|
-
/** Saved panel ids beyond `panelReopenLimit`, not attempted, honestly reported (see /panels to open the rest). */
|
|
80
|
-
readonly notReopened: readonly string[];
|
|
81
61
|
}
|
|
82
62
|
|
|
83
63
|
export interface SessionResumeOutcome {
|
|
@@ -85,51 +65,18 @@ export interface SessionResumeOutcome {
|
|
|
85
65
|
readonly resumedMessageCount: number;
|
|
86
66
|
readonly restoredAnchorCount: number;
|
|
87
67
|
readonly journalReplay: ReplayIntoConversationResult;
|
|
88
|
-
readonly panels: PanelReopenOutcome;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Exported so both session-workflow.ts's standalone `reopenPanelsFromReturnContext`
|
|
93
|
-
* (kept for its existing direct unit-test coverage, see
|
|
94
|
-
* session-workflow-panel-restore.test.ts) and `resumeSessionCore` below share
|
|
95
|
-
* the exact same default cap.
|
|
96
|
-
*/
|
|
97
|
-
export const DEFAULT_PANEL_REOPEN_LIMIT = 4;
|
|
98
|
-
|
|
99
|
-
export function reopenPanelsWithModalSkip(
|
|
100
|
-
panelManager: SessionResumePanelManager,
|
|
101
|
-
openPanelIds: readonly string[] | undefined,
|
|
102
|
-
limit: number,
|
|
103
|
-
): PanelReopenOutcome {
|
|
104
|
-
if (!openPanelIds || openPanelIds.length === 0) return { reopened: [], movedToModal: [], notReopened: [] };
|
|
105
|
-
const within = openPanelIds.slice(0, limit);
|
|
106
|
-
const overflow = openPanelIds.slice(limit);
|
|
107
|
-
const reopened: string[] = [];
|
|
108
|
-
const movedToModal: string[] = [];
|
|
109
|
-
for (const panelId of within) {
|
|
110
|
-
// A MIGRATE-TO-MODAL id has no panel to restore, a modal is not part of
|
|
111
|
-
// the saved panel layout. Skip it (don't pop a modal mid-resume) and note
|
|
112
|
-
// it once, rather than firing open() and revealing an empty workspace.
|
|
113
|
-
if (panelManager.getModalRedirect(panelId) !== undefined) {
|
|
114
|
-
movedToModal.push(panelId);
|
|
115
|
-
continue;
|
|
116
|
-
}
|
|
117
|
-
try {
|
|
118
|
-
panelManager.open(panelId);
|
|
119
|
-
reopened.push(panelId);
|
|
120
|
-
} catch {
|
|
121
|
-
// Ignore unknown or currently unavailable panel ids during resume.
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
if (reopened.length > 0) panelManager.show();
|
|
125
|
-
return { reopened, movedToModal, notReopened: overflow };
|
|
126
68
|
}
|
|
127
69
|
|
|
128
70
|
/**
|
|
129
71
|
* The canonical resume sequence: load, reset + restore the conversation,
|
|
130
72
|
* restore rewind anchors, replay any post-snapshot journal records, hydrate
|
|
131
|
-
* footer usage
|
|
132
|
-
*
|
|
73
|
+
* footer usage and reselect the model.
|
|
74
|
+
*
|
|
75
|
+
* Sessions saved by an older TUI can carry a legacy pane list in their
|
|
76
|
+
* return context (`returnContext.openPanels` plus an "Open panels: ..."
|
|
77
|
+
* line). The SDK's session loader (`loadedReturnContext`) drops both, so
|
|
78
|
+
* `meta.returnContext` here never has them, and the journal-replay rewrite
|
|
79
|
+
* below writes the session back without them.
|
|
133
80
|
*/
|
|
134
81
|
export async function resumeSessionCore(sessionId: string, deps: SessionResumeDeps): Promise<SessionResumeOutcome> {
|
|
135
82
|
const { meta, messages } = deps.sessionManager.load(sessionId);
|
|
@@ -140,6 +87,8 @@ export async function resumeSessionCore(sessionId: string, deps: SessionResumeDe
|
|
|
140
87
|
title: meta.title,
|
|
141
88
|
titleSource: meta.titleSource,
|
|
142
89
|
});
|
|
90
|
+
// The work tree's folds (turns, lanes, open beads) come back with the session.
|
|
91
|
+
restoreWorkTreeFolds(deps.conversation, deps.surface.sessionsDir, sessionId);
|
|
143
92
|
deps.conversation.rebuildHistory();
|
|
144
93
|
deps.runtime.sessionId = sessionId;
|
|
145
94
|
|
|
@@ -190,17 +139,10 @@ export async function resumeSessionCore(sessionId: string, deps: SessionResumeDe
|
|
|
190
139
|
}
|
|
191
140
|
if (meta.provider) deps.runtime.provider = meta.provider;
|
|
192
141
|
|
|
193
|
-
const panels = reopenPanelsWithModalSkip(
|
|
194
|
-
deps.panelManager,
|
|
195
|
-
meta.returnContext?.openPanels,
|
|
196
|
-
deps.panelReopenLimit ?? DEFAULT_PANEL_REOPEN_LIMIT,
|
|
197
|
-
);
|
|
198
|
-
|
|
199
142
|
return {
|
|
200
143
|
meta,
|
|
201
144
|
resumedMessageCount: deps.conversation.getMessageCount(),
|
|
202
145
|
restoredAnchorCount,
|
|
203
146
|
journalReplay,
|
|
204
|
-
panels,
|
|
205
147
|
};
|
|
206
148
|
}
|
|
@@ -38,6 +38,13 @@ export interface StreamMetrics {
|
|
|
38
38
|
* the synthetic 'live' render id.
|
|
39
39
|
*/
|
|
40
40
|
activeToolCallId: string | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Arguments of the tool calls received this turn, by callId (from
|
|
43
|
+
* TOOL_RECEIVED), so the throbber can name the running call's key argument.
|
|
44
|
+
* An entry is dropped when its call finishes (succeeded, failed or
|
|
45
|
+
* cancelled), and the map keeps at most 64 entries, oldest dropped first.
|
|
46
|
+
*/
|
|
47
|
+
toolArgsByCallId: Map<string, Record<string, unknown>>;
|
|
41
48
|
/**
|
|
42
49
|
* Epoch ms of the most recent STREAM_START or STREAM_DELTA; undefined when
|
|
43
50
|
* idle (no turn in flight). Read every render frame, not just on the
|
|
@@ -68,6 +75,7 @@ export function createStreamMetrics(): StreamMetrics {
|
|
|
68
75
|
return {
|
|
69
76
|
startTime: 0, deltaCount: 0, tokenSpeed: 0, ttftMs: undefined, ttftRecorded: false,
|
|
70
77
|
activeToolStartedAtMs: undefined, activeToolName: undefined, activeToolCallId: undefined,
|
|
78
|
+
toolArgsByCallId: new Map(),
|
|
71
79
|
lastDeltaAtMs: undefined, stallEpisode: 0,
|
|
72
80
|
reconnectAttempt: undefined, reconnectMaxAttempts: undefined,
|
|
73
81
|
};
|
|
@@ -194,6 +202,14 @@ export interface WireStreamEventMetricsOptions {
|
|
|
194
202
|
* in silence on a backend the user did not choose.
|
|
195
203
|
*/
|
|
196
204
|
readonly retryTurn?: (notice?: string) => boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Called synchronously, inside the TURN_ERROR handler, when failover has
|
|
207
|
+
* re-submitted the turn (retryTurn returned true). main.ts passes
|
|
208
|
+
* turn-event-wiring's continueTurnAfterFailover, so the failed attempt is
|
|
209
|
+
* not told as its own turn: one notice per user turn, for how it finally
|
|
210
|
+
* ended.
|
|
211
|
+
*/
|
|
212
|
+
readonly onFailoverRetry?: () => void;
|
|
197
213
|
/**
|
|
198
214
|
* Optional cost catalog for attaching per-1M-token cost information to
|
|
199
215
|
* the failover notice. When provided and both models have non-zero pricing,
|
|
@@ -352,7 +368,7 @@ export function wireStreamEventMetrics(
|
|
|
352
368
|
): WireStreamEventMetricsResult {
|
|
353
369
|
const {
|
|
354
370
|
events, metrics, orchestrator, providerRegistry,
|
|
355
|
-
systemMessageRouter, render, providerOptimizer, retryTurn, costLookup,
|
|
371
|
+
systemMessageRouter, render, providerOptimizer, retryTurn, onFailoverRetry, costLookup,
|
|
356
372
|
isApprovalPending, stallThresholdMs, failoverState, getConfiguredRegistryKey,
|
|
357
373
|
getConfiguredReasoningEffort,
|
|
358
374
|
} = options;
|
|
@@ -636,7 +652,9 @@ export function wireStreamEventMetrics(
|
|
|
636
652
|
// retryTurn option doc). Emitting it here instead would delete it.
|
|
637
653
|
const failoverNotice = `[Failover] ${fromProvider} -> ${next.providerId} (${errorClass})${billingSuffix}${costSuffix}`
|
|
638
654
|
+ (effortNote ? `\n[Failover] ${effortNote}` : '');
|
|
639
|
-
if (
|
|
655
|
+
if (retryTurn(failoverNotice)) {
|
|
656
|
+
onFailoverRetry?.();
|
|
657
|
+
} else {
|
|
640
658
|
// No turn to re-submit (the failed turn did not come from the
|
|
641
659
|
// composer, so there is no pre-submission snapshot to roll back to).
|
|
642
660
|
// The registry has still MOVED, so the switch gets narrated here and
|
|
@@ -714,6 +732,11 @@ export function wireStreamEventMetrics(
|
|
|
714
732
|
render();
|
|
715
733
|
}));
|
|
716
734
|
|
|
735
|
+
unsubs.push(events.tools.on('TOOL_RECEIVED', (ev) => {
|
|
736
|
+
// Bounded: a turn that never finishes its calls cannot grow this without limit.
|
|
737
|
+
if (metrics.toolArgsByCallId.size >= 64) metrics.toolArgsByCallId.delete(metrics.toolArgsByCallId.keys().next().value!);
|
|
738
|
+
metrics.toolArgsByCallId.set(ev.callId, ev.args ?? {});
|
|
739
|
+
}));
|
|
717
740
|
unsubs.push(events.tools.on('TOOL_EXECUTING', (ev) => {
|
|
718
741
|
metrics.activeToolStartedAtMs = ev.startedAt;
|
|
719
742
|
metrics.activeToolName = ev.tool;
|
|
@@ -728,19 +751,22 @@ export function wireStreamEventMetrics(
|
|
|
728
751
|
// delta), the very next frame would read msSinceLastDelta as the full
|
|
729
752
|
// tool-execution duration and immediately report a stall, even though the
|
|
730
753
|
// model hasn't had a chance to resume producing tokens yet.
|
|
731
|
-
unsubs.push(events.tools.on('TOOL_SUCCEEDED', () => {
|
|
754
|
+
unsubs.push(events.tools.on('TOOL_SUCCEEDED', (ev) => {
|
|
755
|
+
metrics.toolArgsByCallId.delete(ev.callId);
|
|
732
756
|
metrics.activeToolStartedAtMs = undefined;
|
|
733
757
|
metrics.activeToolName = undefined;
|
|
734
758
|
metrics.activeToolCallId = undefined;
|
|
735
759
|
metrics.lastDeltaAtMs = Date.now();
|
|
736
760
|
}));
|
|
737
|
-
unsubs.push(events.tools.on('TOOL_FAILED', () => {
|
|
761
|
+
unsubs.push(events.tools.on('TOOL_FAILED', (ev) => {
|
|
762
|
+
metrics.toolArgsByCallId.delete(ev.callId);
|
|
738
763
|
metrics.activeToolStartedAtMs = undefined;
|
|
739
764
|
metrics.activeToolName = undefined;
|
|
740
765
|
metrics.activeToolCallId = undefined;
|
|
741
766
|
metrics.lastDeltaAtMs = Date.now();
|
|
742
767
|
}));
|
|
743
|
-
unsubs.push(events.tools.on('TOOL_CANCELLED', () => {
|
|
768
|
+
unsubs.push(events.tools.on('TOOL_CANCELLED', (ev) => {
|
|
769
|
+
metrics.toolArgsByCallId.delete(ev.callId);
|
|
744
770
|
metrics.activeToolStartedAtMs = undefined;
|
|
745
771
|
metrics.activeToolName = undefined;
|
|
746
772
|
metrics.activeToolCallId = undefined;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* source these rules catch is emitted (from the SDK) through
|
|
5
5
|
* SystemMessageRouter, so this one funnel is where first-run plumbing is kept
|
|
6
6
|
* out of the user's stream while the information stays reachable elsewhere
|
|
7
|
-
* (
|
|
7
|
+
* (Agents modal, /health, /model, activity log). (item 1.)
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
export interface NoiseGateDeps {
|
|
@@ -48,7 +48,7 @@ export function classifyNoise(message: string, deps: NoiseGateDeps): NoiseVerdic
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
// 1d, periodic "[Agents] N running:" status snapshot. The same live detail
|
|
51
|
-
// is shown in the
|
|
51
|
+
// is shown in the Agents modal (per-agent activity) and the footer count, so
|
|
52
52
|
// the 30-second transcript churn is dropped. Meaningful lifecycle lines
|
|
53
53
|
// ("[Agents] ✓ …", "[Agents] Cohort …", "[Agents] ✗ …") do not match.
|
|
54
54
|
if (AGENTS_RUNNING_SNAPSHOT_RE.test(message)) {
|
|
@@ -5,20 +5,19 @@
|
|
|
5
5
|
* Delivery is resolved from the message KIND ('system' | 'wrfc' |
|
|
6
6
|
* 'operational'), which maps to a configurable routing target
|
|
7
7
|
* (ui.systemMessages / ui.wrfcMessages / ui.operationalMessages, each
|
|
8
|
-
* 'panel' | 'conversation' | 'both'). resolveSystemMessageDelivery()
|
|
9
|
-
* that target, plus whether a
|
|
10
|
-
* toConversation } decision.
|
|
8
|
+
* 'panel' | 'conversation' | 'both', the SDK's target names). resolveSystemMessageDelivery()
|
|
9
|
+
* turns that target, plus whether a side surface is attached (the SDK's
|
|
10
|
+
* `hasPanel` argument), into a { toPanel, toConversation } decision.
|
|
11
11
|
*
|
|
12
|
-
* (the purge): the
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* has been removed entirely, so this router now always resolves with
|
|
12
|
+
* (the purge): the side surface this router used to optionally push into
|
|
13
|
+
* was DELETE-disposition (no surviving human surface, not something worth a
|
|
14
|
+
* dedicated console) and has been removed entirely, so this router now always resolves with
|
|
16
15
|
* `hasPanel = false`. Per resolveSystemMessageDelivery's own contract that
|
|
17
|
-
* means EVERY kind/target combination (including 'panel'-
|
|
16
|
+
* means EVERY kind/target combination (including 'panel'-target) falls back
|
|
18
17
|
* to `toConversation: true`, nothing this router routes can vanish; it all
|
|
19
18
|
* reaches conversation.addTypedSystemMessage(), which the transcript
|
|
20
19
|
* renders as a navigable system line. This is deliberate, not a regression:
|
|
21
|
-
* operational chatter that used to be tucked away in a rarely-opened
|
|
20
|
+
* operational chatter that used to be tucked away in a rarely-opened side surface
|
|
22
21
|
* now surfaces inline, same as the messages that were already forced there
|
|
23
22
|
* (see FORCE_CONVERSATION_PREFIXES below).
|
|
24
23
|
*
|
|
@@ -61,7 +60,7 @@ export type {
|
|
|
61
60
|
SystemMessageTarget,
|
|
62
61
|
} from '@/runtime/index.ts';
|
|
63
62
|
|
|
64
|
-
/**
|
|
63
|
+
/** Emphasis level. Side-surface delivery was removed (see file doc); kept as the priority vocabulary for callers and for the SDK's delivery-resolution signature. */
|
|
65
64
|
export type SystemMessagePriority = 'high' | 'low';
|
|
66
65
|
|
|
67
66
|
/**
|
|
@@ -88,7 +87,7 @@ function mustReachConversation(message: string): boolean {
|
|
|
88
87
|
|
|
89
88
|
/**
|
|
90
89
|
* Routes system messages to the conversation based on priority level and
|
|
91
|
-
* configured target. See file doc for the
|
|
90
|
+
* configured target. See file doc for the side-surface removal.
|
|
92
91
|
*/
|
|
93
92
|
export class SystemMessageRouter {
|
|
94
93
|
/** Buffered provider "from last session" replay lines, folded on a microtask. */
|
|
@@ -113,7 +112,7 @@ export class SystemMessageRouter {
|
|
|
113
112
|
*
|
|
114
113
|
* @param message - Message text.
|
|
115
114
|
* @param priority - 'high' | 'low' (kept for callers; no longer changes
|
|
116
|
-
* delivery now that there is no
|
|
115
|
+
* delivery now that there is no side surface to emphasize on).
|
|
117
116
|
* @param kind - Classification kind ('system' | 'wrfc' | 'operational');
|
|
118
117
|
* used to resolve routing target and conversation navigability.
|
|
119
118
|
*/
|
|
@@ -137,7 +136,7 @@ export class SystemMessageRouter {
|
|
|
137
136
|
/** Post-noise-gate delivery: resolve target and append to the conversation. */
|
|
138
137
|
private deliver(message: string, kind: SystemMessageKind): void {
|
|
139
138
|
const target = this.getTargetForKind(kind);
|
|
140
|
-
// hasPanel is always false now that
|
|
139
|
+
// hasPanel is always false now that side-surface delivery was removed, resolveSystemMessageDelivery's own
|
|
141
140
|
// contract means every target ('panel' | 'conversation' | 'both')
|
|
142
141
|
// resolves toConversation: true in that case (see file doc).
|
|
143
142
|
const delivery = resolveSystemMessageDelivery(target, false);
|
|
@@ -227,10 +226,9 @@ export class SystemMessageRouter {
|
|
|
227
226
|
|
|
228
227
|
/**
|
|
229
228
|
* Route a message that must reach the conversation unconditionally. Skips
|
|
230
|
-
* the noise gate and the configured routing target
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
* otherwise it would be invisible while the splash still owns the screen.
|
|
229
|
+
* the noise gate and the configured routing target. Like every system
|
|
230
|
+
* message it shows as a toast and stays in the notification history
|
|
231
|
+
* (core/notices.ts), so it is seen even while the splash owns the screen.
|
|
234
232
|
*
|
|
235
233
|
* Two callers qualify today:
|
|
236
234
|
* - a receipt for an explicit user action at this shell (answering the
|
|
@@ -244,7 +242,7 @@ export class SystemMessageRouter {
|
|
|
244
242
|
* guarantee rather than a second string match.
|
|
245
243
|
*/
|
|
246
244
|
userReceipt(message: string): void {
|
|
247
|
-
this.conversation.addTypedSystemMessage(message, classifySystemMessageKind(message)
|
|
245
|
+
this.conversation.addTypedSystemMessage(message, classifySystemMessageKind(message));
|
|
248
246
|
}
|
|
249
247
|
}
|
|
250
248
|
|