@pellux/goodvibes-tui 1.27.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +125 -2
- package/README.md +7 -9
- package/bin/goodvibes +2 -2
- package/bin/launcher-support.js +8 -4
- package/docs/README.md +11 -2
- package/docs/foundation-artifacts/operator-contract.json +6403 -2347
- package/package.json +14 -25
- package/scripts/postinstall.js +35 -35
- package/src/audio/spoken-turn-model-routing.ts +1 -1
- package/src/cli/bundle-command.ts +5 -5
- package/src/cli/completions/generate.ts +1 -1
- package/src/cli/doctor.ts +3 -3
- package/src/cli/entrypoint.ts +12 -7
- package/src/cli/help.ts +4 -5
- package/src/cli/hooks-command.ts +1 -1
- package/src/cli/index.ts +1 -4
- package/src/cli/launch-auto-update.ts +59 -7
- package/src/cli/management-commands.ts +6 -6
- package/src/cli/management-utils.ts +5 -5
- package/src/cli/management.ts +7 -7
- package/src/cli/network-posture.ts +1 -1
- package/src/cli/package-verification.ts +7 -6
- package/src/cli/plugin-bundles-command.ts +1 -1
- package/src/cli/plugin-command.ts +2 -2
- package/src/cli/service-command.ts +2 -2
- package/src/cli/service-posture.ts +4 -4
- package/src/cli/status.ts +9 -8
- package/src/cli/surface-command.ts +4 -4
- package/src/cli/tui-startup.ts +12 -3
- package/src/cli-flags.ts +3 -3
- package/src/config/goodvibes-home-audit.ts +0 -2
- package/src/config/secret-config.ts +37 -5
- package/src/config/tui-extension-settings.ts +1 -1
- package/src/core/approval-alert.ts +2 -2
- package/src/core/budget-breach-notifier.ts +3 -3
- package/src/core/conversation-compaction-render.ts +1 -1
- package/src/core/conversation-line-cache.ts +1 -1
- package/src/core/conversation-render-context.ts +1 -1
- package/src/core/conversation-rendering.ts +2 -2
- package/src/core/conversation.ts +10 -10
- package/src/core/long-task-notifier.ts +2 -2
- package/src/core/memory-diagnostics-gateway.ts +1 -1
- package/src/core/scriptable-statusline.ts +1 -1
- package/src/core/session-auto-titler.ts +1 -1
- package/src/core/session-resume-core.ts +2 -2
- package/src/core/stream-event-wiring.ts +24 -44
- package/src/core/terminal-notifier.ts +3 -3
- package/src/core/turn-cancellation.ts +1 -1
- package/src/core/turn-event-wiring.ts +5 -5
- package/src/input/command-registry.ts +6 -6
- package/src/input/commands/channel-pairing.ts +1 -1
- package/src/input/commands/cluster-runtime.ts +1 -1
- package/src/input/commands/codebase-runtime.ts +1 -1
- package/src/input/commands/devices-runtime.ts +1 -1
- package/src/input/commands/hosted-runtime.ts +330 -0
- package/src/input/commands/local-setup-review.ts +1 -1
- package/src/input/commands/local-setup-transfer.ts +2 -2
- package/src/input/commands/local-setup.ts +3 -3
- package/src/input/commands/managed-runtime.ts +2 -2
- package/src/input/commands/operator-rpc.ts +24 -110
- package/src/input/commands/payment-card-intake.ts +1 -1
- package/src/input/commands/permissions-provenance.ts +2 -2
- package/src/input/commands/plugin-runtime.ts +1 -1
- package/src/input/commands/provider.ts +1 -1
- package/src/input/commands/relay-runtime.ts +18 -9
- package/src/input/commands/rewind-runtime.ts +1 -1
- package/src/input/commands/runtime-services.ts +1 -1
- package/src/input/commands/services-runtime.ts +1 -1
- package/src/input/commands/session-workflow.ts +1 -1
- package/src/input/commands/settings-sync-runtime.ts +2 -2
- package/src/input/commands/share-runtime.ts +1 -1
- package/src/input/commands/tasks-runtime.ts +145 -55
- package/src/input/commands/update-runtime.ts +31 -28
- package/src/input/commands/work-plan-runtime.ts +2 -2
- package/src/input/commands/workstream-attempts.ts +1 -1
- package/src/input/commands/workstream-runtime.ts +2 -2
- package/src/input/commands.ts +2 -0
- package/src/input/feature-unit-layout.ts +1 -1
- package/src/input/feed-context-factory.ts +3 -3
- package/src/input/handler-content-actions.ts +2 -2
- package/src/input/handler-feed-routes.ts +1 -1
- package/src/input/handler-feed.ts +3 -3
- package/src/input/handler-modal-token-routes.ts +1 -1
- package/src/input/handler-onboarding-daemon-adopt.ts +3 -2
- package/src/input/handler-onboarding.ts +1 -1
- package/src/input/handler-types.ts +2 -2
- package/src/input/handler-ui-state.ts +1 -1
- package/src/input/handler.ts +4 -4
- package/src/input/input-history.ts +1 -1
- package/src/input/onboarding/onboarding-feature-units.ts +2 -2
- package/src/input/onboarding/onboarding-runtime-status.ts +15 -1
- package/src/input/onboarding/onboarding-wizard-apply.ts +17 -8
- package/src/input/onboarding/onboarding-wizard-cloudflare-step.ts +5 -3
- package/src/input/onboarding/onboarding-wizard-external-surfaces.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-types.ts +1 -1
- package/src/input/payments-config.ts +6 -6
- package/src/input/search.ts +1 -1
- package/src/input/session-picker-modal.ts +46 -0
- package/src/input/settings-modal-activation.ts +1 -1
- package/src/input/settings-modal-behavior.ts +4 -4
- package/src/input/settings-modal-commit.ts +11 -0
- package/src/input/settings-modal-data.ts +13 -80
- package/src/input/settings-modal-mutations.ts +33 -0
- package/src/input/settings-modal-secrets.ts +34 -0
- package/src/input/settings-modal-subscriptions.ts +1 -1
- package/src/input/settings-modal-types.ts +15 -1
- package/src/input/settings-modal.ts +28 -3
- package/src/input/worktree-setup-config.ts +1 -1
- package/src/main.ts +11 -9
- package/src/panels/agent-inspector-shared.ts +2 -2
- package/src/panels/base-panel.ts +2 -2
- package/src/panels/builtin/operations.ts +6 -8
- package/src/panels/builtin/session.ts +17 -0
- package/src/panels/builtin/shared.ts +5 -5
- package/src/panels/builtin-modals.ts +3 -3
- package/src/panels/confirm-state.ts +1 -1
- package/src/panels/cost-tracker-panel.ts +4 -4
- package/src/panels/diff-panel.ts +2 -2
- package/src/panels/diff-review-panel.ts +2 -2
- package/src/panels/expandable-list-panel.ts +2 -2
- package/src/panels/fleet-acts.ts +1 -1
- package/src/panels/fleet-observed-render.ts +1 -1
- package/src/panels/fleet-panel-format.ts +1 -1
- package/src/panels/fleet-panel.ts +1 -1
- package/src/panels/fleet-spawn.ts +1 -1
- package/src/panels/fleet-steer.ts +1 -1
- package/src/panels/fleet-transcript.ts +1 -1
- package/src/panels/git-panel.ts +1 -1
- package/src/panels/hosted-session-feed.ts +352 -0
- package/src/panels/hosted-session-panel.ts +221 -0
- package/src/panels/local-auth-panel.ts +3 -3
- package/src/panels/modals/devices-modal.ts +1 -1
- package/src/panels/modals/local-auth-modal.ts +1 -1
- package/src/panels/modals/pairing-modal.ts +1 -1
- package/src/panels/modals/services-modal.ts +1 -1
- package/src/panels/modals/settings-sync-modal.ts +1 -1
- package/src/panels/modals/subscription-modal.ts +1 -1
- package/src/panels/modals/work-plan-modal.ts +1 -1
- package/src/panels/notifications-panel.ts +1 -1
- package/src/panels/panel-confirm-overlay.ts +1 -1
- package/src/panels/plugins-panel.ts +2 -2
- package/src/panels/polish-core.ts +2 -2
- package/src/panels/polish-tables.ts +1 -1
- package/src/panels/polish.ts +2 -2
- package/src/panels/scrollable-list-panel.ts +3 -3
- package/src/panels/skills-panel.ts +3 -3
- package/src/panels/token-budget-panel.ts +5 -5
- package/src/panels/types.ts +1 -2
- package/src/permissions/prompt.ts +1 -1
- package/src/renderer/autocomplete-overlay.ts +1 -1
- package/src/renderer/block-actions-overlay.ts +1 -1
- package/src/renderer/bookmark-modal.ts +1 -1
- package/src/renderer/buffer.ts +1 -1
- package/src/renderer/code-block.ts +1 -1
- package/src/renderer/composer-fragments.ts +1 -1
- package/src/renderer/compositor.ts +2 -2
- package/src/renderer/config-modal.ts +1 -1
- package/src/renderer/context-inspector.ts +1 -1
- package/src/renderer/conversation-layout.ts +2 -2
- package/src/renderer/conversation-overlays.ts +1 -1
- package/src/renderer/conversation-surface.ts +2 -2
- package/src/renderer/diff-view.ts +1 -1
- package/src/renderer/diff.ts +1 -1
- package/src/renderer/file-picker-overlay.ts +1 -1
- package/src/renderer/fleet-tab-strip.ts +1 -1
- package/src/renderer/fullscreen-primitives.ts +2 -2
- package/src/renderer/fullscreen-workspace.ts +1 -1
- package/src/renderer/header-line.ts +1 -1
- package/src/renderer/help-overlay.ts +1 -1
- package/src/renderer/history-search-overlay.ts +2 -2
- package/src/renderer/layout.ts +5 -8
- package/src/renderer/markdown-inline.ts +1 -1
- package/src/renderer/markdown-table.ts +1 -1
- package/src/renderer/markdown.ts +1 -1
- package/src/renderer/mcp-workspace.ts +1 -1
- package/src/renderer/modal-factory.ts +2 -2
- package/src/renderer/model-workspace.ts +2 -2
- package/src/renderer/onboarding/onboarding-wizard.ts +1 -1
- package/src/renderer/overlay-box.ts +1 -1
- package/src/renderer/panel-composite.ts +1 -1
- package/src/renderer/panel-workspace-bar.ts +1 -1
- package/src/renderer/process-indicator.ts +1 -1
- package/src/renderer/profile-picker-modal.ts +1 -1
- package/src/renderer/search-overlay.ts +2 -2
- package/src/renderer/selection-modal-overlay.ts +1 -1
- package/src/renderer/session-picker-modal.ts +124 -3
- package/src/renderer/settings-modal-helpers.ts +2 -0
- package/src/renderer/settings-modal.ts +2 -2
- package/src/renderer/shell-surface.ts +2 -2
- package/src/renderer/system-message.ts +1 -1
- package/src/renderer/tab-strip.ts +1 -1
- package/src/renderer/theme-mode-config.ts +1 -1
- package/src/renderer/theme.ts +11 -12
- package/src/renderer/thinking.ts +1 -1
- package/src/renderer/tool-call.ts +2 -2
- package/src/renderer/tool-result-expanded-lines.ts +1 -1
- package/src/renderer/turn-injection.ts +7 -8
- package/src/renderer/ui-factory.ts +3 -3
- package/src/runtime/bootstrap-command-context.ts +4 -4
- package/src/runtime/bootstrap-command-parts.ts +5 -5
- package/src/runtime/bootstrap-core.ts +30 -30
- package/src/runtime/bootstrap-shell.ts +4 -4
- package/src/runtime/bootstrap.ts +128 -157
- package/src/runtime/client/approval-updates.ts +82 -0
- package/src/runtime/client/build-floors.ts +167 -0
- package/src/runtime/client/daemon-attach-handshake.ts +115 -0
- package/src/runtime/client/fleet-union.ts +147 -0
- package/src/runtime/client/host-service-status.ts +71 -0
- package/src/runtime/client/hosted-exit.ts +86 -0
- package/src/runtime/client/hosted-roster.ts +110 -0
- package/src/runtime/client/hosted-session-stream.ts +178 -0
- package/src/runtime/client/hosted-sessions.ts +187 -0
- package/src/runtime/client/operator-endpoint.ts +213 -0
- package/src/runtime/client/spine-adoption.ts +99 -0
- package/src/runtime/cloudflare-control-plane.ts +1 -1
- package/src/runtime/context-accounting-source.ts +1 -1
- package/src/runtime/context.ts +2 -2
- package/src/runtime/conversation-rewind-port.ts +42 -14
- package/src/runtime/daemon-attach-notices.ts +55 -19
- package/src/runtime/diagnostics/panels/ops.ts +1 -1
- package/src/runtime/disposal-wiring.ts +4 -24
- package/src/runtime/index.ts +119 -105
- package/src/runtime/install-self-check-startup.ts +2 -2
- package/src/runtime/interaction-seams.ts +1 -1
- package/src/runtime/knowledge-services.ts +8 -2
- package/src/runtime/legacy-daemon-migration.ts +15 -3
- package/src/runtime/legacy-daemon-reconcile.ts +3 -2
- package/src/runtime/memory-spine-transport.ts +37 -267
- package/src/runtime/notification-dispatch.ts +2 -2
- package/src/runtime/onboarding/apply.ts +2 -2
- package/src/runtime/onboarding/derivation.ts +2 -2
- package/src/runtime/onboarding/markers.ts +2 -2
- package/src/runtime/onboarding/progress.ts +2 -2
- package/src/runtime/onboarding/snapshot.ts +1 -1
- package/src/runtime/onboarding/state.ts +2 -2
- package/src/runtime/onboarding/types.ts +2 -2
- package/src/runtime/orchestrator-core-services.ts +1 -1
- package/src/runtime/path-shadow-startup.ts +28 -221
- package/src/runtime/power-keepawake-remote.ts +3 -2
- package/src/runtime/process-lifecycle.ts +2 -2
- package/src/runtime/provider-fallback.ts +10 -66
- package/src/runtime/recovery-autosave.ts +1 -1
- package/src/runtime/recovery-offer-wiring.ts +39 -23
- package/src/runtime/recovery-prompt.ts +31 -17
- package/src/runtime/relay-reachability-bridge.ts +53 -42
- package/src/runtime/release-artifacts.ts +2 -1
- package/src/runtime/runtime-services-types.ts +82 -35
- package/src/runtime/services.ts +305 -300
- package/src/runtime/session-resume-liveness-confirm.ts +1 -1
- package/src/runtime/ui-services.ts +7 -6
- package/src/runtime/update-check.ts +23 -43
- package/src/runtime/workspace-checkpointing.ts +1 -1
- package/src/runtime/wrfc-persistence.ts +2 -2
- package/src/shell/ui-openers.ts +30 -7
- package/src/utils/clipboard.ts +1 -1
- package/src/verification/verification-ledger.ts +10 -8
- package/src/version.ts +1 -1
- package/bin/goodvibes-daemon +0 -90
- package/src/cli/config-overrides.ts +0 -267
- package/src/cli/endpoints.ts +0 -109
- package/src/cli/parser.ts +0 -395
- package/src/cli/redaction.ts +0 -170
- package/src/cli/types.ts +0 -84
- package/src/cluster/commands.ts +0 -382
- package/src/cluster/remote-daemon-target.ts +0 -225
- package/src/cluster/render.ts +0 -268
- package/src/config/atomic-write.ts +0 -70
- package/src/config/credential-availability.ts +0 -122
- package/src/config/goodvibes-home.ts +0 -149
- package/src/config/index.ts +0 -88
- package/src/config/provider-model.ts +0 -23
- package/src/config/read-versioned.ts +0 -228
- package/src/core/alert-gating.ts +0 -67
- package/src/core/consolidation-receipt.ts +0 -41
- package/src/core/focus-tracker.ts +0 -41
- package/src/core/history.ts +0 -45
- package/src/core/memory-status.ts +0 -118
- package/src/core/orchestrator.ts +0 -7
- package/src/core/pairing-devices.ts +0 -49
- package/src/core/pairing-handoff.ts +0 -101
- package/src/core/pairing-offers.ts +0 -83
- package/src/core/pairing-origin.ts +0 -78
- package/src/core/rewind-turn-anchors.ts +0 -311
- package/src/core/session-recovery.ts +0 -210
- package/src/core/stable-host.ts +0 -171
- package/src/core/transcript-journal.ts +0 -503
- package/src/daemon/cli.ts +0 -641
- package/src/daemon/handlers/context.ts +0 -29
- package/src/daemon/handlers/contracts.ts +0 -77
- package/src/daemon/handlers/credentials.ts +0 -139
- package/src/daemon/handlers/drafts/draft-store.ts +0 -427
- package/src/daemon/handlers/drafts/index.ts +0 -17
- package/src/daemon/handlers/drafts/register.ts +0 -331
- package/src/daemon/handlers/errors.ts +0 -18
- package/src/daemon/handlers/inbox/cursor-store.ts +0 -457
- package/src/daemon/handlers/inbox/index.ts +0 -284
- package/src/daemon/handlers/inbox/mapping.ts +0 -192
- package/src/daemon/handlers/inbox/poller.ts +0 -212
- package/src/daemon/handlers/inbox/provider-adapter.ts +0 -156
- package/src/daemon/handlers/inbox/providers/discord.ts +0 -252
- package/src/daemon/handlers/inbox/providers/email.ts +0 -152
- package/src/daemon/handlers/inbox/providers/imap-client.ts +0 -300
- package/src/daemon/handlers/inbox/providers/route-util.ts +0 -24
- package/src/daemon/handlers/inbox/providers/slack.ts +0 -263
- package/src/daemon/handlers/index.ts +0 -117
- package/src/daemon/handlers/register.ts +0 -168
- package/src/daemon/handlers/remote/backends/cloud-terminal.ts +0 -142
- package/src/daemon/handlers/remote/backends/docker.ts +0 -79
- package/src/daemon/handlers/remote/backends/index.ts +0 -40
- package/src/daemon/handlers/remote/backends/local-process.ts +0 -113
- package/src/daemon/handlers/remote/backends/process-runner.ts +0 -127
- package/src/daemon/handlers/remote/backends/ssh.ts +0 -125
- package/src/daemon/handlers/remote/backends/types.ts +0 -97
- package/src/daemon/handlers/remote/dispatcher.ts +0 -181
- package/src/daemon/handlers/remote/index.ts +0 -119
- package/src/daemon/handlers/remote/peer-registry.ts +0 -357
- package/src/daemon/handlers/remote/service.ts +0 -191
- package/src/daemon/handlers/routing/inbox-bridge.ts +0 -71
- package/src/daemon/handlers/routing/index.ts +0 -261
- package/src/daemon/handlers/routing/route-store.ts +0 -319
- package/src/daemon/handlers/routing/routing-resolver.ts +0 -75
- package/src/daemon/handlers/sqlite-store.ts +0 -278
- package/src/daemon/handlers/triage/index.ts +0 -57
- package/src/daemon/handlers/triage/integration.ts +0 -213
- package/src/daemon/handlers/triage/pipeline.ts +0 -274
- package/src/daemon/handlers/triage/scorer.ts +0 -287
- package/src/daemon/handlers/triage/tagger/discord.ts +0 -187
- package/src/daemon/handlers/triage/tagger/imap.ts +0 -384
- package/src/daemon/handlers/triage/tagger/index.ts +0 -184
- package/src/daemon/handlers/triage/tagger/shared.ts +0 -70
- package/src/daemon/handlers/triage/tagger/slack.ts +0 -69
- package/src/daemon/handlers/triage/types.ts +0 -50
- package/src/daemon/lifecycle.ts +0 -41
- package/src/daemon/provision-wake-model.ts +0 -81
- package/src/daemon/safe-serve.ts +0 -61
- package/src/daemon/send/channels.ts +0 -200
- package/src/daemon/send/command.ts +0 -332
- package/src/daemon/send/composition.ts +0 -99
- package/src/daemon/send/failure-text.ts +0 -93
- package/src/daemon/send/inert-text.ts +0 -225
- package/src/daemon/send/stdin.ts +0 -24
- package/src/daemon/service-commands.ts +0 -329
- package/src/export/cost-utils.ts +0 -319
- package/src/input/selection.ts +0 -135
- package/src/plugins/loader.ts +0 -15
- package/src/renderer/bottom-bar.ts +0 -58
- package/src/renderer/conversation-tree.ts +0 -228
- package/src/runtime/agent-graph-composition.ts +0 -78
- package/src/runtime/channel-composition.ts +0 -46
- package/src/runtime/cluster-composition.ts +0 -124
- package/src/runtime/cluster-group-composition.ts +0 -284
- package/src/runtime/code-index-services.ts +0 -167
- package/src/runtime/daemon-handler-composition.ts +0 -76
- package/src/runtime/device-posture-composition.ts +0 -110
- package/src/runtime/durability-housekeeping.ts +0 -183
- package/src/runtime/durability-services.ts +0 -155
- package/src/runtime/embedded-service-factories.ts +0 -58
- package/src/runtime/feature-settings.ts +0 -154
- package/src/runtime/fleet-needs-input-push.ts +0 -70
- package/src/runtime/fleet-services.ts +0 -41
- package/src/runtime/idle-power-services.ts +0 -85
- package/src/runtime/mail-composition.ts +0 -65
- package/src/runtime/memory-fold.ts +0 -55
- package/src/runtime/operator-token-cleanup.ts +0 -109
- package/src/runtime/path-shadow.ts +0 -418
- package/src/runtime/perf/panel-health-monitor.ts +0 -18
- package/src/runtime/provider-optimizer-wiring.ts +0 -55
- package/src/runtime/reachability-notice.ts +0 -100
- package/src/runtime/remote-execution-composition.ts +0 -62
- package/src/runtime/session-liveness-marker.ts +0 -257
- package/src/runtime/session-pointer-surface.ts +0 -22
- package/src/runtime/session-storage-services.ts +0 -41
- package/src/runtime/surface-feature-flags.ts +0 -96
- package/src/runtime/terminal-output-guard.ts +0 -235
- package/src/runtime/trust/workspace-registration.ts +0 -192
- package/src/runtime/trust/workspace-trust.ts +0 -229
- package/src/runtime/ui/index.ts +0 -39
- package/src/runtime/ui/model-picker/data-provider.ts +0 -182
- package/src/runtime/ui/model-picker/health-enrichment.ts +0 -231
- package/src/runtime/ui/model-picker/index.ts +0 -59
- package/src/runtime/ui/model-picker/types.ts +0 -153
- package/src/runtime/ui/provider-health/data-provider.ts +0 -244
- package/src/runtime/ui/provider-health/fallback-visualizer.ts +0 -71
- package/src/runtime/ui/provider-health/index.ts +0 -46
- package/src/runtime/ui/provider-health/types.ts +0 -146
- package/src/runtime/ui-events.ts +0 -1
- package/src/runtime/ui-read-model-helpers.ts +0 -1
- package/src/runtime/ui-read-models-observability-maintenance.ts +0 -1
- package/src/runtime/ui-read-models-observability-options.ts +0 -1
- package/src/runtime/ui-read-models-observability-remote.ts +0 -1
- package/src/runtime/ui-read-models-observability-security.ts +0 -1
- package/src/runtime/ui-read-models-observability-system.ts +0 -1
- package/src/runtime/ui-read-models-observability.ts +0 -1
- package/src/runtime/ui-service-queries.ts +0 -1
- package/src/runtime/voice-setup-services.ts +0 -98
- package/src/runtime/workstream-attempts-validation.ts +0 -77
- package/src/runtime/workstream-draft-edits.ts +0 -95
- package/src/runtime/workstream-draft-store.ts +0 -274
- package/src/runtime/workstream-draft-types.ts +0 -42
- package/src/runtime/workstream-services.ts +0 -373
- package/src/tools/index.ts +0 -1
- package/src/types/grid.ts +0 -48
- package/src/types/sql-js.d.ts +0 -15
- package/src/work-plans/work-plan-store.ts +0 -702
package/src/export/cost-utils.ts
DELETED
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
// ---------------------------------------------------------------------------
|
|
2
|
-
// cost-utils — canonical pricing source for token cost calculations (consumed by CostTrackerPanel and share-runtime)
|
|
3
|
-
//
|
|
4
|
-
// Pricing resolution order (resolvePricing):
|
|
5
|
-
// 1. `:free` suffix (OpenRouter free-tier convention) — always priced at $0.
|
|
6
|
-
// 2. The live SDK model catalog, when a source has been wired via
|
|
7
|
-
// setPricingSource() (bootstrap-core.ts wires ProviderRegistry.getRawCatalogModels()
|
|
8
|
-
// once catalog init completes) — exact id match, then prefix/substring.
|
|
9
|
-
// 3. STATIC_FALLBACK_PRICING — a small hand-maintained safety net for common
|
|
10
|
-
// frontier models, used when the catalog has no source wired (e.g. tests)
|
|
11
|
-
// or hasn't matched (catalog not yet loaded, or a model this net covers
|
|
12
|
-
// that the catalog happens to miss).
|
|
13
|
-
// 4. Unpriced: the model is genuinely unknown to every source above. This is
|
|
14
|
-
// reported explicitly via `priced: false` so consumers can render an
|
|
15
|
-
// honest "unpriced" state instead of a silent $0.
|
|
16
|
-
// ---------------------------------------------------------------------------
|
|
17
|
-
|
|
18
|
-
import { computeUsageCostUsd, type CatalogModel, type ResolvedModelPricing } from '@pellux/goodvibes-sdk/platform/providers';
|
|
19
|
-
|
|
20
|
-
export interface ModelPricing {
|
|
21
|
-
input: number;
|
|
22
|
-
output: number;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Where a resolved price came from, for the render-side source distinction:
|
|
27
|
-
* 'user' = the manual pricing.modelPrices entry ("your price"), 'provider' =
|
|
28
|
-
* served by the provider API, 'catalog' = the live model catalog (dated),
|
|
29
|
-
* 'fallback' = this module's small built-in safety net.
|
|
30
|
-
*/
|
|
31
|
-
export type PricingSourceKind = 'user' | 'provider' | 'catalog' | 'fallback';
|
|
32
|
-
|
|
33
|
-
/** Result of a pricing lookup: the resolved (possibly zero) price, and whether it's real. */
|
|
34
|
-
export interface PricingResult {
|
|
35
|
-
pricing: ModelPricing;
|
|
36
|
-
/** False when no source recognized the model — the zero pricing is a placeholder, not a real price. */
|
|
37
|
-
priced: boolean;
|
|
38
|
-
/** Which source priced the model (present only when priced). */
|
|
39
|
-
source?: PricingSourceKind;
|
|
40
|
-
/** ISO date (YYYY-MM-DD) of the catalog/provider snapshot the price came from, when known. */
|
|
41
|
-
asOf?: string;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Hand-maintained safety net, used only when the live catalog has no source
|
|
45
|
-
// wired or does not recognize the model. NOT the primary pricing source —
|
|
46
|
-
// see resolvePricing() below.
|
|
47
|
-
const STATIC_FALLBACK_PRICING: Record<string, ModelPricing> = {
|
|
48
|
-
// Free tier
|
|
49
|
-
'openrouter/free': { input: 0, output: 0 },
|
|
50
|
-
|
|
51
|
-
// InceptionLabs
|
|
52
|
-
'mercury-2': { input: 0.50, output: 1.50 },
|
|
53
|
-
'mercury-edit': { input: 0.50, output: 1.50 },
|
|
54
|
-
|
|
55
|
-
// OpenAI
|
|
56
|
-
'gpt-5.4': { input: 5, output: 15 },
|
|
57
|
-
'gpt-5.3-chat-latest': { input: 3, output: 10 },
|
|
58
|
-
'gpt-5-mini': { input: 0.15, output: 0.60 },
|
|
59
|
-
'gpt-5-nano': { input: 0.05, output: 0.20 },
|
|
60
|
-
'gpt-oss-120b': { input: 0, output: 0 },
|
|
61
|
-
|
|
62
|
-
// Anthropic
|
|
63
|
-
'claude-opus-4-6': { input: 15, output: 75 },
|
|
64
|
-
'claude-sonnet-4-6': { input: 3, output: 15 },
|
|
65
|
-
'claude-haiku-4-5': { input: 0.80, output: 4 },
|
|
66
|
-
|
|
67
|
-
// Google
|
|
68
|
-
'gemini-3.1-pro': { input: 1.25, output: 5 },
|
|
69
|
-
'gemini-3-flash': { input: 0.075, output: 0.30 },
|
|
70
|
-
'gemini-3.1-flash-lite': { input: 0.02, output: 0.10 },
|
|
71
|
-
'gemini-2.5-pro': { input: 1.25, output: 5 },
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
// Module-level injection point. Kept as a bare singleton (not threaded through
|
|
75
|
-
// call sites) because the 9 existing consumers are pure functions with no
|
|
76
|
-
// ProviderRegistry in scope; see brief for the tradeoff. Tests that
|
|
77
|
-
// never call setPricingSource() fall through to the static-fallback path,
|
|
78
|
-
// which keeps them isolated from catalog state by default.
|
|
79
|
-
let pricingSource: (() => readonly CatalogModel[]) | null = null;
|
|
80
|
-
|
|
81
|
-
/** Wire (or clear, with null) the live catalog as the primary pricing source. */
|
|
82
|
-
export function setPricingSource(source: (() => readonly CatalogModel[]) | null): void {
|
|
83
|
-
pricingSource = source;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// The ONE model pricing resolver (manual pricing.modelPrices -> registration
|
|
87
|
-
// -> provider-served -> catalog -> honest unknown), wired from
|
|
88
|
-
// bootstrap-core.ts as ProviderRegistry.resolveModelPricing once the runtime
|
|
89
|
-
// exists. When set, it is consulted FIRST so a manual price the user sets is
|
|
90
|
-
// visible to every cost surface immediately; the legacy catalog/static chain
|
|
91
|
-
// below remains the fallback for resolver-unknown models and for surfaces
|
|
92
|
-
// (tests, headless) that never wire a registry.
|
|
93
|
-
let modelPricingResolver: ((modelId: string) => ResolvedModelPricing) | null = null;
|
|
94
|
-
|
|
95
|
-
/** Wire (or clear, with null) the registry's resolveModelPricing as the primary pricing source. */
|
|
96
|
-
export function setModelPricingResolver(resolver: ((modelId: string) => ResolvedModelPricing) | null): void {
|
|
97
|
-
modelPricingResolver = resolver;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* One-call bootstrap wiring: the live catalog as the legacy source AND the
|
|
102
|
-
* registry's ONE pricing resolver (manual pricing.modelPrices -> registration
|
|
103
|
-
* -> provider-served -> catalog -> honest unknown) as the primary, so every
|
|
104
|
-
* cost surface sees a manually-set price immediately and can name its source.
|
|
105
|
-
*/
|
|
106
|
-
export function wireCostPricing(registry: {
|
|
107
|
-
getRawCatalogModels(): readonly CatalogModel[];
|
|
108
|
-
resolveModelPricing(modelRef: string): ResolvedModelPricing;
|
|
109
|
-
}): void {
|
|
110
|
-
setPricingSource(() => registry.getRawCatalogModels());
|
|
111
|
-
setModelPricingResolver((modelId) => registry.resolveModelPricing(modelId));
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function findInCatalog(modelId: string, models: readonly CatalogModel[]): ModelPricing | null {
|
|
115
|
-
const exact = models.find((m) => m.id === modelId);
|
|
116
|
-
if (exact) return exact.tier === 'free' ? { input: 0, output: 0 } : exact.pricing;
|
|
117
|
-
for (const m of models) {
|
|
118
|
-
if (modelId.startsWith(m.id) || modelId.includes(m.id)) {
|
|
119
|
-
return m.tier === 'free' ? { input: 0, output: 0 } : m.pricing;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return null;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function findInStaticFallback(modelId: string): ModelPricing | null {
|
|
126
|
-
const exact = STATIC_FALLBACK_PRICING[modelId];
|
|
127
|
-
if (exact) return exact;
|
|
128
|
-
for (const [key, pricing] of Object.entries(STATIC_FALLBACK_PRICING)) {
|
|
129
|
-
if (modelId.startsWith(key) || modelId.includes(key)) return pricing;
|
|
130
|
-
}
|
|
131
|
-
return null;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* resolvePricing — resolve USD-per-1M-token pricing for a model ID, and
|
|
136
|
-
* whether that pricing is real (vs. an unpriced placeholder). See the module
|
|
137
|
-
* header for the full resolution order.
|
|
138
|
-
*/
|
|
139
|
-
export function resolvePricing(modelId: string): PricingResult {
|
|
140
|
-
if (modelId.endsWith(':free')) return { pricing: { input: 0, output: 0 }, priced: true, source: 'catalog' };
|
|
141
|
-
|
|
142
|
-
// The ONE resolver first: manual price -> registration -> provider-served
|
|
143
|
-
// -> catalog. A 'priced' answer carries its source (and snapshot date when
|
|
144
|
-
// known) so render surfaces can say "your price" vs "catalog price, as of
|
|
145
|
-
// <date>". Unknown/subscription answers fall through to the legacy chain
|
|
146
|
-
// so nothing regresses while the catalog is still loading.
|
|
147
|
-
if (modelPricingResolver) {
|
|
148
|
-
const resolved = modelPricingResolver(modelId);
|
|
149
|
-
if (resolved.status === 'priced') {
|
|
150
|
-
return {
|
|
151
|
-
pricing: { input: resolved.rates.inputPerMTok, output: resolved.rates.outputPerMTok },
|
|
152
|
-
priced: true,
|
|
153
|
-
source: resolved.source,
|
|
154
|
-
...(resolved.asOf ? { asOf: resolved.asOf } : {}),
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const models = pricingSource?.() ?? [];
|
|
160
|
-
const catalogHit = findInCatalog(modelId, models);
|
|
161
|
-
if (catalogHit) return { pricing: catalogHit, priced: true, source: 'catalog' };
|
|
162
|
-
|
|
163
|
-
const fallbackHit = findInStaticFallback(modelId);
|
|
164
|
-
if (fallbackHit) return { pricing: fallbackHit, priced: true, source: 'fallback' };
|
|
165
|
-
|
|
166
|
-
// Genuinely unknown — no source recognizes this model. Report honestly
|
|
167
|
-
// rather than collapsing into the same zero a free model would return.
|
|
168
|
-
return { pricing: { input: 0, output: 0 }, priced: false };
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* The render-side source distinction for a priced model: "your price" for a
|
|
173
|
-
* manual pricing.modelPrices entry, "catalog price, as of <date>" (or
|
|
174
|
-
* provider-served/built-in equivalents) otherwise. Null when the model is
|
|
175
|
-
* unpriced — callers render the explicit "price unknown" marker instead.
|
|
176
|
-
*/
|
|
177
|
-
export function describePricingSource(modelId: string): string | null {
|
|
178
|
-
const result = resolvePricing(modelId);
|
|
179
|
-
if (!result.priced) return null;
|
|
180
|
-
switch (result.source) {
|
|
181
|
-
case 'user':
|
|
182
|
-
return 'your price';
|
|
183
|
-
case 'provider':
|
|
184
|
-
return result.asOf ? `provider price, as of ${result.asOf}` : 'provider price';
|
|
185
|
-
case 'catalog':
|
|
186
|
-
return result.asOf ? `catalog price, as of ${result.asOf}` : 'catalog price';
|
|
187
|
-
case 'fallback':
|
|
188
|
-
return 'built-in price';
|
|
189
|
-
default:
|
|
190
|
-
return 'catalog price';
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* getPricing — resolve USD-per-1M-token pricing for a model ID.
|
|
196
|
-
* Back-compat wrapper over resolvePricing(); returns zero for both genuinely
|
|
197
|
-
* free and genuinely unknown models (use resolvePricing/isModelPriced to
|
|
198
|
-
* distinguish the two).
|
|
199
|
-
*/
|
|
200
|
-
export function getPricing(modelId: string): ModelPricing {
|
|
201
|
-
return resolvePricing(modelId).pricing;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/** True when `modelId` resolves to a real price (free or paid), false when it's an unpriced placeholder. */
|
|
205
|
-
export function isModelPriced(modelId: string): boolean {
|
|
206
|
-
return resolvePricing(modelId).priced;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* calcSessionCost — compute total session cost in USD given raw token counters
|
|
211
|
-
* and the active model ID. Same formula used by CostTrackerPanel.onTurnComplete.
|
|
212
|
-
*
|
|
213
|
-
* inputTokens — cumulative input tokens
|
|
214
|
-
* outputTokens — cumulative output tokens
|
|
215
|
-
* cacheRead — cumulative cache-read tokens
|
|
216
|
-
* cacheWrite — cumulative cache-write tokens
|
|
217
|
-
* modelId — registry model identifier
|
|
218
|
-
*
|
|
219
|
-
* Unpriced models contribute 0 to the total (same as before this WO) — only
|
|
220
|
-
* the display layer distinguishes "genuinely free/priced" from "unpriced".
|
|
221
|
-
*/
|
|
222
|
-
export function calcSessionCost(
|
|
223
|
-
inputTokens: number,
|
|
224
|
-
outputTokens: number,
|
|
225
|
-
cacheRead: number,
|
|
226
|
-
cacheWrite: number,
|
|
227
|
-
modelId: string,
|
|
228
|
-
): number {
|
|
229
|
-
// Through the ONE resolver when wired: computeUsageCostUsd applies the
|
|
230
|
-
// source's explicit cache rates (or the published per-provider ratio)
|
|
231
|
-
// instead of billing cache traffic at the full input rate.
|
|
232
|
-
if (modelPricingResolver) {
|
|
233
|
-
const resolved = modelPricingResolver(modelId);
|
|
234
|
-
if (resolved.status === 'priced') {
|
|
235
|
-
return computeUsageCostUsd(resolved, {
|
|
236
|
-
inputTokens,
|
|
237
|
-
outputTokens,
|
|
238
|
-
cacheReadTokens: cacheRead,
|
|
239
|
-
cacheWriteTokens: cacheWrite,
|
|
240
|
-
}) ?? 0;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
const pricing = getPricing(modelId);
|
|
244
|
-
// Cache reads/writes count toward billable input side (same convention as panel)
|
|
245
|
-
const billableInput = inputTokens + cacheRead + cacheWrite;
|
|
246
|
-
return (billableInput * pricing.input + outputTokens * pricing.output) / 1_000_000;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* computeBudgetBreach — pure predicate shared by CostTrackerPanel's render-time
|
|
251
|
-
* "OVER BUDGET" flag and the background budget-breach notifier
|
|
252
|
-
* (core/budget-breach-notifier.ts), so both agree on exactly one definition
|
|
253
|
-
* of "over budget". `budgetThreshold <= 0` means no budget is configured
|
|
254
|
-
* (disabled), which can never be breached.
|
|
255
|
-
*/
|
|
256
|
-
export function computeBudgetBreach(sessionCost: number, budgetThreshold: number): boolean {
|
|
257
|
-
return budgetThreshold > 0 && sessionCost > budgetThreshold;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/** Read/write access to the `behavior.budgetAlertUsd` TUI-local config key. Plain
|
|
261
|
-
* callbacks (rather than a ConfigManager reference) so callers can pass a
|
|
262
|
-
* generic-key-cast wrapper without this module depending on the SDK config types. */
|
|
263
|
-
export interface BudgetAlertConfigAccess {
|
|
264
|
-
readonly get: (key: string) => unknown;
|
|
265
|
-
readonly set: (key: string, value: unknown) => void;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/** Default for the `behavior.budgetAlertUsd` synthetic setting: 0 = no budget configured. */
|
|
269
|
-
export const BUDGET_ALERT_USD_DEFAULT = 0;
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* The dot-path config key backing the session cost-budget alert threshold.
|
|
273
|
-
* Shared by cost-tracker-panel.ts (get/set), settings-modal-data.ts (the
|
|
274
|
-
* settings-modal-visible synthetic entry), and readBudgetAlertUsd below, so
|
|
275
|
-
* the string literal lives in exactly one place.
|
|
276
|
-
*/
|
|
277
|
-
export const BUDGET_ALERT_USD_CONFIG_KEY = 'behavior.budgetAlertUsd';
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* readBudgetAlertUsd — read the session cost-budget alert threshold (USD) from
|
|
281
|
-
* config. This is the single source of truth CostTrackerPanel and the
|
|
282
|
-
* background budget-breach notifier (core/budget-breach-notifier.ts) both
|
|
283
|
-
* read, so a threshold set via the panel's 'b' key is immediately visible to
|
|
284
|
-
* the notifier and vice versa. Falls back to BUDGET_ALERT_USD_DEFAULT (off)
|
|
285
|
-
* when the key is absent or invalid.
|
|
286
|
-
*/
|
|
287
|
-
export function readBudgetAlertUsd(configGet: (key: string) => unknown): number {
|
|
288
|
-
const raw = configGet(BUDGET_ALERT_USD_CONFIG_KEY);
|
|
289
|
-
const parsed = typeof raw === 'number' ? raw : Number(raw);
|
|
290
|
-
return Number.isFinite(parsed) && parsed >= 0 ? parsed : BUDGET_ALERT_USD_DEFAULT;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* The SDK settings key holding the user's manual per-model prices — the
|
|
295
|
-
* highest-precedence source in the ONE pricing resolver. Object map of
|
|
296
|
-
* `provider:model` -> { input, output, cacheRead?, cacheWrite? } in USD per
|
|
297
|
-
* 1M tokens.
|
|
298
|
-
*/
|
|
299
|
-
export const MODEL_PRICES_CONFIG_KEY = 'pricing.modelPrices';
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Persist a manual price for one `provider:model` key into
|
|
303
|
-
* pricing.modelPrices, preserving every other entry. The registry's resolver
|
|
304
|
-
* reads the key live per call, so the new price is visible to every cost
|
|
305
|
-
* surface on the next render — no restart.
|
|
306
|
-
*/
|
|
307
|
-
export function writeManualModelPrice(
|
|
308
|
-
config: BudgetAlertConfigAccess,
|
|
309
|
-
modelKey: string,
|
|
310
|
-
price: { input: number; output: number },
|
|
311
|
-
): void {
|
|
312
|
-
const current = config.get(MODEL_PRICES_CONFIG_KEY);
|
|
313
|
-
const map: Record<string, unknown> =
|
|
314
|
-
current && typeof current === 'object' && !Array.isArray(current)
|
|
315
|
-
? { ...(current as Record<string, unknown>) }
|
|
316
|
-
: {};
|
|
317
|
-
map[modelKey] = { input: price.input, output: price.output };
|
|
318
|
-
config.set(MODEL_PRICES_CONFIG_KEY, map);
|
|
319
|
-
}
|
package/src/input/selection.ts
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import type { InfiniteBuffer } from '../core/history.ts';
|
|
2
|
-
import type { Cell } from '../types/grid.ts';
|
|
3
|
-
|
|
4
|
-
export interface SelectionPoint {
|
|
5
|
-
col: number;
|
|
6
|
-
row: number;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* SelectionManager - Owns text selection state.
|
|
11
|
-
* Extracted from StateManager. Requires access to the history buffer
|
|
12
|
-
* and scroll state (scrollTop, viewportHeight) at call time.
|
|
13
|
-
*/
|
|
14
|
-
export class SelectionManager {
|
|
15
|
-
public anchor: SelectionPoint | null = null;
|
|
16
|
-
public focus: SelectionPoint | null = null;
|
|
17
|
-
public isDragging = false;
|
|
18
|
-
|
|
19
|
-
private screenToAbsoluteRow(viewportRow: number, scrollTop: number, vHeight: number, lineCount: number): number {
|
|
20
|
-
const offset = Math.max(0, vHeight - lineCount);
|
|
21
|
-
return scrollTop + (viewportRow - offset);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
public startSelection(col: number, viewportRow: number, scrollTop: number, vHeight: number, lineCount: number): void {
|
|
25
|
-
const absoluteRow = this.screenToAbsoluteRow(viewportRow, scrollTop, vHeight, lineCount);
|
|
26
|
-
this.anchor = { col, row: absoluteRow };
|
|
27
|
-
this.focus = { col, row: absoluteRow };
|
|
28
|
-
this.isDragging = true;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
public extendSelection(col: number, viewportRow: number, scrollTop: number, vHeight: number, lineCount: number): void {
|
|
32
|
-
if (!this.isDragging) return;
|
|
33
|
-
const absoluteRow = this.screenToAbsoluteRow(viewportRow, scrollTop, vHeight, lineCount);
|
|
34
|
-
this.focus = { col, row: absoluteRow };
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
public endSelection(): void {
|
|
38
|
-
this.isDragging = false;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
public clearSelection(): void {
|
|
42
|
-
this.anchor = null;
|
|
43
|
-
this.focus = null;
|
|
44
|
-
this.isDragging = false;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
public hasSelection(): boolean {
|
|
48
|
-
if (!this.anchor || !this.focus) return false;
|
|
49
|
-
return this.anchor.row !== this.focus.row || this.anchor.col !== this.focus.col;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
public getSelectedText(history: InfiniteBuffer): string {
|
|
53
|
-
if (!this.anchor || !this.focus) return '';
|
|
54
|
-
|
|
55
|
-
const start =
|
|
56
|
-
this.anchor.row < this.focus.row ||
|
|
57
|
-
(this.anchor.row === this.focus.row && this.anchor.col <= this.focus.col)
|
|
58
|
-
? this.anchor
|
|
59
|
-
: this.focus;
|
|
60
|
-
const end = start === this.anchor ? this.focus : this.anchor;
|
|
61
|
-
|
|
62
|
-
const lines: string[] = [];
|
|
63
|
-
const allLines = history.getAllLines();
|
|
64
|
-
|
|
65
|
-
for (let r = Math.max(0, start.row); r <= Math.min(allLines.length - 1, end.row); r++) {
|
|
66
|
-
const line = allLines[r];
|
|
67
|
-
if (!line) continue;
|
|
68
|
-
|
|
69
|
-
const startCol = r === start.row ? start.col : 0;
|
|
70
|
-
const endCol = r === end.row ? end.col : line.length;
|
|
71
|
-
const gutterEnd = this.findLineNumberGutterEnd(line);
|
|
72
|
-
const effectiveStartCol = startCol < gutterEnd ? gutterEnd : startCol;
|
|
73
|
-
|
|
74
|
-
let lineText = '';
|
|
75
|
-
for (let c = Math.max(0, effectiveStartCol); c < Math.min(line.length, endCol); c++) {
|
|
76
|
-
const cell = line[c];
|
|
77
|
-
if (cell && cell.char !== '') lineText += cell.char;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
lines.push(this.stripDecorativePrefix(lineText));
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return lines.join('\n');
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
private findLineNumberGutterEnd(line: Cell[]): number {
|
|
87
|
-
let i = 0;
|
|
88
|
-
while (i < line.length) {
|
|
89
|
-
const cell = line[i];
|
|
90
|
-
if (cell?.char === ' ' && !cell?.dim && (cell?.bg ?? '') === '') {
|
|
91
|
-
i++;
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
break;
|
|
95
|
-
}
|
|
96
|
-
const start = i;
|
|
97
|
-
let sawDigit = false;
|
|
98
|
-
while (i < line.length) {
|
|
99
|
-
const cell = line[i];
|
|
100
|
-
const ch = cell?.char ?? '';
|
|
101
|
-
if (cell?.dim && ch !== '' && /[0-9 │]/.test(ch)) {
|
|
102
|
-
if (/[0-9]/.test(ch)) sawDigit = true;
|
|
103
|
-
i++;
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
|
-
if (!sawDigit) return start;
|
|
109
|
-
if (i < line.length && line[i]?.char === ' ') i++;
|
|
110
|
-
return i > start ? i : start;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
private stripDecorativePrefix(text: string): string {
|
|
114
|
-
return text
|
|
115
|
-
.replace(/^(\s*)(?:[▸▾▶►●○◆▲△▼▽•✕✓▌]\s+)+/u, '$1')
|
|
116
|
-
.replace(/^(\s*)\[(?:x|~| )\]\s+/u, '$1')
|
|
117
|
-
.trimEnd();
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
public isCellSelected(col: number, absoluteRow: number): boolean {
|
|
121
|
-
if (!this.anchor || !this.focus) return false;
|
|
122
|
-
const start =
|
|
123
|
-
this.anchor.row < this.focus.row ||
|
|
124
|
-
(this.anchor.row === this.focus.row && this.anchor.col <= this.focus.col)
|
|
125
|
-
? this.anchor
|
|
126
|
-
: this.focus;
|
|
127
|
-
const end = start === this.anchor ? this.focus : this.anchor;
|
|
128
|
-
if (absoluteRow < start.row || absoluteRow > end.row) return false;
|
|
129
|
-
if (absoluteRow === start.row && absoluteRow === end.row)
|
|
130
|
-
return col >= start.col && col < end.col;
|
|
131
|
-
if (absoluteRow === start.row) return col >= start.col;
|
|
132
|
-
if (absoluteRow === end.row) return col < end.col;
|
|
133
|
-
return true;
|
|
134
|
-
}
|
|
135
|
-
}
|
package/src/plugins/loader.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export {
|
|
2
|
-
getUserPluginDirectory,
|
|
3
|
-
getPluginDirectories,
|
|
4
|
-
discoverPlugins,
|
|
5
|
-
loadPlugin,
|
|
6
|
-
unloadPlugin,
|
|
7
|
-
} from '@pellux/goodvibes-sdk/platform/plugins';
|
|
8
|
-
export type {
|
|
9
|
-
PluginPathOptions,
|
|
10
|
-
PluginManifest,
|
|
11
|
-
PluginEntryPoint,
|
|
12
|
-
LoadedPlugin,
|
|
13
|
-
DiscoveredPlugin,
|
|
14
|
-
PluginLoaderDeps,
|
|
15
|
-
} from '@pellux/goodvibes-sdk/platform/plugins';
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { createEmptyLine, createStyledCell, type Line } from '../types/grid.ts';
|
|
2
|
-
import { getDisplayWidth } from '../utils/terminal-width.ts';
|
|
3
|
-
|
|
4
|
-
export interface BottomBarStyle {
|
|
5
|
-
readonly fg: string;
|
|
6
|
-
readonly bg: string;
|
|
7
|
-
readonly bold?: boolean;
|
|
8
|
-
readonly dim?: boolean;
|
|
9
|
-
readonly underline?: boolean;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function createBottomBarLine(width: number, style: BottomBarStyle): Line {
|
|
13
|
-
const line = createEmptyLine(width);
|
|
14
|
-
for (let col = 0; col < width; col++) {
|
|
15
|
-
line[col] = createStyledCell(' ', {
|
|
16
|
-
fg: style.fg,
|
|
17
|
-
bg: style.bg,
|
|
18
|
-
bold: style.bold ?? false,
|
|
19
|
-
dim: style.dim ?? false,
|
|
20
|
-
underline: style.underline ?? false,
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
return line;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function writeBottomBarText(
|
|
27
|
-
line: Line,
|
|
28
|
-
startX: number,
|
|
29
|
-
maxWidth: number,
|
|
30
|
-
text: string,
|
|
31
|
-
style: BottomBarStyle,
|
|
32
|
-
): void {
|
|
33
|
-
let x = startX;
|
|
34
|
-
let used = 0;
|
|
35
|
-
for (const ch of text) {
|
|
36
|
-
const cellWidth = getDisplayWidth(ch);
|
|
37
|
-
if (cellWidth <= 0) continue;
|
|
38
|
-
if (used + cellWidth > maxWidth || x >= line.length) break;
|
|
39
|
-
line[x] = createStyledCell(ch, {
|
|
40
|
-
fg: style.fg,
|
|
41
|
-
bg: style.bg,
|
|
42
|
-
bold: style.bold ?? false,
|
|
43
|
-
dim: style.dim ?? false,
|
|
44
|
-
underline: style.underline ?? false,
|
|
45
|
-
});
|
|
46
|
-
if (cellWidth > 1 && x + 1 < line.length) {
|
|
47
|
-
line[x + 1] = createStyledCell(' ', {
|
|
48
|
-
fg: style.fg,
|
|
49
|
-
bg: style.bg,
|
|
50
|
-
bold: style.bold ?? false,
|
|
51
|
-
dim: style.dim ?? false,
|
|
52
|
-
underline: style.underline ?? false,
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
x += cellWidth;
|
|
56
|
-
used += cellWidth;
|
|
57
|
-
}
|
|
58
|
-
}
|