@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,329 @@
|
|
|
1
|
+
import type { McpRegistry } from '@pellux/goodvibes-sdk/platform/mcp';
|
|
2
|
+
import type { ProviderRegistry } from '@pellux/goodvibes-sdk/platform/providers';
|
|
3
|
+
import type { ConversationManager } from '../core/conversation';
|
|
4
|
+
import type { ConfigManager } from '../config/index.ts';
|
|
5
|
+
import type { DeepReadonly, GoodVibesConfig } from '../config/index.ts';
|
|
6
|
+
import type { ToolRegistry } from '@pellux/goodvibes-sdk/platform/tools';
|
|
7
|
+
import type { PermissionRequestHandler } from '@pellux/goodvibes-sdk/platform/permissions';
|
|
8
|
+
import type { SelectionItem, SelectionResult, SelectionAction } from './selection-modal.ts';
|
|
9
|
+
import type { FileUndoManager } from '@pellux/goodvibes-sdk/platform/state';
|
|
10
|
+
import type { PanelManager } from '../panels/panel-manager.ts';
|
|
11
|
+
import type { KeybindingsManager } from './keybindings.ts';
|
|
12
|
+
import type { OnboardingWizardMode } from './onboarding/onboarding-wizard.ts';
|
|
13
|
+
import type { OpenOnboardingWizardOptions } from './handler-ui-state.ts';
|
|
14
|
+
import type { KnowledgeApi } from '@pellux/goodvibes-sdk/platform/knowledge';
|
|
15
|
+
import type { HookApi } from '@pellux/goodvibes-sdk/platform/hooks';
|
|
16
|
+
import type { McpApi } from '@pellux/goodvibes-sdk/platform/mcp';
|
|
17
|
+
import type { ProviderApi } from '@pellux/goodvibes-sdk/platform/providers';
|
|
18
|
+
import type { OpsApi } from '@/runtime/index.ts';
|
|
19
|
+
import type { OperatorClient } from '@/runtime/index.ts';
|
|
20
|
+
import type { PeerClient } from '@/runtime/index.ts';
|
|
21
|
+
import type { DirectTransport } from '@/runtime/index.ts';
|
|
22
|
+
import type { VoiceProviderRegistry, VoiceService } from '@pellux/goodvibes-sdk/platform/voice';
|
|
23
|
+
import type {
|
|
24
|
+
CommandWorkspaceShellServices,
|
|
25
|
+
} from '@/runtime/index.ts';
|
|
26
|
+
import type {
|
|
27
|
+
CommandPlatformShellServices,
|
|
28
|
+
} from '@/runtime/index.ts';
|
|
29
|
+
import type {
|
|
30
|
+
CommandExtensionShellServices,
|
|
31
|
+
} from '@/runtime/index.ts';
|
|
32
|
+
import type {
|
|
33
|
+
CommandOpsShellServices,
|
|
34
|
+
RemoteCommandService,
|
|
35
|
+
PlanRuntimeService,
|
|
36
|
+
} from '@/runtime/index.ts';
|
|
37
|
+
|
|
38
|
+
export type {
|
|
39
|
+
RemoteCommandService,
|
|
40
|
+
PlanRuntimeService,
|
|
41
|
+
} from '@/runtime/index.ts';
|
|
42
|
+
|
|
43
|
+
export interface CommandRuntimeState {
|
|
44
|
+
model: string;
|
|
45
|
+
provider: string;
|
|
46
|
+
debugMode: boolean;
|
|
47
|
+
systemPrompt: string;
|
|
48
|
+
reasoningEffort: string;
|
|
49
|
+
sessionId: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Top-level shell actions remain flat because commands and nearby shell routes
|
|
54
|
+
* use them constantly, and nesting them would add noise without clarifying
|
|
55
|
+
* ownership.
|
|
56
|
+
*/
|
|
57
|
+
export interface CommandUiActions {
|
|
58
|
+
renderRequest: () => void;
|
|
59
|
+
print: (text: string) => void;
|
|
60
|
+
exit: () => void;
|
|
61
|
+
submitInput?: (text: string, content?: import('@pellux/goodvibes-sdk/platform/providers').ContentPart[]) => void;
|
|
62
|
+
submitSpokenInput?: (text: string, content?: import('@pellux/goodvibes-sdk/platform/providers').ContentPart[]) => void;
|
|
63
|
+
stopSpokenOutput?: () => void;
|
|
64
|
+
pasteFromClipboard?: () => {
|
|
65
|
+
pasted: boolean;
|
|
66
|
+
kind: 'image' | 'text' | 'none';
|
|
67
|
+
marker?: string;
|
|
68
|
+
};
|
|
69
|
+
executeCommand?: (name: string, args: string[]) => Promise<boolean>;
|
|
70
|
+
cancelGeneration?: () => void;
|
|
71
|
+
completeModelSelection?: (selection: {
|
|
72
|
+
model: { id: string; provider: string; displayName: string; registryKey: string };
|
|
73
|
+
effort: string;
|
|
74
|
+
contextCap?: number | null;
|
|
75
|
+
/** Which config target to write the selected model to. Defaults to 'main'. */
|
|
76
|
+
target?: import('./model-picker.ts').ModelPickerTarget;
|
|
77
|
+
}) => void;
|
|
78
|
+
clearScreen?: () => void;
|
|
79
|
+
activatePlan?: (planId: string, task: string) => void;
|
|
80
|
+
requestPermission?: PermissionRequestHandler;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface CommandShellUiOpeners {
|
|
84
|
+
reloadSystemPrompt?: () => string;
|
|
85
|
+
openOnboardingWizard?: (modeOrOptions?: OnboardingWizardMode | OpenOnboardingWizardOptions) => void;
|
|
86
|
+
openModelPicker?: () => void;
|
|
87
|
+
openModelPickerWithTarget?: (target: import('./model-picker.ts').ModelPickerTarget) => boolean;
|
|
88
|
+
openProviderModelPickerWithTarget?: (target: import('./model-picker.ts').ModelPickerTarget) => boolean;
|
|
89
|
+
openProviderPicker?: () => void;
|
|
90
|
+
openContextInspector?: () => void;
|
|
91
|
+
openBookmarkModal?: () => void;
|
|
92
|
+
jumpToBookmark?: (key: string) => void;
|
|
93
|
+
scrollToLine?: (line: number) => void;
|
|
94
|
+
openHelpOverlay?: () => void;
|
|
95
|
+
openSelection?: (
|
|
96
|
+
title: string,
|
|
97
|
+
items: SelectionItem[],
|
|
98
|
+
opts: { preSelectId?: string; allowSearch?: boolean; customActions?: Map<string, SelectionAction> } | undefined,
|
|
99
|
+
callback: (result: SelectionResult | null) => void,
|
|
100
|
+
) => void;
|
|
101
|
+
openSettingsModal?: (target?: string) => void;
|
|
102
|
+
openSessionPicker?: () => void;
|
|
103
|
+
openProfilePicker?: () => void;
|
|
104
|
+
openShortcutsOverlay?: () => void;
|
|
105
|
+
getScrollTop?: () => number;
|
|
106
|
+
openPanelPicker?: () => void;
|
|
107
|
+
showPanel?: (panelId: string, pane?: 'top' | 'bottom') => void;
|
|
108
|
+
focusPanels?: () => void;
|
|
109
|
+
focusPrompt?: () => void;
|
|
110
|
+
openOpsPanel?: () => void;
|
|
111
|
+
openCockpitPanel?: () => void;
|
|
112
|
+
openOrchestrationPanel?: () => void;
|
|
113
|
+
openForensicsPanel?: () => void;
|
|
114
|
+
openIncidentPanel?: () => void;
|
|
115
|
+
openPolicyPanel?: () => void;
|
|
116
|
+
openHooksPanel?: () => void;
|
|
117
|
+
openCommunicationPanel?: () => void;
|
|
118
|
+
openMcpWorkspace?: () => void;
|
|
119
|
+
openAgentWorkspace?: () => void;
|
|
120
|
+
openSecurityPanel?: () => void;
|
|
121
|
+
openKnowledgePanel?: () => void;
|
|
122
|
+
openRemotePanel?: () => void;
|
|
123
|
+
openSubscriptionPanel?: () => void;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface CommandSessionServices {
|
|
127
|
+
readonly conversationManager: ConversationManager;
|
|
128
|
+
readonly runtime: CommandRuntimeState;
|
|
129
|
+
readonly sessionManager?: import('@pellux/goodvibes-sdk/platform/sessions').SessionManager;
|
|
130
|
+
readonly sessionMemoryStore?: import('@pellux/goodvibes-sdk/platform/core').SessionMemoryStore;
|
|
131
|
+
readonly sessionLineageTracker?: import('@pellux/goodvibes-sdk/platform/core').SessionLineageTracker;
|
|
132
|
+
readonly changeTracker?: import('@pellux/goodvibes-sdk/platform/sessions').SessionChangeTracker;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export interface CommandProviderServices {
|
|
136
|
+
readonly providerRegistry: ProviderRegistry;
|
|
137
|
+
readonly providerOptimizer?: import('@pellux/goodvibes-sdk/platform/providers').ProviderOptimizer;
|
|
138
|
+
readonly favoritesStore?: import('@pellux/goodvibes-sdk/platform/providers').FavoritesStore;
|
|
139
|
+
readonly benchmarkStore?: import('@pellux/goodvibes-sdk/platform/providers').BenchmarkStore;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Compose locally-owned command helpers with the narrower shell bridge-owned
|
|
144
|
+
* runtime surfaces exported from runtime/shell-command-services.ts.
|
|
145
|
+
*/
|
|
146
|
+
export interface CommandWorkspaceUiServices {
|
|
147
|
+
keybindingsManager?: KeybindingsManager;
|
|
148
|
+
fileUndoManager?: FileUndoManager;
|
|
149
|
+
panelManager?: PanelManager;
|
|
150
|
+
profileManager?: import('@pellux/goodvibes-sdk/platform/profiles').ProfileManager;
|
|
151
|
+
bookmarkManager?: import('@pellux/goodvibes-sdk/platform/bookmarks').BookmarkManager;
|
|
152
|
+
projectPlanningService?: import('@pellux/goodvibes-sdk/platform/knowledge').ProjectPlanningService;
|
|
153
|
+
projectPlanningProjectId?: string;
|
|
154
|
+
workPlanStore?: import('../work-plans/work-plan-store.ts').WorkPlanStore;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export interface CommandWorkspaceServices
|
|
158
|
+
extends CommandWorkspaceUiServices,
|
|
159
|
+
CommandWorkspaceShellServices {}
|
|
160
|
+
|
|
161
|
+
export interface CommandPlatformConfigServices {
|
|
162
|
+
readonly config: DeepReadonly<GoodVibesConfig>;
|
|
163
|
+
readonly configManager: ConfigManager;
|
|
164
|
+
readonly voiceProviderRegistry?: VoiceProviderRegistry;
|
|
165
|
+
readonly voiceService?: VoiceService;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export interface CommandPlatformServices
|
|
169
|
+
extends CommandPlatformConfigServices,
|
|
170
|
+
CommandPlatformShellServices {}
|
|
171
|
+
|
|
172
|
+
export interface CommandOpsServices
|
|
173
|
+
extends CommandOpsShellServices {}
|
|
174
|
+
|
|
175
|
+
export interface CommandExtensionRegistryServices {
|
|
176
|
+
readonly toolRegistry: ToolRegistry;
|
|
177
|
+
readonly mcpRegistry: McpRegistry;
|
|
178
|
+
readonly evalRegistry?: import('../panels/eval-panel.ts').EvalRegistry;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export interface CommandExtensionServices
|
|
182
|
+
extends CommandExtensionRegistryServices,
|
|
183
|
+
CommandExtensionShellServices {}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* CommandContext - Passed to every slash command handler so commands can
|
|
187
|
+
* interact with the shell-facing platform surface without treating every
|
|
188
|
+
* service as one flat bag of unrelated properties.
|
|
189
|
+
*/
|
|
190
|
+
export interface CommandContext
|
|
191
|
+
extends CommandUiActions,
|
|
192
|
+
CommandShellUiOpeners {
|
|
193
|
+
readonly session: CommandSessionServices;
|
|
194
|
+
readonly provider: CommandProviderServices;
|
|
195
|
+
readonly workspace: CommandWorkspaceServices;
|
|
196
|
+
readonly platform: CommandPlatformServices;
|
|
197
|
+
readonly ops: CommandOpsServices;
|
|
198
|
+
readonly extensions: CommandExtensionServices;
|
|
199
|
+
readonly clients?: {
|
|
200
|
+
readonly operator?: OperatorClient;
|
|
201
|
+
readonly peer?: PeerClient;
|
|
202
|
+
readonly providerApi?: ProviderApi;
|
|
203
|
+
readonly knowledgeApi?: KnowledgeApi;
|
|
204
|
+
readonly hookApi?: HookApi;
|
|
205
|
+
readonly mcpApi?: McpApi;
|
|
206
|
+
readonly opsApi?: OpsApi;
|
|
207
|
+
readonly transport?: DirectTransport;
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* SlashCommand - A single slash command definition.
|
|
213
|
+
*/
|
|
214
|
+
export interface SlashCommand {
|
|
215
|
+
/** Primary name, e.g. "model". Full invocation is "/model". */
|
|
216
|
+
name: string;
|
|
217
|
+
/** Alternate names, e.g. ["m"]. */
|
|
218
|
+
aliases?: string[];
|
|
219
|
+
/** One-line description shown in /help output. */
|
|
220
|
+
description: string;
|
|
221
|
+
/** Optional usage hint, e.g. "<model-id>". */
|
|
222
|
+
usage?: string;
|
|
223
|
+
/** Short inline argument hint shown after cursor in dim grey, e.g. "[name]". Falls back to usage if not set. */
|
|
224
|
+
argsHint?: string;
|
|
225
|
+
/** The function executed when the command is invoked. */
|
|
226
|
+
handler: (args: string[], context: CommandContext) => void | Promise<void>;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* CommandRegistry - Central registry for all slash commands.
|
|
231
|
+
* Supports fuzzy prefix matching for autocomplete.
|
|
232
|
+
*/
|
|
233
|
+
export class CommandRegistry {
|
|
234
|
+
private commands = new Map<string, SlashCommand>();
|
|
235
|
+
private aliasIndex = new Map<string, SlashCommand>();
|
|
236
|
+
|
|
237
|
+
/** Register a command. Also indexes all aliases for O(1) lookup. */
|
|
238
|
+
register(command: SlashCommand): void {
|
|
239
|
+
this.commands.set(command.name, command);
|
|
240
|
+
for (const alias of command.aliases ?? []) {
|
|
241
|
+
this.aliasIndex.set(alias, command);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/** Remove a command by primary name. Also removes its alias entries. */
|
|
246
|
+
unregister(name: string): void {
|
|
247
|
+
const cmd = this.commands.get(name);
|
|
248
|
+
if (cmd) {
|
|
249
|
+
for (const alias of cmd.aliases ?? []) {
|
|
250
|
+
this.aliasIndex.delete(alias);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
this.commands.delete(name);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* get - Look up a command by its primary name or any alias. O(1) for both.
|
|
258
|
+
*/
|
|
259
|
+
get(name: string): SlashCommand | undefined {
|
|
260
|
+
return this.commands.get(name) ?? this.aliasIndex.get(name);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/** All registered commands. */
|
|
264
|
+
getAll(): SlashCommand[] {
|
|
265
|
+
return Array.from(this.commands.values());
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* list - Compatibility alias for the simpler SDK registry surface.
|
|
270
|
+
*/
|
|
271
|
+
list(): SlashCommand[] {
|
|
272
|
+
return this.getAll();
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* fuzzyMatch - Return commands ranked by how well `query` matches their
|
|
277
|
+
* name or aliases. Returns all commands when query is empty.
|
|
278
|
+
*/
|
|
279
|
+
fuzzyMatch(query: string): Array<{ command: SlashCommand; score: number }> {
|
|
280
|
+
const q = query.toLowerCase();
|
|
281
|
+
const results: Array<{ command: SlashCommand; score: number }> = [];
|
|
282
|
+
|
|
283
|
+
for (const cmd of this.commands.values()) {
|
|
284
|
+
const names = [cmd.name, ...(cmd.aliases ?? [])];
|
|
285
|
+
let bestScore = 0;
|
|
286
|
+
|
|
287
|
+
for (const candidate of names) {
|
|
288
|
+
const score = scoreMatch(q, candidate);
|
|
289
|
+
if (score > bestScore) bestScore = score;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (bestScore > 0 || q === '') {
|
|
293
|
+
results.push({ command: cmd, score: q === '' ? 1 : bestScore });
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Sort: higher score first, then alphabetically
|
|
298
|
+
results.sort((a, b) => b.score - a.score || a.command.name.localeCompare(b.command.name));
|
|
299
|
+
return results;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* execute - Look up and run a command. Returns true if found, false otherwise.
|
|
304
|
+
*/
|
|
305
|
+
async execute(rawName: string, args: string[], context: CommandContext): Promise<boolean> {
|
|
306
|
+
const cmd = this.get(rawName);
|
|
307
|
+
if (!cmd) return false;
|
|
308
|
+
await cmd.handler(args, context);
|
|
309
|
+
return true;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* scoreMatch - Simple prefix/subsequence scorer.
|
|
315
|
+
* Returns 0 if no match, higher is better.
|
|
316
|
+
*/
|
|
317
|
+
function scoreMatch(query: string, candidate: string): number {
|
|
318
|
+
if (query === '') return 1;
|
|
319
|
+
if (candidate === query) return 100;
|
|
320
|
+
if (candidate.startsWith(query)) return 80;
|
|
321
|
+
|
|
322
|
+
// Subsequence check
|
|
323
|
+
let qi = 0;
|
|
324
|
+
for (let ci = 0; ci < candidate.length && qi < query.length; ci++) {
|
|
325
|
+
if (candidate[ci] === query[qi]) qi++;
|
|
326
|
+
}
|
|
327
|
+
if (qi === query.length) return 40 - query.length; // shorter query → higher score
|
|
328
|
+
return 0;
|
|
329
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { CommandRegistry, SlashCommand } from '../command-registry.ts';
|
|
2
|
+
|
|
3
|
+
type ExternalizedCommandId = 'git' | 'diff' | 'worktree' | 'sandbox';
|
|
4
|
+
|
|
5
|
+
interface ExternalizedCommandSpec {
|
|
6
|
+
readonly name: ExternalizedCommandId;
|
|
7
|
+
readonly aliases?: readonly string[];
|
|
8
|
+
readonly description: string;
|
|
9
|
+
readonly usage: string;
|
|
10
|
+
readonly owner: string;
|
|
11
|
+
readonly reason: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const EXTERNALIZED_TUI_COMMANDS: readonly ExternalizedCommandSpec[] = [
|
|
15
|
+
{
|
|
16
|
+
name: 'git',
|
|
17
|
+
aliases: ['g'],
|
|
18
|
+
description: 'Externalized: git workflows are owned by GoodVibes TUI',
|
|
19
|
+
usage: '[status|log|diff]',
|
|
20
|
+
owner: 'GoodVibes TUI',
|
|
21
|
+
reason: 'Git status, commits, and repository mutation belong to the coding TUI, not the serial Agent surface.',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'diff',
|
|
25
|
+
aliases: ['d'],
|
|
26
|
+
description: 'Externalized: code diff review is owned by GoodVibes TUI',
|
|
27
|
+
usage: '[session|head|working|staged|<git-ref>]',
|
|
28
|
+
owner: 'GoodVibes TUI',
|
|
29
|
+
reason: 'Diff views are part of delegated build/fix/review work and should stay attached to the coding TUI execution context.',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'worktree',
|
|
33
|
+
aliases: ['worktrees'],
|
|
34
|
+
description: 'Externalized: git worktree lifecycle is owned by GoodVibes TUI',
|
|
35
|
+
usage: '[review|inspect|attach|recover|cleanup]',
|
|
36
|
+
owner: 'GoodVibes TUI',
|
|
37
|
+
reason: 'Worktree creation, attachment, recovery, and cleanup are coding-session lifecycle operations.',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'sandbox',
|
|
41
|
+
description: 'Externalized: sandbox and QEMU workflows are owned by GoodVibes TUI',
|
|
42
|
+
usage: '[review|probe|session|qemu|bundle|preset]',
|
|
43
|
+
owner: 'GoodVibes TUI',
|
|
44
|
+
reason: 'Sandbox/QEMU setup and session execution are terminal-native coding/runtime isolation workflows.',
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
function makeExternalizedCommand(spec: ExternalizedCommandSpec): SlashCommand {
|
|
49
|
+
return {
|
|
50
|
+
name: spec.name,
|
|
51
|
+
aliases: spec.aliases ? [...spec.aliases] : undefined,
|
|
52
|
+
description: spec.description,
|
|
53
|
+
usage: spec.usage,
|
|
54
|
+
argsHint: spec.usage,
|
|
55
|
+
handler(_args, ctx) {
|
|
56
|
+
ctx.print([
|
|
57
|
+
`${spec.name} is externalized in GoodVibes Agent.`,
|
|
58
|
+
` owner: ${spec.owner}`,
|
|
59
|
+
` reason: ${spec.reason}`,
|
|
60
|
+
' Agent policy: no local coding TUI, git/worktree, or sandbox execution from this surface.',
|
|
61
|
+
' build/fix/review: ask Agent to delegate the full request to GoodVibes TUI, or run goodvibes-tui in the target workspace.',
|
|
62
|
+
' result: blocked here; no local files, config, worktrees, sandbox sessions, or repository state were changed.',
|
|
63
|
+
].join('\n'));
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function registerAgentExternalizedTuiCommands(registry: CommandRegistry): void {
|
|
69
|
+
for (const spec of EXTERNALIZED_TUI_COMMANDS) {
|
|
70
|
+
registry.register(makeExternalizedCommand(spec));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CommandRegistry } from '../command-registry.ts';
|
|
2
|
+
|
|
3
|
+
export function registerAgentWorkspaceRuntimeCommands(registry: CommandRegistry): void {
|
|
4
|
+
registry.register({
|
|
5
|
+
name: 'agent',
|
|
6
|
+
aliases: ['home', 'operator'],
|
|
7
|
+
description: 'Open the GoodVibes Agent operator workspace',
|
|
8
|
+
usage: '',
|
|
9
|
+
handler(_args, ctx) {
|
|
10
|
+
if (!ctx.openAgentWorkspace) {
|
|
11
|
+
ctx.print('Agent operator workspace is not available in this runtime.');
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
ctx.openAgentWorkspace();
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { CommandRegistry } from '../command-registry.ts';
|
|
2
|
+
|
|
3
|
+
export function registerBranchRuntimeCommands(registry: CommandRegistry): void {
|
|
4
|
+
registry.register({
|
|
5
|
+
name: 'fork',
|
|
6
|
+
aliases: ['branch-save'],
|
|
7
|
+
description: 'Save a named snapshot of the current conversation',
|
|
8
|
+
usage: '[name]',
|
|
9
|
+
argsHint: '[name]',
|
|
10
|
+
handler(args, ctx) {
|
|
11
|
+
const name = args[0];
|
|
12
|
+
const branchName = ctx.session.conversationManager.forkBranch(name);
|
|
13
|
+
const msgCount = ctx.session.conversationManager.getMessageCount();
|
|
14
|
+
ctx.print(`Forked conversation as "${branchName}" (${msgCount} message${msgCount === 1 ? '' : 's'}).`);
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
registry.register({
|
|
19
|
+
name: 'branch',
|
|
20
|
+
aliases: ['br'],
|
|
21
|
+
description: 'List conversation branches or switch to one',
|
|
22
|
+
usage: '[name]',
|
|
23
|
+
argsHint: '[name]',
|
|
24
|
+
handler(args, ctx) {
|
|
25
|
+
if (args.length === 0) {
|
|
26
|
+
const branches = ctx.session.conversationManager.listBranches();
|
|
27
|
+
if (branches.length === 0) {
|
|
28
|
+
ctx.print('No branches. Use /fork [name] to create one.');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const current = ctx.session.conversationManager.getCurrentBranch();
|
|
32
|
+
const lines = [`Branches (current: ${current}):`];
|
|
33
|
+
for (const branch of branches) {
|
|
34
|
+
const marker = branch.isCurrent ? '▶' : ' ';
|
|
35
|
+
lines.push(` ${marker} ${branch.name} (${branch.messageCount} message${branch.messageCount === 1 ? '' : 's'})`);
|
|
36
|
+
}
|
|
37
|
+
ctx.print(lines.join('\n'));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const name = args[0];
|
|
41
|
+
const ok = ctx.session.conversationManager.switchBranch(name);
|
|
42
|
+
if (!ok) {
|
|
43
|
+
ctx.print(`Branch "${name}" not found. Use /fork [name] to create one, or /branch to list.`);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
ctx.print(`Switched to branch "${name}".`);
|
|
47
|
+
ctx.renderRequest();
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
registry.register({
|
|
52
|
+
name: 'merge',
|
|
53
|
+
aliases: [],
|
|
54
|
+
description: 'Append messages from a branch after the fork point',
|
|
55
|
+
usage: '<name>',
|
|
56
|
+
argsHint: '<name>',
|
|
57
|
+
handler(args, ctx) {
|
|
58
|
+
const name = args[0];
|
|
59
|
+
if (!name) {
|
|
60
|
+
ctx.print('Usage: /merge <branch-name>\nSee /branch for available branches.');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const ok = ctx.session.conversationManager.mergeBranch(name);
|
|
64
|
+
if (!ok) {
|
|
65
|
+
ctx.print(`Branch "${name}" not found. Use /branch to list available branches.`);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
ctx.print(`Merged branch "${name}" into current conversation.`);
|
|
69
|
+
ctx.renderRequest();
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
}
|