@pellux/goodvibes-tui 2.0.13 → 2.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.goodvibes/GOODVIBES.md +1 -1
- package/.goodvibes/agents/reviewer.md +8 -8
- package/.goodvibes/skills/add-provider/SKILL.md +22 -22
- package/CHANGELOG.md +61 -0
- package/README.md +40 -29
- package/docs/README.md +1 -1
- package/docs/foundation-artifacts/README.md +5 -5
- package/docs/foundation-artifacts/operator-contract.json +123 -123
- package/package.json +12 -10
- package/scripts/postinstall.js +3 -3
- package/src/audio/activation-sound.ts +7 -7
- package/src/audio/capture.ts +7 -7
- package/src/audio/onnxruntime-assets.d.ts +1 -1
- package/src/audio/player.ts +4 -4
- package/src/audio/spoken-turn-wiring.ts +4 -4
- package/src/audio/voice-capture-wiring.ts +5 -5
- package/src/audio/voice-input-session.ts +3 -3
- package/src/audio/wake-inference.ts +13 -8
- package/src/audio/wake-runtime.ts +10 -10
- package/src/cli/completions/generate.ts +2 -2
- package/src/cli/doctor.ts +13 -13
- package/src/cli/ensure-goodvibes-gitignore.ts +3 -3
- package/src/cli/entrypoint.ts +3 -3
- package/src/cli/help.ts +6 -6
- package/src/cli/hooks-command.ts +4 -4
- package/src/cli/hooks-report.ts +4 -4
- package/src/cli/launch-auto-update.ts +17 -17
- package/src/cli/management-commands.ts +8 -8
- package/src/cli/management-utils.ts +3 -3
- package/src/cli/management.ts +1 -1
- package/src/cli/plugin-bundles-command.ts +10 -10
- package/src/cli/plugin-command.ts +9 -9
- package/src/cli/service-posture.ts +1 -1
- package/src/cli/status.ts +10 -10
- package/src/cli/surface-command.ts +4 -4
- package/src/cli/tui-startup.ts +23 -23
- package/src/config/run-daemon-config-migration.ts +3 -3
- package/src/config/secret-config.ts +10 -10
- package/src/config/surface.ts +1 -1
- package/src/config/tui-extension-settings.ts +8 -8
- package/src/core/active-model-identity.ts +7 -7
- package/src/core/approval-alert.ts +5 -5
- package/src/core/bookmark-navigation.ts +3 -3
- package/src/core/budget-breach-notifier.ts +6 -6
- package/src/core/compaction-receipt.ts +8 -8
- package/src/core/composer-state.ts +2 -2
- package/src/core/context-usage.ts +1 -1
- package/src/core/conversation-compaction-render.ts +3 -3
- package/src/core/conversation-event-navigation.ts +2 -2
- package/src/core/conversation-fold.ts +9 -9
- package/src/core/conversation-line-cache.ts +14 -14
- package/src/core/conversation-render-context.ts +6 -6
- package/src/core/conversation-rendering.ts +27 -30
- package/src/core/conversation-search-expansion.ts +6 -6
- package/src/core/conversation-splash-state.ts +3 -3
- package/src/core/conversation-turn-structure.ts +13 -13
- package/src/core/conversation-types.ts +3 -3
- package/src/core/conversation-user-receipts.ts +5 -5
- package/src/core/conversation.ts +17 -17
- package/src/core/format-user-error.ts +5 -5
- package/src/core/long-task-notifier.ts +9 -9
- package/src/core/memory-diagnostics-gateway.ts +8 -8
- package/src/core/memory-provenance.ts +5 -5
- package/src/core/model-routing-chip.ts +3 -3
- package/src/core/pairing-tailscale-gateway.ts +3 -3
- package/src/core/permission-mode.ts +5 -5
- package/src/core/power-chip-source.ts +3 -3
- package/src/core/power-status.ts +8 -8
- package/src/core/rewind-receipt.ts +6 -6
- package/src/core/session-resume-core.ts +8 -8
- package/src/core/stream-event-wiring.ts +36 -36
- package/src/core/stream-stall-watchdog.ts +4 -4
- package/src/core/system-message-noise.ts +7 -7
- package/src/core/system-message-router.ts +10 -10
- package/src/core/terminal-notifier.ts +5 -5
- package/src/core/turn-budget-outcome.ts +5 -5
- package/src/core/turn-cancellation.ts +3 -3
- package/src/core/turn-event-wiring.ts +16 -16
- package/src/core/voice-capture-status.ts +2 -2
- package/src/core/voice-provision-gateway.ts +12 -12
- package/src/core/voice-provision-status.ts +19 -19
- package/src/core/voice-stt-gateway.ts +6 -6
- package/src/core/wake-provision-runner.ts +7 -7
- package/src/core/wake-provision-status.ts +17 -17
- package/src/core/workstream-notification.ts +8 -8
- package/src/export/gist-uploader.ts +7 -7
- package/src/input/autocomplete.ts +3 -3
- package/src/input/bookmark-modal.ts +1 -1
- package/src/input/command-args-hint.ts +2 -2
- package/src/input/command-reference.ts +9 -9
- package/src/input/command-registry.ts +32 -32
- package/src/input/commands/acp-runtime.ts +6 -6
- package/src/input/commands/calendar-runtime.ts +9 -9
- package/src/input/commands/channel-pairing.ts +11 -11
- package/src/input/commands/channel-runtime.ts +1 -1
- package/src/input/commands/checkin-runtime.ts +4 -4
- package/src/input/commands/checkpoint-runtime.ts +4 -4
- package/src/input/commands/ci-runtime.ts +4 -4
- package/src/input/commands/cluster-runtime.ts +3 -3
- package/src/input/commands/codebase-runtime.ts +16 -16
- package/src/input/commands/config.ts +6 -6
- package/src/input/commands/connection-status.ts +12 -12
- package/src/input/commands/context-window.ts +2 -2
- package/src/input/commands/cost-attribution-format.ts +4 -4
- package/src/input/commands/cost-runtime.ts +2 -2
- package/src/input/commands/devices-runtime.ts +7 -7
- package/src/input/commands/diff-runtime.ts +2 -2
- package/src/input/commands/editor-runtime.ts +1 -1
- package/src/input/commands/eval.ts +4 -4
- package/src/input/commands/experience-runtime.ts +1 -1
- package/src/input/commands/git-runtime.ts +3 -3
- package/src/input/commands/graph-runtime.ts +3 -3
- package/src/input/commands/guidance-runtime.ts +1 -1
- package/src/input/commands/health-metrics-format.ts +2 -2
- package/src/input/commands/health-runtime.ts +8 -8
- package/src/input/commands/hosted-runtime.ts +13 -13
- package/src/input/commands/image-runtime.ts +6 -6
- package/src/input/commands/intelligence-runtime.ts +2 -2
- package/src/input/commands/local-auth-runtime.ts +3 -3
- package/src/input/commands/local-provider-runtime.ts +3 -3
- package/src/input/commands/local-runtime.ts +7 -7
- package/src/input/commands/mail-runtime.ts +9 -9
- package/src/input/commands/mcp-runtime.ts +1 -1
- package/src/input/commands/memory.ts +13 -13
- package/src/input/commands/notify-runtime.ts +1 -1
- package/src/input/commands/operator-panel-runtime.ts +8 -8
- package/src/input/commands/operator-rpc.ts +3 -3
- package/src/input/commands/operator-runtime.ts +3 -3
- package/src/input/commands/palette-runtime.ts +1 -1
- package/src/input/commands/payment-card-intake.ts +17 -17
- package/src/input/commands/permissions-provenance.ts +7 -7
- package/src/input/commands/permissions-runtime.ts +1 -1
- package/src/input/commands/planning-runtime.ts +9 -9
- package/src/input/commands/platform-services-runtime.ts +2 -2
- package/src/input/commands/policy-dispatch.ts +6 -6
- package/src/input/commands/power-runtime.ts +6 -6
- package/src/input/commands/principals-runtime.ts +3 -3
- package/src/input/commands/product-runtime.ts +3 -3
- package/src/input/commands/profile-render.ts +13 -13
- package/src/input/commands/profile-runtime.ts +13 -13
- package/src/input/commands/profile-types.ts +13 -13
- package/src/input/commands/provider-accounts-runtime.ts +5 -5
- package/src/input/commands/provider.ts +10 -10
- package/src/input/commands/qrcode-runtime.ts +3 -3
- package/src/input/commands/queue-runtime.ts +6 -6
- package/src/input/commands/recall-files-config.ts +4 -4
- package/src/input/commands/recall-files-git.ts +3 -3
- package/src/input/commands/recall-files.ts +12 -12
- package/src/input/commands/recall-query.ts +3 -3
- package/src/input/commands/recall-review.ts +3 -3
- package/src/input/commands/recall-shared.ts +1 -1
- package/src/input/commands/relay-runtime.ts +5 -5
- package/src/input/commands/remote-runtime.ts +3 -3
- package/src/input/commands/review-runtime.ts +8 -8
- package/src/input/commands/rewind-runtime.ts +21 -21
- package/src/input/commands/runtime-services.ts +1 -2
- package/src/input/commands/schedule-nl.ts +2 -2
- package/src/input/commands/schedule-runtime.ts +2 -2
- package/src/input/commands/secret-runtime.ts +3 -3
- package/src/input/commands/session-content.ts +7 -7
- package/src/input/commands/session-picker-filter.ts +3 -3
- package/src/input/commands/session-workflow.ts +10 -10
- package/src/input/commands/session.ts +15 -15
- package/src/input/commands/settings-sync-runtime.ts +2 -2
- package/src/input/commands/share-runtime.ts +4 -4
- package/src/input/commands/shell-core.ts +11 -11
- package/src/input/commands/tasks-runtime.ts +4 -4
- package/src/input/commands/test-runtime.ts +6 -6
- package/src/input/commands/tts-runtime.ts +4 -4
- package/src/input/commands/update-runtime.ts +27 -27
- package/src/input/commands/websearch-runtime.ts +2 -2
- package/src/input/commands/work-plan-runtime.ts +2 -2
- package/src/input/commands/workstream-attempt-dependents.ts +4 -4
- package/src/input/commands/workstream-attempts.ts +16 -16
- package/src/input/commands/workstream-runtime.ts +36 -36
- package/src/input/commands/worktree-runtime.ts +6 -6
- package/src/input/composer-capture.ts +5 -5
- package/src/input/concealed-input.ts +2 -2
- package/src/input/config-modal-types.ts +16 -16
- package/src/input/config-modal.ts +30 -30
- package/src/input/daemon-owned-settings-descriptions.ts +4 -4
- package/src/input/delete-key-policy.ts +1 -1
- package/src/input/exec-env-scrub-config.ts +7 -7
- package/src/input/feature-unit-layout.ts +5 -5
- package/src/input/feed-context-factory.ts +38 -38
- package/src/input/file-picker.ts +1 -1
- package/src/input/handler-command-route.ts +2 -2
- package/src/input/handler-content-actions.ts +8 -8
- package/src/input/handler-feed-routes.ts +13 -13
- package/src/input/handler-feed.ts +31 -31
- package/src/input/handler-interactions.ts +2 -2
- package/src/input/handler-modal-routes.ts +13 -13
- package/src/input/handler-modal-stack.ts +1 -1
- package/src/input/handler-modal-token-routes.ts +1 -1
- package/src/input/handler-onboarding-daemon-adopt.ts +6 -6
- package/src/input/handler-picker-routes.ts +7 -7
- package/src/input/handler-prompt-buffer.ts +1 -1
- package/src/input/handler-shortcuts.ts +12 -12
- package/src/input/handler-types.ts +3 -3
- package/src/input/handler-ui-state.ts +1 -1
- package/src/input/handler.ts +9 -9
- package/src/input/input-history.ts +1 -1
- package/src/input/keybindings.ts +13 -13
- package/src/input/kill-ring.ts +7 -11
- package/src/input/model-picker-filter.ts +3 -3
- package/src/input/model-picker-items.ts +5 -5
- package/src/input/model-picker-types.ts +2 -2
- package/src/input/model-picker.ts +18 -18
- package/src/input/onboarding/onboarding-feature-units.ts +9 -13
- package/src/input/onboarding/onboarding-provider-key-fields.ts +3 -3
- package/src/input/onboarding/onboarding-runtime-status.ts +3 -3
- package/src/input/onboarding/onboarding-wizard-apply.ts +6 -6
- package/src/input/onboarding/onboarding-wizard-cloudflare-step.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-constants.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-external-surfaces.ts +4 -4
- package/src/input/onboarding/onboarding-wizard-network-adopt.ts +6 -6
- package/src/input/onboarding/onboarding-wizard-steps.ts +2 -2
- package/src/input/panel-integration-actions.ts +3 -3
- package/src/input/panel-mouse-geometry.ts +1 -1
- package/src/input/panel-paste-flood-guard.ts +9 -9
- package/src/input/payments-config.ts +15 -15
- package/src/input/profile-picker-modal.ts +1 -1
- package/src/input/provider-key-intake.ts +9 -9
- package/src/input/relay-settings-descriptions.ts +3 -3
- package/src/input/sandbox-exec-config.ts +9 -9
- package/src/input/search.ts +18 -18
- package/src/input/selection-modal-queue.ts +10 -10
- package/src/input/selection-modal.ts +2 -2
- package/src/input/session-picker-modal.ts +7 -7
- package/src/input/settings-modal-activation.ts +1 -1
- package/src/input/settings-modal-adjustment.ts +2 -2
- package/src/input/settings-modal-commit.ts +6 -6
- package/src/input/settings-modal-connections.ts +2 -2
- package/src/input/settings-modal-data.ts +29 -29
- package/src/input/settings-modal-mutations.ts +7 -7
- package/src/input/settings-modal-reset.ts +3 -3
- package/src/input/settings-modal-search.ts +6 -6
- package/src/input/settings-modal-secrets.ts +3 -3
- package/src/input/settings-modal-types.ts +16 -16
- package/src/input/settings-modal.ts +4 -4
- package/src/input/voice-local-settings.ts +3 -3
- package/src/input/worktree-setup-config.ts +8 -8
- package/src/main.ts +15 -15
- package/src/panels/agent-inspector-shared.ts +5 -5
- package/src/panels/base-panel.ts +3 -3
- package/src/panels/builtin/agent.ts +3 -3
- package/src/panels/builtin/development.ts +4 -4
- package/src/panels/builtin/knowledge.ts +1 -1
- package/src/panels/builtin/operations.ts +12 -12
- package/src/panels/builtin/session.ts +8 -8
- package/src/panels/builtin/shared.ts +6 -6
- package/src/panels/builtin-modals.ts +8 -8
- package/src/panels/confirm-state.ts +5 -5
- package/src/panels/cost-tracker-panel.ts +22 -22
- package/src/panels/diff-panel.ts +20 -20
- package/src/panels/diff-review-model.ts +5 -5
- package/src/panels/diff-review-panel.ts +5 -5
- package/src/panels/eval-registry.ts +2 -2
- package/src/panels/expandable-list-panel.ts +5 -5
- package/src/panels/fleet-acts.ts +20 -20
- package/src/panels/fleet-deep-link.ts +5 -5
- package/src/panels/fleet-gateway.ts +12 -12
- package/src/panels/fleet-observed-render.ts +11 -11
- package/src/panels/fleet-panel-format.ts +14 -14
- package/src/panels/fleet-panel-worktree-detail.ts +8 -8
- package/src/panels/fleet-panel.ts +34 -34
- package/src/panels/fleet-read-model.ts +49 -49
- package/src/panels/fleet-spawn.ts +15 -15
- package/src/panels/fleet-steer.ts +7 -7
- package/src/panels/fleet-stop.ts +5 -5
- package/src/panels/fleet-tabs.ts +14 -14
- package/src/panels/fleet-transcript.ts +26 -26
- package/src/panels/git-panel.ts +8 -8
- package/src/panels/hosted-session-feed.ts +13 -13
- package/src/panels/hosted-session-panel.ts +7 -7
- package/src/panels/index.ts +1 -1
- package/src/panels/local-auth-panel.ts +15 -15
- package/src/panels/memory-consolidation-gateway.ts +8 -8
- package/src/panels/modals/devices-modal.ts +8 -8
- package/src/panels/modals/hooks-modal.ts +1 -1
- package/src/panels/modals/keybindings-modal.ts +5 -5
- package/src/panels/modals/knowledge-modal.ts +2 -2
- package/src/panels/modals/local-auth-modal.ts +4 -4
- package/src/panels/modals/marketplace-modal.ts +3 -3
- package/src/panels/modals/memory-modal.ts +19 -19
- package/src/panels/modals/modal-surface-helpers.ts +1 -1
- package/src/panels/modals/modal-theme.ts +3 -3
- package/src/panels/modals/pairing-modal.ts +19 -19
- package/src/panels/modals/planning-modal.ts +4 -4
- package/src/panels/modals/plugins-modal.ts +1 -1
- package/src/panels/modals/policy-modal.ts +4 -4
- package/src/panels/modals/provider-health-modal.ts +1 -1
- package/src/panels/modals/remote-modal.ts +1 -1
- package/src/panels/modals/sandbox-modal.ts +2 -2
- package/src/panels/modals/security-modal.ts +4 -4
- package/src/panels/modals/services-modal.ts +1 -1
- package/src/panels/modals/work-plan-modal.ts +4 -4
- package/src/panels/notifications-feed.ts +6 -6
- package/src/panels/notifications-panel.ts +6 -6
- package/src/panels/panel-confirm-overlay.ts +4 -4
- package/src/panels/panel-manager.ts +13 -13
- package/src/panels/plugins-panel.ts +6 -6
- package/src/panels/polish-core.ts +2 -2
- package/src/panels/polish-tables.ts +2 -2
- package/src/panels/polish.ts +1 -1
- package/src/panels/project-planning-answer-actions.ts +3 -3
- package/src/panels/scrollable-list-panel.ts +15 -15
- package/src/panels/search-focus.ts +1 -1
- package/src/panels/session-maintenance.ts +1 -1
- package/src/panels/skills-panel.ts +3 -3
- package/src/panels/token-budget-panel.ts +11 -11
- package/src/panels/types.ts +14 -14
- package/src/panels/workstream-graph-render.ts +5 -5
- package/src/panels/wrfc-panel-format.ts +1 -1
- package/src/permissions/broker-approval-card.ts +13 -13
- package/src/permissions/hunk-selection.ts +13 -13
- package/src/permissions/prompt.ts +22 -22
- package/src/permissions/sandbox-exec-gate.ts +5 -5
- package/src/providers/provider-classification.ts +1 -1
- package/src/providers/reasoning-effort-surface.ts +12 -12
- package/src/renderer/ansi-sanitize.ts +5 -6
- package/src/renderer/autocomplete-overlay.ts +5 -5
- package/src/renderer/block-actions-overlay.ts +1 -1
- package/src/renderer/bookmark-modal.ts +1 -1
- package/src/renderer/code-block.ts +2 -2
- package/src/renderer/compaction-history-modal.ts +4 -4
- package/src/renderer/compaction-preview.ts +5 -5
- package/src/renderer/compaction-quality.ts +5 -5
- package/src/renderer/composer-fragments.ts +6 -6
- package/src/renderer/compositor.ts +9 -9
- package/src/renderer/config-modal.ts +3 -3
- package/src/renderer/context-inspector.ts +1 -1
- package/src/renderer/context-status-hint.ts +10 -10
- package/src/renderer/conversation-layout.ts +2 -2
- package/src/renderer/conversation-overlays.ts +2 -2
- package/src/renderer/conversation-surface.ts +6 -6
- package/src/renderer/diff.ts +4 -4
- package/src/renderer/fleet-tab-strip.ts +2 -2
- package/src/renderer/footer-tips.ts +4 -4
- package/src/renderer/fullscreen-primitives.ts +1 -1
- package/src/renderer/git-status.ts +5 -5
- package/src/renderer/header-line.ts +5 -5
- package/src/renderer/help-overlay.ts +5 -5
- package/src/renderer/hint-grammar.ts +2 -2
- package/src/renderer/layout.ts +1 -1
- package/src/renderer/markdown-inline.ts +3 -3
- package/src/renderer/markdown-table.ts +7 -7
- package/src/renderer/modal-factory.ts +3 -3
- package/src/renderer/model-picker-overlay.ts +2 -2
- package/src/renderer/model-workspace.ts +7 -7
- package/src/renderer/onboarding/onboarding-wizard.ts +1 -1
- package/src/renderer/overlay-box.ts +1 -1
- package/src/renderer/panel-composite.ts +5 -5
- package/src/renderer/panel-workspace-bar.ts +1 -1
- package/src/renderer/process-indicator.ts +8 -8
- package/src/renderer/profile-picker-modal.ts +3 -3
- package/src/renderer/prompt-content-width.ts +1 -1
- package/src/renderer/search-overlay.ts +3 -3
- package/src/renderer/selection-modal-overlay.ts +6 -6
- package/src/renderer/semantic-diff.ts +6 -7
- package/src/renderer/session-picker-modal.ts +24 -24
- package/src/renderer/settings-modal-connections.ts +3 -3
- package/src/renderer/settings-modal-helpers.ts +16 -16
- package/src/renderer/settings-modal.ts +10 -10
- package/src/renderer/shell-surface.ts +8 -8
- package/src/renderer/status-glyphs.ts +6 -6
- package/src/renderer/syntax-highlighter.ts +2 -3
- package/src/renderer/system-message.ts +3 -3
- package/src/renderer/tab-strip.ts +2 -2
- package/src/renderer/term-caps.ts +12 -12
- package/src/renderer/terminal-bg-probe.ts +10 -10
- package/src/renderer/terminal-escapes.ts +1 -1
- package/src/renderer/theme-mode-config.ts +3 -3
- package/src/renderer/theme.ts +34 -34
- package/src/renderer/thinking.ts +1 -1
- package/src/renderer/tool-call.ts +5 -5
- package/src/renderer/tool-result-expanded-lines.ts +3 -3
- package/src/renderer/tool-result-summary.ts +6 -6
- package/src/renderer/turn-injection.ts +9 -9
- package/src/renderer/ui-factory.ts +33 -33
- package/src/renderer/ui-primitives.ts +4 -4
- package/src/runtime/bootstrap-command-parts.ts +3 -3
- package/src/runtime/bootstrap-core.ts +21 -21
- package/src/runtime/bootstrap-hook-bridge.ts +8 -8
- package/src/runtime/bootstrap-shell.ts +9 -9
- package/src/runtime/bootstrap.ts +16 -16
- package/src/runtime/client/approval-updates.ts +3 -3
- package/src/runtime/client/build-floors.ts +7 -7
- package/src/runtime/client/daemon-attach-handshake.ts +5 -5
- package/src/runtime/client/fleet-union.ts +7 -7
- package/src/runtime/client/host-service-status.ts +2 -2
- package/src/runtime/client/hosted-exit.ts +4 -4
- package/src/runtime/client/hosted-roster.ts +4 -4
- package/src/runtime/client/hosted-session-stream.ts +5 -5
- package/src/runtime/client/hosted-sessions.ts +8 -8
- package/src/runtime/client/operator-endpoint.ts +14 -14
- package/src/runtime/client/spine-adoption.ts +8 -8
- package/src/runtime/context-accounting-source.ts +4 -4
- package/src/runtime/context.ts +2 -2
- package/src/runtime/conversation-rewind-port.ts +6 -6
- package/src/runtime/credential-composition.ts +2 -2
- package/src/runtime/daemon-attach-notices.ts +6 -6
- package/src/runtime/diagnostics/panels/index.ts +1 -1
- package/src/runtime/diagnostics/panels/ops.ts +2 -2
- package/src/runtime/disposal-wiring.ts +6 -6
- package/src/runtime/index.ts +11 -11
- package/src/runtime/install-self-check-startup.ts +4 -4
- package/src/runtime/install-self-check.ts +6 -6
- package/src/runtime/interaction-seams.ts +4 -4
- package/src/runtime/knowledge-services.ts +2 -2
- package/src/runtime/legacy-daemon-migration.ts +37 -37
- package/src/runtime/legacy-daemon-reconcile.ts +30 -30
- package/src/runtime/memory-governance-services.ts +3 -3
- package/src/runtime/memory-spine-transport.ts +3 -3
- package/src/runtime/notification-dispatch.ts +4 -4
- package/src/runtime/onboarding/apply.ts +1 -1
- package/src/runtime/onboarding/derivation.ts +1 -1
- package/src/runtime/onboarding/fast-path.ts +7 -7
- package/src/runtime/onboarding/progress.ts +2 -2
- package/src/runtime/onboarding/provider-key-capture.ts +4 -4
- package/src/runtime/onboarding/snapshot.ts +2 -2
- package/src/runtime/onboarding/state.ts +4 -4
- package/src/runtime/onboarding/types.ts +4 -4
- package/src/runtime/orchestrator-core-services.ts +5 -5
- package/src/runtime/path-shadow-startup.ts +3 -3
- package/src/runtime/perf/panel-contracts.ts +1 -1
- package/src/runtime/power-keepawake-remote.ts +6 -6
- package/src/runtime/process-lifecycle.ts +14 -14
- package/src/runtime/provider-fallback.ts +3 -3
- package/src/runtime/recovery-autosave.ts +3 -3
- package/src/runtime/recovery-decisions.ts +19 -19
- package/src/runtime/recovery-offer-wiring.ts +4 -4
- package/src/runtime/recovery-prompt.ts +20 -20
- package/src/runtime/relay-reachability-bridge.ts +3 -3
- package/src/runtime/release-artifacts.ts +1 -1
- package/src/runtime/resume-notice.ts +20 -20
- package/src/runtime/runtime-services-types.ts +20 -20
- package/src/runtime/services.ts +20 -20
- package/src/runtime/session-continuity-hints.ts +1 -1
- package/src/runtime/session-inbound-inputs.ts +12 -12
- package/src/runtime/session-resume-liveness-confirm.ts +4 -4
- package/src/runtime/session-spine-transport.ts +3 -3
- package/src/runtime/store/domains/panels.ts +2 -2
- package/src/runtime/store/domains/ui-perf.ts +2 -2
- package/src/runtime/store/index.ts +1 -1
- package/src/runtime/store/selectors/index.ts +1 -1
- package/src/runtime/store/state.ts +2 -2
- package/src/runtime/ui-services.ts +3 -3
- package/src/runtime/workspace-checkpointing.ts +3 -3
- package/src/runtime/wrfc-persistence.ts +15 -15
- package/src/scripts/process-messages.ts +1 -1
- package/src/shell/blocking-input.ts +9 -9
- package/src/shell/recovery-input-helpers.ts +2 -2
- package/src/shell/retry-affordance.ts +9 -9
- package/src/shell/ui-openers.ts +14 -14
- package/src/shell/voice-capture-shell.ts +3 -3
- package/src/tools/wrfc-agent-guard.ts +4 -4
- package/src/utils/browser.ts +2 -2
- package/src/utils/format-duration.ts +3 -3
- package/src/utils/format-number.ts +2 -2
- package/src/utils/splash-lines.ts +4 -4
- package/src/utils/terminal-width.ts +6 -6
- package/src/verification/verification-ledger.ts +25 -25
- package/src/version.ts +3 -3
|
@@ -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
|
|
@@ -15,7 +15,7 @@ import { togglePlanMode, permissionModeLabel, type PermissionModeValue } from '.
|
|
|
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
|
|
|
@@ -178,7 +178,7 @@ export function registerPlanningRuntimeCommands(registry: CommandRegistry): void
|
|
|
178
178
|
return;
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
// /plan dismiss
|
|
181
|
+
// /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
184
|
// later /plan <goal> starts fresh. Mid-execution is refused outright.
|
|
@@ -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
|
+
// /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) {
|
|
@@ -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,7 +273,7 @@ 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]}"
|
|
276
|
+
`Unknown /plan subcommand "${args[0]}": did you mean panel, approve, list, show, or status? ` +
|
|
277
277
|
`To seed a planning goal, use /plan <a real sentence describing the change>.`,
|
|
278
278
|
);
|
|
279
279
|
return;
|
|
@@ -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[]>();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* profile-runtime.ts
|
|
3
3
|
*
|
|
4
|
-
* `/profile
|
|
4
|
+
* `/profile`, the owner profile in the TUI: what the platform knows about the
|
|
5
5
|
* person who owns it, kept as one hand-editable Markdown file at daemon scope
|
|
6
6
|
* (docs/owner-profile.md).
|
|
7
7
|
*
|
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
*
|
|
15
15
|
* plus `set`, `note`, `undo` and `status` so a correction, a note, a recovery
|
|
16
16
|
* and a diagnosis do not require leaving the terminal or hand-editing the file
|
|
17
|
-
* (which remains allowed, and authoritative
|
|
17
|
+
* (which remains allowed, and authoritative, §4.5).
|
|
18
18
|
*
|
|
19
19
|
* ## Why it goes over the operator wire
|
|
20
20
|
*
|
|
21
21
|
* Same reason `/principals`, `/ci` and `/checkin` do (see operator-rpc.ts): the
|
|
22
22
|
* `profile.*` family ships in the operator contract and has not been promoted to
|
|
23
|
-
* the in-process `OperatorClient` facade. Surfaces never open the profile file
|
|
23
|
+
* the in-process `OperatorClient` facade. Surfaces never open the profile file,
|
|
24
24
|
* the daemon is the single writer, which is what makes its rename-based atomic
|
|
25
25
|
* writes sufficient with no lock (§3, §5.4). This command therefore has no file
|
|
26
26
|
* path, no parser and no writer of its own, and could not corrupt the document
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
*
|
|
31
31
|
* Values reach exactly one place: the string handed to `ctx.print`. This module
|
|
32
32
|
* imports no logger, builds no diagnostic payload, and never puts a value in an
|
|
33
|
-
* error message
|
|
33
|
+
* error message, a failed call renders `describeOperatorRpcError`, which
|
|
34
34
|
* describes the transport, not the content. A write prints the daemon's
|
|
35
35
|
* one-line disclosure and the field names that changed, never the value that was
|
|
36
36
|
* just recorded (§8.2). The `People` section is third-party personal data and is
|
|
@@ -80,7 +80,7 @@ const USAGE = [
|
|
|
80
80
|
' in the file (e.g. "shipping address") once that field is recorded. /profile show',
|
|
81
81
|
' prints each field id beside its value.',
|
|
82
82
|
'',
|
|
83
|
-
' Notes in People, Places, Work and Notes have no field id
|
|
83
|
+
' Notes in People, Places, Work and Notes have no field id; forget those with',
|
|
84
84
|
' --section and the line as /profile show prints it. The leading "-" is optional;',
|
|
85
85
|
' the rest must match, and if two notes read the same nothing is removed.',
|
|
86
86
|
].join('\n');
|
|
@@ -118,7 +118,7 @@ export interface ProfileCommandDeps {
|
|
|
118
118
|
const DEFAULT_DEPS: ProfileCommandDeps = { resolveRpc: getOperatorRpc };
|
|
119
119
|
|
|
120
120
|
function unrecognizedResponse(verb: string): string {
|
|
121
|
-
return `${PROFILE_TAG} the daemon answered ${verb} with a response this build does not recognise
|
|
121
|
+
return `${PROFILE_TAG} the daemon answered ${verb} with a response this build does not recognise; it is probably running a different platform version. Nothing was read or written.`;
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
/**
|
|
@@ -126,7 +126,7 @@ function unrecognizedResponse(verb: string): string {
|
|
|
126
126
|
*
|
|
127
127
|
* A dotted token is already an id and is passed through untouched. A bare label
|
|
128
128
|
* ("shipping address") is matched against the labels in the live `profile.read`
|
|
129
|
-
* response
|
|
129
|
+
* response, deliberately NOT against a copy of the SDK's field registry, which
|
|
130
130
|
* would be a second list to keep in step with the first. A label that matches
|
|
131
131
|
* nothing is passed through unchanged so the daemon answers with its own message
|
|
132
132
|
* naming what is wrong, rather than this command guessing.
|
|
@@ -205,7 +205,7 @@ async function runWrite<TVerb extends ProfileWriteVerb, TBody extends ProfileInp
|
|
|
205
205
|
/**
|
|
206
206
|
* `--section <name>` followed by free text, shared by `/profile note` and
|
|
207
207
|
* `/profile forget`. Section defaults to Notes, which is only meaningful for
|
|
208
|
-
* `note
|
|
208
|
+
* `note`, `forget` calls this solely when `--section` was given.
|
|
209
209
|
*/
|
|
210
210
|
function parseSectionArgs(args: readonly string[]): { section: string; text: string } {
|
|
211
211
|
if (args[1] === '--section' && typeof args[2] === 'string' && args[2].length > 0) {
|
|
@@ -235,12 +235,12 @@ export function registerProfileRuntimeCommands(
|
|
|
235
235
|
//
|
|
236
236
|
// where/forget/undo take the whole remainder as the field, so a label
|
|
237
237
|
// written with a space ("shipping address") works unquoted. `set` cannot
|
|
238
|
-
// do that
|
|
238
|
+
// do that, everything after the first token is the value, so a label
|
|
239
239
|
// there must be one word, or the field id.
|
|
240
240
|
const fieldToken = sub === 'set' ? args[1] : args.slice(1).join(' ').trim();
|
|
241
241
|
|
|
242
242
|
// `/profile forget --section <name> <text>` removes a prose bullet, which
|
|
243
|
-
// is the only way to forget a line in People, Places, Work or Notes
|
|
243
|
+
// is the only way to forget a line in People, Places, Work or Notes,
|
|
244
244
|
// those sections have no mechanical fields at all (§4.3), so without this
|
|
245
245
|
// "forget that" would answer for a shipping address but not for a note
|
|
246
246
|
// about a person. The line is named by its exact text, never by position:
|
|
@@ -272,7 +272,7 @@ export function registerProfileRuntimeCommands(
|
|
|
272
272
|
return;
|
|
273
273
|
}
|
|
274
274
|
// `methodId as string` is what picks the generic overload, so the result
|
|
275
|
-
// stays `unknown` and has to go through a checker
|
|
275
|
+
// stays `unknown` and has to go through a checker, see ProfileInvoke.
|
|
276
276
|
const invoke: ProfileInvoke = (methodId, input) =>
|
|
277
277
|
rpc.sdk.operator.invoke(methodId as string, input as unknown as Record<string, unknown>);
|
|
278
278
|
const print = (text: string): void => { ctx.print(text); };
|
|
@@ -309,8 +309,8 @@ export function registerProfileRuntimeCommands(
|
|
|
309
309
|
// outright. An earlier build defaulted it to owner-direct instead, and
|
|
310
310
|
// stating the claim rather than leaning on that default is precisely
|
|
311
311
|
// why this command kept working when it was tightened. It is the only
|
|
312
|
-
// gate `forget` and `undo` have
|
|
313
|
-
// removal
|
|
312
|
+
// gate `forget` and `undo` have, layers 2 and 3 do not apply to a
|
|
313
|
+
// removal, so it is not a field to leave to anyone else's default.
|
|
314
314
|
//
|
|
315
315
|
// This surface can hardcode it; the agent must not. The TUI's only
|
|
316
316
|
// input is the owner at his own keyboard, whereas the agent can be
|