@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
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
-
import type { ConfigKey, ConfigManager, ConfigSetting, GoodVibesConfig } from '../config/index.ts';
|
|
3
|
-
import { CONFIG_SCHEMA, ConfigError } from '../config/index.ts';
|
|
4
|
-
import { featureEnablementWrite, getFeatureSetting } from '../runtime/feature-settings.ts';
|
|
5
|
-
import type { GoodVibesCliCommand, GoodVibesCliFlags } from './types.ts';
|
|
6
|
-
import { RUNTIME_ENDPOINT_CONFIG_KEYS, hostModeForHostname } from './endpoints.ts';
|
|
7
|
-
import type { RuntimeEndpointId } from './endpoints.ts';
|
|
8
|
-
|
|
9
|
-
const CONFIG_SCHEMA_BY_KEY = new Map<string, ConfigSetting>(
|
|
10
|
-
CONFIG_SCHEMA.map((setting) => [setting.key, setting]),
|
|
11
|
-
);
|
|
12
|
-
|
|
13
|
-
function parseConfigOverrideValue(value: string): unknown {
|
|
14
|
-
const trimmed = value.trim();
|
|
15
|
-
if (trimmed.length === 0) return '';
|
|
16
|
-
try {
|
|
17
|
-
return JSON.parse(trimmed) as unknown;
|
|
18
|
-
} catch {
|
|
19
|
-
if (trimmed === 'true') return true;
|
|
20
|
-
if (trimmed === 'false') return false;
|
|
21
|
-
if (/^-?\d+(?:\.\d+)?$/.test(trimmed)) return Number(trimmed);
|
|
22
|
-
return value;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function getRuntimeConfig(configManager: ConfigManager): GoodVibesConfig {
|
|
27
|
-
const mutable = configManager as unknown as { config?: GoodVibesConfig };
|
|
28
|
-
if (!mutable.config || typeof mutable.config !== 'object') {
|
|
29
|
-
throw new ConfigError('ConfigManager runtime config is not available for CLI overrides.');
|
|
30
|
-
}
|
|
31
|
-
return mutable.config;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function validateConfigValue(setting: ConfigSetting, value: unknown): void {
|
|
35
|
-
if (setting.type === 'boolean' && typeof value !== 'boolean') {
|
|
36
|
-
throw new ConfigError(`Invalid value for ${setting.key}: expected boolean.`);
|
|
37
|
-
}
|
|
38
|
-
if (setting.type === 'number' && (typeof value !== 'number' || !Number.isFinite(value))) {
|
|
39
|
-
throw new ConfigError(`Invalid value for ${setting.key}: expected number.`);
|
|
40
|
-
}
|
|
41
|
-
if (setting.type === 'string' && typeof value !== 'string') {
|
|
42
|
-
throw new ConfigError(`Invalid value for ${setting.key}: expected string.`);
|
|
43
|
-
}
|
|
44
|
-
if (setting.type === 'enum' && setting.enumValues && !setting.enumValues.includes(String(value))) {
|
|
45
|
-
throw new ConfigError(`Invalid value for ${setting.key}: "${String(value)}". Allowed: ${setting.enumValues.join(', ')}`);
|
|
46
|
-
}
|
|
47
|
-
if (setting.validate && !setting.validate(value)) {
|
|
48
|
-
throw new ConfigError(`Invalid value for ${setting.key}: ${String(value)}`);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function setNestedConfigValue(config: GoodVibesConfig, key: ConfigKey, value: unknown): void {
|
|
53
|
-
const parts = key.split('.');
|
|
54
|
-
let cursor: unknown = config;
|
|
55
|
-
for (const part of parts.slice(0, -1)) {
|
|
56
|
-
if (cursor == null || typeof cursor !== 'object' || !(part in cursor)) {
|
|
57
|
-
throw new ConfigError(`Invalid config path: section '${part}' does not exist`);
|
|
58
|
-
}
|
|
59
|
-
cursor = (cursor as Record<string, unknown>)[part];
|
|
60
|
-
}
|
|
61
|
-
if (cursor == null || typeof cursor !== 'object') {
|
|
62
|
-
throw new ConfigError(`Invalid config path: section '${parts.slice(0, -1).join('.')}' does not exist`);
|
|
63
|
-
}
|
|
64
|
-
(cursor as Record<string, unknown>)[parts[parts.length - 1]!] = value;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Typed accessor for the SDK's private file paths on ConfigManager.
|
|
69
|
-
*
|
|
70
|
-
* SDK coupling: configPath and projectConfigPath are declared `private readonly`
|
|
71
|
-
* in the SDK's ConfigManager (see manager.d.ts — configPath, projectConfigPath). No public accessors exist
|
|
72
|
-
* as of the SDK version pinned in this project. This cast is the narrowest
|
|
73
|
-
* possible workaround. SDK public-accessor request: see HANDOFF-FROM-TUI-SESSION-20260611.md,
|
|
74
|
-
* Item 6 area. If the SDK ever exposes getConfigPath()/getProjectConfigPath(), replace
|
|
75
|
-
* this cast with those calls and remove this comment.
|
|
76
|
-
*
|
|
77
|
-
* Fail-open: if the cast produces undefined (SDK internal rename), the paths are
|
|
78
|
-
* treated as absent and the default is applied safely.
|
|
79
|
-
*/
|
|
80
|
-
function getPersistedPaths(configManager: ConfigManager): { configPath: string | undefined; projectConfigPath: string | undefined } {
|
|
81
|
-
const manager = configManager as unknown as { configPath?: string; projectConfigPath?: string };
|
|
82
|
-
return {
|
|
83
|
-
configPath: typeof manager.configPath === 'string' ? manager.configPath : undefined,
|
|
84
|
-
projectConfigPath: typeof manager.projectConfigPath === 'string' ? manager.projectConfigPath : undefined,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Returns true if the given dot-path key is explicitly present anywhere
|
|
90
|
-
* in the provided raw JSON object.
|
|
91
|
-
*/
|
|
92
|
-
function isKeyPresentInRaw(raw: Record<string, unknown>, key: ConfigKey): boolean {
|
|
93
|
-
const parts = key.split('.');
|
|
94
|
-
let cursor: unknown = raw;
|
|
95
|
-
for (const part of parts) {
|
|
96
|
-
if (cursor == null || typeof cursor !== 'object' || !(part in (cursor as object))) {
|
|
97
|
-
return false;
|
|
98
|
-
}
|
|
99
|
-
cursor = (cursor as Record<string, unknown>)[part];
|
|
100
|
-
}
|
|
101
|
-
return true;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Apply a TUI default to a config key, but ONLY if the user has not explicitly
|
|
106
|
-
* set the key in EITHER their global OR project persisted settings files.
|
|
107
|
-
* Reads the raw settings JSON from disk (bypasses the in-memory merged config)
|
|
108
|
-
* so a user's explicit `false` in either file is never silently overridden at startup.
|
|
109
|
-
*
|
|
110
|
-
* Each settings file is read independently: a parse failure on one file
|
|
111
|
-
* contributes nothing but does NOT prevent the other file from being checked.
|
|
112
|
-
* The default is applied only when the key is absent from every readable file
|
|
113
|
-
* (e.g. new install, both files missing, or both unparseable).
|
|
114
|
-
*/
|
|
115
|
-
export function applyRuntimeConfigDefault(configManager: ConfigManager, key: ConfigKey, defaultValue: unknown): void {
|
|
116
|
-
const { configPath, projectConfigPath } = getPersistedPaths(configManager);
|
|
117
|
-
// Check each settings file independently. A read/parse failure on one path
|
|
118
|
-
// contributes nothing but must not prevent the other path from being checked.
|
|
119
|
-
for (const filePath of [configPath, projectConfigPath]) {
|
|
120
|
-
if (typeof filePath !== 'string' || !existsSync(filePath)) continue;
|
|
121
|
-
try {
|
|
122
|
-
const raw = JSON.parse(readFileSync(filePath, 'utf-8')) as Record<string, unknown>;
|
|
123
|
-
if (isKeyPresentInRaw(raw, key)) {
|
|
124
|
-
// Key is explicitly set in this persisted config — respect the user's value.
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
} catch {
|
|
128
|
-
// Unreadable or malformed JSON — this file contributes nothing; continue to next.
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
applyRuntimeConfigValue(configManager, key, defaultValue);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Every TUI-side config default applied at startup, in one place. Currently:
|
|
136
|
-
* show token speed ON (the SDK schema default is false). applyRuntimeConfigDefault
|
|
137
|
-
* reads the global + project settings files and only applies the default
|
|
138
|
-
* in-memory when the key is absent from both (e.g. a new install); an explicit
|
|
139
|
-
* user value is respected. No disk write.
|
|
140
|
-
*/
|
|
141
|
-
export function applyTuiRuntimeConfigDefaults(configManager: ConfigManager): void {
|
|
142
|
-
applyRuntimeConfigDefault(configManager, 'display.showTokenSpeed', true);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Applies the persisted `behavior.hitlMode` config value to the live mode
|
|
147
|
-
* manager at startup, ignoring unset or unrecognized values. Extracted from
|
|
148
|
-
* main() verbatim (a plain move, no behavior change).
|
|
149
|
-
*/
|
|
150
|
-
export function applyConfiguredHitlMode(
|
|
151
|
-
configManager: ConfigManager,
|
|
152
|
-
modeManager: { setHITLMode(mode: 'quiet' | 'balanced' | 'operator'): void },
|
|
153
|
-
): void {
|
|
154
|
-
const hitlMode = configManager.get('behavior.hitlMode');
|
|
155
|
-
if (hitlMode === 'quiet' || hitlMode === 'balanced' || hitlMode === 'operator') {
|
|
156
|
-
modeManager.setHITLMode(hitlMode);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
export function applyRuntimeConfigValue(configManager: ConfigManager, key: ConfigKey, value: unknown): void {
|
|
161
|
-
const setting = CONFIG_SCHEMA_BY_KEY.get(key);
|
|
162
|
-
if (!setting) {
|
|
163
|
-
throw new ConfigError(`Unknown config key: ${key}`);
|
|
164
|
-
}
|
|
165
|
-
validateConfigValue(setting, value);
|
|
166
|
-
setNestedConfigValue(getRuntimeConfig(configManager), key, value);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
export function applyRuntimeConfigOverrides(
|
|
170
|
-
configManager: ConfigManager,
|
|
171
|
-
overrides: readonly string[],
|
|
172
|
-
): readonly string[] {
|
|
173
|
-
const errors: string[] = [];
|
|
174
|
-
for (const override of overrides) {
|
|
175
|
-
const index = override.indexOf('=');
|
|
176
|
-
if (index <= 0) {
|
|
177
|
-
errors.push(`Invalid --config override "${override}". Expected key=value.`);
|
|
178
|
-
continue;
|
|
179
|
-
}
|
|
180
|
-
const key = override.slice(0, index) as ConfigKey;
|
|
181
|
-
const rawValue = override.slice(index + 1);
|
|
182
|
-
try {
|
|
183
|
-
applyRuntimeConfigValue(configManager, key, parseConfigOverrideValue(rawValue));
|
|
184
|
-
} catch (error) {
|
|
185
|
-
errors.push(error instanceof Error ? `Invalid --config ${override}: ${error.message}` : `Invalid --config ${override}`);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
return errors;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Session-only feature overrides (--enable-feature / --disable-feature).
|
|
193
|
-
* Each feature is switched through its real domain settings key (e.g.
|
|
194
|
-
* sandbox.enabled, behavior.compactionStrategy) in the runtime config layer;
|
|
195
|
-
* features without an off position (constant capabilities on non-boolean
|
|
196
|
-
* keys) and unknown ids are reported as errors rather than silently ignored.
|
|
197
|
-
*/
|
|
198
|
-
export function applyRuntimeFeatureFlagOverrides(
|
|
199
|
-
configManager: ConfigManager,
|
|
200
|
-
options: {
|
|
201
|
-
readonly enableFeatures: readonly string[];
|
|
202
|
-
readonly disableFeatures: readonly string[];
|
|
203
|
-
},
|
|
204
|
-
): readonly string[] {
|
|
205
|
-
if (options.enableFeatures.length === 0 && options.disableFeatures.length === 0) return [];
|
|
206
|
-
const config = getRuntimeConfig(configManager);
|
|
207
|
-
const errors: string[] = [];
|
|
208
|
-
const apply = (feature: string, enabled: boolean, flagName: string): void => {
|
|
209
|
-
const write = featureEnablementWrite(feature, enabled);
|
|
210
|
-
if (!write) {
|
|
211
|
-
errors.push(getFeatureSetting(feature)
|
|
212
|
-
? `${flagName} ${feature}: this capability has no ${enabled ? 'on' : 'off'} switch (its domain settings govern it directly).`
|
|
213
|
-
: `${flagName} ${feature}: unknown feature id.`);
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
setNestedConfigValue(config, write.key, write.value);
|
|
217
|
-
};
|
|
218
|
-
for (const feature of options.enableFeatures) apply(feature, true, '--enable-feature');
|
|
219
|
-
for (const feature of options.disableFeatures) apply(feature, false, '--disable-feature');
|
|
220
|
-
return errors;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
export function applyRuntimeEndpointFlagOverrides(
|
|
224
|
-
configManager: ConfigManager,
|
|
225
|
-
endpoint: RuntimeEndpointId,
|
|
226
|
-
flags: Pick<GoodVibesCliFlags, 'hostname' | 'port'>,
|
|
227
|
-
): readonly string[] {
|
|
228
|
-
const keys = RUNTIME_ENDPOINT_CONFIG_KEYS[endpoint];
|
|
229
|
-
const errors: string[] = [];
|
|
230
|
-
|
|
231
|
-
if (flags.hostname !== undefined) {
|
|
232
|
-
try {
|
|
233
|
-
applyRuntimeConfigValue(configManager, keys.hostMode, hostModeForHostname(flags.hostname));
|
|
234
|
-
applyRuntimeConfigValue(configManager, keys.host, flags.hostname);
|
|
235
|
-
} catch (error) {
|
|
236
|
-
errors.push(error instanceof Error
|
|
237
|
-
? `Invalid --hostname ${flags.hostname}: ${error.message}`
|
|
238
|
-
: `Invalid --hostname ${flags.hostname}`);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
if (flags.port !== undefined) {
|
|
243
|
-
try {
|
|
244
|
-
applyRuntimeConfigValue(configManager, keys.port, flags.port);
|
|
245
|
-
} catch (error) {
|
|
246
|
-
errors.push(error instanceof Error
|
|
247
|
-
? `Invalid --port ${flags.port}: ${error.message}`
|
|
248
|
-
: `Invalid --port ${flags.port}`);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
return errors;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
export function applyRuntimeCommandEndpointFlagOverrides(
|
|
256
|
-
configManager: ConfigManager,
|
|
257
|
-
command: GoodVibesCliCommand,
|
|
258
|
-
flags: Pick<GoodVibesCliFlags, 'hostname' | 'port'>,
|
|
259
|
-
): readonly string[] {
|
|
260
|
-
if (flags.hostname === undefined && flags.port === undefined) return [];
|
|
261
|
-
if (command === 'web') return applyRuntimeEndpointFlagOverrides(configManager, 'web', flags);
|
|
262
|
-
if (command === 'listener') return applyRuntimeEndpointFlagOverrides(configManager, 'httpListener', flags);
|
|
263
|
-
if (command === 'control-plane' || command === 'pair' || command === 'serve') {
|
|
264
|
-
return applyRuntimeEndpointFlagOverrides(configManager, 'controlPlane', flags);
|
|
265
|
-
}
|
|
266
|
-
return [];
|
|
267
|
-
}
|
package/src/cli/endpoints.ts
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import type { ConfigKey, ConfigManager } from '../config/index.ts';
|
|
2
|
-
|
|
3
|
-
export type RuntimeEndpointId = 'controlPlane' | 'httpListener' | 'web';
|
|
4
|
-
export type RuntimeHostMode = 'local' | 'network' | 'custom';
|
|
5
|
-
|
|
6
|
-
export const RUNTIME_ENDPOINT_DEFAULT_PORTS: Record<RuntimeEndpointId, number> = {
|
|
7
|
-
controlPlane: 3421,
|
|
8
|
-
httpListener: 3422,
|
|
9
|
-
web: 3423,
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export const RUNTIME_ENDPOINT_CONFIG_KEYS: Record<RuntimeEndpointId, {
|
|
13
|
-
readonly hostMode: ConfigKey;
|
|
14
|
-
readonly host: ConfigKey;
|
|
15
|
-
readonly port: ConfigKey;
|
|
16
|
-
}> = {
|
|
17
|
-
controlPlane: {
|
|
18
|
-
hostMode: 'controlPlane.hostMode',
|
|
19
|
-
host: 'controlPlane.host',
|
|
20
|
-
port: 'controlPlane.port',
|
|
21
|
-
},
|
|
22
|
-
httpListener: {
|
|
23
|
-
hostMode: 'httpListener.hostMode',
|
|
24
|
-
host: 'httpListener.host',
|
|
25
|
-
port: 'httpListener.port',
|
|
26
|
-
},
|
|
27
|
-
web: {
|
|
28
|
-
hostMode: 'web.hostMode',
|
|
29
|
-
host: 'web.host',
|
|
30
|
-
port: 'web.port',
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export interface RuntimeEndpointBinding {
|
|
35
|
-
readonly hostMode: string;
|
|
36
|
-
readonly configuredHost: string;
|
|
37
|
-
readonly host: string;
|
|
38
|
-
readonly port: number;
|
|
39
|
-
/**
|
|
40
|
-
* False when the stored hostMode is not one of the SDK's recognized modes
|
|
41
|
-
* ('local' | 'network' | 'custom'). The SDK's resolveHostBinding is a switch
|
|
42
|
-
* with NO default case: an unrecognized mode yields an undefined binding and
|
|
43
|
-
* the daemon throws in its constructor before ever binding. Displays must
|
|
44
|
-
* therefore never present the host/port below as a definite binding when
|
|
45
|
-
* this is false — the fallback values exist only so display code has
|
|
46
|
-
* something structured to show alongside the warning.
|
|
47
|
-
*/
|
|
48
|
-
readonly recognized: boolean;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* THE one display seam for endpoint bindings: every surface that renders a
|
|
53
|
-
* binding as text goes through this, so no surface can present the resolver's
|
|
54
|
-
* loopback fallback as a definite bind for a hostMode the SDK cannot handle
|
|
55
|
-
* (its bind resolver has no default case — the daemon throws before binding).
|
|
56
|
-
* The recognized case renders the familiar `<mode> <host>:<port>`.
|
|
57
|
-
*/
|
|
58
|
-
export function formatRuntimeEndpointBinding(binding: RuntimeEndpointBinding): string {
|
|
59
|
-
if (binding.recognized) {
|
|
60
|
-
return `${binding.hostMode} ${binding.host}:${binding.port}`;
|
|
61
|
-
}
|
|
62
|
-
return `'${binding.hostMode}' — not a recognized host mode (expected local|network|custom); the daemon cannot bind this endpoint until it is corrected`;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export function hostModeForHostname(hostname: string): RuntimeHostMode {
|
|
66
|
-
const normalized = hostname.toLowerCase();
|
|
67
|
-
if (normalized === '0.0.0.0' || normalized === '::') return 'network';
|
|
68
|
-
if (normalized === '127.0.0.1' || normalized === 'localhost' || normalized === '::1') return 'local';
|
|
69
|
-
return 'custom';
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export function resolveRuntimeEndpointBinding(
|
|
73
|
-
config: Pick<ConfigManager, 'get'>,
|
|
74
|
-
endpoint: RuntimeEndpointId,
|
|
75
|
-
): RuntimeEndpointBinding {
|
|
76
|
-
const keys = RUNTIME_ENDPOINT_CONFIG_KEYS[endpoint];
|
|
77
|
-
const hostMode = String(config.get(keys.hostMode) ?? 'local');
|
|
78
|
-
const configuredHost = String(config.get(keys.host) ?? '127.0.0.1');
|
|
79
|
-
// Port coercion is anchored PER ENDPOINT to what the SDK actually does with
|
|
80
|
-
// the stored value, so a display never disagrees with the machinery:
|
|
81
|
-
// - controlPlane / httpListener bind via resolveHostBinding, which is fed
|
|
82
|
-
// `Number(raw ?? default)` and applies `customPort || DEFAULT` — a
|
|
83
|
-
// stored 0 or non-numeric value collapses to the endpoint default.
|
|
84
|
-
// - web has NO resolveHostBinding consumer in the SDK at all; its closest
|
|
85
|
-
// machinery (resolveWebPort, which drives tailscale-serve, plus the
|
|
86
|
-
// surface registry/announcements) uses bare `Number(raw ?? default)`
|
|
87
|
-
// with no || collapse — 0 stays 0 and a non-numeric value stays NaN.
|
|
88
|
-
// Collapsing here would make the display assert a port the tailscale/
|
|
89
|
-
// announcement machinery is not actually using. (The SDK's web-port
|
|
90
|
-
// handling is inconsistent-by-absence — a proper resolveHostBinding-style
|
|
91
|
-
// web resolver is an SDK-side fix; until then this mirrors resolveWebPort.)
|
|
92
|
-
const rawPort = Number(config.get(keys.port) ?? RUNTIME_ENDPOINT_DEFAULT_PORTS[endpoint]);
|
|
93
|
-
const port = endpoint === 'web' ? rawPort : (rawPort || RUNTIME_ENDPOINT_DEFAULT_PORTS[endpoint]);
|
|
94
|
-
if (hostMode === 'network') {
|
|
95
|
-
return { hostMode, configuredHost, host: '0.0.0.0', port, recognized: true };
|
|
96
|
-
}
|
|
97
|
-
if (hostMode === 'custom') {
|
|
98
|
-
return { hostMode, configuredHost, host: configuredHost || '127.0.0.1', port, recognized: true };
|
|
99
|
-
}
|
|
100
|
-
if (hostMode === 'local') {
|
|
101
|
-
return { hostMode, configuredHost, host: '127.0.0.1', port, recognized: true };
|
|
102
|
-
}
|
|
103
|
-
// Unrecognized hostMode ('LAN', 'Network', '', a trimmed variant, …): the
|
|
104
|
-
// SDK bind path has NO default case for this — resolveHostBinding returns
|
|
105
|
-
// undefined and the daemon throws before binding. There IS no real binding
|
|
106
|
-
// to display; recognized:false tells callers to warn instead of asserting
|
|
107
|
-
// the loopback fallback below as fact.
|
|
108
|
-
return { hostMode, configuredHost, host: '127.0.0.1', port, recognized: false };
|
|
109
|
-
}
|