@pellux/goodvibes-tui 2.0.14 → 2.0.16
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/.goodvibes/GOODVIBES.md +1 -1
- package/.goodvibes/agents/reviewer.md +8 -8
- package/.goodvibes/skills/add-provider/SKILL.md +22 -22
- package/CHANGELOG.md +49 -0
- package/README.md +64 -44
- package/docs/README.md +6 -6
- package/docs/foundation-artifacts/README.md +5 -5
- package/docs/foundation-artifacts/operator-contract.json +123 -123
- package/package.json +12 -10
- package/scripts/postinstall.js +3 -3
- package/src/audio/activation-sound.ts +7 -7
- package/src/audio/capture.ts +7 -7
- package/src/audio/onnxruntime-assets.d.ts +1 -1
- package/src/audio/player.ts +4 -4
- package/src/audio/spoken-turn-wiring.ts +4 -4
- package/src/audio/voice-capture-wiring.ts +5 -5
- package/src/audio/voice-input-session.ts +3 -3
- package/src/audio/wake-inference.ts +13 -8
- package/src/audio/wake-runtime.ts +10 -10
- package/src/cli/completions/generate.ts +2 -2
- package/src/cli/doctor.ts +13 -13
- package/src/cli/ensure-goodvibes-gitignore.ts +3 -3
- package/src/cli/entrypoint.ts +3 -3
- package/src/cli/help.ts +6 -6
- package/src/cli/hooks-command.ts +4 -4
- package/src/cli/hooks-report.ts +4 -4
- package/src/cli/launch-auto-update.ts +17 -17
- package/src/cli/management-commands.ts +8 -8
- package/src/cli/management-utils.ts +3 -3
- package/src/cli/management.ts +1 -1
- package/src/cli/plugin-bundles-command.ts +10 -10
- package/src/cli/plugin-command.ts +9 -9
- package/src/cli/service-posture.ts +1 -1
- package/src/cli/status.ts +10 -10
- package/src/cli/surface-command.ts +4 -4
- package/src/cli/tui-startup.ts +23 -23
- package/src/config/run-daemon-config-migration.ts +3 -3
- package/src/config/secret-config.ts +10 -10
- package/src/config/surface.ts +1 -1
- package/src/config/tui-extension-settings.ts +8 -8
- package/src/core/active-model-identity.ts +7 -7
- package/src/core/approval-alert.ts +5 -5
- package/src/core/bookmark-navigation.ts +3 -3
- package/src/core/budget-breach-notifier.ts +6 -6
- package/src/core/compaction-receipt.ts +8 -8
- package/src/core/composer-state.ts +2 -2
- package/src/core/context-usage.ts +1 -1
- package/src/core/conversation-compaction-render.ts +3 -3
- package/src/core/conversation-event-navigation.ts +2 -2
- package/src/core/conversation-fold.ts +9 -9
- package/src/core/conversation-line-cache.ts +14 -14
- package/src/core/conversation-render-context.ts +6 -6
- package/src/core/conversation-rendering.ts +27 -30
- package/src/core/conversation-search-expansion.ts +6 -6
- package/src/core/conversation-splash-state.ts +3 -3
- package/src/core/conversation-turn-structure.ts +13 -13
- package/src/core/conversation-types.ts +3 -3
- package/src/core/conversation-user-receipts.ts +5 -5
- package/src/core/conversation.ts +17 -17
- package/src/core/format-user-error.ts +5 -5
- package/src/core/long-task-notifier.ts +9 -9
- package/src/core/memory-diagnostics-gateway.ts +8 -8
- package/src/core/memory-provenance.ts +5 -5
- package/src/core/model-routing-chip.ts +3 -3
- package/src/core/pairing-tailscale-gateway.ts +3 -3
- package/src/core/permission-mode.ts +5 -5
- package/src/core/power-chip-source.ts +3 -3
- package/src/core/power-status.ts +8 -8
- package/src/core/rewind-receipt.ts +6 -6
- package/src/core/session-resume-core.ts +8 -8
- package/src/core/stream-event-wiring.ts +36 -36
- package/src/core/stream-stall-watchdog.ts +4 -4
- package/src/core/system-message-noise.ts +7 -7
- package/src/core/system-message-router.ts +10 -10
- package/src/core/terminal-notifier.ts +5 -5
- package/src/core/turn-budget-outcome.ts +5 -5
- package/src/core/turn-cancellation.ts +3 -3
- package/src/core/turn-event-wiring.ts +16 -16
- package/src/core/voice-capture-status.ts +2 -2
- package/src/core/voice-provision-gateway.ts +12 -12
- package/src/core/voice-provision-status.ts +19 -19
- package/src/core/voice-stt-gateway.ts +6 -6
- package/src/core/wake-provision-runner.ts +7 -7
- package/src/core/wake-provision-status.ts +17 -17
- package/src/core/workstream-notification.ts +8 -8
- package/src/export/gist-uploader.ts +7 -7
- package/src/input/autocomplete.ts +3 -3
- package/src/input/bookmark-modal.ts +1 -1
- package/src/input/command-args-hint.ts +2 -2
- package/src/input/command-reference.ts +9 -9
- package/src/input/command-registry.ts +32 -32
- package/src/input/commands/acp-runtime.ts +6 -6
- package/src/input/commands/calendar-runtime.ts +9 -9
- package/src/input/commands/channel-pairing.ts +11 -11
- package/src/input/commands/channel-runtime.ts +1 -1
- package/src/input/commands/checkin-runtime.ts +4 -4
- package/src/input/commands/checkpoint-runtime.ts +4 -4
- package/src/input/commands/ci-runtime.ts +4 -4
- package/src/input/commands/cluster-runtime.ts +3 -3
- package/src/input/commands/codebase-runtime.ts +16 -16
- package/src/input/commands/config.ts +6 -6
- package/src/input/commands/connection-status.ts +12 -12
- package/src/input/commands/context-window.ts +2 -2
- package/src/input/commands/cost-attribution-format.ts +4 -4
- package/src/input/commands/cost-runtime.ts +2 -2
- package/src/input/commands/devices-runtime.ts +7 -7
- package/src/input/commands/diff-runtime.ts +2 -2
- package/src/input/commands/editor-runtime.ts +1 -1
- package/src/input/commands/eval.ts +4 -4
- package/src/input/commands/experience-runtime.ts +1 -1
- package/src/input/commands/git-runtime.ts +3 -3
- package/src/input/commands/graph-runtime.ts +3 -3
- package/src/input/commands/guidance-runtime.ts +1 -1
- package/src/input/commands/health-metrics-format.ts +2 -2
- package/src/input/commands/health-runtime.ts +8 -8
- package/src/input/commands/hosted-runtime.ts +13 -13
- package/src/input/commands/image-runtime.ts +6 -6
- package/src/input/commands/intelligence-runtime.ts +2 -2
- package/src/input/commands/local-auth-runtime.ts +3 -3
- package/src/input/commands/local-provider-runtime.ts +3 -3
- package/src/input/commands/local-runtime.ts +7 -7
- package/src/input/commands/mail-runtime.ts +9 -9
- package/src/input/commands/mcp-runtime.ts +1 -1
- package/src/input/commands/memory.ts +13 -13
- package/src/input/commands/notify-runtime.ts +1 -1
- package/src/input/commands/operator-panel-runtime.ts +8 -8
- package/src/input/commands/operator-rpc.ts +3 -3
- package/src/input/commands/operator-runtime.ts +3 -3
- package/src/input/commands/palette-runtime.ts +1 -1
- package/src/input/commands/payment-card-intake.ts +17 -17
- package/src/input/commands/permissions-provenance.ts +7 -7
- package/src/input/commands/permissions-runtime.ts +1 -1
- package/src/input/commands/planning-runtime.ts +19 -19
- package/src/input/commands/platform-services-runtime.ts +2 -2
- package/src/input/commands/policy-dispatch.ts +6 -6
- package/src/input/commands/power-runtime.ts +6 -6
- package/src/input/commands/principals-runtime.ts +3 -3
- package/src/input/commands/product-runtime.ts +3 -3
- package/src/input/commands/profile-render.ts +13 -13
- package/src/input/commands/profile-runtime.ts +13 -13
- package/src/input/commands/profile-types.ts +13 -13
- package/src/input/commands/provider-accounts-runtime.ts +5 -5
- package/src/input/commands/provider.ts +10 -10
- package/src/input/commands/qrcode-runtime.ts +3 -3
- package/src/input/commands/queue-runtime.ts +6 -6
- package/src/input/commands/recall-files-config.ts +4 -4
- package/src/input/commands/recall-files-git.ts +3 -3
- package/src/input/commands/recall-files.ts +12 -12
- package/src/input/commands/recall-query.ts +3 -3
- package/src/input/commands/recall-review.ts +3 -3
- package/src/input/commands/recall-shared.ts +1 -1
- package/src/input/commands/relay-runtime.ts +5 -5
- package/src/input/commands/remote-runtime.ts +3 -3
- package/src/input/commands/review-runtime.ts +8 -8
- package/src/input/commands/rewind-runtime.ts +21 -21
- package/src/input/commands/runtime-services.ts +1 -2
- package/src/input/commands/schedule-nl.ts +2 -2
- package/src/input/commands/schedule-runtime.ts +2 -2
- package/src/input/commands/secret-runtime.ts +3 -3
- package/src/input/commands/session-content.ts +7 -7
- package/src/input/commands/session-picker-filter.ts +3 -3
- package/src/input/commands/session-workflow.ts +10 -10
- package/src/input/commands/session.ts +15 -15
- package/src/input/commands/settings-sync-runtime.ts +2 -2
- package/src/input/commands/share-runtime.ts +4 -4
- package/src/input/commands/shell-core.ts +11 -11
- package/src/input/commands/tasks-runtime.ts +4 -4
- package/src/input/commands/test-runtime.ts +6 -6
- package/src/input/commands/tts-runtime.ts +4 -4
- package/src/input/commands/update-runtime.ts +27 -27
- package/src/input/commands/websearch-runtime.ts +2 -2
- package/src/input/commands/work-plan-runtime.ts +2 -2
- package/src/input/commands/workstream-attempt-dependents.ts +4 -4
- package/src/input/commands/workstream-attempts.ts +16 -16
- package/src/input/commands/workstream-runtime.ts +36 -36
- package/src/input/commands/worktree-runtime.ts +6 -6
- package/src/input/composer-capture.ts +5 -5
- package/src/input/concealed-input.ts +2 -2
- package/src/input/config-modal-types.ts +16 -16
- package/src/input/config-modal.ts +30 -30
- package/src/input/daemon-owned-settings-descriptions.ts +4 -4
- package/src/input/delete-key-policy.ts +1 -1
- package/src/input/exec-env-scrub-config.ts +7 -7
- package/src/input/feature-unit-layout.ts +5 -5
- package/src/input/feed-context-factory.ts +38 -38
- package/src/input/file-picker.ts +1 -1
- package/src/input/handler-command-route.ts +2 -2
- package/src/input/handler-content-actions.ts +8 -8
- package/src/input/handler-feed-routes.ts +13 -13
- package/src/input/handler-feed.ts +31 -31
- package/src/input/handler-interactions.ts +2 -2
- package/src/input/handler-modal-routes.ts +13 -13
- package/src/input/handler-modal-stack.ts +1 -1
- package/src/input/handler-modal-token-routes.ts +1 -1
- package/src/input/handler-onboarding-daemon-adopt.ts +6 -6
- package/src/input/handler-picker-routes.ts +7 -7
- package/src/input/handler-prompt-buffer.ts +1 -1
- package/src/input/handler-shortcuts.ts +12 -12
- package/src/input/handler-types.ts +3 -3
- package/src/input/handler-ui-state.ts +1 -1
- package/src/input/handler.ts +9 -9
- package/src/input/input-history.ts +1 -1
- package/src/input/keybindings.ts +13 -13
- package/src/input/kill-ring.ts +7 -11
- package/src/input/model-picker-filter.ts +3 -3
- package/src/input/model-picker-items.ts +5 -5
- package/src/input/model-picker-types.ts +2 -2
- package/src/input/model-picker.ts +18 -18
- package/src/input/onboarding/onboarding-feature-units.ts +9 -13
- package/src/input/onboarding/onboarding-provider-key-fields.ts +3 -3
- package/src/input/onboarding/onboarding-runtime-status.ts +3 -3
- package/src/input/onboarding/onboarding-wizard-apply.ts +6 -6
- package/src/input/onboarding/onboarding-wizard-cloudflare-step.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-constants.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-external-surfaces.ts +4 -4
- package/src/input/onboarding/onboarding-wizard-network-adopt.ts +6 -6
- package/src/input/onboarding/onboarding-wizard-steps.ts +2 -2
- package/src/input/panel-integration-actions.ts +3 -3
- package/src/input/panel-mouse-geometry.ts +1 -1
- package/src/input/panel-paste-flood-guard.ts +9 -9
- package/src/input/payments-config.ts +15 -15
- package/src/input/profile-picker-modal.ts +1 -1
- package/src/input/provider-key-intake.ts +9 -9
- package/src/input/relay-settings-descriptions.ts +3 -3
- package/src/input/sandbox-exec-config.ts +9 -9
- package/src/input/search.ts +18 -18
- package/src/input/selection-modal-queue.ts +10 -10
- package/src/input/selection-modal.ts +2 -2
- package/src/input/session-picker-modal.ts +7 -7
- package/src/input/settings-modal-activation.ts +1 -1
- package/src/input/settings-modal-adjustment.ts +2 -2
- package/src/input/settings-modal-commit.ts +6 -6
- package/src/input/settings-modal-connections.ts +2 -2
- package/src/input/settings-modal-data.ts +29 -29
- package/src/input/settings-modal-mutations.ts +7 -7
- package/src/input/settings-modal-reset.ts +3 -3
- package/src/input/settings-modal-search.ts +6 -6
- package/src/input/settings-modal-secrets.ts +3 -3
- package/src/input/settings-modal-types.ts +16 -16
- package/src/input/settings-modal.ts +4 -4
- package/src/input/voice-local-settings.ts +3 -3
- package/src/input/worktree-setup-config.ts +8 -8
- package/src/main.ts +15 -15
- package/src/panels/agent-inspector-shared.ts +5 -5
- package/src/panels/base-panel.ts +3 -3
- package/src/panels/builtin/agent.ts +3 -3
- package/src/panels/builtin/development.ts +4 -4
- package/src/panels/builtin/knowledge.ts +1 -1
- package/src/panels/builtin/operations.ts +12 -12
- package/src/panels/builtin/session.ts +8 -8
- package/src/panels/builtin/shared.ts +6 -6
- package/src/panels/builtin-modals.ts +8 -8
- package/src/panels/confirm-state.ts +5 -5
- package/src/panels/cost-tracker-panel.ts +22 -22
- package/src/panels/diff-panel.ts +20 -20
- package/src/panels/diff-review-model.ts +5 -5
- package/src/panels/diff-review-panel.ts +5 -5
- package/src/panels/eval-registry.ts +2 -2
- package/src/panels/expandable-list-panel.ts +5 -5
- package/src/panels/fleet-acts.ts +20 -20
- package/src/panels/fleet-deep-link.ts +5 -5
- package/src/panels/fleet-gateway.ts +12 -12
- package/src/panels/fleet-observed-render.ts +11 -11
- package/src/panels/fleet-panel-format.ts +14 -14
- package/src/panels/fleet-panel-worktree-detail.ts +8 -8
- package/src/panels/fleet-panel.ts +34 -34
- package/src/panels/fleet-read-model.ts +49 -49
- package/src/panels/fleet-spawn.ts +15 -15
- package/src/panels/fleet-steer.ts +7 -7
- package/src/panels/fleet-stop.ts +5 -5
- package/src/panels/fleet-tabs.ts +14 -14
- package/src/panels/fleet-transcript.ts +26 -26
- package/src/panels/git-panel.ts +8 -8
- package/src/panels/hosted-session-feed.ts +13 -13
- package/src/panels/hosted-session-panel.ts +7 -7
- package/src/panels/index.ts +1 -1
- package/src/panels/local-auth-panel.ts +15 -15
- package/src/panels/memory-consolidation-gateway.ts +8 -8
- package/src/panels/modals/devices-modal.ts +8 -8
- package/src/panels/modals/hooks-modal.ts +1 -1
- package/src/panels/modals/keybindings-modal.ts +5 -5
- package/src/panels/modals/knowledge-modal.ts +2 -2
- package/src/panels/modals/local-auth-modal.ts +4 -4
- package/src/panels/modals/marketplace-modal.ts +3 -3
- package/src/panels/modals/memory-modal.ts +19 -19
- package/src/panels/modals/modal-surface-helpers.ts +1 -1
- package/src/panels/modals/modal-theme.ts +3 -3
- package/src/panels/modals/pairing-modal.ts +19 -19
- package/src/panels/modals/planning-modal.ts +11 -11
- package/src/panels/modals/plugins-modal.ts +1 -1
- package/src/panels/modals/policy-modal.ts +4 -4
- package/src/panels/modals/provider-health-modal.ts +1 -1
- package/src/panels/modals/remote-modal.ts +1 -1
- package/src/panels/modals/sandbox-modal.ts +2 -2
- package/src/panels/modals/security-modal.ts +4 -4
- package/src/panels/modals/services-modal.ts +1 -1
- package/src/panels/modals/work-plan-modal.ts +4 -4
- package/src/panels/notifications-feed.ts +6 -6
- package/src/panels/notifications-panel.ts +6 -6
- package/src/panels/panel-confirm-overlay.ts +4 -4
- package/src/panels/panel-manager.ts +13 -13
- package/src/panels/plugins-panel.ts +6 -6
- package/src/panels/polish-core.ts +2 -2
- package/src/panels/polish-tables.ts +2 -2
- package/src/panels/polish.ts +1 -1
- package/src/panels/project-planning-answer-actions.ts +3 -3
- package/src/panels/scrollable-list-panel.ts +15 -15
- package/src/panels/search-focus.ts +1 -1
- package/src/panels/session-maintenance.ts +1 -1
- package/src/panels/skills-panel.ts +3 -3
- package/src/panels/token-budget-panel.ts +11 -11
- package/src/panels/types.ts +14 -14
- package/src/panels/workstream-graph-render.ts +5 -5
- package/src/panels/wrfc-panel-format.ts +1 -1
- package/src/permissions/broker-approval-card.ts +13 -13
- package/src/permissions/hunk-selection.ts +13 -13
- package/src/permissions/prompt.ts +22 -22
- package/src/permissions/sandbox-exec-gate.ts +5 -5
- package/src/providers/provider-classification.ts +1 -1
- package/src/providers/reasoning-effort-surface.ts +12 -12
- package/src/renderer/ansi-sanitize.ts +5 -6
- package/src/renderer/autocomplete-overlay.ts +5 -5
- package/src/renderer/block-actions-overlay.ts +1 -1
- package/src/renderer/bookmark-modal.ts +1 -1
- package/src/renderer/code-block.ts +2 -2
- package/src/renderer/compaction-history-modal.ts +4 -4
- package/src/renderer/compaction-preview.ts +5 -5
- package/src/renderer/compaction-quality.ts +5 -5
- package/src/renderer/composer-fragments.ts +6 -6
- package/src/renderer/compositor.ts +9 -9
- package/src/renderer/config-modal.ts +3 -3
- package/src/renderer/context-inspector.ts +1 -1
- package/src/renderer/context-status-hint.ts +10 -10
- package/src/renderer/conversation-layout.ts +2 -2
- package/src/renderer/conversation-overlays.ts +2 -2
- package/src/renderer/conversation-surface.ts +6 -6
- package/src/renderer/diff.ts +4 -4
- package/src/renderer/fleet-tab-strip.ts +2 -2
- package/src/renderer/footer-tips.ts +4 -4
- package/src/renderer/fullscreen-primitives.ts +1 -1
- package/src/renderer/git-status.ts +5 -5
- package/src/renderer/header-line.ts +5 -5
- package/src/renderer/help-overlay.ts +5 -5
- package/src/renderer/hint-grammar.ts +2 -2
- package/src/renderer/layout.ts +1 -1
- package/src/renderer/markdown-inline.ts +3 -3
- package/src/renderer/markdown-table.ts +7 -7
- package/src/renderer/modal-factory.ts +3 -3
- package/src/renderer/model-picker-overlay.ts +2 -2
- package/src/renderer/model-workspace.ts +7 -7
- package/src/renderer/onboarding/onboarding-wizard.ts +1 -1
- package/src/renderer/overlay-box.ts +1 -1
- package/src/renderer/panel-composite.ts +5 -5
- package/src/renderer/panel-workspace-bar.ts +1 -1
- package/src/renderer/process-indicator.ts +8 -8
- package/src/renderer/profile-picker-modal.ts +3 -3
- package/src/renderer/prompt-content-width.ts +1 -1
- package/src/renderer/search-overlay.ts +3 -3
- package/src/renderer/selection-modal-overlay.ts +6 -6
- package/src/renderer/semantic-diff.ts +6 -7
- package/src/renderer/session-picker-modal.ts +24 -24
- package/src/renderer/settings-modal-connections.ts +3 -3
- package/src/renderer/settings-modal-helpers.ts +16 -16
- package/src/renderer/settings-modal.ts +10 -10
- package/src/renderer/shell-surface.ts +8 -8
- package/src/renderer/status-glyphs.ts +6 -6
- package/src/renderer/syntax-highlighter.ts +2 -3
- package/src/renderer/system-message.ts +3 -3
- package/src/renderer/tab-strip.ts +2 -2
- package/src/renderer/term-caps.ts +12 -12
- package/src/renderer/terminal-bg-probe.ts +10 -10
- package/src/renderer/terminal-escapes.ts +1 -1
- package/src/renderer/theme-mode-config.ts +3 -3
- package/src/renderer/theme.ts +34 -34
- package/src/renderer/thinking.ts +1 -1
- package/src/renderer/tool-call.ts +5 -5
- package/src/renderer/tool-result-expanded-lines.ts +3 -3
- package/src/renderer/tool-result-summary.ts +6 -6
- package/src/renderer/turn-injection.ts +9 -9
- package/src/renderer/ui-factory.ts +33 -33
- package/src/renderer/ui-primitives.ts +4 -4
- package/src/runtime/bootstrap-command-parts.ts +3 -3
- package/src/runtime/bootstrap-core.ts +21 -21
- package/src/runtime/bootstrap-hook-bridge.ts +8 -8
- package/src/runtime/bootstrap-shell.ts +9 -9
- package/src/runtime/bootstrap.ts +16 -16
- package/src/runtime/client/approval-updates.ts +3 -3
- package/src/runtime/client/build-floors.ts +7 -7
- package/src/runtime/client/daemon-attach-handshake.ts +5 -5
- package/src/runtime/client/fleet-union.ts +7 -7
- package/src/runtime/client/host-service-status.ts +2 -2
- package/src/runtime/client/hosted-exit.ts +4 -4
- package/src/runtime/client/hosted-roster.ts +4 -4
- package/src/runtime/client/hosted-session-stream.ts +5 -5
- package/src/runtime/client/hosted-sessions.ts +8 -8
- package/src/runtime/client/operator-endpoint.ts +14 -14
- package/src/runtime/client/spine-adoption.ts +8 -8
- package/src/runtime/context-accounting-source.ts +4 -4
- package/src/runtime/context.ts +2 -2
- package/src/runtime/conversation-rewind-port.ts +6 -6
- package/src/runtime/credential-composition.ts +2 -2
- package/src/runtime/daemon-attach-notices.ts +6 -6
- package/src/runtime/diagnostics/panels/index.ts +1 -1
- package/src/runtime/diagnostics/panels/ops.ts +2 -2
- package/src/runtime/disposal-wiring.ts +6 -6
- package/src/runtime/index.ts +11 -11
- package/src/runtime/install-self-check-startup.ts +4 -4
- package/src/runtime/install-self-check.ts +6 -6
- package/src/runtime/interaction-seams.ts +4 -4
- package/src/runtime/knowledge-services.ts +2 -2
- package/src/runtime/legacy-daemon-migration.ts +37 -37
- package/src/runtime/legacy-daemon-reconcile.ts +30 -30
- package/src/runtime/memory-governance-services.ts +3 -3
- package/src/runtime/memory-spine-transport.ts +3 -3
- package/src/runtime/notification-dispatch.ts +4 -4
- package/src/runtime/onboarding/apply.ts +1 -1
- package/src/runtime/onboarding/derivation.ts +1 -1
- package/src/runtime/onboarding/fast-path.ts +7 -7
- package/src/runtime/onboarding/progress.ts +2 -2
- package/src/runtime/onboarding/provider-key-capture.ts +4 -4
- package/src/runtime/onboarding/snapshot.ts +2 -2
- package/src/runtime/onboarding/state.ts +4 -4
- package/src/runtime/onboarding/types.ts +4 -4
- package/src/runtime/orchestrator-core-services.ts +5 -5
- package/src/runtime/path-shadow-startup.ts +3 -3
- package/src/runtime/perf/panel-contracts.ts +1 -1
- package/src/runtime/power-keepawake-remote.ts +6 -6
- package/src/runtime/process-lifecycle.ts +14 -14
- package/src/runtime/provider-fallback.ts +3 -3
- package/src/runtime/recovery-autosave.ts +3 -3
- package/src/runtime/recovery-decisions.ts +19 -19
- package/src/runtime/recovery-offer-wiring.ts +4 -4
- package/src/runtime/recovery-prompt.ts +20 -20
- package/src/runtime/relay-reachability-bridge.ts +3 -3
- package/src/runtime/release-artifacts.ts +1 -1
- package/src/runtime/resume-notice.ts +20 -20
- package/src/runtime/runtime-services-types.ts +20 -20
- package/src/runtime/services.ts +20 -20
- package/src/runtime/session-continuity-hints.ts +1 -1
- package/src/runtime/session-inbound-inputs.ts +12 -12
- package/src/runtime/session-resume-liveness-confirm.ts +4 -4
- package/src/runtime/session-spine-transport.ts +3 -3
- package/src/runtime/store/domains/panels.ts +2 -2
- package/src/runtime/store/domains/ui-perf.ts +2 -2
- package/src/runtime/store/index.ts +1 -1
- package/src/runtime/store/selectors/index.ts +1 -1
- package/src/runtime/store/state.ts +2 -2
- package/src/runtime/ui-services.ts +3 -3
- package/src/runtime/workspace-checkpointing.ts +3 -3
- package/src/runtime/wrfc-persistence.ts +15 -15
- package/src/scripts/process-messages.ts +1 -1
- package/src/shell/blocking-input.ts +9 -9
- package/src/shell/recovery-input-helpers.ts +2 -2
- package/src/shell/retry-affordance.ts +9 -9
- package/src/shell/ui-openers.ts +14 -14
- package/src/shell/voice-capture-shell.ts +3 -3
- package/src/tools/wrfc-agent-guard.ts +4 -4
- package/src/utils/browser.ts +2 -2
- package/src/utils/format-duration.ts +3 -3
- package/src/utils/format-number.ts +2 -2
- package/src/utils/splash-lines.ts +4 -4
- package/src/utils/terminal-width.ts +6 -6
- package/src/verification/verification-ledger.ts +25 -25
- package/src/version.ts +3 -3
|
@@ -14,7 +14,7 @@ import { UI_TONES } from './ui-primitives.ts';
|
|
|
14
14
|
* tree-sitter parse doesn't visibly shift color mid-stream.
|
|
15
15
|
* `accent` and `bg` are chrome (the language-label header bar and the body
|
|
16
16
|
* background), not syntax tokens, and keep their original VS Code Dark+
|
|
17
|
-
* values
|
|
17
|
+
* values, folded here from two separate literals (one in the header, one
|
|
18
18
|
* duplicated on the footer line) into a single named source.
|
|
19
19
|
*/
|
|
20
20
|
const FALLBACK_THEME = {
|
|
@@ -389,7 +389,7 @@ export function renderCodeBlock(
|
|
|
389
389
|
}
|
|
390
390
|
line[cx] = createStyledCell(ch, { fg: token.fg, bg: BG, bold: token.bold, italic: token.italic });
|
|
391
391
|
// Bound the wide-glyph placeholder against the body's own right edge
|
|
392
|
-
// (effectiveWidth), not the full line width
|
|
392
|
+
// (effectiveWidth), not the full line width, otherwise a 2-column
|
|
393
393
|
// glyph landing on the last body column spills its placeholder cell
|
|
394
394
|
// into the reserved right-margin band the header/footer stop at.
|
|
395
395
|
if (cw === 2 && cx + 1 < effectiveWidth) line[cx + 1] = { ...line[cx], char: '' };
|
|
@@ -17,7 +17,7 @@ import type { CompactionQualityScore } from './compaction-quality.ts';
|
|
|
17
17
|
// ─── formatCompactionEvent ────────────────────────────────────────────────────
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
* Exported for direct unit testing ()
|
|
20
|
+
* Exported for direct unit testing (), the grade suffix is a pure
|
|
21
21
|
* function of the event and an optional score, independent of whichever
|
|
22
22
|
* runtime lookup (getCompactionQualityScore) supplies that score.
|
|
23
23
|
*/
|
|
@@ -35,7 +35,7 @@ export function formatCompactionEvent(
|
|
|
35
35
|
const trigger = ev.trigger === 'auto' ? 'auto' : 'manual';
|
|
36
36
|
// Honest omission: no score means none was computed for this event (e.g. it
|
|
37
37
|
// pre-dates this feature, or ran through the small-window path, which has
|
|
38
|
-
// no CompactionEvent to key a score by)
|
|
38
|
+
// no CompactionEvent to key a score by), never fabricate a grade.
|
|
39
39
|
const qualityStr = qualityScore ? ` quality=${qualityScore.grade} (${qualityScore.score.toFixed(2)})` : '';
|
|
40
40
|
return (
|
|
41
41
|
`#${n} ${timeStr} [${trigger}] ` +
|
|
@@ -56,7 +56,7 @@ function fmtN(n: number): string {
|
|
|
56
56
|
export function buildCompactionHistoryText(): string {
|
|
57
57
|
const events = getCompactionEvents();
|
|
58
58
|
if (events.length === 0) {
|
|
59
|
-
return '[Context] No compactions recorded this session. (Restore is not available
|
|
59
|
+
return '[Context] No compactions recorded this session. (Restore is not available: the SDK does not yet expose a snapshot restore API.)';
|
|
60
60
|
}
|
|
61
61
|
const lines: string[] = [
|
|
62
62
|
`[Context] Compaction history (${events.length} total, most recent first):`,
|
|
@@ -66,6 +66,6 @@ export function buildCompactionHistoryText(): string {
|
|
|
66
66
|
const ev = ordered[i]!;
|
|
67
67
|
lines.push(' ' + formatCompactionEvent(ev, ordered.length - i, getCompactionQualityScore(ev.timestamp)));
|
|
68
68
|
}
|
|
69
|
-
lines.push(' (Restore not available
|
|
69
|
+
lines.push(' (Restore not available: the SDK does not yet expose a snapshot restore API.)');
|
|
70
70
|
return lines.join('\n');
|
|
71
71
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Pre-compact: shows an honest estimate of what compaction will do
|
|
5
5
|
* (message count and token estimate before → after). The SDK has no dry-run
|
|
6
6
|
* API; we derive the after-estimate from the DEFAULT_COMPACTION_CONFIG
|
|
7
|
-
* totalCeiling (6500 tokens)
|
|
7
|
+
* totalCeiling (6500 tokens), clearly labelled as an ESTIMATE.
|
|
8
8
|
*
|
|
9
9
|
* Post-compact: shows a before/after notice using the CompactionEvent
|
|
10
10
|
* data returned by compactMessages(), which contains the real
|
|
@@ -49,7 +49,7 @@ export interface CompactionAfterOptions {
|
|
|
49
49
|
/**
|
|
50
50
|
* Out-of-band quality-score grade for this run (). Omitted or null
|
|
51
51
|
* when no score was computed (e.g. the small-window compaction path, which
|
|
52
|
-
* has no CompactionEvent to key a score by)
|
|
52
|
+
* has no CompactionEvent to key a score by), no line is rendered then.
|
|
53
53
|
*/
|
|
54
54
|
readonly qualityScore?: CompactionQualityScore | null | undefined;
|
|
55
55
|
}
|
|
@@ -78,7 +78,7 @@ export function buildCompactionPreview(opts: CompactionPreviewOptions): string {
|
|
|
78
78
|
|
|
79
79
|
return (
|
|
80
80
|
`[Context] ${triggerStr} conversation: ~${fmtN(tokensBefore)} tokens across ${msgCount} message${msgCount === 1 ? '' : 's'}${contextStr}.` +
|
|
81
|
-
` Estimated result: ~${fmtN(tokensAfterEstimate)} tokens (estimate
|
|
81
|
+
` Estimated result: ~${fmtN(tokensAfterEstimate)} tokens (estimate; actual depends on content).` +
|
|
82
82
|
(pinStr ? ` ${pinStr.trim()}` : '')
|
|
83
83
|
);
|
|
84
84
|
}
|
|
@@ -129,7 +129,7 @@ function fmtN(n: number): string {
|
|
|
129
129
|
/**
|
|
130
130
|
* Build the /keep command usage text (shown when no args are provided).
|
|
131
131
|
*
|
|
132
|
-
* Exported for testability
|
|
132
|
+
* Exported for testability, the shell-core handler renders this string directly.
|
|
133
133
|
*/
|
|
134
134
|
export function buildPinUsageText(): string {
|
|
135
135
|
return (
|
|
@@ -147,7 +147,7 @@ export function buildPinUsageText(): string {
|
|
|
147
147
|
* @param text - The pinned text
|
|
148
148
|
* @param count - Total pinned memory count after adding
|
|
149
149
|
*
|
|
150
|
-
* Exported for testability
|
|
150
|
+
* Exported for testability, the shell-core handler renders this string directly.
|
|
151
151
|
*/
|
|
152
152
|
export function buildPinSuccessText(id: string, text: string, count: number): string {
|
|
153
153
|
return (
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Reality check: the SDK's `computeQualityScore()`
|
|
5
5
|
* (platform/runtime/compaction/quality-score.ts) is only ever called from a
|
|
6
6
|
* SEPARATE pipeline, `CompactionManager` (platform/runtime/compaction/manager.ts).
|
|
7
|
-
* The TUI's actual `/compact` path never instantiates `CompactionManager
|
|
7
|
+
* The TUI's actual `/compact` path never instantiates `CompactionManager`, it
|
|
8
8
|
* goes through `platform/core/context-compaction.ts` via
|
|
9
9
|
* `ConversationManager.compact()` (see `compactConversation()` in
|
|
10
10
|
* runtime-services.ts), which has no scoring of its own. Adopting the whole
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* Honesty note: the `strategy` value passed to `computeQualityScore()` is a
|
|
21
21
|
* BORROWED rubric label describing what `compactConversation()`'s structured
|
|
22
22
|
* multi-section extraction actually does (collapse the whole conversation
|
|
23
|
-
* into one handoff message)
|
|
23
|
+
* into one handoff message), it is NOT a real `CompactionStrategy`
|
|
24
24
|
* escalation result, and no strategy switch is triggered from it. Every
|
|
25
25
|
* rendering of the score says so explicitly (see `formatQualityScoreLine`).
|
|
26
26
|
*
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* api-extractor regen for a value the SDK's own compaction log never
|
|
30
30
|
* populates). Keyed by `CompactionEvent.timestamp` rather than array index,
|
|
31
31
|
* because `compactSmallWindow`'s null-event path (small-context-window
|
|
32
|
-
* models
|
|
32
|
+
* models, see runtime-services.ts) can create index gaps.
|
|
33
33
|
*/
|
|
34
34
|
|
|
35
35
|
import { computeQualityScore, describeScore } from '@/runtime/index.ts';
|
|
@@ -41,7 +41,7 @@ export type { CompactionQualityScore } from '@/runtime/index.ts';
|
|
|
41
41
|
/**
|
|
42
42
|
* Bound the TUI-local score store the same way the SDK bounds its own
|
|
43
43
|
* compaction event log (context-compaction.ts caps at 50 and shifts the
|
|
44
|
-
* oldest entry)
|
|
44
|
+
* oldest entry), a long-running session should not accumulate this forever.
|
|
45
45
|
*/
|
|
46
46
|
const MAX_TRACKED_SCORES = 50;
|
|
47
47
|
|
|
@@ -80,7 +80,7 @@ export function scoreCompactionRun(input: ScoreCompactionRunInput): CompactionQu
|
|
|
80
80
|
messages: input.messagesBefore,
|
|
81
81
|
tokensBefore: input.tokensBefore,
|
|
82
82
|
contextWindow: input.contextWindow,
|
|
83
|
-
// Borrowed rubric label, not a real strategy escalation
|
|
83
|
+
// Borrowed rubric label, not a real strategy escalation, see module doc.
|
|
84
84
|
strategy: 'collapse',
|
|
85
85
|
};
|
|
86
86
|
const strategyOutput: StrategyOutput = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// ---------------------------------------------------------------------------
|
|
2
|
-
// composer-fragments.ts
|
|
2
|
+
// composer-fragments.ts, composer-adjacent transcript fragments extracted from
|
|
3
3
|
// ui-factory.ts (file-size hygiene): the mid-turn queued-message editable list
|
|
4
4
|
// and the optional "used N memories" provenance chip. Pure renderers; the
|
|
5
5
|
// UIFactory static methods are thin wrappers over these.
|
|
@@ -15,14 +15,14 @@ import { activeTheme } from './theme.ts';
|
|
|
15
15
|
* message shows a 1-based number so it can be named to `/queue edit <n> …` /
|
|
16
16
|
* `/queue delete <n>` (the SDK editQueuedMessage / deleteQueuedMessage verbs). A
|
|
17
17
|
* delivered message has already left the queue, so the list only ever shows what
|
|
18
|
-
* is still editable
|
|
18
|
+
* is still editable, delivery is immutability, made visible.
|
|
19
19
|
*/
|
|
20
20
|
export function renderQueuedMessageList(width: number, items: readonly { readonly id: string; readonly text: string }[]): Line[] {
|
|
21
21
|
if (items.length === 0) return [];
|
|
22
22
|
const t = activeUiTones();
|
|
23
23
|
const bodyBg = activeTheme().collapsedBodyBg;
|
|
24
24
|
const lines: Line[] = [];
|
|
25
|
-
const header = `${items.length} queued
|
|
25
|
+
const header = `${items.length} queued: /queue edit·delete until delivered`;
|
|
26
26
|
lines.push(...renderConversationFragment(header, width, { prefix: ' ⧗ ', prefixFg: t.state.reasoning, text: t.fg.dim, bodyBg, dim: true }));
|
|
27
27
|
items.forEach((item, index) => {
|
|
28
28
|
lines.push(...renderConversationFragment(item.text, width, { prefix: ` ${index + 1}. `, prefixFg: t.state.reasoning, text: t.fg.dim, bodyBg, dim: true }));
|
|
@@ -32,7 +32,7 @@ export function renderQueuedMessageList(width: number, items: readonly { readonl
|
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* One drilled-in memory-provenance row. `record` is the RESOLVED record summary
|
|
35
|
-
* (undefined = still resolving, null = no longer available)
|
|
35
|
+
* (undefined = still resolving, null = no longer available), the drill-in
|
|
36
36
|
* shows a human summary, never a raw record id, matching the webui's detail
|
|
37
37
|
* fetch (per-id, so one missing record never blanks the rest).
|
|
38
38
|
*/
|
|
@@ -44,7 +44,7 @@ export interface MemoryProvenanceEntry {
|
|
|
44
44
|
/**
|
|
45
45
|
* The optional "used N memories" turn chip. Collapsed: one small line naming the
|
|
46
46
|
* count with the drill-in hint. Expanded (Alt+M): the same line followed by one
|
|
47
|
-
* line per memory
|
|
47
|
+
* line per memory, its resolved SUMMARY (with the record class), a "resolving…"
|
|
48
48
|
* placeholder while the fetch is in flight, or an honest "no longer available"
|
|
49
49
|
* for a record that has since been forgotten. Empty when no memories were used.
|
|
50
50
|
*/
|
|
@@ -53,7 +53,7 @@ export function renderMemoryProvenanceChip(width: number, count: number, entries
|
|
|
53
53
|
const t = activeUiTones();
|
|
54
54
|
const bodyBg = activeTheme().collapsedBodyBg;
|
|
55
55
|
const noun = count === 1 ? 'memory' : 'memories';
|
|
56
|
-
const header = expanded ? `used ${count} ${noun}
|
|
56
|
+
const header = expanded ? `used ${count} ${noun}: Alt+M to hide` : `used ${count} ${noun}: Alt+M to list`;
|
|
57
57
|
const lines: Line[] = renderConversationFragment(header, width, { prefix: ' ◆ ', prefixFg: t.state.info, text: t.fg.dim, bodyBg, dim: true });
|
|
58
58
|
if (expanded) {
|
|
59
59
|
entries.forEach((entry, index) => {
|
|
@@ -28,7 +28,7 @@ export interface SearchInfo {
|
|
|
28
28
|
export interface PanelCompositeData {
|
|
29
29
|
/**
|
|
30
30
|
* The single consolidated workspace tab bar spanning all open panels across
|
|
31
|
-
* both panes. There are no per-pane tab bars
|
|
31
|
+
* both panes. There are no per-pane tab bars, pane focus is shown by the
|
|
32
32
|
* accent border (see `topFocused`/`bottomFocused`).
|
|
33
33
|
*/
|
|
34
34
|
workspaceBar: Line;
|
|
@@ -62,7 +62,7 @@ export interface CompositeRequest {
|
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
64
|
* Compositor - Authoritative TUI layout engine with Selection Overlay.
|
|
65
|
-
* Decoupled from global state
|
|
65
|
+
* Decoupled from global state, all needed data is passed as parameters.
|
|
66
66
|
*/
|
|
67
67
|
export class Compositor {
|
|
68
68
|
/** Double-buffer reuse: back is written, front is the last-rendered reference. */
|
|
@@ -80,7 +80,7 @@ export class Compositor {
|
|
|
80
80
|
* and anything that writes to the terminal outside composite() moves content
|
|
81
81
|
* the compositor never wrote. After either, a row the model believes is
|
|
82
82
|
* already blank is never re-emitted, so whatever the terminal is showing
|
|
83
|
-
* there
|
|
83
|
+
* there, splash art, a stale rule line, survives every later frame. The
|
|
84
84
|
* erase is what clears cells the diff structurally skips (wide-glyph
|
|
85
85
|
* continuation cells, see DiffEngine.diff), which a diff against a null
|
|
86
86
|
* front buffer alone cannot do.
|
|
@@ -93,12 +93,12 @@ export class Compositor {
|
|
|
93
93
|
this.diffEngine = new DiffEngine(this.caps);
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
/** Exposed for unit tests
|
|
96
|
+
/** Exposed for unit tests, returns the detected color capability. */
|
|
97
97
|
public get termCapsForTest(): TermColorCaps {
|
|
98
98
|
return this.caps;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
/** Exposed for unit tests
|
|
101
|
+
/** Exposed for unit tests, returns the last composited buffer. */
|
|
102
102
|
public get lastBufferForTest(): TerminalBuffer | null {
|
|
103
103
|
return this.frontBuffer;
|
|
104
104
|
}
|
|
@@ -126,7 +126,7 @@ export class Compositor {
|
|
|
126
126
|
public composite(params: CompositeRequest): void {
|
|
127
127
|
const { width, height, header, viewport, footer, selection, search, panel, panelWidth } = params;
|
|
128
128
|
// A size change reallocates the buffer, which drops every record of what
|
|
129
|
-
// the terminal is currently showing
|
|
129
|
+
// the terminal is currently showing, repaint in full rather than diff
|
|
130
130
|
// against a model that no longer describes the screen.
|
|
131
131
|
const resized = this.frontBuffer !== null
|
|
132
132
|
&& (this.frontBuffer.width !== width || this.frontBuffer.height !== height);
|
|
@@ -148,7 +148,7 @@ export class Compositor {
|
|
|
148
148
|
const leftWidth = hasPanel ? Math.max(1, width - panelWidth - 1) : width;
|
|
149
149
|
const sepX = hasPanel ? leftWidth : -1;
|
|
150
150
|
|
|
151
|
-
// 1. Draw Header
|
|
151
|
+
// 1. Draw Header, always full width
|
|
152
152
|
header.forEach((line, i) => newBuffer.blitLine(i, line));
|
|
153
153
|
|
|
154
154
|
// 2. Draw Viewport directly after the supplied header.
|
|
@@ -320,7 +320,7 @@ export class Compositor {
|
|
|
320
320
|
// (rows past the supplied viewport lines are covered by the loop above,
|
|
321
321
|
// separator column included, so they can no longer keep a stale frame.)
|
|
322
322
|
|
|
323
|
-
// 3. Draw Footer (Pinned to Bottom)
|
|
323
|
+
// 3. Draw Footer (Pinned to Bottom), always full width
|
|
324
324
|
const footerStart = height - footer.length;
|
|
325
325
|
footer.forEach((line, i) => {
|
|
326
326
|
const screenY = footerStart + i;
|
|
@@ -329,7 +329,7 @@ export class Compositor {
|
|
|
329
329
|
});
|
|
330
330
|
|
|
331
331
|
// 4. Diff and Render
|
|
332
|
-
// Diff against front-buffer (last-rendered), then swap front/back
|
|
332
|
+
// Diff against front-buffer (last-rendered), then swap front/back, no clone() needed.
|
|
333
333
|
// On a full repaint the SGR run-state is reset (the erase below leaves the
|
|
334
334
|
// terminal's attributes unknown) and the diff runs against no previous
|
|
335
335
|
// frame, so every cell of the grid is emitted.
|
|
@@ -5,13 +5,13 @@ import { activeUiTones } from './theme.ts';
|
|
|
5
5
|
import type { ConfigModal, ConfigModalRenderModel } from '../input/config-modal.ts';
|
|
6
6
|
|
|
7
7
|
// Matches ModalFactory.createModal's own box-width computation (margin 4,
|
|
8
|
-
// requested max width 76
|
|
8
|
+
// requested max width 76, see renderConfigModalModel below) so the
|
|
9
9
|
// wrap-clamp in ConfigModal.getRenderModel() measures against the SAME width
|
|
10
10
|
// the list section will actually wrap at, at the current terminal size.
|
|
11
11
|
const MODAL_MARGIN = 4;
|
|
12
12
|
const MODAL_MAX_WIDTH = 76;
|
|
13
13
|
/**
|
|
14
|
-
* renderConfigModal
|
|
14
|
+
* renderConfigModal, the single render path for every ConfigModalSurface.
|
|
15
15
|
* Reads the host's frozen-structure-plus-live-values render model and maps it
|
|
16
16
|
* onto ModalFactory.createModal (the same renderer settings-modal uses), so the
|
|
17
17
|
* chrome, tab strip, list, and footer are one dialect across all migrated
|
|
@@ -32,7 +32,7 @@ export function renderConfigModal(modal: ConfigModal, width: number, height: num
|
|
|
32
32
|
return renderConfigModalModel(model, width);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
/** Pure model→Line[] mapping
|
|
35
|
+
/** Pure model→Line[] mapping, the shared inner step of renderConfigModal. */
|
|
36
36
|
function renderConfigModalModel(model: ConfigModalRenderModel, width: number): Line[] {
|
|
37
37
|
// Read the active-mode chrome tones per call (this render path is not on a
|
|
38
38
|
// hot loop; the modal renders once per keystroke).
|
|
@@ -8,7 +8,7 @@ import { UI_TONES } from './ui-primitives.ts';
|
|
|
8
8
|
// ─── ContextInspectorModal ────────────────────────────────────────────────────
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* ContextInspectorModal
|
|
11
|
+
* ContextInspectorModal, state for the context inspector overlay.
|
|
12
12
|
*/
|
|
13
13
|
export class ContextInspectorModal {
|
|
14
14
|
public active = false;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Context status hint
|
|
2
|
+
* Context status hint, TASK-056.
|
|
3
3
|
*
|
|
4
4
|
* Produces a short, dismissible status-line hint when the session maintenance
|
|
5
5
|
* level indicates compaction is recommended or repair is needed. The hint is
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
*
|
|
16
16
|
* Evidence policy (why the guards below exist)
|
|
17
17
|
* ────────────────────────────────────────────
|
|
18
|
-
* A fresh boot printed "Context high (0% used)
|
|
18
|
+
* A fresh boot printed "Context high (0% used), auto-compact will run before
|
|
19
19
|
* the next turn." before a single token had been counted. The evaluator was
|
|
20
20
|
* not at fault: `evaluateSessionMaintenance` reaches 'suggest-compact' when
|
|
21
21
|
* `remainingTokens <= 15_000`, and at boot the resolved window is still the
|
|
22
|
-
* SDK's DEFAULT_CONTEXT_WINDOW fallback (8,192
|
|
22
|
+
* SDK's DEFAULT_CONTEXT_WINDOW fallback (8,192, the "8.2k" the footer meter
|
|
23
23
|
* shows before the real window arrives), so 8,192 free tokens tripped that
|
|
24
24
|
* rule instantly. Arithmetically consistent; factually false. No context had
|
|
25
25
|
* been consumed and no auto-compact was imminent.
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
* 2. The window is one the provider vouched for, not the fallback constant.
|
|
32
32
|
* A model whose real window happens to equal the fallback is
|
|
33
33
|
* indistinguishable from "not resolved yet", and in that ambiguity
|
|
34
|
-
* staying quiet is the honest choice
|
|
34
|
+
* staying quiet is the honest choice, the Tokens panel and /context
|
|
35
35
|
* still show the real numbers either way.
|
|
36
36
|
* Neither guard touches 'compacting', which reports work that is provably
|
|
37
37
|
* running rather than a prediction about headroom.
|
|
@@ -69,8 +69,8 @@ function hasRealContextNumbers(
|
|
|
69
69
|
* Build the passive status-line hint text for context pressure.
|
|
70
70
|
*
|
|
71
71
|
* Returns null when no hint is warranted (stable / watch / unknown), and also
|
|
72
|
-
* when a pressure level is not yet backed by real numbers
|
|
73
|
-
* policy above. The caller renders this as a dim informational line
|
|
72
|
+
* when a pressure level is not yet backed by real numbers, see the evidence
|
|
73
|
+
* policy above. The caller renders this as a dim informational line, no
|
|
74
74
|
* prompts, no blocking, no confirmation required.
|
|
75
75
|
*/
|
|
76
76
|
function buildContextStatusHint(options: ContextStatusHintOptions): string | null {
|
|
@@ -79,17 +79,17 @@ function buildContextStatusHint(options: ContextStatusHintOptions): string | nul
|
|
|
79
79
|
switch (level) {
|
|
80
80
|
case 'needs-repair':
|
|
81
81
|
if (!hasRealContextNumbers(options)) return null;
|
|
82
|
-
return ` Context pressure critical (${usagePct}% used)
|
|
82
|
+
return ` Context pressure critical (${usagePct}% used); compaction needs attention. Run /compact or /health review.`;
|
|
83
83
|
|
|
84
84
|
case 'suggest-compact':
|
|
85
85
|
if (!hasRealContextNumbers(options)) return null;
|
|
86
86
|
if (autoCompactEnabled) {
|
|
87
|
-
return ` Context high (${usagePct}% used)
|
|
87
|
+
return ` Context high (${usagePct}% used): auto-compact will run before the next turn.`;
|
|
88
88
|
}
|
|
89
|
-
return ` Context high (${usagePct}% used)
|
|
89
|
+
return ` Context high (${usagePct}% used): run /compact to recover headroom.`;
|
|
90
90
|
|
|
91
91
|
case 'compacting':
|
|
92
|
-
return ` Compacting context
|
|
92
|
+
return ` Compacting context: freeing headroom...`;
|
|
93
93
|
|
|
94
94
|
default:
|
|
95
95
|
return null;
|
|
@@ -42,11 +42,11 @@ export function buildConversationViewport(
|
|
|
42
42
|
* Absolute history-line index of the bottom-most visible row of the
|
|
43
43
|
* conversation viewport. The buffer bottom-aligns content shorter than the
|
|
44
44
|
* viewport (InfiniteBuffer.getSnapshot pads with blank lines at the TOP, not
|
|
45
|
-
* the bottom
|
|
45
|
+
* the bottom, see history.ts), so the naive `scrollTop + viewportHeight - 1`
|
|
46
46
|
* overshoots past the real last line whenever the whole transcript already
|
|
47
47
|
* fits on screen. Clamping to `lineCount - 1` handles both cases with one
|
|
48
48
|
* formula: when scrollLocked at the true bottom (the common case), this is
|
|
49
|
-
* exactly the last rendered content line
|
|
49
|
+
* exactly the last rendered content line, the block the user is actually
|
|
50
50
|
* looking at, not whatever sits at the TOP of the viewport (scrollTop alone).
|
|
51
51
|
*/
|
|
52
52
|
export function getViewportBottomLine(scrollTop: number, viewportHeight: number, lineCount: number): number {
|
|
@@ -42,7 +42,7 @@ export function applyConversationOverlays(
|
|
|
42
42
|
// Overlay posture rule: workspaces (onboarding, model, settings, mcp, help,
|
|
43
43
|
// shortcuts) claim the full viewport and are mutually exclusive with docked
|
|
44
44
|
// pickers/modals. Once a fullscreen workspace claims the screen, no docked
|
|
45
|
-
// overlay is drawn on top of it
|
|
45
|
+
// overlay is drawn on top of it, enforcing a single visible overlay even if
|
|
46
46
|
// stray state survives the handler's clearModalStack. The input layer keeps
|
|
47
47
|
// the modal stack to one entry; this is the renderer-side backstop.
|
|
48
48
|
let fullscreenClaimed = false;
|
|
@@ -78,7 +78,7 @@ export function applyConversationOverlays(
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
// retirement: the process, agent-detail, and live-tail modal overlays
|
|
81
|
-
// were removed with those modals
|
|
81
|
+
// were removed with those modals, F2 now opens the Fleet panel, which
|
|
82
82
|
// subsumes the live process tree.
|
|
83
83
|
|
|
84
84
|
if (!fullscreenClaimed && input.contextInspectorModal.active) {
|
|
@@ -106,14 +106,14 @@ export function renderConversationFragment(
|
|
|
106
106
|
indentCols = 0,
|
|
107
107
|
): Line[] {
|
|
108
108
|
// A tree fragment is a continuation of the row above it, so it starts at that
|
|
109
|
-
// row's content column
|
|
109
|
+
// row's content column, which puts its ` ▸ ` prefix glyph in exactly the same
|
|
110
110
|
// column as the parent row's own ` ▸ N lines ` badge. A flush fragment (a user
|
|
111
111
|
// message ghost box) keeps the box margin it has always used.
|
|
112
112
|
const indent = Math.max(0, indentCols);
|
|
113
113
|
const margin = indent > 0 ? treeContentCol(indent) : LAYOUT.USER_BOX_MARGIN;
|
|
114
114
|
const prefixWidth = getDisplayWidth(palette.prefix);
|
|
115
115
|
// The indent is charged to the content budget rather than allowed to push the
|
|
116
|
-
// fragment past the right edge
|
|
116
|
+
// fragment past the right edge, a narrow terminal shrinks the preview text
|
|
117
117
|
// instead of silently truncating its tail.
|
|
118
118
|
const maxContentWidth = Math.max(1, width - margin - LAYOUT.USER_BOX_MARGIN - prefixWidth - 2);
|
|
119
119
|
const wrapped = wrapText(content, maxContentWidth);
|
|
@@ -177,15 +177,15 @@ export function renderConversationFragment(
|
|
|
177
177
|
* A COLLAPSED block, as exactly one row: the event line, with its preview
|
|
178
178
|
* riding on the same line right after the badges.
|
|
179
179
|
*
|
|
180
|
-
* Collapsed blocks used to render as a framed fragment
|
|
181
|
-
* interior line of text, a `▀▀▀` cap
|
|
180
|
+
* Collapsed blocks used to render as a framed fragment, a `▄▄▄` cap, an
|
|
181
|
+
* interior line of text, a `▀▀▀` cap, around what was, in every case, a single
|
|
182
182
|
* line. Four rows of chrome per fold made a screen of collapsed output mostly
|
|
183
183
|
* frame. The text those rows carried moves onto the event line and the frame
|
|
184
184
|
* goes; the `▸ N lines` badge is the count, so nothing restates it.
|
|
185
185
|
*
|
|
186
186
|
* The preview is TRUNCATED to fit, never wrapped: wrapping would put the row
|
|
187
187
|
* back to two lines, which is the thing being removed. Whitespace is flattened
|
|
188
|
-
* by the caller's choice of preview text
|
|
188
|
+
* by the caller's choice of preview text, a raw tab or newline would blow the
|
|
189
189
|
* column out.
|
|
190
190
|
*/
|
|
191
191
|
export function renderConversationFoldedRow(
|
|
@@ -202,7 +202,7 @@ export function renderConversationFoldedRow(
|
|
|
202
202
|
// Whether a preview renders at all, and its flattening, are the policy's call
|
|
203
203
|
// (foldPreviewText returns null for "no preview"). Only the TRUNCATION is
|
|
204
204
|
// ours: display width is a product-local rule the policy deliberately leaves
|
|
205
|
-
// to the caller
|
|
205
|
+
// to the caller, and it must truncate, never wrap.
|
|
206
206
|
const trimmed = foldPreviewText(preview, availCols);
|
|
207
207
|
if (trimmed === null) {
|
|
208
208
|
return renderConversationEventLine(width, tone, details, indentCols);
|
package/src/renderer/diff.ts
CHANGED
|
@@ -74,7 +74,7 @@ export class DiffEngine {
|
|
|
74
74
|
// the SGR state did not change, skip cursor re-addressing.
|
|
75
75
|
// Emit a cursor move only on run breaks (new row, gap, or style change).
|
|
76
76
|
if (sgrOutput === '' && this.lastEmitY === y && this.lastEmitX === x - 1) {
|
|
77
|
-
// Contiguous run on same row, same SGR
|
|
77
|
+
// Contiguous run on same row, same SGR, just append the char.
|
|
78
78
|
output += newCell.char;
|
|
79
79
|
} else {
|
|
80
80
|
output += `\x1b[${y + 1};${x + 1}H`;
|
|
@@ -107,7 +107,7 @@ export class DiffEngine {
|
|
|
107
107
|
* Convert a raw color string (hex or r;g;b) to the "r;g;b" form expected
|
|
108
108
|
* by applyStyles. For non-RGB palette indices the value is returned as-is.
|
|
109
109
|
* This mirrors the original sanitizeColor contract but is now capability-aware
|
|
110
|
-
* only in the sense of normalizing hex → "r;g;b"
|
|
110
|
+
* only in the sense of normalizing hex → "r;g;b", downsampling happens in
|
|
111
111
|
* applyStyles via downsampleColor.
|
|
112
112
|
*/
|
|
113
113
|
private sanitizeColor(color: string): string {
|
|
@@ -148,7 +148,7 @@ export class DiffEngine {
|
|
|
148
148
|
if (cell.strikethrough) style += '\x1b[9m';
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
// Foreground color
|
|
151
|
+
// Foreground color, capability-downsampled
|
|
152
152
|
const fgOut = downsampleColor(fg, this.caps, 'fg');
|
|
153
153
|
if (fgOut !== null) {
|
|
154
154
|
if (this.caps.capability === 'basic16') {
|
|
@@ -160,7 +160,7 @@ export class DiffEngine {
|
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
// Background color
|
|
163
|
+
// Background color, capability-downsampled
|
|
164
164
|
const bgOut = downsampleColor(bg, this.caps, 'bg');
|
|
165
165
|
if (bgOut !== null) {
|
|
166
166
|
if (this.caps.capability === 'basic16') {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// renderTabStrip exactly as panel-workspace-bar.ts does for the workspace
|
|
6
6
|
// tab bar. Deliberately a SEPARATE, visually distinct strip from the
|
|
7
7
|
// workspace bar: workspace tabs switch PANELS, fleet session tabs switch
|
|
8
|
-
// ATTACHED PROCESSES within one panel
|
|
8
|
+
// ATTACHED PROCESSES within one panel, conflating their styling would blur
|
|
9
9
|
// that distinction for the operator.
|
|
10
10
|
// ---------------------------------------------------------------------------
|
|
11
11
|
|
|
@@ -22,7 +22,7 @@ const LABEL_FG = UI_TONES.fg.secondary;
|
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* Render the fleet session-tab strip, or `null` when there are no attached
|
|
25
|
-
* tabs
|
|
25
|
+
* tabs, the panel omits the strip entirely in that case (root-tab-only),
|
|
26
26
|
* which is what keeps the pre-session-tab fleet-panel goldens byte-identical.
|
|
27
27
|
*/
|
|
28
28
|
export function renderFleetTabStrip(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* footer-tips.ts
|
|
2
|
+
* footer-tips.ts, the persistent discoverability hint shown in the shell
|
|
3
3
|
* footer's tip slot.
|
|
4
4
|
*
|
|
5
5
|
* instead of a single frozen "/help for commands" line, the footer
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* is actively running, the process-monitor tip is promoted to the front so the
|
|
9
9
|
* operator can jump to F2 while work is in flight. Selection is a pure function
|
|
10
10
|
* of context so the footer renders deterministically (golden frames stay
|
|
11
|
-
* stable)
|
|
11
|
+
* stable), no wall-clock input.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
export interface FooterTipContext {
|
|
@@ -25,7 +25,7 @@ export function isAgentActive(composerStatus: string | undefined): boolean {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
// Ctrl+P is a TOGGLE (open+focus when nothing is open or unfocused,
|
|
28
|
-
// hide when the workspace already has focus
|
|
28
|
+
// hide when the workspace already has focus, see openPanelPicker in
|
|
29
29
|
// shell/ui-openers.ts). The bare noun 'panels' undersold that; naming the verb
|
|
30
30
|
// keeps the tip honest about what the chord actually does.
|
|
31
31
|
const TIP_PANELS = 'Ctrl+P toggle panels';
|
|
@@ -33,7 +33,7 @@ const TIP_PANELS = 'Ctrl+P toggle panels';
|
|
|
33
33
|
// tip names 'fleet', not 'processes'.
|
|
34
34
|
const TIP_PROCESSES = 'F2 fleet';
|
|
35
35
|
const TIP_HELP = '? help';
|
|
36
|
-
// f: an empty-composer Ctrl+C does NOT quit on the first press
|
|
36
|
+
// f: an empty-composer Ctrl+C does NOT quit on the first press, it arms a
|
|
37
37
|
// ~1s "press again to exit" confirm, and only a SECOND Ctrl+C within that window
|
|
38
38
|
// exits (an intentional accidental-exit guard). The old 'Ctrl+C quit' tip
|
|
39
39
|
// implied a single press quits, so two presses seconds apart appeared to do
|
|
@@ -6,7 +6,7 @@ import { activeUiTones, registerThemeRefresh } from './theme.ts';
|
|
|
6
6
|
|
|
7
7
|
// Built from the mode-resolved chrome tones (activeUiTones) and rebuilt IN PLACE
|
|
8
8
|
// on a mode flip via the registered refresher (read by reference across the
|
|
9
|
-
// fullscreen workspace surfaces
|
|
9
|
+
// fullscreen workspace surfaces, see theme.ts's active-mode runtime note).
|
|
10
10
|
function buildFullscreenPalette(): Record<string, string> {
|
|
11
11
|
const t = activeUiTones();
|
|
12
12
|
return {
|
|
@@ -13,11 +13,11 @@ export interface GitHeaderInfo {
|
|
|
13
13
|
const FALLBACK: GitHeaderInfo = { branch: '?', dirty: false, ahead: 0, behind: 0 };
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* GitStatusProvider
|
|
16
|
+
* GitStatusProvider, Fetches git state for the header bar.
|
|
17
17
|
*
|
|
18
18
|
* Results are cached for 2 seconds (TTL). The next call after expiry triggers
|
|
19
19
|
* a fresh fetch and returns the cached value immediately (stale-while-revalidate).
|
|
20
|
-
* Never throws
|
|
20
|
+
* Never throws, returns FALLBACK on any error.
|
|
21
21
|
*/
|
|
22
22
|
export class GitStatusProvider {
|
|
23
23
|
private cache: GitHeaderInfo = { ...FALLBACK };
|
|
@@ -61,7 +61,7 @@ export class GitStatusProvider {
|
|
|
61
61
|
* GitService.isGitRepo() check) but amortizes the cost for the header: the
|
|
62
62
|
* cheap synchronous isGitRepo() spawn runs every tick; the heavier async
|
|
63
63
|
* status()+branch() fetch (this.refresh()) only runs when that boolean
|
|
64
|
-
* actually flips
|
|
64
|
+
* actually flips, e.g. an external `git init`, or `.git` removed.
|
|
65
65
|
*/
|
|
66
66
|
startPolling(intervalMs: number, onChange: (info: GitHeaderInfo) => void): void {
|
|
67
67
|
if (this.pollTimer !== null) return;
|
|
@@ -110,7 +110,7 @@ export class GitStatusProvider {
|
|
|
110
110
|
statusResult.conflicted.length > 0 ||
|
|
111
111
|
statusResult.not_added.length > 0;
|
|
112
112
|
this.cache = {
|
|
113
|
-
// Empty `current` means an unborn HEAD
|
|
113
|
+
// Empty `current` means an unborn HEAD, a repo with no commits yet.
|
|
114
114
|
// Show "new" instead of an unfriendly "?" for that first-run case. (5a)
|
|
115
115
|
branch: branchResult.current || 'new',
|
|
116
116
|
dirty,
|
|
@@ -119,7 +119,7 @@ export class GitStatusProvider {
|
|
|
119
119
|
};
|
|
120
120
|
this.lastFetch = Date.now();
|
|
121
121
|
} catch {
|
|
122
|
-
// Never throw
|
|
122
|
+
// Never throw, return fallback
|
|
123
123
|
if (this.lastFetch === 0) {
|
|
124
124
|
this.cache = { ...FALLBACK };
|
|
125
125
|
this.lastFetch = Date.now();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* header-line.ts
|
|
2
|
+
* header-line.ts, the top-of-screen header row: brand, version, optional
|
|
3
3
|
* conversation title, optional git segment, and the right-hand model/provider
|
|
4
4
|
* pair.
|
|
5
5
|
*
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* remains the call name everywhere and delegates here.
|
|
9
9
|
*
|
|
10
10
|
* The model/provider pair rendered here is the SERVING backend, resolved by
|
|
11
|
-
* core/active-model-identity.ts
|
|
11
|
+
* core/active-model-identity.ts, the same resolution the footer uses, so the
|
|
12
12
|
* two surfaces can no longer disagree about who is answering. `note` carries
|
|
13
13
|
* the divergence marker naming the user's configured selection when serving
|
|
14
14
|
* has moved off it.
|
|
@@ -43,7 +43,7 @@ function buildGitSegment(gitInfo: GitHeaderInfo): { text: string; width: number
|
|
|
43
43
|
* Graded, never truncated mid-word: the full marker (which names the
|
|
44
44
|
* configured selection) is preferred; a bare "divergent" keyword is the
|
|
45
45
|
* fallback on a narrow terminal; on a very narrow terminal the marker is
|
|
46
|
-
* dropped entirely. Dropping it is safe
|
|
46
|
+
* dropped entirely. Dropping it is safe, what remains is still the SERVING
|
|
47
47
|
* backend, so the header never claims the configured backend is answering.
|
|
48
48
|
* The footer carries the full marker with far more room (see ui-factory's
|
|
49
49
|
* prioritized context segments).
|
|
@@ -80,7 +80,7 @@ export function renderHeaderLine(
|
|
|
80
80
|
): Line[] {
|
|
81
81
|
const lines: Line[] = [];
|
|
82
82
|
// Header/footer/thinking paint on the transparent terminal background, so
|
|
83
|
-
// they read chrome.* (light-terminal-aware)
|
|
83
|
+
// they read chrome.* (light-terminal-aware), NOT fg.*/state.*, which stay
|
|
84
84
|
// tuned for the opaque dark modal/panel boxes. Read live per render so a
|
|
85
85
|
// mode flip re-resolves without any module reload (see theme.ts).
|
|
86
86
|
const t = activeUiTones();
|
|
@@ -99,7 +99,7 @@ export function renderHeaderLine(
|
|
|
99
99
|
let curX = 0;
|
|
100
100
|
for (const char of brand) { line[curX++] = { char, fg: CYAN, bg: '', bold: true, dim: false, underline: false, italic: false, strikethrough: false }; }
|
|
101
101
|
for (const char of ver) { line[curX++] = { char, fg: GREY, bg: '', bold: false, dim: true, underline: false, italic: false, strikethrough: false }; }
|
|
102
|
-
// Optional conversation title
|
|
102
|
+
// Optional conversation title, shown after brand/ver, truncated to fit
|
|
103
103
|
if (title) {
|
|
104
104
|
const titleStr = `│ ${title} `;
|
|
105
105
|
// Reserve space for git info (if present) + model/provider + marker on the right
|