@pellux/goodvibes-tui 2.0.21 → 2.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/CHANGELOG.md +58 -0
- package/README.md +16 -16
- package/docs/README.md +4 -4
- package/docs/foundation-artifacts/operator-contract.json +1 -1
- package/package.json +16 -6
- package/src/cli/management.ts +5 -2
- package/src/cli/tui-startup.ts +34 -39
- package/src/core/agent-view-render.ts +157 -0
- package/src/core/approval-alert.ts +49 -11
- package/src/core/bookmark-navigation.ts +7 -1
- package/src/core/budget-breach-notifier.ts +27 -8
- package/src/core/compaction-receipt.ts +1 -1
- package/src/core/context-usage.ts +1 -1
- package/src/core/conversation-compaction-render.ts +3 -3
- package/src/core/conversation-display-only.ts +86 -0
- package/src/core/conversation-event-navigation.ts +27 -0
- package/src/core/conversation-line-cache.ts +216 -447
- package/src/core/conversation-render-context.ts +20 -27
- package/src/core/conversation-rendering.ts +157 -575
- package/src/core/conversation-splash-state.ts +6 -1
- package/src/core/conversation-types.ts +35 -0
- package/src/core/conversation-usage.ts +12 -0
- package/src/core/conversation.ts +130 -131
- package/src/core/long-task-notifier.ts +100 -31
- package/src/core/notices.ts +75 -0
- package/src/core/pairing-tailscale-gateway.ts +1 -1
- package/src/core/process-output-log.ts +143 -0
- package/src/core/rewind-receipt.ts +1 -1
- package/src/core/session-focus.ts +190 -0
- package/src/core/session-resume-core.ts +23 -81
- package/src/core/stream-event-wiring.ts +31 -5
- package/src/core/system-message-noise.ts +2 -2
- package/src/core/system-message-router.ts +16 -18
- package/src/core/turn-event-wiring.ts +272 -33
- package/src/core/work-tree-focus.ts +290 -0
- package/src/core/work-tree-fold-store.ts +143 -0
- package/src/core/work-tree-model.ts +799 -0
- package/src/core/work-tree-render.ts +384 -0
- package/src/core/work-tree-sources.ts +184 -0
- package/src/core/work-tree-wiring.ts +176 -0
- package/src/core/workstream-notification.ts +36 -6
- package/src/core/wrfc-notice-titles.ts +37 -0
- package/src/input/agents-modal-text.ts +119 -0
- package/src/input/agents-modal.ts +699 -0
- package/src/input/bookmark-modal.ts +33 -9
- package/src/input/changes-git.ts +251 -0
- package/src/input/changes-modal.ts +629 -0
- package/src/input/changes-model.ts +125 -0
- package/src/input/command-palette-types.ts +41 -0
- package/src/input/command-palette.ts +272 -0
- package/src/input/command-registry.ts +77 -35
- package/src/input/commands/acp-runtime.ts +19 -9
- package/src/input/commands/channel-runtime.ts +2 -2
- package/src/input/commands/ci-runtime.ts +1 -1
- package/src/input/commands/codebase-runtime.ts +1 -1
- package/src/input/commands/config.ts +7 -1
- package/src/input/commands/context-window.ts +25 -19
- package/src/input/commands/control-room-runtime.ts +18 -18
- package/src/input/commands/conversation-runtime.ts +0 -1
- package/src/input/commands/cost-runtime.ts +29 -20
- package/src/input/commands/diff-runtime.ts +35 -181
- package/src/input/commands/eval.ts +1 -1
- package/src/input/commands/experience-runtime.ts +3 -7
- package/src/input/commands/fresh-conversation.ts +86 -0
- package/src/input/commands/git-runtime.ts +5 -22
- package/src/input/commands/graph-runtime.ts +1 -1
- package/src/input/commands/guidance-runtime.ts +1 -1
- package/src/input/commands/health-runtime.ts +8 -9
- package/src/input/commands/hooks-runtime.ts +2 -2
- package/src/input/commands/hosted-runtime.ts +3 -3
- package/src/input/commands/incident-runtime.ts +3 -3
- package/src/input/commands/intelligence-runtime.ts +6 -9
- package/src/input/commands/knowledge.ts +2 -2
- package/src/input/commands/legacy-panel-command.ts +57 -0
- package/src/input/commands/local-auth-runtime.ts +8 -9
- package/src/input/commands/local-provider-runtime.ts +7 -4
- package/src/input/commands/local-runtime.ts +12 -15
- package/src/input/commands/local-setup-review.ts +1 -1
- package/src/input/commands/local-setup.ts +13 -19
- package/src/input/commands/memory.ts +1 -1
- package/src/input/commands/notify-runtime.ts +9 -0
- package/src/input/commands/operator-runtime.ts +10 -12
- package/src/input/commands/permissions-provenance.ts +3 -3
- package/src/input/commands/planning-runtime.ts +7 -7
- package/src/input/commands/platform-sandbox-runtime.ts +2 -2
- package/src/input/commands/platform-services-runtime.ts +1 -1
- package/src/input/commands/policy-dispatch.ts +2 -2
- package/src/input/commands/policy.ts +3 -3
- package/src/input/commands/provider.ts +1 -1
- package/src/input/commands/remote-runtime.ts +1 -1
- package/src/input/commands/review-runtime.ts +39 -94
- package/src/input/commands/rewind-runtime.ts +81 -108
- package/src/input/commands/runtime-services.ts +15 -17
- package/src/input/commands/services-runtime.ts +2 -2
- package/src/input/commands/session-content.ts +21 -5
- package/src/input/commands/session-workflow.ts +13 -38
- package/src/input/commands/settings-sync-runtime.ts +2 -2
- package/src/input/commands/shell-core.ts +19 -4
- package/src/input/commands/skills-runtime.ts +2 -2
- package/src/input/commands/status-runtime.ts +13 -0
- package/src/input/commands/subscription-runtime.ts +1 -1
- package/src/input/commands/tasks-runtime.ts +2 -8
- package/src/input/commands/work-plan-runtime.ts +4 -4
- package/src/input/commands/workstream-attempts.ts +24 -47
- package/src/input/commands/workstream-runtime.ts +2 -2
- package/src/input/commands/worktree-runtime.ts +3 -3
- package/src/input/commands.ts +3 -1
- package/src/input/composer-editor.ts +44 -0
- package/src/input/concealed-input.ts +1 -1
- package/src/input/config-modal-types.ts +20 -8
- package/src/input/config-modal.ts +106 -105
- package/src/input/confirm-dialog-types.ts +28 -0
- package/src/input/confirm-dialog.ts +70 -0
- package/src/input/delete-key-policy.ts +3 -3
- package/src/input/feed-context-factory.ts +15 -16
- package/src/input/handler-command-route.ts +7 -42
- package/src/input/handler-content-actions.ts +16 -15
- package/src/input/handler-feed-routes.ts +26 -211
- package/src/input/handler-feed.ts +68 -95
- package/src/input/handler-interactions.ts +5 -3
- package/src/input/handler-modal-routes.ts +215 -216
- package/src/input/handler-modal-stack.ts +81 -11
- package/src/input/handler-modal-token-routes.ts +4 -0
- package/src/input/handler-onboarding.ts +0 -1
- package/src/input/handler-picker-routes.ts +65 -107
- package/src/input/handler-session-view-route.ts +149 -0
- package/src/input/handler-shortcuts.ts +16 -154
- package/src/input/handler-types.ts +4 -2
- package/src/input/handler-ui-state.ts +45 -15
- package/src/input/handler-work-tree-route.ts +123 -0
- package/src/input/handler.ts +25 -70
- package/src/input/keybindings.ts +16 -71
- package/src/input/masked-entry-modal.ts +117 -0
- package/src/input/mcp-workspace.ts +48 -17
- package/src/input/model-picker-filter.ts +8 -0
- package/src/input/model-picker-open.ts +99 -0
- package/src/input/model-picker-types.ts +1 -1
- package/src/input/model-picker.ts +92 -9
- package/src/input/notifications-modal.ts +123 -0
- package/src/input/overlay-filter.ts +26 -0
- package/src/input/profile-picker-modal.ts +37 -8
- package/src/input/search.ts +3 -3
- package/src/input/selection-modal-queue.ts +2 -0
- package/src/input/selection-modal.ts +28 -16
- package/src/input/session-picker-modal.ts +33 -8
- package/src/input/settings-modal-activation.ts +7 -2
- package/src/input/settings-modal-data.ts +11 -6
- package/src/input/settings-modal-types.ts +1 -1
- package/src/input/settings-modal.ts +20 -20
- package/src/input/submission-intent.ts +1 -1
- package/src/input/submission-router.ts +4 -9
- package/src/input/surface-modal-host.ts +110 -0
- package/src/input/theme-settings-actions.ts +82 -0
- package/src/input/usage-modal.ts +183 -0
- package/src/input/views.ts +97 -0
- package/src/main.ts +175 -165
- package/src/permissions/hunk-selection.ts +1 -1
- package/src/permissions/prompt-card.ts +511 -0
- package/src/permissions/prompt.ts +59 -622
- package/src/renderer/agents-modal.ts +310 -0
- package/src/renderer/autocomplete-overlay.ts +42 -220
- package/src/renderer/back-to-bottom.ts +80 -0
- package/src/renderer/block-actions-overlay.ts +30 -48
- package/src/renderer/bookmark-modal.ts +48 -79
- package/src/renderer/changes-modal.ts +325 -0
- package/src/renderer/code-block.ts +184 -106
- package/src/renderer/command-palette.ts +93 -0
- package/src/renderer/composer-fragments.ts +4 -4
- package/src/renderer/composer.ts +146 -0
- package/src/renderer/compositor.ts +26 -160
- package/src/renderer/config-modal.ts +185 -81
- package/src/renderer/confirm-dialog.ts +50 -0
- package/src/renderer/context-inspector.ts +116 -154
- package/src/renderer/context-status-hint.ts +4 -4
- package/src/renderer/conversation-layout.ts +20 -0
- package/src/renderer/conversation-overlays.ts +94 -84
- package/src/renderer/conversation-surface.ts +19 -38
- package/src/renderer/diff-tint.ts +98 -0
- package/src/renderer/file-picker-overlay.ts +63 -90
- package/src/renderer/footer-targets.ts +38 -0
- package/src/renderer/git-status.ts +3 -4
- package/src/renderer/header-line.ts +140 -117
- package/src/renderer/help-overlay.ts +133 -219
- package/src/renderer/history-search-overlay.ts +15 -12
- package/src/renderer/lane-graph/bead.ts +800 -0
- package/src/renderer/lane-graph/glyphs.ts +134 -0
- package/src/renderer/lane-graph/layout.ts +248 -0
- package/src/renderer/lane-graph/paint.ts +537 -0
- package/src/renderer/lane-graph/semantic-memo.ts +77 -0
- package/src/renderer/layout-engine.ts +2 -57
- package/src/renderer/layout.ts +7 -13
- package/src/renderer/markdown-inline.ts +2 -1
- package/src/renderer/markdown-table.ts +17 -12
- package/src/renderer/markdown.ts +92 -34
- package/src/renderer/masked-entry-modal.ts +78 -0
- package/src/renderer/mcp-workspace.ts +166 -203
- package/src/renderer/model-workspace.ts +381 -436
- package/src/renderer/notifications-modal.ts +116 -0
- package/src/renderer/onboarding/onboarding-wizard.ts +178 -588
- package/src/renderer/process-view.ts +192 -0
- package/src/renderer/profile-picker-modal.ts +58 -110
- package/src/renderer/search-overlay.ts +6 -3
- package/src/renderer/selection-modal-overlay.ts +87 -327
- package/src/renderer/semantic-diff.ts +2 -2
- package/src/renderer/session-chips.ts +102 -0
- package/src/renderer/session-picker-modal.ts +177 -297
- package/src/renderer/settings-modal-connections.ts +14 -23
- package/src/renderer/settings-modal-context.ts +367 -0
- package/src/renderer/settings-modal-helpers.ts +6 -11
- package/src/renderer/settings-modal.ts +322 -726
- package/src/renderer/shell-surface.ts +277 -175
- package/src/renderer/shortcuts-overlay.ts +217 -0
- package/src/renderer/status-line.ts +475 -0
- package/src/renderer/surface-compose.ts +174 -0
- package/src/renderer/surface-kit-extra.ts +303 -0
- package/src/renderer/surface-kit-list.ts +366 -0
- package/src/renderer/surface-kit-parts.ts +360 -0
- package/src/renderer/surface-kit.ts +568 -0
- package/src/renderer/syntax-highlighter.ts +280 -197
- package/src/renderer/syntax-theme.ts +51 -0
- package/src/renderer/system-message.ts +0 -1
- package/src/renderer/term-caps.ts +42 -1
- package/src/renderer/terminal-bg-probe.ts +116 -19
- package/src/renderer/terminal-palette-probe.ts +322 -0
- package/src/renderer/terminal-palette-reader.ts +183 -0
- package/src/renderer/terminal-palette.ts +58 -0
- package/src/renderer/theme-mode-config.ts +16 -1
- package/src/renderer/theme.ts +234 -207
- package/src/renderer/thinking.ts +0 -1
- package/src/renderer/throbber.ts +188 -0
- package/src/renderer/toast-center.ts +119 -0
- package/src/renderer/ui-factory.ts +39 -602
- package/src/renderer/ui-primitives.ts +8 -25
- package/src/renderer/usage-modal.ts +353 -0
- package/src/renderer/user-message.ts +58 -0
- package/src/renderer/voice-capture-chip.ts +53 -0
- package/src/runtime/bootstrap-command-context.ts +0 -5
- package/src/runtime/bootstrap-command-parts.ts +38 -89
- package/src/runtime/bootstrap-core.ts +13 -15
- package/src/runtime/bootstrap-hook-bridge.ts +12 -21
- package/src/runtime/bootstrap-notifier-sync.ts +17 -1
- package/src/runtime/bootstrap-shell.ts +16 -50
- package/src/runtime/bootstrap.ts +14 -14
- package/src/runtime/client/fleet-union.ts +5 -5
- package/src/runtime/client/hosted-exit.ts +2 -2
- package/src/runtime/client/hosted-sessions.ts +1 -1
- package/src/runtime/client/spine-adoption.ts +1 -1
- package/src/runtime/context-accounting-source.ts +5 -4
- package/src/runtime/index.ts +1 -0
- package/src/runtime/notification-dispatch.ts +102 -29
- package/src/runtime/recovery-offer-wiring.ts +4 -1
- package/src/runtime/recovery-prompt.ts +31 -15
- package/src/runtime/runtime-services-types.ts +10 -6
- package/src/runtime/services.ts +17 -12
- package/src/runtime/session-continuity-hints.ts +2 -5
- package/src/runtime/session-inbound-inputs.ts +1 -1
- package/src/runtime/session-resume-liveness-confirm.ts +14 -2
- package/src/runtime/startup-typeahead-gate.ts +103 -0
- package/src/runtime/store/domains/domain-read-matrix.ts +0 -1
- package/src/runtime/store/domains/index.ts +0 -8
- package/src/runtime/store/selectors/index.ts +0 -28
- package/src/runtime/store/state.ts +0 -8
- package/src/runtime/ui-services.ts +4 -6
- package/src/runtime/usage-tracker.ts +348 -0
- package/src/runtime/wrfc-persistence.ts +4 -4
- package/src/shell/blocking-input.ts +92 -2
- package/src/shell/recovery-input-helpers.ts +1 -1
- package/src/shell/session-views.ts +539 -0
- package/src/shell/status-report.ts +86 -0
- package/src/shell/transcript-scroll.ts +68 -0
- package/src/shell/ui-openers.ts +84 -172
- package/src/shell/view-openers.ts +205 -0
- package/src/tools/wrfc-agent-guard.ts +22 -2
- package/src/utils/format-duration.ts +4 -8
- package/src/utils/splash-lines.ts +9 -1
- package/src/utils/terminal-width.ts +56 -0
- package/src/verification/verification-ledger.ts +18 -16
- package/src/{panels → views}/agent-inspector-shared.ts +2 -2
- package/src/{panels → views}/builtin-modals.ts +22 -21
- package/src/views/builtin-views.ts +135 -0
- package/src/{panels → views}/confirm-state.ts +9 -9
- package/src/{panels → views}/diff-review-model.ts +10 -3
- package/src/{panels → views}/eval-registry.ts +1 -1
- package/src/{panels → views}/fleet-acts.ts +49 -85
- package/src/{panels/fleet-panel-format.ts → views/fleet-format.ts} +40 -40
- package/src/{panels → views}/fleet-gateway.ts +5 -5
- package/src/{panels → views}/fleet-observed-render.ts +16 -16
- package/src/{panels → views}/fleet-read-model.ts +9 -9
- package/src/{panels/fleet-tabs.ts → views/fleet-session-tabs.ts} +13 -13
- package/src/{panels → views}/fleet-spawn.ts +33 -49
- package/src/{panels → views}/fleet-steer.ts +12 -12
- package/src/{panels → views}/fleet-stop.ts +4 -4
- package/src/{panels → views}/fleet-transcript.ts +26 -27
- package/src/{panels/fleet-panel-worktree-detail.ts → views/fleet-worktree-detail.ts} +7 -7
- package/src/{panels → views}/hosted-session-feed.ts +6 -6
- package/src/views/modal-surface-registry.ts +41 -0
- package/src/{panels → views}/modals/devices-modal.ts +2 -2
- package/src/{panels → views}/modals/hooks-modal.ts +13 -13
- package/src/{panels → views}/modals/keybindings-modal.ts +19 -27
- package/src/{panels → views}/modals/knowledge-modal.ts +6 -5
- package/src/{panels → views}/modals/local-auth-modal.ts +22 -21
- package/src/{panels → views}/modals/marketplace-modal.ts +11 -11
- package/src/{panels → views}/modals/memory-modal.ts +8 -8
- package/src/{panels → views}/modals/modal-surface-helpers.ts +15 -5
- package/src/{panels → views}/modals/pairing-modal.ts +9 -9
- package/src/{panels → views}/modals/planning-modal.ts +15 -20
- package/src/{panels → views}/modals/plugins-modal.ts +6 -6
- package/src/{panels → views}/modals/policy-modal.ts +13 -5
- package/src/{panels → views}/modals/provider-health-modal.ts +4 -4
- package/src/{panels → views}/modals/remote-modal.ts +3 -3
- package/src/{panels → views}/modals/sandbox-modal.ts +4 -4
- package/src/{panels → views}/modals/security-modal.ts +22 -16
- package/src/{panels → views}/modals/services-modal.ts +3 -3
- package/src/{panels → views}/modals/settings-sync-modal.ts +4 -4
- package/src/{panels → views}/modals/skills-modal.ts +9 -9
- package/src/{panels → views}/modals/subscription-modal.ts +3 -3
- package/src/{panels → views}/modals/work-plan-modal.ts +10 -13
- package/src/views/notifications-feed.ts +314 -0
- package/src/{panels → views}/polish-core.ts +38 -36
- package/src/{panels → views}/polish-tables.ts +35 -26
- package/src/{panels → views}/polish.ts +101 -95
- package/src/{panels → views}/project-planning-answer-actions.ts +3 -3
- package/src/{panels → views}/provider-health-routes.ts +14 -14
- package/src/{panels → views}/search-focus.ts +8 -8
- package/src/{panels → views}/session-maintenance.ts +11 -11
- package/src/views/skills-discovery.ts +159 -0
- package/src/views/view-deps.ts +80 -0
- package/src/views/view-panel-adapter.ts +53 -0
- package/src/{panels → views}/workstream-graph-render.ts +1 -1
- package/src/core/conversation-fold.ts +0 -101
- package/src/core/conversation-turn-structure.ts +0 -464
- package/src/core/conversation-user-receipts.ts +0 -42
- package/src/input/commands/operator-panel-runtime.ts +0 -186
- package/src/input/panel-integration-actions.ts +0 -33
- package/src/input/panel-mouse-geometry.ts +0 -97
- package/src/input/panel-paste-flood-guard.ts +0 -86
- package/src/panels/base-panel.ts +0 -301
- package/src/panels/builtin/agent.ts +0 -27
- package/src/panels/builtin/development.ts +0 -92
- package/src/panels/builtin/knowledge.ts +0 -12
- package/src/panels/builtin/operations.ts +0 -177
- package/src/panels/builtin/session.ts +0 -81
- package/src/panels/builtin/shared.ts +0 -357
- package/src/panels/builtin-panels.ts +0 -28
- package/src/panels/cost-tracker-panel.ts +0 -746
- package/src/panels/diff-panel.ts +0 -797
- package/src/panels/diff-review-panel.ts +0 -395
- package/src/panels/expandable-list-panel.ts +0 -189
- package/src/panels/fleet-deep-link.ts +0 -31
- package/src/panels/fleet-panel.ts +0 -799
- package/src/panels/git-panel.ts +0 -800
- package/src/panels/hosted-session-panel.ts +0 -221
- package/src/panels/index.ts +0 -21
- package/src/panels/local-auth-panel.ts +0 -478
- package/src/panels/notifications-feed.ts +0 -127
- package/src/panels/notifications-panel.ts +0 -160
- package/src/panels/panel-confirm-overlay.ts +0 -72
- package/src/panels/panel-manager.ts +0 -791
- package/src/panels/plugins-panel.ts +0 -371
- package/src/panels/scrollable-list-panel.ts +0 -498
- package/src/panels/skills-panel.ts +0 -454
- package/src/panels/token-budget-panel.ts +0 -688
- package/src/panels/types.ts +0 -191
- package/src/panels/wrfc-panel-format.ts +0 -133
- package/src/renderer/diff-view.ts +0 -134
- package/src/renderer/fleet-tab-strip.ts +0 -56
- package/src/renderer/footer-tips.ts +0 -53
- package/src/renderer/fullscreen-primitives.ts +0 -146
- package/src/renderer/fullscreen-workspace.ts +0 -194
- package/src/renderer/hint-grammar.ts +0 -52
- package/src/renderer/modal-factory.ts +0 -480
- package/src/renderer/overlay-box.ts +0 -154
- package/src/renderer/overlay-viewport.ts +0 -104
- package/src/renderer/panel-composite.ts +0 -145
- package/src/renderer/panel-workspace-bar.ts +0 -54
- package/src/renderer/process-indicator.ts +0 -163
- package/src/renderer/tab-strip.ts +0 -222
- package/src/renderer/text-layout.ts +0 -31
- package/src/renderer/tool-call.ts +0 -276
- package/src/renderer/tool-result-expanded-lines.ts +0 -48
- package/src/renderer/tool-result-summary.ts +0 -219
- package/src/runtime/diagnostics/panels/index.ts +0 -21
- package/src/runtime/diagnostics/panels/ops.ts +0 -156
- package/src/runtime/perf/panel-contracts.ts +0 -32
- package/src/runtime/store/domains/panels.ts +0 -117
- /package/src/{panels → views}/memory-consolidation-gateway.ts +0 -0
- /package/src/{panels → views}/modals/modal-theme.ts +0 -0
- /package/src/{panels → views}/provider-health-domains.ts +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { dirname, resolve } from 'node:path';
|
|
3
3
|
import type { CommandRegistry } from '../command-registry.ts';
|
|
4
|
-
import {
|
|
4
|
+
import { requireShellPaths } from './runtime-services.ts';
|
|
5
5
|
import { createVoiceProvisionGateway, renderVoiceProvision, runVoiceSetupWithProgress, VOICE_SETUP_ANNOUNCEMENT } from '../../core/voice-provision-gateway.ts';
|
|
6
6
|
import { resolveWakeRuntimeSettings } from '@pellux/goodvibes-sdk/platform/voice/wake/runtime';
|
|
7
7
|
import { terminalWakeCapabilities } from '../../core/wake-provision-status.ts';
|
|
@@ -158,12 +158,8 @@ export function registerExperienceRuntimeCommands(registry: CommandRegistry): vo
|
|
|
158
158
|
handler(args, ctx) {
|
|
159
159
|
const sub = (args[0] ?? 'matrix').toLowerCase();
|
|
160
160
|
if (sub === 'open' || sub === 'panel') {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
const panelManager = requirePanelManager(ctx);
|
|
164
|
-
panelManager.open('approval');
|
|
165
|
-
panelManager.show();
|
|
166
|
-
}
|
|
161
|
+
// Approvals waiting on you are rows in the Agents view (b jumps to them).
|
|
162
|
+
if (!ctx.openView?.('approval')) ctx.print('The Agents view is not available in this session.');
|
|
167
163
|
return;
|
|
168
164
|
}
|
|
169
165
|
const matrix = [
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fresh-conversation.ts, what /clear does: start a fresh conversation in this
|
|
3
|
+
* terminal session without losing the one on screen.
|
|
4
|
+
*
|
|
5
|
+
* /clear used to hide the transcript while keeping every message in the
|
|
6
|
+
* model's context, so the header kept the old title and the status line kept
|
|
7
|
+
* the old context usage, both true of a conversation the screen no longer
|
|
8
|
+
* showed. Now the conversation on screen is first saved as its own session
|
|
9
|
+
* (resumable by id, like /session fork, taking its view sidecar and rewind
|
|
10
|
+
* anchors with it), then the live conversation is reset: no messages, no
|
|
11
|
+
* title, the system prompt reloaded, no rewind anchors, and the usage counters
|
|
12
|
+
* recomputed from the (empty) transcript, so the header and status line
|
|
13
|
+
* describe the fresh conversation.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { randomBytes } from 'node:crypto';
|
|
17
|
+
import { rmSync } from 'node:fs';
|
|
18
|
+
import { join } from 'node:path';
|
|
19
|
+
import type { SessionMeta } from '@pellux/goodvibes-sdk/platform/sessions';
|
|
20
|
+
import { clearTurnAnchors, getTurnAnchors, persistTurnAnchors, recordTurnAnchor } from '@pellux/goodvibes-sdk/platform/rewind';
|
|
21
|
+
import type { CommandContext } from '../command-registry.ts';
|
|
22
|
+
import { saveWorkTreeFolds } from '../../core/work-tree-fold-store.ts';
|
|
23
|
+
|
|
24
|
+
export interface FreshConversationResult {
|
|
25
|
+
/** Session id the previous conversation was saved under, or null when there was nothing to keep. */
|
|
26
|
+
readonly savedAs: string | null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Whether a transcript holds a conversation worth keeping (anything the user or the model said). */
|
|
30
|
+
function hasConversation(ctx: CommandContext): boolean {
|
|
31
|
+
return ctx.session.conversationManager.getMessageSnapshot().some((m) => m.role === 'user' || m.role === 'assistant');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Save the conversation on screen as its own session, then reset the live one.
|
|
36
|
+
* Throws (and changes nothing) when the save fails, so a conversation is never
|
|
37
|
+
* dropped without a saved copy.
|
|
38
|
+
*/
|
|
39
|
+
export function startFreshConversation(ctx: CommandContext): FreshConversationResult {
|
|
40
|
+
const conversation = ctx.session.conversationManager;
|
|
41
|
+
const surface = ctx.workspace.surface;
|
|
42
|
+
let savedAs: string | null = null;
|
|
43
|
+
if (hasConversation(ctx) && ctx.session.sessionManager) {
|
|
44
|
+
const id = `user-${randomBytes(4).toString('hex')}`;
|
|
45
|
+
const exported = conversation.toJSON() as { messages?: unknown[] };
|
|
46
|
+
const meta: SessionMeta = {
|
|
47
|
+
title: conversation.title,
|
|
48
|
+
model: ctx.session.runtime.model,
|
|
49
|
+
provider: ctx.session.runtime.provider,
|
|
50
|
+
timestamp: Date.now(),
|
|
51
|
+
titleSource: conversation.getTitleSource(),
|
|
52
|
+
// The user asked for this conversation to be set aside; it is not turn machinery.
|
|
53
|
+
saveSource: 'user',
|
|
54
|
+
};
|
|
55
|
+
ctx.session.sessionManager.save(id, (exported.messages ?? []) as never[], meta);
|
|
56
|
+
if (surface) {
|
|
57
|
+
// The saved copy keeps its view (folds, failed/cancelled turn headers)
|
|
58
|
+
// and its rewind anchors, which describe exactly that transcript.
|
|
59
|
+
saveWorkTreeFolds(surface.sessionsDir, id, conversation.workTree.foldState(), conversation.workTree.turnOutcomes());
|
|
60
|
+
for (const anchor of getTurnAnchors(ctx.session.runtime.sessionId)) recordTurnAnchor(id, anchor);
|
|
61
|
+
persistTurnAnchors(id, surface);
|
|
62
|
+
}
|
|
63
|
+
savedAs = id;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const liveId = ctx.session.runtime.sessionId;
|
|
67
|
+
conversation.resetAll();
|
|
68
|
+
if (ctx.reloadSystemPrompt) ctx.session.runtime.systemPrompt = ctx.reloadSystemPrompt();
|
|
69
|
+
// Rewind anchors and the view sidecar point into the old transcript.
|
|
70
|
+
clearTurnAnchors(liveId);
|
|
71
|
+
if (surface) {
|
|
72
|
+
// persistTurnAnchors writes nothing for an empty list, so the old sidecar
|
|
73
|
+
// (`<sessionId>.anchors.json`, the SDK's rewind/turn-anchors.ts name) is
|
|
74
|
+
// removed here, or a later resume would bring the old anchors back.
|
|
75
|
+
try {
|
|
76
|
+
if (!/[\\/]/.test(liveId)) rmSync(join(surface.sessionsDir, `${liveId}.anchors.json`), { force: true });
|
|
77
|
+
} catch {
|
|
78
|
+
// best effort: the in-memory anchors are already gone
|
|
79
|
+
}
|
|
80
|
+
saveWorkTreeFolds(surface.sessionsDir, liveId, [], []);
|
|
81
|
+
}
|
|
82
|
+
// Token counters and context usage come from the transcript: now empty.
|
|
83
|
+
ctx.session.hydrateSessionUsage?.();
|
|
84
|
+
conversation.rebuildHistory();
|
|
85
|
+
return { savedAs };
|
|
86
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CommandRegistry } from '../command-registry.ts';
|
|
2
2
|
import { GitService } from '@pellux/goodvibes-sdk/platform/git';
|
|
3
|
-
import { requireShellPaths
|
|
3
|
+
import { requireShellPaths } from './runtime-services.ts';
|
|
4
4
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
5
5
|
|
|
6
6
|
export function registerGitRuntimeCommands(registry: CommandRegistry): void {
|
|
@@ -64,34 +64,17 @@ export function registerGitRuntimeCommands(registry: CommandRegistry): void {
|
|
|
64
64
|
break;
|
|
65
65
|
}
|
|
66
66
|
case 'diff': {
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
// panel. The old path sliced the raw text at 4,000 chars and printed a
|
|
70
|
-
// stub; a large diff now renders complete.
|
|
67
|
+
// The full, uncapped working-tree diff, in the Changes modal's
|
|
68
|
+
// "not staged" view (hunks can be staged from there).
|
|
71
69
|
try {
|
|
72
70
|
const structured = await git.diffStructured();
|
|
73
71
|
if (structured.files.length === 0) {
|
|
74
72
|
ctx.print('No unstaged changes.');
|
|
75
73
|
break;
|
|
76
74
|
}
|
|
77
|
-
const { DiffPanel } = await import('../../panels/diff-panel.ts');
|
|
78
|
-
const pm = requirePanelManager(ctx);
|
|
79
|
-
let panel = pm.getAllOpen().find((p) => p.id === 'diff');
|
|
80
|
-
if (!panel) {
|
|
81
|
-
try {
|
|
82
|
-
panel = pm.open('diff');
|
|
83
|
-
} catch {
|
|
84
|
-
ctx.print('Could not open diff panel.');
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
pm.activateById('diff');
|
|
89
|
-
if (!pm.isVisible()) pm.show();
|
|
90
|
-
ctx.focusPanels?.();
|
|
91
|
-
(panel as InstanceType<typeof DiffPanel>).loadStructuredDiff(structured);
|
|
92
75
|
const fileWord = structured.files.length === 1 ? 'file' : 'files';
|
|
93
|
-
ctx.print(`
|
|
94
|
-
ctx.
|
|
76
|
+
ctx.print(`Unstaged: ${structured.files.length} ${fileWord}, +${structured.additions} -${structured.deletions}.`);
|
|
77
|
+
if (ctx.openChanges) ctx.openChanges({ source: 'working' });
|
|
95
78
|
} catch (e) {
|
|
96
79
|
ctx.print(`Git diff failed: ${summarizeError(e)}`);
|
|
97
80
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CommandRegistry } from '../command-registry.ts';
|
|
2
2
|
import { getOperatorRpc, describeOperatorRpcError } from './operator-rpc.ts';
|
|
3
|
-
import { renderWorkstreamGraphLines } from '../../
|
|
3
|
+
import { renderWorkstreamGraphLines } from '../../views/workstream-graph-render.ts';
|
|
4
4
|
|
|
5
5
|
// ---------------------------------------------------------------------------
|
|
6
6
|
// /graph, a workstream's task graph (fleet.graph.get) rendered legibly.
|
|
@@ -78,7 +78,7 @@ export function registerGuidanceRuntimeCommands(registry: CommandRegistry): void
|
|
|
78
78
|
const maintenance = evaluateSessionMaintenance({
|
|
79
79
|
configManager: ctx.platform.configManager,
|
|
80
80
|
currentTokens: estimateConversationTokens(llmMessages),
|
|
81
|
-
contextWindow: ctx.provider.providerRegistry.
|
|
81
|
+
contextWindow: ctx.provider.providerRegistry.getKnownContextWindowForModel(ctx.provider.providerRegistry.getCurrentModel()) ?? 0,
|
|
82
82
|
messageCount: llmMessages.length,
|
|
83
83
|
sessionMemoryCount: requireSessionMemoryStore(ctx).list().length,
|
|
84
84
|
session: session.session,
|
|
@@ -8,7 +8,6 @@ import { buildProviderAccountSnapshot } from '@/runtime/index.ts';
|
|
|
8
8
|
import { getSettingsControlPlaneSnapshot } from '@/runtime/index.ts';
|
|
9
9
|
import { listPersistedWorktreeMeta, summarizeWorktreeOwnership } from '@/runtime/index.ts';
|
|
10
10
|
import {
|
|
11
|
-
openCommandPanel,
|
|
12
11
|
requireLocalUserAuthManager,
|
|
13
12
|
requireOperatorClient,
|
|
14
13
|
requireReadModels,
|
|
@@ -48,7 +47,7 @@ export function registerHealthRuntimeCommands(registry: CommandRegistry): void {
|
|
|
48
47
|
const readModels = requireReadModels(ctx);
|
|
49
48
|
|
|
50
49
|
if (sub === 'open' || sub === 'panel' || sub === 'provider') {
|
|
51
|
-
ctx.openModal?.('providers-modal'); // provider-health
|
|
50
|
+
ctx.openModal?.('providers-modal'); // provider-health view -> config modal
|
|
52
51
|
return;
|
|
53
52
|
}
|
|
54
53
|
|
|
@@ -305,11 +304,11 @@ export function registerHealthRuntimeCommands(registry: CommandRegistry): void {
|
|
|
305
304
|
if (sub === 'maintenance') {
|
|
306
305
|
const session = readModels.session.getSnapshot();
|
|
307
306
|
const providerRegistry = ctx.provider.providerRegistry;
|
|
308
|
-
// Resolve the context window the same way the
|
|
307
|
+
// Resolve the context window the same way the Usage modal does so the
|
|
309
308
|
// maintenance usage %/remaining agree across every diagnostics surface.
|
|
310
|
-
const contextWindow = providerRegistry.
|
|
309
|
+
const contextWindow = providerRegistry.getKnownContextWindowForModel(
|
|
311
310
|
providerRegistry.getCurrentModel(),
|
|
312
|
-
);
|
|
311
|
+
) ?? 0; // 0: unknown window, no usage percentage
|
|
313
312
|
const llmMessages = typeof ctx.session.conversationManager.getMessagesForLLM === 'function'
|
|
314
313
|
? ctx.session.conversationManager.getMessagesForLLM()
|
|
315
314
|
: [];
|
|
@@ -431,7 +430,7 @@ export function registerHealthRuntimeCommands(registry: CommandRegistry): void {
|
|
|
431
430
|
lines.push(' /health maintenance');
|
|
432
431
|
lines.push(' /guidance review');
|
|
433
432
|
lines.push(' /compact');
|
|
434
|
-
lines.push(' /
|
|
433
|
+
lines.push(' /usage');
|
|
435
434
|
lines.push(' verify: /health maintenance');
|
|
436
435
|
} else if (domain === 'worktrees') {
|
|
437
436
|
lines.push(' domain: worktrees');
|
|
@@ -458,11 +457,11 @@ export function registerHealthRuntimeCommands(registry: CommandRegistry): void {
|
|
|
458
457
|
const llmMessages = typeof ctx.session.conversationManager.getMessagesForLLM === 'function'
|
|
459
458
|
? ctx.session.conversationManager.getMessagesForLLM()
|
|
460
459
|
: [];
|
|
461
|
-
// Resolve the context window the same way the
|
|
460
|
+
// Resolve the context window the same way the Usage modal does so the
|
|
462
461
|
// maintenance usage %/remaining agree across every diagnostics surface.
|
|
463
|
-
const contextWindow = providerRegistry.
|
|
462
|
+
const contextWindow = providerRegistry.getKnownContextWindowForModel(
|
|
464
463
|
providerRegistry.getCurrentModel(),
|
|
465
|
-
);
|
|
464
|
+
) ?? 0; // 0: unknown window, no usage percentage
|
|
466
465
|
const maintenance = evaluateSessionMaintenance({
|
|
467
466
|
configManager: ctx.platform.configManager,
|
|
468
467
|
currentTokens: estimateConversationTokens(llmMessages),
|
|
@@ -11,8 +11,8 @@ export function registerHooksRuntimeCommands(registry: CommandRegistry): void {
|
|
|
11
11
|
async handler(args, ctx) {
|
|
12
12
|
const hookApi = requireHookApi(ctx);
|
|
13
13
|
const workbench = hookApi.workbench;
|
|
14
|
-
if (args.length === 0 && ctx.
|
|
15
|
-
ctx.
|
|
14
|
+
if (args.length === 0 && ctx.openHooksView) {
|
|
15
|
+
ctx.openHooksView();
|
|
16
16
|
return;
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
} from '../../runtime/client/hosted-sessions.ts';
|
|
45
45
|
import { watchHostedSession, type HostedSessionSubscription } from '../../runtime/client/hosted-session-stream.ts';
|
|
46
46
|
import { getOrCreateCompanionToken } from '@pellux/goodvibes-sdk/platform/pairing';
|
|
47
|
-
import { getSharedHostedSessionFeed, type HostedSessionFeed } from '../../
|
|
47
|
+
import { getSharedHostedSessionFeed, type HostedSessionFeed } from '../../views/hosted-session-feed.ts';
|
|
48
48
|
import { getSharedHostedSessionRoster } from '../../runtime/client/hosted-roster.ts';
|
|
49
49
|
|
|
50
50
|
/** The last list this terminal printed, so `attach 2` means what the user just read. */
|
|
@@ -194,7 +194,7 @@ async function attachSession(
|
|
|
194
194
|
`[hosted] attached to ${hostedSessionLabel(attachment.session)} (${attachment.history.length} message(s) backfilled)`,
|
|
195
195
|
` ${describeDetachEffect(attachment.session)}`,
|
|
196
196
|
].join('\n'));
|
|
197
|
-
context.
|
|
197
|
+
context.openAgents?.({ hosted: true });
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
/** Turn `attach 2` into the id the user just read off `/hosted list`. */
|
|
@@ -278,7 +278,7 @@ export function registerHostedRuntimeCommands(registry: CommandRegistry): void {
|
|
|
278
278
|
if (sub === 'say') await seams.client.steer(attachedId, body);
|
|
279
279
|
else await seams.client.followUp(attachedId, body);
|
|
280
280
|
ctx.print(sub === 'say'
|
|
281
|
-
? '[hosted] sent: its output arrives
|
|
281
|
+
? '[hosted] sent: its output arrives in the Agents view under Hosted (/agents).'
|
|
282
282
|
: '[hosted] queued: it runs after the current turn.');
|
|
283
283
|
return;
|
|
284
284
|
}
|
|
@@ -16,11 +16,11 @@ export function registerIncidentRuntimeCommands(registry: CommandRegistry): void
|
|
|
16
16
|
const subcommand = (args[0] ?? 'open').toLowerCase();
|
|
17
17
|
const forensicRegistry = ctx.extensions.forensicsRegistry;
|
|
18
18
|
if (subcommand === 'open') {
|
|
19
|
-
if (ctx.
|
|
20
|
-
ctx.
|
|
19
|
+
if (ctx.openIncidentView) {
|
|
20
|
+
ctx.openIncidentView();
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
|
-
ctx.print('
|
|
23
|
+
ctx.print('The Agents view is not available in this runtime.');
|
|
24
24
|
return;
|
|
25
25
|
}
|
|
26
26
|
if (!forensicRegistry) {
|
|
@@ -4,7 +4,7 @@ import type { CommandContext, CommandRegistry } from '../command-registry.ts';
|
|
|
4
4
|
import { CodeIntelligence } from '@pellux/goodvibes-sdk/platform/intelligence';
|
|
5
5
|
import type { DocumentSymbol } from '@pellux/goodvibes-sdk/platform/intelligence';
|
|
6
6
|
import type { SymbolInfo } from '@pellux/goodvibes-sdk/platform/intelligence';
|
|
7
|
-
import {
|
|
7
|
+
import { openCommandView, requireReadModels, requireShellPaths } from './runtime-services.ts';
|
|
8
8
|
|
|
9
9
|
function resolveTargetPath(pathArg: string, ctx: CommandContext): string {
|
|
10
10
|
return requireShellPaths(ctx).resolveWorkspacePath(pathArg);
|
|
@@ -55,16 +55,13 @@ export function registerIntelligenceRuntimeCommands(registry: CommandRegistry):
|
|
|
55
55
|
async handler(args, ctx) {
|
|
56
56
|
const sub = (args[0] ?? 'review').toLowerCase();
|
|
57
57
|
if (sub === 'panel' || sub === 'open') {
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
// to resolve through, so this prints an honest notice and opens
|
|
62
|
-
// Fleet instead of throwing "Unknown panel".
|
|
63
|
-
ctx.print('Intelligence panel retired: use /intelligence review|diagnostics|symbols|outline|definition|references|hover|repair for the live data. Opening Fleet.');
|
|
58
|
+
// There is no intelligence view; its read model backs every
|
|
59
|
+
// subcommand below. Say so and open Agents rather than failing.
|
|
60
|
+
ctx.print('There is no intelligence view: use /intelligence review|diagnostics|symbols|outline|definition|references|hover|repair for the live data. Opening Agents.');
|
|
64
61
|
try {
|
|
65
|
-
|
|
62
|
+
openCommandView(ctx, 'agents');
|
|
66
63
|
} catch {
|
|
67
|
-
//
|
|
64
|
+
// The view openers may be absent in lightweight command-only contexts.
|
|
68
65
|
}
|
|
69
66
|
return;
|
|
70
67
|
}
|
|
@@ -141,8 +141,8 @@ export const knowledgeCommand: SlashCommand = {
|
|
|
141
141
|
if (!knowledge) {
|
|
142
142
|
return;
|
|
143
143
|
}
|
|
144
|
-
if (args.length === 0 && context.
|
|
145
|
-
context.
|
|
144
|
+
if (args.length === 0 && context.openKnowledgeView) {
|
|
145
|
+
context.openKnowledgeView();
|
|
146
146
|
return;
|
|
147
147
|
}
|
|
148
148
|
const sub = (args[0] ?? 'status').toLowerCase();
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { CommandRegistry } from '../command-registry.ts';
|
|
2
|
+
import { AGENT_VIEW_NAMES, CHANGES_VIEW_NAMES, USAGE_VIEW_NAMES, takeTargetFlag } from '../views.ts';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* `/panel` is the legacy alias for the old pane names. Every view lives in a
|
|
6
|
+
* modal, and the old names still arrive from muscle memory, notes, scripts and
|
|
7
|
+
* deep links (`/panel open fleet --target <id>`). `/panel <name>` and
|
|
8
|
+
* `/panel open <name>` open the modal that holds that content now;
|
|
9
|
+
* `/panel list` says where each old name goes. The verbs that only made sense
|
|
10
|
+
* for side panes (close, move, focus, split, width, height) have nothing to
|
|
11
|
+
* act on and say so.
|
|
12
|
+
*/
|
|
13
|
+
export function registerLegacyPanelCommand(registry: CommandRegistry): void {
|
|
14
|
+
registry.register({
|
|
15
|
+
name: 'panel',
|
|
16
|
+
aliases: ['panels'],
|
|
17
|
+
description: 'Open a view by its old pane name (fleet, tokens, git, …) in its modal; /panel list shows where each goes',
|
|
18
|
+
usage: '[<name> | open <name> [--target <id>[:<kind>]] | list]',
|
|
19
|
+
argsHint: '<name> | open <name> | list',
|
|
20
|
+
handler(args, ctx) {
|
|
21
|
+
const rest = [...args];
|
|
22
|
+
const target = takeTargetFlag(rest);
|
|
23
|
+
const sub = rest[0]?.toLowerCase() ?? '';
|
|
24
|
+
if (!sub || sub === 'toggle') {
|
|
25
|
+
ctx.print('There are no panes any more: views open as modals. Try /agents, /usage, /changes or /notifications, or ctrl+p to search.');
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (sub === 'list') {
|
|
29
|
+
ctx.print([
|
|
30
|
+
'Where the old panes went:',
|
|
31
|
+
` Agents (/agents, F2): ${AGENT_VIEW_NAMES.filter((n) => n !== 'agents').join(', ')}, hosted`,
|
|
32
|
+
` Usage (/usage): ${USAGE_VIEW_NAMES.filter((n) => n !== 'usage').join(', ')}`,
|
|
33
|
+
` Changes (/changes): ${CHANGES_VIEW_NAMES.filter((n) => n !== 'changes').join(', ')}`,
|
|
34
|
+
' Notifications (/notifications): notifications',
|
|
35
|
+
' Sessions (/sessions): sessions',
|
|
36
|
+
' Local Auth (/local-auth): local-auth',
|
|
37
|
+
'Settings-style views (services, providers, plugins, hooks, memory, …) open their own modals by the same names.',
|
|
38
|
+
].join('\n'));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (sub === 'close' || sub === 'move' || sub === 'focus' || sub === 'split' || sub === 'width' || sub === 'height') {
|
|
42
|
+
ctx.print(`There are no panes to ${sub}: views open as modals and Esc closes them.`);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const name = sub === 'open' ? rest[1] : rest[0];
|
|
46
|
+
if (!name) {
|
|
47
|
+
ctx.print('Usage: /panel open <name> [--target <id>[:<kind>]]');
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (!ctx.openView) {
|
|
51
|
+
ctx.print('Views are not available in this session.');
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (!ctx.openView(name, target)) ctx.print(`Nothing holds "${name}". /panel list shows where the old names go.`);
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CommandContext, CommandRegistry } from '../command-registry.ts';
|
|
2
|
-
import {
|
|
2
|
+
import { requireLocalUserAuthManager } from './runtime-services.ts';
|
|
3
3
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
4
4
|
|
|
5
5
|
function formatRoles(roles: readonly string[]): string {
|
|
@@ -7,12 +7,11 @@ function formatRoles(roles: readonly string[]): string {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export function handleLocalAuthCommand(args: string[], ctx: CommandContext): void {
|
|
10
|
-
|
|
10
|
+
// Bare /local-auth opens the Local Auth modal where one can open; the text
|
|
11
|
+
// review stays at /local-auth review.
|
|
12
|
+
const sub = (args[0] ?? (ctx.openModal ? 'open' : 'review')).toLowerCase();
|
|
11
13
|
const auth = requireLocalUserAuthManager(ctx);
|
|
12
14
|
if (sub === 'panel' || sub === 'open') {
|
|
13
|
-
// browse view moved to local-auth-modal. The LocalAuthPanel itself is
|
|
14
|
-
// kept (masked password-entry host) but is no longer the /local-auth panel
|
|
15
|
-
// destination, masked entry is reached via add-user/rotate-password below.
|
|
16
15
|
ctx.openModal?.('local-auth-modal');
|
|
17
16
|
return;
|
|
18
17
|
}
|
|
@@ -21,11 +20,11 @@ export function handleLocalAuthCommand(args: string[], ctx: CommandContext): voi
|
|
|
21
20
|
const username = args[1];
|
|
22
21
|
const password = args[2];
|
|
23
22
|
if (!username) {
|
|
24
|
-
ctx.print('Usage: /auth local add-user <username> <password> [roles]\nTip: invoke without a password to
|
|
23
|
+
ctx.print('Usage: /auth local add-user <username> <password> [roles]\nTip: invoke without a password to type it in the masked prompt: /auth local add-user <username>');
|
|
25
24
|
return;
|
|
26
25
|
}
|
|
27
26
|
if (!password) {
|
|
28
|
-
// No password supplied
|
|
27
|
+
// No password supplied: open the masked password prompt.
|
|
29
28
|
if (ctx.openLocalAuthMaskedEntry) {
|
|
30
29
|
ctx.openLocalAuthMaskedEntry('add-user', username);
|
|
31
30
|
} else {
|
|
@@ -64,11 +63,11 @@ export function handleLocalAuthCommand(args: string[], ctx: CommandContext): voi
|
|
|
64
63
|
const username = args[1];
|
|
65
64
|
const password = args[2];
|
|
66
65
|
if (!username) {
|
|
67
|
-
ctx.print('Usage: /auth local rotate-password <username> <password>\nTip: invoke without a password to
|
|
66
|
+
ctx.print('Usage: /auth local rotate-password <username> <password>\nTip: invoke without a password to type it in the masked prompt: /auth local rotate-password <username>');
|
|
68
67
|
return;
|
|
69
68
|
}
|
|
70
69
|
if (!password) {
|
|
71
|
-
// No password supplied
|
|
70
|
+
// No password supplied: open the masked password prompt.
|
|
72
71
|
if (ctx.openLocalAuthMaskedEntry) {
|
|
73
72
|
ctx.openLocalAuthMaskedEntry('rotate-password', username);
|
|
74
73
|
} else {
|
|
@@ -79,21 +79,24 @@ export function registerLocalProviderRuntimeCommands(registry: CommandRegistry):
|
|
|
79
79
|
contextWindows = await fetchModelContextWindows(parsedUrl.hostname, parseInt(parsedUrl.port) || 80, 'unknown', discoveredModelIds);
|
|
80
80
|
} catch {}
|
|
81
81
|
} else {
|
|
82
|
-
ctx.print('Note: Context window detection is only supported for http:// URLs.
|
|
82
|
+
ctx.print('Note: Context window detection is only supported for http:// URLs. Windows the endpoint does not report are left unknown.');
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
const defaultModel = `${name}-model`;
|
|
86
|
+
// A window is written only when the endpoint reported one. A guessed
|
|
87
|
+
// number written here would read as the model's real window forever
|
|
88
|
+
// after (the meter, compaction and prompt tier all trust it), so an
|
|
89
|
+
// unreported window is left out and the model's window is unknown.
|
|
86
90
|
const models: CustomProviderConfig['models'] = discoveredModelIds.length === 0
|
|
87
91
|
? [{
|
|
88
92
|
id: defaultModel,
|
|
89
93
|
displayName: defaultModel,
|
|
90
|
-
contextWindow: 8192,
|
|
91
94
|
capabilities: { toolCalling: true, codeEditing: true, reasoning: false, multimodal: false },
|
|
92
95
|
}]
|
|
93
96
|
: discoveredModelIds.map((id) => ({
|
|
94
97
|
id,
|
|
95
98
|
displayName: id,
|
|
96
|
-
contextWindow: contextWindows[id]
|
|
99
|
+
...(contextWindows[id] !== undefined && contextWindows[id] > 0 ? { contextWindow: contextWindows[id] } : {}),
|
|
97
100
|
capabilities: { toolCalling: true, codeEditing: true, reasoning: false, multimodal: false },
|
|
98
101
|
}));
|
|
99
102
|
// The key is never embedded in the provider JSON. The config references
|
|
@@ -115,7 +118,7 @@ export function registerLocalProviderRuntimeCommands(registry: CommandRegistry):
|
|
|
115
118
|
ctx.print(`Error writing provider file: ${summarizeError(e)}`);
|
|
116
119
|
return;
|
|
117
120
|
}
|
|
118
|
-
ctx.print(`Provider '${name}' added with ${models.length} model(s):\n${discoveredModelIds.length > 0 ? discoveredModelIds.map((id) => ` • ${id} (${
|
|
121
|
+
ctx.print(`Provider '${name}' added with ${models.length} model(s):\n${discoveredModelIds.length > 0 ? discoveredModelIds.map((id) => ` • ${id} (${contextWindows[id] !== undefined && contextWindows[id] > 0 ? `${contextWindows[id].toLocaleString()} ctx` : 'context window unknown'})`).join('\n') : ` • ${defaultModel} (starter entry)`}\nThe file watcher will auto-register it shortly.`);
|
|
119
122
|
// Capture the key with the keystrokes masked, straight into the secrets
|
|
120
123
|
// manager, never a cleartext argument, never written into the JSON.
|
|
121
124
|
if (ctx.beginConcealedInput) {
|
|
@@ -7,7 +7,7 @@ import type { ContentPart } from '@pellux/goodvibes-sdk/platform/providers';
|
|
|
7
7
|
import { formatModelDiscoveryReport } from '@pellux/goodvibes-sdk/platform/providers';
|
|
8
8
|
import { resolveAndValidatePath } from '@pellux/goodvibes-sdk/platform/utils';
|
|
9
9
|
import { BUILTIN_SECRET_PROVIDER_SOURCES, describeSecretRef, isSecretRefInput, resolveSecretRef } from '@pellux/goodvibes-sdk/platform/config';
|
|
10
|
-
import {
|
|
10
|
+
import { openCommandView, requireBookmarkManager, requireProviderApi, requireSecretsManager } from './runtime-services.ts';
|
|
11
11
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
12
12
|
|
|
13
13
|
function isGoodVibesSecretRefInput(value: string): boolean {
|
|
@@ -55,8 +55,8 @@ function toggleBlocks(typeFilter: string, collapsed: boolean, ctx: CommandContex
|
|
|
55
55
|
// state, needing a second pass. '/collapse tool' needs no matching step:
|
|
56
56
|
// collapsing the turn hides every result regardless of its own key.
|
|
57
57
|
if (!collapsed && block.type === 'assistant_turn' && block.groupMemberIndexes) {
|
|
58
|
-
for (const memberIdx of block.groupMemberIndexes) {
|
|
59
|
-
const memberKey = `msg_${memberIdx}`;
|
|
58
|
+
for (const [k, memberIdx] of block.groupMemberIndexes.entries()) {
|
|
59
|
+
const memberKey = block.groupMemberKeys?.[k] ?? `msg_${memberIdx}`;
|
|
60
60
|
ctx.session.conversationManager.setCollapsed(memberKey, false);
|
|
61
61
|
// An explicit /expand is a deliberate user action on this key, same
|
|
62
62
|
// as Tab/Ctrl+Y/Ctrl+B, exempts it from search's close-time
|
|
@@ -77,11 +77,11 @@ export function registerLocalRuntimeCommands(registry: CommandRegistry): void {
|
|
|
77
77
|
aliases: [],
|
|
78
78
|
description: 'Alias for /incident open',
|
|
79
79
|
handler(_args, ctx) {
|
|
80
|
-
if (ctx.
|
|
81
|
-
ctx.
|
|
80
|
+
if (ctx.openIncidentView) {
|
|
81
|
+
ctx.openIncidentView();
|
|
82
82
|
return;
|
|
83
83
|
}
|
|
84
|
-
ctx.print('
|
|
84
|
+
ctx.print('The Agents view is not available in this runtime.');
|
|
85
85
|
},
|
|
86
86
|
});
|
|
87
87
|
|
|
@@ -93,16 +93,13 @@ export function registerLocalRuntimeCommands(registry: CommandRegistry): void {
|
|
|
93
93
|
handler(args, ctx) {
|
|
94
94
|
const sub = (args[0] ?? '').toLowerCase();
|
|
95
95
|
if (sub === 'panel' || sub === 'review') {
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
|
|
99
|
-
// to resolve through, so this prints an honest notice and opens
|
|
100
|
-
// Fleet instead of the retired inspector.
|
|
101
|
-
ctx.print('Tools panel retired: tool activity now renders inline in the transcript and per-agent in the Fleet panel. Opening Fleet.');
|
|
96
|
+
// Tool results render inline in the transcript and per agent in the
|
|
97
|
+
// Agents modal; there is no separate tools view.
|
|
98
|
+
ctx.print('Tool activity renders inline in the transcript and per agent in the Agents view. Opening Agents.');
|
|
102
99
|
try {
|
|
103
|
-
|
|
100
|
+
openCommandView(ctx, 'agents');
|
|
104
101
|
} catch {
|
|
105
|
-
//
|
|
102
|
+
// The view openers may be absent in lightweight command-only contexts.
|
|
106
103
|
}
|
|
107
104
|
if (sub === 'review') {
|
|
108
105
|
ctx.print([
|
|
@@ -110,7 +107,7 @@ export function registerLocalRuntimeCommands(registry: CommandRegistry): void {
|
|
|
110
107
|
' Native file tools stay compact by default.',
|
|
111
108
|
' Read/write/edit/notebook capabilities are available through the native tool stack, with detail routed inline and to approval surfaces instead of transcript bloat.',
|
|
112
109
|
' Shell and native tool approvals classify work into read, mutation, destructive, dependency, config, notebook, network, remote, and lifecycle risk families.',
|
|
113
|
-
' Use /tools panel to
|
|
110
|
+
' Use /tools panel to open Agents for live per-agent tool activity.',
|
|
114
111
|
' Use /approval review shell or /approval review file when you need the action-specific why-prompted posture.',
|
|
115
112
|
].join('\n'));
|
|
116
113
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { dirname, join, resolve } from 'node:path';
|
|
2
2
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import type { CommandContext } from '../command-registry.ts';
|
|
4
|
-
import { discoverSkills } from '../../
|
|
4
|
+
import { discoverSkills } from '../../views/skills-discovery.ts';
|
|
5
5
|
import { buildSandboxReview, isRunningInWsl } from '@/runtime/index.ts';
|
|
6
6
|
import { renderQemuWrapperTemplate } from '@/runtime/index.ts';
|
|
7
7
|
import { getPluginDirectories } from '@pellux/goodvibes-sdk/platform/plugins';
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
parseSetupLink,
|
|
16
16
|
} from './local-setup-transfer.ts';
|
|
17
17
|
import { buildSetupReviewSnapshot, exportSetupSupportBundle, renderSetupSandboxReview } from './local-setup-review.ts';
|
|
18
|
-
import { openOnboardingWizard,
|
|
18
|
+
import { openOnboardingWizard, requireShellPaths } from './runtime-services.ts';
|
|
19
19
|
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
20
20
|
|
|
21
21
|
type SetupSnapshot = Awaited<ReturnType<typeof buildSetupReviewSnapshot>>;
|
|
@@ -247,32 +247,26 @@ export function registerLocalSetupCommands(registry: CommandRegistry): void {
|
|
|
247
247
|
ctx.print(`Invalid setup link: ${link}`);
|
|
248
248
|
return;
|
|
249
249
|
}
|
|
250
|
-
const
|
|
251
|
-
cockpit: ctx.
|
|
252
|
-
security: ctx.
|
|
253
|
-
remote: ctx.
|
|
254
|
-
knowledge: ctx.
|
|
255
|
-
incident: ctx.
|
|
256
|
-
hooks: ctx.
|
|
257
|
-
orchestration: ctx.
|
|
250
|
+
const viewOpeners: Record<string, (() => void) | undefined> = {
|
|
251
|
+
cockpit: ctx.openCockpitView,
|
|
252
|
+
security: ctx.openSecurityView,
|
|
253
|
+
remote: ctx.openRemoteView,
|
|
254
|
+
knowledge: ctx.openKnowledgeView,
|
|
255
|
+
incident: ctx.openIncidentView,
|
|
256
|
+
hooks: ctx.openHooksView,
|
|
257
|
+
orchestration: ctx.openOrchestrationView,
|
|
258
258
|
};
|
|
259
259
|
if (parsed.surface === 'tasks') {
|
|
260
|
-
|
|
261
|
-
else {
|
|
262
|
-
const panelManager = requirePanelManager(ctx);
|
|
263
|
-
panelManager.open('tasks');
|
|
264
|
-
panelManager.show();
|
|
265
|
-
ctx.renderRequest();
|
|
266
|
-
}
|
|
260
|
+
ctx.openView?.('tasks');
|
|
267
261
|
ctx.print(`Opened setup link for tasks${parsed.target ? ` (${parsed.target})` : ''}.`);
|
|
268
262
|
return;
|
|
269
263
|
}
|
|
270
|
-
const
|
|
271
|
-
if (!
|
|
264
|
+
const openSurface = viewOpeners[parsed.surface];
|
|
265
|
+
if (!openSurface) {
|
|
272
266
|
ctx.print(`Unsupported setup link surface: ${parsed.surface}`);
|
|
273
267
|
return;
|
|
274
268
|
}
|
|
275
|
-
|
|
269
|
+
openSurface();
|
|
276
270
|
ctx.print(`Opened setup link for ${parsed.surface}${parsed.target ? ` (${parsed.target})` : ''}.`);
|
|
277
271
|
return;
|
|
278
272
|
}
|
|
@@ -38,7 +38,7 @@ import { handleRecallFilesApply, handleRecallFilesReview, handleRecallFilesSync
|
|
|
38
38
|
* now registered here as a real alias of `/recall`, the word means the same
|
|
39
39
|
* durable Project Memory Substrate on both surfaces. The modal that exists
|
|
40
40
|
* for this data, the Project Memory Substrate, is still `memory-modal.ts`,
|
|
41
|
-
* owned by THIS command, confirmed by the
|
|
41
|
+
* owned by THIS command, confirmed by the view-id redirect
|
|
42
42
|
* `registerModalRedirect('memory', 'memory-modal')` in builtin-modals.ts.
|
|
43
43
|
*/
|
|
44
44
|
function printRecallUsage(context: CommandContext): void {
|