@pellux/goodvibes-tui 2.0.13 → 2.0.15
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 +61 -0
- package/README.md +40 -29
- package/docs/README.md +1 -1
- 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 +9 -9
- 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 +4 -4
- 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,16 +14,16 @@ import { GOODVIBES_TUI_SURFACE_ROOT } from '../../config/surface.ts';
|
|
|
14
14
|
// split into five operator domains, applied per-registration below. Kept in
|
|
15
15
|
// this file's original registration order (rather than physically regrouped
|
|
16
16
|
// by category) because several registrations below close over shared local
|
|
17
|
-
// state
|
|
17
|
+
// state, `ui`, defined once near the top of this function.
|
|
18
18
|
//
|
|
19
19
|
// (the purge): cockpit, approval, automation, routes, control-plane,
|
|
20
20
|
// worktrees, tasks, orchestration, ops, ops-control, and communication were
|
|
21
21
|
// RETIRE-INTO-FLEET (their live views are subsumed by the Fleet panel below
|
|
22
|
-
|
|
22
|
+
//, each id now redirects there via registerAlias); debug and eval were
|
|
23
23
|
// DELETE-disposition (no surviving human surface). See
|
|
24
24
|
// .goodvibes/audit/2026-07-04-wave6-briefs.json for the full
|
|
25
25
|
// disposition map. The rosterReadModel/agent-lifecycle wiring that used to
|
|
26
|
-
// feed CockpitPanel exclusively was removed along with it
|
|
26
|
+
// feed CockpitPanel exclusively was removed along with it, Fleet reads the
|
|
27
27
|
// process registry directly via fleetReadModel below, not via the roster
|
|
28
28
|
// read-model.
|
|
29
29
|
//
|
|
@@ -34,12 +34,12 @@ import { GOODVIBES_TUI_SURFACE_ROOT } from '../../config/surface.ts';
|
|
|
34
34
|
// marketplace, policy, knowledge, memory, docs, qr-code, work-plan,
|
|
35
35
|
// project-planning) migrated to config-modal surfaces. All surfaces AND
|
|
36
36
|
// their panel-id redirects are registered centrally in registerBuiltinModals
|
|
37
|
-
// (builtin-modals.ts) now
|
|
38
|
-
// with the group-B port. local-auth is a DELIBERATE EXCEPTION
|
|
37
|
+
// (builtin-modals.ts) now, the interim ecosystem redirect bridge was deleted
|
|
38
|
+
// with the group-B port. local-auth is a DELIBERATE EXCEPTION, see below.
|
|
39
39
|
export function registerOperationsPanels(manager: PanelManager, deps: ResolvedBuiltinPanelDeps): void {
|
|
40
40
|
const ui = requireUiServices(deps);
|
|
41
41
|
|
|
42
|
-
// Fleet
|
|
42
|
+
// Fleet, everything running, not just what this terminal started. The read
|
|
43
43
|
// model is composed once in runtime/services.ts (so its refresh timer has an
|
|
44
44
|
// owner that stops it) and unions this surface's own live process registry
|
|
45
45
|
// with the adopted daemon's rows; see runtime/client/fleet-union.ts for who
|
|
@@ -108,7 +108,7 @@ export function registerOperationsPanels(manager: PanelManager, deps: ResolvedBu
|
|
|
108
108
|
resume: (id: string) => fleetReadModel.resume(id),
|
|
109
109
|
kill: (id: string, opts: { cascade: boolean }) => fleetReadModel.kill(id, opts),
|
|
110
110
|
// Full-fidelity transcript source for an attached agent
|
|
111
|
-
// tab
|
|
111
|
+
// tab, live while the agent runs, frozen briefly after it completes
|
|
112
112
|
// (AgentManager's bounded retention ring), empty once evicted (the
|
|
113
113
|
// panel degrades to the on-disk ledger fallback in that case).
|
|
114
114
|
getConversationSnapshot: (agentId: string) => ui.agents.agentManager.getConversationSnapshot(agentId),
|
|
@@ -119,7 +119,7 @@ export function registerOperationsPanels(manager: PanelManager, deps: ResolvedBu
|
|
|
119
119
|
});
|
|
120
120
|
|
|
121
121
|
// Compat: '/panel open <id>' (and any saved layout/muscle memory) for
|
|
122
|
-
// every retired runtime-ops console still resolves
|
|
122
|
+
// every retired runtime-ops console still resolves, redirected to fleet,
|
|
123
123
|
// which absorbs orchestration, permissions, communication, task, and
|
|
124
124
|
// process-tree views (see FleetPanel's own description above).
|
|
125
125
|
manager.registerAlias('cockpit', 'fleet');
|
|
@@ -135,16 +135,16 @@ export function registerOperationsPanels(manager: PanelManager, deps: ResolvedBu
|
|
|
135
135
|
manager.registerAlias('communication', 'fleet');
|
|
136
136
|
manager.registerAlias('incident', 'fleet');
|
|
137
137
|
// Re-pointed: forensics used to resolve to the (now-retired) incident
|
|
138
|
-
// workspace; both ids now land on fleet directly
|
|
138
|
+
// workspace; both ids now land on fleet directly, alias
|
|
139
139
|
// resolution is a single hop, so this cannot chain through 'incident'.
|
|
140
140
|
manager.registerAlias('forensics', 'fleet');
|
|
141
141
|
|
|
142
|
-
// Notifications
|
|
142
|
+
// Notifications, the visible home for the panel_only notification
|
|
143
143
|
// target: anything a NotificationRouter (SDK) routes there (including
|
|
144
144
|
// burst/batch-collapsed groups, shown with their real running count)
|
|
145
145
|
// renders here instead of having nowhere to go. See notifications-feed.ts
|
|
146
146
|
// for why this exists. Not preloaded (only 'tokens' preloads, per the
|
|
147
|
-
// panel-consolidation cleanup below)
|
|
147
|
+
// panel-consolidation cleanup below), the shared feed singleton
|
|
148
148
|
// accumulates independently of whether this view has been opened yet, so
|
|
149
149
|
// nothing is lost by instantiating it lazily on first open like every
|
|
150
150
|
// other panel here.
|
|
@@ -160,7 +160,7 @@ export function registerOperationsPanels(manager: PanelManager, deps: ResolvedBu
|
|
|
160
160
|
// local-auth is a DELIBERATE EXCEPTION to the purge: it stays a
|
|
161
161
|
// registered panel because it is the host for the masked password-entry
|
|
162
162
|
// sub-mode (LocalAuthPanel.openMaskedEntry, driven by
|
|
163
|
-
// ctx.openLocalAuthMaskedEntry
|
|
163
|
+
// ctx.openLocalAuthMaskedEntry, the only path that keeps a plaintext
|
|
164
164
|
// password out of argv/history/scrollback). Its browse view is mirrored by
|
|
165
165
|
// local-auth-modal (reached via the /local-auth front-door), but the panel
|
|
166
166
|
// itself cannot be retired without regressing that secure input, and no
|
|
@@ -5,17 +5,17 @@ import type { ResolvedBuiltinPanelDeps } from './shared.ts';
|
|
|
5
5
|
import { requireUiServices } from './shared.ts';
|
|
6
6
|
|
|
7
7
|
// (the purge): panel-list and system-messages were registered here
|
|
8
|
-
// before the purge
|
|
9
|
-
// handful of panels (dead weight now that the registry is much smaller
|
|
8
|
+
// before the purge, both DELETE-disposition. panel-list was a picker over a
|
|
9
|
+
// handful of panels (dead weight now that the registry is much smaller,
|
|
10
10
|
// the picker itself is replaced by a live-registry selection modal on
|
|
11
11
|
// Ctrl+P, see shell/ui-openers.ts). system-messages' buffered notices are
|
|
12
12
|
// rerouted to the transcript's system channel instead of vanishing: with no
|
|
13
13
|
// panel attached, SystemMessageRouter's delivery resolution
|
|
14
14
|
// (resolveSystemMessageDelivery, SDK) already falls back to
|
|
15
|
-
// conversation.addTypedSystemMessage for every kind/target combination
|
|
15
|
+
// conversation.addTypedSystemMessage for every kind/target combination, see
|
|
16
16
|
// bootstrap-shell.ts and core/system-message-router.ts.
|
|
17
17
|
//
|
|
18
|
-
// (the purge)
|
|
18
|
+
// (the purge), group B: 'qr-code', 'sessions', and 'docs' also
|
|
19
19
|
// migrated. 'qr-code' → the 'pairing-modal' surface; 'docs' → the
|
|
20
20
|
// 'keybindings-modal' surface (merged with the shortcuts-overlay content);
|
|
21
21
|
// 'sessions' folds into the existing session-picker modal ('sessions' redirects
|
|
@@ -27,7 +27,7 @@ export function registerSessionPanels(manager: PanelManager, deps: ResolvedBuilt
|
|
|
27
27
|
id: 'tokens',
|
|
28
28
|
name: 'Tokens',
|
|
29
29
|
// registry previously said 'K' while the live panel's own
|
|
30
|
-
// super() call used 'T'
|
|
30
|
+
// super() call used 'T', a pre-existing registry/instance mismatch as
|
|
31
31
|
// well as a collision ('K' with knowledge/skills, 'T' with thinking).
|
|
32
32
|
// Unified to a single unique glyph in both places.
|
|
33
33
|
icon: '▢',
|
|
@@ -36,7 +36,7 @@ export function registerSessionPanels(manager: PanelManager, deps: ResolvedBuilt
|
|
|
36
36
|
// Preloaded (absorbed from the retired ContextVisualizerPanel) so turn
|
|
37
37
|
// history and pressure accumulate in the background even before the user
|
|
38
38
|
// opens the tab. The only builtin panel that still preloads post-purge
|
|
39
|
-
|
|
39
|
+
//, see registerBuiltinPanels callers for the others' preload
|
|
40
40
|
// removal.
|
|
41
41
|
preload: true,
|
|
42
42
|
retainOnClose: true,
|
|
@@ -59,7 +59,7 @@ export function registerSessionPanels(manager: PanelManager, deps: ResolvedBuilt
|
|
|
59
59
|
},
|
|
60
60
|
});
|
|
61
61
|
|
|
62
|
-
// Hosted Session
|
|
62
|
+
// Hosted Session, a conversation whose loop runs INSIDE the daemon rather
|
|
63
63
|
// than in this process, rendered from the same `turn`/`tools` event domains a
|
|
64
64
|
// local turn emits (see panels/hosted-session-feed.ts). Not preloaded: a
|
|
65
65
|
// terminal that never opts into hosting should not carry an empty tab for it,
|
|
@@ -75,7 +75,7 @@ export function registerSessionPanels(manager: PanelManager, deps: ResolvedBuilt
|
|
|
75
75
|
factory: () => new HostedSessionPanel(),
|
|
76
76
|
});
|
|
77
77
|
|
|
78
|
-
// compat: the retired 'context' panel id still resolves
|
|
78
|
+
// compat: the retired 'context' panel id still resolves, redirected
|
|
79
79
|
// to the merged tokens console ('/panel open context', saved layouts).
|
|
80
80
|
manager.registerAlias('context', 'tokens');
|
|
81
81
|
}
|
|
@@ -73,13 +73,13 @@ export interface BuiltinPanelDeps {
|
|
|
73
73
|
forensicsRegistry?: import('@/runtime/index.ts').ForensicsRegistry;
|
|
74
74
|
/**
|
|
75
75
|
* EvalRegistry for the `/eval` command surface.: 'eval' the panel was
|
|
76
|
-
* deleted (DELETE-disposition), but this field is left in place
|
|
76
|
+
* deleted (DELETE-disposition), but this field is left in place, no
|
|
77
77
|
* builtin panel factory reads it anymore, and it was never wired at
|
|
78
78
|
* bootstrap in production either way (the eval CLI command reads its own
|
|
79
79
|
* copy via CommandContext.extensions.evalRegistry).
|
|
80
80
|
*/
|
|
81
81
|
evalRegistry?: import('../eval-registry.ts').EvalRegistry;
|
|
82
|
-
/** Host-vs-client memory access for the Memory modal
|
|
82
|
+
/** Host-vs-client memory access for the Memory modal, the spine client, never the raw registry (routes over the wire when a daemon is adopted). */
|
|
83
83
|
memoryRegistry?: MemoryAccess;
|
|
84
84
|
/** Shared policy runtime state for governance/policy diagnostics. */
|
|
85
85
|
policyRuntimeState?: import('@/runtime/index.ts').PolicyRuntimeState;
|
|
@@ -105,7 +105,7 @@ export interface BuiltinPanelDeps {
|
|
|
105
105
|
/** Shared sandbox session registry for sandbox surfaces and tools. */
|
|
106
106
|
sandboxSessionRegistry: SandboxSessionRegistry;
|
|
107
107
|
/**
|
|
108
|
-
* Resolved daemon home directory (e.g. `~/.goodvibes/daemon`)
|
|
108
|
+
* Resolved daemon home directory (e.g. `~/.goodvibes/daemon`), owned by the composition root
|
|
109
109
|
* and passed explicitly so panel factories do not discover cwd/home implicitly.
|
|
110
110
|
*/
|
|
111
111
|
daemonHomeDir?: string;
|
|
@@ -123,7 +123,7 @@ export interface BuiltinPanelDeps {
|
|
|
123
123
|
workPlanStore?: import('@pellux/goodvibes-sdk/platform/workflow').WorkPlanStore;
|
|
124
124
|
/** Explicit UI-facing runtime services for agent/process/WRFC/remote panels and modals. */
|
|
125
125
|
uiServices?: UiRuntimeServices;
|
|
126
|
-
/** Shared plugin manager for plugin and security panels (widened past the read-only observer surface —
|
|
126
|
+
/** Shared plugin manager for plugin and security panels (widened past the read-only observer surface, — so PluginsPanel can drive enable/disable/verify/lift-quarantine). */
|
|
127
127
|
pluginManager?: PluginManagerControls;
|
|
128
128
|
/** Shared hook dispatcher for the hooks control-room panel. */
|
|
129
129
|
hookDispatcher?: Pick<HookDispatcher, 'listHooks' | 'getChains'>;
|
|
@@ -153,7 +153,7 @@ export interface BuiltinPanelDeps {
|
|
|
153
153
|
/**
|
|
154
154
|
* Surface a Fleet act result/receipt/error to the operator (late-bound to the
|
|
155
155
|
* command context's print, which the Fleet pick/conflict/discard acts use for
|
|
156
|
-
* their receipts
|
|
156
|
+
* their receipts, the same conversation sink the command flow prints to).
|
|
157
157
|
*/
|
|
158
158
|
fleetActsNotify?: (message: string) => void;
|
|
159
159
|
/**
|
|
@@ -309,7 +309,7 @@ export function requireKnowledgeApi(deps: BuiltinPanelDeps): KnowledgeApi {
|
|
|
309
309
|
* was not wired at bootstrap for this build/session. Renders a single
|
|
310
310
|
* "dependency not configured" empty state via `buildEmptyState` so opening
|
|
311
311
|
* the panel id (`/panel open <id>`, a saved layout, a cross-panel jump)
|
|
312
|
-
* always resolves to a real panel instead of "Unknown panel"
|
|
312
|
+
* always resolves to a real panel instead of "Unknown panel", the panel
|
|
313
313
|
* type is always registered; only its data source is sometimes absent.
|
|
314
314
|
*/
|
|
315
315
|
class UnconfiguredDependencyPanel extends BasePanel {
|
|
@@ -36,12 +36,12 @@ import { createPlanningModalSurface } from './modals/planning-modal.ts';
|
|
|
36
36
|
* panel-consolidation cleanup. Called once at startup from registerBuiltinPanels, AFTER the panels'
|
|
37
37
|
* deps are resolved (the surfaces close over the same read-models the retired
|
|
38
38
|
* panels used). For each surface migrated from a standalone panel this does two things:
|
|
39
|
-
* 1. registerModalSurface
|
|
40
|
-
* 2. registerModalRedirect
|
|
39
|
+
* 1. registerModalSurface, the data + actions the config-modal host renders.
|
|
40
|
+
* 2. registerModalRedirect, so `/panel open <old-id>`, saved layouts, and any
|
|
41
41
|
* alias still resolve to the modal.
|
|
42
42
|
*
|
|
43
43
|
* The Providers & Connectivity + Security subset is registered first, followed by the
|
|
44
|
-
* Ecosystem & Governance set
|
|
44
|
+
* Ecosystem & Governance set, the 12 ported config-modal
|
|
45
45
|
* surfaces plus the `sessions` fold into the existing session-picker modal.
|
|
46
46
|
*/
|
|
47
47
|
export function registerBuiltinModals(manager: PanelManager, deps: ResolvedBuiltinPanelDeps): void {
|
|
@@ -93,7 +93,7 @@ export function registerBuiltinModals(manager: PanelManager, deps: ResolvedBuilt
|
|
|
93
93
|
|
|
94
94
|
// plugins/hooks/knowledge deps are wired at bootstrap in production
|
|
95
95
|
// (bootstrap-shell.ts) but may be absent in a partially-wired context (e.g. a
|
|
96
|
-
// release-gate harness)
|
|
96
|
+
// release-gate harness), register a degraded placeholder rather than throw,
|
|
97
97
|
// so the surface + redirect always resolve (the "always register, degrade
|
|
98
98
|
// honestly" charter pattern).
|
|
99
99
|
manager.registerModalSurface(deps.pluginManager
|
|
@@ -133,8 +133,8 @@ export function registerBuiltinModals(manager: PanelManager, deps: ResolvedBuilt
|
|
|
133
133
|
|
|
134
134
|
manager.registerModalSurface(createMemoryModalSurface({
|
|
135
135
|
memoryRegistry: deps.memoryRegistry as MemoryModalDeps['memoryRegistry'],
|
|
136
|
-
// Lazily resolved
|
|
137
|
-
// like the Fleet gateway (fleet-gateway.ts)
|
|
136
|
+
// Lazily resolved, a fresh factory call per Proposals-tab fetch, exactly
|
|
137
|
+
// like the Fleet gateway (fleet-gateway.ts), so a daemon that comes up
|
|
138
138
|
// AFTER this session started is still reachable on the next refresh.
|
|
139
139
|
resolveConsolidationGateway: () => createMemoryConsolidationGateway({
|
|
140
140
|
configManager: deps.configManager,
|
|
@@ -202,7 +202,7 @@ function buildPairingConnectionInfo(deps: ResolvedBuiltinPanelDeps): PairingModa
|
|
|
202
202
|
// presentable; the web app declines it if the device has no authenticator.
|
|
203
203
|
stepUpAvailable: true,
|
|
204
204
|
});
|
|
205
|
-
// Mint a fresh per-device token and encode the canonical `#pair=` deep link
|
|
205
|
+
// Mint a fresh per-device token and encode the canonical `#pair=` deep link,
|
|
206
206
|
// the same mint the pairing.handoff.create verb performs, no raw JSON blob.
|
|
207
207
|
const handoff = mintPairingHandoff({
|
|
208
208
|
pairingTokens: ui.platform.pairingTokens,
|
|
@@ -224,7 +224,7 @@ function buildPairingConnectionInfo(deps: ResolvedBuiltinPanelDeps): PairingModa
|
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
/** A minimal config-modal surface that renders an honest "not wired" degraded
|
|
227
|
-
* state
|
|
227
|
+
* state, used when a group-B surface's bootstrap dependency is absent. */
|
|
228
228
|
function unwiredSurface(name: string, title: string, reason: string): ConfigModalSurface {
|
|
229
229
|
return {
|
|
230
230
|
name,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// ---------------------------------------------------------------------------
|
|
2
|
-
// useConfirmState<T
|
|
2
|
+
// useConfirmState<T>, reusable inline confirm/cancel helper
|
|
3
3
|
//
|
|
4
4
|
// ── Project-standard confirm contract (all panels must match) ──────────────
|
|
5
5
|
//
|
|
@@ -45,11 +45,11 @@ export interface ConfirmState<T = string> {
|
|
|
45
45
|
* - ABSORBED: any other key while confirm is active (keeps confirm pending)
|
|
46
46
|
*
|
|
47
47
|
* Returns:
|
|
48
|
-
* - `'confirmed'
|
|
48
|
+
* - `'confirmed'`, user pressed Enter, Return, or y; caller must execute
|
|
49
49
|
* the action and clear state (set confirm to null)
|
|
50
|
-
* - `'cancelled'
|
|
51
|
-
* - `'absorbed'`
|
|
52
|
-
* - `'inactive'`
|
|
50
|
+
* - `'cancelled'`, user pressed n or Esc; caller must clear state
|
|
51
|
+
* - `'absorbed'` , any other key while confirm is active; caller returns true
|
|
52
|
+
* - `'inactive'` , no confirm pending; caller continues normal dispatch
|
|
53
53
|
*/
|
|
54
54
|
export function handleConfirmInput<T = string>(
|
|
55
55
|
confirm: ConfirmState<T> | null,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// ---------------------------------------------------------------------------
|
|
2
|
-
// CostTrackerPanel
|
|
2
|
+
// CostTrackerPanel, per-session / per-agent / per-plan cost estimates
|
|
3
3
|
// ---------------------------------------------------------------------------
|
|
4
4
|
|
|
5
5
|
import type { Line } from '@pellux/goodvibes-sdk/platform/types';
|
|
@@ -107,9 +107,9 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
107
107
|
private agents = new Map<string, AgentEntry>();
|
|
108
108
|
|
|
109
109
|
// Budget alert threshold in USD (0 = disabled). Mutable at runtime via the
|
|
110
|
-
// in-panel 'b' numeric entry or the /cost budget <usd> command
|
|
110
|
+
// in-panel 'b' numeric entry or the /cost budget <usd> command, both call
|
|
111
111
|
// setBudgetThreshold() below. When configAccess is wired (production path),
|
|
112
|
-
// this field is a cache only
|
|
112
|
+
// this field is a cache only, currentBudgetThreshold() re-reads
|
|
113
113
|
// behavior.budgetAlertUsd from config on every use so the panel and the
|
|
114
114
|
// background budget-breach notifier (core/budget-breach-notifier.ts) never
|
|
115
115
|
// disagree about the threshold. Tests that omit configAccess fall back to
|
|
@@ -147,7 +147,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
147
147
|
// Getter for live orchestrator usage
|
|
148
148
|
private readonly getOrchestratorUsage: () => UsageSnapshot & { model?: string };
|
|
149
149
|
|
|
150
|
-
// Optional resolver for agent usage on completion
|
|
150
|
+
// Optional resolver for agent usage on completion, enables real cost attribution.
|
|
151
151
|
// When omitted, completed agents show $0 (honest: data unavailable).
|
|
152
152
|
private readonly getAgentStatus: ((agentId: string) => AgentRecord | null) | undefined;
|
|
153
153
|
|
|
@@ -188,7 +188,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
188
188
|
|
|
189
189
|
// Refresh mid-turn too: a single turn can span many LLM calls (tool
|
|
190
190
|
// loops), so waiting for TURN_COMPLETED leaves the meter frozen for the
|
|
191
|
-
// whole turn. LLM_RESPONSE_RECEIVED fires per call
|
|
191
|
+
// whole turn. LLM_RESPONSE_RECEIVED fires per call, same refresh path.
|
|
192
192
|
this.unsubs.push(
|
|
193
193
|
turnEvents.on('LLM_RESPONSE_RECEIVED', () => this.refreshSessionCost()),
|
|
194
194
|
);
|
|
@@ -209,7 +209,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
209
209
|
}),
|
|
210
210
|
);
|
|
211
211
|
|
|
212
|
-
// Agent completed
|
|
212
|
+
// Agent completed, capture real token usage via AgentRecord when available
|
|
213
213
|
this.unsubs.push(
|
|
214
214
|
agentEvents.on('AGENT_COMPLETED', (payload) => {
|
|
215
215
|
const entry = this.agents.get(payload.agentId);
|
|
@@ -281,7 +281,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
281
281
|
}
|
|
282
282
|
|
|
283
283
|
override onDeactivate(): void {
|
|
284
|
-
// Stop polling while hidden
|
|
284
|
+
// Stop polling while hidden, nothing to catch up on that a fresh
|
|
285
285
|
// onActivate() poll won't cover.
|
|
286
286
|
this.stopStatusPollTimer();
|
|
287
287
|
}
|
|
@@ -306,7 +306,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
306
306
|
/**
|
|
307
307
|
* Poll getAgentStatus() for every agent still marked 'running'. Completion
|
|
308
308
|
* already captures real usage via AGENT_COMPLETED, but a long-running agent
|
|
309
|
-
* would otherwise show 'unknown' tokens / $0 cost for its entire lifetime
|
|
309
|
+
* would otherwise show 'unknown' tokens / $0 cost for its entire lifetime,
|
|
310
310
|
* this fills the row in as usage becomes available mid-flight.
|
|
311
311
|
*/
|
|
312
312
|
private pollRunningAgents(): void {
|
|
@@ -349,7 +349,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
349
349
|
/**
|
|
350
350
|
* The budget-threshold entry field wants every character of a burst
|
|
351
351
|
* (paste, or fast typing landing in one input.feed() call) delivered one
|
|
352
|
-
* at a time, same as it always has
|
|
352
|
+
* at a time, same as it always has, see the interface doc on
|
|
353
353
|
* `Panel.isCapturingTextBurst`.
|
|
354
354
|
*/
|
|
355
355
|
isCapturingTextBurst(): boolean {
|
|
@@ -369,7 +369,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
369
369
|
|
|
370
370
|
if (key === 'p') {
|
|
371
371
|
// One action from any price display: edit the manual price for the
|
|
372
|
-
// session's provider:model. Needs a wired config (production path)
|
|
372
|
+
// session's provider:model. Needs a wired config (production path),
|
|
373
373
|
// without one the key falls through rather than opening a dead editor.
|
|
374
374
|
if (!this.configAccess) return false;
|
|
375
375
|
this.priceEntry = '';
|
|
@@ -410,7 +410,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
410
410
|
}
|
|
411
411
|
return true;
|
|
412
412
|
}
|
|
413
|
-
// Digits and a single decimal point only
|
|
413
|
+
// Digits and a single decimal point only, this is a USD amount, not free text.
|
|
414
414
|
if (key.length === 1 && /[0-9.]/.test(key) && !(key === '.' && this.budgetEntry?.includes('.'))) {
|
|
415
415
|
this.budgetEntry = (this.budgetEntry ?? '') + key;
|
|
416
416
|
this.markDirty();
|
|
@@ -456,7 +456,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
456
456
|
}
|
|
457
457
|
return true;
|
|
458
458
|
}
|
|
459
|
-
// Two USD amounts separated by a comma (or space)
|
|
459
|
+
// Two USD amounts separated by a comma (or space), digits, dots, comma, space.
|
|
460
460
|
if (key.length === 1 && /[0-9., ]/.test(key)) {
|
|
461
461
|
this.priceEntry = (this.priceEntry ?? '') + key;
|
|
462
462
|
this.markDirty();
|
|
@@ -467,7 +467,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
467
467
|
|
|
468
468
|
/**
|
|
469
469
|
* Scroll the agent list. Over-consumption fix: only absorbs the key (and
|
|
470
|
-
* only advances) when the agent list is actually long enough to scroll
|
|
470
|
+
* only advances) when the agent list is actually long enough to scroll,
|
|
471
471
|
* mirrors the same `> 5` threshold render() uses to decide whether to show
|
|
472
472
|
* scroll hints (below). Previously this always returned true and grew
|
|
473
473
|
* scrollOffset unboundedly even with a handful of agents, swallowing
|
|
@@ -506,7 +506,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
506
506
|
const sourceDescription = sessionPriced ? describePricingSource(this.sessionModel) : null;
|
|
507
507
|
const sourceStr = sessionPriced
|
|
508
508
|
? (sourceDescription ? ` (${sourceDescription})` : '')
|
|
509
|
-
: '
|
|
509
|
+
: ': press p to set a price';
|
|
510
510
|
const budgetStr = budgetThreshold > 0
|
|
511
511
|
? ` / ${formatCost(budgetThreshold)}`
|
|
512
512
|
: '';
|
|
@@ -514,7 +514,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
514
514
|
const sessionLines: Line[] = [
|
|
515
515
|
this.renderKeyValue(width, ' Total', `${costStr}${budgetStr}${alertStr}${sourceStr}`, costFg),
|
|
516
516
|
];
|
|
517
|
-
// Budget meter
|
|
517
|
+
// Budget meter, the single most important glance for this panel: how much
|
|
518
518
|
// of the configured budget the session has consumed. Only shown when a
|
|
519
519
|
// budget is set (otherwise the bar would be meaningless).
|
|
520
520
|
if (budgetThreshold > 0) {
|
|
@@ -570,7 +570,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
570
570
|
const planCost = agentList.reduce((sum, a) => sum + a.cost, 0);
|
|
571
571
|
const running = agentList.filter((a) => a.status === 'running').length;
|
|
572
572
|
const failed = agentList.filter((a) => a.status === 'failed').length;
|
|
573
|
-
// Plan total mixes the session model with every agent's model
|
|
573
|
+
// Plan total mixes the session model with every agent's model, flag it
|
|
574
574
|
// as unpriced (rather than showing a sum that silently omits unpriced
|
|
575
575
|
// agents' contribution) if any one of them has no real pricing.
|
|
576
576
|
const planHasUnpriced = !isModelPriced(this.sessionModel) || agentList.some((a) => !isModelPriced(a.model));
|
|
@@ -582,7 +582,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
582
582
|
...(running > 0 ? [{ text: ` ${running} running`, fg: C.running }] : []),
|
|
583
583
|
...(failed > 0 ? [{ text: ` ${failed} failed`, fg: C.bad }] : []),
|
|
584
584
|
]),
|
|
585
|
-
// Per-agent cost ledger as an aligned table
|
|
585
|
+
// Per-agent cost ledger as an aligned table, agent, model, tokens, cost
|
|
586
586
|
// line up in columns instead of wrapping across two ragged rows.
|
|
587
587
|
...buildTable(
|
|
588
588
|
width,
|
|
@@ -684,7 +684,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
684
684
|
]);
|
|
685
685
|
}
|
|
686
686
|
|
|
687
|
-
// Non-masked numeric entry for the 'b' budget-alert key
|
|
687
|
+
// Non-masked numeric entry for the 'b' budget-alert key, the value is a
|
|
688
688
|
// USD amount, not a secret, so (unlike LocalAuthPanel's masked entry) it is
|
|
689
689
|
// echoed directly rather than dotted out.
|
|
690
690
|
private renderBudgetEntryPrompt(width: number, height: number): Line[] {
|
|
@@ -698,7 +698,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
698
698
|
buildPanelLine(width, [[' [Enter] Confirm [Esc] Cancel [Backspace] Delete char', C.dim]]),
|
|
699
699
|
];
|
|
700
700
|
const workspace = buildPanelWorkspace(width, height, {
|
|
701
|
-
title: ' Cost Tracker
|
|
701
|
+
title: ' Cost Tracker: Budget',
|
|
702
702
|
intro: 'Type a USD amount and press Enter to set the budget alert threshold.',
|
|
703
703
|
sections: [{ lines: promptLines }],
|
|
704
704
|
palette: DEFAULT_PANEL_PALETTE,
|
|
@@ -710,7 +710,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
710
710
|
// Non-masked entry for the 'p' manual-price key. Two USD-per-1M-token
|
|
711
711
|
// amounts (input,output); persists to pricing.modelPrices for the session's
|
|
712
712
|
// provider:model live. A model without a provider prefix cannot carry a
|
|
713
|
-
// manual price (the settings key is keyed provider:model)
|
|
713
|
+
// manual price (the settings key is keyed provider:model), the prompt says
|
|
714
714
|
// so instead of accepting a value it could not store.
|
|
715
715
|
private renderPriceEntryPrompt(width: number, height: number): Line[] {
|
|
716
716
|
const editable = this.canEditSessionModelPrice();
|
|
@@ -719,7 +719,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
719
719
|
const promptLines: Line[] = editable
|
|
720
720
|
? [
|
|
721
721
|
buildPanelLine(width, [[` Set your manual price for ${this.sessionModel} (USD per 1M tokens).`, C.label]]),
|
|
722
|
-
buildPanelLine(width, [[' Format: input,output
|
|
722
|
+
buildPanelLine(width, [[' Format: input,output, for example 3.00,15.00', C.dim]]),
|
|
723
723
|
buildPanelLine(width, [['', C.label]]),
|
|
724
724
|
buildPanelLine(width, [[' Price ', C.label], [display, C.cost]]),
|
|
725
725
|
buildPanelLine(width, [['', C.label]]),
|
|
@@ -732,7 +732,7 @@ export class CostTrackerPanel extends BasePanel {
|
|
|
732
732
|
buildPanelLine(width, [[' [Esc] Close', C.dim]]),
|
|
733
733
|
];
|
|
734
734
|
const workspace = buildPanelWorkspace(width, height, {
|
|
735
|
-
title: ' Cost Tracker
|
|
735
|
+
title: ' Cost Tracker: Model Price',
|
|
736
736
|
intro: editable
|
|
737
737
|
? 'Your price wins over provider and catalog prices, immediately and everywhere.'
|
|
738
738
|
: 'Manual prices are stored per provider:model.',
|
package/src/panels/diff-panel.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// ---------------------------------------------------------------------------
|
|
2
|
-
// DiffPanel
|
|
2
|
+
// DiffPanel, unified diff view of agent file changes
|
|
3
3
|
// ---------------------------------------------------------------------------
|
|
4
4
|
|
|
5
5
|
import type { Line } from '@pellux/goodvibes-sdk/platform/types';
|
|
@@ -22,15 +22,15 @@ import {
|
|
|
22
22
|
} from './polish.ts';
|
|
23
23
|
|
|
24
24
|
// ---------------------------------------------------------------------------
|
|
25
|
-
// Colour palette
|
|
25
|
+
// Colour palette, dedicated diff-viewer scheme (like a mini syntax
|
|
26
26
|
// highlighter). Each hex literal is named once and reused for every role
|
|
27
27
|
// that shares it, including the workspace-chrome aliases (info/dim/value/
|
|
28
28
|
// empty) so the raw-hex count never grows. The title band itself is NOT
|
|
29
|
-
// overridden
|
|
29
|
+
// overridden, buildPanelWorkspace always falls back to the canonical
|
|
30
30
|
// DEFAULT_PANEL_PALETTE.headerBg (one title band everywhere).
|
|
31
31
|
// ---------------------------------------------------------------------------
|
|
32
32
|
|
|
33
|
-
// Hunk blue is the shared DIFF_TONES token
|
|
33
|
+
// Hunk blue is the shared DIFF_TONES token, diff-view.ts (conversation)
|
|
34
34
|
// and git-panel.ts's inline diff converge onto this file's pre-existing value.
|
|
35
35
|
const HUNK_BLUE: string = DIFF_TONES.hunk;
|
|
36
36
|
// Context rows and line-number gutter use the shared theme's muted/dim
|
|
@@ -38,7 +38,7 @@ const HUNK_BLUE: string = DIFF_TONES.hunk;
|
|
|
38
38
|
const CONTEXT_GRAY = UI_TONES.fg.muted;
|
|
39
39
|
const FILENAME_WHITE = '#ffffff';
|
|
40
40
|
// Add/del text colors are the shared DIFF_TONES tokens, whose values ARE this
|
|
41
|
-
// panel's shipped colors
|
|
41
|
+
// panel's shipped colors, this panel is the reference diff look (diff-view
|
|
42
42
|
// was unwired dead code until, so "majority of surfaces" was a mirage);
|
|
43
43
|
// the conversation surface converges onto these, not the reverse.
|
|
44
44
|
const ADD_GREEN: string = DIFF_TONES.add;
|
|
@@ -56,7 +56,7 @@ const TAB_BG = '#222222';
|
|
|
56
56
|
const STATUS_BAR_BG = '#444444';
|
|
57
57
|
|
|
58
58
|
const COLOR = extendPalette(DEFAULT_PANEL_PALETTE, {
|
|
59
|
-
// Workspace-chrome aliases (title band excluded
|
|
59
|
+
// Workspace-chrome aliases (title band excluded, no headerBg override)
|
|
60
60
|
info: HUNK_BLUE,
|
|
61
61
|
dim: CONTEXT_GRAY,
|
|
62
62
|
value: FILENAME_WHITE,
|
|
@@ -148,7 +148,7 @@ function parseDiff(raw: string): ParsedLine[] {
|
|
|
148
148
|
result.push({ kind: 'deletion', text: line.slice(1), beforeNum: before, afterNum: null });
|
|
149
149
|
before++;
|
|
150
150
|
} else if (line.startsWith('\\')) {
|
|
151
|
-
// "No newline at end of file" note
|
|
151
|
+
// "No newline at end of file" note, treat as header
|
|
152
152
|
result.push({ kind: 'header', text: line, beforeNum: null, afterNum: null });
|
|
153
153
|
} else {
|
|
154
154
|
// context line (starts with space, or empty for blank context)
|
|
@@ -168,7 +168,7 @@ function parseDiff(raw: string): ParsedLine[] {
|
|
|
168
168
|
|
|
169
169
|
/**
|
|
170
170
|
* Synthetic placeholder entries ('(error)', '(no changes)', '(no staged
|
|
171
|
-
* changes)', '(not a git repo)') are not real diffs
|
|
171
|
+
* changes)', '(not a git repo)') are not real diffs, parenthesized so they
|
|
172
172
|
* can be styled distinctly in the tab/status bar instead of reading as a fake
|
|
173
173
|
* diff of a real file.
|
|
174
174
|
*/
|
|
@@ -181,7 +181,7 @@ function isPlaceholderPath(filePath: string): boolean {
|
|
|
181
181
|
* order: the standard two-sided header (`diff --git a/x b/y`, bare or
|
|
182
182
|
* quoted), the combined/merge-conflict header (`diff --cc <path>` /
|
|
183
183
|
* `diff --combined <path>`, which carries no a/b prefixes), then falls back
|
|
184
|
-
* to the `+++`/`---` file lines (present across every variant, uniformly)
|
|
184
|
+
* to the `+++`/`---` file lines (present across every variant, uniformly),
|
|
185
185
|
* skipping a `/dev/null` side (deleted/new file). 'unknown' is reserved for
|
|
186
186
|
* genuinely unparseable input.
|
|
187
187
|
*/
|
|
@@ -274,7 +274,7 @@ export class DiffPanel extends BasePanel {
|
|
|
274
274
|
private selectedFile = 0;
|
|
275
275
|
private scrollOffset = 0;
|
|
276
276
|
|
|
277
|
-
/** One-line confirmation for the 'w'/'h'/'s' self-load hotkeys
|
|
277
|
+
/** One-line confirmation for the 'w'/'h'/'s' self-load hotkeys, otherwise a
|
|
278
278
|
* reload that produces identical content is visually indistinguishable
|
|
279
279
|
* from the keypress doing nothing at all. */
|
|
280
280
|
private hotkeyStatus: string | null = null;
|
|
@@ -320,7 +320,7 @@ export class DiffPanel extends BasePanel {
|
|
|
320
320
|
}
|
|
321
321
|
|
|
322
322
|
/**
|
|
323
|
-
* Ingest a StructuredDiff (GitService.diffStructured
|
|
323
|
+
* Ingest a StructuredDiff (GitService.diffStructured, the FULL, uncapped
|
|
324
324
|
* working-tree diff). Each file becomes one DiffEntry (unified text
|
|
325
325
|
* reconstructed) so the existing tabs/renderer work unchanged; the old
|
|
326
326
|
* 4,000-char slice is gone and a diff of any length renders complete.
|
|
@@ -340,7 +340,7 @@ export class DiffPanel extends BasePanel {
|
|
|
340
340
|
}
|
|
341
341
|
|
|
342
342
|
/**
|
|
343
|
-
* Defensive gate mirroring GitPanel's own notGitRepo messaging
|
|
343
|
+
* Defensive gate mirroring GitPanel's own notGitRepo messaging, short-
|
|
344
344
|
* circuits before any of this panel's self-load git spawns run, instead of
|
|
345
345
|
* letting git fail per-subcommand with an inconsistent error shape.
|
|
346
346
|
*/
|
|
@@ -414,7 +414,7 @@ export class DiffPanel extends BasePanel {
|
|
|
414
414
|
|
|
415
415
|
/**
|
|
416
416
|
* Run `git diff --cached` and populate the staged changes. Self-load entry
|
|
417
|
-
* point for the 's' key
|
|
417
|
+
* point for the 's' key, its own diff plumbing, independent of the
|
|
418
418
|
* `/diff staged` command handler.
|
|
419
419
|
*/
|
|
420
420
|
async showStagedDiff(): Promise<void> {
|
|
@@ -444,7 +444,7 @@ export class DiffPanel extends BasePanel {
|
|
|
444
444
|
/**
|
|
445
445
|
* Best-effort semantic-diff enrichment for a set of files, run against the
|
|
446
446
|
* before-content at `ref` and the current on-disk after-content. Self-contained
|
|
447
|
-
* diff plumbing
|
|
447
|
+
* diff plumbing, does not depend on the `/diff` command handler.
|
|
448
448
|
*/
|
|
449
449
|
private async enrichSemanticDiffs(files: string[], ref: string): Promise<void> {
|
|
450
450
|
if (files.length === 0) return;
|
|
@@ -517,7 +517,7 @@ export class DiffPanel extends BasePanel {
|
|
|
517
517
|
|
|
518
518
|
/**
|
|
519
519
|
* Wraps a self-load hotkey ('w'/'h'/'s') with visible before/after status
|
|
520
|
-
* text in the status bar
|
|
520
|
+
* text in the status bar, otherwise a reload whose content is unchanged
|
|
521
521
|
* from what's already shown is indistinguishable from the keypress having
|
|
522
522
|
* done nothing at all (contrast with `/diff working`'s ctx.print() calls).
|
|
523
523
|
*/
|
|
@@ -540,7 +540,7 @@ export class DiffPanel extends BasePanel {
|
|
|
540
540
|
// Shift+Tab: most terminals send the bare CSI-Z ("backtab") escape
|
|
541
541
|
// sequence rather than a Tab keypress with a shift modifier, and the
|
|
542
542
|
// input tokenizer passes that sequence through unchanged as the
|
|
543
|
-
// logical key name
|
|
543
|
+
// logical key name, so it (and the friendlier aliases some terminals/
|
|
544
544
|
// future tokenizer versions may emit) are matched explicitly here.
|
|
545
545
|
case '\x1b[Z':
|
|
546
546
|
case 'shift-tab':
|
|
@@ -559,7 +559,7 @@ export class DiffPanel extends BasePanel {
|
|
|
559
559
|
// handlePanelIntegrationAction cross-panel hook (the same bridge
|
|
560
560
|
// FileExplorerPanel used). 'preview' is DELETE-disposition with no
|
|
561
561
|
// successor surface (no file-picker-overlay preview to repoint to
|
|
562
|
-
// either
|
|
562
|
+
// either, verified), so the key and the hook were removed rather than
|
|
563
563
|
// repointed; diff no longer has an 'o' action.
|
|
564
564
|
|
|
565
565
|
private scrollUp(): void {
|
|
@@ -630,7 +630,7 @@ export class DiffPanel extends BasePanel {
|
|
|
630
630
|
width,
|
|
631
631
|
' No diff to display.',
|
|
632
632
|
'Load a git diff or select a changed file to populate the workspace. w=working h=HEAD s=staged self-load right here.',
|
|
633
|
-
// corrected
|
|
633
|
+
// corrected, bare /diff loads files changed *this
|
|
634
634
|
// session* (falling back to the full HEAD diff when none are
|
|
635
635
|
// tracked yet), not the working-tree diff the w key already
|
|
636
636
|
// loads in-panel; the old summary text described the wrong
|
|
@@ -711,7 +711,7 @@ export class DiffPanel extends BasePanel {
|
|
|
711
711
|
const placeholder = isPlaceholderPath(entry.filePath);
|
|
712
712
|
const stat = diffStat(entry);
|
|
713
713
|
// Placeholder entries ('(error)', '(no changes)', ...) get a distinct
|
|
714
|
-
// warn color regardless of active/inactive
|
|
714
|
+
// warn color regardless of active/inactive, they are not a real diff
|
|
715
715
|
// of a real file and must not read as one.
|
|
716
716
|
const fg = placeholder ? COLOR.warn : (active ? COLOR.tabActive : COLOR.tabInactive);
|
|
717
717
|
const bg = active ? COLOR.tabActiveBg : COLOR.tabBg;
|
|
@@ -745,7 +745,7 @@ export class DiffPanel extends BasePanel {
|
|
|
745
745
|
const fileInfo = truncateDisplay(entry.filePath, pathBudget);
|
|
746
746
|
const segments: Array<{ text: string; fg: string; bg?: string; bold?: boolean }> = [
|
|
747
747
|
// Placeholder states ('(error)', '(no changes)', ...) are not a real
|
|
748
|
-
// diff of a real file
|
|
748
|
+
// diff of a real file, a distinct warn color keeps them from being
|
|
749
749
|
// mistaken for one.
|
|
750
750
|
{ text: ` ${fileInfo} `, fg: placeholder ? COLOR.warn : COLOR.filename, bg: COLOR.statusBar, bold: true },
|
|
751
751
|
{ text: `[${this.selectedFile + 1}/${this.entries.length}]`, fg: COLOR.tabInactive, bg: COLOR.statusBar },
|