@pellux/goodvibes-tui 1.27.1 → 2.0.2
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/CHANGELOG.md +127 -2
- package/README.md +7 -9
- package/bin/goodvibes +2 -2
- package/bin/launcher-support.js +8 -4
- package/docs/README.md +11 -2
- package/docs/foundation-artifacts/operator-contract.json +6403 -2347
- package/package.json +14 -25
- package/scripts/postinstall.js +35 -35
- package/src/audio/spoken-turn-model-routing.ts +1 -1
- package/src/cli/bundle-command.ts +5 -5
- package/src/cli/completions/generate.ts +1 -1
- package/src/cli/doctor.ts +3 -3
- package/src/cli/entrypoint.ts +12 -7
- package/src/cli/help.ts +4 -5
- package/src/cli/hooks-command.ts +1 -1
- package/src/cli/index.ts +1 -4
- package/src/cli/launch-auto-update.ts +59 -7
- package/src/cli/management-commands.ts +6 -6
- package/src/cli/management-utils.ts +5 -5
- package/src/cli/management.ts +7 -7
- package/src/cli/network-posture.ts +1 -1
- package/src/cli/package-verification.ts +7 -6
- package/src/cli/plugin-bundles-command.ts +1 -1
- package/src/cli/plugin-command.ts +2 -2
- package/src/cli/service-command.ts +2 -2
- package/src/cli/service-posture.ts +4 -4
- package/src/cli/status.ts +9 -8
- package/src/cli/surface-command.ts +4 -4
- package/src/cli/tui-startup.ts +3 -3
- package/src/cli-flags.ts +3 -3
- package/src/config/goodvibes-home-audit.ts +0 -2
- package/src/config/secret-config.ts +37 -5
- package/src/config/tui-extension-settings.ts +1 -1
- package/src/core/approval-alert.ts +2 -2
- package/src/core/budget-breach-notifier.ts +3 -3
- package/src/core/conversation-compaction-render.ts +1 -1
- package/src/core/conversation-line-cache.ts +1 -1
- package/src/core/conversation-render-context.ts +1 -1
- package/src/core/conversation-rendering.ts +2 -2
- package/src/core/conversation.ts +10 -10
- package/src/core/long-task-notifier.ts +2 -2
- package/src/core/memory-diagnostics-gateway.ts +1 -1
- package/src/core/scriptable-statusline.ts +1 -1
- package/src/core/session-auto-titler.ts +1 -1
- package/src/core/session-resume-core.ts +2 -2
- package/src/core/stream-event-wiring.ts +24 -44
- package/src/core/terminal-notifier.ts +3 -3
- package/src/core/turn-cancellation.ts +1 -1
- package/src/core/turn-event-wiring.ts +5 -5
- package/src/input/command-registry.ts +6 -6
- package/src/input/commands/channel-pairing.ts +1 -1
- package/src/input/commands/cluster-runtime.ts +1 -1
- package/src/input/commands/codebase-runtime.ts +1 -1
- package/src/input/commands/devices-runtime.ts +1 -1
- package/src/input/commands/hosted-runtime.ts +330 -0
- package/src/input/commands/local-setup-review.ts +1 -1
- package/src/input/commands/local-setup-transfer.ts +2 -2
- package/src/input/commands/local-setup.ts +3 -3
- package/src/input/commands/managed-runtime.ts +2 -2
- package/src/input/commands/operator-rpc.ts +24 -110
- package/src/input/commands/payment-card-intake.ts +1 -1
- package/src/input/commands/permissions-provenance.ts +2 -2
- package/src/input/commands/plugin-runtime.ts +1 -1
- package/src/input/commands/provider.ts +1 -1
- package/src/input/commands/relay-runtime.ts +18 -9
- package/src/input/commands/rewind-runtime.ts +1 -1
- package/src/input/commands/runtime-services.ts +1 -1
- package/src/input/commands/services-runtime.ts +1 -1
- package/src/input/commands/session-workflow.ts +1 -1
- package/src/input/commands/settings-sync-runtime.ts +2 -2
- package/src/input/commands/share-runtime.ts +1 -1
- package/src/input/commands/tasks-runtime.ts +145 -55
- package/src/input/commands/update-runtime.ts +31 -28
- package/src/input/commands/work-plan-runtime.ts +2 -2
- package/src/input/commands/workstream-attempts.ts +1 -1
- package/src/input/commands/workstream-runtime.ts +2 -2
- package/src/input/commands.ts +2 -0
- package/src/input/feature-unit-layout.ts +1 -1
- package/src/input/feed-context-factory.ts +3 -3
- package/src/input/handler-content-actions.ts +2 -2
- package/src/input/handler-feed-routes.ts +1 -1
- package/src/input/handler-feed.ts +3 -3
- package/src/input/handler-modal-token-routes.ts +1 -1
- package/src/input/handler-onboarding-daemon-adopt.ts +3 -2
- package/src/input/handler-onboarding.ts +1 -1
- package/src/input/handler-types.ts +2 -2
- package/src/input/handler-ui-state.ts +1 -1
- package/src/input/handler.ts +4 -4
- package/src/input/input-history.ts +1 -1
- package/src/input/onboarding/onboarding-feature-units.ts +2 -2
- package/src/input/onboarding/onboarding-runtime-status.ts +15 -1
- package/src/input/onboarding/onboarding-wizard-apply.ts +17 -8
- package/src/input/onboarding/onboarding-wizard-cloudflare-step.ts +5 -3
- package/src/input/onboarding/onboarding-wizard-external-surfaces.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-types.ts +1 -1
- package/src/input/payments-config.ts +6 -6
- package/src/input/search.ts +1 -1
- package/src/input/session-picker-modal.ts +46 -0
- package/src/input/settings-modal-activation.ts +1 -1
- package/src/input/settings-modal-behavior.ts +4 -4
- package/src/input/settings-modal-commit.ts +11 -0
- package/src/input/settings-modal-data.ts +9 -122
- package/src/input/settings-modal-mutations.ts +33 -0
- package/src/input/settings-modal-secrets.ts +34 -0
- package/src/input/settings-modal-subscriptions.ts +1 -1
- package/src/input/settings-modal-types.ts +15 -1
- package/src/input/settings-modal.ts +28 -3
- package/src/input/worktree-setup-config.ts +1 -1
- package/src/main.ts +11 -9
- package/src/panels/agent-inspector-shared.ts +2 -2
- package/src/panels/base-panel.ts +2 -2
- package/src/panels/builtin/operations.ts +6 -8
- package/src/panels/builtin/session.ts +17 -0
- package/src/panels/builtin/shared.ts +5 -5
- package/src/panels/builtin-modals.ts +3 -3
- package/src/panels/confirm-state.ts +1 -1
- package/src/panels/cost-tracker-panel.ts +4 -4
- package/src/panels/diff-panel.ts +2 -2
- package/src/panels/diff-review-panel.ts +2 -2
- package/src/panels/expandable-list-panel.ts +2 -2
- package/src/panels/fleet-acts.ts +1 -1
- package/src/panels/fleet-observed-render.ts +1 -1
- package/src/panels/fleet-panel-format.ts +1 -1
- package/src/panels/fleet-panel.ts +1 -1
- package/src/panels/fleet-spawn.ts +1 -1
- package/src/panels/fleet-steer.ts +1 -1
- package/src/panels/fleet-transcript.ts +1 -1
- package/src/panels/git-panel.ts +1 -1
- package/src/panels/hosted-session-feed.ts +352 -0
- package/src/panels/hosted-session-panel.ts +221 -0
- package/src/panels/local-auth-panel.ts +3 -3
- package/src/panels/modals/devices-modal.ts +1 -1
- package/src/panels/modals/local-auth-modal.ts +1 -1
- package/src/panels/modals/pairing-modal.ts +1 -1
- package/src/panels/modals/services-modal.ts +1 -1
- package/src/panels/modals/settings-sync-modal.ts +1 -1
- package/src/panels/modals/subscription-modal.ts +1 -1
- package/src/panels/modals/work-plan-modal.ts +1 -1
- package/src/panels/notifications-panel.ts +1 -1
- package/src/panels/panel-confirm-overlay.ts +1 -1
- package/src/panels/plugins-panel.ts +2 -2
- package/src/panels/polish-core.ts +2 -2
- package/src/panels/polish-tables.ts +1 -1
- package/src/panels/polish.ts +2 -2
- package/src/panels/scrollable-list-panel.ts +3 -3
- package/src/panels/skills-panel.ts +3 -3
- package/src/panels/token-budget-panel.ts +5 -5
- package/src/panels/types.ts +1 -2
- package/src/permissions/prompt.ts +1 -1
- package/src/renderer/autocomplete-overlay.ts +1 -1
- package/src/renderer/block-actions-overlay.ts +1 -1
- package/src/renderer/bookmark-modal.ts +1 -1
- package/src/renderer/buffer.ts +1 -1
- package/src/renderer/code-block.ts +1 -1
- package/src/renderer/composer-fragments.ts +1 -1
- package/src/renderer/compositor.ts +2 -2
- package/src/renderer/config-modal.ts +1 -1
- package/src/renderer/context-inspector.ts +1 -1
- package/src/renderer/conversation-layout.ts +2 -2
- package/src/renderer/conversation-overlays.ts +1 -1
- package/src/renderer/conversation-surface.ts +2 -2
- package/src/renderer/diff-view.ts +1 -1
- package/src/renderer/diff.ts +1 -1
- package/src/renderer/file-picker-overlay.ts +1 -1
- package/src/renderer/fleet-tab-strip.ts +1 -1
- package/src/renderer/fullscreen-primitives.ts +2 -2
- package/src/renderer/fullscreen-workspace.ts +1 -1
- package/src/renderer/header-line.ts +1 -1
- package/src/renderer/help-overlay.ts +1 -1
- package/src/renderer/history-search-overlay.ts +2 -2
- package/src/renderer/layout.ts +5 -8
- package/src/renderer/markdown-inline.ts +1 -1
- package/src/renderer/markdown-table.ts +1 -1
- package/src/renderer/markdown.ts +1 -1
- package/src/renderer/mcp-workspace.ts +1 -1
- package/src/renderer/modal-factory.ts +2 -2
- package/src/renderer/model-workspace.ts +2 -2
- package/src/renderer/onboarding/onboarding-wizard.ts +1 -1
- package/src/renderer/overlay-box.ts +1 -1
- package/src/renderer/panel-composite.ts +1 -1
- package/src/renderer/panel-workspace-bar.ts +1 -1
- package/src/renderer/process-indicator.ts +1 -1
- package/src/renderer/profile-picker-modal.ts +1 -1
- package/src/renderer/search-overlay.ts +2 -2
- package/src/renderer/selection-modal-overlay.ts +1 -1
- package/src/renderer/session-picker-modal.ts +124 -3
- package/src/renderer/settings-modal-helpers.ts +2 -0
- package/src/renderer/settings-modal.ts +2 -2
- package/src/renderer/shell-surface.ts +2 -2
- package/src/renderer/system-message.ts +1 -1
- package/src/renderer/tab-strip.ts +1 -1
- package/src/renderer/theme-mode-config.ts +21 -33
- package/src/renderer/theme.ts +11 -12
- package/src/renderer/thinking.ts +1 -1
- package/src/renderer/tool-call.ts +2 -2
- package/src/renderer/tool-result-expanded-lines.ts +1 -1
- package/src/renderer/turn-injection.ts +7 -8
- package/src/renderer/ui-factory.ts +3 -3
- package/src/runtime/bootstrap-command-context.ts +4 -4
- package/src/runtime/bootstrap-command-parts.ts +5 -5
- package/src/runtime/bootstrap-core.ts +30 -30
- package/src/runtime/bootstrap-shell.ts +4 -4
- package/src/runtime/bootstrap.ts +128 -157
- package/src/runtime/client/approval-updates.ts +82 -0
- package/src/runtime/client/build-floors.ts +167 -0
- package/src/runtime/client/daemon-attach-handshake.ts +115 -0
- package/src/runtime/client/fleet-union.ts +147 -0
- package/src/runtime/client/host-service-status.ts +71 -0
- package/src/runtime/client/hosted-exit.ts +86 -0
- package/src/runtime/client/hosted-roster.ts +110 -0
- package/src/runtime/client/hosted-session-stream.ts +178 -0
- package/src/runtime/client/hosted-sessions.ts +187 -0
- package/src/runtime/client/operator-endpoint.ts +213 -0
- package/src/runtime/client/spine-adoption.ts +99 -0
- package/src/runtime/cloudflare-control-plane.ts +1 -1
- package/src/runtime/context-accounting-source.ts +1 -1
- package/src/runtime/context.ts +2 -2
- package/src/runtime/conversation-rewind-port.ts +42 -14
- package/src/runtime/daemon-attach-notices.ts +55 -19
- package/src/runtime/diagnostics/panels/ops.ts +1 -1
- package/src/runtime/disposal-wiring.ts +4 -24
- package/src/runtime/index.ts +119 -105
- package/src/runtime/install-self-check-startup.ts +2 -2
- package/src/runtime/interaction-seams.ts +1 -1
- package/src/runtime/knowledge-services.ts +8 -2
- package/src/runtime/legacy-daemon-migration.ts +4 -3
- package/src/runtime/legacy-daemon-reconcile.ts +3 -2
- package/src/runtime/memory-spine-transport.ts +37 -267
- package/src/runtime/notification-dispatch.ts +2 -2
- package/src/runtime/onboarding/apply.ts +2 -2
- package/src/runtime/onboarding/derivation.ts +2 -2
- package/src/runtime/onboarding/markers.ts +2 -2
- package/src/runtime/onboarding/progress.ts +2 -2
- package/src/runtime/onboarding/snapshot.ts +1 -1
- package/src/runtime/onboarding/state.ts +2 -2
- package/src/runtime/onboarding/types.ts +2 -2
- package/src/runtime/orchestrator-core-services.ts +1 -1
- package/src/runtime/path-shadow-startup.ts +28 -221
- package/src/runtime/power-keepawake-remote.ts +3 -2
- package/src/runtime/process-lifecycle.ts +2 -2
- package/src/runtime/provider-fallback.ts +10 -66
- package/src/runtime/recovery-autosave.ts +1 -1
- package/src/runtime/recovery-offer-wiring.ts +39 -23
- package/src/runtime/recovery-prompt.ts +31 -17
- package/src/runtime/relay-reachability-bridge.ts +53 -42
- package/src/runtime/release-artifacts.ts +2 -1
- package/src/runtime/runtime-services-types.ts +82 -35
- package/src/runtime/services.ts +305 -300
- package/src/runtime/session-resume-liveness-confirm.ts +1 -1
- package/src/runtime/ui-services.ts +7 -6
- package/src/runtime/update-check.ts +23 -43
- package/src/runtime/workspace-checkpointing.ts +1 -1
- package/src/runtime/wrfc-persistence.ts +2 -2
- package/src/shell/ui-openers.ts +30 -7
- package/src/utils/clipboard.ts +1 -1
- package/src/verification/verification-ledger.ts +10 -8
- package/src/version.ts +1 -1
- package/bin/goodvibes-daemon +0 -90
- package/src/cli/config-overrides.ts +0 -267
- package/src/cli/endpoints.ts +0 -109
- package/src/cli/parser.ts +0 -395
- package/src/cli/redaction.ts +0 -170
- package/src/cli/types.ts +0 -84
- package/src/cluster/commands.ts +0 -382
- package/src/cluster/remote-daemon-target.ts +0 -225
- package/src/cluster/render.ts +0 -268
- package/src/config/atomic-write.ts +0 -70
- package/src/config/credential-availability.ts +0 -122
- package/src/config/goodvibes-home.ts +0 -149
- package/src/config/index.ts +0 -88
- package/src/config/provider-model.ts +0 -23
- package/src/config/read-versioned.ts +0 -228
- package/src/core/alert-gating.ts +0 -67
- package/src/core/consolidation-receipt.ts +0 -41
- package/src/core/focus-tracker.ts +0 -41
- package/src/core/history.ts +0 -45
- package/src/core/memory-status.ts +0 -118
- package/src/core/orchestrator.ts +0 -7
- package/src/core/pairing-devices.ts +0 -49
- package/src/core/pairing-handoff.ts +0 -101
- package/src/core/pairing-offers.ts +0 -83
- package/src/core/pairing-origin.ts +0 -78
- package/src/core/rewind-turn-anchors.ts +0 -311
- package/src/core/session-recovery.ts +0 -210
- package/src/core/stable-host.ts +0 -171
- package/src/core/transcript-journal.ts +0 -503
- package/src/daemon/cli.ts +0 -693
- package/src/daemon/fatal-boot-report.ts +0 -111
- package/src/daemon/handlers/context.ts +0 -29
- package/src/daemon/handlers/contracts.ts +0 -77
- package/src/daemon/handlers/credentials.ts +0 -139
- package/src/daemon/handlers/drafts/draft-store.ts +0 -427
- package/src/daemon/handlers/drafts/index.ts +0 -17
- package/src/daemon/handlers/drafts/register.ts +0 -331
- package/src/daemon/handlers/errors.ts +0 -18
- package/src/daemon/handlers/inbox/cursor-store.ts +0 -457
- package/src/daemon/handlers/inbox/index.ts +0 -284
- package/src/daemon/handlers/inbox/mapping.ts +0 -192
- package/src/daemon/handlers/inbox/poller.ts +0 -212
- package/src/daemon/handlers/inbox/provider-adapter.ts +0 -156
- package/src/daemon/handlers/inbox/providers/discord.ts +0 -252
- package/src/daemon/handlers/inbox/providers/email.ts +0 -152
- package/src/daemon/handlers/inbox/providers/imap-client.ts +0 -300
- package/src/daemon/handlers/inbox/providers/route-util.ts +0 -24
- package/src/daemon/handlers/inbox/providers/slack.ts +0 -263
- package/src/daemon/handlers/index.ts +0 -117
- package/src/daemon/handlers/register.ts +0 -168
- package/src/daemon/handlers/remote/backends/cloud-terminal.ts +0 -142
- package/src/daemon/handlers/remote/backends/docker.ts +0 -79
- package/src/daemon/handlers/remote/backends/index.ts +0 -40
- package/src/daemon/handlers/remote/backends/local-process.ts +0 -113
- package/src/daemon/handlers/remote/backends/process-runner.ts +0 -127
- package/src/daemon/handlers/remote/backends/ssh.ts +0 -125
- package/src/daemon/handlers/remote/backends/types.ts +0 -97
- package/src/daemon/handlers/remote/dispatcher.ts +0 -181
- package/src/daemon/handlers/remote/index.ts +0 -119
- package/src/daemon/handlers/remote/peer-registry.ts +0 -357
- package/src/daemon/handlers/remote/service.ts +0 -191
- package/src/daemon/handlers/routing/inbox-bridge.ts +0 -71
- package/src/daemon/handlers/routing/index.ts +0 -261
- package/src/daemon/handlers/routing/route-store.ts +0 -319
- package/src/daemon/handlers/routing/routing-resolver.ts +0 -75
- package/src/daemon/handlers/sqlite-store.ts +0 -278
- package/src/daemon/handlers/triage/index.ts +0 -57
- package/src/daemon/handlers/triage/integration.ts +0 -213
- package/src/daemon/handlers/triage/pipeline.ts +0 -274
- package/src/daemon/handlers/triage/scorer.ts +0 -287
- package/src/daemon/handlers/triage/tagger/discord.ts +0 -187
- package/src/daemon/handlers/triage/tagger/imap.ts +0 -384
- package/src/daemon/handlers/triage/tagger/index.ts +0 -184
- package/src/daemon/handlers/triage/tagger/shared.ts +0 -70
- package/src/daemon/handlers/triage/tagger/slack.ts +0 -69
- package/src/daemon/handlers/triage/types.ts +0 -50
- package/src/daemon/lifecycle.ts +0 -41
- package/src/daemon/provision-wake-model.ts +0 -81
- package/src/daemon/safe-serve.ts +0 -61
- package/src/daemon/send/channels.ts +0 -200
- package/src/daemon/send/command.ts +0 -332
- package/src/daemon/send/composition.ts +0 -99
- package/src/daemon/send/failure-text.ts +0 -93
- package/src/daemon/send/inert-text.ts +0 -225
- package/src/daemon/send/stdin.ts +0 -24
- package/src/daemon/service-commands.ts +0 -329
- package/src/export/cost-utils.ts +0 -319
- package/src/input/selection.ts +0 -135
- package/src/plugins/loader.ts +0 -15
- package/src/renderer/bottom-bar.ts +0 -58
- package/src/renderer/conversation-tree.ts +0 -228
- package/src/runtime/agent-graph-composition.ts +0 -78
- package/src/runtime/channel-composition.ts +0 -46
- package/src/runtime/cluster-composition.ts +0 -124
- package/src/runtime/cluster-group-composition.ts +0 -284
- package/src/runtime/code-index-services.ts +0 -167
- package/src/runtime/daemon-handler-composition.ts +0 -76
- package/src/runtime/device-posture-composition.ts +0 -110
- package/src/runtime/durability-housekeeping.ts +0 -183
- package/src/runtime/durability-services.ts +0 -155
- package/src/runtime/embedded-service-factories.ts +0 -74
- package/src/runtime/feature-settings.ts +0 -154
- package/src/runtime/fleet-needs-input-push.ts +0 -70
- package/src/runtime/fleet-services.ts +0 -41
- package/src/runtime/idle-power-services.ts +0 -85
- package/src/runtime/mail-composition.ts +0 -65
- package/src/runtime/memory-fold.ts +0 -55
- package/src/runtime/operator-token-cleanup.ts +0 -109
- package/src/runtime/path-shadow.ts +0 -418
- package/src/runtime/perf/panel-health-monitor.ts +0 -18
- package/src/runtime/provider-optimizer-wiring.ts +0 -55
- package/src/runtime/reachability-notice.ts +0 -100
- package/src/runtime/remote-execution-composition.ts +0 -62
- package/src/runtime/session-liveness-marker.ts +0 -257
- package/src/runtime/session-pointer-surface.ts +0 -22
- package/src/runtime/session-storage-services.ts +0 -41
- package/src/runtime/surface-feature-flags.ts +0 -96
- package/src/runtime/terminal-output-guard.ts +0 -235
- package/src/runtime/trust/workspace-registration.ts +0 -192
- package/src/runtime/trust/workspace-trust.ts +0 -229
- package/src/runtime/ui/index.ts +0 -39
- package/src/runtime/ui/model-picker/data-provider.ts +0 -182
- package/src/runtime/ui/model-picker/health-enrichment.ts +0 -231
- package/src/runtime/ui/model-picker/index.ts +0 -59
- package/src/runtime/ui/model-picker/types.ts +0 -153
- package/src/runtime/ui/provider-health/data-provider.ts +0 -244
- package/src/runtime/ui/provider-health/fallback-visualizer.ts +0 -71
- package/src/runtime/ui/provider-health/index.ts +0 -46
- package/src/runtime/ui/provider-health/types.ts +0 -146
- package/src/runtime/ui-events.ts +0 -1
- package/src/runtime/ui-read-model-helpers.ts +0 -1
- package/src/runtime/ui-read-models-observability-maintenance.ts +0 -1
- package/src/runtime/ui-read-models-observability-options.ts +0 -1
- package/src/runtime/ui-read-models-observability-remote.ts +0 -1
- package/src/runtime/ui-read-models-observability-security.ts +0 -1
- package/src/runtime/ui-read-models-observability-system.ts +0 -1
- package/src/runtime/ui-read-models-observability.ts +0 -1
- package/src/runtime/ui-service-queries.ts +0 -1
- package/src/runtime/voice-setup-services.ts +0 -98
- package/src/runtime/workstream-attempts-validation.ts +0 -77
- package/src/runtime/workstream-draft-edits.ts +0 -95
- package/src/runtime/workstream-draft-store.ts +0 -274
- package/src/runtime/workstream-draft-types.ts +0 -42
- package/src/runtime/workstream-services.ts +0 -373
- package/src/tools/index.ts +0 -1
- package/src/types/grid.ts +0 -48
- package/src/types/sql-js.d.ts +0 -15
- package/src/work-plans/work-plan-store.ts +0 -702
package/src/cli/parser.ts
DELETED
|
@@ -1,395 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
GoodVibesCliCommand,
|
|
3
|
-
GoodVibesCliFlags,
|
|
4
|
-
GoodVibesCliOutputFormat,
|
|
5
|
-
GoodVibesCliParseResult,
|
|
6
|
-
} from './types.ts';
|
|
7
|
-
|
|
8
|
-
const COMMAND_ALIASES: Readonly<Record<string, GoodVibesCliCommand>> = {
|
|
9
|
-
tui: 'tui',
|
|
10
|
-
app: 'tui',
|
|
11
|
-
run: 'run',
|
|
12
|
-
exec: 'run',
|
|
13
|
-
e: 'run',
|
|
14
|
-
serve: 'serve',
|
|
15
|
-
daemon: 'serve',
|
|
16
|
-
server: 'serve',
|
|
17
|
-
web: 'web',
|
|
18
|
-
service: 'service',
|
|
19
|
-
services: 'service',
|
|
20
|
-
status: 'status',
|
|
21
|
-
doctor: 'doctor',
|
|
22
|
-
onboarding: 'onboarding',
|
|
23
|
-
setup: 'onboarding',
|
|
24
|
-
models: 'models',
|
|
25
|
-
model: 'models',
|
|
26
|
-
providers: 'providers',
|
|
27
|
-
provider: 'providers',
|
|
28
|
-
auth: 'auth',
|
|
29
|
-
subscription: 'subscription',
|
|
30
|
-
subscriptions: 'subscription',
|
|
31
|
-
secrets: 'secrets',
|
|
32
|
-
secret: 'secrets',
|
|
33
|
-
sessions: 'sessions',
|
|
34
|
-
session: 'sessions',
|
|
35
|
-
tasks: 'tasks',
|
|
36
|
-
task: 'tasks',
|
|
37
|
-
pair: 'pair',
|
|
38
|
-
qrcode: 'pair',
|
|
39
|
-
qr: 'pair',
|
|
40
|
-
surfaces: 'surfaces',
|
|
41
|
-
surface: 'surfaces',
|
|
42
|
-
listener: 'listener',
|
|
43
|
-
'http-listener': 'listener',
|
|
44
|
-
webhook: 'listener',
|
|
45
|
-
'control-plane': 'control-plane',
|
|
46
|
-
controlplane: 'control-plane',
|
|
47
|
-
cp: 'control-plane',
|
|
48
|
-
'support-bundle': 'support-bundle',
|
|
49
|
-
// `bundle`/`bundles` are retained as backward-compat aliases for the shipped
|
|
50
|
-
// command word; the primary, unambiguous name is `support-bundle` (distinct
|
|
51
|
-
// from the `plugin bundles` capability-bundle surface).
|
|
52
|
-
bundle: 'support-bundle',
|
|
53
|
-
bundles: 'support-bundle',
|
|
54
|
-
remote: 'remote',
|
|
55
|
-
bridge: 'bridge',
|
|
56
|
-
hooks: 'hooks',
|
|
57
|
-
hook: 'hooks',
|
|
58
|
-
plugin: 'plugin',
|
|
59
|
-
plugins: 'plugin',
|
|
60
|
-
completion: 'completion',
|
|
61
|
-
completions: 'completion',
|
|
62
|
-
help: 'help',
|
|
63
|
-
version: 'version',
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
function createDefaultFlags(): GoodVibesCliFlags {
|
|
67
|
-
return {
|
|
68
|
-
provider: undefined,
|
|
69
|
-
model: undefined,
|
|
70
|
-
daemonHome: undefined,
|
|
71
|
-
workingDir: undefined,
|
|
72
|
-
help: false,
|
|
73
|
-
version: false,
|
|
74
|
-
prompt: undefined,
|
|
75
|
-
print: false,
|
|
76
|
-
outputFormat: 'text',
|
|
77
|
-
configOverrides: [],
|
|
78
|
-
enableFeatures: [],
|
|
79
|
-
disableFeatures: [],
|
|
80
|
-
noAltScreen: false,
|
|
81
|
-
port: undefined,
|
|
82
|
-
hostname: undefined,
|
|
83
|
-
open: false,
|
|
84
|
-
continueLast: false,
|
|
85
|
-
resume: undefined,
|
|
86
|
-
session: undefined,
|
|
87
|
-
fork: undefined,
|
|
88
|
-
yes: false,
|
|
89
|
-
nonInteractive: false,
|
|
90
|
-
strict: false,
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function splitOption(token: string): { readonly name: string; readonly value: string | undefined } {
|
|
95
|
-
const index = token.indexOf('=');
|
|
96
|
-
if (index < 0) return { name: token, value: undefined };
|
|
97
|
-
return {
|
|
98
|
-
name: token.slice(0, index),
|
|
99
|
-
value: token.slice(index + 1),
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function getValue(
|
|
104
|
-
argv: readonly string[],
|
|
105
|
-
index: number,
|
|
106
|
-
inlineValue: string | undefined,
|
|
107
|
-
optionName: string,
|
|
108
|
-
errors: string[],
|
|
109
|
-
): { readonly value: string | undefined; readonly nextIndex: number } {
|
|
110
|
-
if (inlineValue !== undefined) return { value: inlineValue, nextIndex: index };
|
|
111
|
-
const next = argv[index + 1];
|
|
112
|
-
if (next === undefined || (next.startsWith('-') && next !== '-')) {
|
|
113
|
-
errors.push(`${optionName} requires a value.`);
|
|
114
|
-
return { value: undefined, nextIndex: index };
|
|
115
|
-
}
|
|
116
|
-
return { value: next, nextIndex: index + 1 };
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function getOptionalValue(
|
|
120
|
-
argv: readonly string[],
|
|
121
|
-
index: number,
|
|
122
|
-
inlineValue: string | undefined,
|
|
123
|
-
): { readonly value: string | undefined; readonly nextIndex: number } {
|
|
124
|
-
if (inlineValue !== undefined) return { value: inlineValue, nextIndex: index };
|
|
125
|
-
const next = argv[index + 1];
|
|
126
|
-
if (next === undefined || next.startsWith('-')) return { value: undefined, nextIndex: index };
|
|
127
|
-
return { value: next, nextIndex: index + 1 };
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function parsePort(value: string | undefined, optionName: string, errors: string[]): number | undefined {
|
|
131
|
-
if (value === undefined) return undefined;
|
|
132
|
-
if (!/^\d+$/.test(value)) {
|
|
133
|
-
errors.push(`${optionName} must be a port number from 1 to 65535.`);
|
|
134
|
-
return undefined;
|
|
135
|
-
}
|
|
136
|
-
const port = Number.parseInt(value, 10);
|
|
137
|
-
if (port < 1 || port > 65535) {
|
|
138
|
-
errors.push(`${optionName} must be a port number from 1 to 65535.`);
|
|
139
|
-
return undefined;
|
|
140
|
-
}
|
|
141
|
-
return port;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function normalizeOutputFormat(value: string | undefined, flagName: string, errors: string[]): GoodVibesCliOutputFormat {
|
|
145
|
-
if (value === 'text' || value === 'json' || value === 'stream-json') return value;
|
|
146
|
-
errors.push(`${flagName} must be one of: text, json, stream-json.`);
|
|
147
|
-
return 'text';
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
function inferProviderFromModel(model: string, currentProvider: string | undefined): string | undefined {
|
|
151
|
-
if (currentProvider !== undefined) return currentProvider;
|
|
152
|
-
if (model.includes(':')) return model.split(':')[0];
|
|
153
|
-
if (model.includes('/')) return model.split('/')[0];
|
|
154
|
-
return undefined;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
function withFlag<K extends keyof GoodVibesCliFlags>(
|
|
158
|
-
flags: GoodVibesCliFlags,
|
|
159
|
-
key: K,
|
|
160
|
-
value: GoodVibesCliFlags[K],
|
|
161
|
-
): GoodVibesCliFlags {
|
|
162
|
-
return { ...flags, [key]: value };
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
function appendFlagArray<K extends 'configOverrides' | 'enableFeatures' | 'disableFeatures'>(
|
|
166
|
-
flags: GoodVibesCliFlags,
|
|
167
|
-
key: K,
|
|
168
|
-
value: string,
|
|
169
|
-
): GoodVibesCliFlags {
|
|
170
|
-
return {
|
|
171
|
-
...flags,
|
|
172
|
-
[key]: [...flags[key], value],
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
export function parseGoodVibesCli(
|
|
177
|
-
argv: readonly string[],
|
|
178
|
-
binary = 'goodvibes',
|
|
179
|
-
): GoodVibesCliParseResult {
|
|
180
|
-
let flags = createDefaultFlags();
|
|
181
|
-
let command: GoodVibesCliCommand = 'tui';
|
|
182
|
-
let rawCommand: string | undefined;
|
|
183
|
-
const commandArgs: string[] = [];
|
|
184
|
-
const positionals: string[] = [];
|
|
185
|
-
const errors: string[] = [];
|
|
186
|
-
const warnings: string[] = [];
|
|
187
|
-
let sawCommand = false;
|
|
188
|
-
let passthrough = false;
|
|
189
|
-
|
|
190
|
-
for (let index = 0; index < argv.length; index += 1) {
|
|
191
|
-
const token = argv[index]!;
|
|
192
|
-
|
|
193
|
-
if (passthrough) {
|
|
194
|
-
if (sawCommand) commandArgs.push(token);
|
|
195
|
-
else positionals.push(token);
|
|
196
|
-
continue;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if (token === '--') {
|
|
200
|
-
passthrough = true;
|
|
201
|
-
continue;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
if (!token.startsWith('-') || token === '-') {
|
|
205
|
-
if (!sawCommand) {
|
|
206
|
-
const normalized = COMMAND_ALIASES[token.toLowerCase()];
|
|
207
|
-
if (normalized) {
|
|
208
|
-
command = normalized;
|
|
209
|
-
rawCommand = token;
|
|
210
|
-
sawCommand = true;
|
|
211
|
-
continue;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
positionals.push(token);
|
|
215
|
-
if (sawCommand) commandArgs.push(token);
|
|
216
|
-
continue;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const { name, value: inlineValue } = splitOption(token);
|
|
220
|
-
|
|
221
|
-
if (name === '--help' || name === '-h') {
|
|
222
|
-
flags = withFlag(flags, 'help', true);
|
|
223
|
-
continue;
|
|
224
|
-
}
|
|
225
|
-
if (name === '--version' || name === '-v') {
|
|
226
|
-
flags = withFlag(flags, 'version', true);
|
|
227
|
-
continue;
|
|
228
|
-
}
|
|
229
|
-
if (name === '--print') {
|
|
230
|
-
flags = withFlag(flags, 'print', true);
|
|
231
|
-
if (!sawCommand) command = 'run';
|
|
232
|
-
continue;
|
|
233
|
-
}
|
|
234
|
-
if (name === '--json') {
|
|
235
|
-
flags = withFlag(flags, 'outputFormat', 'json');
|
|
236
|
-
continue;
|
|
237
|
-
}
|
|
238
|
-
if (name === '--no-alt-screen') {
|
|
239
|
-
flags = withFlag(flags, 'noAltScreen', true);
|
|
240
|
-
continue;
|
|
241
|
-
}
|
|
242
|
-
if (name === '--open') {
|
|
243
|
-
flags = withFlag(flags, 'open', true);
|
|
244
|
-
continue;
|
|
245
|
-
}
|
|
246
|
-
if (name === '--continue') {
|
|
247
|
-
flags = withFlag(flags, 'continueLast', true);
|
|
248
|
-
continue;
|
|
249
|
-
}
|
|
250
|
-
if (name === '--fork') {
|
|
251
|
-
const consumed = getOptionalValue(argv, index, inlineValue);
|
|
252
|
-
index = consumed.nextIndex;
|
|
253
|
-
flags = withFlag(flags, 'fork', consumed.value ?? true);
|
|
254
|
-
continue;
|
|
255
|
-
}
|
|
256
|
-
if (name === '--yes' || name === '-y') {
|
|
257
|
-
flags = withFlag(flags, 'yes', true);
|
|
258
|
-
continue;
|
|
259
|
-
}
|
|
260
|
-
if (name === '--non-interactive') {
|
|
261
|
-
flags = withFlag(withFlag(flags, 'nonInteractive', true), 'yes', true);
|
|
262
|
-
continue;
|
|
263
|
-
}
|
|
264
|
-
if (name === '--strict') {
|
|
265
|
-
flags = withFlag(flags, 'strict', true);
|
|
266
|
-
continue;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
if (name === '--provider') {
|
|
270
|
-
const consumed = getValue(argv, index, inlineValue, name, errors);
|
|
271
|
-
index = consumed.nextIndex;
|
|
272
|
-
if (consumed.value !== undefined) flags = withFlag(flags, 'provider', consumed.value);
|
|
273
|
-
continue;
|
|
274
|
-
}
|
|
275
|
-
if (name === '--model' || name === '-m') {
|
|
276
|
-
const consumed = getValue(argv, index, inlineValue, name, errors);
|
|
277
|
-
index = consumed.nextIndex;
|
|
278
|
-
if (consumed.value !== undefined) {
|
|
279
|
-
flags = withFlag(flags, 'model', consumed.value);
|
|
280
|
-
flags = withFlag(flags, 'provider', inferProviderFromModel(consumed.value, flags.provider));
|
|
281
|
-
}
|
|
282
|
-
continue;
|
|
283
|
-
}
|
|
284
|
-
if (name === '--daemon-home') {
|
|
285
|
-
const consumed = getValue(argv, index, inlineValue, name, errors);
|
|
286
|
-
index = consumed.nextIndex;
|
|
287
|
-
if (consumed.value !== undefined) flags = withFlag(flags, 'daemonHome', consumed.value);
|
|
288
|
-
continue;
|
|
289
|
-
}
|
|
290
|
-
if (name === '--working-dir' || name === '--cd' || name === '-C') {
|
|
291
|
-
const consumed = getValue(argv, index, inlineValue, name, errors);
|
|
292
|
-
index = consumed.nextIndex;
|
|
293
|
-
if (consumed.value !== undefined) flags = withFlag(flags, 'workingDir', consumed.value);
|
|
294
|
-
continue;
|
|
295
|
-
}
|
|
296
|
-
if (name === '--prompt' || name === '-p') {
|
|
297
|
-
const consumed = getValue(argv, index, inlineValue, name, errors);
|
|
298
|
-
index = consumed.nextIndex;
|
|
299
|
-
if (consumed.value !== undefined) {
|
|
300
|
-
flags = withFlag(flags, 'prompt', consumed.value);
|
|
301
|
-
if (!sawCommand) command = 'run';
|
|
302
|
-
}
|
|
303
|
-
continue;
|
|
304
|
-
}
|
|
305
|
-
if (name === '--output-format' || name === '--output' || name === '-o') {
|
|
306
|
-
const consumed = getValue(argv, index, inlineValue, name, errors);
|
|
307
|
-
index = consumed.nextIndex;
|
|
308
|
-
flags = withFlag(flags, 'outputFormat', normalizeOutputFormat(consumed.value, name, errors));
|
|
309
|
-
if (name === '--output-format') {
|
|
310
|
-
warnings.push('--output-format is deprecated; use --output (or -o) instead.');
|
|
311
|
-
}
|
|
312
|
-
continue;
|
|
313
|
-
}
|
|
314
|
-
if (name === '--config' || name === '-c') {
|
|
315
|
-
const consumed = getValue(argv, index, inlineValue, name, errors);
|
|
316
|
-
index = consumed.nextIndex;
|
|
317
|
-
if (consumed.value !== undefined) flags = appendFlagArray(flags, 'configOverrides', consumed.value);
|
|
318
|
-
continue;
|
|
319
|
-
}
|
|
320
|
-
if (name === '--enable') {
|
|
321
|
-
const consumed = getValue(argv, index, inlineValue, name, errors);
|
|
322
|
-
index = consumed.nextIndex;
|
|
323
|
-
if (consumed.value !== undefined) flags = appendFlagArray(flags, 'enableFeatures', consumed.value);
|
|
324
|
-
continue;
|
|
325
|
-
}
|
|
326
|
-
if (name === '--disable') {
|
|
327
|
-
const consumed = getValue(argv, index, inlineValue, name, errors);
|
|
328
|
-
index = consumed.nextIndex;
|
|
329
|
-
if (consumed.value !== undefined) flags = appendFlagArray(flags, 'disableFeatures', consumed.value);
|
|
330
|
-
continue;
|
|
331
|
-
}
|
|
332
|
-
if (name === '--port') {
|
|
333
|
-
const consumed = getValue(argv, index, inlineValue, name, errors);
|
|
334
|
-
index = consumed.nextIndex;
|
|
335
|
-
flags = withFlag(flags, 'port', parsePort(consumed.value, name, errors));
|
|
336
|
-
continue;
|
|
337
|
-
}
|
|
338
|
-
if (name === '--hostname' || name === '--host') {
|
|
339
|
-
const consumed = getValue(argv, index, inlineValue, name, errors);
|
|
340
|
-
index = consumed.nextIndex;
|
|
341
|
-
if (consumed.value !== undefined) flags = withFlag(flags, 'hostname', consumed.value);
|
|
342
|
-
continue;
|
|
343
|
-
}
|
|
344
|
-
if (name === '--resume' || name === '-r') {
|
|
345
|
-
const consumed = getOptionalValue(argv, index, inlineValue);
|
|
346
|
-
index = consumed.nextIndex;
|
|
347
|
-
flags = withFlag(flags, 'resume', consumed.value ?? 'latest');
|
|
348
|
-
continue;
|
|
349
|
-
}
|
|
350
|
-
if (name === '--session' || name === '-s') {
|
|
351
|
-
const consumed = getValue(argv, index, inlineValue, name, errors);
|
|
352
|
-
index = consumed.nextIndex;
|
|
353
|
-
if (consumed.value !== undefined) flags = withFlag(flags, 'session', consumed.value);
|
|
354
|
-
continue;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
if (sawCommand) {
|
|
358
|
-
commandArgs.push(token);
|
|
359
|
-
continue;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
errors.push(`Unknown option: ${name}`);
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
if (flags.prompt === undefined && (command === 'run' || flags.print) && positionals.length > 0) {
|
|
366
|
-
flags = withFlag(flags, 'prompt', positionals.join(' '));
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
if (rawCommand !== undefined && command === 'unknown') {
|
|
370
|
-
errors.push(`Unknown command: ${rawCommand}`);
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
// Session lifecycle conflict detection — only one of --continue / --resume / --fork may be used.
|
|
374
|
-
const sessionLifecycleFlags = [
|
|
375
|
-
flags.continueLast ? '--continue' : undefined,
|
|
376
|
-
flags.resume !== undefined ? '--resume' : undefined,
|
|
377
|
-
flags.fork !== undefined ? '--fork' : undefined,
|
|
378
|
-
].filter((f): f is string => f !== undefined);
|
|
379
|
-
if (sessionLifecycleFlags.length > 1) {
|
|
380
|
-
errors.push(
|
|
381
|
-
`Conflicting session lifecycle flags: ${sessionLifecycleFlags.join(' and ')}. Use only one of --continue, --resume, or --fork.`,
|
|
382
|
-
);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
return {
|
|
386
|
-
binary,
|
|
387
|
-
command,
|
|
388
|
-
rawCommand,
|
|
389
|
-
commandArgs,
|
|
390
|
-
positionals,
|
|
391
|
-
flags,
|
|
392
|
-
errors,
|
|
393
|
-
warnings,
|
|
394
|
-
};
|
|
395
|
-
}
|
package/src/cli/redaction.ts
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
export const REDACTED_VALUE = '<redacted>';
|
|
2
|
-
|
|
3
|
-
// Matches a config path whose LAST SEGMENT is exactly one of these words. That
|
|
4
|
-
// is the whole reach of this pattern, and it is why the declared list below
|
|
5
|
-
// exists: `surfaces.calendar.caldavPassword` does not end in a `.password`
|
|
6
|
-
// segment, it ends in a `caldavPassword` segment, so this pattern answers false
|
|
7
|
-
// for it — as it does for `imapPassword`, `appPassword` and `authToken`.
|
|
8
|
-
const SENSITIVE_PATH_PATTERN = /(^|\.)(apiKey|accessToken|botToken|appToken|signingSecret|webhookSecret|verifyToken|verificationToken|secret|password|token|keyFile)$/i;
|
|
9
|
-
|
|
10
|
-
// Credential-bearing config keys that are sensitive by NAME rather than by the
|
|
11
|
-
// generic trailing-word list above. Every one of these was carried in the clear
|
|
12
|
-
// by a support bundle before it was listed here, because the pattern matches a
|
|
13
|
-
// trailing WORD and these names carry the credential word in the middle or
|
|
14
|
-
// prefixed by a protocol ("caldavPassword", "imapPassword", "appPassword",
|
|
15
|
-
// "authToken").
|
|
16
|
-
//
|
|
17
|
-
// The `*Ref` Cloudflare keys normally hold a `goodvibes://secrets/...`
|
|
18
|
-
// reference, which shouldRedactValue already lets through as safe. They are
|
|
19
|
-
// listed as a BACKSTOP, for the same reason the mail keys are worth listing
|
|
20
|
-
// twice over: it costs nothing, and it is what stands between a future code
|
|
21
|
-
// path that writes a literal token there and that token reaching a file the
|
|
22
|
-
// owner emails to someone for support.
|
|
23
|
-
const SENSITIVE_CONFIG_KEYS: ReadonlySet<string> = new Set([
|
|
24
|
-
// Mailbox / CalDAV — the credentials the daemon polls mail and calendar with.
|
|
25
|
-
'surfaces.email.password',
|
|
26
|
-
'surfaces.email.imapPassword',
|
|
27
|
-
'surfaces.email.imap.password',
|
|
28
|
-
'surfaces.email.smtp.password',
|
|
29
|
-
'surfaces.calendar.caldavPassword',
|
|
30
|
-
// Telephony.
|
|
31
|
-
'surfaces.telephony.authToken',
|
|
32
|
-
'surfaces.msteams.appPassword',
|
|
33
|
-
// Cloudflare token references.
|
|
34
|
-
'cloudflare.apiTokenRef',
|
|
35
|
-
'cloudflare.tunnelTokenRef',
|
|
36
|
-
'cloudflare.accessServiceTokenRef',
|
|
37
|
-
'cloudflare.workerTokenRef',
|
|
38
|
-
'cloudflare.workerClientTokenRef',
|
|
39
|
-
// Cluster shared phrase.
|
|
40
|
-
'cluster.secret',
|
|
41
|
-
// Payment card material. ADDED to this set, never substituted for it: this
|
|
42
|
-
// set is a hardcoded list with no delegation, so replacing it wholesale with
|
|
43
|
-
// another product's would silently stop redacting whatever that one omits.
|
|
44
|
-
// The four names below end in no word the suffix pattern knows —
|
|
45
|
-
// "cardNumber", "cardExpiry" and "cardholderName" match none of them — which
|
|
46
|
-
// is the whole reason a declared list exists rather than a naming habit.
|
|
47
|
-
// (The `.map` below lowercases every entry; the lookup lowercases too.)
|
|
48
|
-
'payments.cardNumber',
|
|
49
|
-
'payments.cardExpiry',
|
|
50
|
-
'payments.cardCvv',
|
|
51
|
-
'payments.cardholderName',
|
|
52
|
-
].map((key) => key.toLowerCase()));
|
|
53
|
-
|
|
54
|
-
const SECRET_LIKE_TEXT_PATTERNS: readonly RegExp[] = [
|
|
55
|
-
/\bsk-[A-Za-z0-9_-]{16,}\b/g,
|
|
56
|
-
/\bghp_[A-Za-z0-9_]{16,}\b/g,
|
|
57
|
-
/\bgho_[A-Za-z0-9_]{16,}\b/g,
|
|
58
|
-
/\bghu_[A-Za-z0-9_]{16,}\b/g,
|
|
59
|
-
/\bghs_[A-Za-z0-9_]{16,}\b/g,
|
|
60
|
-
/\bgithub_pat_[A-Za-z0-9_]{24,}\b/g,
|
|
61
|
-
/\b(?:xoxb|xapp|xoxp|xoxa)-[A-Za-z0-9-]{16,}\b/g,
|
|
62
|
-
/\b[A-Za-z0-9._%+-]+:[A-Za-z0-9._%+-]{8,}@/g,
|
|
63
|
-
];
|
|
64
|
-
|
|
65
|
-
export function isSensitiveConfigPath(path: string): boolean {
|
|
66
|
-
return SENSITIVE_PATH_PATTERN.test(path) || SENSITIVE_CONFIG_KEYS.has(path.toLowerCase());
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export function isRedactedValue(value: unknown): boolean {
|
|
70
|
-
return value === REDACTED_VALUE;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export interface RedactedConfigResult<T> {
|
|
74
|
-
readonly value: T;
|
|
75
|
-
readonly redactedPaths: readonly string[];
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Redaction rule for sensitive config paths:
|
|
79
|
-
// - Non-string values: redact if truthy (i.e. non-null, non-undefined, non-zero, non-false).
|
|
80
|
-
// Rationale: zero and false are never meaningful secrets; null/undefined mean absent.
|
|
81
|
-
// - String values: redact non-empty strings that are not goodvibes:// secret refs.
|
|
82
|
-
// Rationale: empty string means unset; secret refs are safe placeholders, not raw values.
|
|
83
|
-
function shouldRedactValue(path: string, value: unknown): boolean {
|
|
84
|
-
if (!isSensitiveConfigPath(path)) return false;
|
|
85
|
-
if (typeof value !== 'string') return value !== null && value !== undefined && Boolean(value);
|
|
86
|
-
if (value.trim().length === 0) return false;
|
|
87
|
-
if (value.startsWith('goodvibes://secrets/')) return false;
|
|
88
|
-
return true;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function redactUnknown(value: unknown, path: string, redactedPaths: string[]): unknown {
|
|
92
|
-
if (shouldRedactValue(path, value)) {
|
|
93
|
-
redactedPaths.push(path);
|
|
94
|
-
return REDACTED_VALUE;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (Array.isArray(value)) {
|
|
98
|
-
return value.map((item, index) => redactUnknown(item, `${path}.${index}`, redactedPaths));
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (value && typeof value === 'object') {
|
|
102
|
-
const result: Record<string, unknown> = {};
|
|
103
|
-
for (const [key, nested] of Object.entries(value)) {
|
|
104
|
-
const nestedPath = path ? `${path}.${key}` : key;
|
|
105
|
-
result[key] = redactUnknown(nested, nestedPath, redactedPaths);
|
|
106
|
-
}
|
|
107
|
-
return result;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return value;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export function redactConfig<T>(config: T): RedactedConfigResult<T> {
|
|
114
|
-
const redactedPaths: string[] = [];
|
|
115
|
-
return {
|
|
116
|
-
value: redactUnknown(config, '', redactedPaths) as T,
|
|
117
|
-
redactedPaths,
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export function redactText(input: string): string {
|
|
122
|
-
// Assignment form: keyword=value — anchored so 'monkey=' and 'donkey=' do NOT match.
|
|
123
|
-
// Matches: token=, access_token=, api_key=, api-key=, secret=, password= and colon form token: value
|
|
124
|
-
let output = input
|
|
125
|
-
.replace(
|
|
126
|
-
/(?<![A-Za-z])(?:access_token|api[_-]?key|secret|password|token)\s*=\s*([^ \t\r\n"'`]+)/gi,
|
|
127
|
-
(m, val) => m.slice(0, m.length - val.length) + REDACTED_VALUE,
|
|
128
|
-
)
|
|
129
|
-
.replace(
|
|
130
|
-
/(?<![A-Za-z])(?:access_token|api[_-]?key|secret|password|token)\s*:\s*([^ \t\r\n"'`]+)/gi,
|
|
131
|
-
(m, val) => m.slice(0, m.length - val.length) + REDACTED_VALUE,
|
|
132
|
-
);
|
|
133
|
-
for (const pattern of SECRET_LIKE_TEXT_PATTERNS) {
|
|
134
|
-
output = output.replace(pattern, REDACTED_VALUE);
|
|
135
|
-
}
|
|
136
|
-
return output;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function collectSensitiveValues(value: unknown, path: string, values: string[]): void {
|
|
140
|
-
if (shouldRedactValue(path, value) && typeof value === 'string') {
|
|
141
|
-
values.push(value);
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
if (Array.isArray(value)) {
|
|
145
|
-
value.forEach((item, index) => collectSensitiveValues(item, `${path}.${index}`, values));
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
if (value && typeof value === 'object') {
|
|
149
|
-
for (const [key, nested] of Object.entries(value)) {
|
|
150
|
-
collectSensitiveValues(nested, path ? `${path}.${key}` : key, values);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
export function collectSensitiveConfigValues(config: unknown): readonly string[] {
|
|
156
|
-
const values: string[] = [];
|
|
157
|
-
collectSensitiveValues(config, '', values);
|
|
158
|
-
return [...new Set(values)].sort((left, right) => right.length - left.length);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export function redactSerializedSecrets(serialized: string, secretValues: readonly string[]): string {
|
|
162
|
-
let output = redactText(serialized);
|
|
163
|
-
for (const secret of secretValues) {
|
|
164
|
-
if (!secret) continue;
|
|
165
|
-
const encoded = JSON.stringify(secret).slice(1, -1);
|
|
166
|
-
output = output.split(encoded).join(REDACTED_VALUE);
|
|
167
|
-
output = output.split(secret).join(REDACTED_VALUE);
|
|
168
|
-
}
|
|
169
|
-
return output;
|
|
170
|
-
}
|
package/src/cli/types.ts
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import type { ConfigManager } from '../config/index.ts';
|
|
2
|
-
|
|
3
|
-
export type GoodVibesCliCommand =
|
|
4
|
-
| 'tui'
|
|
5
|
-
| 'run'
|
|
6
|
-
| 'serve'
|
|
7
|
-
| 'web'
|
|
8
|
-
| 'service'
|
|
9
|
-
| 'status'
|
|
10
|
-
| 'doctor'
|
|
11
|
-
| 'onboarding'
|
|
12
|
-
| 'models'
|
|
13
|
-
| 'providers'
|
|
14
|
-
| 'auth'
|
|
15
|
-
| 'subscription'
|
|
16
|
-
| 'secrets'
|
|
17
|
-
| 'sessions'
|
|
18
|
-
| 'tasks'
|
|
19
|
-
| 'pair'
|
|
20
|
-
| 'surfaces'
|
|
21
|
-
| 'listener'
|
|
22
|
-
| 'control-plane'
|
|
23
|
-
| 'support-bundle'
|
|
24
|
-
| 'remote'
|
|
25
|
-
| 'bridge'
|
|
26
|
-
| 'hooks'
|
|
27
|
-
| 'plugin'
|
|
28
|
-
| 'completion'
|
|
29
|
-
| 'help'
|
|
30
|
-
| 'version'
|
|
31
|
-
| 'unknown';
|
|
32
|
-
|
|
33
|
-
export type GoodVibesCliOutputFormat = 'text' | 'json' | 'stream-json';
|
|
34
|
-
|
|
35
|
-
export interface CliCommandOutput {
|
|
36
|
-
readonly output: string;
|
|
37
|
-
readonly exitCode: number;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export interface GoodVibesCliFlags {
|
|
41
|
-
readonly provider: string | undefined;
|
|
42
|
-
readonly model: string | undefined;
|
|
43
|
-
readonly daemonHome: string | undefined;
|
|
44
|
-
readonly workingDir: string | undefined;
|
|
45
|
-
readonly help: boolean;
|
|
46
|
-
readonly version: boolean;
|
|
47
|
-
readonly prompt: string | undefined;
|
|
48
|
-
readonly print: boolean;
|
|
49
|
-
readonly outputFormat: GoodVibesCliOutputFormat;
|
|
50
|
-
readonly configOverrides: readonly string[];
|
|
51
|
-
readonly enableFeatures: readonly string[];
|
|
52
|
-
readonly disableFeatures: readonly string[];
|
|
53
|
-
readonly noAltScreen: boolean;
|
|
54
|
-
readonly port: number | undefined;
|
|
55
|
-
readonly hostname: string | undefined;
|
|
56
|
-
readonly open: boolean;
|
|
57
|
-
readonly continueLast: boolean;
|
|
58
|
-
readonly resume: string | undefined;
|
|
59
|
-
readonly session: string | undefined;
|
|
60
|
-
readonly fork: string | true | undefined;
|
|
61
|
-
readonly yes: boolean;
|
|
62
|
-
readonly nonInteractive: boolean;
|
|
63
|
-
/** `doctor --strict`: advisory findings also fail (exit 1), for CI. Ignored by every other command. */
|
|
64
|
-
readonly strict: boolean;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export interface GoodVibesCliParseResult {
|
|
68
|
-
readonly binary: string;
|
|
69
|
-
readonly command: GoodVibesCliCommand;
|
|
70
|
-
readonly rawCommand: string | undefined;
|
|
71
|
-
readonly commandArgs: readonly string[];
|
|
72
|
-
readonly positionals: readonly string[];
|
|
73
|
-
readonly flags: GoodVibesCliFlags;
|
|
74
|
-
readonly errors: readonly string[];
|
|
75
|
-
/** Deprecation and soft-warning messages (non-fatal). Callers should surface these to users. */
|
|
76
|
-
readonly warnings: readonly string[];
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export interface CliCommandRuntime {
|
|
80
|
-
readonly cli: GoodVibesCliParseResult;
|
|
81
|
-
readonly configManager: ConfigManager;
|
|
82
|
-
readonly workingDirectory: string;
|
|
83
|
-
readonly homeDirectory: string;
|
|
84
|
-
}
|