@pellux/goodvibes-tui 2.0.14 → 2.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.goodvibes/GOODVIBES.md +1 -1
- package/.goodvibes/agents/reviewer.md +8 -8
- package/.goodvibes/skills/add-provider/SKILL.md +22 -22
- package/CHANGELOG.md +35 -0
- package/README.md +40 -29
- package/docs/README.md +1 -1
- package/docs/foundation-artifacts/README.md +5 -5
- package/docs/foundation-artifacts/operator-contract.json +123 -123
- package/package.json +12 -10
- package/scripts/postinstall.js +3 -3
- package/src/audio/activation-sound.ts +7 -7
- package/src/audio/capture.ts +7 -7
- package/src/audio/onnxruntime-assets.d.ts +1 -1
- package/src/audio/player.ts +4 -4
- package/src/audio/spoken-turn-wiring.ts +4 -4
- package/src/audio/voice-capture-wiring.ts +5 -5
- package/src/audio/voice-input-session.ts +3 -3
- package/src/audio/wake-inference.ts +13 -8
- package/src/audio/wake-runtime.ts +10 -10
- package/src/cli/completions/generate.ts +2 -2
- package/src/cli/doctor.ts +13 -13
- package/src/cli/ensure-goodvibes-gitignore.ts +3 -3
- package/src/cli/entrypoint.ts +3 -3
- package/src/cli/help.ts +6 -6
- package/src/cli/hooks-command.ts +4 -4
- package/src/cli/hooks-report.ts +4 -4
- package/src/cli/launch-auto-update.ts +17 -17
- package/src/cli/management-commands.ts +8 -8
- package/src/cli/management-utils.ts +3 -3
- package/src/cli/management.ts +1 -1
- package/src/cli/plugin-bundles-command.ts +10 -10
- package/src/cli/plugin-command.ts +9 -9
- package/src/cli/service-posture.ts +1 -1
- package/src/cli/status.ts +10 -10
- package/src/cli/surface-command.ts +4 -4
- package/src/cli/tui-startup.ts +23 -23
- package/src/config/run-daemon-config-migration.ts +3 -3
- package/src/config/secret-config.ts +10 -10
- package/src/config/surface.ts +1 -1
- package/src/config/tui-extension-settings.ts +8 -8
- package/src/core/active-model-identity.ts +7 -7
- package/src/core/approval-alert.ts +5 -5
- package/src/core/bookmark-navigation.ts +3 -3
- package/src/core/budget-breach-notifier.ts +6 -6
- package/src/core/compaction-receipt.ts +8 -8
- package/src/core/composer-state.ts +2 -2
- package/src/core/context-usage.ts +1 -1
- package/src/core/conversation-compaction-render.ts +3 -3
- package/src/core/conversation-event-navigation.ts +2 -2
- package/src/core/conversation-fold.ts +9 -9
- package/src/core/conversation-line-cache.ts +14 -14
- package/src/core/conversation-render-context.ts +6 -6
- package/src/core/conversation-rendering.ts +27 -30
- package/src/core/conversation-search-expansion.ts +6 -6
- package/src/core/conversation-splash-state.ts +3 -3
- package/src/core/conversation-turn-structure.ts +13 -13
- package/src/core/conversation-types.ts +3 -3
- package/src/core/conversation-user-receipts.ts +5 -5
- package/src/core/conversation.ts +17 -17
- package/src/core/format-user-error.ts +5 -5
- package/src/core/long-task-notifier.ts +9 -9
- package/src/core/memory-diagnostics-gateway.ts +8 -8
- package/src/core/memory-provenance.ts +5 -5
- package/src/core/model-routing-chip.ts +3 -3
- package/src/core/pairing-tailscale-gateway.ts +3 -3
- package/src/core/permission-mode.ts +5 -5
- package/src/core/power-chip-source.ts +3 -3
- package/src/core/power-status.ts +8 -8
- package/src/core/rewind-receipt.ts +6 -6
- package/src/core/session-resume-core.ts +8 -8
- package/src/core/stream-event-wiring.ts +36 -36
- package/src/core/stream-stall-watchdog.ts +4 -4
- package/src/core/system-message-noise.ts +7 -7
- package/src/core/system-message-router.ts +10 -10
- package/src/core/terminal-notifier.ts +5 -5
- package/src/core/turn-budget-outcome.ts +5 -5
- package/src/core/turn-cancellation.ts +3 -3
- package/src/core/turn-event-wiring.ts +16 -16
- package/src/core/voice-capture-status.ts +2 -2
- package/src/core/voice-provision-gateway.ts +12 -12
- package/src/core/voice-provision-status.ts +19 -19
- package/src/core/voice-stt-gateway.ts +6 -6
- package/src/core/wake-provision-runner.ts +7 -7
- package/src/core/wake-provision-status.ts +17 -17
- package/src/core/workstream-notification.ts +8 -8
- package/src/export/gist-uploader.ts +7 -7
- package/src/input/autocomplete.ts +3 -3
- package/src/input/bookmark-modal.ts +1 -1
- package/src/input/command-args-hint.ts +2 -2
- package/src/input/command-reference.ts +9 -9
- package/src/input/command-registry.ts +32 -32
- package/src/input/commands/acp-runtime.ts +6 -6
- package/src/input/commands/calendar-runtime.ts +9 -9
- package/src/input/commands/channel-pairing.ts +11 -11
- package/src/input/commands/channel-runtime.ts +1 -1
- package/src/input/commands/checkin-runtime.ts +4 -4
- package/src/input/commands/checkpoint-runtime.ts +4 -4
- package/src/input/commands/ci-runtime.ts +4 -4
- package/src/input/commands/cluster-runtime.ts +3 -3
- package/src/input/commands/codebase-runtime.ts +16 -16
- package/src/input/commands/config.ts +6 -6
- package/src/input/commands/connection-status.ts +12 -12
- package/src/input/commands/context-window.ts +2 -2
- package/src/input/commands/cost-attribution-format.ts +4 -4
- package/src/input/commands/cost-runtime.ts +2 -2
- package/src/input/commands/devices-runtime.ts +7 -7
- package/src/input/commands/diff-runtime.ts +2 -2
- package/src/input/commands/editor-runtime.ts +1 -1
- package/src/input/commands/eval.ts +4 -4
- package/src/input/commands/experience-runtime.ts +1 -1
- package/src/input/commands/git-runtime.ts +3 -3
- package/src/input/commands/graph-runtime.ts +3 -3
- package/src/input/commands/guidance-runtime.ts +1 -1
- package/src/input/commands/health-metrics-format.ts +2 -2
- package/src/input/commands/health-runtime.ts +8 -8
- package/src/input/commands/hosted-runtime.ts +13 -13
- package/src/input/commands/image-runtime.ts +6 -6
- package/src/input/commands/intelligence-runtime.ts +2 -2
- package/src/input/commands/local-auth-runtime.ts +3 -3
- package/src/input/commands/local-provider-runtime.ts +3 -3
- package/src/input/commands/local-runtime.ts +7 -7
- package/src/input/commands/mail-runtime.ts +9 -9
- package/src/input/commands/mcp-runtime.ts +1 -1
- package/src/input/commands/memory.ts +13 -13
- package/src/input/commands/notify-runtime.ts +1 -1
- package/src/input/commands/operator-panel-runtime.ts +8 -8
- package/src/input/commands/operator-rpc.ts +3 -3
- package/src/input/commands/operator-runtime.ts +3 -3
- package/src/input/commands/palette-runtime.ts +1 -1
- package/src/input/commands/payment-card-intake.ts +17 -17
- package/src/input/commands/permissions-provenance.ts +7 -7
- package/src/input/commands/permissions-runtime.ts +1 -1
- package/src/input/commands/planning-runtime.ts +9 -9
- package/src/input/commands/platform-services-runtime.ts +2 -2
- package/src/input/commands/policy-dispatch.ts +6 -6
- package/src/input/commands/power-runtime.ts +6 -6
- package/src/input/commands/principals-runtime.ts +3 -3
- package/src/input/commands/product-runtime.ts +3 -3
- package/src/input/commands/profile-render.ts +13 -13
- package/src/input/commands/profile-runtime.ts +13 -13
- package/src/input/commands/profile-types.ts +13 -13
- package/src/input/commands/provider-accounts-runtime.ts +5 -5
- package/src/input/commands/provider.ts +10 -10
- package/src/input/commands/qrcode-runtime.ts +3 -3
- package/src/input/commands/queue-runtime.ts +6 -6
- package/src/input/commands/recall-files-config.ts +4 -4
- package/src/input/commands/recall-files-git.ts +3 -3
- package/src/input/commands/recall-files.ts +12 -12
- package/src/input/commands/recall-query.ts +3 -3
- package/src/input/commands/recall-review.ts +3 -3
- package/src/input/commands/recall-shared.ts +1 -1
- package/src/input/commands/relay-runtime.ts +5 -5
- package/src/input/commands/remote-runtime.ts +3 -3
- package/src/input/commands/review-runtime.ts +8 -8
- package/src/input/commands/rewind-runtime.ts +21 -21
- package/src/input/commands/runtime-services.ts +1 -2
- package/src/input/commands/schedule-nl.ts +2 -2
- package/src/input/commands/schedule-runtime.ts +2 -2
- package/src/input/commands/secret-runtime.ts +3 -3
- package/src/input/commands/session-content.ts +7 -7
- package/src/input/commands/session-picker-filter.ts +3 -3
- package/src/input/commands/session-workflow.ts +10 -10
- package/src/input/commands/session.ts +15 -15
- package/src/input/commands/settings-sync-runtime.ts +2 -2
- package/src/input/commands/share-runtime.ts +4 -4
- package/src/input/commands/shell-core.ts +11 -11
- package/src/input/commands/tasks-runtime.ts +4 -4
- package/src/input/commands/test-runtime.ts +6 -6
- package/src/input/commands/tts-runtime.ts +4 -4
- package/src/input/commands/update-runtime.ts +27 -27
- package/src/input/commands/websearch-runtime.ts +2 -2
- package/src/input/commands/work-plan-runtime.ts +2 -2
- package/src/input/commands/workstream-attempt-dependents.ts +4 -4
- package/src/input/commands/workstream-attempts.ts +16 -16
- package/src/input/commands/workstream-runtime.ts +36 -36
- package/src/input/commands/worktree-runtime.ts +6 -6
- package/src/input/composer-capture.ts +5 -5
- package/src/input/concealed-input.ts +2 -2
- package/src/input/config-modal-types.ts +16 -16
- package/src/input/config-modal.ts +30 -30
- package/src/input/daemon-owned-settings-descriptions.ts +4 -4
- package/src/input/delete-key-policy.ts +1 -1
- package/src/input/exec-env-scrub-config.ts +7 -7
- package/src/input/feature-unit-layout.ts +5 -5
- package/src/input/feed-context-factory.ts +38 -38
- package/src/input/file-picker.ts +1 -1
- package/src/input/handler-command-route.ts +2 -2
- package/src/input/handler-content-actions.ts +8 -8
- package/src/input/handler-feed-routes.ts +13 -13
- package/src/input/handler-feed.ts +31 -31
- package/src/input/handler-interactions.ts +2 -2
- package/src/input/handler-modal-routes.ts +13 -13
- package/src/input/handler-modal-stack.ts +1 -1
- package/src/input/handler-modal-token-routes.ts +1 -1
- package/src/input/handler-onboarding-daemon-adopt.ts +6 -6
- package/src/input/handler-picker-routes.ts +7 -7
- package/src/input/handler-prompt-buffer.ts +1 -1
- package/src/input/handler-shortcuts.ts +12 -12
- package/src/input/handler-types.ts +3 -3
- package/src/input/handler-ui-state.ts +1 -1
- package/src/input/handler.ts +9 -9
- package/src/input/input-history.ts +1 -1
- package/src/input/keybindings.ts +13 -13
- package/src/input/kill-ring.ts +7 -11
- package/src/input/model-picker-filter.ts +3 -3
- package/src/input/model-picker-items.ts +5 -5
- package/src/input/model-picker-types.ts +2 -2
- package/src/input/model-picker.ts +18 -18
- package/src/input/onboarding/onboarding-feature-units.ts +9 -13
- package/src/input/onboarding/onboarding-provider-key-fields.ts +3 -3
- package/src/input/onboarding/onboarding-runtime-status.ts +3 -3
- package/src/input/onboarding/onboarding-wizard-apply.ts +6 -6
- package/src/input/onboarding/onboarding-wizard-cloudflare-step.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-constants.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-external-surfaces.ts +4 -4
- package/src/input/onboarding/onboarding-wizard-network-adopt.ts +6 -6
- package/src/input/onboarding/onboarding-wizard-steps.ts +2 -2
- package/src/input/panel-integration-actions.ts +3 -3
- package/src/input/panel-mouse-geometry.ts +1 -1
- package/src/input/panel-paste-flood-guard.ts +9 -9
- package/src/input/payments-config.ts +15 -15
- package/src/input/profile-picker-modal.ts +1 -1
- package/src/input/provider-key-intake.ts +9 -9
- package/src/input/relay-settings-descriptions.ts +3 -3
- package/src/input/sandbox-exec-config.ts +9 -9
- package/src/input/search.ts +18 -18
- package/src/input/selection-modal-queue.ts +10 -10
- package/src/input/selection-modal.ts +2 -2
- package/src/input/session-picker-modal.ts +7 -7
- package/src/input/settings-modal-activation.ts +1 -1
- package/src/input/settings-modal-adjustment.ts +2 -2
- package/src/input/settings-modal-commit.ts +6 -6
- package/src/input/settings-modal-connections.ts +2 -2
- package/src/input/settings-modal-data.ts +29 -29
- package/src/input/settings-modal-mutations.ts +7 -7
- package/src/input/settings-modal-reset.ts +3 -3
- package/src/input/settings-modal-search.ts +6 -6
- package/src/input/settings-modal-secrets.ts +3 -3
- package/src/input/settings-modal-types.ts +16 -16
- package/src/input/settings-modal.ts +4 -4
- package/src/input/voice-local-settings.ts +3 -3
- package/src/input/worktree-setup-config.ts +8 -8
- package/src/main.ts +15 -15
- package/src/panels/agent-inspector-shared.ts +5 -5
- package/src/panels/base-panel.ts +3 -3
- package/src/panels/builtin/agent.ts +3 -3
- package/src/panels/builtin/development.ts +4 -4
- package/src/panels/builtin/knowledge.ts +1 -1
- package/src/panels/builtin/operations.ts +12 -12
- package/src/panels/builtin/session.ts +8 -8
- package/src/panels/builtin/shared.ts +6 -6
- package/src/panels/builtin-modals.ts +8 -8
- package/src/panels/confirm-state.ts +5 -5
- package/src/panels/cost-tracker-panel.ts +22 -22
- package/src/panels/diff-panel.ts +20 -20
- package/src/panels/diff-review-model.ts +5 -5
- package/src/panels/diff-review-panel.ts +5 -5
- package/src/panels/eval-registry.ts +2 -2
- package/src/panels/expandable-list-panel.ts +5 -5
- package/src/panels/fleet-acts.ts +20 -20
- package/src/panels/fleet-deep-link.ts +5 -5
- package/src/panels/fleet-gateway.ts +12 -12
- package/src/panels/fleet-observed-render.ts +11 -11
- package/src/panels/fleet-panel-format.ts +14 -14
- package/src/panels/fleet-panel-worktree-detail.ts +8 -8
- package/src/panels/fleet-panel.ts +34 -34
- package/src/panels/fleet-read-model.ts +49 -49
- package/src/panels/fleet-spawn.ts +15 -15
- package/src/panels/fleet-steer.ts +7 -7
- package/src/panels/fleet-stop.ts +5 -5
- package/src/panels/fleet-tabs.ts +14 -14
- package/src/panels/fleet-transcript.ts +26 -26
- package/src/panels/git-panel.ts +8 -8
- package/src/panels/hosted-session-feed.ts +13 -13
- package/src/panels/hosted-session-panel.ts +7 -7
- package/src/panels/index.ts +1 -1
- package/src/panels/local-auth-panel.ts +15 -15
- package/src/panels/memory-consolidation-gateway.ts +8 -8
- package/src/panels/modals/devices-modal.ts +8 -8
- package/src/panels/modals/hooks-modal.ts +1 -1
- package/src/panels/modals/keybindings-modal.ts +5 -5
- package/src/panels/modals/knowledge-modal.ts +2 -2
- package/src/panels/modals/local-auth-modal.ts +4 -4
- package/src/panels/modals/marketplace-modal.ts +3 -3
- package/src/panels/modals/memory-modal.ts +19 -19
- package/src/panels/modals/modal-surface-helpers.ts +1 -1
- package/src/panels/modals/modal-theme.ts +3 -3
- package/src/panels/modals/pairing-modal.ts +19 -19
- package/src/panels/modals/planning-modal.ts +4 -4
- package/src/panels/modals/plugins-modal.ts +1 -1
- package/src/panels/modals/policy-modal.ts +4 -4
- package/src/panels/modals/provider-health-modal.ts +1 -1
- package/src/panels/modals/remote-modal.ts +1 -1
- package/src/panels/modals/sandbox-modal.ts +2 -2
- package/src/panels/modals/security-modal.ts +4 -4
- package/src/panels/modals/services-modal.ts +1 -1
- package/src/panels/modals/work-plan-modal.ts +4 -4
- package/src/panels/notifications-feed.ts +6 -6
- package/src/panels/notifications-panel.ts +6 -6
- package/src/panels/panel-confirm-overlay.ts +4 -4
- package/src/panels/panel-manager.ts +13 -13
- package/src/panels/plugins-panel.ts +6 -6
- package/src/panels/polish-core.ts +2 -2
- package/src/panels/polish-tables.ts +2 -2
- package/src/panels/polish.ts +1 -1
- package/src/panels/project-planning-answer-actions.ts +3 -3
- package/src/panels/scrollable-list-panel.ts +15 -15
- package/src/panels/search-focus.ts +1 -1
- package/src/panels/session-maintenance.ts +1 -1
- package/src/panels/skills-panel.ts +3 -3
- package/src/panels/token-budget-panel.ts +11 -11
- package/src/panels/types.ts +14 -14
- package/src/panels/workstream-graph-render.ts +5 -5
- package/src/panels/wrfc-panel-format.ts +1 -1
- package/src/permissions/broker-approval-card.ts +13 -13
- package/src/permissions/hunk-selection.ts +13 -13
- package/src/permissions/prompt.ts +22 -22
- package/src/permissions/sandbox-exec-gate.ts +5 -5
- package/src/providers/provider-classification.ts +1 -1
- package/src/providers/reasoning-effort-surface.ts +12 -12
- package/src/renderer/ansi-sanitize.ts +5 -6
- package/src/renderer/autocomplete-overlay.ts +5 -5
- package/src/renderer/block-actions-overlay.ts +1 -1
- package/src/renderer/bookmark-modal.ts +1 -1
- package/src/renderer/code-block.ts +2 -2
- package/src/renderer/compaction-history-modal.ts +4 -4
- package/src/renderer/compaction-preview.ts +5 -5
- package/src/renderer/compaction-quality.ts +5 -5
- package/src/renderer/composer-fragments.ts +6 -6
- package/src/renderer/compositor.ts +9 -9
- package/src/renderer/config-modal.ts +3 -3
- package/src/renderer/context-inspector.ts +1 -1
- package/src/renderer/context-status-hint.ts +10 -10
- package/src/renderer/conversation-layout.ts +2 -2
- package/src/renderer/conversation-overlays.ts +2 -2
- package/src/renderer/conversation-surface.ts +6 -6
- package/src/renderer/diff.ts +4 -4
- package/src/renderer/fleet-tab-strip.ts +2 -2
- package/src/renderer/footer-tips.ts +4 -4
- package/src/renderer/fullscreen-primitives.ts +1 -1
- package/src/renderer/git-status.ts +5 -5
- package/src/renderer/header-line.ts +5 -5
- package/src/renderer/help-overlay.ts +5 -5
- package/src/renderer/hint-grammar.ts +2 -2
- package/src/renderer/layout.ts +1 -1
- package/src/renderer/markdown-inline.ts +3 -3
- package/src/renderer/markdown-table.ts +7 -7
- package/src/renderer/modal-factory.ts +3 -3
- package/src/renderer/model-picker-overlay.ts +2 -2
- package/src/renderer/model-workspace.ts +7 -7
- package/src/renderer/onboarding/onboarding-wizard.ts +1 -1
- package/src/renderer/overlay-box.ts +1 -1
- package/src/renderer/panel-composite.ts +5 -5
- package/src/renderer/panel-workspace-bar.ts +1 -1
- package/src/renderer/process-indicator.ts +8 -8
- package/src/renderer/profile-picker-modal.ts +3 -3
- package/src/renderer/prompt-content-width.ts +1 -1
- package/src/renderer/search-overlay.ts +3 -3
- package/src/renderer/selection-modal-overlay.ts +6 -6
- package/src/renderer/semantic-diff.ts +6 -7
- package/src/renderer/session-picker-modal.ts +24 -24
- package/src/renderer/settings-modal-connections.ts +3 -3
- package/src/renderer/settings-modal-helpers.ts +16 -16
- package/src/renderer/settings-modal.ts +10 -10
- package/src/renderer/shell-surface.ts +8 -8
- package/src/renderer/status-glyphs.ts +6 -6
- package/src/renderer/syntax-highlighter.ts +2 -3
- package/src/renderer/system-message.ts +3 -3
- package/src/renderer/tab-strip.ts +2 -2
- package/src/renderer/term-caps.ts +12 -12
- package/src/renderer/terminal-bg-probe.ts +10 -10
- package/src/renderer/terminal-escapes.ts +1 -1
- package/src/renderer/theme-mode-config.ts +3 -3
- package/src/renderer/theme.ts +34 -34
- package/src/renderer/thinking.ts +1 -1
- package/src/renderer/tool-call.ts +5 -5
- package/src/renderer/tool-result-expanded-lines.ts +3 -3
- package/src/renderer/tool-result-summary.ts +6 -6
- package/src/renderer/turn-injection.ts +9 -9
- package/src/renderer/ui-factory.ts +33 -33
- package/src/renderer/ui-primitives.ts +4 -4
- package/src/runtime/bootstrap-command-parts.ts +3 -3
- package/src/runtime/bootstrap-core.ts +21 -21
- package/src/runtime/bootstrap-hook-bridge.ts +8 -8
- package/src/runtime/bootstrap-shell.ts +9 -9
- package/src/runtime/bootstrap.ts +16 -16
- package/src/runtime/client/approval-updates.ts +3 -3
- package/src/runtime/client/build-floors.ts +7 -7
- package/src/runtime/client/daemon-attach-handshake.ts +5 -5
- package/src/runtime/client/fleet-union.ts +7 -7
- package/src/runtime/client/host-service-status.ts +2 -2
- package/src/runtime/client/hosted-exit.ts +4 -4
- package/src/runtime/client/hosted-roster.ts +4 -4
- package/src/runtime/client/hosted-session-stream.ts +5 -5
- package/src/runtime/client/hosted-sessions.ts +8 -8
- package/src/runtime/client/operator-endpoint.ts +14 -14
- package/src/runtime/client/spine-adoption.ts +8 -8
- package/src/runtime/context-accounting-source.ts +4 -4
- package/src/runtime/context.ts +2 -2
- package/src/runtime/conversation-rewind-port.ts +6 -6
- package/src/runtime/credential-composition.ts +2 -2
- package/src/runtime/daemon-attach-notices.ts +6 -6
- package/src/runtime/diagnostics/panels/index.ts +1 -1
- package/src/runtime/diagnostics/panels/ops.ts +2 -2
- package/src/runtime/disposal-wiring.ts +6 -6
- package/src/runtime/index.ts +11 -11
- package/src/runtime/install-self-check-startup.ts +4 -4
- package/src/runtime/install-self-check.ts +6 -6
- package/src/runtime/interaction-seams.ts +4 -4
- package/src/runtime/knowledge-services.ts +2 -2
- package/src/runtime/legacy-daemon-migration.ts +37 -37
- package/src/runtime/legacy-daemon-reconcile.ts +30 -30
- package/src/runtime/memory-governance-services.ts +3 -3
- package/src/runtime/memory-spine-transport.ts +3 -3
- package/src/runtime/notification-dispatch.ts +4 -4
- package/src/runtime/onboarding/apply.ts +1 -1
- package/src/runtime/onboarding/derivation.ts +1 -1
- package/src/runtime/onboarding/fast-path.ts +7 -7
- package/src/runtime/onboarding/progress.ts +2 -2
- package/src/runtime/onboarding/provider-key-capture.ts +4 -4
- package/src/runtime/onboarding/snapshot.ts +2 -2
- package/src/runtime/onboarding/state.ts +4 -4
- package/src/runtime/onboarding/types.ts +4 -4
- package/src/runtime/orchestrator-core-services.ts +5 -5
- package/src/runtime/path-shadow-startup.ts +3 -3
- package/src/runtime/perf/panel-contracts.ts +1 -1
- package/src/runtime/power-keepawake-remote.ts +6 -6
- package/src/runtime/process-lifecycle.ts +14 -14
- package/src/runtime/provider-fallback.ts +3 -3
- package/src/runtime/recovery-autosave.ts +3 -3
- package/src/runtime/recovery-decisions.ts +19 -19
- package/src/runtime/recovery-offer-wiring.ts +4 -4
- package/src/runtime/recovery-prompt.ts +20 -20
- package/src/runtime/relay-reachability-bridge.ts +3 -3
- package/src/runtime/release-artifacts.ts +1 -1
- package/src/runtime/resume-notice.ts +20 -20
- package/src/runtime/runtime-services-types.ts +20 -20
- package/src/runtime/services.ts +20 -20
- package/src/runtime/session-continuity-hints.ts +1 -1
- package/src/runtime/session-inbound-inputs.ts +12 -12
- package/src/runtime/session-resume-liveness-confirm.ts +4 -4
- package/src/runtime/session-spine-transport.ts +3 -3
- package/src/runtime/store/domains/panels.ts +2 -2
- package/src/runtime/store/domains/ui-perf.ts +2 -2
- package/src/runtime/store/index.ts +1 -1
- package/src/runtime/store/selectors/index.ts +1 -1
- package/src/runtime/store/state.ts +2 -2
- package/src/runtime/ui-services.ts +3 -3
- package/src/runtime/workspace-checkpointing.ts +3 -3
- package/src/runtime/wrfc-persistence.ts +15 -15
- package/src/scripts/process-messages.ts +1 -1
- package/src/shell/blocking-input.ts +9 -9
- package/src/shell/recovery-input-helpers.ts +2 -2
- package/src/shell/retry-affordance.ts +9 -9
- package/src/shell/ui-openers.ts +14 -14
- package/src/shell/voice-capture-shell.ts +3 -3
- package/src/tools/wrfc-agent-guard.ts +4 -4
- package/src/utils/browser.ts +2 -2
- package/src/utils/format-duration.ts +3 -3
- package/src/utils/format-number.ts +2 -2
- package/src/utils/splash-lines.ts +4 -4
- package/src/utils/terminal-width.ts +6 -6
- package/src/verification/verification-ledger.ts +25 -25
- package/src/version.ts +3 -3
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// ---------------------------------------------------------------------------
|
|
2
|
-
// rewind-runtime.ts
|
|
2
|
+
// rewind-runtime.ts, /rewind (message-anchored, unified files + conversation),
|
|
3
3
|
// plus the /undo rewind and /redo rewind reversals over the last receipt.
|
|
4
4
|
//
|
|
5
5
|
// The rewind engine is the SDK's UnifiedRewindService (platform/rewind:
|
|
6
6
|
// plan() previews + issues a single-use confirm token; apply() is token-gated
|
|
7
7
|
// and returns a receipt carrying an undo block). It JOINS the platform's three
|
|
8
|
-
// existing history stores
|
|
8
|
+
// existing history stores, it never adds a fourth. This module wires that
|
|
9
9
|
// service to the TUI's in-process stores through the two ports the service
|
|
10
10
|
// defines:
|
|
11
11
|
// • RewindWorkspacePort ← the in-process WorkspaceCheckpointManager (the
|
|
@@ -51,7 +51,7 @@ export type RewindScope = SdkRewindScope;
|
|
|
51
51
|
const REWIND_SCOPES: readonly RewindScope[] = ['files', 'conversation', 'both'];
|
|
52
52
|
|
|
53
53
|
// ---------------------------------------------------------------------------
|
|
54
|
-
// Ports
|
|
54
|
+
// Ports, bridge the SDK rewind service onto the TUI's in-process stores.
|
|
55
55
|
// ---------------------------------------------------------------------------
|
|
56
56
|
|
|
57
57
|
/**
|
|
@@ -75,7 +75,7 @@ function makeWorkspacePort(mgr: WorkspaceCheckpointManager): RewindWorkspacePort
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
// ---------------------------------------------------------------------------
|
|
78
|
-
// Per-session rewind state
|
|
78
|
+
// Per-session rewind state, the SDK service (with its wired ports) plus the
|
|
79
79
|
// TUI-owned undo/redo stacks of applied receipts.
|
|
80
80
|
// ---------------------------------------------------------------------------
|
|
81
81
|
|
|
@@ -120,7 +120,7 @@ function undoAvailable(receipt: RewindReceipt): boolean {
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
// ---------------------------------------------------------------------------
|
|
123
|
-
// /undo rewind & /redo rewind
|
|
123
|
+
// /undo rewind & /redo rewind, reversal over the last receipt's undo points.
|
|
124
124
|
// Called from session-content.ts so the /undo and /redo commands stay single.
|
|
125
125
|
// ---------------------------------------------------------------------------
|
|
126
126
|
|
|
@@ -201,7 +201,7 @@ function renderTurnList(sessionId: string): string {
|
|
|
201
201
|
if (turns.length === 0) {
|
|
202
202
|
return 'No completed turns recorded this run yet. /rewind targets turns completed in the current session run.';
|
|
203
203
|
}
|
|
204
|
-
const lines = ['Recent turns (newest first)
|
|
204
|
+
const lines = ['Recent turns (newest first): /rewind <n> [files|conversation|both]:'];
|
|
205
205
|
turns.slice(0, 20).forEach((t, i) => {
|
|
206
206
|
lines.push(` ${String(i + 1).padStart(2)}. ${t.label} (${formatAge(t.at)}, ${t.messageCount} msgs)`);
|
|
207
207
|
});
|
|
@@ -233,12 +233,12 @@ function parseScope(token: string | undefined): RewindScope | null {
|
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
// ---------------------------------------------------------------------------
|
|
236
|
-
// Checkpoint-only fallback
|
|
236
|
+
// Checkpoint-only fallback, no completed turns recorded THIS run (e.g. right
|
|
237
237
|
// after a restart) means the message-anchored picker above has nothing to
|
|
238
238
|
// list, even though real workspace checkpoints exist on disk. Rather than
|
|
239
239
|
// dead-ending on "no completed turns" while /checkpoints and the boot notice
|
|
240
240
|
// both point back here, /rewind falls back to listing and restoring
|
|
241
|
-
// checkpoints directly
|
|
241
|
+
// checkpoints directly, a FILES-ONLY restore (there is no turn anchor to
|
|
242
242
|
// join a conversation boundary against), reusing the same diff-panel
|
|
243
243
|
// preview/confirm idiom as the turn-anchored path above.
|
|
244
244
|
// ---------------------------------------------------------------------------
|
|
@@ -247,9 +247,9 @@ const CHECKPOINT_FALLBACK_NO_ANCHORS_MESSAGE = 'No completed turns recorded this
|
|
|
247
247
|
|
|
248
248
|
function renderCheckpointFallbackList(checkpoints: readonly WorkspaceCheckpoint[]): string {
|
|
249
249
|
const lines = [
|
|
250
|
-
'No completed turns recorded this run yet
|
|
250
|
+
'No completed turns recorded this run yet; falling back to workspace checkpoints (FILES ONLY, no conversation state):',
|
|
251
251
|
...checkpoints.slice(0, 20).map((cp, i) => ` ${String(i + 1).padStart(2)}. ${shortId(cp.id).padEnd(12)} ${cp.kind.padEnd(9)} ${cp.label} (${formatAge(cp.createdAt)})`),
|
|
252
|
-
'Restore one: /rewind <n|id
|
|
252
|
+
'Restore one: /rewind <n|id>; files only; conversation history is untouched.',
|
|
253
253
|
];
|
|
254
254
|
return lines.join('\n');
|
|
255
255
|
}
|
|
@@ -272,7 +272,7 @@ function resolveCheckpointRef(checkpoints: readonly WorkspaceCheckpoint[], ref:
|
|
|
272
272
|
/**
|
|
273
273
|
* Handles bare `/rewind` and `/rewind <ref>` when this run has recorded no
|
|
274
274
|
* turn anchors at all. Returns true if it handled the invocation (always,
|
|
275
|
-
* once called), false is never returned
|
|
275
|
+
* once called), false is never returned, kept boolean-shaped only to mirror
|
|
276
276
|
* the calling convention at the call site.
|
|
277
277
|
*/
|
|
278
278
|
async function handleCheckpointOnlyRewind(args: string[], ctx: CommandContext): Promise<void> {
|
|
@@ -325,13 +325,13 @@ async function handleCheckpointOnlyRewind(args: string[], ctx: CommandContext):
|
|
|
325
325
|
|
|
326
326
|
diffPanel.confirmOverlay.arm({
|
|
327
327
|
id: checkpoint.id,
|
|
328
|
-
label: `${checkpoint.label}
|
|
328
|
+
label: `${checkpoint.label}: restore FILES ONLY (no conversation state this run)`,
|
|
329
329
|
verb: 'Restore',
|
|
330
330
|
onConfirm: async () => {
|
|
331
331
|
try {
|
|
332
332
|
await mgr.restore(checkpoint.id, { safetyCheckpoint: true });
|
|
333
333
|
ctx.session.conversationManager.addTypedSystemMessage(
|
|
334
|
-
`[Rewind] Restored files from checkpoint ${shortId(checkpoint.id)} ("${checkpoint.label}"). Files only
|
|
334
|
+
`[Rewind] Restored files from checkpoint ${shortId(checkpoint.id)} ("${checkpoint.label}"). Files only: no turn anchors exist this run, so conversation state is unchanged.`,
|
|
335
335
|
'operational',
|
|
336
336
|
);
|
|
337
337
|
pm.close('diff');
|
|
@@ -342,14 +342,14 @@ async function handleCheckpointOnlyRewind(args: string[], ctx: CommandContext):
|
|
|
342
342
|
}
|
|
343
343
|
},
|
|
344
344
|
onCancel: () => {
|
|
345
|
-
ctx.print('Restore cancelled
|
|
345
|
+
ctx.print('Restore cancelled: nothing changed.');
|
|
346
346
|
pm.close('diff');
|
|
347
347
|
ctx.focusPrompt?.();
|
|
348
348
|
ctx.renderRequest();
|
|
349
349
|
},
|
|
350
350
|
});
|
|
351
351
|
|
|
352
|
-
ctx.print(`Previewing checkpoint restore: "${checkpoint.label}" (FILES ONLY
|
|
352
|
+
ctx.print(`Previewing checkpoint restore: "${checkpoint.label}" (FILES ONLY; no conversation state this run). Confirm in the diff panel: Enter/y to restore, n/Esc to cancel.`);
|
|
353
353
|
ctx.renderRequest();
|
|
354
354
|
}
|
|
355
355
|
|
|
@@ -367,7 +367,7 @@ export function registerRewindRuntimeCommands(registry: CommandRegistry): void {
|
|
|
367
367
|
const sessionId = ctx.session.runtime.sessionId;
|
|
368
368
|
|
|
369
369
|
// No turn anchors recorded this run (most commonly: right after a
|
|
370
|
-
// restart, before /session resume has restored any)
|
|
370
|
+
// restart, before /session resume has restored any), fall back to a
|
|
371
371
|
// files-only restore over the real workspace checkpoints instead of a
|
|
372
372
|
// dead end (see handleCheckpointOnlyRewind's header doc).
|
|
373
373
|
if (recentTurnsNewestFirst(sessionId).length === 0) {
|
|
@@ -393,7 +393,7 @@ export function registerRewindRuntimeCommands(registry: CommandRegistry): void {
|
|
|
393
393
|
const anchor: RewindAnchor = { sessionId, turnId: resolved.turnId };
|
|
394
394
|
|
|
395
395
|
if (wants(scope, 'files') && !ctx.workspace.workspaceCheckpointManager) {
|
|
396
|
-
ctx.print('Checkpoints are not available in this session
|
|
396
|
+
ctx.print('Checkpoints are not available in this session; files rewind cannot run. Try /rewind <n> conversation.');
|
|
397
397
|
return;
|
|
398
398
|
}
|
|
399
399
|
|
|
@@ -413,7 +413,7 @@ export function registerRewindRuntimeCommands(registry: CommandRegistry): void {
|
|
|
413
413
|
}
|
|
414
414
|
|
|
415
415
|
// Preview in the DiffPanel + arm its confirm overlay (same idiom the
|
|
416
|
-
// former checkpoint-id /rewind used
|
|
416
|
+
// former checkpoint-id /rewind used, see checkpoint-runtime.ts).
|
|
417
417
|
const { DiffPanel } = await import('../../panels/diff-panel.ts');
|
|
418
418
|
const pm = requirePanelManager(ctx);
|
|
419
419
|
let panel = pm.getAllOpen().find((p) => p.id === 'diff');
|
|
@@ -438,7 +438,7 @@ export function registerRewindRuntimeCommands(registry: CommandRegistry): void {
|
|
|
438
438
|
const drop = plan.conversation?.messagesToDrop ?? 0;
|
|
439
439
|
const remaining = plan.conversation?.messagesRemaining ?? 0;
|
|
440
440
|
diffPanel.showDiff(
|
|
441
|
-
`Conversation rewind
|
|
441
|
+
`Conversation rewind: drop ${drop} message(s)`,
|
|
442
442
|
`@@ rewind @@\n Keep ${remaining} message(s), drop ${drop} after this turn. No files change.`,
|
|
443
443
|
);
|
|
444
444
|
}
|
|
@@ -449,7 +449,7 @@ export function registerRewindRuntimeCommands(registry: CommandRegistry): void {
|
|
|
449
449
|
|
|
450
450
|
diffPanel.confirmOverlay.arm({
|
|
451
451
|
id: anchor.turnId ?? sessionId,
|
|
452
|
-
label: `${resolved.label}
|
|
452
|
+
label: `${resolved.label}: rewind ${scope} (${summaryParts.join(', ')})`,
|
|
453
453
|
verb: 'Rewind',
|
|
454
454
|
onConfirm: async () => {
|
|
455
455
|
try {
|
|
@@ -478,7 +478,7 @@ export function registerRewindRuntimeCommands(registry: CommandRegistry): void {
|
|
|
478
478
|
}
|
|
479
479
|
},
|
|
480
480
|
onCancel: () => {
|
|
481
|
-
ctx.print('Rewind cancelled
|
|
481
|
+
ctx.print('Rewind cancelled: nothing changed.');
|
|
482
482
|
pm.close('diff');
|
|
483
483
|
ctx.focusPrompt?.();
|
|
484
484
|
ctx.renderRequest();
|
|
@@ -117,7 +117,7 @@ export function openCommandPanel(
|
|
|
117
117
|
* (group-B migration): open a config-modal surface by name via the
|
|
118
118
|
* ctx.openModal seam (ui-openers wires it; the host replaces the interim
|
|
119
119
|
* "not available yet" implementation with real dispatch). Front-doors for
|
|
120
|
-
* panels that migrated to modals call this instead of openCommandPanel
|
|
120
|
+
* panels that migrated to modals call this instead of openCommandPanel, the
|
|
121
121
|
* modal is the surface's new home. Stubbed in tests by setting ctx.openModal.
|
|
122
122
|
*/
|
|
123
123
|
export function openModalCommand(
|
|
@@ -336,7 +336,6 @@ export async function compactConversation(context: CommandContext): Promise<Comp
|
|
|
336
336
|
compactionCtx,
|
|
337
337
|
);
|
|
338
338
|
const eventAfter = getLastCompactionEvent();
|
|
339
|
-
// Return the new event only if it differs from the one recorded before the call.
|
|
340
339
|
if (eventAfter !== null && eventAfter !== eventBefore) {
|
|
341
340
|
//: score this run out-of-band (see compaction-quality.ts for why
|
|
342
341
|
// this can't just subscribe to the SDK's own CompactionManager pipeline)
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Local natural-language schedule parsing for `/schedule add when "<phrase>"`.
|
|
3
3
|
*
|
|
4
4
|
* Parses common English scheduling phrases entirely offline into one of the
|
|
5
|
-
* three concrete schedule shapes the automation manager already understands
|
|
6
|
-
* `cron`, `every` (fixed interval), or `at` (one-shot timestamp)
|
|
5
|
+
* three concrete schedule shapes the automation manager already understands,
|
|
6
|
+
* `cron`, `every` (fixed interval), or `at` (one-shot timestamp), and returns
|
|
7
7
|
* a plain-English description of exactly what it decided, so the caller can
|
|
8
8
|
* ALWAYS echo the concrete interpretation back to the user before anything is
|
|
9
9
|
* saved.
|
|
@@ -58,7 +58,7 @@ function parseAutomationTarget(raw: string | undefined): AutomationSessionTarget
|
|
|
58
58
|
* the SDK's severity ladder, narrowed to the current model's own resolved
|
|
59
59
|
* levels whenever the runtime has published them. A scheduled job may well run
|
|
60
60
|
* on a different model than the one in use now, so a level this model does not
|
|
61
|
-
* offer is still accepted when it is a real level
|
|
61
|
+
* offer is still accepted when it is a real level, it is re-resolved against
|
|
62
62
|
* whichever model actually serves the run.
|
|
63
63
|
*/
|
|
64
64
|
function parseReasoningEffort(raw: string | undefined): AutomationExecutionPolicy['reasoningEffort'] | undefined {
|
|
@@ -123,7 +123,7 @@ export function registerScheduleRuntimeCommands(registry: CommandRegistry): void
|
|
|
123
123
|
// The SDK owns the presence + title of the how-to-create-your-first-
|
|
124
124
|
// routine empty state (shown while automation is on and idle). Its
|
|
125
125
|
// body points at a command name this registry doesn't have, so we
|
|
126
|
-
// render its title with THIS surface's real /schedule commands
|
|
126
|
+
// render its title with THIS surface's real /schedule commands, a
|
|
127
127
|
// command pointer that actually exists in the registry.
|
|
128
128
|
const emptyState = buildAutomationEmptyState({ enabled: true, routineCount: jobs.length });
|
|
129
129
|
ctx.print([
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* /secret
|
|
2
|
+
* /secret, capture a password-like value through the composer's concealed
|
|
3
3
|
* input mode, without the plaintext ever appearing in the transcript or input
|
|
4
4
|
* history.
|
|
5
5
|
*
|
|
@@ -27,7 +27,7 @@ export function registerSecretRuntimeCommands(registry: CommandRegistry): void {
|
|
|
27
27
|
handler(args, ctx) {
|
|
28
28
|
const name = toEnvVarName(args[0] ?? '');
|
|
29
29
|
if (!name) {
|
|
30
|
-
ctx.print('[Secret] Usage: /secret <NAME
|
|
30
|
+
ctx.print('[Secret] Usage: /secret <NAME>; the value is typed on the next line with the keystrokes masked.');
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
33
|
if (!ctx.beginConcealedInput) {
|
|
@@ -43,7 +43,7 @@ export function registerSecretRuntimeCommands(registry: CommandRegistry): void {
|
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
45
|
process.env[name] = value;
|
|
46
|
-
// Never echo the value
|
|
46
|
+
// Never echo the value, only a redacted confirmation of length.
|
|
47
47
|
ctx.print(`[Secret] Stored ${name} (${value.length} character${value.length === 1 ? '' : 's'}, value hidden). Available to shell/tool runs as $${name}.`);
|
|
48
48
|
},
|
|
49
49
|
onCancel: () => {
|
|
@@ -169,7 +169,7 @@ export function registerSessionContentCommands(registry: CommandRegistry): void
|
|
|
169
169
|
registry.register({
|
|
170
170
|
name: 'undo',
|
|
171
171
|
aliases: [],
|
|
172
|
-
description: 'Undo last action. /undo rewind
|
|
172
|
+
description: 'Undo last action. /undo rewind reverses the last /rewind. /undo file reverts the last file write/edit. /undo alone removes the last conversation turn',
|
|
173
173
|
usage: '[rewind|file]',
|
|
174
174
|
argsHint: '[rewind|file]',
|
|
175
175
|
async handler(args, ctx) {
|
|
@@ -203,7 +203,7 @@ export function registerSessionContentCommands(registry: CommandRegistry): void
|
|
|
203
203
|
|
|
204
204
|
registry.register({
|
|
205
205
|
name: 'redo',
|
|
206
|
-
description: 'Redo last undone action. /redo rewind
|
|
206
|
+
description: 'Redo last undone action. /redo rewind re-applies the last undone /rewind. /redo file re-applies the last reverted file. /redo alone restores a conversation turn',
|
|
207
207
|
usage: '[rewind|file]',
|
|
208
208
|
argsHint: '[rewind|file]',
|
|
209
209
|
async handler(args, ctx) {
|
|
@@ -259,7 +259,7 @@ export function registerSessionContentCommands(registry: CommandRegistry): void
|
|
|
259
259
|
argsHint: '[resume <id|name>]',
|
|
260
260
|
async handler(_args, ctx) {
|
|
261
261
|
// Splash's "resume last session" hint and users' muscle memory both say
|
|
262
|
-
// `/sessions resume <id>` (plural, matching this command's own name)
|
|
262
|
+
// `/sessions resume <id>` (plural, matching this command's own name),
|
|
263
263
|
// but subcommands like `resume` are only implemented on the singular
|
|
264
264
|
// `/session` command. Forward instead of silently listing and dropping
|
|
265
265
|
// the subcommand+id on the floor.
|
|
@@ -268,7 +268,7 @@ export function registerSessionContentCommands(registry: CommandRegistry): void
|
|
|
268
268
|
return;
|
|
269
269
|
}
|
|
270
270
|
const sessionManager = requireSessionManager(ctx);
|
|
271
|
-
// Excludes subagent-shaped transcripts (see session-picker-filter.ts)
|
|
271
|
+
// Excludes subagent-shaped transcripts (see session-picker-filter.ts),
|
|
272
272
|
// an unfiltered list here drowns real user sessions in spawned-agent
|
|
273
273
|
// noise. A direct `/sessions resume agent-xxxxxxxx` still reaches them.
|
|
274
274
|
const sessions = filterUserFacingSessions(sessionManager.list());
|
|
@@ -403,12 +403,12 @@ export function registerSessionContentCommands(registry: CommandRegistry): void
|
|
|
403
403
|
},
|
|
404
404
|
});
|
|
405
405
|
|
|
406
|
-
// From the core-verb naming pass (MEMORY fragmentation
|
|
406
|
+
// From the core-verb naming pass (MEMORY fragmentation, worst-class
|
|
407
407
|
// collision #2): this command used to be named /memory, colliding with
|
|
408
408
|
// the agent's /memory (an alias that forwards to /recall, the durable
|
|
409
|
-
// cross-session MemoryStore)
|
|
409
|
+
// cross-session MemoryStore), same command name, two unrelated features.
|
|
410
410
|
// Renamed to /note (this feature manages EPHEMERAL, session-scoped sticky
|
|
411
|
-
// notes pinned across context compaction
|
|
411
|
+
// notes pinned across context compaction, an entirely different resource
|
|
412
412
|
// from /recall's durable records). /memory is now registered as an alias
|
|
413
413
|
// of /recall below (memory.ts), matching the agent, so the word means the
|
|
414
414
|
// same thing on both surfaces. See
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* session-picker-filter.ts
|
|
2
|
+
* session-picker-filter.ts, keep subagent transcripts out of user-facing
|
|
3
3
|
* session pickers.
|
|
4
4
|
*
|
|
5
5
|
* Subagents spawned during a session get their own SessionManager-persisted
|
|
6
6
|
* transcript, named `agent-<id>` (see the SDK's agent manager, which mints
|
|
7
7
|
* ids as `agent-${uuid.slice(0, 8)}`). Those files are real, loadable
|
|
8
|
-
* sessions
|
|
8
|
+
* sessions, useful for forensic/debugging access, but they are not
|
|
9
9
|
* sessions a user ever started, and in a workspace with many spawned agents
|
|
10
10
|
* they drown the handful of sessions the user actually wants to pick from
|
|
11
11
|
* in `/resume` and `/sessions`.
|
|
12
12
|
*
|
|
13
13
|
* Both pickers filter agent-shaped entries out of the LIST/BROWSE view only.
|
|
14
14
|
* Direct resume by exact id/name (`/resume agent-xxxxxxxx`, `/session resume
|
|
15
|
-
* agent-xxxxxxxx`) is untouched and still reaches them
|
|
15
|
+
* agent-xxxxxxxx`) is untouched and still reaches them, this only affects
|
|
16
16
|
* what shows up when the id isn't already known.
|
|
17
17
|
*/
|
|
18
18
|
import type { SessionInfo } from '@pellux/goodvibes-sdk/platform/sessions';
|
|
@@ -75,7 +75,7 @@ function buildTranscriptReviewLines(
|
|
|
75
75
|
return [
|
|
76
76
|
`Transcript Events${kind === 'all' ? '' : `: ${kind}`}`,
|
|
77
77
|
` events: ${events.length}`,
|
|
78
|
-
...events.slice(0, 16).map((event) => ` #${String(event.messageIndex).padStart(3)} ${event.kind.padEnd(20)} ${event.title}
|
|
78
|
+
...events.slice(0, 16).map((event) => ` #${String(event.messageIndex).padStart(3)} ${event.kind.padEnd(20)} ${event.title}: ${event.detail}`),
|
|
79
79
|
...(events.length > 16 ? [` … ${events.length - 16} more event(s)`] : []),
|
|
80
80
|
];
|
|
81
81
|
}
|
|
@@ -84,14 +84,14 @@ function buildTranscriptReviewLines(
|
|
|
84
84
|
// (W6 review, finding 3: saved-layout restore with 'sessions' must not lie)
|
|
85
85
|
// can be unit-tested directly instead of through a full /resume harness.
|
|
86
86
|
// Delegates to the shared reopenPanelsWithModalSkip (core/session-resume-core.ts)
|
|
87
|
-
|
|
87
|
+
//, the same routine resumeSessionCore uses, so this standalone entry point
|
|
88
88
|
// and the canonical resume sequence can never diverge on panel-reopen behavior.
|
|
89
89
|
export function reopenPanelsFromReturnContext(ctx: CommandContext, summary: SessionReturnContextSummary | undefined): string[] {
|
|
90
90
|
if (!summary?.openPanels || summary.openPanels.length === 0) return [];
|
|
91
91
|
const panelManager = requirePanelManager(ctx);
|
|
92
92
|
const { reopened, movedToModal, notReopened } = reopenPanelsWithModalSkip(panelManager, summary.openPanels, DEFAULT_PANEL_REOPEN_LIMIT);
|
|
93
93
|
if (movedToModal.length > 0) {
|
|
94
|
-
ctx.print(`Note: ${movedToModal.join(', ')} moved to a modal
|
|
94
|
+
ctx.print(`Note: ${movedToModal.join(', ')} moved to a modal; reopen via its command instead of as a panel.`);
|
|
95
95
|
}
|
|
96
96
|
if (notReopened.length > 0) {
|
|
97
97
|
ctx.print(` …and ${notReopened.length} more not reopened (/panels to open)`);
|
|
@@ -213,7 +213,7 @@ export async function handleSessionWorkflowCommand(args: string[], ctx: CommandC
|
|
|
213
213
|
provider: ctx.session.runtime.provider,
|
|
214
214
|
timestamp: Date.now(),
|
|
215
215
|
// Naming a session is an act of curation, so the file this
|
|
216
|
-
// materializes for rename to act on is a user save, not machinery
|
|
216
|
+
// materializes for rename to act on is a user save, not machinery,
|
|
217
217
|
// the retention sweep must not expire something the user named.
|
|
218
218
|
saveSource: 'user',
|
|
219
219
|
});
|
|
@@ -229,7 +229,7 @@ export async function handleSessionWorkflowCommand(args: string[], ctx: CommandC
|
|
|
229
229
|
}
|
|
230
230
|
|
|
231
231
|
if (sub === 'resume') {
|
|
232
|
-
// '--force' bypasses the multi-instance liveness confirm below
|
|
232
|
+
// '--force' bypasses the multi-instance liveness confirm below, never a
|
|
233
233
|
// session-id/name token itself (session ids never start with '--').
|
|
234
234
|
const rawArgs = args.slice(1);
|
|
235
235
|
const force = rawArgs.includes('--force');
|
|
@@ -250,14 +250,14 @@ export async function handleSessionWorkflowCommand(args: string[], ctx: CommandC
|
|
|
250
250
|
}
|
|
251
251
|
|
|
252
252
|
// Multi-instance safety: warn (and require --force) when this session
|
|
253
|
-
// looks open in another still-running terminal right now
|
|
253
|
+
// looks open in another still-running terminal right now, resuming it
|
|
254
254
|
// here would fork its live state out from under that other instance.
|
|
255
255
|
// Best-effort: a missing/stale marker (or this process's OWN marker,
|
|
256
256
|
// e.g. re-resuming the session already active here) never blocks anything.
|
|
257
257
|
const liveness = checkSessionLiveness(requireSurface(ctx), found.name);
|
|
258
258
|
if (liveness.live && liveness.pid !== process.pid && !force) {
|
|
259
259
|
ctx.print(
|
|
260
|
-
`Session appears open in another terminal (pid ${liveness.pid})
|
|
260
|
+
`Session appears open in another terminal (pid ${liveness.pid}): resuming will fork its live state.\n` +
|
|
261
261
|
`Re-run \`/session resume ${found.name} --force\` to proceed anyway.`,
|
|
262
262
|
);
|
|
263
263
|
return true;
|
|
@@ -279,10 +279,10 @@ export async function handleSessionWorkflowCommand(args: string[], ctx: CommandC
|
|
|
279
279
|
ctx.renderRequest();
|
|
280
280
|
ctx.print(`Resumed session: ${found.name}\n Name: ${meta.title || '(untitled)'}\n Messages: ${resumedMessageCount}\n Model: ${meta.model || ctx.session.runtime.model}`);
|
|
281
281
|
if (restoredAnchorCount > 0) {
|
|
282
|
-
ctx.print(` Rewind: restored ${restoredAnchorCount} turn anchor(s)
|
|
282
|
+
ctx.print(` Rewind: restored ${restoredAnchorCount} turn anchor(s); /rewind is available for this resumed session.`);
|
|
283
283
|
}
|
|
284
284
|
if (journalReplay.replayed > 0) {
|
|
285
|
-
ctx.print(` [Recovery] Replayed ${journalReplay.replayed} journal record(s)
|
|
285
|
+
ctx.print(` [Recovery] Replayed ${journalReplay.replayed} journal record(s): restored turns since last snapshot.`);
|
|
286
286
|
}
|
|
287
287
|
if (journalReplay.hadCorruptTail && journalReplay.replayed === 0) {
|
|
288
288
|
ctx.print(' [Recovery] Journal tail was corrupt or unrecognised (quarantined). Proceeding with snapshot only.');
|
|
@@ -290,7 +290,7 @@ export async function handleSessionWorkflowCommand(args: string[], ctx: CommandC
|
|
|
290
290
|
ctx.print(' [Recovery] Journal tail was partially corrupt (quarantined). Replay stopped at last good record.');
|
|
291
291
|
}
|
|
292
292
|
if (panels.movedToModal.length > 0) {
|
|
293
|
-
ctx.print(`Note: ${panels.movedToModal.join(', ')} moved to a modal
|
|
293
|
+
ctx.print(`Note: ${panels.movedToModal.join(', ')} moved to a modal; reopen via its command instead of as a panel.`);
|
|
294
294
|
}
|
|
295
295
|
if (panels.notReopened.length > 0) {
|
|
296
296
|
ctx.print(` …and ${panels.notReopened.length} more not reopened (/panels to open)`);
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* /session command handler
|
|
2
|
+
* /session command handler, Multi-session Orchestration.
|
|
3
3
|
*
|
|
4
4
|
* Implements session and workflow commands:
|
|
5
5
|
*
|
|
6
6
|
* /session link-task <taskId> [--session <sessionId>] [--depends-on <ref>] [--label <label>]
|
|
7
|
-
*
|
|
7
|
+
* , Register a task as a global cross-session ref, optionally linking it to a
|
|
8
8
|
* dependency.
|
|
9
9
|
*
|
|
10
10
|
* /session handoff <taskId> --to <sessionId> [--session <sessionId>] [--reason <reason>]
|
|
11
|
-
*
|
|
11
|
+
* , Initiate a task handoff from the current session to another.
|
|
12
12
|
*
|
|
13
13
|
* /session graph [--session <sessionId>] [--format text|json]
|
|
14
|
-
*
|
|
14
|
+
* , Display the cross-session task dependency graph.
|
|
15
15
|
*
|
|
16
16
|
* /session cancel <taskId|--scope session> [--session <sessionId>] [--scope task|subtree|session]
|
|
17
|
-
*
|
|
17
|
+
* , Cancel tasks with configurable scope semantics.
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
import type { SlashCommand, CommandContext } from '../command-registry.ts';
|
|
@@ -92,7 +92,7 @@ function handleLinkTask(args: string[], context: CommandContext): void {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
if (taskId.includes(':')) {
|
|
95
|
-
context.print('Error: taskId cannot contain ":"
|
|
95
|
+
context.print('Error: taskId cannot contain ":"; it conflicts with the composite key format.');
|
|
96
96
|
return;
|
|
97
97
|
}
|
|
98
98
|
|
|
@@ -318,11 +318,11 @@ function handleCancel(args: string[], context: CommandContext): void {
|
|
|
318
318
|
// ── Top-level command definition ───────────────────────────────────────────────
|
|
319
319
|
|
|
320
320
|
/**
|
|
321
|
-
* SESSION_SUBCOMMAND_ARG_HINTS
|
|
321
|
+
* SESSION_SUBCOMMAND_ARG_HINTS, the single source of truth for each
|
|
322
322
|
* `/session <subcommand>` argument hint, co-located with the switch below so
|
|
323
323
|
* the two can't silently drift apart (command-args-hint.ts imports this
|
|
324
|
-
* directly instead of hand-maintaining its own copy; a drift test
|
|
325
|
-
* src/test/input/command-args-hint.test.ts
|
|
324
|
+
* directly instead of hand-maintaining its own copy; a drift test,
|
|
325
|
+
* src/test/input/command-args-hint.test.ts, cross-checks every key here
|
|
326
326
|
* against the default usage text's own subcommand list). Aliases (`link`,
|
|
327
327
|
* `ho`, `g`) share their canonical subcommand's hint text.
|
|
328
328
|
*/
|
|
@@ -349,14 +349,14 @@ export const SESSION_SUBCOMMAND_ARG_HINTS: Record<string, string> = {
|
|
|
349
349
|
};
|
|
350
350
|
|
|
351
351
|
/**
|
|
352
|
-
* sessionCommand
|
|
352
|
+
* sessionCommand, The `/session` slash command.
|
|
353
353
|
*
|
|
354
354
|
* The ONE front-door for all session operations. Owns two domains:
|
|
355
355
|
*
|
|
356
356
|
* Lifecycle (continuity, export, resume, pruning):
|
|
357
357
|
* list | rename | resume | fork | save | info | events | groups | hotspots | export | search | delete
|
|
358
358
|
*
|
|
359
|
-
* Orchestration (cross-session task DAG
|
|
359
|
+
* Orchestration (cross-session task DAG, 40 tests, cycle detection):
|
|
360
360
|
* link-task | handoff | graph | cancel
|
|
361
361
|
*
|
|
362
362
|
* Orchestration-command decision (TASK-032):
|
|
@@ -380,7 +380,7 @@ export const sessionCommand: SlashCommand = {
|
|
|
380
380
|
switch (sub) {
|
|
381
381
|
// ── Lifecycle subcommands ────────────────────────────────────────────────
|
|
382
382
|
// Each delegates explicitly to handleSessionWorkflowCommand so every
|
|
383
|
-
// subcommand has a deterministic, named path
|
|
383
|
+
// subcommand has a deterministic, named path, no silent fallthrough.
|
|
384
384
|
case 'list':
|
|
385
385
|
case 'rename':
|
|
386
386
|
case 'resume':
|
|
@@ -457,7 +457,7 @@ export const sessionCommand: SlashCommand = {
|
|
|
457
457
|
};
|
|
458
458
|
|
|
459
459
|
/**
|
|
460
|
-
* /resume
|
|
460
|
+
* /resume, the discoverable front door to session resume.
|
|
461
461
|
*
|
|
462
462
|
* `/session resume <id>` has always existed but is buried behind a
|
|
463
463
|
* subcommand nobody remembers mid-context-switch. `/resume` with no
|
|
@@ -469,7 +469,7 @@ export const sessionCommand: SlashCommand = {
|
|
|
469
469
|
export const resumeCommand: SlashCommand = {
|
|
470
470
|
name: 'resume',
|
|
471
471
|
aliases: [],
|
|
472
|
-
description: 'Resume a previous session
|
|
472
|
+
description: 'Resume a previous session, pick from a list or pass an id/name',
|
|
473
473
|
usage: '[session-id-or-name]',
|
|
474
474
|
argsHint: '[id|name]',
|
|
475
475
|
handler: async (args: string[], ctx: CommandContext): Promise<void> => {
|
|
@@ -479,7 +479,7 @@ export const resumeCommand: SlashCommand = {
|
|
|
479
479
|
}
|
|
480
480
|
const sm = requireSessionManager(ctx);
|
|
481
481
|
// Excludes the current session and subagent-shaped transcripts (see
|
|
482
|
-
// session-picker-filter.ts)
|
|
482
|
+
// session-picker-filter.ts), a direct `/resume agent-xxxxxxxx` still
|
|
483
483
|
// reaches them, this only keeps the picker itself readable.
|
|
484
484
|
const sessions = filterUserFacingSessions(sm.list()).filter((s) => s.name !== ctx.session.runtime.sessionId);
|
|
485
485
|
if (sessions.length === 0) {
|
|
@@ -27,14 +27,14 @@ export function registerSettingsSyncRuntimeCommands(registry: CommandRegistry):
|
|
|
27
27
|
name: 'settings-sync',
|
|
28
28
|
aliases: ['settingssync'],
|
|
29
29
|
description: 'Open the settings sync modal (bare); review posture, export/import bundles, or resolve conflicts by subcommand',
|
|
30
|
-
usage: '[panel|report|review|show <key>|staged|conflicts|resolve <key> <local|synced>|failures|rollback-history|export <path>|inspect <path>|pull <path>|push <path>|lock <key> <source> <reason...>|unlock <key>]
|
|
30
|
+
usage: '[panel|report|review|show <key>|staged|conflicts|resolve <key> <local|synced>|failures|rollback-history|export <path>|inspect <path>|pull <path>|push <path>|lock <key> <source> <reason...>|unlock <key>]: bare opens the modal',
|
|
31
31
|
handler(args, ctx) {
|
|
32
32
|
const shellPaths = requireShellPaths(ctx);
|
|
33
33
|
const controlPlaneConfigDir = ctx.platform.configManager.getControlPlaneConfigDir();
|
|
34
34
|
const sub = (args[0] ?? '').toLowerCase();
|
|
35
35
|
// item 3 (report-vs-modal front doors): settings-sync has a full
|
|
36
36
|
// modal surface (settings-sync-modal), so the bare command now opens it
|
|
37
|
-
|
|
37
|
+
//, the old bare/`review` transcript report moved to an explicit
|
|
38
38
|
// `report` subcommand (scriptability preserved: /settings-sync report).
|
|
39
39
|
if (sub === '') {
|
|
40
40
|
ctx.openModal?.('settings-sync-modal');
|
|
@@ -80,7 +80,7 @@ export function registerShareRuntimeCommands(registry: CommandRegistry): void {
|
|
|
80
80
|
};
|
|
81
81
|
|
|
82
82
|
if (!convData.messages || convData.messages.length === 0) {
|
|
83
|
-
ctx.print('Nothing to export
|
|
83
|
+
ctx.print('Nothing to export: conversation is empty.');
|
|
84
84
|
return;
|
|
85
85
|
}
|
|
86
86
|
|
|
@@ -113,12 +113,12 @@ export function registerShareRuntimeCommands(registry: CommandRegistry): void {
|
|
|
113
113
|
const sessionCostUsd = calcSessionCost(
|
|
114
114
|
totalInput, totalOutput, totalCacheRead, totalCacheWrite, sessionModel,
|
|
115
115
|
);
|
|
116
|
-
// The exported document has no field for "this cost is a placeholder"
|
|
116
|
+
// The exported document has no field for "this cost is a placeholder",
|
|
117
117
|
// omit `cost` entirely rather than embed a misleading 0 when the model
|
|
118
118
|
// never resolved to a real price.
|
|
119
119
|
const costIsUnpriced = !isModelPriced(sessionModel);
|
|
120
120
|
if (costIsUnpriced) {
|
|
121
|
-
ctx.print(`Note: cost omitted from export
|
|
121
|
+
ctx.print(`Note: cost omitted from export; no pricing data for model "${sessionModel}".`);
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
const metadata = {
|
|
@@ -167,7 +167,7 @@ export function registerShareRuntimeCommands(registry: CommandRegistry): void {
|
|
|
167
167
|
authHeaders = await svcRegistry.resolveAuth('github').catch(() => null);
|
|
168
168
|
}
|
|
169
169
|
} catch {
|
|
170
|
-
// serviceRegistry absent or resolveAuth threw
|
|
170
|
+
// serviceRegistry absent or resolveAuth threw, fall through to env var
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
const token = resolveGithubToken(authHeaders ?? undefined);
|