@pellux/goodvibes-tui 2.0.14 → 2.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.goodvibes/GOODVIBES.md +1 -1
- package/.goodvibes/agents/reviewer.md +8 -8
- package/.goodvibes/skills/add-provider/SKILL.md +22 -22
- package/CHANGELOG.md +49 -0
- package/README.md +64 -44
- package/docs/README.md +6 -6
- package/docs/foundation-artifacts/README.md +5 -5
- package/docs/foundation-artifacts/operator-contract.json +123 -123
- package/package.json +12 -10
- package/scripts/postinstall.js +3 -3
- package/src/audio/activation-sound.ts +7 -7
- package/src/audio/capture.ts +7 -7
- package/src/audio/onnxruntime-assets.d.ts +1 -1
- package/src/audio/player.ts +4 -4
- package/src/audio/spoken-turn-wiring.ts +4 -4
- package/src/audio/voice-capture-wiring.ts +5 -5
- package/src/audio/voice-input-session.ts +3 -3
- package/src/audio/wake-inference.ts +13 -8
- package/src/audio/wake-runtime.ts +10 -10
- package/src/cli/completions/generate.ts +2 -2
- package/src/cli/doctor.ts +13 -13
- package/src/cli/ensure-goodvibes-gitignore.ts +3 -3
- package/src/cli/entrypoint.ts +3 -3
- package/src/cli/help.ts +6 -6
- package/src/cli/hooks-command.ts +4 -4
- package/src/cli/hooks-report.ts +4 -4
- package/src/cli/launch-auto-update.ts +17 -17
- package/src/cli/management-commands.ts +8 -8
- package/src/cli/management-utils.ts +3 -3
- package/src/cli/management.ts +1 -1
- package/src/cli/plugin-bundles-command.ts +10 -10
- package/src/cli/plugin-command.ts +9 -9
- package/src/cli/service-posture.ts +1 -1
- package/src/cli/status.ts +10 -10
- package/src/cli/surface-command.ts +4 -4
- package/src/cli/tui-startup.ts +23 -23
- package/src/config/run-daemon-config-migration.ts +3 -3
- package/src/config/secret-config.ts +10 -10
- package/src/config/surface.ts +1 -1
- package/src/config/tui-extension-settings.ts +8 -8
- package/src/core/active-model-identity.ts +7 -7
- package/src/core/approval-alert.ts +5 -5
- package/src/core/bookmark-navigation.ts +3 -3
- package/src/core/budget-breach-notifier.ts +6 -6
- package/src/core/compaction-receipt.ts +8 -8
- package/src/core/composer-state.ts +2 -2
- package/src/core/context-usage.ts +1 -1
- package/src/core/conversation-compaction-render.ts +3 -3
- package/src/core/conversation-event-navigation.ts +2 -2
- package/src/core/conversation-fold.ts +9 -9
- package/src/core/conversation-line-cache.ts +14 -14
- package/src/core/conversation-render-context.ts +6 -6
- package/src/core/conversation-rendering.ts +27 -30
- package/src/core/conversation-search-expansion.ts +6 -6
- package/src/core/conversation-splash-state.ts +3 -3
- package/src/core/conversation-turn-structure.ts +13 -13
- package/src/core/conversation-types.ts +3 -3
- package/src/core/conversation-user-receipts.ts +5 -5
- package/src/core/conversation.ts +17 -17
- package/src/core/format-user-error.ts +5 -5
- package/src/core/long-task-notifier.ts +9 -9
- package/src/core/memory-diagnostics-gateway.ts +8 -8
- package/src/core/memory-provenance.ts +5 -5
- package/src/core/model-routing-chip.ts +3 -3
- package/src/core/pairing-tailscale-gateway.ts +3 -3
- package/src/core/permission-mode.ts +5 -5
- package/src/core/power-chip-source.ts +3 -3
- package/src/core/power-status.ts +8 -8
- package/src/core/rewind-receipt.ts +6 -6
- package/src/core/session-resume-core.ts +8 -8
- package/src/core/stream-event-wiring.ts +36 -36
- package/src/core/stream-stall-watchdog.ts +4 -4
- package/src/core/system-message-noise.ts +7 -7
- package/src/core/system-message-router.ts +10 -10
- package/src/core/terminal-notifier.ts +5 -5
- package/src/core/turn-budget-outcome.ts +5 -5
- package/src/core/turn-cancellation.ts +3 -3
- package/src/core/turn-event-wiring.ts +16 -16
- package/src/core/voice-capture-status.ts +2 -2
- package/src/core/voice-provision-gateway.ts +12 -12
- package/src/core/voice-provision-status.ts +19 -19
- package/src/core/voice-stt-gateway.ts +6 -6
- package/src/core/wake-provision-runner.ts +7 -7
- package/src/core/wake-provision-status.ts +17 -17
- package/src/core/workstream-notification.ts +8 -8
- package/src/export/gist-uploader.ts +7 -7
- package/src/input/autocomplete.ts +3 -3
- package/src/input/bookmark-modal.ts +1 -1
- package/src/input/command-args-hint.ts +2 -2
- package/src/input/command-reference.ts +9 -9
- package/src/input/command-registry.ts +32 -32
- package/src/input/commands/acp-runtime.ts +6 -6
- package/src/input/commands/calendar-runtime.ts +9 -9
- package/src/input/commands/channel-pairing.ts +11 -11
- package/src/input/commands/channel-runtime.ts +1 -1
- package/src/input/commands/checkin-runtime.ts +4 -4
- package/src/input/commands/checkpoint-runtime.ts +4 -4
- package/src/input/commands/ci-runtime.ts +4 -4
- package/src/input/commands/cluster-runtime.ts +3 -3
- package/src/input/commands/codebase-runtime.ts +16 -16
- package/src/input/commands/config.ts +6 -6
- package/src/input/commands/connection-status.ts +12 -12
- package/src/input/commands/context-window.ts +2 -2
- package/src/input/commands/cost-attribution-format.ts +4 -4
- package/src/input/commands/cost-runtime.ts +2 -2
- package/src/input/commands/devices-runtime.ts +7 -7
- package/src/input/commands/diff-runtime.ts +2 -2
- package/src/input/commands/editor-runtime.ts +1 -1
- package/src/input/commands/eval.ts +4 -4
- package/src/input/commands/experience-runtime.ts +1 -1
- package/src/input/commands/git-runtime.ts +3 -3
- package/src/input/commands/graph-runtime.ts +3 -3
- package/src/input/commands/guidance-runtime.ts +1 -1
- package/src/input/commands/health-metrics-format.ts +2 -2
- package/src/input/commands/health-runtime.ts +8 -8
- package/src/input/commands/hosted-runtime.ts +13 -13
- package/src/input/commands/image-runtime.ts +6 -6
- package/src/input/commands/intelligence-runtime.ts +2 -2
- package/src/input/commands/local-auth-runtime.ts +3 -3
- package/src/input/commands/local-provider-runtime.ts +3 -3
- package/src/input/commands/local-runtime.ts +7 -7
- package/src/input/commands/mail-runtime.ts +9 -9
- package/src/input/commands/mcp-runtime.ts +1 -1
- package/src/input/commands/memory.ts +13 -13
- package/src/input/commands/notify-runtime.ts +1 -1
- package/src/input/commands/operator-panel-runtime.ts +8 -8
- package/src/input/commands/operator-rpc.ts +3 -3
- package/src/input/commands/operator-runtime.ts +3 -3
- package/src/input/commands/palette-runtime.ts +1 -1
- package/src/input/commands/payment-card-intake.ts +17 -17
- package/src/input/commands/permissions-provenance.ts +7 -7
- package/src/input/commands/permissions-runtime.ts +1 -1
- package/src/input/commands/planning-runtime.ts +19 -19
- package/src/input/commands/platform-services-runtime.ts +2 -2
- package/src/input/commands/policy-dispatch.ts +6 -6
- package/src/input/commands/power-runtime.ts +6 -6
- package/src/input/commands/principals-runtime.ts +3 -3
- package/src/input/commands/product-runtime.ts +3 -3
- package/src/input/commands/profile-render.ts +13 -13
- package/src/input/commands/profile-runtime.ts +13 -13
- package/src/input/commands/profile-types.ts +13 -13
- package/src/input/commands/provider-accounts-runtime.ts +5 -5
- package/src/input/commands/provider.ts +10 -10
- package/src/input/commands/qrcode-runtime.ts +3 -3
- package/src/input/commands/queue-runtime.ts +6 -6
- package/src/input/commands/recall-files-config.ts +4 -4
- package/src/input/commands/recall-files-git.ts +3 -3
- package/src/input/commands/recall-files.ts +12 -12
- package/src/input/commands/recall-query.ts +3 -3
- package/src/input/commands/recall-review.ts +3 -3
- package/src/input/commands/recall-shared.ts +1 -1
- package/src/input/commands/relay-runtime.ts +5 -5
- package/src/input/commands/remote-runtime.ts +3 -3
- package/src/input/commands/review-runtime.ts +8 -8
- package/src/input/commands/rewind-runtime.ts +21 -21
- package/src/input/commands/runtime-services.ts +1 -2
- package/src/input/commands/schedule-nl.ts +2 -2
- package/src/input/commands/schedule-runtime.ts +2 -2
- package/src/input/commands/secret-runtime.ts +3 -3
- package/src/input/commands/session-content.ts +7 -7
- package/src/input/commands/session-picker-filter.ts +3 -3
- package/src/input/commands/session-workflow.ts +10 -10
- package/src/input/commands/session.ts +15 -15
- package/src/input/commands/settings-sync-runtime.ts +2 -2
- package/src/input/commands/share-runtime.ts +4 -4
- package/src/input/commands/shell-core.ts +11 -11
- package/src/input/commands/tasks-runtime.ts +4 -4
- package/src/input/commands/test-runtime.ts +6 -6
- package/src/input/commands/tts-runtime.ts +4 -4
- package/src/input/commands/update-runtime.ts +27 -27
- package/src/input/commands/websearch-runtime.ts +2 -2
- package/src/input/commands/work-plan-runtime.ts +2 -2
- package/src/input/commands/workstream-attempt-dependents.ts +4 -4
- package/src/input/commands/workstream-attempts.ts +16 -16
- package/src/input/commands/workstream-runtime.ts +36 -36
- package/src/input/commands/worktree-runtime.ts +6 -6
- package/src/input/composer-capture.ts +5 -5
- package/src/input/concealed-input.ts +2 -2
- package/src/input/config-modal-types.ts +16 -16
- package/src/input/config-modal.ts +30 -30
- package/src/input/daemon-owned-settings-descriptions.ts +4 -4
- package/src/input/delete-key-policy.ts +1 -1
- package/src/input/exec-env-scrub-config.ts +7 -7
- package/src/input/feature-unit-layout.ts +5 -5
- package/src/input/feed-context-factory.ts +38 -38
- package/src/input/file-picker.ts +1 -1
- package/src/input/handler-command-route.ts +2 -2
- package/src/input/handler-content-actions.ts +8 -8
- package/src/input/handler-feed-routes.ts +13 -13
- package/src/input/handler-feed.ts +31 -31
- package/src/input/handler-interactions.ts +2 -2
- package/src/input/handler-modal-routes.ts +13 -13
- package/src/input/handler-modal-stack.ts +1 -1
- package/src/input/handler-modal-token-routes.ts +1 -1
- package/src/input/handler-onboarding-daemon-adopt.ts +6 -6
- package/src/input/handler-picker-routes.ts +7 -7
- package/src/input/handler-prompt-buffer.ts +1 -1
- package/src/input/handler-shortcuts.ts +12 -12
- package/src/input/handler-types.ts +3 -3
- package/src/input/handler-ui-state.ts +1 -1
- package/src/input/handler.ts +9 -9
- package/src/input/input-history.ts +1 -1
- package/src/input/keybindings.ts +13 -13
- package/src/input/kill-ring.ts +7 -11
- package/src/input/model-picker-filter.ts +3 -3
- package/src/input/model-picker-items.ts +5 -5
- package/src/input/model-picker-types.ts +2 -2
- package/src/input/model-picker.ts +18 -18
- package/src/input/onboarding/onboarding-feature-units.ts +9 -13
- package/src/input/onboarding/onboarding-provider-key-fields.ts +3 -3
- package/src/input/onboarding/onboarding-runtime-status.ts +3 -3
- package/src/input/onboarding/onboarding-wizard-apply.ts +6 -6
- package/src/input/onboarding/onboarding-wizard-cloudflare-step.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-constants.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-external-surfaces.ts +4 -4
- package/src/input/onboarding/onboarding-wizard-network-adopt.ts +6 -6
- package/src/input/onboarding/onboarding-wizard-steps.ts +2 -2
- package/src/input/panel-integration-actions.ts +3 -3
- package/src/input/panel-mouse-geometry.ts +1 -1
- package/src/input/panel-paste-flood-guard.ts +9 -9
- package/src/input/payments-config.ts +15 -15
- package/src/input/profile-picker-modal.ts +1 -1
- package/src/input/provider-key-intake.ts +9 -9
- package/src/input/relay-settings-descriptions.ts +3 -3
- package/src/input/sandbox-exec-config.ts +9 -9
- package/src/input/search.ts +18 -18
- package/src/input/selection-modal-queue.ts +10 -10
- package/src/input/selection-modal.ts +2 -2
- package/src/input/session-picker-modal.ts +7 -7
- package/src/input/settings-modal-activation.ts +1 -1
- package/src/input/settings-modal-adjustment.ts +2 -2
- package/src/input/settings-modal-commit.ts +6 -6
- package/src/input/settings-modal-connections.ts +2 -2
- package/src/input/settings-modal-data.ts +29 -29
- package/src/input/settings-modal-mutations.ts +7 -7
- package/src/input/settings-modal-reset.ts +3 -3
- package/src/input/settings-modal-search.ts +6 -6
- package/src/input/settings-modal-secrets.ts +3 -3
- package/src/input/settings-modal-types.ts +16 -16
- package/src/input/settings-modal.ts +4 -4
- package/src/input/voice-local-settings.ts +3 -3
- package/src/input/worktree-setup-config.ts +8 -8
- package/src/main.ts +15 -15
- package/src/panels/agent-inspector-shared.ts +5 -5
- package/src/panels/base-panel.ts +3 -3
- package/src/panels/builtin/agent.ts +3 -3
- package/src/panels/builtin/development.ts +4 -4
- package/src/panels/builtin/knowledge.ts +1 -1
- package/src/panels/builtin/operations.ts +12 -12
- package/src/panels/builtin/session.ts +8 -8
- package/src/panels/builtin/shared.ts +6 -6
- package/src/panels/builtin-modals.ts +8 -8
- package/src/panels/confirm-state.ts +5 -5
- package/src/panels/cost-tracker-panel.ts +22 -22
- package/src/panels/diff-panel.ts +20 -20
- package/src/panels/diff-review-model.ts +5 -5
- package/src/panels/diff-review-panel.ts +5 -5
- package/src/panels/eval-registry.ts +2 -2
- package/src/panels/expandable-list-panel.ts +5 -5
- package/src/panels/fleet-acts.ts +20 -20
- package/src/panels/fleet-deep-link.ts +5 -5
- package/src/panels/fleet-gateway.ts +12 -12
- package/src/panels/fleet-observed-render.ts +11 -11
- package/src/panels/fleet-panel-format.ts +14 -14
- package/src/panels/fleet-panel-worktree-detail.ts +8 -8
- package/src/panels/fleet-panel.ts +34 -34
- package/src/panels/fleet-read-model.ts +49 -49
- package/src/panels/fleet-spawn.ts +15 -15
- package/src/panels/fleet-steer.ts +7 -7
- package/src/panels/fleet-stop.ts +5 -5
- package/src/panels/fleet-tabs.ts +14 -14
- package/src/panels/fleet-transcript.ts +26 -26
- package/src/panels/git-panel.ts +8 -8
- package/src/panels/hosted-session-feed.ts +13 -13
- package/src/panels/hosted-session-panel.ts +7 -7
- package/src/panels/index.ts +1 -1
- package/src/panels/local-auth-panel.ts +15 -15
- package/src/panels/memory-consolidation-gateway.ts +8 -8
- package/src/panels/modals/devices-modal.ts +8 -8
- package/src/panels/modals/hooks-modal.ts +1 -1
- package/src/panels/modals/keybindings-modal.ts +5 -5
- package/src/panels/modals/knowledge-modal.ts +2 -2
- package/src/panels/modals/local-auth-modal.ts +4 -4
- package/src/panels/modals/marketplace-modal.ts +3 -3
- package/src/panels/modals/memory-modal.ts +19 -19
- package/src/panels/modals/modal-surface-helpers.ts +1 -1
- package/src/panels/modals/modal-theme.ts +3 -3
- package/src/panels/modals/pairing-modal.ts +19 -19
- package/src/panels/modals/planning-modal.ts +11 -11
- package/src/panels/modals/plugins-modal.ts +1 -1
- package/src/panels/modals/policy-modal.ts +4 -4
- package/src/panels/modals/provider-health-modal.ts +1 -1
- package/src/panels/modals/remote-modal.ts +1 -1
- package/src/panels/modals/sandbox-modal.ts +2 -2
- package/src/panels/modals/security-modal.ts +4 -4
- package/src/panels/modals/services-modal.ts +1 -1
- package/src/panels/modals/work-plan-modal.ts +4 -4
- package/src/panels/notifications-feed.ts +6 -6
- package/src/panels/notifications-panel.ts +6 -6
- package/src/panels/panel-confirm-overlay.ts +4 -4
- package/src/panels/panel-manager.ts +13 -13
- package/src/panels/plugins-panel.ts +6 -6
- package/src/panels/polish-core.ts +2 -2
- package/src/panels/polish-tables.ts +2 -2
- package/src/panels/polish.ts +1 -1
- package/src/panels/project-planning-answer-actions.ts +3 -3
- package/src/panels/scrollable-list-panel.ts +15 -15
- package/src/panels/search-focus.ts +1 -1
- package/src/panels/session-maintenance.ts +1 -1
- package/src/panels/skills-panel.ts +3 -3
- package/src/panels/token-budget-panel.ts +11 -11
- package/src/panels/types.ts +14 -14
- package/src/panels/workstream-graph-render.ts +5 -5
- package/src/panels/wrfc-panel-format.ts +1 -1
- package/src/permissions/broker-approval-card.ts +13 -13
- package/src/permissions/hunk-selection.ts +13 -13
- package/src/permissions/prompt.ts +22 -22
- package/src/permissions/sandbox-exec-gate.ts +5 -5
- package/src/providers/provider-classification.ts +1 -1
- package/src/providers/reasoning-effort-surface.ts +12 -12
- package/src/renderer/ansi-sanitize.ts +5 -6
- package/src/renderer/autocomplete-overlay.ts +5 -5
- package/src/renderer/block-actions-overlay.ts +1 -1
- package/src/renderer/bookmark-modal.ts +1 -1
- package/src/renderer/code-block.ts +2 -2
- package/src/renderer/compaction-history-modal.ts +4 -4
- package/src/renderer/compaction-preview.ts +5 -5
- package/src/renderer/compaction-quality.ts +5 -5
- package/src/renderer/composer-fragments.ts +6 -6
- package/src/renderer/compositor.ts +9 -9
- package/src/renderer/config-modal.ts +3 -3
- package/src/renderer/context-inspector.ts +1 -1
- package/src/renderer/context-status-hint.ts +10 -10
- package/src/renderer/conversation-layout.ts +2 -2
- package/src/renderer/conversation-overlays.ts +2 -2
- package/src/renderer/conversation-surface.ts +6 -6
- package/src/renderer/diff.ts +4 -4
- package/src/renderer/fleet-tab-strip.ts +2 -2
- package/src/renderer/footer-tips.ts +4 -4
- package/src/renderer/fullscreen-primitives.ts +1 -1
- package/src/renderer/git-status.ts +5 -5
- package/src/renderer/header-line.ts +5 -5
- package/src/renderer/help-overlay.ts +5 -5
- package/src/renderer/hint-grammar.ts +2 -2
- package/src/renderer/layout.ts +1 -1
- package/src/renderer/markdown-inline.ts +3 -3
- package/src/renderer/markdown-table.ts +7 -7
- package/src/renderer/modal-factory.ts +3 -3
- package/src/renderer/model-picker-overlay.ts +2 -2
- package/src/renderer/model-workspace.ts +7 -7
- package/src/renderer/onboarding/onboarding-wizard.ts +1 -1
- package/src/renderer/overlay-box.ts +1 -1
- package/src/renderer/panel-composite.ts +5 -5
- package/src/renderer/panel-workspace-bar.ts +1 -1
- package/src/renderer/process-indicator.ts +8 -8
- package/src/renderer/profile-picker-modal.ts +3 -3
- package/src/renderer/prompt-content-width.ts +1 -1
- package/src/renderer/search-overlay.ts +3 -3
- package/src/renderer/selection-modal-overlay.ts +6 -6
- package/src/renderer/semantic-diff.ts +6 -7
- package/src/renderer/session-picker-modal.ts +24 -24
- package/src/renderer/settings-modal-connections.ts +3 -3
- package/src/renderer/settings-modal-helpers.ts +16 -16
- package/src/renderer/settings-modal.ts +10 -10
- package/src/renderer/shell-surface.ts +8 -8
- package/src/renderer/status-glyphs.ts +6 -6
- package/src/renderer/syntax-highlighter.ts +2 -3
- package/src/renderer/system-message.ts +3 -3
- package/src/renderer/tab-strip.ts +2 -2
- package/src/renderer/term-caps.ts +12 -12
- package/src/renderer/terminal-bg-probe.ts +10 -10
- package/src/renderer/terminal-escapes.ts +1 -1
- package/src/renderer/theme-mode-config.ts +3 -3
- package/src/renderer/theme.ts +34 -34
- package/src/renderer/thinking.ts +1 -1
- package/src/renderer/tool-call.ts +5 -5
- package/src/renderer/tool-result-expanded-lines.ts +3 -3
- package/src/renderer/tool-result-summary.ts +6 -6
- package/src/renderer/turn-injection.ts +9 -9
- package/src/renderer/ui-factory.ts +33 -33
- package/src/renderer/ui-primitives.ts +4 -4
- package/src/runtime/bootstrap-command-parts.ts +3 -3
- package/src/runtime/bootstrap-core.ts +21 -21
- package/src/runtime/bootstrap-hook-bridge.ts +8 -8
- package/src/runtime/bootstrap-shell.ts +9 -9
- package/src/runtime/bootstrap.ts +16 -16
- package/src/runtime/client/approval-updates.ts +3 -3
- package/src/runtime/client/build-floors.ts +7 -7
- package/src/runtime/client/daemon-attach-handshake.ts +5 -5
- package/src/runtime/client/fleet-union.ts +7 -7
- package/src/runtime/client/host-service-status.ts +2 -2
- package/src/runtime/client/hosted-exit.ts +4 -4
- package/src/runtime/client/hosted-roster.ts +4 -4
- package/src/runtime/client/hosted-session-stream.ts +5 -5
- package/src/runtime/client/hosted-sessions.ts +8 -8
- package/src/runtime/client/operator-endpoint.ts +14 -14
- package/src/runtime/client/spine-adoption.ts +8 -8
- package/src/runtime/context-accounting-source.ts +4 -4
- package/src/runtime/context.ts +2 -2
- package/src/runtime/conversation-rewind-port.ts +6 -6
- package/src/runtime/credential-composition.ts +2 -2
- package/src/runtime/daemon-attach-notices.ts +6 -6
- package/src/runtime/diagnostics/panels/index.ts +1 -1
- package/src/runtime/diagnostics/panels/ops.ts +2 -2
- package/src/runtime/disposal-wiring.ts +6 -6
- package/src/runtime/index.ts +11 -11
- package/src/runtime/install-self-check-startup.ts +4 -4
- package/src/runtime/install-self-check.ts +6 -6
- package/src/runtime/interaction-seams.ts +4 -4
- package/src/runtime/knowledge-services.ts +2 -2
- package/src/runtime/legacy-daemon-migration.ts +37 -37
- package/src/runtime/legacy-daemon-reconcile.ts +30 -30
- package/src/runtime/memory-governance-services.ts +3 -3
- package/src/runtime/memory-spine-transport.ts +3 -3
- package/src/runtime/notification-dispatch.ts +4 -4
- package/src/runtime/onboarding/apply.ts +1 -1
- package/src/runtime/onboarding/derivation.ts +1 -1
- package/src/runtime/onboarding/fast-path.ts +7 -7
- package/src/runtime/onboarding/progress.ts +2 -2
- package/src/runtime/onboarding/provider-key-capture.ts +4 -4
- package/src/runtime/onboarding/snapshot.ts +2 -2
- package/src/runtime/onboarding/state.ts +4 -4
- package/src/runtime/onboarding/types.ts +4 -4
- package/src/runtime/orchestrator-core-services.ts +5 -5
- package/src/runtime/path-shadow-startup.ts +3 -3
- package/src/runtime/perf/panel-contracts.ts +1 -1
- package/src/runtime/power-keepawake-remote.ts +6 -6
- package/src/runtime/process-lifecycle.ts +14 -14
- package/src/runtime/provider-fallback.ts +3 -3
- package/src/runtime/recovery-autosave.ts +3 -3
- package/src/runtime/recovery-decisions.ts +19 -19
- package/src/runtime/recovery-offer-wiring.ts +4 -4
- package/src/runtime/recovery-prompt.ts +20 -20
- package/src/runtime/relay-reachability-bridge.ts +3 -3
- package/src/runtime/release-artifacts.ts +1 -1
- package/src/runtime/resume-notice.ts +20 -20
- package/src/runtime/runtime-services-types.ts +20 -20
- package/src/runtime/services.ts +20 -20
- package/src/runtime/session-continuity-hints.ts +1 -1
- package/src/runtime/session-inbound-inputs.ts +12 -12
- package/src/runtime/session-resume-liveness-confirm.ts +4 -4
- package/src/runtime/session-spine-transport.ts +3 -3
- package/src/runtime/store/domains/panels.ts +2 -2
- package/src/runtime/store/domains/ui-perf.ts +2 -2
- package/src/runtime/store/index.ts +1 -1
- package/src/runtime/store/selectors/index.ts +1 -1
- package/src/runtime/store/state.ts +2 -2
- package/src/runtime/ui-services.ts +3 -3
- package/src/runtime/workspace-checkpointing.ts +3 -3
- package/src/runtime/wrfc-persistence.ts +15 -15
- package/src/scripts/process-messages.ts +1 -1
- package/src/shell/blocking-input.ts +9 -9
- package/src/shell/recovery-input-helpers.ts +2 -2
- package/src/shell/retry-affordance.ts +9 -9
- package/src/shell/ui-openers.ts +14 -14
- package/src/shell/voice-capture-shell.ts +3 -3
- package/src/tools/wrfc-agent-guard.ts +4 -4
- package/src/utils/browser.ts +2 -2
- package/src/utils/format-duration.ts +3 -3
- package/src/utils/format-number.ts +2 -2
- package/src/utils/splash-lines.ts +4 -4
- package/src/utils/terminal-width.ts +6 -6
- package/src/verification/verification-ledger.ts +25 -25
- package/src/version.ts +3 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* /payments card
|
|
2
|
+
* /payments card, capture a payment card through the composer's concealed
|
|
3
3
|
* input mode, following the same guided-chain pattern as /channel pair
|
|
4
4
|
* (channel-pairing.ts) and the SAME concealed-input mechanism as
|
|
5
5
|
* provider-key-intake.ts (see concealed-input.ts).
|
|
@@ -9,48 +9,48 @@
|
|
|
9
9
|
* masked concealed-input prompt in turn and stored via
|
|
10
10
|
* persistSecretBackedConfigValue, the same secret-manager + config-reference
|
|
11
11
|
* path every other secret-backed setting in this app uses. The plaintext
|
|
12
|
-
* never reaches the transcript, input history, or a log line
|
|
12
|
+
* never reaches the transcript, input history, or a log line, only a
|
|
13
13
|
* redacted confirmation is printed after each field.
|
|
14
14
|
*
|
|
15
15
|
* Billing and shipping address are ordinary (non-secret) config fields, now
|
|
16
16
|
* real structured CONFIG_SCHEMA entries (payments.billingAddress.{name,
|
|
17
17
|
* line1, line2, city, region, postalCode, country} and the shippingAddress
|
|
18
|
-
* equivalents)
|
|
18
|
+
* equivalents), this command points the user at the Payments settings
|
|
19
19
|
* category (or /config payments) to set them, the same way /channel pair
|
|
20
20
|
* directs non-secret credential fields, rather than routing plain text
|
|
21
21
|
* through the concealed (masked) input path where it does not belong.
|
|
22
22
|
*
|
|
23
|
-
* Stored with `scope: 'daemon'`: the daemon
|
|
24
|
-
* client
|
|
23
|
+
* Stored with `scope: 'daemon'`: the daemon, not just this interactive
|
|
24
|
+
* client, is what completes an autonomous purchase, so the credential must
|
|
25
25
|
* land in the daemon-scoped secret tier the daemon actually reads.
|
|
26
26
|
*
|
|
27
27
|
* The config-reference half (the `goodvibes://secrets/...` marker
|
|
28
28
|
* persistSecretBackedConfigValue writes alongside the secret) goes through
|
|
29
|
-
* `ctx.platform.configManager` directly
|
|
29
|
+
* `ctx.platform.configManager` directly, the same real ConfigManager every
|
|
30
30
|
* other command in this app uses, not a TUI-local store. See
|
|
31
31
|
* payments-config.ts's header comment for why these particular keys
|
|
32
32
|
* (`payments.cardNumber`, etc., flat sub-keys under the SDK's real
|
|
33
33
|
* `payments` section) are ConfigManager-safe even though the SDK's
|
|
34
34
|
* CONFIG_SCHEMA has no scalar entry for them yet: `payments.` is a
|
|
35
35
|
* daemon-owned config prefix, so the reference lands in the daemon's own
|
|
36
|
-
* settings file and is visible to the daemon, the webui and the agent
|
|
36
|
+
* settings file and is visible to the daemon, the webui and the agent,
|
|
37
37
|
* not just this TUI session.
|
|
38
38
|
*
|
|
39
39
|
* ── Card details are entered only at a local terminal or the webui ────────
|
|
40
40
|
*
|
|
41
41
|
* Owner ruling (see the SDK's platform/payments/entry-surface.ts): card
|
|
42
|
-
* material may be TYPED only on `tui`, `agent-terminal`, or `webui
|
|
42
|
+
* material may be TYPED only on `tui`, `agent-terminal`, or `webui`, never
|
|
43
43
|
* over Telegram, ntfy, Discord, Slack, WhatsApp, Signal, a webhook, or any
|
|
44
44
|
* other remote messaging surface. A card number typed into a hosted chat is
|
|
45
45
|
* stored on that provider's own servers, in history this app cannot erase,
|
|
46
|
-
* and it already passed through their infrastructure before reaching us
|
|
46
|
+
* and it already passed through their infrastructure before reaching us,
|
|
47
47
|
* our own encryption at rest does nothing for a value copied elsewhere on
|
|
48
48
|
* its way in. This is a SEPARATE question from which surfaces may APPROVE or
|
|
49
49
|
* VETO a purchase (every command-authority channel still can); the two are
|
|
50
50
|
* never merged into one check.
|
|
51
51
|
*
|
|
52
52
|
* This command always runs inside the TUI's own composer (CARD_ENTRY_SURFACE
|
|
53
|
-
* below), which the SDK's allowlist accepts
|
|
53
|
+
* below), which the SDK's allowlist accepts, so this gate changes nothing
|
|
54
54
|
* about today's behavior. What it buys is that the refusal already exists
|
|
55
55
|
* the moment this app (or a shared command registry) ever grows a path that
|
|
56
56
|
* lets `/payments card` be reached from somewhere else: the check is real
|
|
@@ -69,7 +69,7 @@ import {
|
|
|
69
69
|
} from '../payments-config.ts';
|
|
70
70
|
|
|
71
71
|
/**
|
|
72
|
-
* This command is wired only into the TUI's own composer command registry
|
|
72
|
+
* This command is wired only into the TUI's own composer command registry,
|
|
73
73
|
* it is never reachable from a channel bridge (Telegram, Discord, ...), each
|
|
74
74
|
* of which has its own separate command surface in the daemon. The constant
|
|
75
75
|
* still names the surface explicitly and is checked through the SDK's own
|
|
@@ -110,7 +110,7 @@ function renderCardStatus(ctx: CommandContext): string[] {
|
|
|
110
110
|
/** Chain a masked prompt for each card secret field, storing each through the daemon-scoped secret tier. */
|
|
111
111
|
function promptCardFields(ctx: CommandContext, fields: readonly CardField[], index: number): void {
|
|
112
112
|
if (index >= fields.length) {
|
|
113
|
-
ctx.print('\nCard stored. Billing/shipping address and the rest of the payment capability are ordinary config values
|
|
113
|
+
ctx.print('\nCard stored. Billing/shipping address and the rest of the payment capability are ordinary config values; set them via /config payments or the Settings > Payments category.');
|
|
114
114
|
ctx.renderRequest();
|
|
115
115
|
return;
|
|
116
116
|
}
|
|
@@ -119,7 +119,7 @@ function promptCardFields(ctx: CommandContext, fields: readonly CardField[], ind
|
|
|
119
119
|
ctx.print('[payments] Concealed input is unavailable on this surface; card entry requires it and cannot fall back to plaintext.');
|
|
120
120
|
return;
|
|
121
121
|
}
|
|
122
|
-
ctx.print(`[payments] Enter ${field.label} (e.g. ${field.placeholder})
|
|
122
|
+
ctx.print(`[payments] Enter ${field.label} (e.g. ${field.placeholder}): masked; Enter to store, Esc to stop.`);
|
|
123
123
|
ctx.beginConcealedInput({
|
|
124
124
|
label: field.label,
|
|
125
125
|
onSubmit: (value) => {
|
|
@@ -153,7 +153,7 @@ function promptCardFields(ctx: CommandContext, fields: readonly CardField[], ind
|
|
|
153
153
|
/**
|
|
154
154
|
* Start the card-entry flow, gated on the SDK's own entry-surface allowlist
|
|
155
155
|
* rather than an assumption baked into this command. `surface` defaults to
|
|
156
|
-
* this command's real, fixed identity (CARD_ENTRY_SURFACE)
|
|
156
|
+
* this command's real, fixed identity (CARD_ENTRY_SURFACE), exposed as a
|
|
157
157
|
* parameter only so tests can drive the refusal path without needing this
|
|
158
158
|
* app to actually be reachable from a remote channel.
|
|
159
159
|
*/
|
|
@@ -166,11 +166,11 @@ export function startCardEntryFlow(ctx: CommandContext, surface: string = CARD_E
|
|
|
166
166
|
ctx.print('[payments] Concealed input is unavailable on this surface.');
|
|
167
167
|
return;
|
|
168
168
|
}
|
|
169
|
-
ctx.print(`Entering ${CARD_SECRET_FIELDS.length} card field(s)
|
|
169
|
+
ctx.print(`Entering ${CARD_SECRET_FIELDS.length} card field(s): masked; Esc to stop at any point.`);
|
|
170
170
|
promptCardFields(ctx, CARD_SECRET_FIELDS, 0);
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
/** Entry point for `/payments [card|status]
|
|
173
|
+
/** Entry point for `/payments [card|status]`, exported directly so tests can drive it without the registry. */
|
|
174
174
|
export function runPaymentsCommand(args: readonly string[], ctx: CommandContext): void {
|
|
175
175
|
const sub = (args[0] ?? '').toLowerCase();
|
|
176
176
|
if (sub === '' || sub === 'status') {
|
|
@@ -184,7 +184,7 @@ export function runPaymentsCommand(args: readonly string[], ctx: CommandContext)
|
|
|
184
184
|
ctx.print('Usage: /payments [card|status]');
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
/** Card secret fields in prompt order
|
|
187
|
+
/** Card secret fields in prompt order, exported for tests that need to drive the chain field-by-field. */
|
|
188
188
|
export { CARD_SECRET_FIELDS };
|
|
189
189
|
|
|
190
190
|
export function registerPaymentCardCommands(registry: CommandRegistry): void {
|
|
@@ -9,7 +9,7 @@ import { SHIPPED_CREDENTIAL_READ_RULES } from '@pellux/goodvibes-sdk/platform/pe
|
|
|
9
9
|
// Shows every permission-relevant setting in effect AND where each value came
|
|
10
10
|
// from. Provenance is taken from the platform's own ConfigManager.
|
|
11
11
|
// describeConfigKeySource (the recorded on-disk tier: shared / project / global
|
|
12
|
-
// / default)
|
|
12
|
+
// / default), never a guess. Because CLI --config overrides mutate the config
|
|
13
13
|
// in memory WITHOUT touching any file, we additionally compare the live value
|
|
14
14
|
// against the recorded on-disk / built-in-default value: when they diverge, the
|
|
15
15
|
// value was changed at runtime and its true origin is NOT recorded on disk, so
|
|
@@ -34,7 +34,7 @@ export interface PermissionProvenanceRow {
|
|
|
34
34
|
readonly note?: string;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
/** A shipped (SDK-managed, code-embedded) policy rule
|
|
37
|
+
/** A shipped (SDK-managed, code-embedded) policy rule, not driven by any config key, so it has no ConfigKey-based tier. */
|
|
38
38
|
export interface ShippedPolicyRuleRow {
|
|
39
39
|
readonly id: string;
|
|
40
40
|
readonly effect: 'allow' | 'deny';
|
|
@@ -50,8 +50,8 @@ export interface PermissionProvenance {
|
|
|
50
50
|
/**
|
|
51
51
|
* Shipped managed policy rules baked into the SDK's PermissionManager
|
|
52
52
|
* (currently: default-deny reads of well-known credential stores). These
|
|
53
|
-
* are NOT config-key-driven
|
|
54
|
-
* could be recorded in
|
|
53
|
+
* are NOT config-key-driven, there is no on/off setting and no file they
|
|
54
|
+
* could be recorded in, so they cannot use the shared/project/global/
|
|
55
55
|
* default tier model above. Listed separately with an honest "shipped
|
|
56
56
|
* default" origin rather than force-fit into a ConfigKey row.
|
|
57
57
|
*/
|
|
@@ -165,7 +165,7 @@ function buildRow(
|
|
|
165
165
|
} else if (originPath) {
|
|
166
166
|
const fv = fileValue(originPath, key);
|
|
167
167
|
if (!fv || !fv.present) {
|
|
168
|
-
// The tier says this file carries the key, but we could not read it back
|
|
168
|
+
// The tier says this file carries the key, but we could not read it back,
|
|
169
169
|
// do not guess; report the origin as unrecorded.
|
|
170
170
|
return { ...base, origin: `origin not recorded (${tier} config file could not be read back)`, originPath, recorded: false, overridden: false };
|
|
171
171
|
}
|
|
@@ -221,7 +221,7 @@ function displayValue(value: unknown): string {
|
|
|
221
221
|
/** Render the provenance panel as plain lines for the command surface. */
|
|
222
222
|
export function renderPermissionProvenance(provenance: PermissionProvenance): string {
|
|
223
223
|
const lines: string[] = [
|
|
224
|
-
'Permissions
|
|
224
|
+
'Permissions: settings in effect and where each came from',
|
|
225
225
|
` session mode: ${provenance.sessionMode} (${provenance.sessionModeLabel})`,
|
|
226
226
|
'',
|
|
227
227
|
'Every line is traceable to its recorded origin. A value changed at runtime',
|
|
@@ -248,7 +248,7 @@ export function renderPermissionProvenance(provenance: PermissionProvenance): st
|
|
|
248
248
|
|
|
249
249
|
if (provenance.shippedRules.length > 0) {
|
|
250
250
|
lines.push('');
|
|
251
|
-
lines.push('Shipped policy rules
|
|
251
|
+
lines.push('Shipped policy rules: baked into the SDK, not driven by any config key');
|
|
252
252
|
lines.push('(origin: shipped default; a user allow-rule always wins over these):');
|
|
253
253
|
for (const rule of provenance.shippedRules) {
|
|
254
254
|
lines.push(` ${rule.id} [${rule.effect}] tools: ${rule.toolPattern}`);
|
|
@@ -78,7 +78,7 @@ async function revokeRememberedRule(ctx: CommandContext, ruleId: string): Promis
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
/**
|
|
81
|
-
* `/permissions
|
|
81
|
+
* `/permissions`, the permission settings surface. With no arguments it prints
|
|
82
82
|
* every permission-relevant setting in effect and where each value came from
|
|
83
83
|
* (provenance; read-only). `rules` lists the durable remembered approvals with a
|
|
84
84
|
* press-Enter revoke; `revoke <id>` removes one by id. Revokes hit the same
|
|
@@ -9,13 +9,13 @@ import { openModalCommand, requirePlanManager, requireSessionLineageTracker } fr
|
|
|
9
9
|
import { togglePlanMode, permissionModeLabel, type PermissionModeValue } from '../../core/permission-mode.ts';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* Single-token verbs that look like a `/plan` subcommand but are not real ones.
|
|
12
|
+
* Single-token verbs that look like a `/project-plan` subcommand but are not real ones.
|
|
13
13
|
* A lone one of these is refused rather than seeded as a goal, so a stray verb
|
|
14
14
|
* can never overwrite the project goal with itself.
|
|
15
15
|
*
|
|
16
16
|
* `dismiss` and `answer` are now REAL subcommands (handled above this
|
|
17
17
|
* guard), so they were removed from the refuse-list. `pause`/`stop`/`cancel`
|
|
18
|
-
* remain here
|
|
18
|
+
* remain here, they still have no backing verb and must not seed a goal.
|
|
19
19
|
*/
|
|
20
20
|
const PSEUDO_SUBCOMMAND_VERBS = new Set(['pause', 'stop', 'cancel']);
|
|
21
21
|
|
|
@@ -165,7 +165,7 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
165
165
|
if (args[0] === 'show') {
|
|
166
166
|
const id = args[1];
|
|
167
167
|
if (!id) {
|
|
168
|
-
ctx.print('Usage: /plan show <plan-id>');
|
|
168
|
+
ctx.print('Usage: /project-plan show <plan-id>');
|
|
169
169
|
return;
|
|
170
170
|
}
|
|
171
171
|
const plans = planManager.list();
|
|
@@ -178,16 +178,16 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
178
178
|
return;
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
// /plan dismiss
|
|
181
|
+
// /project-plan dismiss, archive the current plan. Dismisses the active
|
|
182
182
|
// execution plan (ExecutionPlanManager.dismiss, honest per-state) AND
|
|
183
183
|
// deactivates the project-planning interview state shown in the modal so a
|
|
184
|
-
// later /plan <goal> starts fresh. Mid-execution is refused outright.
|
|
184
|
+
// later /project-plan <goal> starts fresh. Mid-execution is refused outright.
|
|
185
185
|
if (args[0] === 'dismiss') {
|
|
186
186
|
const dismissal = planManager.dismiss(ctx.session.runtime.sessionId);
|
|
187
187
|
if (dismissal.outcome === 'requires-cancel') {
|
|
188
188
|
ctx.print(
|
|
189
189
|
`Plan "${dismissal.blockedBy?.title ?? 'active plan'}" is mid-execution and was not dismissed. ` +
|
|
190
|
-
`Run /workstream cancel to stop it first, then /plan dismiss.`,
|
|
190
|
+
`Run /workstream cancel to stop it first, then /project-plan dismiss.`,
|
|
191
191
|
);
|
|
192
192
|
return;
|
|
193
193
|
}
|
|
@@ -213,7 +213,7 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
213
213
|
if (dismissal.outcome === 'dismissed') {
|
|
214
214
|
ctx.print(
|
|
215
215
|
`Dismissed plan "${dismissal.plan?.title ?? 'active plan'}" ` +
|
|
216
|
-
`(archived as dismissed; retained in /plan list; /plan <goal> starts fresh).${planningNote}`,
|
|
216
|
+
`(archived as dismissed; retained in /project-plan list; /project-plan <goal> starts fresh).${planningNote}`,
|
|
217
217
|
);
|
|
218
218
|
} else if (planningNote) {
|
|
219
219
|
ctx.print(`No active execution plan to dismiss.${planningNote}`);
|
|
@@ -223,7 +223,7 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
223
223
|
return;
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
-
// /plan answer <n|question-id> <text
|
|
226
|
+
// /project-plan answer <n|question-id> <text>, record a real answer to an
|
|
227
227
|
// open planning question (moves open → answered, consumed on next refine).
|
|
228
228
|
if (args[0] === 'answer') {
|
|
229
229
|
if (!projectPlanningService || !projectId) {
|
|
@@ -233,7 +233,7 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
233
233
|
const ref = args[1];
|
|
234
234
|
const answerText = args.slice(2).join(' ').trim();
|
|
235
235
|
if (!ref || !answerText) {
|
|
236
|
-
ctx.print('Usage: /plan answer <question-number|question-id> <your answer>');
|
|
236
|
+
ctx.print('Usage: /project-plan answer <question-number|question-id> <your answer>');
|
|
237
237
|
return;
|
|
238
238
|
}
|
|
239
239
|
const asNum = Number(ref);
|
|
@@ -243,7 +243,7 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
243
243
|
const answerResult = await projectPlanningService.answerQuestion({ projectId, ...selector, answer: answerText });
|
|
244
244
|
if (!answerResult.answered) {
|
|
245
245
|
if (answerResult.reason === 'no-state') {
|
|
246
|
-
ctx.print('No project planning state exists yet. Seed it with /plan <goal>.');
|
|
246
|
+
ctx.print('No project planning state exists yet. Seed it with /project-plan <goal>.');
|
|
247
247
|
} else if (answerResult.reason === 'question-not-found') {
|
|
248
248
|
const open = answerResult.openQuestions;
|
|
249
249
|
const listing = open.length > 0
|
|
@@ -251,7 +251,7 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
251
251
|
: ' (no open questions)';
|
|
252
252
|
ctx.print(`No open question matched "${ref}". Open questions:\n${listing}`);
|
|
253
253
|
} else {
|
|
254
|
-
ctx.print('Usage: /plan answer <question-number|question-id> <your answer>');
|
|
254
|
+
ctx.print('Usage: /project-plan answer <question-number|question-id> <your answer>');
|
|
255
255
|
}
|
|
256
256
|
return;
|
|
257
257
|
}
|
|
@@ -265,7 +265,7 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
265
265
|
}
|
|
266
266
|
|
|
267
267
|
// Defense (review finding): a single verb-looking token is almost never a
|
|
268
|
-
// real planning goal
|
|
268
|
+
// real planning goal, it is a mistyped or removed subcommand. The
|
|
269
269
|
// Planning modal used to dispatch `/plan dismiss`, which has no
|
|
270
270
|
// subcommand and silently fell through to this free-form branch, seeding
|
|
271
271
|
// the goal with the literal "dismiss". Refuse to seed on a lone
|
|
@@ -273,8 +273,8 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
273
273
|
// corrupting the goal.
|
|
274
274
|
if (args.length === 1 && PSEUDO_SUBCOMMAND_VERBS.has(args[0].toLowerCase())) {
|
|
275
275
|
ctx.print(
|
|
276
|
-
`Unknown /plan subcommand "${args[0]}"
|
|
277
|
-
`To seed a planning goal, use /plan <a real sentence describing the change>.`,
|
|
276
|
+
`Unknown /project-plan subcommand "${args[0]}": did you mean panel, approve, list, show, or status? ` +
|
|
277
|
+
`To seed a planning goal, use /project-plan <a real sentence describing the change>.`,
|
|
278
278
|
);
|
|
279
279
|
return;
|
|
280
280
|
}
|
|
@@ -289,7 +289,7 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
289
289
|
state: {
|
|
290
290
|
goal: taskDescription,
|
|
291
291
|
knownContext: [
|
|
292
|
-
`Workspace planning was seeded from the TUI /plan command.`,
|
|
292
|
+
`Workspace planning was seeded from the TUI /project-plan command.`,
|
|
293
293
|
],
|
|
294
294
|
metadata: {
|
|
295
295
|
active: true,
|
|
@@ -318,13 +318,13 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
318
318
|
});
|
|
319
319
|
|
|
320
320
|
// /plan now enters/toggles the SESSION PERMISSION plan mode (read-only
|
|
321
|
-
// planning posture)
|
|
321
|
+
// planning posture), distinct from the project-planning manager above, which
|
|
322
322
|
// moved to /project-plan (alias /planning). The change goes through the SDK
|
|
323
323
|
// config surface (permissions.mode), the same value the PermissionManager
|
|
324
324
|
// reads and Shift+Tab cycles, so plan mode is one concept across surfaces.
|
|
325
325
|
registry.register({
|
|
326
326
|
name: 'plan',
|
|
327
|
-
description: 'Enter or exit plan mode
|
|
327
|
+
description: 'Enter or exit plan mode, a read-only planning posture where writes, commands, and network calls are blocked',
|
|
328
328
|
usage: '[on | off | toggle]',
|
|
329
329
|
argsHint: '[on|off]',
|
|
330
330
|
handler(args, ctx) {
|
|
@@ -337,8 +337,8 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
337
337
|
: togglePlanMode(current);
|
|
338
338
|
configManager.set('permissions.mode', next);
|
|
339
339
|
ctx.print(next === 'plan'
|
|
340
|
-
? '[Permissions] Plan mode ON
|
|
341
|
-
: `[Permissions] Plan mode OFF
|
|
340
|
+
? '[Permissions] Plan mode ON; read-only: writes, commands, and network calls are blocked until you exit (/plan off or Shift+Tab).'
|
|
341
|
+
: `[Permissions] Plan mode OFF; mode: ${permissionModeLabel(next)}.`);
|
|
342
342
|
},
|
|
343
343
|
});
|
|
344
344
|
}
|
|
@@ -130,7 +130,7 @@ export function registerPlatformServicesRuntimeCommands(registry: CommandRegistr
|
|
|
130
130
|
registry.register({
|
|
131
131
|
name: 'helpers',
|
|
132
132
|
aliases: ['integration-api'],
|
|
133
|
-
description: 'Review local integration helper
|
|
133
|
+
description: 'Review local integration helper APIs for remote clients and future web frontends',
|
|
134
134
|
usage: '[review|bundle export <path>|bundle inspect <path>]',
|
|
135
135
|
handler(args, ctx) {
|
|
136
136
|
const shellPaths = requireShellPaths(ctx);
|
|
@@ -188,7 +188,7 @@ export function registerPlatformServicesRuntimeCommands(registry: CommandRegistr
|
|
|
188
188
|
registry.register({
|
|
189
189
|
name: 'deeplink',
|
|
190
190
|
aliases: ['link'],
|
|
191
|
-
description: 'Review and package deep-link entrypoints for setup and operator
|
|
191
|
+
description: 'Review and package deep-link entrypoints for setup and operator screens',
|
|
192
192
|
usage: '[review|open <surface> [target]|bundle export <path>|bundle inspect <path>]',
|
|
193
193
|
handler(args, ctx) {
|
|
194
194
|
const shellPaths = requireShellPaths(ctx);
|
|
@@ -219,7 +219,7 @@ async function handlePreflight(_args: string[], context: CommandContext): Promis
|
|
|
219
219
|
context.print(`[policy] ${review.summary}`);
|
|
220
220
|
for (const issue of review.issues.slice(0, 8)) {
|
|
221
221
|
const subject = issue.serverName ? ` ${issue.serverName}` : '';
|
|
222
|
-
const detail = issue.detail ?
|
|
222
|
+
const detail = issue.detail ? `: ${issue.detail}` : '';
|
|
223
223
|
context.print(` [${issue.severity.toUpperCase()}] ${issue.source}${subject}: ${issue.message}${detail}`);
|
|
224
224
|
}
|
|
225
225
|
}
|
|
@@ -235,14 +235,14 @@ async function handlePromote(args: string[], context: CommandContext): Promise<v
|
|
|
235
235
|
if (!result.ok) {
|
|
236
236
|
context.print(`[policy] Promotion blocked: ${result.error}`);
|
|
237
237
|
if (result.gate) {
|
|
238
|
-
context.print(`[policy] Gate: ${result.gate.status}
|
|
238
|
+
context.print(`[policy] Gate: ${result.gate.status}; divergence rate ${result.gate.divergenceRate !== undefined ? fmtRate(result.gate.divergenceRate) : 'unknown'} (threshold ${fmtRate(result.gate.threshold)}, ${result.gate.totalEvaluations} evaluations).`);
|
|
239
239
|
}
|
|
240
240
|
return;
|
|
241
241
|
}
|
|
242
242
|
const current = registry.getCurrent();
|
|
243
243
|
context.print(`[policy] Promoted: "${result.bundleId}" is now the active enforcement policy.`);
|
|
244
244
|
if (result.gate) {
|
|
245
|
-
context.print(`[policy] Gate at promotion: ${result.gate.status}
|
|
245
|
+
context.print(`[policy] Gate at promotion: ${result.gate.status}; divergence rate ${result.gate.divergenceRate !== undefined ? fmtRate(result.gate.divergenceRate) : 'unknown'} (threshold ${fmtRate(result.gate.threshold)}).`);
|
|
246
246
|
}
|
|
247
247
|
if (current) context.print(bundleSummary('[policy] Active bundle', current));
|
|
248
248
|
policyState.notify();
|
|
@@ -280,7 +280,7 @@ async function handleStatus(_args: string[], context: CommandContext): Promise<v
|
|
|
280
280
|
const dashboard = policyState.getDashboard();
|
|
281
281
|
if (dashboard) {
|
|
282
282
|
const snap = dashboard.getSnapshot();
|
|
283
|
-
context.print(`[policy] Divergence gate: ${snap.gate.status}
|
|
283
|
+
context.print(`[policy] Divergence gate: ${snap.gate.status}; ${snap.gate.divergenceRate !== undefined ? fmtRate(snap.gate.divergenceRate) : fmtRate(snap.report.overall.divergenceRate)} (${snap.report.overall.totalEvaluations} evaluations).`);
|
|
284
284
|
} else {
|
|
285
285
|
context.print('[policy] No active simulation dashboard.');
|
|
286
286
|
}
|
|
@@ -306,11 +306,11 @@ export function renderPolicyUsage(): string {
|
|
|
306
306
|
// this._state.recordTrendEntry() directly and /policy had no equivalent verb.
|
|
307
307
|
// This exposes it as a thin wrapper: recordTrendEntry() forwards to the attached
|
|
308
308
|
// DivergencePanel, so it only captures a sample while a simulation dashboard is
|
|
309
|
-
// active
|
|
309
|
+
// active, reported honestly here rather than silently no-op'ing.
|
|
310
310
|
function handleRecordTrend(_args: string[], context: CommandContext): void {
|
|
311
311
|
const policyState = getPolicyState(context);
|
|
312
312
|
if (!policyState.getDashboard()) {
|
|
313
|
-
context.print('[policy] No active simulation dashboard
|
|
313
|
+
context.print('[policy] No active simulation dashboard; nothing to sample. Run `/policy simulate` first, then `/policy record-trend`.');
|
|
314
314
|
return;
|
|
315
315
|
}
|
|
316
316
|
policyState.recordTrendEntry();
|
|
@@ -2,20 +2,20 @@ import type { CommandRegistry } from '../command-registry.ts';
|
|
|
2
2
|
import { powerStatusLines } from '../../core/power-status.ts';
|
|
3
3
|
|
|
4
4
|
// ---------------------------------------------------------------------------
|
|
5
|
-
// /power
|
|
5
|
+
// /power, host sleep ownership (the ops/status idiom surface for power.*).
|
|
6
6
|
//
|
|
7
|
-
// Shows the honest account of sleep ownership
|
|
7
|
+
// Shows the honest account of sleep ownership, the "sleep disabled" chip
|
|
8
8
|
// meaning, each "held because X" work-inhibition reason, and the lid-split note
|
|
9
9
|
// rendered VERBATIM when the OS could block idle-sleep but not lid-close
|
|
10
|
-
// suspend
|
|
10
|
+
// suspend, and toggles the daemon-held keep-awake switch. Owner ruling: the
|
|
11
11
|
// always-visible chip IS the safety mechanism, so there is no timer and no
|
|
12
|
-
// AC-only option
|
|
12
|
+
// AC-only option, keep-awake is exactly one on/off toggle.
|
|
13
13
|
// ---------------------------------------------------------------------------
|
|
14
14
|
|
|
15
15
|
export function registerPowerRuntimeCommands(registry: CommandRegistry): void {
|
|
16
16
|
registry.register({
|
|
17
17
|
name: 'power',
|
|
18
|
-
description: 'Host sleep ownership
|
|
18
|
+
description: 'Host sleep ownership: show status and toggle keep-awake',
|
|
19
19
|
usage: '[status | on | off | toggle]',
|
|
20
20
|
argsHint: '[status|on|off|toggle]',
|
|
21
21
|
async handler(args, ctx) {
|
|
@@ -43,7 +43,7 @@ export function registerPowerRuntimeCommands(registry: CommandRegistry): void {
|
|
|
43
43
|
const current = ctx.getPowerState().keepAwake;
|
|
44
44
|
const next = sub === 'on' ? true : sub === 'off' ? false : !current;
|
|
45
45
|
const state = await ctx.setKeepAwake(next);
|
|
46
|
-
const lines = [state.keepAwake ? 'Keep-awake ON
|
|
46
|
+
const lines = [state.keepAwake ? 'Keep-awake ON: this host will not idle-sleep.' : 'Keep-awake OFF.'];
|
|
47
47
|
// Surface the honest lid-split note verbatim if the SDK served one.
|
|
48
48
|
if (state.note) lines.push(` ${state.note}`);
|
|
49
49
|
ctx.print(lines.join('\n'));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* principals-runtime.ts
|
|
3
3
|
*
|
|
4
|
-
* `/principals
|
|
4
|
+
* `/principals`, identity-mapping admin over `principals.*`: named
|
|
5
5
|
* principals (people, bots, services, tokens) and the channel identities
|
|
6
6
|
* ({channel, value} pairs, e.g. {channel:'slack', value:'U123'}) mapped to
|
|
7
7
|
* them. Goes over the operator wire (see operator-rpc.ts) for the same
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* `principals.resolve` is the honest lookup this command exists to make
|
|
12
12
|
* reachable: an unmapped identity resolves to the shared "unknown" principal
|
|
13
|
-
* with `known: false
|
|
13
|
+
* with `known: false`, the registry never guesses, and this command never
|
|
14
14
|
* papers over that with a name that looks real.
|
|
15
15
|
*/
|
|
16
16
|
import type { CommandRegistry } from '../command-registry.ts';
|
|
@@ -199,7 +199,7 @@ export function registerPrincipalsRuntimeCommands(registry: CommandRegistry): vo
|
|
|
199
199
|
try {
|
|
200
200
|
const result = await rpc.sdk.operator.invoke('principals.resolve', { channel, value });
|
|
201
201
|
if (!result.known) {
|
|
202
|
-
ctx.print(`[principals resolve] unknown principal
|
|
202
|
+
ctx.print(`[principals resolve] unknown principal: ${channel}:${value} is not mapped to any registered principal.`);
|
|
203
203
|
return;
|
|
204
204
|
}
|
|
205
205
|
ctx.print(`[principals resolve] ${channel}:${value} -> ${result.principal.name}\n${renderPrincipal(result.principal)}`);
|
|
@@ -167,13 +167,13 @@ export function registerProductRuntimeCommands(registry: CommandRegistry): void
|
|
|
167
167
|
const choice = (args[1] ?? '').toLowerCase();
|
|
168
168
|
if (choice === 'trusted' || choice === 'trust' || choice === 'full' || choice === 'yes') {
|
|
169
169
|
await manager.setLevel('trusted');
|
|
170
|
-
ctx.print('This workspace is now TRUSTED
|
|
170
|
+
ctx.print('This workspace is now TRUSTED; all tools may run, subject to your permission settings.');
|
|
171
171
|
ctx.renderRequest();
|
|
172
172
|
return;
|
|
173
173
|
}
|
|
174
174
|
if (choice === 'restricted' || choice === 'restrict' || choice === 'readonly' || choice === 'read-only' || choice === 'no') {
|
|
175
175
|
await manager.setLevel('restricted');
|
|
176
|
-
ctx.print('This workspace is now RESTRICTED
|
|
176
|
+
ctx.print('This workspace is now RESTRICTED; read-only exploration; write/execute/delegate tools are denied until you run `/trust workspace trusted`.');
|
|
177
177
|
ctx.renderRequest();
|
|
178
178
|
return;
|
|
179
179
|
}
|
|
@@ -189,7 +189,7 @@ export function registerProductRuntimeCommands(registry: CommandRegistry): void
|
|
|
189
189
|
? 'All tools may run, subject to your normal permission settings.'
|
|
190
190
|
: 'Read-only exploration: write, execute, and delegate tools are denied until you trust this workspace.',
|
|
191
191
|
];
|
|
192
|
-
if (!manager.isDecided()) lines.push('Not yet decided
|
|
192
|
+
if (!manager.isDecided()) lines.push('Not yet decided: run `/trust workspace trusted` to enable full capability.');
|
|
193
193
|
const registrationManager = ctx.workspace.workspaceRegistrationManager;
|
|
194
194
|
if (registrationManager) {
|
|
195
195
|
lines.push(`Registration: ${await registrationManager.describe()}`);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* How `/profile` puts the owner profile on screen. Every function here is pure:
|
|
5
5
|
* it takes a checked response (profile-types.ts) and returns a string. Nothing
|
|
6
|
-
* in this file reads a file, opens a connection, or writes to a log
|
|
6
|
+
* in this file reads a file, opens a connection, or writes to a log, which is
|
|
7
7
|
* what makes the containment rule in docs/owner-profile.md §10/§11.3 testable
|
|
8
8
|
* rather than a claim: a profile value can only leave through the string these
|
|
9
9
|
* functions return, and the only thing that consumes that string is `ctx.print`.
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* Two rules the renderers hold to:
|
|
18
18
|
*
|
|
19
19
|
* - **A write never echoes the value.** `renderProfileWriteResult` prints the
|
|
20
|
-
* daemon's own one-line disclosure ("Noted
|
|
20
|
+
* daemon's own one-line disclosure ("Noted, saved your office address to
|
|
21
21
|
* your profile.") and the field names that changed. The value the owner just
|
|
22
22
|
* set is deliberately absent: repeating it puts a closed-tier string into the
|
|
23
23
|
* transcript for no benefit (§8.2).
|
|
@@ -53,7 +53,7 @@ export function describeProfileState(state: ProfileStateView): string | null {
|
|
|
53
53
|
return `Your profile could not be read: ${state.reason ?? 'no reason given'}\n file: ${state.path}`;
|
|
54
54
|
}
|
|
55
55
|
if (state.exists === false) {
|
|
56
|
-
return `Your profile is empty
|
|
56
|
+
return `Your profile is empty: nothing has been recorded yet.\n file: ${state.path}`;
|
|
57
57
|
}
|
|
58
58
|
return null;
|
|
59
59
|
}
|
|
@@ -66,7 +66,7 @@ function padTo(text: string, width: number): string {
|
|
|
66
66
|
* One field row: the label as written in the file, the value, and the field id
|
|
67
67
|
* so `/profile where <id>` and `/profile forget <id>` are copy-pasteable.
|
|
68
68
|
*
|
|
69
|
-
* An invalid value is shown verbatim with its reason rather than hidden
|
|
69
|
+
* An invalid value is shown verbatim with its reason rather than hidden, the
|
|
70
70
|
* owner typed it, and a parser that disliked it is not grounds for pretending it
|
|
71
71
|
* is not there (§4.3).
|
|
72
72
|
*/
|
|
@@ -88,7 +88,7 @@ function renderSection(section: ProfileSectionView): string {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
/**
|
|
91
|
-
* "What do you know about me?"
|
|
91
|
+
* "What do you know about me?", the whole document, by section, in the order
|
|
92
92
|
* the file has it. Sections the owner added himself render exactly like the
|
|
93
93
|
* canonical ones, because his headings are as real as the built-in ones (§4.5).
|
|
94
94
|
*/
|
|
@@ -120,7 +120,7 @@ function renderProvenanceDetail(provenance: ProfileProvenanceView, indent: strin
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
/**
|
|
123
|
-
* "Where did you get that?"
|
|
123
|
+
* "Where did you get that?", the surface, the date and the owner's verbatim
|
|
124
124
|
* words, plus every superseded predecessor still retained as a history comment.
|
|
125
125
|
*
|
|
126
126
|
* A field with no suffix reports that he wrote it by hand. That is the honest
|
|
@@ -135,9 +135,9 @@ export function renderProfileProvenance(report: ProfileProvenanceReportView): st
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
if (!report.present) {
|
|
138
|
-
lines.push(' not currently recorded
|
|
138
|
+
lines.push(' not currently recorded: only superseded history remains:');
|
|
139
139
|
} else if (report.handEdited) {
|
|
140
|
-
lines.push(' no provenance recorded
|
|
140
|
+
lines.push(' no provenance recorded: you wrote or edited this line by hand.');
|
|
141
141
|
} else if (report.provenance) {
|
|
142
142
|
lines.push(...renderProvenanceDetail(report.provenance, ' '));
|
|
143
143
|
} else {
|
|
@@ -149,7 +149,7 @@ export function renderProfileProvenance(report: ProfileProvenanceReportView): st
|
|
|
149
149
|
for (const previous of report.superseded) {
|
|
150
150
|
lines.push(` ${previous.value} (replaced ${previous.supersededOn})`);
|
|
151
151
|
if (previous.provenance) lines.push(...renderProvenanceDetail(previous.provenance, ' '));
|
|
152
|
-
else lines.push(' no provenance recorded
|
|
152
|
+
else lines.push(' no provenance recorded: hand-written.');
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
155
|
return lines.join('\n');
|
|
@@ -167,7 +167,7 @@ function renderChangeNames(result: ProfileWriteResultView): string[] {
|
|
|
167
167
|
/**
|
|
168
168
|
* What a write actually did.
|
|
169
169
|
*
|
|
170
|
-
* `ok: false` prints the daemon's reason and nothing else
|
|
170
|
+
* `ok: false` prints the daemon's reason and nothing else, no "done", no
|
|
171
171
|
* change list, no disclosure. That covers the case §9.2 names explicitly:
|
|
172
172
|
* forgetting something that was not there reports that it was not there.
|
|
173
173
|
*
|
|
@@ -180,7 +180,7 @@ export function renderProfileWriteResult(result: ProfileWriteResultView): string
|
|
|
180
180
|
return `${PROFILE_TAG} ${result.reason ?? 'the write was refused, and the daemon gave no reason.'}`;
|
|
181
181
|
}
|
|
182
182
|
if (result.changes.length === 0) {
|
|
183
|
-
return `${PROFILE_TAG} nothing changed${result.reason ?
|
|
183
|
+
return `${PROFILE_TAG} nothing changed${result.reason ? `: ${result.reason}` : '.'}`;
|
|
184
184
|
}
|
|
185
185
|
const disclosure = result.disclosure.trim();
|
|
186
186
|
const lines = [disclosure.length > 0 ? `${PROFILE_TAG} ${disclosure}` : `${PROFILE_TAG} done.`];
|
|
@@ -214,7 +214,7 @@ export function renderProfileStatus(state: ProfileStateView): string {
|
|
|
214
214
|
if (invalid.length === 0) {
|
|
215
215
|
lines.push(' fields that did not validate: none');
|
|
216
216
|
} else {
|
|
217
|
-
lines.push(` fields that did not validate (${invalid.length})
|
|
217
|
+
lines.push(` fields that did not validate (${invalid.length}): the value is kept as you typed it:`);
|
|
218
218
|
for (const entry of invalid) lines.push(` ${entry.fieldId}: ${entry.reason}`);
|
|
219
219
|
}
|
|
220
220
|
return lines.join('\n');
|
|
@@ -224,7 +224,7 @@ export function renderProfileStatus(state: ProfileStateView): string {
|
|
|
224
224
|
* Every field id present in the document, paired with the label written on its
|
|
225
225
|
* line. Used to resolve `/profile where shipping address` to
|
|
226
226
|
* `commerce.shippingAddress` without keeping a copy of the SDK's field registry
|
|
227
|
-
* here
|
|
227
|
+
* here, the mapping comes from the live response, so it cannot drift.
|
|
228
228
|
*/
|
|
229
229
|
export function collectFieldLabels(document: ProfileDocumentView): ReadonlyMap<string, string[]> {
|
|
230
230
|
const byLabel = new Map<string, string[]>();
|