@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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// ---------------------------------------------------------------------------
|
|
2
|
-
// workstream-graph-render.ts
|
|
2
|
+
// workstream-graph-render.ts, render a workstream's task graph (fleet.graph.get)
|
|
3
3
|
// legibly, so the observability layer shows the dependency graph's shape,
|
|
4
4
|
// states, and pool posture WITHOUT opening any transcript.
|
|
5
5
|
//
|
|
@@ -23,7 +23,7 @@ export function renderPoolSummary(pool: WorkstreamGraphSnapshot['pool']): string
|
|
|
23
23
|
return pool.atCap ? `${base}, at cap (fleet.maxSize=${pool.maxSize})` : base;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
/** The leading glyph for a node
|
|
26
|
+
/** The leading glyph for a node, orphaned/blocked/stalled tells win over the base state. */
|
|
27
27
|
function nodeGlyph(node: WorkstreamGraphNode): string {
|
|
28
28
|
if (node.orphaned) return '⊘';
|
|
29
29
|
if (node.blockedReason) return '⊘';
|
|
@@ -41,7 +41,7 @@ function nodeGlyph(node: WorkstreamGraphNode): string {
|
|
|
41
41
|
function nodeTell(node: WorkstreamGraphNode, needs: readonly string[]): string {
|
|
42
42
|
const parts: string[] = [];
|
|
43
43
|
if (node.blockedReason) {
|
|
44
|
-
parts.push(`blocked
|
|
44
|
+
parts.push(`blocked: waiting on: ${node.blockedReason}`);
|
|
45
45
|
} else if (node.state === 'running') {
|
|
46
46
|
parts.push(node.agentId ? `running (${node.agentId})` : 'running');
|
|
47
47
|
} else if (node.state === 'ready') {
|
|
@@ -61,7 +61,7 @@ function fit(line: string, width: number): string {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
|
-
* Wrap content to the width on word boundaries
|
|
64
|
+
* Wrap content to the width on word boundaries, NO clipping: the whole tell
|
|
65
65
|
* (including a long "waiting on: …" reason) survives onto indented continuation
|
|
66
66
|
* lines rather than being cut off. `firstIndent` leads the first line;
|
|
67
67
|
* `contIndent` leads each continuation. A single word longer than the width is
|
|
@@ -96,7 +96,7 @@ function wrapContent(content: string, width: number, firstIndent: string, contIn
|
|
|
96
96
|
export function renderWorkstreamGraphLines(snapshot: WorkstreamGraphSnapshot, width: number): string[] {
|
|
97
97
|
const lines: string[] = [];
|
|
98
98
|
// Title and pool posture on their own lines so neither clips the other at a
|
|
99
|
-
// narrow width
|
|
99
|
+
// narrow width, the pool summary ("… at cap (fleet.maxSize=N)") is load-bearing.
|
|
100
100
|
lines.push(fit(snapshot.title, width));
|
|
101
101
|
lines.push(fit(` ${renderPoolSummary(snapshot.pool)}`, width));
|
|
102
102
|
|
|
@@ -120,7 +120,7 @@ export function constraintStatusMarker(
|
|
|
120
120
|
if (finding.satisfied) {
|
|
121
121
|
return { tag: '[SAT]', fg: C.good, dim: false };
|
|
122
122
|
}
|
|
123
|
-
// Unsatisfied
|
|
123
|
+
// Unsatisfied, use severity to pick colour and tag text
|
|
124
124
|
const sev = finding.severity ?? 'major';
|
|
125
125
|
let sevTag: string;
|
|
126
126
|
let fg: string;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* broker-approval-card
|
|
2
|
+
* broker-approval-card, render a broker-originated approval ask as a real
|
|
3
3
|
* TUI approval card.
|
|
4
4
|
*
|
|
5
5
|
* The approval broker publishes every ask (local runtime asks, plus
|
|
6
6
|
* broker-originated ones like the CI fix-session offer). Local asks carry a
|
|
7
7
|
* `localPrompt` that opens their own card; broker-originated asks do not, so
|
|
8
|
-
* before this they were invisible in the TUI
|
|
8
|
+
* before this they were invisible in the TUI, the ask sat pending with no
|
|
9
9
|
* surface. This helper opens a card straight from broker state for those.
|
|
10
10
|
*
|
|
11
11
|
* A local ask's own prompt is opened by the broker immediately AFTER it
|
|
12
12
|
* publishes (see ApprovalBroker.requestApproval), so the open here is deferred
|
|
13
13
|
* one microtask and re-checks: if a card (the local one, or another broker
|
|
14
|
-
* card) is already up, it does nothing
|
|
14
|
+
* card) is already up, it does nothing, only a genuinely unhandled ask surfaces.
|
|
15
15
|
* The card's resolve answers the broker directly via resolveApproval, so a TUI
|
|
16
16
|
* decision on a broker-originated ask reaches every waiter on that record.
|
|
17
17
|
*/
|
|
@@ -21,7 +21,7 @@ import type { ApprovalRequesterLookup } from './hunk-selection.ts';
|
|
|
21
21
|
import type { PendingPermissionState } from '../shell/blocking-input.ts';
|
|
22
22
|
import type { PermissionPromptRequest, RememberTier } from '@pellux/goodvibes-sdk/platform/permissions';
|
|
23
23
|
|
|
24
|
-
/** The broker seam this helper answers through
|
|
24
|
+
/** The broker seam this helper answers through, a subset of ApprovalBroker. */
|
|
25
25
|
export interface BrokerApprovalCardBroker extends ApprovalRequesterLookup {
|
|
26
26
|
getApproval(approvalId: string): { readonly status: string; readonly request: PermissionPromptRequest } | null;
|
|
27
27
|
resolveApproval(
|
|
@@ -46,7 +46,7 @@ export interface BrokerApprovalChangeParams {
|
|
|
46
46
|
readonly request: PermissionPromptRequest;
|
|
47
47
|
/** The REAL attachable session id once an ACCEPTED ask (e.g. a ci:fix-session offer) has spawned its session. */
|
|
48
48
|
readonly fixSessionId?: string | undefined;
|
|
49
|
-
/** The honest failure when an accepted ask's spawn did NOT produce an attachable session
|
|
49
|
+
/** The honest failure when an accepted ask's spawn did NOT produce an attachable session, mutually exclusive with fixSessionId. */
|
|
50
50
|
readonly fixSessionError?: string | undefined;
|
|
51
51
|
};
|
|
52
52
|
readonly getPending: () => PendingPermissionState | null;
|
|
@@ -55,7 +55,7 @@ export interface BrokerApprovalChangeParams {
|
|
|
55
55
|
readonly render: () => void;
|
|
56
56
|
/**
|
|
57
57
|
* Fired when a record carries the id of a session an accepted ask spawned
|
|
58
|
-
* (the CI fix-session). The surface that accepted
|
|
58
|
+
* (the CI fix-session). The surface that accepted, attached now, turns this
|
|
59
59
|
* into a jump/attach affordance. Called each time the field is seen; the
|
|
60
60
|
* caller de-duplicates by id.
|
|
61
61
|
*/
|
|
@@ -74,7 +74,7 @@ export interface BrokerApprovalChangeParams {
|
|
|
74
74
|
const isActiveStatus = (status: string): boolean => status === 'pending' || status === 'claimed';
|
|
75
75
|
|
|
76
76
|
export interface FixSessionAffordanceDeps {
|
|
77
|
-
/** Announce the ready fix session as one actionable line
|
|
77
|
+
/** Announce the ready fix session as one actionable line, never a retype instruction. */
|
|
78
78
|
readonly notify: (message: string) => void;
|
|
79
79
|
/** Arm the one-key jump with the spawned session id; the surface consumes it on the jump key. */
|
|
80
80
|
readonly arm: (fixSessionId: string) => void;
|
|
@@ -83,7 +83,7 @@ export interface FixSessionAffordanceDeps {
|
|
|
83
83
|
/**
|
|
84
84
|
* Build the one-key jump/attach affordance for a spawned fix-session: the first
|
|
85
85
|
* time a given session id is seen it ARMS the jump (the surface attaches on the
|
|
86
|
-
* jump key
|
|
86
|
+
* jump key, the machine does the resume, the user never retypes an id) and
|
|
87
87
|
* surfaces a one-line actionable notice. Repeats are no-ops (de-duplicated by
|
|
88
88
|
* id), so the live record update and the listApprovals refresh path can both
|
|
89
89
|
* feed it safely.
|
|
@@ -94,7 +94,7 @@ export function buildFixSessionAffordance(deps: FixSessionAffordanceDeps): (fixS
|
|
|
94
94
|
if (seen.has(fixSessionId)) return;
|
|
95
95
|
seen.add(fixSessionId);
|
|
96
96
|
deps.arm(fixSessionId);
|
|
97
|
-
deps.notify('[CI] Fix session ready
|
|
97
|
+
deps.notify('[CI] Fix session ready: press j to jump to it.');
|
|
98
98
|
};
|
|
99
99
|
}
|
|
100
100
|
|
|
@@ -116,7 +116,7 @@ export function buildFixSessionErrorNotice(notify: (message: string) => void): (
|
|
|
116
116
|
export interface FixSessionAttachKeyDeps {
|
|
117
117
|
/** The armed fix-session id (the surface clears the arm before calling this). */
|
|
118
118
|
readonly armedFixSessionId: string;
|
|
119
|
-
/** Attach/jump to the fix session
|
|
119
|
+
/** Attach/jump to the fix session, runs the resume so the user never retypes an id. */
|
|
120
120
|
readonly attach: (fixSessionId: string) => void;
|
|
121
121
|
readonly render: () => void;
|
|
122
122
|
}
|
|
@@ -163,8 +163,8 @@ export function handleBrokerApprovalChange(params: BrokerApprovalChangeParams):
|
|
|
163
163
|
const active = isActiveStatus(approval.status);
|
|
164
164
|
|
|
165
165
|
// An accepted ask that spawned a session (the CI fix-session) publishes its
|
|
166
|
-
// REAL session id as a record update
|
|
167
|
-
// it
|
|
166
|
+
// REAL session id as a record update, the live in-process handle to jump to
|
|
167
|
+
// it, or, when the spawn failed, an honest error instead of a dead id
|
|
168
168
|
// (mutually exclusive). Both arrive after the card has resolved and cleared,
|
|
169
169
|
// so surface them independently of the card lifecycle below.
|
|
170
170
|
if (approval.fixSessionId) params.onFixSessionStarted?.(approval.fixSessionId);
|
|
@@ -172,7 +172,7 @@ export function handleBrokerApprovalChange(params: BrokerApprovalChangeParams):
|
|
|
172
172
|
|
|
173
173
|
const pending = getPending();
|
|
174
174
|
if (pending && pending.callId === approval.callId) {
|
|
175
|
-
// This is the card already on screen
|
|
175
|
+
// This is the card already on screen, clear it once its approval resolves.
|
|
176
176
|
if (!active) { setPending(null); render(); }
|
|
177
177
|
return;
|
|
178
178
|
}
|
|
@@ -6,7 +6,7 @@ import type { PermissionAttribution, PermissionPromptRequest, RememberTier } fro
|
|
|
6
6
|
* Scoped to the `edit` tool only: EditInput.edits is already an array of
|
|
7
7
|
* independent, atomic find/replace units (each a natural "hunk"), so no
|
|
8
8
|
* diff/hunk-apply primitive is needed here. The `write` (whole-file
|
|
9
|
-
* overwrite) tool stays whole-payload accept/reject
|
|
9
|
+
* overwrite) tool stays whole-payload accept/reject, true whole-file hunk
|
|
10
10
|
* splitting would require a genuinely new SDK diff/patch-apply primitive,
|
|
11
11
|
* flagged as an explicit v2 follow-up, not built here.
|
|
12
12
|
*
|
|
@@ -18,7 +18,7 @@ import type { PermissionAttribution, PermissionPromptRequest, RememberTier } fro
|
|
|
18
18
|
* symbol, per the cross-repo compile contract for this wave.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
/** Structural shape of one EditItem, read defensively
|
|
21
|
+
/** Structural shape of one EditItem, read defensively, see module doc. */
|
|
22
22
|
export interface EditItemLike {
|
|
23
23
|
readonly path: string;
|
|
24
24
|
readonly find: string;
|
|
@@ -39,7 +39,7 @@ export type HunkCommit = 'apply' | 'cancel' | null;
|
|
|
39
39
|
* (0.36.0, no `modifiedArgs` field yet) so main.ts can resolve a decision
|
|
40
40
|
* carrying `modifiedArgs` without a nominal import of a not-yet-published
|
|
41
41
|
* SDK symbol. Assign to a variable of this type before calling the SDK's
|
|
42
|
-
* typed `resolve(decision: PermissionPromptDecision)
|
|
42
|
+
* typed `resolve(decision: PermissionPromptDecision)`, passing a variable
|
|
43
43
|
* (not an object literal) sidesteps TypeScript's excess-property check, and
|
|
44
44
|
* the extra field is invisible to 0.36.0 callers, structurally compatible
|
|
45
45
|
* once 0.37 adds it for real.
|
|
@@ -50,7 +50,7 @@ export interface PermissionPromptDecisionWithModifiedArgs {
|
|
|
50
50
|
modifiedArgs?: Record<string, unknown>;
|
|
51
51
|
/** Generalizing remember tier: 'session' | 'exact' | 'command-class' | 'path' | 'tool'. */
|
|
52
52
|
rememberTier?: RememberTier;
|
|
53
|
-
/** Free-text from the user; most useful on deny
|
|
53
|
+
/** Free-text from the user; most useful on deny, rides the structured "user declined" tool result. */
|
|
54
54
|
reason?: string;
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -90,7 +90,7 @@ function readEditItems(args: Record<string, unknown>): EditItemLike[] | null {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
/**
|
|
93
|
-
* isHunkSelectable
|
|
93
|
+
* isHunkSelectable, true iff this is a multi-edit `edit` tool call. Single-edit
|
|
94
94
|
* `edit` calls, `write` calls, and everything else keep the exact current
|
|
95
95
|
* y/a/n flow untouched (zero behavior change for the common case).
|
|
96
96
|
*/
|
|
@@ -100,7 +100,7 @@ export function isHunkSelectable(request: PermissionPromptRequest): boolean {
|
|
|
100
100
|
return items !== null && items.length > 1;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
/** Builds initial hunk-selection state
|
|
103
|
+
/** Builds initial hunk-selection state, all hunks selected by default (matches today's "y = approve everything" expectation as the zero-navigation path). */
|
|
104
104
|
export function buildHunkSelectionState(request: PermissionPromptRequest): HunkSelectionState {
|
|
105
105
|
const hunks = readEditItems(request.args) ?? [];
|
|
106
106
|
return {
|
|
@@ -111,7 +111,7 @@ export function buildHunkSelectionState(request: PermissionPromptRequest): HunkS
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
/**
|
|
114
|
-
* applyHunkKey
|
|
114
|
+
* applyHunkKey, pure reducer over raw stdin `data` for an active hunk-selection
|
|
115
115
|
* prompt. Mirrors the outer y/a/n prompt's raw-data key routing (not the
|
|
116
116
|
* normalized panel key vocabulary) since Space must be distinguishable from
|
|
117
117
|
* the trimmed/lowercased `key` the outer switch uses.
|
|
@@ -156,7 +156,7 @@ export function applyHunkKey(state: HunkSelectionState, data: string): HunkKeyRe
|
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
/**
|
|
159
|
-
* buildModifiedEditArgs
|
|
159
|
+
* buildModifiedEditArgs, returns request.args with `edits` filtered to exactly
|
|
160
160
|
* the selected hunks (in original order), preserving every other EditInput
|
|
161
161
|
* field (match/transaction/output/dry_run/validate) untouched.
|
|
162
162
|
*/
|
|
@@ -178,7 +178,7 @@ export interface ApprovalRequesterLookup {
|
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
/**
|
|
181
|
-
* Human label for a `mcp-server` or `sandbox-escalation` attribution
|
|
181
|
+
* Human label for a `mcp-server` or `sandbox-escalation` attribution, the two
|
|
182
182
|
* non-agent origins the approval broker can name (see PermissionAttribution in
|
|
183
183
|
* the SDK). `background-agent` deliberately falls through to the
|
|
184
184
|
* broker-metadata lookup below instead, which resolves a richer label
|
|
@@ -206,7 +206,7 @@ function describeNonAgentAttribution(attribution: PermissionAttribution): string
|
|
|
206
206
|
* for a request exists by the time its local prompt is shown), preferring an
|
|
207
207
|
* explicit requester recorded in the broker record's metadata (agentId /
|
|
208
208
|
* agent / requestedBy / actor / actorSurface), then the owning session id.
|
|
209
|
-
* Returns null when nothing identifying is available
|
|
209
|
+
* Returns null when nothing identifying is available, the prompt then omits
|
|
210
210
|
* the attribution line rather than guessing a name.
|
|
211
211
|
*/
|
|
212
212
|
export function resolveApprovalRequester(
|
|
@@ -238,11 +238,11 @@ export function resolveApprovalRequester(
|
|
|
238
238
|
}
|
|
239
239
|
|
|
240
240
|
/**
|
|
241
|
-
* buildPendingPermissionExtras
|
|
241
|
+
* buildPendingPermissionExtras, the `hunkState` + wrapped `resolve` fields
|
|
242
242
|
* (plus the input-debounce timestamp and requester attribution) main.ts spreads
|
|
243
243
|
* onto its PendingPermissionState alongside `...request`. Bundled into one
|
|
244
244
|
* helper (rather than inlined in main.ts) to keep main.ts's net line count at
|
|
245
|
-
* zero for this change
|
|
245
|
+
* zero for this change, main.ts sits at the 800-line architecture cap and must
|
|
246
246
|
* never grow it.
|
|
247
247
|
*
|
|
248
248
|
* `openedAt` is the moment the prompt appeared; the blocking-input handler uses
|
|
@@ -264,7 +264,7 @@ export function buildPendingPermissionExtras(
|
|
|
264
264
|
replyBuffer: string | undefined;
|
|
265
265
|
} {
|
|
266
266
|
// An exec-prompt ask (a running command waiting on stdin) opens straight in
|
|
267
|
-
// answer mode: every printable key types the answer
|
|
267
|
+
// answer mode: every printable key types the answer, a run whose prompt
|
|
268
268
|
// needs a literal 'y' must never have it eaten as a card command key.
|
|
269
269
|
const isExecPrompt = request.attribution?.kind === 'exec-prompt';
|
|
270
270
|
return {
|
|
@@ -66,7 +66,7 @@ function collectField(arr: unknown, field: string): string[] {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
/**
|
|
69
|
-
* The real display target(s) of a tool invocation
|
|
69
|
+
* The real display target(s) of a tool invocation, the paths/commands/urls a
|
|
70
70
|
* user needs to see, extracted from the actual arg shapes so a nested
|
|
71
71
|
* `{files:[{path}]}` no longer falls through to a raw JSON blob. (2a.)
|
|
72
72
|
* Returns [] when nothing recognisable is present (caller falls back).
|
|
@@ -103,17 +103,17 @@ function categoryVerb(category: PermissionCategory): string {
|
|
|
103
103
|
/**
|
|
104
104
|
* Single source of truth for how many Line rows the hunk-list section
|
|
105
105
|
* occupies: 1 header row + up to MAX_VISIBLE_HUNKS checkbox rows + 1 trailer
|
|
106
|
-
* row (rendered as "+N more" when truncated, blank otherwise
|
|
106
|
+
* row (rendered as "+N more" when truncated, blank otherwise, always
|
|
107
107
|
* present so the row count never depends on which branch fires). Both
|
|
108
108
|
* getPromptHeight and createPromptLines call this SAME function, so they
|
|
109
|
-
* cannot drift apart (Risk 2
|
|
109
|
+
* cannot drift apart (Risk 2, main.ts's render loop reserves viewport
|
|
110
110
|
* space from getPromptHeight *before* the real render happens).
|
|
111
111
|
*/
|
|
112
112
|
/**
|
|
113
113
|
* The optional sandbox model-judgment tier (see sandbox-judgment.ts in the
|
|
114
|
-
* SDK) annotates an escalation ask by pushing one string
|
|
114
|
+
* SDK) annotates an escalation ask by pushing one string, verbatim
|
|
115
115
|
* "model judgment: looks safe because…" / "model judgment: flags risk
|
|
116
|
-
* because…"
|
|
116
|
+
* because…", onto `analysis.reasons`, alongside the sandbox-boundary and
|
|
117
117
|
* policy reasons. Pulled out here so it gets its own clearly-labeled row
|
|
118
118
|
* instead of blending into the generic Review bullets, where the truncation
|
|
119
119
|
* to 2 reasons could silently cut it (it is typically the LAST reason
|
|
@@ -162,7 +162,7 @@ export class PermissionPromptUI {
|
|
|
162
162
|
return targets.length > 0 ? targets : [getDisplayArg(request.tool, request.args)];
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
/** Path-field row texts
|
|
165
|
+
/** Path-field row texts, one per target when few, a "N files:" summary when many. */
|
|
166
166
|
private static pathRowTexts(targets: string[], maxLen: number): string[] {
|
|
167
167
|
const clamp = (s: string): string => (s.length > maxLen ? `...${s.slice(-(maxLen - 3))}` : s);
|
|
168
168
|
if (targets.length <= 1) return [clamp(targets[0] ?? '(unknown)')];
|
|
@@ -183,11 +183,11 @@ export class PermissionPromptUI {
|
|
|
183
183
|
): boolean {
|
|
184
184
|
if (hunkState || detailsExpanded) return false;
|
|
185
185
|
// Shell execution, delegation and network requests always show the full
|
|
186
|
-
// card
|
|
186
|
+
// card, their action semantics (command, side effects, host, checklist)
|
|
187
187
|
// warrant scrutiny even when the risk model rates them low. Only mundane
|
|
188
188
|
// low-risk filesystem reads/writes condense. (2b.)
|
|
189
189
|
if (request.category === 'execute' || request.category === 'delegate') return false;
|
|
190
|
-
// Remember tiers are one-key choices that must be visible to be usable
|
|
190
|
+
// Remember tiers are one-key choices that must be visible to be usable,
|
|
191
191
|
// a request carrying rememberOptions always shows the full card.
|
|
192
192
|
if (request.rememberOptions && request.rememberOptions.length > 0) return false;
|
|
193
193
|
const analysis = this.fallbackAnalysis(request);
|
|
@@ -238,13 +238,13 @@ export class PermissionPromptUI {
|
|
|
238
238
|
const clamp = (s: string): string => (s.length > width ? `${s.slice(0, Math.max(0, width - 3))}...` : s);
|
|
239
239
|
return options.map((option, index) => {
|
|
240
240
|
const labelCol = index === 0 ? 'Remember ' : ' '.repeat(9);
|
|
241
|
-
return clamp(` ${labelCol}: [${index + 1}] ${option.label}
|
|
241
|
+
return clamp(` ${labelCol}: [${index + 1}] ${option.label}; ${option.detail}`);
|
|
242
242
|
});
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
/**
|
|
246
246
|
* The FULL command of an execute ask, wrapped across as many rows as it
|
|
247
|
-
* needs
|
|
247
|
+
* needs, never truncated. Empty for non-execute asks and for asks without
|
|
248
248
|
* a string command. Shared by getPromptHeight and createPromptLines.
|
|
249
249
|
*/
|
|
250
250
|
private static commandRowTexts(request: PermissionPromptRequest, width: number): string[] {
|
|
@@ -340,7 +340,7 @@ export class PermissionPromptUI {
|
|
|
340
340
|
|
|
341
341
|
/**
|
|
342
342
|
* Assemble the card's view state from the pending-permission slot and the
|
|
343
|
-
* broker's live queue (the honest count of OTHER pending asks
|
|
343
|
+
* broker's live queue (the honest count of OTHER pending asks, coalesced
|
|
344
344
|
* asks share one record, so they are never double-counted). One helper so
|
|
345
345
|
* main.ts passes identical state to getPromptHeight and createPromptLines.
|
|
346
346
|
*/
|
|
@@ -372,7 +372,7 @@ export class PermissionPromptUI {
|
|
|
372
372
|
const attributionLines = requestedBy ? 1 : 0;
|
|
373
373
|
const rememberLines = this.rememberRowTexts(request, hunkState, width).length;
|
|
374
374
|
// Condensed low-risk card: top separator, title, [attribution], [preview],
|
|
375
|
-
// summary, choices, bottom separator
|
|
375
|
+
// summary, choices, bottom separator, see createPromptLines' condensed branch.
|
|
376
376
|
if (this.isCondensed(request, hunkState, detailsExpanded)) return 5 + attributionLines + rememberLines;
|
|
377
377
|
const analysis = this.fallbackAnalysis(request);
|
|
378
378
|
const { annotation: judgmentAnnotation, rest: reasonsMinusJudgment } = extractModelJudgmentAnnotation(analysis.reasons);
|
|
@@ -445,7 +445,7 @@ export class PermissionPromptUI {
|
|
|
445
445
|
// Honest queue: how many OTHER broker asks are waiting behind this one.
|
|
446
446
|
// They surface in turn as each is answered; the count keeps that visible.
|
|
447
447
|
const queueSuffix = view?.queueCount && view.queueCount > 0
|
|
448
|
-
?
|
|
448
|
+
? `: ${view.queueCount} more waiting`
|
|
449
449
|
: '';
|
|
450
450
|
|
|
451
451
|
// Attribution line (which agent/process is asking) and the remember block
|
|
@@ -506,14 +506,14 @@ export class PermissionPromptUI {
|
|
|
506
506
|
lines.push(UIFactory.stringToLine(` ${labelCol}: ${rowText}`.padEnd(width), width, { fg: TEXT }));
|
|
507
507
|
});
|
|
508
508
|
|
|
509
|
-
// The FULL command of an execute ask, wrapped
|
|
509
|
+
// The FULL command of an execute ask, wrapped, never truncated. The Path
|
|
510
510
|
// row above stays as the one-line subject; this block is the whole truth.
|
|
511
511
|
for (const rowText of this.commandRowTexts(request, width)) {
|
|
512
512
|
lines.push(UIFactory.stringToLine(rowText.padEnd(width), width, { fg: TEXT }));
|
|
513
513
|
}
|
|
514
514
|
|
|
515
515
|
// Exec-prompt attribution: the running command and the terminal prompt it
|
|
516
|
-
// is stuck on, wrapped in full
|
|
516
|
+
// is stuck on, wrapped in full, the typed answer feeds this run's stdin.
|
|
517
517
|
for (const rowText of this.execPromptRowTexts(request, width)) {
|
|
518
518
|
lines.push(UIFactory.stringToLine(rowText.padEnd(width), width, { fg: WARN }));
|
|
519
519
|
}
|
|
@@ -541,7 +541,7 @@ export class PermissionPromptUI {
|
|
|
541
541
|
// Sandbox escalation row: when the sandbox-aware exec gate turned an
|
|
542
542
|
// auto-allow into an ask because the boundary-safe command still needs host
|
|
543
543
|
// access, name what it wants ("wants network …"). The escalation text is the
|
|
544
|
-
// SDK policy's, verbatim
|
|
544
|
+
// SDK policy's, verbatim, this row only surfaces it.
|
|
545
545
|
const sandboxAnnotation = readSandboxAskAnnotation(request);
|
|
546
546
|
if (sandboxAnnotation && sandboxAnnotation.sandboxEscalations.length > 0) {
|
|
547
547
|
const escalations = sandboxAnnotation.sandboxEscalations.join('; ');
|
|
@@ -572,8 +572,8 @@ export class PermissionPromptUI {
|
|
|
572
572
|
|
|
573
573
|
// Model-judgment annotation: gets its own clearly-labeled row (never
|
|
574
574
|
// subject to the Review truncation below) so a `sandbox-model-judgment`
|
|
575
|
-
// verdict
|
|
576
|
-
|
|
575
|
+
// verdict, "model judgment: looks safe because…" / "flags risk because…"
|
|
576
|
+
//, is never silently cut. See extractModelJudgmentAnnotation.
|
|
577
577
|
const { annotation: judgmentAnnotation, rest: reasonsMinusJudgment } = extractModelJudgmentAnnotation(analysis.reasons);
|
|
578
578
|
if (judgmentAnnotation) {
|
|
579
579
|
const maxJudgmentLen = Math.max(10, width - 16);
|
|
@@ -598,7 +598,7 @@ export class PermissionPromptUI {
|
|
|
598
598
|
const checklistLine = ` Checklist : ${truncatedChecklist}`;
|
|
599
599
|
lines.push(UIFactory.stringToLine(checklistLine.padEnd(width), width, { fg: DIM }));
|
|
600
600
|
|
|
601
|
-
// Raw args row
|
|
601
|
+
// Raw args row, the full tool arguments live here in the details view so
|
|
602
602
|
// the Path field above can render clean path(s), never a JSON blob. (2a.)
|
|
603
603
|
const rawArgs = JSON.stringify(args);
|
|
604
604
|
const maxRawLen = Math.max(10, width - 16);
|
|
@@ -609,14 +609,14 @@ export class PermissionPromptUI {
|
|
|
609
609
|
lines.push(UIFactory.stringToLine(' '.repeat(width), width));
|
|
610
610
|
|
|
611
611
|
// Real colored diff for a write/edit ask (adds green, removals red, hunk
|
|
612
|
-
// headers blue
|
|
612
|
+
// headers blue, the same diff-view machinery the transcript uses).
|
|
613
613
|
const diffTextLines = this.writeDiffLines(request, hunkState);
|
|
614
614
|
if (diffTextLines) {
|
|
615
615
|
lines.push(...renderDiffView(diffTextLines.join('\n'), width));
|
|
616
616
|
}
|
|
617
617
|
|
|
618
618
|
if (hunkState) {
|
|
619
|
-
// Hunk list
|
|
619
|
+
// Hunk list, see hunkListRowCount() for the row-count contract this
|
|
620
620
|
// block must match exactly (Risk 2: getPromptHeight/createPromptLines
|
|
621
621
|
// parity is what keeps main.ts's render loop from clipping the
|
|
622
622
|
// viewport).
|
|
@@ -631,7 +631,7 @@ export class PermissionPromptUI {
|
|
|
631
631
|
const box = selected.has(i) ? '[x]' : '[ ]';
|
|
632
632
|
const findPreview = hunk.find.replace(/\n/g, '⏎').slice(0, maxPreviewLen);
|
|
633
633
|
const replacePreview = hunk.replace.replace(/\n/g, '⏎').slice(0, maxPreviewLen);
|
|
634
|
-
const rowText = ` ${box} ${i + 1}. ${hunk.path}
|
|
634
|
+
const rowText = ` ${box} ${i + 1}. ${hunk.path}: "${findPreview}" -> "${replacePreview}"`;
|
|
635
635
|
const isCursor = i === cursor;
|
|
636
636
|
lines.push(UIFactory.stringToLine(
|
|
637
637
|
rowText.padEnd(width),
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* sandbox-exec-gate.ts
|
|
2
|
+
* sandbox-exec-gate.ts, sandbox-aware layer over the exec approval ask.
|
|
3
3
|
*
|
|
4
4
|
* The per-command exec sandbox already RUNS boundary-safe commands inside a
|
|
5
5
|
* bubblewrap boundary (the SDK exec tool's runner half). This is the APPROVAL
|
|
6
6
|
* half: when the base permission policy would prompt ("ask") for an exec, and
|
|
7
7
|
* the sandbox is genuinely active, a command that runs entirely inside the OS
|
|
8
|
-
* boundary with no host-access need should auto-allow instead of prompting
|
|
8
|
+
* boundary with no host-access need should auto-allow instead of prompting,
|
|
9
9
|
* and a command that still needs host access should surface as an explicit ask
|
|
10
10
|
* that NAMES what it wants ("wants network …", "wants host privilege
|
|
11
11
|
* escalation").
|
|
12
12
|
*
|
|
13
|
-
* The decision is the SDK's `decideSandboxedExec
|
|
13
|
+
* The decision is the SDK's `decideSandboxedExec`, never re-implemented here.
|
|
14
14
|
* This module only (a) reads the live sandbox posture, (b) extracts the exec
|
|
15
15
|
* command(s) from the request, (c) maps the SDK decision onto the existing ask
|
|
16
16
|
* callback: allow → approve without prompting; ask → attach the named
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*
|
|
21
21
|
* This runs INSIDE the permission machinery's ask layer (like trustGatedAsk), so
|
|
22
22
|
* it composes with the real layer chain and is only ever consulted for execs the
|
|
23
|
-
* base policy already resolved to "ask"
|
|
23
|
+
* base policy already resolved to "ask", it can never turn a deny into an allow,
|
|
24
24
|
* and the frozen catastrophic block is untouched.
|
|
25
25
|
*/
|
|
26
26
|
import { decideSandboxedExec } from '@pellux/goodvibes-sdk/platform/runtime/permissions/sandbox-policy';
|
|
@@ -57,7 +57,7 @@ export interface SandboxExecAskDeps {
|
|
|
57
57
|
readonly readEgressAllowlist: () => readonly string[];
|
|
58
58
|
/**
|
|
59
59
|
* Honest host availability of the exec sandbox backend. Probing the host spawns
|
|
60
|
-
* bwrap, so the caller passes a memoized probe
|
|
60
|
+
* bwrap, so the caller passes a memoized probe, invoked at most once, and only
|
|
61
61
|
* when an exec ask actually arrives while the feature + config are on.
|
|
62
62
|
*/
|
|
63
63
|
readonly detectAvailability: () => SandboxAvailability;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* reasoning-effort-surface.ts
|
|
2
|
+
* reasoning-effort-surface.ts, the TUI's single reading of the SDK's
|
|
3
3
|
* per-model reasoning-effort spec.
|
|
4
4
|
*
|
|
5
5
|
* Every effort-shaped surface (the `/effort` command, the model picker's
|
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
* The honest presentation differs per spec kind, so the wording is generated
|
|
13
13
|
* here rather than templated at each call site:
|
|
14
14
|
*
|
|
15
|
-
* - `effort`
|
|
16
|
-
* - `budget_tokens
|
|
15
|
+
* - `effort` , the model names its levels; offer exactly those.
|
|
16
|
+
* - `budget_tokens`, the model takes a thinking-token budget, so each level
|
|
17
17
|
* is shown with the budget it sends.
|
|
18
|
-
* - `toggle`
|
|
18
|
+
* - `toggle` , reasoning is on or off only; say so, and do not imply
|
|
19
19
|
* that the levels in between mean anything.
|
|
20
|
-
* - `unavailable`
|
|
20
|
+
* - `unavailable` , nothing is configurable; the picker says that instead
|
|
21
21
|
* of presenting an empty list.
|
|
22
22
|
*
|
|
23
23
|
* A `fallback`-sourced spec is a labelled guess: neither the live catalog nor
|
|
@@ -176,7 +176,7 @@ export function effortPresentationForModel(model: EffortModelLike): EffortPresen
|
|
|
176
176
|
headline = `${name} takes a thinking-token budget; each level below sends the budget shown.`;
|
|
177
177
|
break;
|
|
178
178
|
case 'toggle':
|
|
179
|
-
headline = `${name} only exposes reasoning on or off
|
|
179
|
+
headline = `${name} only exposes reasoning on or off; there is no depth to choose.`;
|
|
180
180
|
break;
|
|
181
181
|
case 'unavailable':
|
|
182
182
|
headline = `${name} has no configurable reasoning level; it runs at its own fixed depth.`;
|
|
@@ -212,7 +212,7 @@ export function describeEffortForModel(model: EffortModelLike, current: string |
|
|
|
212
212
|
}
|
|
213
213
|
|
|
214
214
|
if (resolved.value === undefined) {
|
|
215
|
-
lines.push(` Sent on the wire: nothing
|
|
215
|
+
lines.push(` Sent on the wire: nothing; ${model.displayName ?? model.id} runs at its own default.`);
|
|
216
216
|
} else if (spec.kind === 'budget_tokens') {
|
|
217
217
|
lines.push(` Sent on the wire: ${wire} = ${budgetTokensForLevel(resolved.value, spec).toLocaleString()}`);
|
|
218
218
|
} else {
|
|
@@ -256,16 +256,16 @@ export function describeConfiguredEffort(registryKey: string, configured: string
|
|
|
256
256
|
const resolved = resolveEffortForModelSurface(configured === '' ? undefined : configured, model);
|
|
257
257
|
const wire = describeReasoningWire(spec, providerId);
|
|
258
258
|
|
|
259
|
-
if (spec.kind === 'unavailable') return `not sent
|
|
259
|
+
if (spec.kind === 'unavailable') return `not sent: ${modelId} has no configurable reasoning level`;
|
|
260
260
|
if (spec.source === 'fallback') {
|
|
261
|
-
return `${resolved.value ?? '(model default)'}
|
|
261
|
+
return `${resolved.value ?? '(model default)'}: unverified: ${modelId} is not in the model catalog, so some providers send nothing for it`;
|
|
262
262
|
}
|
|
263
|
-
if (resolved.value === undefined) return `not sent
|
|
263
|
+
if (resolved.value === undefined) return `not sent: ${modelId} applies its own default`;
|
|
264
264
|
if (spec.kind === 'budget_tokens') {
|
|
265
265
|
return `${resolved.value} (${wire} = ${budgetTokensForLevel(resolved.value, spec).toLocaleString()})`;
|
|
266
266
|
}
|
|
267
267
|
if (resolved.value !== configured && configured !== '') {
|
|
268
|
-
return `${resolved.value} (${wire})
|
|
268
|
+
return `${resolved.value} (${wire}): '${configured}' is not available on ${modelId}`;
|
|
269
269
|
}
|
|
270
270
|
return `${resolved.value} (${wire})`;
|
|
271
271
|
}
|
|
@@ -273,7 +273,7 @@ export function describeConfiguredEffort(registryKey: string, configured: string
|
|
|
273
273
|
/**
|
|
274
274
|
* Re-resolve a configured level against a model that is about to serve, for
|
|
275
275
|
* the model-switch and failover paths. Returns the level to use and, when it
|
|
276
|
-
* had to change, the SDK's own sentence explaining why
|
|
276
|
+
* had to change, the SDK's own sentence explaining why, printed verbatim so
|
|
277
277
|
* the wording cannot drift from the resolution that produced it.
|
|
278
278
|
*/
|
|
279
279
|
export function remapEffortForServingModel(
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
*
|
|
4
4
|
* The TUI grid renders content character-by-character via writeStyledText,
|
|
5
5
|
* which already drops zero-width characters (including ESC \x1b) by checking
|
|
6
|
-
* display width. However, that is incidental protection
|
|
6
|
+
* display width. However, that is incidental protection, not a contract.
|
|
7
7
|
* This module provides explicit, intentional sanitization.
|
|
8
8
|
*
|
|
9
9
|
* Strategy:
|
|
10
10
|
* - STRIP all non-SGR escape sequences (cursor moves, OSC, BEL, alt-screen,
|
|
11
11
|
* DECSET/private mode, and any other CSI/ESC sequences).
|
|
12
|
-
* - PRESERVE SGR color/style codes (\x1b[<params>m)
|
|
12
|
+
* - PRESERVE SGR color/style codes (\x1b[<params>m), used legitimately by
|
|
13
13
|
* the TUI's own colorized output paths.
|
|
14
14
|
* - STRIP bare BEL (\x07) characters.
|
|
15
15
|
*
|
|
@@ -46,11 +46,10 @@ const BEL = /\x07/g;
|
|
|
46
46
|
* @returns Sanitized string safe for grid rendering
|
|
47
47
|
*/
|
|
48
48
|
export function stripDangerousAnsi(input: string): string {
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
//
|
|
49
|
+
// SGR sequences are extracted to placeholders before the other escape
|
|
50
|
+
// sequences are stripped, then restored, to avoid complex negative
|
|
51
|
+
// lookahead regexes.
|
|
52
52
|
|
|
53
|
-
// Collect SGR sequences and replace with unique markers
|
|
54
53
|
const sgrTokens: string[] = [];
|
|
55
54
|
const withPlaceholders = input.replace(SGR_PATTERN, (match) => {
|
|
56
55
|
const idx = sgrTokens.length;
|
|
@@ -33,7 +33,7 @@ function putText(line: Line, startX: number, maxWidth: number, text: string, sty
|
|
|
33
33
|
*
|
|
34
34
|
* A row's description renders inline only when it genuinely fits beside the
|
|
35
35
|
* command name; otherwise the FULL description wraps onto its own line(s)
|
|
36
|
-
* below the command name, with no line cap
|
|
36
|
+
* below the command name, with no line cap, descriptive text is never
|
|
37
37
|
* clipped (same fix as selection-modal-overlay.ts's modal rule). Item
|
|
38
38
|
* visibility is row-budget aware (a wrapped description can cost more than
|
|
39
39
|
* one physical row), always showing the selected item in full and falling
|
|
@@ -55,7 +55,7 @@ export function renderAutocompleteOverlay(
|
|
|
55
55
|
chromeRows,
|
|
56
56
|
minContentRows: 6,
|
|
57
57
|
// Rows grow with wrapped descriptions (never clipped) rather than
|
|
58
|
-
// staying pinned at a small constant
|
|
58
|
+
// staying pinned at a small constant, still bounded by the viewport.
|
|
59
59
|
maxContentRows: Math.max(10, viewportHeight - chromeRows - 4),
|
|
60
60
|
});
|
|
61
61
|
const layout = createOverlayBoxLayout(width, metrics.margin, metrics.boxWidth);
|
|
@@ -90,7 +90,7 @@ export function renderAutocompleteOverlay(
|
|
|
90
90
|
|
|
91
91
|
// palette curation (item 4): on a bare '/' (query === ''), the results
|
|
92
92
|
// list is "common tier" (score 2) followed by "alphabetical rest" (score
|
|
93
|
-
// 1)
|
|
93
|
+
// 1), see CommandRegistry.fuzzyMatch. commonCount marks that boundary;
|
|
94
94
|
// a one-row separator draws there when it falls inside the visible window.
|
|
95
95
|
const hasCommonSeparator = state.query === '' && state.commonCount > 0 && state.commonCount < total;
|
|
96
96
|
|
|
@@ -187,7 +187,7 @@ export function renderAutocompleteOverlay(
|
|
|
187
187
|
});
|
|
188
188
|
lines.push(line);
|
|
189
189
|
} else {
|
|
190
|
-
// Doesn't fit beside the command name
|
|
190
|
+
// Doesn't fit beside the command name, wrap the FULL description onto
|
|
191
191
|
// its own line(s) below at the full row width, rather than clipping it.
|
|
192
192
|
lines.push(line);
|
|
193
193
|
for (const wrapped of wrapWithHangingIndent(command.description, wrapWidth, '')) {
|
|
@@ -216,7 +216,7 @@ export function renderAutocompleteOverlay(
|
|
|
216
216
|
|
|
217
217
|
const footerLine = createOverlayContentLine(width, layout);
|
|
218
218
|
// vocab unification: "Run"/"Close" match the /help selection modal's
|
|
219
|
-
// hint bar (selection-modal-overlay.ts)
|
|
219
|
+
// hint bar (selection-modal-overlay.ts), both surfaces execute a command
|
|
220
220
|
// on Enter, so they now say so the same way.
|
|
221
221
|
const hints = '[Tab] Complete [Up/Down] Navigate [Enter] Run [Esc] Close';
|
|
222
222
|
putText(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* renderBlockActionsMenu
|
|
2
|
+
* renderBlockActionsMenu, renders the BlockActionsMenu (src/renderer/block-actions.ts)
|
|
3
3
|
* as a docked overlay, so opening it via Enter-on-an-empty-composer actually
|
|
4
4
|
* shows something. Follows the established docked-overlay pattern (see
|
|
5
5
|
* selection-modal-overlay.ts / bookmark-modal.ts): ModalFactory sizes the box
|