@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
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
// fleet-spawn.ts
|
|
3
3
|
//
|
|
4
4
|
// The Fleet panel's ACP spawn affordance: 'n' on the fleet surface lists the
|
|
5
|
-
// third-party coding agents the daemon discovered (acp.agents.list
|
|
5
|
+
// third-party coding agents the daemon discovered (acp.agents.list, read-only,
|
|
6
6
|
// quiet when none), you pick one, then pick a working directory from the known
|
|
7
|
-
// candidates (the registered workspaces + the current dir
|
|
7
|
+
// candidates (the registered workspaces + the current dir, no free-text path
|
|
8
8
|
// retyping where a known dir exists), and acp.sessions.create hosts it as a
|
|
9
9
|
// long-lived daemon session. The new row shows up on the next fleet snapshot as
|
|
10
10
|
// kind 'acp-agent' and steers/stops/flags-for-attention like any other row.
|
|
11
11
|
//
|
|
12
|
-
// A structured spawn failure ({binary, stage, message}) is surfaced verbatim
|
|
12
|
+
// A structured spawn failure ({binary, stage, message}) is surfaced verbatim,
|
|
13
13
|
// never a hung row: the daemon bounds the handshake and returns a 'failed'
|
|
14
14
|
// record, and this controller reports its three honest fields.
|
|
15
15
|
//
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
|
|
35
35
|
/** One discovered third-party ACP agent (acp.agents.list). */
|
|
36
36
|
export type AcpDiscoveredAgent = OperatorMethodOutput<'acp.agents.list'>['agents'][number];
|
|
37
|
-
/** acp.sessions.create output
|
|
37
|
+
/** acp.sessions.create output, the hosted record + whether it started. */
|
|
38
38
|
export type AcpSpawnResult = OperatorMethodOutput<'acp.sessions.create'>;
|
|
39
39
|
/** One registered workspace root (workspaces.registrations.list). */
|
|
40
40
|
export type AcpWorkspaceRegistration = OperatorMethodOutput<'workspaces.registrations.list'>['workspaces'][number];
|
|
@@ -47,13 +47,13 @@ export interface AcpDirCandidate {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
|
-
* The async verb surface the spawn flow drives
|
|
50
|
+
* The async verb surface the spawn flow drives, real daemon round-trips in
|
|
51
51
|
* production (createAcpSpawnGateway), a mocked shape in tests.
|
|
52
52
|
*/
|
|
53
53
|
export interface AcpSpawnGateway {
|
|
54
54
|
/** Discovered third-party agents (read-only; empty is a quiet, honest absence). */
|
|
55
55
|
listAgents(): Promise<readonly AcpDiscoveredAgent[]>;
|
|
56
|
-
/** The registered workspace roots
|
|
56
|
+
/** The registered workspace roots, the known-dir candidates for the picker. */
|
|
57
57
|
listWorkspaces(): Promise<readonly AcpWorkspaceRegistration[]>;
|
|
58
58
|
/** Host a discovered agent in a directory as a long-lived daemon session. */
|
|
59
59
|
createSession(input: { readonly agentId: string; readonly cwd: string }): Promise<AcpSpawnResult>;
|
|
@@ -69,7 +69,7 @@ export interface AcpSpawnGatewayDeps {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
/**
|
|
72
|
-
* Build the live ACP spawn gateway over the generic operator invoke path
|
|
72
|
+
* Build the live ACP spawn gateway over the generic operator invoke path, the
|
|
73
73
|
* same daemon resolution the fleet acts use. Honest unavailable reason when no
|
|
74
74
|
* daemon is reachable, so the spawn key refuses cleanly instead of throwing.
|
|
75
75
|
*/
|
|
@@ -88,7 +88,7 @@ export function createAcpSpawnGateway(deps: AcpSpawnGatewayDeps): AcpSpawnGatewa
|
|
|
88
88
|
export interface FleetSpawnDeps {
|
|
89
89
|
/** Resolve a live gateway per action (a daemon that comes up mid-session is seen). */
|
|
90
90
|
readonly resolveGateway: () => AcpSpawnGatewayResolution;
|
|
91
|
-
/** The current working directory
|
|
91
|
+
/** The current working directory, always a candidate dir (labeled "current directory"). */
|
|
92
92
|
readonly currentDirectory: () => string;
|
|
93
93
|
/** Surface a result/receipt/error line to the operator (system message). */
|
|
94
94
|
readonly notify: (message: string) => void;
|
|
@@ -204,10 +204,10 @@ export class FleetSpawn {
|
|
|
204
204
|
const result = await gateway.createSession({ agentId, cwd });
|
|
205
205
|
const hosted = result.hosted;
|
|
206
206
|
if (hosted.error) {
|
|
207
|
-
// Structured failure rendered verbatim
|
|
208
|
-
this.deps.notify(`[Fleet] Could not host ${hosted.title || agentId}: ${hosted.error.stage} stage failed for ${hosted.error.binary}
|
|
207
|
+
// Structured failure rendered verbatim, never a hung row.
|
|
208
|
+
this.deps.notify(`[Fleet] Could not host ${hosted.title || agentId}: ${hosted.error.stage} stage failed for ${hosted.error.binary}; ${hosted.error.message}`);
|
|
209
209
|
} else {
|
|
210
|
-
this.deps.notify(`[Fleet] Hosting ${hosted.title || agentId} in ${cwd}
|
|
210
|
+
this.deps.notify(`[Fleet] Hosting ${hosted.title || agentId} in ${cwd}; it appears as an acp-agent row; steer and stop it like any agent.`);
|
|
211
211
|
}
|
|
212
212
|
} catch (err) {
|
|
213
213
|
this.deps.notify(`ACP session create failed: ${summarizeError(err)}`);
|
|
@@ -225,10 +225,10 @@ export class FleetSpawn {
|
|
|
225
225
|
const lines: Line[] = [];
|
|
226
226
|
if (this.creating) {
|
|
227
227
|
lines.push(buildPanelLine(width, [[' Hosting the agent…', P.dim]]));
|
|
228
|
-
return buildPanelWorkspace(width, height, { title: 'Fleet
|
|
228
|
+
return buildPanelWorkspace(width, height, { title: 'Fleet: Host an agent', sections: [{ lines }], footerLines: [], palette: P });
|
|
229
229
|
}
|
|
230
230
|
if (this.mode.step === 'agent') {
|
|
231
|
-
lines.push(buildPanelLine(width, [[' Host a third-party coding agent
|
|
231
|
+
lines.push(buildPanelLine(width, [[' Host a third-party coding agent; pick one, then a directory.', P.dim]]));
|
|
232
232
|
lines.push(buildPanelLine(width, [['', P.dim]]));
|
|
233
233
|
this.mode.agents.forEach((agent, i) => {
|
|
234
234
|
const selected = i === (this.mode as AgentStep).index;
|
|
@@ -239,7 +239,7 @@ export class FleetSpawn {
|
|
|
239
239
|
]));
|
|
240
240
|
});
|
|
241
241
|
} else {
|
|
242
|
-
lines.push(buildPanelLine(width, [[` Directory for ${this.mode.agent.title}
|
|
242
|
+
lines.push(buildPanelLine(width, [[` Directory for ${this.mode.agent.title}: a known dir, no path to type.`, P.dim]]));
|
|
243
243
|
lines.push(buildPanelLine(width, [['', P.dim]]));
|
|
244
244
|
this.mode.candidates.forEach((cand, i) => {
|
|
245
245
|
const selected = i === (this.mode as DirStep).index;
|
|
@@ -255,7 +255,7 @@ export class FleetSpawn {
|
|
|
255
255
|
{ keys: 'Enter', label: this.mode.step === 'agent' ? 'pick agent' : 'host here' },
|
|
256
256
|
{ keys: 'Esc', label: 'cancel' },
|
|
257
257
|
], P)];
|
|
258
|
-
return buildPanelWorkspace(width, height, { title: 'Fleet
|
|
258
|
+
return buildPanelWorkspace(width, height, { title: 'Fleet: Host an agent', sections: [{ lines }], footerLines, palette: P });
|
|
259
259
|
}
|
|
260
260
|
|
|
261
261
|
private requireGateway(): AcpSpawnGateway | null {
|
|
@@ -34,7 +34,7 @@ export function steerBadgeTone(status: SteerBadgeStatus, palette: PanelPalette):
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
/** Labels of the currently live, steerable agent nodes other than `excludeNodeId
|
|
37
|
+
/** Labels of the currently live, steerable agent nodes other than `excludeNodeId`, offered when a steer target has gone inactive (WO item 4). */
|
|
38
38
|
export function liveSteerableLabels(nodes: readonly ProcessNode[], excludeNodeId: string): string[] {
|
|
39
39
|
return nodes
|
|
40
40
|
.filter((node) => node.id !== excludeNodeId && node.kind === 'agent' && node.capabilities.steerable && !isTerminalProcessState(node.state))
|
|
@@ -44,8 +44,8 @@ export function liveSteerableLabels(nodes: readonly ProcessNode[], excludeNodeId
|
|
|
44
44
|
/** Refusal message for a steer that could not be queued: states why + preserves the draft + suggests live targets. */
|
|
45
45
|
export function steerRefusalMessage(reason: string, siblingLabels: readonly string[]): string {
|
|
46
46
|
const suggestion = siblingLabels.length > 0
|
|
47
|
-
? ` Draft kept
|
|
48
|
-
: ' Draft kept
|
|
47
|
+
? ` Draft kept: steerable now: ${siblingLabels.slice(0, 3).join(', ')}${siblingLabels.length > 3 ? '…' : ''}.`
|
|
48
|
+
: ' Draft kept: no other agents are currently steerable.';
|
|
49
49
|
return `${reason}.${suggestion}`;
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -55,10 +55,10 @@ export function renderSteerBadgeLine(badge: SteerBadge, width: number, palette:
|
|
|
55
55
|
const tone = steerBadgeTone(badge.status, palette);
|
|
56
56
|
const forTarget = targetLabel ? ` for ${targetLabel}` : '';
|
|
57
57
|
const label = badge.status === 'queued'
|
|
58
|
-
? `steer queued${forTarget}
|
|
58
|
+
? `steer queued${forTarget}: delivers on its next turn (watch the ${glyph} badge)`
|
|
59
59
|
: badge.status === 'consumed'
|
|
60
60
|
? 'steer consumed'
|
|
61
|
-
: `steer dropped
|
|
61
|
+
: `steer dropped: ${badge.note ?? 'the target ended before delivery'}`;
|
|
62
62
|
return buildPanelLine(width, [
|
|
63
63
|
[' ', palette.dim],
|
|
64
64
|
[glyph, tone],
|
|
@@ -75,7 +75,7 @@ export function renderSteerBadgeLine(badge: SteerBadge, width: number, palette:
|
|
|
75
75
|
* its short linger so a tab doesn't accumulate stale indicators.
|
|
76
76
|
*
|
|
77
77
|
* Mutates `tab.steerBadge` in place (same mutable-slot convention as
|
|
78
|
-
* `FleetTab.ledgerEntries
|
|
78
|
+
* `FleetTab.ledgerEntries`, see fleet-panel.ts's ensureLedgerLoaded).
|
|
79
79
|
* Returns true when anything changed, so the caller knows whether to mark
|
|
80
80
|
* itself dirty.
|
|
81
81
|
*/
|
|
@@ -102,7 +102,7 @@ export function reconcileSteerBadges(
|
|
|
102
102
|
changed = true;
|
|
103
103
|
} else if (badge.queuedAt !== undefined && now - badge.queuedAt > STEER_TTL_MS) {
|
|
104
104
|
// Long-tool-call case: the target is still healthy and non-terminal,
|
|
105
|
-
// but the underlying steer message's own TTL (the SDK's MessageBus
|
|
105
|
+
// but the underlying steer message's own TTL (the SDK's MessageBus,
|
|
106
106
|
// see registry.js's steer(), which stamps every steer with
|
|
107
107
|
// STEER_TTL_MS) has lapsed without a COMMUNICATION_CONSUMED ever
|
|
108
108
|
// arriving. The SDK gives no explicit expiry signal, so without this
|
package/src/panels/fleet-stop.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// ---------------------------------------------------------------------------
|
|
2
2
|
// fleet-stop.ts
|
|
3
3
|
//
|
|
4
|
-
// d1
|
|
4
|
+
// d1, the "stopping…" write-window overlay, split out of fleet-panel.ts
|
|
5
5
|
// to keep that file under the architecture 800-line gate (same rationale as
|
|
6
6
|
// fleet-steer.ts). FleetPanel owns nothing here beyond a FleetStopTracker
|
|
7
7
|
// instance; all the state->display logic lives in these pure helpers.
|
|
@@ -26,7 +26,7 @@ export const BLOCKED_GLYPH = '⚑';
|
|
|
26
26
|
/**
|
|
27
27
|
* Tracks node ids the operator just asked to stop (kill/interrupt/pause) mapped
|
|
28
28
|
* to the keypress time. While an id is present AND within STOP_SETTLE_MS its row
|
|
29
|
-
* renders a display-only 'stopping…' instead of the raw state
|
|
29
|
+
* renders a display-only 'stopping…' instead of the raw state, so the tree
|
|
30
30
|
* never claims the past-tense 'killed'/'interrupted' during the brief write
|
|
31
31
|
* window between the keypress and the state actually flipping. After the settle
|
|
32
32
|
* window the TRUE state is ALWAYS shown, so a genuinely stuck kill is never
|
|
@@ -90,7 +90,7 @@ export interface FleetPauseDeps {
|
|
|
90
90
|
* resumable node is resumed (interrupt's inverse); a live pausable node is
|
|
91
91
|
* paused via the registry's interrupt() (its disable path). Honest refusal for
|
|
92
92
|
* non-resumable/non-pausable kinds. Returns true when the key is consumed,
|
|
93
|
-
* false to fall through (terminal, non-paused node
|
|
93
|
+
* false to fall through (terminal, non-paused node, nothing to toggle).
|
|
94
94
|
*/
|
|
95
95
|
export function toggleFleetPause(node: ProcessNode, deps: FleetPauseDeps): boolean {
|
|
96
96
|
if (node.state === 'paused') {
|
|
@@ -141,7 +141,7 @@ export function buildFleetTreeHints(
|
|
|
141
141
|
];
|
|
142
142
|
// Jump-to-blocked is offered whenever something is waiting on the operator,
|
|
143
143
|
// in either view (the blocked nodes live in the active fleet, and the jump
|
|
144
|
-
// switches back to it)
|
|
144
|
+
// switches back to it), so it is placed before the view-specific branch.
|
|
145
145
|
if (blockedCount > 0) hints.push({ keys: 'b', label: `blocked (${blockedCount})` });
|
|
146
146
|
if (viewMode === 'archived') {
|
|
147
147
|
// Archive view: restore + return to the live fleet; nothing here is live,
|
|
@@ -194,7 +194,7 @@ export function countDescendantStats(rows: readonly FleetTreeRow[], nodeId: stri
|
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
/**
|
|
197
|
-
* Build the confirm-overlay arm options for a cascade Kill of one node
|
|
197
|
+
* Build the confirm-overlay arm options for a cascade Kill of one node, the
|
|
198
198
|
* label carries the descendant count so the operator sees what a confirm takes
|
|
199
199
|
* down. Extracted from FleetPanel to keep that file under the 800-line cap.
|
|
200
200
|
*/
|
package/src/panels/fleet-tabs.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
//
|
|
15
15
|
// Attachable kinds: only 'agent' and 'wrfc-chain' carry anything worth
|
|
16
16
|
// attaching to (a transcript for an agent; a live member summary for a
|
|
17
|
-
// chain
|
|
17
|
+
// chain, see fleet-transcript.ts). workflow/trigger/schedule/watcher/
|
|
18
18
|
// background-process/wrfc-subtask nodes have no transcript and are never
|
|
19
19
|
// attachable (FleetPanel shows a status message instead, matching the
|
|
20
20
|
// existing i/K "not supported" convention).
|
|
@@ -34,14 +34,14 @@ export function isAttachableFleetKind(kind: ProcessKind): kind is FleetAttachabl
|
|
|
34
34
|
/**
|
|
35
35
|
* Lifecycle of a queued steer message, tracked
|
|
36
36
|
* per-tab. `queued` means `ProcessRegistry.steer()` accepted the message
|
|
37
|
-
* onto the target's inbox, NOT that the agent has seen it
|
|
37
|
+
* onto the target's inbox, NOT that the agent has seen it, that is the
|
|
38
38
|
* later, honest `consumed` transition (a `COMMUNICATION_CONSUMED` runtime-bus
|
|
39
39
|
* event matching this badge's `messageId`). `dropped` is a TUI-side
|
|
40
40
|
* inference: the SDK emits no "expired"/"cancelled" signal for a queued
|
|
41
41
|
* steer, so if the target node goes terminal (done/failed/killed/
|
|
42
42
|
* interrupted) while the badge is still `queued`, FleetPanel resolves it to
|
|
43
43
|
* `dropped` itself rather than leaving the badge hanging forever (see
|
|
44
|
-
* fleet-panel.ts reconcileSteerBadges
|
|
44
|
+
* fleet-panel.ts reconcileSteerBadges, cross-WO note: the SDK engineer
|
|
45
45
|
* confirmed no dropped signal exists).
|
|
46
46
|
*/
|
|
47
47
|
export type SteerBadgeStatus = 'queued' | 'consumed' | 'dropped';
|
|
@@ -50,19 +50,19 @@ export type SteerBadgeStatus = 'queued' | 'consumed' | 'dropped';
|
|
|
50
50
|
export interface SteerBadge {
|
|
51
51
|
readonly messageId: string;
|
|
52
52
|
readonly status: SteerBadgeStatus;
|
|
53
|
-
/** Present for 'dropped'
|
|
53
|
+
/** Present for 'dropped', a one-line honest explanation shown in the tab. */
|
|
54
54
|
readonly note?: string;
|
|
55
|
-
/** epoch ms when status left 'queued' (consumed or dropped)
|
|
55
|
+
/** epoch ms when status left 'queued' (consumed or dropped), drives FleetPanel's linger-then-clear tick. */
|
|
56
56
|
readonly resolvedAt?: number;
|
|
57
57
|
/**
|
|
58
58
|
* epoch ms when status entered 'queued' (set once, at submit time). Drives
|
|
59
59
|
* fleet-steer.ts's reconcileSteerBadges TTL-expiry fallback: the SDK's
|
|
60
60
|
* MessageBus attaches its own STEER_TTL_MS to the underlying steer message
|
|
61
61
|
* (see registry.js's steer()) but never tells the TUI when that TTL lapses
|
|
62
|
-
* without delivery
|
|
62
|
+
* without delivery, the "agent stays healthy/non-terminal through one
|
|
63
63
|
* very long tool call, and the steer simply expires unseen in the bus"
|
|
64
64
|
* case. Without this, that badge would show 'queued' forever. Optional
|
|
65
|
-
* because older/hand-built badges (tests, pre-fix data) may not carry it
|
|
65
|
+
* because older/hand-built badges (tests, pre-fix data) may not carry it,
|
|
66
66
|
* absence just means "no TTL-expiry inference possible for this badge",
|
|
67
67
|
* not an error.
|
|
68
68
|
*/
|
|
@@ -73,7 +73,7 @@ export interface SteerBadge {
|
|
|
73
73
|
* Append one character of steer-composer input to a draft, normalizing a
|
|
74
74
|
* pasted multi-line block's line breaks (terminals transmit bracketed-paste
|
|
75
75
|
* newlines as literal `\r`/`\n` characters delivered one at a time through
|
|
76
|
-
* the same per-char burst pipeline as ordinary typing
|
|
76
|
+
* the same per-char burst pipeline as ordinary typing, see
|
|
77
77
|
* handler-feed-routes.ts's isCapturingTextBurst contract) to a single
|
|
78
78
|
* collapsed space instead of either corrupting the one-line field with a
|
|
79
79
|
* raw control character or silently dropping the content. Mirrors how a
|
|
@@ -89,10 +89,10 @@ export function appendSteerText(draft: string, ch: string): string {
|
|
|
89
89
|
|
|
90
90
|
/**
|
|
91
91
|
* One attached session tab. `agentId` is the SDK attach handle for
|
|
92
|
-
* `AgentManager.getConversationSnapshot(agentId)
|
|
92
|
+
* `AgentManager.getConversationSnapshot(agentId)`, populated only for
|
|
93
93
|
* 'agent' tabs (agent.ts sets ProcessNode.id = record.id, so node.id IS the
|
|
94
94
|
* agentId). 'wrfc-chain' tabs render a live member-summary instead of a
|
|
95
|
-
* transcript (a chain has no single conversation of its own
|
|
95
|
+
* transcript (a chain has no single conversation of its own, see
|
|
96
96
|
* fleet-transcript.ts renderFleetChainSummary) and carry an empty agentId,
|
|
97
97
|
* unused.
|
|
98
98
|
*
|
|
@@ -112,7 +112,7 @@ export interface FleetTab {
|
|
|
112
112
|
* Cached parsed ledger fallback for a terminal agent whose conversation
|
|
113
113
|
* snapshot has been evicted from the SDK's retention ring (the degraded
|
|
114
114
|
* fallback path). `null` = not yet loaded/attempted; `[]` = loaded and
|
|
115
|
-
* empty (or the load failed)
|
|
115
|
+
* empty (or the load failed), both render the same honest "no transcript"
|
|
116
116
|
* state once loaded is true.
|
|
117
117
|
*/
|
|
118
118
|
ledgerEntries: Record<string, unknown>[] | null;
|
|
@@ -122,7 +122,7 @@ export interface FleetTab {
|
|
|
122
122
|
* when not composing. Mirrors git-panel.ts's `commitMessage` mutable-slot
|
|
123
123
|
* convention (FleetPanel.isCapturingTextBurst() gates on this being
|
|
124
124
|
* non-null so a burst/paste lands here char-by-char, never as tree/tab
|
|
125
|
-
* hotkeys
|
|
125
|
+
* hotkeys, see FleetPanel.handleSteerInput).
|
|
126
126
|
*/
|
|
127
127
|
steerDraft: string | null;
|
|
128
128
|
/** This tab's most recent steer message's lifecycle, or null. */
|
|
@@ -172,7 +172,7 @@ export function activeFleetTab(state: FleetTabsState): FleetTab | null {
|
|
|
172
172
|
/**
|
|
173
173
|
* Attach a node as a tab (Enter on an attachable tree row). Re-focuses an
|
|
174
174
|
* already-open tab for the same node instead of creating a duplicate.
|
|
175
|
-
* Returns `state` unchanged if `node.kind` is not attachable
|
|
175
|
+
* Returns `state` unchanged if `node.kind` is not attachable, callers
|
|
176
176
|
* (FleetPanel) are expected to guard with `isAttachableFleetKind` first and
|
|
177
177
|
* report a status message rather than silently doing nothing; this
|
|
178
178
|
* function's own no-op fallback is defense in depth.
|
|
@@ -222,7 +222,7 @@ export function switchFleetTab(state: FleetTabsState, activeTabIndex: number): F
|
|
|
222
222
|
return { tabs: state.tabs, activeTabIndex };
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
/** Move focus to the next/previous tab in the strip (wrapping is deliberately NOT applied
|
|
225
|
+
/** Move focus to the next/previous tab in the strip (wrapping is deliberately NOT applied, clamps at the ends). */
|
|
226
226
|
export function stepFleetTab(state: FleetTabsState, direction: 1 | -1): FleetTabsState {
|
|
227
227
|
const next = state.activeTabIndex + direction;
|
|
228
228
|
return switchFleetTab(state, Math.max(0, Math.min(state.tabs.length, next)));
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
//
|
|
4
4
|
// Renders the content of an attached FleetPanel
|
|
5
5
|
// session tab. Three sources, chosen by what the SDK can actually provide
|
|
6
|
-
// (see the design brief's "central reality check"
|
|
6
|
+
// (see the design brief's "central reality check", a full-fidelity live
|
|
7
7
|
// transcript needs a ConversationMessageSnapshot[] history source, which
|
|
8
8
|
// only exists for a RUNNING agent or a just-completed one still inside the
|
|
9
9
|
// SDK's bounded retention ring):
|
|
10
10
|
//
|
|
11
|
-
// - 'live'/'frozen'
|
|
11
|
+
// - 'live'/'frozen' , a non-empty ConversationMessageSnapshot[] from
|
|
12
12
|
// AgentManager.getConversationSnapshot(agentId), rendered through the
|
|
13
13
|
// EXACT SAME conversation-rendering machinery the main session surface
|
|
14
14
|
// uses (MessageLineCache -> conversation-rendering.ts render functions),
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
// user would see in their own session. 'live' while the agent is still
|
|
17
17
|
// running, 'frozen' once it has completed but the snapshot has not yet
|
|
18
18
|
// been evicted from the retention ring.
|
|
19
|
-
// - 'unavailable'
|
|
20
|
-
// (evicted past the retention bound, or an agent kind
|
|
21
|
-
// owner
|
|
19
|
+
// - 'unavailable' , a terminal agent whose snapshot came back empty
|
|
20
|
+
// (evicted past the retention bound, or an agent kind, e.g. the WRFC
|
|
21
|
+
// owner, that never registered a live conversation source at all).
|
|
22
22
|
// FleetPanel degrades to the on-disk event ledger (renderFleetLedgerFallback)
|
|
23
23
|
// for this case; this module never fabricates transcript content.
|
|
24
24
|
//
|
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
} from './fleet-read-model.ts';
|
|
46
46
|
|
|
47
47
|
/** Duplicated from fleet-panel.ts's private helper (same tiny mapping) rather than
|
|
48
|
-
* cross-importing
|
|
48
|
+
* cross-importing, fleet-panel.ts imports THIS module to render tab content, so
|
|
49
49
|
* importing back would form a cycle. See fleet-panel.ts's own toneColor for the
|
|
50
50
|
* canonical copy; keep both in sync if the tone set ever changes. */
|
|
51
51
|
function toneColor(tone: FleetStateTone, palette: PanelPalette): string {
|
|
@@ -70,17 +70,17 @@ export interface FleetTranscriptRender {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
/**
|
|
73
|
-
* (design point 4)
|
|
73
|
+
* (design point 4), a 'frozen' transcript is a static capture of a
|
|
74
74
|
* completed process, not something that will change on the next render. The
|
|
75
75
|
* distinction matters because this wave also introduced kill/interrupt
|
|
76
76
|
* display bugs (elapsed/usage briefly climbing after a terminal state
|
|
77
|
-
* shows)
|
|
77
|
+
* shows), a done-section tab that looked indistinguishable from a live one
|
|
78
78
|
* would misleadingly suggest the underlying agent is still doing something.
|
|
79
79
|
* Shown once at the top of a 'frozen' tab's content; 'live' tabs never show
|
|
80
80
|
* it, and 'unavailable' tabs get the ledger fallback's own notice instead
|
|
81
81
|
* (renderFleetLedgerFallback below) rather than this one.
|
|
82
82
|
*/
|
|
83
|
-
const FROZEN_TRANSCRIPT_NOTICE = 'Read-only
|
|
83
|
+
const FROZEN_TRANSCRIPT_NOTICE = 'Read-only: this agent finished; not a live view.';
|
|
84
84
|
|
|
85
85
|
function renderFrozenTranscriptNotice(width: number): Line[] {
|
|
86
86
|
const palette = DEFAULT_PANEL_PALETTE;
|
|
@@ -93,15 +93,15 @@ function renderFrozenTranscriptNotice(width: number): Line[] {
|
|
|
93
93
|
|
|
94
94
|
/**
|
|
95
95
|
* Render an agent tab's transcript from a `ConversationMessageSnapshot[]`
|
|
96
|
-
* already fetched by the caller (this module does no I/O of its own
|
|
96
|
+
* already fetched by the caller (this module does no I/O of its own, it is
|
|
97
97
|
* a pure renderer, same convention as fleet-read-model.ts).
|
|
98
98
|
*
|
|
99
|
-
* `isTerminal` distinguishes 'live' (the agent is still running
|
|
99
|
+
* `isTerminal` distinguishes 'live' (the agent is still running, the
|
|
100
100
|
* snapshot came from the SDK's live source, so it will change on the next
|
|
101
|
-
* render) from 'frozen' (the agent finished
|
|
101
|
+
* render) from 'frozen' (the agent finished, the snapshot is a static final
|
|
102
102
|
* capture; caller is showing a completed conversation, not a live one).
|
|
103
103
|
* An empty snapshot on a terminal agent means the source was never
|
|
104
|
-
* registered or has been evicted
|
|
104
|
+
* registered or has been evicted, the caller falls back to
|
|
105
105
|
* `renderFleetLedgerFallback`; an empty snapshot on a non-terminal agent
|
|
106
106
|
* (e.g. the SDK hasn't sent a turn yet) legitimately means "no messages yet".
|
|
107
107
|
*/
|
|
@@ -124,7 +124,7 @@ export function renderFleetAgentTranscript(
|
|
|
124
124
|
addLines: (lines: Line[]): void => { historyLines.push(...lines); },
|
|
125
125
|
getLineCount: (): number => historyLines.length,
|
|
126
126
|
};
|
|
127
|
-
// Scratch block/collapse/error registries
|
|
127
|
+
// Scratch block/collapse/error registries, collapse-toggle and block-copy
|
|
128
128
|
// interactions are out of scope for this tab (a later item, per the brief's
|
|
129
129
|
// "transcript browse" follow-on); this render is a read-only tail view.
|
|
130
130
|
const context: ConversationRenderContext = {
|
|
@@ -147,7 +147,7 @@ export function renderFleetAgentTranscript(
|
|
|
147
147
|
// No `&& budgetHeight > 0` guard: when the notice alone already consumes
|
|
148
148
|
// the whole height budget, `historyLines.slice(historyLines.length - 0)`
|
|
149
149
|
// correctly yields an empty tail (nothing fits), rather than falling
|
|
150
|
-
// through to the full, un-sliced history
|
|
150
|
+
// through to the full, un-sliced history, which the caller would then
|
|
151
151
|
// head-clip, silently swapping in the OLDEST lines instead of the
|
|
152
152
|
// most-recent tail this view promises.
|
|
153
153
|
const visible = historyLines.length > budgetHeight
|
|
@@ -157,7 +157,7 @@ export function renderFleetAgentTranscript(
|
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
// ---------------------------------------------------------------------------
|
|
160
|
-
// Chain summary
|
|
160
|
+
// Chain summary, 'wrfc-chain' tabs have no single conversation
|
|
161
161
|
// ---------------------------------------------------------------------------
|
|
162
162
|
|
|
163
163
|
/**
|
|
@@ -177,7 +177,7 @@ export function renderFleetChainSummary(
|
|
|
177
177
|
const C = DEFAULT_PANEL_PALETTE;
|
|
178
178
|
if (memberRows.length === 0) {
|
|
179
179
|
const message = chainDoneOrAbsent
|
|
180
|
-
? ' chain completed
|
|
180
|
+
? ' chain completed: members no longer tracked'
|
|
181
181
|
: ' (no member agents yet)';
|
|
182
182
|
return [buildPanelLine(width, [[message, C.dim]])];
|
|
183
183
|
}
|
|
@@ -196,13 +196,13 @@ export function renderFleetChainSummary(
|
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
// ---------------------------------------------------------------------------
|
|
199
|
-
// Ledger fallback
|
|
199
|
+
// Ledger fallback, degraded activity view for a terminal agent whose
|
|
200
200
|
// full-fidelity snapshot is unavailable (an honest fallback)
|
|
201
201
|
// ---------------------------------------------------------------------------
|
|
202
202
|
|
|
203
203
|
/**
|
|
204
204
|
* Parse an agent's `<agentId>.jsonl` event ledger. Tolerant of malformed
|
|
205
|
-
* lines (skipped, not thrown)
|
|
205
|
+
* lines (skipped, not thrown), matches agent-detail-modal.ts's existing
|
|
206
206
|
* JSONL-reading convention for the same file shape.
|
|
207
207
|
*/
|
|
208
208
|
export function parseAgentLedger(raw: string): Record<string, unknown>[] {
|
|
@@ -231,7 +231,7 @@ function renderLedgerEntry(width: number, entry: Record<string, unknown>, palett
|
|
|
231
231
|
const model = typeof entry['model'] === 'string' ? entry['model'] : 'unknown model';
|
|
232
232
|
const provider = typeof entry['provider'] === 'string' ? entry['provider'] : 'unknown';
|
|
233
233
|
return renderConversationEventLine(width, { marker: '●', markerFg: palette.dim, label: 'session', labelFg: palette.dim }, [
|
|
234
|
-
{ text: `started
|
|
234
|
+
{ text: `started: ${model} (${provider})`, fg: palette.value },
|
|
235
235
|
]);
|
|
236
236
|
}
|
|
237
237
|
case 'session_config': {
|
|
@@ -258,13 +258,13 @@ function renderLedgerEntry(width: number, entry: Record<string, unknown>, palett
|
|
|
258
258
|
const success = entry['success'] !== false;
|
|
259
259
|
const bad = palette.bad ?? DEFAULT_PANEL_PALETTE.bad;
|
|
260
260
|
// the writer already truncates this to 500 chars (session.ts's
|
|
261
|
-
// resultPreview field)
|
|
261
|
+
// resultPreview field), passed through verbatim (collapsed to one
|
|
262
262
|
// line), never re-summarized or fabricated, then tail-truncated again
|
|
263
263
|
// to fit the row.
|
|
264
264
|
const rawPreview = typeof entry['resultPreview'] === 'string' ? entry['resultPreview'] : '';
|
|
265
265
|
const preview = rawPreview.replace(/\s+/g, ' ').trim();
|
|
266
266
|
const label = `${toolName}${success ? '' : ' (failed)'}`;
|
|
267
|
-
const text = preview ? `${label}
|
|
267
|
+
const text = preview ? `${label}: ${preview}` : label;
|
|
268
268
|
return renderConversationEventLine(width, {
|
|
269
269
|
marker: success ? '●' : '✗',
|
|
270
270
|
markerFg: success ? palette.info : bad,
|
|
@@ -288,7 +288,7 @@ function renderLedgerEntry(width: number, entry: Record<string, unknown>, palett
|
|
|
288
288
|
// records, appended to this same JSONL ledger as
|
|
289
289
|
// `{type:'knowledge_injection', turn, ...record}` (orchestrator-runner.ts).
|
|
290
290
|
// Without this case these fell through to the generic 'event' default
|
|
291
|
-
// below (just the bare type name)
|
|
291
|
+
// below (just the bare type name), this renders the honest outcome
|
|
292
292
|
// (what was injected, or why nothing was) instead.
|
|
293
293
|
case 'knowledge_injection': {
|
|
294
294
|
const turn = typeof entry['turn'] === 'number' ? entry['turn'] : '?';
|
|
@@ -300,7 +300,7 @@ function renderLedgerEntry(width: number, entry: Record<string, unknown>, palett
|
|
|
300
300
|
? entry['reason']
|
|
301
301
|
: 'nothing cleared the relevance floor';
|
|
302
302
|
return renderConversationEventLine(width, { marker: '◇', markerFg: palette.dim, label: 'knowledge', labelFg: palette.dim }, [
|
|
303
|
-
{ text: `turn ${turn} · nothing injected
|
|
303
|
+
{ text: `turn ${turn} · nothing injected; ${reason}${backendTag}`, fg: palette.dim },
|
|
304
304
|
]);
|
|
305
305
|
}
|
|
306
306
|
return renderConversationEventLine(width, { marker: '◇', markerFg: palette.info, label: 'knowledge', labelFg: palette.info }, [
|
|
@@ -318,7 +318,7 @@ function renderLedgerEntry(width: number, entry: Record<string, unknown>, palett
|
|
|
318
318
|
* Degraded activity view for a terminal agent whose full-fidelity
|
|
319
319
|
* conversation snapshot is unavailable (evicted, or never registered).
|
|
320
320
|
* Explicitly framed as an activity log, never presented as a transcript
|
|
321
|
-
* replay (the ledger is a truncated event record
|
|
321
|
+
* replay (the ledger is a truncated event record, see session.ts /
|
|
322
322
|
* orchestrator-runner.ts: tool args/results are sliced to 500 chars and
|
|
323
323
|
* assistant response TEXT is never written at all, only its length).
|
|
324
324
|
*
|
|
@@ -336,7 +336,7 @@ export function renderFleetLedgerFallback(
|
|
|
336
336
|
): Line[] {
|
|
337
337
|
const palette = DEFAULT_PANEL_PALETTE;
|
|
338
338
|
const notice = renderConversationNotice(
|
|
339
|
-
'Read-only. Full transcript unavailable for this agent
|
|
339
|
+
'Read-only. Full transcript unavailable for this agent; showing its activity log instead.',
|
|
340
340
|
width,
|
|
341
341
|
{ accent: palette.warn, text: palette.dim, dim: true },
|
|
342
342
|
);
|
package/src/panels/git-panel.ts
CHANGED
|
@@ -57,7 +57,7 @@ type ViewItem =
|
|
|
57
57
|
| { kind: 'commit'; entry: CommitEntry }
|
|
58
58
|
| { kind: 'empty'; label: string };
|
|
59
59
|
|
|
60
|
-
/** Subject carried by the panel's single ConfirmState
|
|
60
|
+
/** Subject carried by the panel's single ConfirmState, either a repo init or a commit. */
|
|
61
61
|
type GitConfirmSubject =
|
|
62
62
|
| { kind: 'init' }
|
|
63
63
|
| { kind: 'commit'; message: string };
|
|
@@ -119,7 +119,7 @@ export class GitPanel extends BasePanel {
|
|
|
119
119
|
/** True when the last refresh failed because `workingDirectory` isn't a git repo. */
|
|
120
120
|
private notGitRepo = false;
|
|
121
121
|
|
|
122
|
-
/** Single pending confirm
|
|
122
|
+
/** Single pending confirm, either "init this repo" or "commit with this message". */
|
|
123
123
|
private confirm: ConfirmState<GitConfirmSubject> | null = null;
|
|
124
124
|
|
|
125
125
|
/** Non-null while composing a commit message; null means the compose UI is closed. */
|
|
@@ -211,12 +211,12 @@ export class GitPanel extends BasePanel {
|
|
|
211
211
|
this.error = null;
|
|
212
212
|
this.notGitRepo = false;
|
|
213
213
|
this.rebuildItems();
|
|
214
|
-
// Do not clear expandedDiff during auto-refresh
|
|
214
|
+
// Do not clear expandedDiff during auto-refresh, only clear on explicit user action
|
|
215
215
|
this._markDirtyAndRender();
|
|
216
216
|
} catch (err) {
|
|
217
217
|
const msg = summarizeError(err);
|
|
218
218
|
if (/not a git\b/i.test(msg)) {
|
|
219
|
-
// I4: no more auto `git init` side effect
|
|
219
|
+
// I4: no more auto `git init` side effect, surface the state and let
|
|
220
220
|
// the user explicitly confirm initialisation with 'i'.
|
|
221
221
|
this.notGitRepo = true;
|
|
222
222
|
this.error = 'Not a git repository here. Press i to initialize one (explicit confirm).';
|
|
@@ -276,7 +276,7 @@ export class GitPanel extends BasePanel {
|
|
|
276
276
|
|
|
277
277
|
// Input handling
|
|
278
278
|
|
|
279
|
-
/** Commit-message entry wants every char of a burst delivered one at a time
|
|
279
|
+
/** Commit-message entry wants every char of a burst delivered one at a time, see Panel.isCapturingTextBurst. */
|
|
280
280
|
isCapturingTextBurst(): boolean {
|
|
281
281
|
return this.commitMessage !== null;
|
|
282
282
|
}
|
|
@@ -346,7 +346,7 @@ export class GitPanel extends BasePanel {
|
|
|
346
346
|
return true;
|
|
347
347
|
}
|
|
348
348
|
case 'i': {
|
|
349
|
-
// Only meaningful when no repo is loaded
|
|
349
|
+
// Only meaningful when no repo is loaded, otherwise leave the key
|
|
350
350
|
// unconsumed instead of absorbing it as a silent no-op.
|
|
351
351
|
if (!this.notGitRepo) return false;
|
|
352
352
|
this.confirm = { subject: { kind: 'init' }, label: this.workingDirectory, verb: 'Init' };
|
|
@@ -437,7 +437,7 @@ export class GitPanel extends BasePanel {
|
|
|
437
437
|
}
|
|
438
438
|
|
|
439
439
|
if (item.kind === 'commit') {
|
|
440
|
-
// Root commits have no parent (`<hash>^` is invalid)
|
|
440
|
+
// Root commits have no parent (`<hash>^` is invalid), the catch below
|
|
441
441
|
// surfaces that instead of pretending a diff exists.
|
|
442
442
|
const before = `${item.entry.hash}^`;
|
|
443
443
|
const after = item.entry.hash;
|
|
@@ -543,7 +543,7 @@ export class GitPanel extends BasePanel {
|
|
|
543
543
|
buildKeyboardHints(width, [{ keys: 'Enter', label: 'review & confirm' }, { keys: 'Esc', label: 'cancel' }], DEFAULT_PANEL_PALETTE),
|
|
544
544
|
];
|
|
545
545
|
return buildPanelWorkspace(width, height, {
|
|
546
|
-
title: ' Git
|
|
546
|
+
title: ' Git: Commit',
|
|
547
547
|
sections: [{ title: 'Message', lines: [inputLine] }],
|
|
548
548
|
footerLines,
|
|
549
549
|
palette: DEFAULT_PANEL_PALETTE,
|