@pellux/goodvibes-agent 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.goodvibes/GOODVIBES.md +35 -0
- package/.goodvibes/agents/reviewer.md +48 -0
- package/.goodvibes/skills/add-provider/SKILL.md +199 -0
- package/CHANGELOG.md +25 -0
- package/README.md +74 -0
- package/bin/goodvibes-agent.ts +2 -0
- package/docs/README.md +23 -0
- package/docs/deployment-and-services.md +57 -0
- package/docs/getting-started.md +53 -0
- package/docs/release-and-publishing.md +46 -0
- package/package.json +134 -0
- package/scripts/check-bun.sh +20 -0
- package/src/audio/player.ts +156 -0
- package/src/audio/spoken-turn-controller.ts +203 -0
- package/src/audio/spoken-turn-model-routing.ts +117 -0
- package/src/audio/spoken-turn-wiring.ts +44 -0
- package/src/audio/text-chunker.ts +110 -0
- package/src/cli/bundle-command.ts +227 -0
- package/src/cli/completion.ts +90 -0
- package/src/cli/config-overrides.ts +159 -0
- package/src/cli/endpoints.ts +63 -0
- package/src/cli/entrypoint.ts +172 -0
- package/src/cli/help.ts +299 -0
- package/src/cli/index.ts +11 -0
- package/src/cli/management-commands.ts +426 -0
- package/src/cli/management.ts +744 -0
- package/src/cli/network-posture.ts +46 -0
- package/src/cli/package-verification.ts +123 -0
- package/src/cli/parser.ts +369 -0
- package/src/cli/provider-auth-routes.ts +22 -0
- package/src/cli/provider-classification.ts +107 -0
- package/src/cli/redaction.ts +105 -0
- package/src/cli/service-command.ts +26 -0
- package/src/cli/service-posture.ts +482 -0
- package/src/cli/status.ts +383 -0
- package/src/cli/surface-command.ts +247 -0
- package/src/cli/tui-startup.ts +32 -0
- package/src/cli/types.ts +69 -0
- package/src/cli-flags.ts +21 -0
- package/src/config/goodvibes-home-audit.ts +465 -0
- package/src/config/index.ts +57 -0
- package/src/config/provider-model.ts +23 -0
- package/src/config/secret-config.ts +119 -0
- package/src/config/secrets.ts +71 -0
- package/src/config/surface.ts +1 -0
- package/src/core/composer-state.ts +61 -0
- package/src/core/conversation-rendering.ts +359 -0
- package/src/core/conversation.ts +551 -0
- package/src/core/history.ts +45 -0
- package/src/core/orchestrator.ts +7 -0
- package/src/core/system-message-router.ts +171 -0
- package/src/daemon/cli.ts +55 -0
- package/src/daemon/safe-serve.ts +61 -0
- package/src/input/agent-workspace.ts +428 -0
- package/src/input/autocomplete.ts +96 -0
- package/src/input/bookmark-modal.ts +115 -0
- package/src/input/command-args-hint.ts +36 -0
- package/src/input/command-registry.ts +329 -0
- package/src/input/commands/agent-externalized-tui.ts +73 -0
- package/src/input/commands/agent-workspace-runtime.ts +17 -0
- package/src/input/commands/branch-runtime.ts +72 -0
- package/src/input/commands/cloudflare-runtime.ts +370 -0
- package/src/input/commands/config.ts +18 -0
- package/src/input/commands/control-room-runtime.ts +255 -0
- package/src/input/commands/conversation-runtime.ts +207 -0
- package/src/input/commands/discovery-runtime.ts +52 -0
- package/src/input/commands/eval.ts +204 -0
- package/src/input/commands/experience-runtime.ts +278 -0
- package/src/input/commands/guidance-runtime.ts +106 -0
- package/src/input/commands/health-runtime.ts +434 -0
- package/src/input/commands/hooks-runtime.ts +148 -0
- package/src/input/commands/incident-runtime.ts +95 -0
- package/src/input/commands/integration-runtime.ts +394 -0
- package/src/input/commands/intelligence-runtime.ts +223 -0
- package/src/input/commands/knowledge.ts +531 -0
- package/src/input/commands/local-auth-runtime.ts +105 -0
- package/src/input/commands/local-provider-runtime.ts +170 -0
- package/src/input/commands/local-runtime.ts +392 -0
- package/src/input/commands/local-setup-review.ts +199 -0
- package/src/input/commands/local-setup-transfer.ts +135 -0
- package/src/input/commands/local-setup.ts +282 -0
- package/src/input/commands/managed-runtime.ts +209 -0
- package/src/input/commands/marketplace-runtime.ts +290 -0
- package/src/input/commands/mcp-runtime.ts +432 -0
- package/src/input/commands/memory-product-runtime.ts +111 -0
- package/src/input/commands/memory.ts +151 -0
- package/src/input/commands/notify-runtime.ts +83 -0
- package/src/input/commands/onboarding-runtime.ts +14 -0
- package/src/input/commands/operator-panel-runtime.ts +146 -0
- package/src/input/commands/operator-runtime.ts +392 -0
- package/src/input/commands/planning-runtime.ts +205 -0
- package/src/input/commands/platform-access-runtime.ts +422 -0
- package/src/input/commands/platform-services-runtime.ts +246 -0
- package/src/input/commands/policy-dispatch.ts +339 -0
- package/src/input/commands/policy.ts +17 -0
- package/src/input/commands/product-runtime.ts +351 -0
- package/src/input/commands/profile-sync-runtime.ts +99 -0
- package/src/input/commands/provider-accounts-runtime.ts +113 -0
- package/src/input/commands/provider.ts +363 -0
- package/src/input/commands/qrcode-runtime.ts +20 -0
- package/src/input/commands/quit-shared.ts +162 -0
- package/src/input/commands/recall-bundle.ts +132 -0
- package/src/input/commands/recall-capture.ts +152 -0
- package/src/input/commands/recall-query.ts +229 -0
- package/src/input/commands/recall-review.ts +98 -0
- package/src/input/commands/recall-shared.ts +22 -0
- package/src/input/commands/remote-runtime-pool.ts +106 -0
- package/src/input/commands/remote-runtime-setup.ts +199 -0
- package/src/input/commands/remote-runtime.ts +431 -0
- package/src/input/commands/replay-runtime.ts +18 -0
- package/src/input/commands/runtime-services.ts +291 -0
- package/src/input/commands/schedule-runtime.ts +91 -0
- package/src/input/commands/services-runtime.ts +209 -0
- package/src/input/commands/session-content.ts +408 -0
- package/src/input/commands/session-workflow.ts +464 -0
- package/src/input/commands/session.ts +375 -0
- package/src/input/commands/settings-sync-runtime.ts +174 -0
- package/src/input/commands/share-runtime.ts +119 -0
- package/src/input/commands/shell-core.ts +307 -0
- package/src/input/commands/skills-runtime.ts +221 -0
- package/src/input/commands/subscription-runtime.ts +434 -0
- package/src/input/commands/tasks-runtime.ts +230 -0
- package/src/input/commands/teamwork-runtime.ts +339 -0
- package/src/input/commands/teleport-runtime.ts +57 -0
- package/src/input/commands/tts-runtime.ts +29 -0
- package/src/input/commands/work-plan-runtime.ts +169 -0
- package/src/input/commands.ts +131 -0
- package/src/input/feed-context-factory.ts +254 -0
- package/src/input/file-picker.ts +192 -0
- package/src/input/handler-command-route.ts +180 -0
- package/src/input/handler-content-actions.ts +497 -0
- package/src/input/handler-feed-routes.ts +648 -0
- package/src/input/handler-feed.ts +452 -0
- package/src/input/handler-interactions.ts +281 -0
- package/src/input/handler-modal-routes.ts +418 -0
- package/src/input/handler-modal-stack.ts +263 -0
- package/src/input/handler-modal-token-routes.ts +329 -0
- package/src/input/handler-onboarding-cloudflare.ts +391 -0
- package/src/input/handler-onboarding.ts +620 -0
- package/src/input/handler-picker-routes.ts +472 -0
- package/src/input/handler-prompt-buffer.ts +320 -0
- package/src/input/handler-shortcuts.ts +213 -0
- package/src/input/handler-ui-state.ts +372 -0
- package/src/input/handler.ts +729 -0
- package/src/input/input-history.ts +297 -0
- package/src/input/keybindings.ts +292 -0
- package/src/input/mcp-workspace.ts +554 -0
- package/src/input/model-picker-provider-filter.ts +28 -0
- package/src/input/model-picker-types.ts +137 -0
- package/src/input/model-picker.ts +797 -0
- package/src/input/onboarding/handler-onboarding-routes.ts +125 -0
- package/src/input/onboarding/onboarding-runtime-status.ts +87 -0
- package/src/input/onboarding/onboarding-wizard-apply.ts +277 -0
- package/src/input/onboarding/onboarding-wizard-cloudflare-step.ts +494 -0
- package/src/input/onboarding/onboarding-wizard-cloudflare.ts +204 -0
- package/src/input/onboarding/onboarding-wizard-constants.ts +158 -0
- package/src/input/onboarding/onboarding-wizard-external-surface-extra-specs.ts +130 -0
- package/src/input/onboarding/onboarding-wizard-external-surfaces.ts +762 -0
- package/src/input/onboarding/onboarding-wizard-helpers.ts +167 -0
- package/src/input/onboarding/onboarding-wizard-rules.ts +256 -0
- package/src/input/onboarding/onboarding-wizard-state.ts +365 -0
- package/src/input/onboarding/onboarding-wizard-steps.ts +798 -0
- package/src/input/onboarding/onboarding-wizard-types.ts +195 -0
- package/src/input/onboarding/onboarding-wizard.ts +711 -0
- package/src/input/panel-integration-actions.ts +78 -0
- package/src/input/profile-picker-modal.ts +222 -0
- package/src/input/search.ts +100 -0
- package/src/input/selection-modal.ts +163 -0
- package/src/input/selection.ts +135 -0
- package/src/input/session-picker-modal.ts +136 -0
- package/src/input/settings-modal-behavior.ts +37 -0
- package/src/input/settings-modal-secrets.ts +41 -0
- package/src/input/settings-modal-subscriptions.ts +95 -0
- package/src/input/settings-modal-types.ts +91 -0
- package/src/input/settings-modal.ts +793 -0
- package/src/input/submission-intent.ts +17 -0
- package/src/input/submission-router.ts +59 -0
- package/src/input/tts-settings-actions.ts +100 -0
- package/src/main.ts +792 -0
- package/src/mcp/runtime-reload.ts +81 -0
- package/src/panels/agent-inspector-panel.ts +521 -0
- package/src/panels/agent-inspector-shared.ts +94 -0
- package/src/panels/agent-logs-panel.ts +559 -0
- package/src/panels/agent-logs-shared.ts +129 -0
- package/src/panels/approval-panel.ts +150 -0
- package/src/panels/automation-control-panel.ts +212 -0
- package/src/panels/base-panel.ts +254 -0
- package/src/panels/builtin/agent.ts +117 -0
- package/src/panels/builtin/development.ts +31 -0
- package/src/panels/builtin/knowledge.ts +26 -0
- package/src/panels/builtin/operations.ts +349 -0
- package/src/panels/builtin/session.ts +129 -0
- package/src/panels/builtin/shared.ts +274 -0
- package/src/panels/builtin-panels.ts +23 -0
- package/src/panels/cockpit-panel.ts +183 -0
- package/src/panels/communication-panel.ts +153 -0
- package/src/panels/confirm-state.ts +61 -0
- package/src/panels/context-visualizer-panel.ts +204 -0
- package/src/panels/control-plane-panel.ts +211 -0
- package/src/panels/cost-tracker-panel.ts +444 -0
- package/src/panels/debug-panel.ts +432 -0
- package/src/panels/diff-panel.ts +520 -0
- package/src/panels/docs-panel.ts +283 -0
- package/src/panels/eval-panel.ts +399 -0
- package/src/panels/file-explorer-panel.ts +584 -0
- package/src/panels/file-preview-panel.ts +434 -0
- package/src/panels/forensics-panel.ts +364 -0
- package/src/panels/git-panel.ts +638 -0
- package/src/panels/hooks-panel.ts +239 -0
- package/src/panels/incident-review-panel.ts +197 -0
- package/src/panels/index.ts +46 -0
- package/src/panels/intelligence-panel.ts +176 -0
- package/src/panels/knowledge-panel.ts +345 -0
- package/src/panels/local-auth-panel.ts +130 -0
- package/src/panels/marketplace-panel.ts +212 -0
- package/src/panels/memory-panel.ts +225 -0
- package/src/panels/ops-control-panel.ts +150 -0
- package/src/panels/ops-strategy-panel.ts +235 -0
- package/src/panels/orchestration-panel.ts +273 -0
- package/src/panels/panel-list-panel.ts +509 -0
- package/src/panels/panel-manager.ts +570 -0
- package/src/panels/panel-picker.ts +106 -0
- package/src/panels/plan-dashboard-panel.ts +274 -0
- package/src/panels/plugins-panel.ts +178 -0
- package/src/panels/policy-panel.ts +308 -0
- package/src/panels/polish.ts +717 -0
- package/src/panels/project-planning-panel.ts +711 -0
- package/src/panels/provider-account-snapshot.ts +259 -0
- package/src/panels/provider-accounts-panel.ts +218 -0
- package/src/panels/provider-health-domains.ts +215 -0
- package/src/panels/provider-health-panel.ts +727 -0
- package/src/panels/provider-health-tracker.ts +115 -0
- package/src/panels/provider-stats-panel.ts +366 -0
- package/src/panels/qr-panel.ts +182 -0
- package/src/panels/remote-panel.ts +449 -0
- package/src/panels/routes-panel.ts +178 -0
- package/src/panels/sandbox-panel.ts +283 -0
- package/src/panels/schedule-panel.ts +329 -0
- package/src/panels/scrollable-list-panel.ts +491 -0
- package/src/panels/search-focus.ts +32 -0
- package/src/panels/security-panel.ts +295 -0
- package/src/panels/services-panel.ts +231 -0
- package/src/panels/session-browser-panel.ts +400 -0
- package/src/panels/session-maintenance.ts +125 -0
- package/src/panels/settings-sync-panel.ts +120 -0
- package/src/panels/skills-panel.ts +431 -0
- package/src/panels/subscription-panel.ts +263 -0
- package/src/panels/symbol-outline-panel.ts +486 -0
- package/src/panels/system-messages-panel.ts +230 -0
- package/src/panels/tasks-panel.ts +399 -0
- package/src/panels/thinking-panel.ts +304 -0
- package/src/panels/token-budget-panel.ts +475 -0
- package/src/panels/tool-inspector-panel.ts +429 -0
- package/src/panels/types.ts +54 -0
- package/src/panels/watchers-panel.ts +193 -0
- package/src/panels/work-plan-panel.ts +175 -0
- package/src/panels/worktree-panel.ts +182 -0
- package/src/panels/wrfc-panel.ts +609 -0
- package/src/permissions/prompt.ts +165 -0
- package/src/planning/project-planning-coordinator.ts +543 -0
- package/src/plugins/loader.ts +15 -0
- package/src/renderer/agent-detail-modal.ts +331 -0
- package/src/renderer/agent-workspace.ts +238 -0
- package/src/renderer/ansi-sanitize.ts +76 -0
- package/src/renderer/autocomplete-overlay.ts +154 -0
- package/src/renderer/block-actions.ts +76 -0
- package/src/renderer/bookmark-modal.ts +101 -0
- package/src/renderer/bottom-bar.ts +58 -0
- package/src/renderer/buffer.ts +113 -0
- package/src/renderer/code-block.ts +373 -0
- package/src/renderer/compositor.ts +283 -0
- package/src/renderer/context-inspector.ts +219 -0
- package/src/renderer/conversation-layout.ts +67 -0
- package/src/renderer/conversation-overlays.ts +140 -0
- package/src/renderer/conversation-surface.ts +260 -0
- package/src/renderer/diff-view.ts +132 -0
- package/src/renderer/diff.ts +130 -0
- package/src/renderer/file-picker-overlay.ts +101 -0
- package/src/renderer/file-tree.ts +153 -0
- package/src/renderer/fullscreen-primitives.ts +130 -0
- package/src/renderer/fullscreen-workspace.ts +199 -0
- package/src/renderer/git-status.ts +89 -0
- package/src/renderer/help-overlay.ts +267 -0
- package/src/renderer/history-search-overlay.ts +73 -0
- package/src/renderer/layout-engine.ts +97 -0
- package/src/renderer/layout.ts +32 -0
- package/src/renderer/live-tail-modal.ts +156 -0
- package/src/renderer/markdown.ts +635 -0
- package/src/renderer/mcp-workspace.ts +237 -0
- package/src/renderer/modal-factory.ts +467 -0
- package/src/renderer/modal-utils.ts +24 -0
- package/src/renderer/model-picker-overlay.ts +473 -0
- package/src/renderer/model-workspace.ts +488 -0
- package/src/renderer/onboarding/onboarding-wizard.ts +615 -0
- package/src/renderer/overlay-box.ts +146 -0
- package/src/renderer/overlay-viewport.ts +104 -0
- package/src/renderer/panel-composite.ts +158 -0
- package/src/renderer/panel-picker-overlay.ts +202 -0
- package/src/renderer/panel-tab-bar.ts +69 -0
- package/src/renderer/panel-workspace-bar.ts +42 -0
- package/src/renderer/process-indicator.ts +96 -0
- package/src/renderer/process-modal.ts +656 -0
- package/src/renderer/process-summary.ts +67 -0
- package/src/renderer/profile-picker-modal.ts +129 -0
- package/src/renderer/progress.ts +98 -0
- package/src/renderer/qr-renderer.ts +120 -0
- package/src/renderer/search-overlay.ts +54 -0
- package/src/renderer/selection-modal-overlay.ts +214 -0
- package/src/renderer/semantic-diff.ts +369 -0
- package/src/renderer/session-picker-modal.ts +127 -0
- package/src/renderer/settings-modal-helpers.ts +193 -0
- package/src/renderer/settings-modal.ts +537 -0
- package/src/renderer/shell-surface.ts +88 -0
- package/src/renderer/status-glyphs.ts +21 -0
- package/src/renderer/status-token.ts +67 -0
- package/src/renderer/surface-layout.ts +101 -0
- package/src/renderer/syntax-highlighter.ts +542 -0
- package/src/renderer/system-message.ts +83 -0
- package/src/renderer/tab-strip.ts +108 -0
- package/src/renderer/text-layout.ts +31 -0
- package/src/renderer/thinking.ts +17 -0
- package/src/renderer/tool-call.ts +234 -0
- package/src/renderer/ui-factory.ts +524 -0
- package/src/renderer/ui-primitives.ts +96 -0
- package/src/runtime/bootstrap-command-context.ts +278 -0
- package/src/runtime/bootstrap-command-parts.ts +386 -0
- package/src/runtime/bootstrap-core.ts +540 -0
- package/src/runtime/bootstrap-hook-bridge.ts +112 -0
- package/src/runtime/bootstrap-shell.ts +283 -0
- package/src/runtime/bootstrap.ts +575 -0
- package/src/runtime/cloudflare-control-plane.ts +349 -0
- package/src/runtime/context.ts +142 -0
- package/src/runtime/diagnostics/panels/index.ts +24 -0
- package/src/runtime/diagnostics/panels/ops.ts +156 -0
- package/src/runtime/diagnostics/panels/panel-resources.ts +118 -0
- package/src/runtime/diagnostics/panels/policy.ts +177 -0
- package/src/runtime/index.ts +662 -0
- package/src/runtime/onboarding/apply.ts +642 -0
- package/src/runtime/onboarding/derivation.ts +534 -0
- package/src/runtime/onboarding/index.ts +7 -0
- package/src/runtime/onboarding/markers.ts +148 -0
- package/src/runtime/onboarding/snapshot.ts +406 -0
- package/src/runtime/onboarding/state.ts +141 -0
- package/src/runtime/onboarding/types.ts +404 -0
- package/src/runtime/onboarding/verify.ts +171 -0
- package/src/runtime/operator-token-cleanup.ts +27 -0
- package/src/runtime/perf/panel-contracts.ts +32 -0
- package/src/runtime/perf/panel-health-monitor.ts +18 -0
- package/src/runtime/sandbox-public-gaps.ts +358 -0
- package/src/runtime/services.ts +670 -0
- package/src/runtime/store/domains/domain-read-matrix.ts +15 -0
- package/src/runtime/store/domains/index.ts +222 -0
- package/src/runtime/store/domains/panels.ts +117 -0
- package/src/runtime/store/domains/ui-perf.ts +103 -0
- package/src/runtime/store/index.ts +305 -0
- package/src/runtime/store/selectors/index.ts +359 -0
- package/src/runtime/store/state.ts +145 -0
- package/src/runtime/surface-feature-flags.ts +65 -0
- package/src/runtime/terminal-output-guard.ts +228 -0
- package/src/runtime/ui/index.ts +39 -0
- package/src/runtime/ui/model-picker/data-provider.ts +182 -0
- package/src/runtime/ui/model-picker/health-enrichment.ts +228 -0
- package/src/runtime/ui/model-picker/index.ts +59 -0
- package/src/runtime/ui/model-picker/types.ts +149 -0
- package/src/runtime/ui/provider-health/data-provider.ts +244 -0
- package/src/runtime/ui/provider-health/fallback-visualizer.ts +71 -0
- package/src/runtime/ui/provider-health/index.ts +46 -0
- package/src/runtime/ui/provider-health/types.ts +146 -0
- package/src/runtime/ui-events.ts +1 -0
- package/src/runtime/ui-read-model-helpers.ts +1 -0
- package/src/runtime/ui-read-models-observability-maintenance.ts +1 -0
- package/src/runtime/ui-read-models-observability-options.ts +1 -0
- package/src/runtime/ui-read-models-observability-remote.ts +1 -0
- package/src/runtime/ui-read-models-observability-security.ts +1 -0
- package/src/runtime/ui-read-models-observability-system.ts +1 -0
- package/src/runtime/ui-read-models-observability.ts +1 -0
- package/src/runtime/ui-read-models.ts +61 -0
- package/src/runtime/ui-service-queries.ts +1 -0
- package/src/runtime/ui-services.ts +190 -0
- package/src/scripts/process-messages.ts +42 -0
- package/src/shell/blocking-input.ts +98 -0
- package/src/shell/service-settings-sync.ts +273 -0
- package/src/shell/ui-openers.ts +352 -0
- package/src/tools/index.ts +1 -0
- package/src/tools/wrfc-agent-guard.ts +49 -0
- package/src/types/grid.ts +48 -0
- package/src/types/sql-js.d.ts +15 -0
- package/src/utils/clipboard.ts +22 -0
- package/src/utils/splash-lines.ts +46 -0
- package/src/utils/terminal-width.ts +185 -0
- package/src/verification/live-verifier.ts +430 -0
- package/src/verification/verification-ledger.ts +242 -0
- package/src/version.ts +17 -0
- package/src/widget/index.ts +2 -0
- package/src/widget/types.ts +9 -0
- package/src/widget/widget.ts +8 -0
- package/src/work-plans/work-plan-store.ts +374 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { getOrCreateCompanionToken } from '@pellux/goodvibes-sdk/platform/pairing';
|
|
3
|
+
import type { ConfigManager } from '../config/index.ts';
|
|
4
|
+
|
|
5
|
+
export const CLOUDFLARE_COMPONENT_IDS = [
|
|
6
|
+
'workers',
|
|
7
|
+
'queues',
|
|
8
|
+
'zeroTrustTunnel',
|
|
9
|
+
'zeroTrustAccess',
|
|
10
|
+
'dns',
|
|
11
|
+
'kv',
|
|
12
|
+
'durableObjects',
|
|
13
|
+
'secretsStore',
|
|
14
|
+
'r2',
|
|
15
|
+
] as const;
|
|
16
|
+
|
|
17
|
+
export type CloudflareComponent = typeof CLOUDFLARE_COMPONENT_IDS[number];
|
|
18
|
+
export type CloudflareComponentSelection = Partial<Record<CloudflareComponent, boolean>>;
|
|
19
|
+
export type CloudflareBatchMode = 'off' | 'explicit' | 'eligible-by-default';
|
|
20
|
+
|
|
21
|
+
export const DEFAULT_CLOUDFLARE_COMPONENT_SELECTION: Readonly<Record<CloudflareComponent, boolean>> = {
|
|
22
|
+
workers: true,
|
|
23
|
+
queues: true,
|
|
24
|
+
zeroTrustTunnel: false,
|
|
25
|
+
zeroTrustAccess: false,
|
|
26
|
+
dns: false,
|
|
27
|
+
kv: false,
|
|
28
|
+
durableObjects: false,
|
|
29
|
+
secretsStore: false,
|
|
30
|
+
r2: false,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const CLOUDFLARE_COMPONENT_LABELS: Readonly<Record<CloudflareComponent, string>> = {
|
|
34
|
+
workers: 'Workers',
|
|
35
|
+
queues: 'Queues',
|
|
36
|
+
zeroTrustTunnel: 'Zero Trust Tunnel',
|
|
37
|
+
zeroTrustAccess: 'Zero Trust Access',
|
|
38
|
+
dns: 'DNS hostname',
|
|
39
|
+
kv: 'KV',
|
|
40
|
+
durableObjects: 'Durable Objects',
|
|
41
|
+
secretsStore: 'Secrets Store',
|
|
42
|
+
r2: 'R2 artifacts',
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export interface CloudflareProvisionStep {
|
|
46
|
+
readonly name: string;
|
|
47
|
+
readonly status: 'ok' | 'skipped' | 'warning';
|
|
48
|
+
readonly message?: string;
|
|
49
|
+
readonly resourceId?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface CloudflareControlPlaneStatus {
|
|
53
|
+
readonly enabled: boolean;
|
|
54
|
+
readonly ready: boolean;
|
|
55
|
+
readonly configured: Record<string, boolean>;
|
|
56
|
+
readonly config: Record<string, unknown>;
|
|
57
|
+
readonly warnings: readonly string[];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface CloudflareTokenRequirement {
|
|
61
|
+
readonly component: CloudflareComponent | 'bootstrap';
|
|
62
|
+
readonly scope: 'account' | 'zone' | 'user' | 'r2';
|
|
63
|
+
readonly permission: string;
|
|
64
|
+
readonly alternatives?: readonly string[];
|
|
65
|
+
readonly reason: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface CloudflareTokenRequirementsResult {
|
|
69
|
+
readonly ok: true;
|
|
70
|
+
readonly components: Readonly<Record<CloudflareComponent, boolean>>;
|
|
71
|
+
readonly permissions: readonly CloudflareTokenRequirement[];
|
|
72
|
+
readonly bootstrapToken: {
|
|
73
|
+
readonly requiredForSdkCreation: boolean;
|
|
74
|
+
readonly storeInGoodVibes: false;
|
|
75
|
+
readonly instructions: readonly string[];
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface CloudflareValidateResult {
|
|
80
|
+
readonly ok: boolean;
|
|
81
|
+
readonly account?: {
|
|
82
|
+
readonly id: string;
|
|
83
|
+
readonly name: string;
|
|
84
|
+
readonly type?: string;
|
|
85
|
+
};
|
|
86
|
+
readonly tokenSource: string;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface CloudflareOperationalTokenResult {
|
|
90
|
+
readonly ok: true;
|
|
91
|
+
readonly tokenId?: string;
|
|
92
|
+
readonly tokenName: string;
|
|
93
|
+
readonly tokenSource: 'bootstrap';
|
|
94
|
+
readonly apiTokenRef?: string;
|
|
95
|
+
readonly generatedToken?: string;
|
|
96
|
+
readonly accountId: string;
|
|
97
|
+
readonly zoneId?: string;
|
|
98
|
+
readonly permissions: readonly CloudflareTokenRequirement[];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface CloudflareDiscoverResult {
|
|
102
|
+
readonly ok: true;
|
|
103
|
+
readonly tokenSource: string;
|
|
104
|
+
readonly accounts: ReadonlyArray<{ readonly id: string; readonly name: string; readonly type?: string }>;
|
|
105
|
+
readonly selectedAccount?: { readonly id: string; readonly name: string; readonly type?: string };
|
|
106
|
+
readonly zones: ReadonlyArray<{ readonly id: string; readonly name: string; readonly status?: string; readonly type?: string }>;
|
|
107
|
+
readonly selectedZone?: { readonly id: string; readonly name: string; readonly status?: string; readonly type?: string };
|
|
108
|
+
readonly workerSubdomain?: string;
|
|
109
|
+
readonly queues?: ReadonlyArray<{ readonly queue_id?: string; readonly queue_name?: string }>;
|
|
110
|
+
readonly kvNamespaces?: ReadonlyArray<{ readonly id?: string; readonly title?: string }>;
|
|
111
|
+
readonly durableObjectNamespaces?: ReadonlyArray<{ readonly id?: string; readonly name?: string; readonly class?: string }>;
|
|
112
|
+
readonly r2Buckets?: ReadonlyArray<{ readonly name?: string; readonly storage_class?: string }>;
|
|
113
|
+
readonly secretsStores?: ReadonlyArray<{ readonly id: string; readonly name: string }>;
|
|
114
|
+
readonly tunnels?: ReadonlyArray<{ readonly id?: string; readonly name?: string; readonly status?: string }>;
|
|
115
|
+
readonly accessApplications?: ReadonlyArray<{ readonly id?: string; readonly name?: string; readonly domain?: string; readonly type?: string }>;
|
|
116
|
+
readonly warnings: readonly string[];
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface CloudflareProvisionResult {
|
|
120
|
+
readonly ok: boolean;
|
|
121
|
+
readonly dryRun: false;
|
|
122
|
+
readonly steps: readonly CloudflareProvisionStep[];
|
|
123
|
+
readonly account?: { readonly id: string; readonly name: string };
|
|
124
|
+
readonly worker?: { readonly name: string; readonly baseUrl?: string; readonly subdomain?: string; readonly hostname?: string; readonly cron?: string };
|
|
125
|
+
readonly queues?: { readonly queueName: string; readonly queueId: string; readonly deadLetterQueueName: string; readonly deadLetterQueueId: string; readonly consumerId?: string };
|
|
126
|
+
readonly tunnel?: { readonly id: string; readonly name: string; readonly hostname?: string; readonly tokenRef?: string };
|
|
127
|
+
readonly access?: { readonly appId?: string; readonly serviceTokenId?: string; readonly serviceTokenRef?: string };
|
|
128
|
+
readonly dns?: {
|
|
129
|
+
readonly zoneId: string;
|
|
130
|
+
readonly zoneName?: string;
|
|
131
|
+
readonly records: ReadonlyArray<{ readonly id?: string; readonly name?: string; readonly type?: string; readonly content?: string }>;
|
|
132
|
+
};
|
|
133
|
+
readonly kv?: { readonly namespaceName: string; readonly namespaceId: string };
|
|
134
|
+
readonly durableObjects?: { readonly namespaceName: string; readonly namespaceId?: string };
|
|
135
|
+
readonly r2?: { readonly bucketName: string; readonly storageClass: 'Standard' };
|
|
136
|
+
readonly secretsStore?: { readonly storeName: string; readonly storeId: string };
|
|
137
|
+
readonly verification?: CloudflareVerifyResult;
|
|
138
|
+
readonly generatedSecrets?: {
|
|
139
|
+
readonly workerClientToken?: string;
|
|
140
|
+
readonly tunnelToken?: string;
|
|
141
|
+
readonly accessServiceTokenClientId?: string;
|
|
142
|
+
readonly accessServiceTokenClientSecret?: string;
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export interface CloudflareVerifyResult {
|
|
147
|
+
readonly ok: boolean;
|
|
148
|
+
readonly workerHealth: {
|
|
149
|
+
readonly ok: boolean;
|
|
150
|
+
readonly status: number;
|
|
151
|
+
readonly error?: string;
|
|
152
|
+
};
|
|
153
|
+
readonly daemonBatchProxy?: {
|
|
154
|
+
readonly ok: boolean;
|
|
155
|
+
readonly status: number;
|
|
156
|
+
readonly error?: string;
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export interface CloudflareDisableResult {
|
|
161
|
+
readonly ok: boolean;
|
|
162
|
+
readonly steps: readonly CloudflareProvisionStep[];
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export interface CloudflareTokenRequirementsRequest {
|
|
166
|
+
readonly components?: CloudflareComponentSelection;
|
|
167
|
+
readonly includeBootstrap?: boolean;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface CloudflareOperationalTokenRequest extends CloudflareTokenRequirementsRequest {
|
|
171
|
+
readonly accountId?: string;
|
|
172
|
+
readonly zoneId?: string;
|
|
173
|
+
readonly zoneName?: string;
|
|
174
|
+
readonly bootstrapToken?: string;
|
|
175
|
+
readonly tokenName?: string;
|
|
176
|
+
readonly expiresOn?: string;
|
|
177
|
+
readonly persistConfig?: boolean;
|
|
178
|
+
readonly storeApiToken?: boolean;
|
|
179
|
+
readonly returnGeneratedToken?: boolean;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export interface CloudflareValidateRequest {
|
|
183
|
+
readonly accountId?: string;
|
|
184
|
+
readonly apiToken?: string;
|
|
185
|
+
readonly apiTokenRef?: string;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export interface CloudflareDiscoverRequest extends CloudflareValidateRequest {
|
|
189
|
+
readonly components?: CloudflareComponentSelection;
|
|
190
|
+
readonly zoneId?: string;
|
|
191
|
+
readonly zoneName?: string;
|
|
192
|
+
readonly includeResources?: boolean;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export interface CloudflareProvisionRequest extends CloudflareDiscoverRequest {
|
|
196
|
+
readonly workerName?: string;
|
|
197
|
+
readonly workerSubdomain?: string;
|
|
198
|
+
readonly workerHostname?: string;
|
|
199
|
+
readonly workerBaseUrl?: string;
|
|
200
|
+
readonly daemonBaseUrl?: string;
|
|
201
|
+
readonly daemonHostname?: string;
|
|
202
|
+
readonly queueName?: string;
|
|
203
|
+
readonly deadLetterQueueName?: string;
|
|
204
|
+
readonly tunnelName?: string;
|
|
205
|
+
readonly tunnelId?: string;
|
|
206
|
+
readonly tunnelServiceUrl?: string;
|
|
207
|
+
readonly tunnelTokenRef?: string;
|
|
208
|
+
readonly accessAppId?: string;
|
|
209
|
+
readonly accessServiceTokenId?: string;
|
|
210
|
+
readonly accessServiceTokenRef?: string;
|
|
211
|
+
readonly kvNamespaceName?: string;
|
|
212
|
+
readonly kvNamespaceId?: string;
|
|
213
|
+
readonly durableObjectNamespaceName?: string;
|
|
214
|
+
readonly durableObjectNamespaceId?: string;
|
|
215
|
+
readonly r2BucketName?: string;
|
|
216
|
+
readonly secretsStoreName?: string;
|
|
217
|
+
readonly secretsStoreId?: string;
|
|
218
|
+
readonly workerCron?: string;
|
|
219
|
+
readonly operatorToken?: string;
|
|
220
|
+
readonly operatorTokenRef?: string;
|
|
221
|
+
readonly workerClientToken?: string;
|
|
222
|
+
readonly workerClientTokenRef?: string;
|
|
223
|
+
readonly storeApiToken?: boolean;
|
|
224
|
+
readonly storeOperatorToken?: boolean;
|
|
225
|
+
readonly storeWorkerClientToken?: boolean;
|
|
226
|
+
readonly returnGeneratedSecrets?: boolean;
|
|
227
|
+
readonly enableWorkersDev?: boolean;
|
|
228
|
+
readonly queueJobPayloads?: boolean;
|
|
229
|
+
readonly verify?: boolean;
|
|
230
|
+
readonly persistConfig?: boolean;
|
|
231
|
+
readonly batchMode?: CloudflareBatchMode;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export interface CloudflareVerifyRequest {
|
|
235
|
+
readonly workerBaseUrl?: string;
|
|
236
|
+
readonly workerClientToken?: string;
|
|
237
|
+
readonly workerClientTokenRef?: string;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export interface CloudflareDisableRequest extends CloudflareValidateRequest {
|
|
241
|
+
readonly workerName?: string;
|
|
242
|
+
readonly disableWorkerSubdomain?: boolean;
|
|
243
|
+
readonly disableCron?: boolean;
|
|
244
|
+
readonly persistConfig?: boolean;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export class CloudflareDaemonRouteError extends Error {
|
|
248
|
+
readonly status: number;
|
|
249
|
+
readonly code: string;
|
|
250
|
+
|
|
251
|
+
constructor(message: string, status: number, code: string) {
|
|
252
|
+
super(message);
|
|
253
|
+
this.name = 'CloudflareDaemonRouteError';
|
|
254
|
+
this.status = status;
|
|
255
|
+
this.code = code;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export interface CloudflareDaemonClient {
|
|
260
|
+
status(): Promise<CloudflareControlPlaneStatus>;
|
|
261
|
+
tokenRequirements(input?: CloudflareTokenRequirementsRequest): Promise<CloudflareTokenRequirementsResult>;
|
|
262
|
+
createOperationalToken(input: CloudflareOperationalTokenRequest): Promise<CloudflareOperationalTokenResult>;
|
|
263
|
+
discover(input?: CloudflareDiscoverRequest): Promise<CloudflareDiscoverResult>;
|
|
264
|
+
validate(input?: CloudflareValidateRequest): Promise<CloudflareValidateResult>;
|
|
265
|
+
provision(input: CloudflareProvisionRequest): Promise<CloudflareProvisionResult>;
|
|
266
|
+
verify(input?: CloudflareVerifyRequest): Promise<CloudflareVerifyResult>;
|
|
267
|
+
disable(input?: CloudflareDisableRequest): Promise<CloudflareDisableResult>;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export interface CloudflareDaemonClientOptions {
|
|
271
|
+
readonly configManager: Pick<ConfigManager, 'get'>;
|
|
272
|
+
readonly homeDirectory: string;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function connectHostForBindHost(host: string): string {
|
|
276
|
+
if (host === '0.0.0.0' || host === '::' || host.trim().length === 0) return '127.0.0.1';
|
|
277
|
+
return host;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function hostForUrl(host: string): string {
|
|
281
|
+
return host.includes(':') && !host.startsWith('[') ? `[${host}]` : host;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export function resolveCloudflareDaemonBaseUrl(configManager: Pick<ConfigManager, 'get'>): string {
|
|
285
|
+
const configuredBaseUrl = String(configManager.get('controlPlane.baseUrl' as never) ?? '').trim();
|
|
286
|
+
if (configuredBaseUrl) return configuredBaseUrl.replace(/\/+$/, '');
|
|
287
|
+
const host = hostForUrl(connectHostForBindHost(String(configManager.get('controlPlane.host' as never) ?? '127.0.0.1')));
|
|
288
|
+
const portValue = Number(configManager.get('controlPlane.port' as never) ?? 3421);
|
|
289
|
+
const port = Number.isFinite(portValue) && portValue > 0 ? portValue : 3421;
|
|
290
|
+
return `http://${host}:${port}`;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export function buildDefaultCloudflareDaemonBaseUrl(configManager: Pick<ConfigManager, 'get'>): string {
|
|
294
|
+
return resolveCloudflareDaemonBaseUrl(configManager);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function readDaemonToken(homeDirectory: string): string {
|
|
298
|
+
const daemonHomeDir = join(homeDirectory, '.goodvibes', 'daemon');
|
|
299
|
+
return getOrCreateCompanionToken('tui', { daemonHomeDir }).token;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
async function readJsonResponse<T>(response: Response): Promise<T> {
|
|
303
|
+
const text = await response.text();
|
|
304
|
+
const body = text.trim().length > 0 ? JSON.parse(text) as unknown : {};
|
|
305
|
+
if (!response.ok) {
|
|
306
|
+
const record = body && typeof body === 'object' ? body as Record<string, unknown> : {};
|
|
307
|
+
const message = typeof record.error === 'string' ? record.error : `Cloudflare daemon route failed with HTTP ${response.status}`;
|
|
308
|
+
const code = typeof record.code === 'string' ? record.code : 'CLOUDFLARE_DAEMON_ROUTE_ERROR';
|
|
309
|
+
throw new CloudflareDaemonRouteError(message, response.status, code);
|
|
310
|
+
}
|
|
311
|
+
return body as T;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export function createCloudflareDaemonClient(options: CloudflareDaemonClientOptions): CloudflareDaemonClient {
|
|
315
|
+
const baseUrl = resolveCloudflareDaemonBaseUrl(options.configManager);
|
|
316
|
+
const token = readDaemonToken(options.homeDirectory);
|
|
317
|
+
|
|
318
|
+
const requestJson = async <T>(path: string, init: RequestInit = {}): Promise<T> => {
|
|
319
|
+
const headers = new Headers(init.headers);
|
|
320
|
+
headers.set('Authorization', `Bearer ${token}`);
|
|
321
|
+
if (init.body !== undefined) headers.set('Content-Type', 'application/json');
|
|
322
|
+
const response = await fetch(`${baseUrl}${path}`, { ...init, headers });
|
|
323
|
+
return await readJsonResponse<T>(response);
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
const postJson = <T>(path: string, body: unknown): Promise<T> => requestJson<T>(path, {
|
|
327
|
+
method: 'POST',
|
|
328
|
+
body: JSON.stringify(body ?? {}),
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
return {
|
|
332
|
+
status: () => requestJson<CloudflareControlPlaneStatus>('/api/cloudflare/status'),
|
|
333
|
+
tokenRequirements: (input = {}) => postJson<CloudflareTokenRequirementsResult>('/api/cloudflare/token/requirements', input),
|
|
334
|
+
createOperationalToken: (input) => postJson<CloudflareOperationalTokenResult>('/api/cloudflare/token/create', input),
|
|
335
|
+
discover: (input = {}) => postJson<CloudflareDiscoverResult>('/api/cloudflare/discover', input),
|
|
336
|
+
validate: (input = {}) => postJson<CloudflareValidateResult>('/api/cloudflare/validate', input),
|
|
337
|
+
provision: (input) => postJson<CloudflareProvisionResult>('/api/cloudflare/provision', input),
|
|
338
|
+
verify: (input = {}) => postJson<CloudflareVerifyResult>('/api/cloudflare/verify', input),
|
|
339
|
+
disable: (input = {}) => postJson<CloudflareDisableResult>('/api/cloudflare/disable', input),
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
export function normalizeCloudflareComponents(selection: CloudflareComponentSelection | undefined): Record<CloudflareComponent, boolean> {
|
|
344
|
+
const result: Record<CloudflareComponent, boolean> = { ...DEFAULT_CLOUDFLARE_COMPONENT_SELECTION };
|
|
345
|
+
for (const component of CLOUDFLARE_COMPONENT_IDS) {
|
|
346
|
+
if (typeof selection?.[component] === 'boolean') result[component] = selection[component] === true;
|
|
347
|
+
}
|
|
348
|
+
return result;
|
|
349
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RuntimeContext — the composition root object returned by bootstrapRuntime().
|
|
3
|
+
*
|
|
4
|
+
* main.ts receives this and uses it to drive the render loop, input handling,
|
|
5
|
+
* and terminal lifecycle. The bootstrap owns initialization; main.ts owns
|
|
6
|
+
* the runtime loop.
|
|
7
|
+
*/
|
|
8
|
+
import type { ConversationManager } from '../core/conversation';
|
|
9
|
+
import type { Orchestrator } from '../core/orchestrator';
|
|
10
|
+
import type { ToolRegistry } from '@pellux/goodvibes-sdk/platform/tools';
|
|
11
|
+
import type { PermissionManager } from '@pellux/goodvibes-sdk/platform/permissions';
|
|
12
|
+
import type { HookDispatcher } from '@pellux/goodvibes-sdk/platform/hooks';
|
|
13
|
+
import type { FileStateCache } from '@pellux/goodvibes-sdk/platform/state';
|
|
14
|
+
import type { ProjectIndex } from '@pellux/goodvibes-sdk/platform/state';
|
|
15
|
+
import type { ProviderRegistry } from '@pellux/goodvibes-sdk/platform/providers';
|
|
16
|
+
import type { RuntimeStore } from './store/index.ts';
|
|
17
|
+
import type { RuntimeEventBus } from '@/runtime/index.ts';
|
|
18
|
+
import type { FeatureFlagManager } from '@/runtime/index.ts';
|
|
19
|
+
import type { MutableRuntimeState } from '@/runtime/index.ts';
|
|
20
|
+
import type { SessionSnapshot } from '@/runtime/index.ts';
|
|
21
|
+
import type { RuntimeServices } from './services.ts';
|
|
22
|
+
import type { ComponentHealthMonitor } from './perf/panel-health-monitor.ts';
|
|
23
|
+
import type { WorktreeRegistry } from '@/runtime/index.ts';
|
|
24
|
+
import type { SandboxSessionRegistry } from '@/runtime/index.ts';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Options accepted by bootstrapRuntime().
|
|
28
|
+
*/
|
|
29
|
+
export interface BootstrapOptions {
|
|
30
|
+
/** App-owned working directory for this runtime instance. */
|
|
31
|
+
workingDir: string;
|
|
32
|
+
/** App-owned home directory for this runtime instance. */
|
|
33
|
+
homeDirectory: string;
|
|
34
|
+
/** Explicit app-owned config manager for this runtime instance. */
|
|
35
|
+
configManager: import('@pellux/goodvibes-sdk/platform/config').ConfigManager;
|
|
36
|
+
/**
|
|
37
|
+
* Callback invoked when the app should exit.
|
|
38
|
+
* If provided, commandContext.exit is wired during bootstrap.
|
|
39
|
+
* Otherwise main.ts binds the shell-owned exit bridge immediately after bootstrap returns.
|
|
40
|
+
*/
|
|
41
|
+
exit?: () => void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The fully-initialized runtime context produced by bootstrapRuntime().
|
|
46
|
+
*
|
|
47
|
+
* main.ts destructures this to obtain what it needs for the render loop
|
|
48
|
+
* and input handling.
|
|
49
|
+
*/
|
|
50
|
+
export interface RuntimeContext {
|
|
51
|
+
// ── Core subsystems ─────────────────────────────────────────────────
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Typed domain event bus for new runtime subsystems.
|
|
55
|
+
*/
|
|
56
|
+
runtimeBus: RuntimeEventBus;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Zustand vanilla store for domain state slices.
|
|
60
|
+
*/
|
|
61
|
+
store: RuntimeStore;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* App-scoped runtime services graph shared across adapters and shells.
|
|
65
|
+
*/
|
|
66
|
+
services: RuntimeServices;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Feature flag and kill-switch manager.
|
|
70
|
+
* Gates runtime subsystems and release controls.
|
|
71
|
+
*/
|
|
72
|
+
featureFlags: FeatureFlagManager;
|
|
73
|
+
|
|
74
|
+
// ── Managers ────────────────────────────────────────────────────────
|
|
75
|
+
|
|
76
|
+
/** Manages conversation history and message rendering. */
|
|
77
|
+
conversation: ConversationManager;
|
|
78
|
+
|
|
79
|
+
/** Controls tool execution approval flow. */
|
|
80
|
+
permissions: PermissionManager;
|
|
81
|
+
|
|
82
|
+
/** Registry of all registered tool implementations. */
|
|
83
|
+
toolRegistry: ToolRegistry;
|
|
84
|
+
|
|
85
|
+
// ── Provider ────────────────────────────────────────────────────────
|
|
86
|
+
|
|
87
|
+
/** Shared provider registry owned by the runtime services graph. */
|
|
88
|
+
providerRegistry: ProviderRegistry;
|
|
89
|
+
|
|
90
|
+
/** Shared component-health monitor owned by the runtime services graph. */
|
|
91
|
+
componentHealthMonitor: ComponentHealthMonitor;
|
|
92
|
+
|
|
93
|
+
/** Shared worktree registry owned by the runtime services graph. */
|
|
94
|
+
worktreeRegistry: WorktreeRegistry;
|
|
95
|
+
|
|
96
|
+
/** Shared sandbox session registry owned by the runtime services graph. */
|
|
97
|
+
sandboxSessionRegistry: SandboxSessionRegistry;
|
|
98
|
+
|
|
99
|
+
// ── Infrastructure ──────────────────────────────────────────────────
|
|
100
|
+
|
|
101
|
+
/** Fires lifecycle hooks registered by the user or plugins. */
|
|
102
|
+
hookDispatcher: HookDispatcher;
|
|
103
|
+
|
|
104
|
+
// ── State ───────────────────────────────────────────────────────────
|
|
105
|
+
|
|
106
|
+
/** File read/write cache shared across read/write/edit tools in a session. */
|
|
107
|
+
fileCache: FileStateCache;
|
|
108
|
+
|
|
109
|
+
/** Project-level file index shared across tools. */
|
|
110
|
+
projectIndex: ProjectIndex;
|
|
111
|
+
|
|
112
|
+
// ── Session ─────────────────────────────────────────────────────────
|
|
113
|
+
|
|
114
|
+
/** Unique identifier for this user session (hex, prefixed "user-"). */
|
|
115
|
+
sessionId: string;
|
|
116
|
+
|
|
117
|
+
/** True if a previous session was resumed at startup. */
|
|
118
|
+
isResumed: boolean;
|
|
119
|
+
|
|
120
|
+
// ── Mutable runtime state ───────────────────────────────────────────
|
|
121
|
+
|
|
122
|
+
/** Mutable model/provider/prompt state closed over by event handlers. */
|
|
123
|
+
runtime: MutableRuntimeState;
|
|
124
|
+
|
|
125
|
+
// ── Orchestrator ─────────────────────────────────────────────────────
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Main LLM orchestrator. Drives the conversation loop, tool execution,
|
|
129
|
+
* streaming, and context compaction.
|
|
130
|
+
*/
|
|
131
|
+
orchestrator: Orchestrator;
|
|
132
|
+
|
|
133
|
+
// ── Lifecycle ────────────────────────────────────────────────────────
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Logical shutdown: save session, fire hooks, stop background managers.
|
|
137
|
+
* Does NOT touch the terminal — main.ts owns terminal teardown.
|
|
138
|
+
*
|
|
139
|
+
* @param sessionData - Latest conversation data to persist.
|
|
140
|
+
*/
|
|
141
|
+
shutdown: (sessionData: SessionSnapshot) => Promise<void>;
|
|
142
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diagnostics panels barrel — re-exports all panel data provider classes.
|
|
3
|
+
*
|
|
4
|
+
* Import from this module to access the individual diagnostic panel providers.
|
|
5
|
+
*/
|
|
6
|
+
export { ToolCallsPanel } from '@/runtime/index.ts';
|
|
7
|
+
export { AgentsPanel } from '@/runtime/index.ts';
|
|
8
|
+
export { TasksPanel } from '@/runtime/index.ts';
|
|
9
|
+
export { EventsPanel } from '@/runtime/index.ts';
|
|
10
|
+
export { StateInspectorPanel } from '@/runtime/index.ts';
|
|
11
|
+
export type { InspectableDomain } from '@/runtime/index.ts';
|
|
12
|
+
export { HealthPanel } from '@/runtime/index.ts';
|
|
13
|
+
export { DivergencePanel } from '@/runtime/index.ts';
|
|
14
|
+
export { ReplayPanel } from '@/runtime/index.ts';
|
|
15
|
+
export { PolicyPanel } from './policy.ts';
|
|
16
|
+
export type { PolicyPanelSnapshot } from './policy.ts';
|
|
17
|
+
export { ToolContractsPanel } from '@/runtime/index.ts';
|
|
18
|
+
export { TransportPanel } from '@/runtime/index.ts';
|
|
19
|
+
export type { TransportPanelSnapshot } from '@/runtime/index.ts';
|
|
20
|
+
export { OpsPanel } from './ops.ts';
|
|
21
|
+
export type { OpsAuditEntry } from './ops.ts';
|
|
22
|
+
export { PanelResourcesPanel } from './panel-resources.ts';
|
|
23
|
+
export { SecurityPanel } from '@/runtime/index.ts';
|
|
24
|
+
export type { SecurityPanelSnapshot } from '@/runtime/index.ts';
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpsPanel — diagnostic data provider for the Operator Control Plane.
|
|
3
|
+
*
|
|
4
|
+
* Subscribes to OPS_AUDIT events from the UI-facing ops event feed and maintains a
|
|
5
|
+
* bounded buffer of intervention records for display
|
|
6
|
+
* in the Ops panel.
|
|
7
|
+
*
|
|
8
|
+
* Controls are only shown when the OpsControlPlane reports the action is legal
|
|
9
|
+
* (state machine allows it), satisfying requirement: "No illegal action appears in UI".
|
|
10
|
+
*/
|
|
11
|
+
import type { RuntimeEventEnvelope } from '@/runtime/index.ts';
|
|
12
|
+
import type { PanelConfig } from '@/runtime/index.ts';
|
|
13
|
+
import { DEFAULT_PANEL_CONFIG, appendBounded, applyFilter } from '@/runtime/index.ts';
|
|
14
|
+
import type { DiagnosticFilter } from '@/runtime/index.ts';
|
|
15
|
+
import type { OpsInterventionReason, OpsEvent } from '@/runtime/index.ts';
|
|
16
|
+
import type { UiEventFeed } from '../../ui-events.ts';
|
|
17
|
+
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Audit entry
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Immutable audit record for a single operator intervention.
|
|
24
|
+
*/
|
|
25
|
+
export interface OpsAuditEntry {
|
|
26
|
+
/** Monotonic sequence number. */
|
|
27
|
+
readonly seq: number;
|
|
28
|
+
/** Epoch ms when the intervention was recorded. */
|
|
29
|
+
readonly ts: number;
|
|
30
|
+
/** The action taken (e.g. 'task.cancel', 'agent.cancel'). */
|
|
31
|
+
readonly action: string;
|
|
32
|
+
/** The target task or agent ID. */
|
|
33
|
+
readonly targetId: string;
|
|
34
|
+
/** Whether this intervention targeted a task or an agent. */
|
|
35
|
+
readonly targetKind: 'task' | 'agent';
|
|
36
|
+
/** The reason code for the intervention. */
|
|
37
|
+
readonly reason: OpsInterventionReason;
|
|
38
|
+
/** Optional operator note. */
|
|
39
|
+
readonly note?: string;
|
|
40
|
+
/** Outcome of the intervention. */
|
|
41
|
+
readonly outcome: 'success' | 'rejected' | 'error';
|
|
42
|
+
/** Error message if outcome is not success. */
|
|
43
|
+
readonly errorMessage?: string;
|
|
44
|
+
/** Trace identifier from the event envelope. */
|
|
45
|
+
readonly traceId: string;
|
|
46
|
+
/** Session identifier from the event envelope. */
|
|
47
|
+
readonly sessionId: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
// OpsPanel
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
|
|
54
|
+
/** Internal mutable record (same shape as immutable OpsAuditEntry). */
|
|
55
|
+
type MutableAuditRecord = {
|
|
56
|
+
seq: number;
|
|
57
|
+
ts: number;
|
|
58
|
+
action: string;
|
|
59
|
+
targetId: string;
|
|
60
|
+
targetKind: 'task' | 'agent';
|
|
61
|
+
reason: OpsInterventionReason;
|
|
62
|
+
note?: string;
|
|
63
|
+
outcome: 'success' | 'rejected' | 'error';
|
|
64
|
+
errorMessage?: string;
|
|
65
|
+
traceId: string;
|
|
66
|
+
sessionId: string;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/** Type alias for the OPS_AUDIT event shape. */
|
|
70
|
+
type OpsAuditEvent = Extract<OpsEvent, { type: 'OPS_AUDIT' }>;
|
|
71
|
+
|
|
72
|
+
export class OpsPanel {
|
|
73
|
+
private readonly _config: PanelConfig;
|
|
74
|
+
private readonly _events: UiEventFeed<OpsEvent>;
|
|
75
|
+
|
|
76
|
+
private readonly _audit: MutableAuditRecord[] = [];
|
|
77
|
+
private _seq = 0;
|
|
78
|
+
|
|
79
|
+
private readonly _subscribers = new Set<() => void>();
|
|
80
|
+
private _unsub: (() => void) | null = null;
|
|
81
|
+
|
|
82
|
+
public constructor(
|
|
83
|
+
events: UiEventFeed<OpsEvent>,
|
|
84
|
+
config: PanelConfig = DEFAULT_PANEL_CONFIG
|
|
85
|
+
) {
|
|
86
|
+
this._config = config;
|
|
87
|
+
this._events = events;
|
|
88
|
+
this._start();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
private _start(): void {
|
|
92
|
+
this._unsub = this._events.onEnvelope('OPS_AUDIT', (envelope) => {
|
|
93
|
+
this._handleAudit(envelope as RuntimeEventEnvelope<'OPS_AUDIT', OpsAuditEvent>);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private _handleAudit(
|
|
98
|
+
envelope: RuntimeEventEnvelope<'OPS_AUDIT', OpsAuditEvent>
|
|
99
|
+
): void {
|
|
100
|
+
const payload = envelope.payload;
|
|
101
|
+
|
|
102
|
+
const record: MutableAuditRecord = {
|
|
103
|
+
seq: ++this._seq,
|
|
104
|
+
ts: envelope.ts,
|
|
105
|
+
action: payload.action,
|
|
106
|
+
targetId: payload.targetId,
|
|
107
|
+
targetKind: payload.targetKind,
|
|
108
|
+
reason: payload.reason,
|
|
109
|
+
note: payload.note,
|
|
110
|
+
outcome: payload.outcome,
|
|
111
|
+
errorMessage: payload.errorMessage,
|
|
112
|
+
traceId: envelope.traceId ?? '',
|
|
113
|
+
sessionId: envelope.sessionId ?? '',
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
appendBounded(this._audit, record, this._config.bufferLimit);
|
|
117
|
+
this._notify();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Returns a filtered snapshot of the audit log, most recent first.
|
|
122
|
+
*/
|
|
123
|
+
public getSnapshot(filter?: DiagnosticFilter): OpsAuditEntry[] {
|
|
124
|
+
const entries = this._audit.map((r) => ({ ...r }) as OpsAuditEntry);
|
|
125
|
+
return applyFilter(entries, filter, (e) => e.ts);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Subscribe to data changes. Returns an unsubscribe function.
|
|
130
|
+
*/
|
|
131
|
+
public subscribe(callback: () => void): () => void {
|
|
132
|
+
this._subscribers.add(callback);
|
|
133
|
+
return () => { this._subscribers.delete(callback); };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Dispose the panel, unsubscribing from the event bus.
|
|
138
|
+
*/
|
|
139
|
+
public dispose(): void {
|
|
140
|
+
if (this._unsub) {
|
|
141
|
+
this._unsub();
|
|
142
|
+
this._unsub = null;
|
|
143
|
+
}
|
|
144
|
+
this._subscribers.clear();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
private _notify(): void {
|
|
148
|
+
for (const cb of this._subscribers) {
|
|
149
|
+
try {
|
|
150
|
+
cb();
|
|
151
|
+
} catch {
|
|
152
|
+
// Non-fatal — subscriber errors must not crash the panel
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|