@pellux/goodvibes-tui 1.27.1 → 2.0.1
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 +116 -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 +13 -80
- 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 +1 -1
- 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,111 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* fatal-boot-report.ts — saying why, on a stream, before the process stops.
|
|
3
|
-
*
|
|
4
|
-
* ── Where this module comes from ──────────────────────────────────────────
|
|
5
|
-
*
|
|
6
|
-
* This is a local mirror of the SDK's `platform/daemon/fatal-boot-report.ts`,
|
|
7
|
-
* kept identical in shape and in exported names (`writeFatalLine`,
|
|
8
|
-
* `writeExitingStdoutLine`, `reportFatalBootFailure`). It lives here only
|
|
9
|
-
* because the published `@pellux/goodvibes-sdk` this repository compiles
|
|
10
|
-
* against predates that export — importing it would not typecheck and CI
|
|
11
|
-
* builds against the published package regardless. Delete this file and switch
|
|
12
|
-
* every importer to the SDK's copy at the next re-pin — but check the SDK's
|
|
13
|
-
* `package.json` "exports" map first: as of the 1.21.0 re-pin (2026-07-30),
|
|
14
|
-
* the compiled `dist/platform/daemon/fatal-boot-report.js` still exists
|
|
15
|
-
* inside the published tarball and `cli.js` still imports it internally, but
|
|
16
|
-
* there is no `./platform/daemon/fatal-boot-report` (or any other) entry in
|
|
17
|
-
* "exports" that makes it importable from outside the package — confirmed by
|
|
18
|
-
* attempting `import { reportFatalBootFailure } from
|
|
19
|
-
* '@pellux/goodvibes-sdk/platform/daemon/fatal-boot-report'`, which Bun
|
|
20
|
-
* refuses to resolve. This file stays load-bearing until a future SDK release
|
|
21
|
-
* adds that subpath export.
|
|
22
|
-
*
|
|
23
|
-
* ── The failure this exists to close ──────────────────────────────────────
|
|
24
|
-
*
|
|
25
|
-
* The shipped daemon died mute. Measured, against the released 1.27.0 binary
|
|
26
|
-
* in an isolated home with an unparseable `.goodvibes/daemon/settings.json`:
|
|
27
|
-
* exit code 1, **zero bytes on stdout, zero bytes on stderr, and no activity
|
|
28
|
-
* log written at all**. It crash-looped 77 times overnight and the only signal
|
|
29
|
-
* an operator had was that everything had stopped.
|
|
30
|
-
*
|
|
31
|
-
* The mechanism was not buffering and not a bypassed handler. It was simpler:
|
|
32
|
-
* `daemon/cli.ts` reported the failure to the activity LOGGER and exited, and
|
|
33
|
-
* at that point in boot the logger had no destination — the daemon entrypoint
|
|
34
|
-
* never called `configureActivityLogger` at all — so the line went nowhere and
|
|
35
|
-
* no file descriptor was ever touched. A `logger.error` is not a disclosure.
|
|
36
|
-
* Only a write to a file descriptor is.
|
|
37
|
-
*
|
|
38
|
-
* ── Why `writeSync(2, …)` and not `process.stderr.write` ──────────────────
|
|
39
|
-
*
|
|
40
|
-
* Because the fatal path must not depend on anything a host can replace or
|
|
41
|
-
* defer. `process.stderr.write` is a property on a mutable global, and THIS
|
|
42
|
-
* repository is the one that replaces it: `src/runtime/terminal-output-guard.ts`
|
|
43
|
-
* intercepts terminal output to keep the rendered screen clean, and a replaced
|
|
44
|
-
* writer that records instead of printing turns a fatal error into silence. It
|
|
45
|
-
* is also a stream, so a write issued immediately before `process.exit()` can
|
|
46
|
-
* still be in flight when the process stops existing.
|
|
47
|
-
*
|
|
48
|
-
* `writeSync(fd, …)` is neither. It is a direct write to the descriptor the
|
|
49
|
-
* service journal is attached to, it has completed when it returns, and no
|
|
50
|
-
* amount of replacing `process.stderr` upstream can intercept it. That is the
|
|
51
|
-
* whole property this module provides, and it is why every early-exit site in
|
|
52
|
-
* the daemon boot path routes through here.
|
|
53
|
-
*/
|
|
54
|
-
|
|
55
|
-
import { writeSync } from 'node:fs';
|
|
56
|
-
import { flushActivityLogSync, logger, summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
57
|
-
|
|
58
|
-
/** stdout and stderr, as the file descriptors they actually are. */
|
|
59
|
-
const STDOUT_FD = 1;
|
|
60
|
-
const STDERR_FD = 2;
|
|
61
|
-
|
|
62
|
-
function writeLineToFd(fd: number, line: string): void {
|
|
63
|
-
try {
|
|
64
|
-
writeSync(fd, line.endsWith('\n') ? line : `${line}\n`);
|
|
65
|
-
} catch {
|
|
66
|
-
// A closed or unwritable descriptor must never turn a diagnostic into a
|
|
67
|
-
// second failure. There is nothing further to fall back to: this IS the
|
|
68
|
-
// fallback.
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Write one line to stderr synchronously, immune to a replaced
|
|
74
|
-
* `process.stderr` and to exit-time truncation. Use this for anything that
|
|
75
|
-
* gates a process exit.
|
|
76
|
-
*/
|
|
77
|
-
export function writeFatalLine(line: string): void {
|
|
78
|
-
writeLineToFd(STDERR_FD, line);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* The stdout twin, for output that must survive an exit that follows it — the
|
|
83
|
-
* help text, the version line, the service-subcommand receipt and the cluster
|
|
84
|
-
* output are all printed and then immediately exited on, which is the same
|
|
85
|
-
* race.
|
|
86
|
-
*/
|
|
87
|
-
export function writeExitingStdoutLine(line: string): void {
|
|
88
|
-
writeLineToFd(STDOUT_FD, line);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Report a fatal boot failure everywhere it can be found, then leave the exit
|
|
93
|
-
* to the caller.
|
|
94
|
-
*
|
|
95
|
-
* The stream write happens FIRST and synchronously. The activity log is
|
|
96
|
-
* attempted after, because it is the part that can fail — it needs a
|
|
97
|
-
* configured destination, a writable directory, and a flush — and the
|
|
98
|
-
* guarantee this function makes is the stream line, not the log line.
|
|
99
|
-
*/
|
|
100
|
-
export function reportFatalBootFailure(error: unknown, context = 'goodvibes daemon host'): void {
|
|
101
|
-
const summary = summarizeError(error);
|
|
102
|
-
writeFatalLine(`${context} failed: ${summary}`);
|
|
103
|
-
if (error instanceof Error && error.stack) writeFatalLine(error.stack);
|
|
104
|
-
try {
|
|
105
|
-
logger.error(`${context} failed`, { error: summary });
|
|
106
|
-
flushActivityLogSync();
|
|
107
|
-
} catch {
|
|
108
|
-
// The reason is already on stderr, which is the guarantee. A log that
|
|
109
|
-
// cannot be written must not escalate into a different failure.
|
|
110
|
-
}
|
|
111
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Host-facing context passed to every surface register function. Replaces the
|
|
3
|
-
* former OperatorContext. It carries the SDK gateway catalog (handlers attach
|
|
4
|
-
* to it), the daemon credential store, a read-only slice of the config manager,
|
|
5
|
-
* resolved directories, and a logger. No SDK descriptor or schema is declared
|
|
6
|
-
* here — the catalog type is re-exported through the contracts seam.
|
|
7
|
-
*/
|
|
8
|
-
import type { ConfigManager } from '@pellux/goodvibes-sdk/platform/config';
|
|
9
|
-
import type { GatewayMethodCatalog } from './contracts.ts';
|
|
10
|
-
import type { DaemonCredentialStore } from './credentials.ts';
|
|
11
|
-
import type { Unregister } from './register.ts';
|
|
12
|
-
|
|
13
|
-
export interface HandlerLogger {
|
|
14
|
-
info(message: string, meta?: unknown): void;
|
|
15
|
-
warn(message: string, meta?: unknown): void;
|
|
16
|
-
error(message: string, meta?: unknown): void;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface HandlerContext {
|
|
20
|
-
readonly catalog: GatewayMethodCatalog;
|
|
21
|
-
readonly credentials: DaemonCredentialStore;
|
|
22
|
-
readonly configManager: Pick<ConfigManager, 'get' | 'getCategory'>;
|
|
23
|
-
readonly workingDirectory: string;
|
|
24
|
-
readonly homeDirectory: string;
|
|
25
|
-
readonly logger: HandlerLogger;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/** Every surface module exports a register function of this shape. */
|
|
29
|
-
export type SurfaceRegister = (ctx: HandlerContext) => Unregister;
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Single SDK-contract import seam for the daemon handler layer.
|
|
3
|
-
*
|
|
4
|
-
* Every other module under `src/daemon/handlers/` imports SDK contract
|
|
5
|
-
* identifiers from HERE and nowhere else. Concentrating the SDK imports in one
|
|
6
|
-
* concrete-submodule module keeps the rest of the layer free of barrel cycles
|
|
7
|
-
* and guarantees the host NEVER re-declares an SDK id, descriptor, or schema —
|
|
8
|
-
* it only attaches handlers to the descriptors the SDK already registered.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
// Catalog + invocation contract types (concrete control-plane subpath, not a project barrel).
|
|
12
|
-
export type {
|
|
13
|
-
GatewayMethodCatalog,
|
|
14
|
-
GatewayMethodDescriptor,
|
|
15
|
-
GatewayMethodInvocation,
|
|
16
|
-
GatewayMethodInvocationContext,
|
|
17
|
-
GatewayMethodHandler,
|
|
18
|
-
} from '@pellux/goodvibes-sdk/platform/control-plane';
|
|
19
|
-
|
|
20
|
-
// Channel domain types reused in handler signatures (read-only SDK interfaces; never re-declared).
|
|
21
|
-
export type {
|
|
22
|
-
ChannelIdentity,
|
|
23
|
-
ChannelResolvedTarget,
|
|
24
|
-
ChannelAccountRecord,
|
|
25
|
-
} from '@pellux/goodvibes-sdk/platform/channels';
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Per-peer authentication envelope passed to peer-scoped remote routes.
|
|
29
|
-
*
|
|
30
|
-
* The daemon-sdk ships `RemotePeerAuth` only as an UNEXPORTED local alias
|
|
31
|
-
* inside `@pellux/goodvibes-daemon-sdk/remote-routes` (it is `unknown` there),
|
|
32
|
-
* so it cannot be re-exported. We mirror that exact shape here for the host
|
|
33
|
-
* implementation. This is an implementable runtime contract, not a method
|
|
34
|
-
* descriptor or schema — declaring it does not violate the no-re-declaration
|
|
35
|
-
* rule for catalog methods.
|
|
36
|
-
*/
|
|
37
|
-
export type RemotePeerAuth = unknown;
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Remote distributed-runtime route service the HOST must implement and supply
|
|
41
|
-
* as `RuntimeServices.distributedRuntime`. The SDK facade injects the instance
|
|
42
|
-
* into `DaemonRemoteRouteContext.distributedRuntime` so the published
|
|
43
|
-
* `remote.peers.*` HTTP routes can dispatch to it.
|
|
44
|
-
*
|
|
45
|
-
* The daemon-sdk declares this interface locally in
|
|
46
|
-
* `@pellux/goodvibes-daemon-sdk/remote-routes` but does NOT export it (the
|
|
47
|
-
* module ends with `export {}`), so it cannot be imported. This declaration
|
|
48
|
-
* mirrors the SDK's exact structural shape (17 methods, verbatim signatures)
|
|
49
|
-
* so a host implementation is assignable to the SDK's context field. The SDK
|
|
50
|
-
* ships no docker/ssh/cloud backend — the host owns the implementation.
|
|
51
|
-
*/
|
|
52
|
-
export interface DistributedRuntimeRouteService {
|
|
53
|
-
listPairRequests(): unknown;
|
|
54
|
-
approvePairRequest(requestId: string, input: Record<string, unknown>): Promise<unknown | null>;
|
|
55
|
-
rejectPairRequest(requestId: string, input: Record<string, unknown>): Promise<unknown | null>;
|
|
56
|
-
listPeers(): unknown;
|
|
57
|
-
rotatePeerToken(peerId: string, input: Record<string, unknown>): Promise<unknown | null>;
|
|
58
|
-
revokePeerToken(peerId: string, input: Record<string, unknown>): Promise<unknown | null>;
|
|
59
|
-
disconnectPeer(peerId: string, input: Record<string, unknown>): Promise<unknown | null>;
|
|
60
|
-
listWork(): unknown;
|
|
61
|
-
invokePeer(input: Record<string, unknown>): Promise<unknown>;
|
|
62
|
-
cancelWork(workId: string, input: Record<string, unknown>): Promise<unknown | null>;
|
|
63
|
-
getNodeHostContract(): unknown;
|
|
64
|
-
requestPairing(input: Record<string, unknown>): Promise<unknown>;
|
|
65
|
-
verifyPairRequest(
|
|
66
|
-
requestId: string,
|
|
67
|
-
challenge: string,
|
|
68
|
-
input: Record<string, unknown>,
|
|
69
|
-
): Promise<unknown | null>;
|
|
70
|
-
heartbeatPeer(auth: RemotePeerAuth, input: Record<string, unknown>): Promise<unknown>;
|
|
71
|
-
claimWork(auth: RemotePeerAuth, input: Record<string, unknown>): Promise<unknown>;
|
|
72
|
-
completeWork(
|
|
73
|
-
auth: RemotePeerAuth,
|
|
74
|
-
workId: string,
|
|
75
|
-
input: Record<string, unknown>,
|
|
76
|
-
): Promise<unknown | null>;
|
|
77
|
-
}
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';
|
|
2
|
-
import type { SecretsManager, SecretScope } from '../../config/secrets.ts';
|
|
3
|
-
import {
|
|
4
|
-
buildGoodVibesSecretKey,
|
|
5
|
-
isSecretReferenceValue,
|
|
6
|
-
} from '../../config/secret-config.ts';
|
|
7
|
-
|
|
8
|
-
export interface DaemonCredentialStore {
|
|
9
|
-
/**
|
|
10
|
-
* Resolve a goodvibes://secrets/ reference OR a raw secret key to its
|
|
11
|
-
* plaintext value (daemon-internal only).
|
|
12
|
-
*/
|
|
13
|
-
resolveRef(ref: string): Promise<string | null>;
|
|
14
|
-
/**
|
|
15
|
-
* Resolve a config-key-derived secret
|
|
16
|
-
* (e.g. 'surfaces.slack.botToken' → GOODVIBES_SURFACES_SLACK_BOT_TOKEN).
|
|
17
|
-
*/
|
|
18
|
-
resolveConfigSecret(configKey: string): Promise<string | null>;
|
|
19
|
-
/**
|
|
20
|
-
* Store a daemon-owned credential. scope defaults 'daemon'.
|
|
21
|
-
*
|
|
22
|
-
* This is the DAEMON's own credential store: every caller is daemon code, and
|
|
23
|
-
* every value written through it is one the daemon itself has to read back —
|
|
24
|
-
* including its own generated draft encryption key (createAtRestCipher below,
|
|
25
|
-
* which calls put() with no scope at all). Defaulting to 'user' filed those
|
|
26
|
-
* in a surface-scoped tier, so the daemon's own material lived somewhere it
|
|
27
|
-
* only found by accident, and a value written on one surface's behalf was
|
|
28
|
-
* invisible to the next.
|
|
29
|
-
*/
|
|
30
|
-
put(
|
|
31
|
-
secretKey: string,
|
|
32
|
-
value: string,
|
|
33
|
-
opts?: { scope?: SecretScope; medium?: 'plaintext' | 'secure' },
|
|
34
|
-
): Promise<void>;
|
|
35
|
-
has(secretKey: string): Promise<boolean>;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** Extract the trailing secret-key segment from a goodvibes://secrets/ reference. */
|
|
39
|
-
function secretKeyFromReference(ref: string): string {
|
|
40
|
-
const normalized = ref.trim();
|
|
41
|
-
const segments = normalized.split('/');
|
|
42
|
-
const last = segments[segments.length - 1] ?? '';
|
|
43
|
-
return decodeURIComponent(last);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function createDaemonCredentialStore(secrets: SecretsManager): DaemonCredentialStore {
|
|
47
|
-
return {
|
|
48
|
-
async resolveRef(ref: string): Promise<string | null> {
|
|
49
|
-
const key = isSecretReferenceValue(ref) ? secretKeyFromReference(ref) : ref;
|
|
50
|
-
return secrets.get(key);
|
|
51
|
-
},
|
|
52
|
-
async resolveConfigSecret(configKey: string): Promise<string | null> {
|
|
53
|
-
return secrets.get(buildGoodVibesSecretKey(configKey));
|
|
54
|
-
},
|
|
55
|
-
async put(
|
|
56
|
-
secretKey: string,
|
|
57
|
-
value: string,
|
|
58
|
-
opts?: { scope?: SecretScope; medium?: 'plaintext' | 'secure' },
|
|
59
|
-
): Promise<void> {
|
|
60
|
-
await secrets.set(secretKey, value, {
|
|
61
|
-
scope: opts?.scope ?? 'daemon',
|
|
62
|
-
medium: opts?.medium ?? 'secure',
|
|
63
|
-
});
|
|
64
|
-
},
|
|
65
|
-
async has(secretKey: string): Promise<boolean> {
|
|
66
|
-
const value = await secrets.get(secretKey);
|
|
67
|
-
return value !== null && value.length > 0;
|
|
68
|
-
},
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// ---------------------------------------------------------------------------
|
|
73
|
-
// At-rest encryption helper for drafts (draft body must be encrypted at rest).
|
|
74
|
-
// ---------------------------------------------------------------------------
|
|
75
|
-
|
|
76
|
-
export interface AtRestCipher {
|
|
77
|
-
encrypt(plaintext: string): Promise<string>;
|
|
78
|
-
decrypt(ciphertext: string): Promise<string>;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const DEFAULT_DRAFT_KEY_NAME = 'GOODVIBES_DAEMON_DRAFT_AESKEY';
|
|
82
|
-
const AES_KEY_BYTES = 32; // AES-256
|
|
83
|
-
const GCM_IV_BYTES = 12;
|
|
84
|
-
const GCM_TAG_BYTES = 16;
|
|
85
|
-
|
|
86
|
-
async function loadOrCreateKey(
|
|
87
|
-
store: DaemonCredentialStore,
|
|
88
|
-
keyName: string,
|
|
89
|
-
): Promise<Buffer> {
|
|
90
|
-
const existing = await store.resolveRef(keyName);
|
|
91
|
-
if (existing && existing.length > 0) {
|
|
92
|
-
const buf = Buffer.from(existing, 'base64');
|
|
93
|
-
if (buf.length === AES_KEY_BYTES) return buf;
|
|
94
|
-
}
|
|
95
|
-
const generated = randomBytes(AES_KEY_BYTES);
|
|
96
|
-
await store.put(keyName, generated.toString('base64'), { medium: 'secure' });
|
|
97
|
-
return generated;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Create an AES-256-GCM at-rest cipher backed by a daemon-owned key.
|
|
102
|
-
* encrypt() returns base64(iv | tag | ciphertext). Uses node:crypto (Bun-compatible).
|
|
103
|
-
* NEVER log resolved keys or plaintext.
|
|
104
|
-
*/
|
|
105
|
-
export function createAtRestCipher(
|
|
106
|
-
store: DaemonCredentialStore,
|
|
107
|
-
keyName: string = DEFAULT_DRAFT_KEY_NAME,
|
|
108
|
-
): AtRestCipher {
|
|
109
|
-
let keyPromise: Promise<Buffer> | null = null;
|
|
110
|
-
const getKey = (): Promise<Buffer> => {
|
|
111
|
-
if (!keyPromise) keyPromise = loadOrCreateKey(store, keyName);
|
|
112
|
-
return keyPromise;
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
return {
|
|
116
|
-
async encrypt(plaintext: string): Promise<string> {
|
|
117
|
-
const key = await getKey();
|
|
118
|
-
const iv = randomBytes(GCM_IV_BYTES);
|
|
119
|
-
const cipher = createCipheriv('aes-256-gcm', key, iv);
|
|
120
|
-
const encrypted = Buffer.concat([
|
|
121
|
-
cipher.update(plaintext, 'utf-8'),
|
|
122
|
-
cipher.final(),
|
|
123
|
-
]);
|
|
124
|
-
const tag = cipher.getAuthTag();
|
|
125
|
-
return Buffer.concat([iv, tag, encrypted]).toString('base64');
|
|
126
|
-
},
|
|
127
|
-
async decrypt(ciphertext: string): Promise<string> {
|
|
128
|
-
const key = await getKey();
|
|
129
|
-
const raw = Buffer.from(ciphertext, 'base64');
|
|
130
|
-
const iv = raw.subarray(0, GCM_IV_BYTES);
|
|
131
|
-
const tag = raw.subarray(GCM_IV_BYTES, GCM_IV_BYTES + GCM_TAG_BYTES);
|
|
132
|
-
const data = raw.subarray(GCM_IV_BYTES + GCM_TAG_BYTES);
|
|
133
|
-
const decipher = createDecipheriv('aes-256-gcm', key, iv);
|
|
134
|
-
decipher.setAuthTag(tag);
|
|
135
|
-
const decrypted = Buffer.concat([decipher.update(data), decipher.final()]);
|
|
136
|
-
return decrypted.toString('utf-8');
|
|
137
|
-
},
|
|
138
|
-
};
|
|
139
|
-
}
|