@pugi/cli 0.1.0-beta.99 → 1.0.0-alpha.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/LICENSE +1 -1
- package/README.md +11 -191
- package/bin/pugi +8 -0
- package/package.json +15 -71
- package/postinstall.mjs +31 -0
- package/CHANGELOG.md +0 -132
- package/THIRD_PARTY_NOTICES.md +0 -40
- package/assets/pugi-mascot.ansi +0 -16
- package/assets/pugi-prozr2-mascot.ansi +0 -9
- package/bin/run.js +0 -34
- package/dist/commands/deploy.js +0 -439
- package/dist/commands/flatten.js +0 -191
- package/dist/commands/jobs-watch.js +0 -201
- package/dist/commands/jobs.js +0 -260
- package/dist/commands/retro.js +0 -210
- package/dist/commands/smoke.js +0 -133
- package/dist/core/agent-progress/cleanup.js +0 -134
- package/dist/core/agent-progress/schema.js +0 -144
- package/dist/core/agent-progress/writer.js +0 -101
- package/dist/core/agents/adaptive-router.js +0 -330
- package/dist/core/agents/loader.js +0 -104
- package/dist/core/agents/query-decomposer.js +0 -297
- package/dist/core/agents/registry.js +0 -69
- package/dist/core/approvals/shortcut-resolver.js +0 -98
- package/dist/core/artifact-chain/dispatcher.js +0 -148
- package/dist/core/artifact-chain/exporter.js +0 -164
- package/dist/core/artifact-chain/state.js +0 -243
- package/dist/core/artifact-chain/steps.js +0 -169
- package/dist/core/ask-user/question.js +0 -92
- package/dist/core/audit/audit-trail.js +0 -275
- package/dist/core/auth/ensure-authenticated.js +0 -129
- package/dist/core/auth/env-provider.js +0 -238
- package/dist/core/auto-open-browser.js +0 -128
- package/dist/core/auto-update/channels.js +0 -122
- package/dist/core/auto-update/checker.js +0 -241
- package/dist/core/auto-update/state.js +0 -235
- package/dist/core/bare-mode/index.js +0 -107
- package/dist/core/bash/redirect.js +0 -281
- package/dist/core/bash-classifier.js +0 -1397
- package/dist/core/checkpoint/resumer.js +0 -149
- package/dist/core/checkpoint/rewinder.js +0 -291
- package/dist/core/checkpoints/shadow-git.js +0 -670
- package/dist/core/citations/parser.js +0 -109
- package/dist/core/classifier/yolo-classifier.js +0 -88
- package/dist/core/clipboard.js +0 -70
- package/dist/core/codegraph/decision-store.js +0 -248
- package/dist/core/codegraph/detect-repo.js +0 -459
- package/dist/core/codegraph/install.js +0 -134
- package/dist/core/codegraph/offer-hook.js +0 -220
- package/dist/core/compact/auto-trigger.js +0 -96
- package/dist/core/compact/buffer-rewriter.js +0 -115
- package/dist/core/compact/summarizer.js +0 -208
- package/dist/core/compact/token-counter.js +0 -108
- package/dist/core/consensus/anvil-fanout.js +0 -276
- package/dist/core/consensus/diff-capture.js +0 -491
- package/dist/core/consensus/rubric.js +0 -233
- package/dist/core/context/builder.js +0 -114
- package/dist/core/context/compaction-events.js +0 -99
- package/dist/core/context/compaction.js +0 -602
- package/dist/core/context/index.js +0 -28
- package/dist/core/context/invariants.js +0 -250
- package/dist/core/context/markdown-loader.js +0 -288
- package/dist/core/context/markdown-traverse.js +0 -255
- package/dist/core/context/pugiignore.js +0 -316
- package/dist/core/context/repo-skeleton.js +0 -533
- package/dist/core/context/tool-eviction.js +0 -55
- package/dist/core/context/watcher.js +0 -342
- package/dist/core/context/working-set.js +0 -165
- package/dist/core/coordinator/agent-tools.js +0 -77
- package/dist/core/coordinator/agent-toolset.js +0 -65
- package/dist/core/coordinator/fsm.js +0 -73
- package/dist/core/coordinator/mode-fsm.js +0 -70
- package/dist/core/cost/rate-card.js +0 -129
- package/dist/core/cost/tracker.js +0 -221
- package/dist/core/credentials.js +0 -355
- package/dist/core/cron/scheduler.js +0 -138
- package/dist/core/denial-tracking/index.js +0 -8
- package/dist/core/denial-tracking/state.js +0 -264
- package/dist/core/diagnostics/probe-runner.js +0 -93
- package/dist/core/diagnostics/probes/api.js +0 -46
- package/dist/core/diagnostics/probes/auth.js +0 -93
- package/dist/core/diagnostics/probes/bare-mode.js +0 -42
- package/dist/core/diagnostics/probes/cli-version.js +0 -127
- package/dist/core/diagnostics/probes/config.js +0 -72
- package/dist/core/diagnostics/probes/denial-tracking.js +0 -57
- package/dist/core/diagnostics/probes/disk.js +0 -81
- package/dist/core/diagnostics/probes/engine-live.js +0 -46
- package/dist/core/diagnostics/probes/git.js +0 -65
- package/dist/core/diagnostics/probes/hooks.js +0 -118
- package/dist/core/diagnostics/probes/mcp.js +0 -75
- package/dist/core/diagnostics/probes/node.js +0 -59
- package/dist/core/diagnostics/probes/pnpm.js +0 -36
- package/dist/core/diagnostics/probes/pugi-md.js +0 -89
- package/dist/core/diagnostics/probes/sandbox.js +0 -72
- package/dist/core/diagnostics/probes/session.js +0 -74
- package/dist/core/diagnostics/probes/status-snapshot.js +0 -488
- package/dist/core/diagnostics/probes/workspace.js +0 -63
- package/dist/core/diagnostics/types.js +0 -70
- package/dist/core/dispatch/cache-cleanup.js +0 -197
- package/dist/core/dispatch/cache-handoff.js +0 -295
- package/dist/core/edits/apply-patch-layer-e.js +0 -189
- package/dist/core/edits/dispatch.js +0 -511
- package/dist/core/edits/format-detector.js +0 -260
- package/dist/core/edits/format-matrix.js +0 -26
- package/dist/core/edits/fuzzy-ladder.js +0 -650
- package/dist/core/edits/index.js +0 -19
- package/dist/core/edits/journal.js +0 -199
- package/dist/core/edits/layer-a-apply.js +0 -217
- package/dist/core/edits/layer-a-fuzzy-apply.js +0 -198
- package/dist/core/edits/layer-b-apply.js +0 -211
- package/dist/core/edits/layer-c-apply.js +0 -160
- package/dist/core/edits/layer-d-ast.js +0 -572
- package/dist/core/edits/marker-parser.js +0 -401
- package/dist/core/edits/security-gate.js +0 -223
- package/dist/core/edits/verify-hook.js +0 -273
- package/dist/core/edits/worktree.js +0 -322
- package/dist/core/engine/adapter-runner.js +0 -8
- package/dist/core/engine/anvil-client.js +0 -344
- package/dist/core/engine/auto-compact.js +0 -179
- package/dist/core/engine/budgets.js +0 -195
- package/dist/core/engine/context-prefix.js +0 -155
- package/dist/core/engine/index.js +0 -12
- package/dist/core/engine/intensity.js +0 -163
- package/dist/core/engine/intent.js +0 -260
- package/dist/core/engine/native-pugi.js +0 -1616
- package/dist/core/engine/noop.js +0 -27
- package/dist/core/engine/prompts.js +0 -236
- package/dist/core/engine/strip-internal-fields.js +0 -124
- package/dist/core/engine/tool-bridge.js +0 -2173
- package/dist/core/engine/verification-patterns.js +0 -195
- package/dist/core/evaluation/golden-dataset.js +0 -293
- package/dist/core/feedback/queue.js +0 -177
- package/dist/core/feedback/submitter.js +0 -145
- package/dist/core/file-cache.js +0 -141
- package/dist/core/flatten/flatten-repo.js +0 -439
- package/dist/core/format/osc8-link.js +0 -28
- package/dist/core/hook-chains.js +0 -392
- package/dist/core/hooks/citation-verify-hook.js +0 -138
- package/dist/core/hooks/citation-verify.js +0 -112
- package/dist/core/hooks/events.js +0 -46
- package/dist/core/hooks/index.js +0 -15
- package/dist/core/hooks/registry.js +0 -216
- package/dist/core/hooks/runner.js +0 -236
- package/dist/core/hooks/v2/event-emitter.js +0 -115
- package/dist/core/hooks/v2/executor.js +0 -282
- package/dist/core/hooks/v2/index.js +0 -25
- package/dist/core/hooks/v2/lifecycle.js +0 -104
- package/dist/core/hooks/v2/loader.js +0 -216
- package/dist/core/hooks/v2/matcher.js +0 -125
- package/dist/core/hooks/v2/trust.js +0 -143
- package/dist/core/hooks/v2/types.js +0 -86
- package/dist/core/hooks/worktree-events.js +0 -158
- package/dist/core/hooks.js +0 -415
- package/dist/core/image/renderer.js +0 -71
- package/dist/core/index-store.js +0 -260
- package/dist/core/init/detector.js +0 -582
- package/dist/core/init/template-renderer.js +0 -242
- package/dist/core/jobs/registry.js +0 -462
- package/dist/core/ledger/results-tsv.js +0 -142
- package/dist/core/log-discipline/stdout-redirect.js +0 -51
- package/dist/core/lsp/cache.js +0 -105
- package/dist/core/lsp/client.js +0 -1229
- package/dist/core/lsp/language-detect.js +0 -66
- package/dist/core/lsp/post-edit-diagnostics.js +0 -171
- package/dist/core/lsp/server-detect.js +0 -173
- package/dist/core/lsp/symbol-cache.js +0 -162
- package/dist/core/lsp/symbol-tools.js +0 -664
- package/dist/core/mcp/client.js +0 -385
- package/dist/core/mcp/http-server.js +0 -553
- package/dist/core/mcp/orchestrator-config.js +0 -192
- package/dist/core/mcp/orchestrator-tools.js +0 -806
- package/dist/core/mcp/permission.js +0 -190
- package/dist/core/mcp/registry.js +0 -193
- package/dist/core/mcp/server-tools.js +0 -219
- package/dist/core/mcp/server.js +0 -397
- package/dist/core/mcp/trust.js +0 -91
- package/dist/core/memory/dual-write.js +0 -416
- package/dist/core/memory/passive-extract.js +0 -130
- package/dist/core/memory/phase1-kinds.js +0 -20
- package/dist/core/memory/secret-scanner.js +0 -304
- package/dist/core/memory-sync/queue.js +0 -170
- package/dist/core/metrics/extract.js +0 -113
- package/dist/core/modes/roo-modes.js +0 -68
- package/dist/core/onboarding/ensure-initialized.js +0 -133
- package/dist/core/onboarding/marker.js +0 -111
- package/dist/core/onboarding/telemetry-state.js +0 -108
- package/dist/core/output-style/presets.js +0 -176
- package/dist/core/output-style/state.js +0 -185
- package/dist/core/path-security.js +0 -345
- package/dist/core/permission.js +0 -369
- package/dist/core/permissions/auto-classifier.js +0 -124
- package/dist/core/permissions/bash-parser.js +0 -371
- package/dist/core/permissions/circuit-breaker.js +0 -83
- package/dist/core/permissions/constrained-edit.js +0 -91
- package/dist/core/permissions/gate.js +0 -278
- package/dist/core/permissions/index.js +0 -20
- package/dist/core/permissions/mode.js +0 -174
- package/dist/core/permissions/network-egress.js +0 -137
- package/dist/core/permissions/state.js +0 -241
- package/dist/core/permissions/tool-class.js +0 -107
- package/dist/core/plan-mode/ui-state.js +0 -51
- package/dist/core/plans/plan-artifact.js +0 -721
- package/dist/core/policy-limits/etag-store.js +0 -122
- package/dist/core/prd-check/parser.js +0 -215
- package/dist/core/prd-check/reporter.js +0 -127
- package/dist/core/prd-check/session-review.js +0 -557
- package/dist/core/prd-check/verifiers.js +0 -223
- package/dist/core/prompt-cache/client-cache.js +0 -99
- package/dist/core/prompts/assembly.js +0 -29
- package/dist/core/prompts/registry.js +0 -364
- package/dist/core/pugi-gitignore.js +0 -52
- package/dist/core/pugi-md/cc-compat-rules.js +0 -735
- package/dist/core/pugi-md/context-injector.js +0 -76
- package/dist/core/pugi-md/walk-up.js +0 -207
- package/dist/core/python/uv-installer.js +0 -270
- package/dist/core/python/uv-resolver.js +0 -83
- package/dist/core/rate-limit/narrator.js +0 -146
- package/dist/core/recipes/cli-types.js +0 -20
- package/dist/core/recipes/loader.js +0 -103
- package/dist/core/recipes/runner.js +0 -345
- package/dist/core/recipes/schema.js +0 -587
- package/dist/core/release-notes/parser.js +0 -241
- package/dist/core/release-notes/state.js +0 -116
- package/dist/core/repl/ask.js +0 -512
- package/dist/core/repl/cancellation.js +0 -98
- package/dist/core/repl/cap-warning.js +0 -91
- package/dist/core/repl/clipboard-read.js +0 -174
- package/dist/core/repl/dispatch-fsm.js +0 -220
- package/dist/core/repl/engine-bridge.js +0 -303
- package/dist/core/repl/history-search.js +0 -175
- package/dist/core/repl/history.js +0 -182
- package/dist/core/repl/kill-ring.js +0 -138
- package/dist/core/repl/model-pricing.js +0 -135
- package/dist/core/repl/privacy-banner.js +0 -71
- package/dist/core/repl/session.js +0 -4962
- package/dist/core/repl/slash-commands.js +0 -747
- package/dist/core/repl/store/index.js +0 -12
- package/dist/core/repl/store/jsonl-log.js +0 -321
- package/dist/core/repl/store/lockfile.js +0 -155
- package/dist/core/repl/store/session-store.js +0 -821
- package/dist/core/repl/store/types.js +0 -44
- package/dist/core/repl/store/uuid-v7.js +0 -68
- package/dist/core/repl/tool-route.js +0 -382
- package/dist/core/repl/workspace-context.js +0 -206
- package/dist/core/repo-map/build.js +0 -125
- package/dist/core/repo-map/cache.js +0 -185
- package/dist/core/repo-map/extractor.js +0 -254
- package/dist/core/repo-map/formatter.js +0 -145
- package/dist/core/repo-map/page-rank.js +0 -105
- package/dist/core/repo-map/scanner.js +0 -211
- package/dist/core/retro/git-collector.js +0 -251
- package/dist/core/retro/health-card.js +0 -25
- package/dist/core/retro/metrics.js +0 -342
- package/dist/core/retro/narrative.js +0 -249
- package/dist/core/retro/plane-collector.js +0 -274
- package/dist/core/retro/pr-issue-link.js +0 -65
- package/dist/core/retro/types.js +0 -16
- package/dist/core/retry-budget/budget.js +0 -284
- package/dist/core/retry-budget/index.js +0 -5
- package/dist/core/retry-budget/retry-cap.js +0 -74
- package/dist/core/routing/lead-worker.js +0 -43
- package/dist/core/routing/pre-flight-estimator.js +0 -108
- package/dist/core/runs/run-tree.js +0 -103
- package/dist/core/sandboxing/adapter.js +0 -29
- package/dist/core/sandboxing/index.js +0 -49
- package/dist/core/sandboxing/none.js +0 -19
- package/dist/core/sandboxing/seatbelt.js +0 -183
- package/dist/core/security/injection-scanner.js +0 -367
- package/dist/core/security/output-filter.js +0 -418
- package/dist/core/session/env-file.js +0 -105
- package/dist/core/session/section-budgets.js +0 -140
- package/dist/core/session.js +0 -377
- package/dist/core/settings.js +0 -400
- package/dist/core/share/formatter.js +0 -271
- package/dist/core/share/redactor.js +0 -221
- package/dist/core/share/uploader.js +0 -267
- package/dist/core/skills/defaults.js +0 -457
- package/dist/core/skills/loader.js +0 -454
- package/dist/core/skills/sources.js +0 -480
- package/dist/core/skills/trust.js +0 -172
- package/dist/core/smoke/headless-driver.js +0 -174
- package/dist/core/smoke/orchestrator.js +0 -194
- package/dist/core/smoke/runner.js +0 -238
- package/dist/core/smoke/scenario-parser.js +0 -316
- package/dist/core/statusline.js +0 -99
- package/dist/core/subagents/dispatcher-real.js +0 -600
- package/dist/core/subagents/dispatcher.js +0 -352
- package/dist/core/subagents/index.js +0 -39
- package/dist/core/subagents/isolation-matrix.js +0 -213
- package/dist/core/subagents/spawn.js +0 -101
- package/dist/core/telemetry/emitter.js +0 -229
- package/dist/core/telemetry/queue.js +0 -251
- package/dist/core/theme/context.js +0 -91
- package/dist/core/theme/presets.js +0 -228
- package/dist/core/theme/state.js +0 -181
- package/dist/core/todos/invariant.js +0 -10
- package/dist/core/todos/state.js +0 -177
- package/dist/core/tool-schema/compressor.js +0 -89
- package/dist/core/transport/version-interceptor.js +0 -166
- package/dist/core/trust.js +0 -109
- package/dist/core/tui/thinking-block.js +0 -64
- package/dist/core/vim/keymap.js +0 -288
- package/dist/core/vim/state.js +0 -92
- package/dist/core/watch-markers/marker-watcher.js +0 -133
- package/dist/core/worktree/include-parser.js +0 -249
- package/dist/core/worktree-manager/cleanup.js +0 -123
- package/dist/core/worktree-manager/manager.js +0 -303
- package/dist/index.js +0 -44
- package/dist/runtime/bootstrap.js +0 -190
- package/dist/runtime/cli.js +0 -8121
- package/dist/runtime/commands/agents.js +0 -385
- package/dist/runtime/commands/budget.js +0 -192
- package/dist/runtime/commands/cancel.js +0 -231
- package/dist/runtime/commands/chain.js +0 -489
- package/dist/runtime/commands/codegraph-status.js +0 -227
- package/dist/runtime/commands/compact.js +0 -297
- package/dist/runtime/commands/config.js +0 -595
- package/dist/runtime/commands/cost.js +0 -199
- package/dist/runtime/commands/delegate.js +0 -312
- package/dist/runtime/commands/dispatch.js +0 -126
- package/dist/runtime/commands/doctor.js +0 -579
- package/dist/runtime/commands/feedback.js +0 -184
- package/dist/runtime/commands/hooks.js +0 -187
- package/dist/runtime/commands/init.js +0 -254
- package/dist/runtime/commands/lsp.js +0 -368
- package/dist/runtime/commands/mcp.js +0 -935
- package/dist/runtime/commands/memory.js +0 -582
- package/dist/runtime/commands/model.js +0 -237
- package/dist/runtime/commands/onboarding.js +0 -275
- package/dist/runtime/commands/patch.js +0 -128
- package/dist/runtime/commands/permissions.js +0 -112
- package/dist/runtime/commands/plan.js +0 -143
- package/dist/runtime/commands/prd-check.js +0 -285
- package/dist/runtime/commands/privacy.js +0 -107
- package/dist/runtime/commands/recipe.js +0 -325
- package/dist/runtime/commands/redo-blob-store.js +0 -92
- package/dist/runtime/commands/redo.js +0 -361
- package/dist/runtime/commands/release-notes.js +0 -229
- package/dist/runtime/commands/repo-map.js +0 -95
- package/dist/runtime/commands/report.js +0 -299
- package/dist/runtime/commands/resume.js +0 -118
- package/dist/runtime/commands/review-consensus.js +0 -414
- package/dist/runtime/commands/rewind.js +0 -333
- package/dist/runtime/commands/roster.js +0 -117
- package/dist/runtime/commands/sessions.js +0 -163
- package/dist/runtime/commands/share.js +0 -316
- package/dist/runtime/commands/skills.js +0 -401
- package/dist/runtime/commands/status.js +0 -186
- package/dist/runtime/commands/stickers.js +0 -82
- package/dist/runtime/commands/style.js +0 -194
- package/dist/runtime/commands/theme.js +0 -196
- package/dist/runtime/commands/undo.js +0 -361
- package/dist/runtime/commands/update.js +0 -289
- package/dist/runtime/commands/vim.js +0 -140
- package/dist/runtime/commands/worktree.js +0 -177
- package/dist/runtime/commands/worktrees.js +0 -155
- package/dist/runtime/deprecation-warning.js +0 -69
- package/dist/runtime/engine-exit-code.js +0 -50
- package/dist/runtime/headless-repl.js +0 -195
- package/dist/runtime/headless.js +0 -548
- package/dist/runtime/load-hooks-or-exit.js +0 -71
- package/dist/runtime/plan-decompose.js +0 -531
- package/dist/runtime/sigint-guard.js +0 -272
- package/dist/runtime/stream-renderer.js +0 -195
- package/dist/runtime/update-check.js +0 -294
- package/dist/runtime/version.js +0 -65
- package/dist/runtime/worktree-bootstrap.js +0 -579
- package/dist/skills/bundled/batch.js +0 -617
- package/dist/skills/bundled/index.js +0 -45
- package/dist/skills/bundled/loop.js +0 -358
- package/dist/skills/bundled/remember.js +0 -383
- package/dist/skills/bundled/simplify.js +0 -289
- package/dist/skills/bundled/skillify.js +0 -373
- package/dist/skills/bundled/stuck.js +0 -558
- package/dist/skills/bundled/verify.js +0 -439
- package/dist/testing/vcr.js +0 -486
- package/dist/tools/agent-tool.js +0 -229
- package/dist/tools/apply-patch.js +0 -556
- package/dist/tools/ask-user-question.js +0 -337
- package/dist/tools/ask-user.js +0 -115
- package/dist/tools/bash.js +0 -1238
- package/dist/tools/brief.js +0 -224
- package/dist/tools/cron.js +0 -433
- package/dist/tools/enter-worktree.js +0 -250
- package/dist/tools/exit-worktree.js +0 -147
- package/dist/tools/file-tools.js +0 -553
- package/dist/tools/http-request.js +0 -336
- package/dist/tools/lsp-tools.js +0 -565
- package/dist/tools/mcp-tool.js +0 -260
- package/dist/tools/multi-edit.js +0 -361
- package/dist/tools/powershell.js +0 -268
- package/dist/tools/registry.js +0 -166
- package/dist/tools/server-tools.js +0 -892
- package/dist/tools/skill-tool.js +0 -96
- package/dist/tools/sleep.js +0 -99
- package/dist/tools/synthetic-output.js +0 -133
- package/dist/tools/tasks.js +0 -208
- package/dist/tools/todo-write.js +0 -184
- package/dist/tools/verify-plan-execution.js +0 -295
- package/dist/tools/web-fetch-injection-scanner.js +0 -207
- package/dist/tools/web-fetch.js +0 -720
- package/dist/tools/web-search.js +0 -458
- package/dist/tui/agent-progress-card.js +0 -111
- package/dist/tui/agent-tree-pane.js +0 -9
- package/dist/tui/agent-tree.js +0 -87
- package/dist/tui/ask-cli.js +0 -52
- package/dist/tui/ask-modal.js +0 -211
- package/dist/tui/ask-user-question-chips.js +0 -315
- package/dist/tui/ask-user-question-prompt.js +0 -203
- package/dist/tui/compact-banner.js +0 -81
- package/dist/tui/conversation-pane.js +0 -164
- package/dist/tui/cost-table.js +0 -111
- package/dist/tui/device-flow.js +0 -142
- package/dist/tui/doctor-table.js +0 -46
- package/dist/tui/feedback-prompt.js +0 -156
- package/dist/tui/input-box.js +0 -732
- package/dist/tui/login-picker.js +0 -69
- package/dist/tui/markdown-render.js +0 -266
- package/dist/tui/multi-file-diff-approval.js +0 -375
- package/dist/tui/onboarding-wizard.js +0 -240
- package/dist/tui/permissions-picker.js +0 -86
- package/dist/tui/render.js +0 -160
- package/dist/tui/repl-render.js +0 -770
- package/dist/tui/repl-splash-art.js +0 -64
- package/dist/tui/repl-splash-mascot.js +0 -154
- package/dist/tui/repl-splash.js +0 -117
- package/dist/tui/repl.js +0 -378
- package/dist/tui/slash-palette.js +0 -106
- package/dist/tui/splash-data.js +0 -61
- package/dist/tui/splash.js +0 -31
- package/dist/tui/status-bar.js +0 -209
- package/dist/tui/status-table.js +0 -7
- package/dist/tui/stickers-art.js +0 -136
- package/dist/tui/style-table.js +0 -28
- package/dist/tui/theme-table.js +0 -29
- package/dist/tui/thinking-spinner.js +0 -123
- package/dist/tui/tool-stream-pane.js +0 -140
- package/dist/tui/update-banner.js +0 -33
- package/dist/tui/vim-input.js +0 -267
- package/dist/tui/welcome-banner.js +0 -107
- package/dist/tui/welcome-data.js +0 -293
- package/dist/tui/workspace-context.js +0 -105
- package/docs/examples/codegraph.mcp.json +0 -10
- package/test/scenarios/codegen-create-file.scenario.txt +0 -13
- package/test/scenarios/compact-force.scenario.txt +0 -12
- package/test/scenarios/identity.scenario.txt +0 -11
- package/test/scenarios/persona-handoff.scenario.txt +0 -12
- package/test/scenarios/walkback.scenario.txt +0 -12
|
@@ -1,747 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* REPL slash command registry - Sprint , expanded wave 2.
|
|
3
|
-
*
|
|
4
|
-
* The REPL input box surfaces a palette of slash commands the operator
|
|
5
|
-
* can run from inside a persistent session. The wave-2 expansion (CEO
|
|
6
|
-
*) grows the surface from 6 to 20 commands so the `/help`
|
|
7
|
-
* overlay matches the breadth the upstream tool / peer CLI operators expect.
|
|
8
|
-
*
|
|
9
|
-
* The registry is pure: each `parseSlashCommand` call returns a
|
|
10
|
-
* `SlashCommandResult` describing what the REPL session should do next.
|
|
11
|
-
* The session module owns the side effects (network calls, dispatcher
|
|
12
|
-
* invocation, exit, transcript clear). Keeping the surface pure lets
|
|
13
|
-
* the unit test exercise every shape without standing up an Ink runtime
|
|
14
|
-
* or an Anvil endpoint.
|
|
15
|
-
*
|
|
16
|
-
* Tiering (per CEO wave-2 spec):
|
|
17
|
-
*
|
|
18
|
-
* Tier 1 - wired against real state (3 + existing 6 = 9 wired):
|
|
19
|
-
* brief, agents, stop, help, quit, web, clear, version, jobs.
|
|
20
|
-
*
|
|
21
|
-
* Tier 2 - best-effort wiring against existing surfaces (3):
|
|
22
|
-
* diff, cost, status.
|
|
23
|
-
*
|
|
24
|
-
* Tier 3 - deterministic stubs ("coming in αX.Y") (8):
|
|
25
|
-
* compact, resume, memory, config, privacy, budget, mcp, undo.
|
|
26
|
-
*
|
|
27
|
-
* Brand voice (brandbook §08): power words `brief / dispatch / stop /
|
|
28
|
-
* agents / quit / shipped`. Tagline `Brief it. It ships.` reserved for
|
|
29
|
-
* `/quit` confirmation and `/help` footer - never inline.
|
|
30
|
-
*/
|
|
31
|
-
import { listRoles } from '../agents/registry.js';
|
|
32
|
-
import { PERMISSION_MODES, parsePermissionMode, } from '../permissions/index.js';
|
|
33
|
-
/**
|
|
34
|
-
* Deterministic stub copy returned by the Tier 3 commands. Spec'd
|
|
35
|
-
* inline so the unit test can pin the exact text without poking at
|
|
36
|
-
* the help overlay. The version tag at the end maps to the sprint we
|
|
37
|
-
* intend to land the real wiring in. Keyed by StubSlashCommandName
|
|
38
|
-
* (not the full SlashCommandName union) so wired commands cannot
|
|
39
|
-
* silently appear here with empty placeholders.
|
|
40
|
-
*/
|
|
41
|
-
export const SLASH_STUB_MESSAGES = Object.freeze({
|
|
42
|
-
// /compact graduated from stub. The session
|
|
43
|
-
// module now owns the summariser round-trip + boundary marker append
|
|
44
|
-
// via `dispatchCompact`. Keep the type record exhaustive so a future
|
|
45
|
-
// stub addition cannot silently overlap the wired set.
|
|
46
|
-
memory: 'Session memory editor lands in .',
|
|
47
|
-
config: 'Run `pugi config list` from a fresh shell for the full surface; in-REPL editor lands in .',
|
|
48
|
-
// alpha 6.13: /privacy graduated from stub; nothing reads this at
|
|
49
|
-
// runtime but the type record stays exhaustive.
|
|
50
|
-
privacy: '',
|
|
51
|
-
budget: 'Run `pugi budget` from a fresh shell; in-REPL summary lands in .',
|
|
52
|
-
// β4 Sl7 : /mcp graduated from stub to a real handler
|
|
53
|
-
// that forwards to `runMcpCommand`. Stub message removed from the
|
|
54
|
-
// exhaustive record so the type narrows correctly.
|
|
55
|
-
//
|
|
56
|
-
// final : /undo graduated from stub to a real
|
|
57
|
-
// handler that forwards to `runUndoCommand` (Aider walk-back —
|
|
58
|
-
// single-step revert of the last mutating tool result, with
|
|
59
|
-
// mtime+hash external-modification gate). Stub message removed.
|
|
60
|
-
});
|
|
61
|
-
export const SLASH_COMMAND_HELP = Object.freeze([
|
|
62
|
-
// Workforce dispatch
|
|
63
|
-
{ name: 'brief', args: '<text>', gloss: 'Dispatch a brief to the workforce', group: 'Workforce dispatch' },
|
|
64
|
-
{ name: 'agents', args: '', gloss: 'List the on-watch agent roster', group: 'Workforce dispatch' },
|
|
65
|
-
{ name: 'delegate', args: '<slug> <brief>', gloss: 'Dispatch a brief to one Tier 1 specialist ', group: 'Workforce dispatch' },
|
|
66
|
-
{ name: 'stop', args: '<persona>', gloss: 'Stop one agent by persona slug', group: 'Workforce dispatch' },
|
|
67
|
-
{ name: 'jobs', args: '[--watch]', gloss: 'List background jobs + agent-progress; --watch mounts the live Ink TUI', group: 'Workforce dispatch' },
|
|
68
|
-
{ name: 'cancel', args: '[<id> | all]', gloss: 'Halt active dispatch by id ', group: 'Workforce dispatch' },
|
|
69
|
-
{ name: 'ask', args: '<question>', gloss: 'Surface a yes/no modal locally ', group: 'Workforce dispatch' },
|
|
70
|
-
// Session
|
|
71
|
-
{ name: 'clear', args: '', gloss: 'Clear conversation pane', group: 'Session' },
|
|
72
|
-
{ name: 'resume', args: '', gloss: 'Pick a stored session to restore', group: 'Session' },
|
|
73
|
-
{ name: 'context', args: '', gloss: 'Show three-tier context summary (Tier 0 skeleton + Tier 1 working set)', group: 'Session' },
|
|
74
|
-
{ name: 'compact', args: '[--force]', gloss: 'Summarise older turns into a boundary marker . --force bypasses the noop-empty guard', group: 'Session' },
|
|
75
|
-
{ name: 'rewind', args: '[N | --to <id>]', gloss: 'Roll the conversation back to a checkpoint ', group: 'Session' },
|
|
76
|
-
{ name: 'memory', args: '', gloss: 'Session memory editor ', group: 'Session', stub: true },
|
|
77
|
-
{ name: 'init', args: '', gloss: 'Scaffold .pugi/ in the current workspace (β1 Sl11)', group: 'Session' },
|
|
78
|
-
// Pugi tools
|
|
79
|
-
{ name: 'web', args: '<url>', gloss: 'Fetch a URL into context', group: 'Pugi tools' },
|
|
80
|
-
{ name: 'diff', args: '', gloss: 'Show pending diff', group: 'Pugi tools' },
|
|
81
|
-
{ name: 'cost', args: '', gloss: 'Session token + USD totals + last 5 turn breakdown', group: 'Pugi tools' },
|
|
82
|
-
{ name: 'quota', args: '', gloss: 'Plan tier + monthly usage caps (sync / review / engine)', group: 'Pugi tools' },
|
|
83
|
-
{ name: 'status', args: '', gloss: 'Session snapshot — id · cwd · mode · tokens · dispatches · auth', group: 'Pugi tools' },
|
|
84
|
-
{ name: 'consensus', args: '[ref]', gloss: '3-model consensus review (codex · claude · deepseek)', group: 'Pugi tools' },
|
|
85
|
-
{ name: 'repo-map', args: '[refresh]', gloss: 'AST-light symbol summary of the workspace ', group: 'Pugi tools' },
|
|
86
|
-
{ name: 'codegraph-status', args: '[--install|--reindex|--offer]', gloss: 'Codegraph MCP — install state, index age, symbol count, refresh CTA ', group: 'Pugi tools' },
|
|
87
|
-
// Settings
|
|
88
|
-
{ name: 'config', args: '', gloss: 'Show config', group: 'Settings', stub: true },
|
|
89
|
-
{ name: 'privacy', args: '', gloss: 'Show privacy mode + contract', group: 'Settings' },
|
|
90
|
-
{ name: 'permissions', args: '[mode] [--persist]', gloss: 'Show or flip permission mode (default / acceptEdits / plan / auto / dontAsk / bypassPermissions) (also: /plan, Shift+Tab cycle)', group: 'Settings' },
|
|
91
|
-
{ name: 'plan', args: '[--back | --persist] [<prompt>]', gloss: 'Switch to plan mode (read-only). Same as /permissions plan, slicker UX.', group: 'Settings' },
|
|
92
|
-
{ name: 'model', args: '[<slug>]', gloss: 'Show or select the active model. Bare /model lists tier-gated options', group: 'Settings' },
|
|
93
|
-
{ name: 'budget', args: '', gloss: 'Show usage budget', group: 'Settings', stub: true },
|
|
94
|
-
{ name: 'mcp', args: '[sub]', gloss: 'MCP servers — list / trust / deny / install / serve / perms', group: 'Settings' },
|
|
95
|
-
{ name: 'style', args: '[name] [--persist|--reset|--list]', gloss: 'Output-style preset (default / terse / explanatory / russian-formal / casual)', group: 'Settings' },
|
|
96
|
-
{ name: 'theme', args: '[name] [--persist|--reset|--list]', gloss: 'TUI color palette (default / dark / light / colorblind)', group: 'Settings' },
|
|
97
|
-
{ name: 'onboarding', args: '[--reset|--non-interactive]', gloss: 'First-run wizard — auth / mode / style / MCP / telemetry ', group: 'Settings' },
|
|
98
|
-
{ name: 'vim', args: '[on|off|status]', gloss: 'Toggle vim-style modal editing in the input buffer ', group: 'Settings' },
|
|
99
|
-
{ name: 'undo', args: '', gloss: 'Revert the last successful write / edit / multi_edit (Aider walk-back, )', group: 'Settings' },
|
|
100
|
-
{ name: 'redo', args: '', gloss: 'Reapply the most recent /undo (LIFO stack, cleanup)', group: 'Settings' },
|
|
101
|
-
// Meta
|
|
102
|
-
{ name: 'help', args: '', gloss: 'Show this help overlay', group: 'Meta' },
|
|
103
|
-
{ name: 'version', args: '', gloss: 'Show CLI version', group: 'Meta' },
|
|
104
|
-
{ name: 'doctor', args: '', gloss: 'Environment health report (auth · API · Node · disk · MCP · …)', group: 'Meta' },
|
|
105
|
-
{ name: 'prd-check', args: '<prd-path | --all | --session> [--json]', gloss: 'Verify PRD against code (default) or session work (--session, final)', group: 'Meta' },
|
|
106
|
-
{ name: 'chain', args: '<new|status|next|show|export|list> [...args]', gloss: 'Artifact chain — PRD → ADR → mindmap → ER → sequence → tests → code ', group: 'Meta' },
|
|
107
|
-
{ name: 'stickers', args: '', gloss: 'show Pugi brand stickers (gimmick)', group: 'Meta' },
|
|
108
|
-
{ name: 'feedback', args: '', gloss: 'file a bug / feature / general comment without leaving the REPL', group: 'Meta' },
|
|
109
|
-
{ name: 'share', args: '[--gist|--pugi] [--redact] [--preview]', gloss: 'Export session transcript to gist / pugi.io ', group: 'Meta' },
|
|
110
|
-
{ name: 'release-notes', args: '[--reset]', gloss: 'Show changelog diff since last upgrade ', group: 'Meta' },
|
|
111
|
-
{ name: 'update', args: '[--check|--apply [--yes]] [--channel <name>]', gloss: 'Check for / apply CLI update on stable / beta / canary ', group: 'Meta' },
|
|
112
|
-
{ name: 'quit', args: '', gloss: 'Exit the REPL', group: 'Meta' },
|
|
113
|
-
]);
|
|
114
|
-
/**
|
|
115
|
-
* Ordered list of groups. Drives the `/help` overlay sectioning so the
|
|
116
|
-
* operator reads commands by intent (dispatch first, meta last).
|
|
117
|
-
*/
|
|
118
|
-
export const SLASH_COMMAND_GROUPS = Object.freeze([
|
|
119
|
-
'Workforce dispatch',
|
|
120
|
-
'Session',
|
|
121
|
-
'Pugi tools',
|
|
122
|
-
'Settings',
|
|
123
|
-
'Meta',
|
|
124
|
-
]);
|
|
125
|
-
/**
|
|
126
|
-
* Parse one line of input from the REPL. The contract:
|
|
127
|
-
*
|
|
128
|
-
* - Empty / whitespace-only input returns `noop` with the original
|
|
129
|
-
* text so the REPL can ignore it without printing anything.
|
|
130
|
-
* - Input that does not start with `/` is treated as an implicit
|
|
131
|
-
* `/brief <text>` - the most-common operator action.
|
|
132
|
-
* - `/<name> [args]` resolves the name against the registry; unknown
|
|
133
|
-
* names return `error` so the REPL can render a one-line tip
|
|
134
|
-
* instead of silently dropping the input.
|
|
135
|
-
* - Tier 3 stubs return `{ kind: 'stub', name, message }` so the REPL
|
|
136
|
-
* can render the deterministic "coming in αX.Y" copy uniformly.
|
|
137
|
-
*
|
|
138
|
-
* The function never throws. Bad input maps to a structured result the
|
|
139
|
-
* REPL can render - the alternative (throwing from a keystroke handler)
|
|
140
|
-
* would unmount Ink mid-frame.
|
|
141
|
-
*/
|
|
142
|
-
/**
|
|
143
|
-
* Pugi backlog : parse the artifact-store subcommands
|
|
144
|
-
* of `/plan`. Kept module-local because the legacy mode-toggle parser
|
|
145
|
-
* already owns the `case 'plan':` branch — this helper is the
|
|
146
|
-
* dispatch tail when the first arg is `show / list / diff / prune`.
|
|
147
|
-
*
|
|
148
|
-
* Argument grammar:
|
|
149
|
-
* /plan show <planId>
|
|
150
|
-
* /plan list [<taskId>]
|
|
151
|
-
* /plan diff <planId> [<otherId>]
|
|
152
|
-
* /plan prune [<maxAgeDays>]
|
|
153
|
-
*
|
|
154
|
-
* Validation:
|
|
155
|
-
* - `planId` is required for show + diff; surfaced as a structured
|
|
156
|
-
* error verdict when missing so the REPL renders one line of
|
|
157
|
-
* guidance instead of falling through to the mode-toggle path.
|
|
158
|
-
* - `maxAgeDays` is parsed as a positive integer; missing leaves the
|
|
159
|
-
* core module's default in place. Negative / NaN inputs become
|
|
160
|
-
* errors so the operator does not silently wipe their plan store.
|
|
161
|
-
*/
|
|
162
|
-
function parsePlanArtifactSubcommand(op, rest) {
|
|
163
|
-
if (op === 'show') {
|
|
164
|
-
const planId = rest[0];
|
|
165
|
-
if (!planId) {
|
|
166
|
-
return {
|
|
167
|
-
kind: 'error',
|
|
168
|
-
message: '/plan show <plan-id> — plan-id is required.',
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
return { kind: 'plan-artifact', sub: { op: 'show', planId } };
|
|
172
|
-
}
|
|
173
|
-
if (op === 'list') {
|
|
174
|
-
const taskId = rest[0];
|
|
175
|
-
return {
|
|
176
|
-
kind: 'plan-artifact',
|
|
177
|
-
sub: taskId ? { op: 'list', taskId } : { op: 'list' },
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
if (op === 'diff') {
|
|
181
|
-
const planId = rest[0];
|
|
182
|
-
if (!planId) {
|
|
183
|
-
return {
|
|
184
|
-
kind: 'error',
|
|
185
|
-
message: '/plan diff <plan-id> [<other-id>] — plan-id is required.',
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
const otherId = rest[1];
|
|
189
|
-
return {
|
|
190
|
-
kind: 'plan-artifact',
|
|
191
|
-
sub: otherId
|
|
192
|
-
? { op: 'diff', planId, otherId }
|
|
193
|
-
: { op: 'diff', planId },
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
// prune
|
|
197
|
-
const raw = rest[0];
|
|
198
|
-
if (raw === undefined) {
|
|
199
|
-
return { kind: 'plan-artifact', sub: { op: 'prune' } };
|
|
200
|
-
}
|
|
201
|
-
const parsed = Number(raw);
|
|
202
|
-
if (!Number.isFinite(parsed) || parsed <= 0 || !Number.isInteger(parsed)) {
|
|
203
|
-
return {
|
|
204
|
-
kind: 'error',
|
|
205
|
-
message: `/plan prune [<days>] — expected positive integer, got '${raw}'.`,
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
return { kind: 'plan-artifact', sub: { op: 'prune', maxAgeDays: parsed } };
|
|
209
|
-
}
|
|
210
|
-
export function parseSlashCommand(input) {
|
|
211
|
-
const trimmed = input.trim();
|
|
212
|
-
if (trimmed.length === 0) {
|
|
213
|
-
return { kind: 'noop', text: '' };
|
|
214
|
-
}
|
|
215
|
-
if (!trimmed.startsWith('/')) {
|
|
216
|
-
return { kind: 'dispatch', brief: trimmed };
|
|
217
|
-
}
|
|
218
|
-
// `/` with no name → render help overlay so the operator discovers
|
|
219
|
-
// the command palette without typing `/help`.
|
|
220
|
-
if (trimmed === '/') {
|
|
221
|
-
return { kind: 'help' };
|
|
222
|
-
}
|
|
223
|
-
const space = trimmed.indexOf(' ');
|
|
224
|
-
const head = space === -1 ? trimmed.slice(1) : trimmed.slice(1, space);
|
|
225
|
-
const tail = space === -1 ? '' : trimmed.slice(space + 1).trim();
|
|
226
|
-
const name = head.toLowerCase();
|
|
227
|
-
switch (name) {
|
|
228
|
-
case 'brief': {
|
|
229
|
-
if (tail.length === 0) {
|
|
230
|
-
return { kind: 'error', message: 'Usage: /brief <text>' };
|
|
231
|
-
}
|
|
232
|
-
return { kind: 'dispatch', brief: tail };
|
|
233
|
-
}
|
|
234
|
-
case 'agents':
|
|
235
|
-
case 'agent':
|
|
236
|
-
case 'roster': {
|
|
237
|
-
return { kind: 'roster' };
|
|
238
|
-
}
|
|
239
|
-
case 'delegate': {
|
|
240
|
-
// tail must start with the persona slug followed by the brief.
|
|
241
|
-
// Slug accepts only the closed-set lowercase ASCII pattern the
|
|
242
|
-
// server-side persona registry enforces; anything else surfaces
|
|
243
|
-
// as a usage error so the operator sees the typo before the
|
|
244
|
-
// round-trip.
|
|
245
|
-
const innerSpace = tail.indexOf(' ');
|
|
246
|
-
if (innerSpace === -1 || innerSpace === 0) {
|
|
247
|
-
return {
|
|
248
|
-
kind: 'error',
|
|
249
|
-
message: 'Usage: /delegate <slug> <one-sentence brief>',
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
const persona = tail.slice(0, innerSpace).toLowerCase();
|
|
253
|
-
const brief = tail.slice(innerSpace + 1).trim();
|
|
254
|
-
// Pattern intentionally mirrors server-side PUGI_DELEGATE_REGEX in
|
|
255
|
-
// sessions.controller.ts (^[a-z]+$). Keeping them lockstep means
|
|
256
|
-
// the REPL surfaces typos locally instead of round-tripping a 4xx.
|
|
257
|
-
if (!/^[a-z]+$/.test(persona)) {
|
|
258
|
-
return {
|
|
259
|
-
kind: 'error',
|
|
260
|
-
message: `/delegate slug must be lowercase ASCII (a-z only); got '${persona}'`,
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
if (brief.length === 0) {
|
|
264
|
-
return {
|
|
265
|
-
kind: 'error',
|
|
266
|
-
message: 'Usage: /delegate <slug> <one-sentence brief>',
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
return { kind: 'delegate', persona, brief };
|
|
270
|
-
}
|
|
271
|
-
case 'stop':
|
|
272
|
-
case 'kill': {
|
|
273
|
-
if (tail.length === 0) {
|
|
274
|
-
return {
|
|
275
|
-
kind: 'error',
|
|
276
|
-
message: `Usage: /stop <persona> (try one of: ${listRoles().join(', ')})`,
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
return { kind: 'stop', persona: tail.toLowerCase() };
|
|
280
|
-
}
|
|
281
|
-
case 'help':
|
|
282
|
-
case '?': {
|
|
283
|
-
return { kind: 'help' };
|
|
284
|
-
}
|
|
285
|
-
case 'quit':
|
|
286
|
-
case 'exit':
|
|
287
|
-
case 'q': {
|
|
288
|
-
return { kind: 'quit' };
|
|
289
|
-
}
|
|
290
|
-
case 'web':
|
|
291
|
-
case 'fetch': {
|
|
292
|
-
if (tail.length === 0) {
|
|
293
|
-
return { kind: 'error', message: 'Usage: /web <url>' };
|
|
294
|
-
}
|
|
295
|
-
return { kind: 'web', url: tail };
|
|
296
|
-
}
|
|
297
|
-
case 'clear':
|
|
298
|
-
case 'cls': {
|
|
299
|
-
return { kind: 'clear' };
|
|
300
|
-
}
|
|
301
|
-
case 'version':
|
|
302
|
-
case 'v': {
|
|
303
|
-
return { kind: 'version' };
|
|
304
|
-
}
|
|
305
|
-
case 'jobs': {
|
|
306
|
-
// cleanup : tokenise the tail so the slash
|
|
307
|
-
// can route `--watch` к the live Ink TUI (same renderer as
|
|
308
|
-
// `pugi jobs --watch`). Unknown tokens fall through silently —
|
|
309
|
-
// the slash surface is intentionally minimal vs. the shell
|
|
310
|
-
// command (which supports list/status/tail/kill subcommands
|
|
311
|
-
// through `runJobsCommand`).
|
|
312
|
-
const tokens = tail.length === 0 ? [] : tail.split(/\s+/).filter((s) => s.length > 0);
|
|
313
|
-
const watch = tokens.includes('--watch') || tokens.includes('-w') || tokens[0] === 'watch';
|
|
314
|
-
return { kind: 'jobs', watch };
|
|
315
|
-
}
|
|
316
|
-
case 'cancel':
|
|
317
|
-
case 'halt': {
|
|
318
|
-
// small-CC-parity batch :
|
|
319
|
-
//
|
|
320
|
-
// /cancel -> list active dispatches
|
|
321
|
-
// /cancel all -> halt every running dispatch
|
|
322
|
-
// /cancel <id> -> halt one (id may be a prefix; runner
|
|
323
|
-
// does startsWith lookup)
|
|
324
|
-
//
|
|
325
|
-
// The `halt` alias matches operator muscle memory from systemd /
|
|
326
|
-
// brand voice (`stop` is already taken by /stop <persona>; cancel
|
|
327
|
-
// is dispatch-id-keyed, stop is persona-keyed). Unknown extra
|
|
328
|
-
// tokens are tolerated — the runner reads only the first.
|
|
329
|
-
const trimmedTail = tail.trim();
|
|
330
|
-
if (trimmedTail.length === 0) {
|
|
331
|
-
return { kind: 'cancel', mode: 'list', dispatchId: '' };
|
|
332
|
-
}
|
|
333
|
-
const firstToken = trimmedTail.split(/\s+/)[0].toLowerCase();
|
|
334
|
-
if (firstToken === 'all' || firstToken === '*') {
|
|
335
|
-
return { kind: 'cancel', mode: 'all', dispatchId: 'all' };
|
|
336
|
-
}
|
|
337
|
-
// Defensive: dispatch ids are filename-safe per the
|
|
338
|
-
// `validateAgentProgress` agentId regex (`[a-zA-Z0-9_-]+`).
|
|
339
|
-
// Reject anything outside that range with a usage tip so the
|
|
340
|
-
// operator sees the typo before the round-trip.
|
|
341
|
-
if (!/^[A-Za-z0-9_-]+$/.test(firstToken)) {
|
|
342
|
-
return {
|
|
343
|
-
kind: 'error',
|
|
344
|
-
message: `/cancel: invalid dispatch id '${firstToken}'. Use letters / digits / '-' / '_' only.`,
|
|
345
|
-
};
|
|
346
|
-
}
|
|
347
|
-
return { kind: 'cancel', mode: 'one', dispatchId: firstToken };
|
|
348
|
-
}
|
|
349
|
-
case 'ask': {
|
|
350
|
-
if (tail.length === 0) {
|
|
351
|
-
return { kind: 'error', message: 'Usage: /ask <question>' };
|
|
352
|
-
}
|
|
353
|
-
return { kind: 'ask', question: tail };
|
|
354
|
-
}
|
|
355
|
-
case 'diff': {
|
|
356
|
-
return { kind: 'diff' };
|
|
357
|
-
}
|
|
358
|
-
case 'cost':
|
|
359
|
-
case 'usage': {
|
|
360
|
-
// L19 : `/usage` is an alias of `/cost` per the cost-
|
|
361
|
-
// command spec. The previous mapping routed `/usage` to the
|
|
362
|
-
// network-backed `/quota` surface, but operators trained on Claude
|
|
363
|
-
// Code expect `/usage` to surface the per-model token breakdown
|
|
364
|
-
// (same shape as `/cost`). `/quota` remains the canonical name
|
|
365
|
-
// for the tier + monthly-cap fetch.
|
|
366
|
-
return { kind: 'cost' };
|
|
367
|
-
}
|
|
368
|
-
case 'quota': {
|
|
369
|
-
return { kind: 'quota' };
|
|
370
|
-
}
|
|
371
|
-
case 'status': {
|
|
372
|
-
return { kind: 'status' };
|
|
373
|
-
}
|
|
374
|
-
case 'consensus':
|
|
375
|
-
case 'review-consensus': {
|
|
376
|
-
// Optional argument: a ref string forwarded verbatim to the
|
|
377
|
-
// consensus diff-capture (`HEAD~1`, `--pr 123`, etc). Empty tail
|
|
378
|
-
// means "default base ref".
|
|
379
|
-
return { kind: 'consensus', ref: tail };
|
|
380
|
-
}
|
|
381
|
-
case 'resume': {
|
|
382
|
-
// : wired against the local SessionStore. The REPL session
|
|
383
|
-
// owns the picker UI (Ink select over the 10 most recent rows)
|
|
384
|
-
// so the slash-command layer stays UI-agnostic.
|
|
385
|
-
return { kind: 'resume' };
|
|
386
|
-
}
|
|
387
|
-
case 'context':
|
|
388
|
-
case 'ctx': {
|
|
389
|
-
// : surface Tier 0 + Tier 1 status. The session module
|
|
390
|
-
// renders the summary as system lines so the operator can see
|
|
391
|
-
// skeleton size + working-set utilisation at a glance.
|
|
392
|
-
return { kind: 'context' };
|
|
393
|
-
}
|
|
394
|
-
case 'privacy': {
|
|
395
|
-
// alpha 6.13: real handler - the session module prints the
|
|
396
|
-
// contract doc + the current mode banner. Tail is ignored (no
|
|
397
|
-
// sub-commands today; mode flips go through
|
|
398
|
-
// `pugi config set privacy=<mode>` from a fresh shell so the
|
|
399
|
-
// device flow + audit identity are wired correctly).
|
|
400
|
-
return { kind: 'privacy' };
|
|
401
|
-
}
|
|
402
|
-
case 'permissions':
|
|
403
|
-
case 'perms': {
|
|
404
|
-
// : `/permissions [mode] [--persist] [--confirm]`.
|
|
405
|
-
//
|
|
406
|
-
// Argument grammar (single line, no quoting):
|
|
407
|
-
// /permissions -> show + table
|
|
408
|
-
// /permissions default|acceptEdits|plan|auto|dontAsk -> flip mode
|
|
409
|
-
// /permissions bypassPermissions --confirm -> flip to
|
|
410
|
-
// bypassPermissions (refused
|
|
411
|
-
// без --confirm — safety)
|
|
412
|
-
// /permissions <mode> --persist -> also write to ~/.pugi/config.json
|
|
413
|
-
//
|
|
414
|
-
// aliases (`ask`, `allow`, `bypass`) are accepted и mapped to
|
|
415
|
-
// their canonical names via `parsePermissionMode`.
|
|
416
|
-
const tokens = tail.length === 0 ? [] : tail.split(/\s+/).filter((s) => s.length > 0);
|
|
417
|
-
if (tokens.length === 0) {
|
|
418
|
-
return { kind: 'permissions', persist: false, confirmBypass: false };
|
|
419
|
-
}
|
|
420
|
-
const headRaw = tokens[0] ?? '';
|
|
421
|
-
const mode = parsePermissionMode(headRaw);
|
|
422
|
-
if (!mode) {
|
|
423
|
-
const modeList = [...PERMISSION_MODES].join('|');
|
|
424
|
-
return {
|
|
425
|
-
kind: 'error',
|
|
426
|
-
message: `Usage: /permissions [${modeList}] [--persist] [--confirm]; unknown mode '${headRaw}'`,
|
|
427
|
-
};
|
|
428
|
-
}
|
|
429
|
-
const flags = tokens.slice(1);
|
|
430
|
-
let persist = false;
|
|
431
|
-
let confirmBypass = false;
|
|
432
|
-
for (const flag of flags) {
|
|
433
|
-
if (flag === '--persist') {
|
|
434
|
-
persist = true;
|
|
435
|
-
}
|
|
436
|
-
else if (flag === '--confirm') {
|
|
437
|
-
confirmBypass = true;
|
|
438
|
-
}
|
|
439
|
-
else {
|
|
440
|
-
return {
|
|
441
|
-
kind: 'error',
|
|
442
|
-
message: `/permissions: unknown flag '${flag}' (allowed: --persist, --confirm)`,
|
|
443
|
-
};
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
return { kind: 'permissions', mode, persist, confirmBypass };
|
|
447
|
-
}
|
|
448
|
-
case 'init': {
|
|
449
|
-
// β1 Sl11: surface the init flow inside the REPL. Tail args
|
|
450
|
-
// are ignored — the init handler is parameterless today; `pugi
|
|
451
|
-
// init --no-defaults` is the CLI surface for skipping bundled
|
|
452
|
-
// skills.
|
|
453
|
-
return { kind: 'init' };
|
|
454
|
-
}
|
|
455
|
-
case 'plan': {
|
|
456
|
-
// `/plan [--back | --persist] [<prompt>]`.
|
|
457
|
-
//
|
|
458
|
-
// Argument grammar (single line, no quoting):
|
|
459
|
-
// /plan -> enter plan mode + banner
|
|
460
|
-
// /plan --back -> restore previous mode
|
|
461
|
-
// /plan --persist -> enter + write global config
|
|
462
|
-
// /plan <prompt...> -> enter + run one-shot engine
|
|
463
|
-
// /plan --auto-back <prompt...> -> enter + run + restore mode
|
|
464
|
-
//
|
|
465
|
-
// The parser pulls the flags off the head of the tail; whatever
|
|
466
|
-
// remains is the prompt. `--back` + a non-empty prompt and
|
|
467
|
-
// `--back` + `--auto-back` are both refused as `error` because
|
|
468
|
-
// they conflict at the verb level.
|
|
469
|
-
//
|
|
470
|
-
// Pugi backlog : when the FIRST token of the
|
|
471
|
-
// tail is one of the artifact subcommands (`show / list / diff /
|
|
472
|
-
// prune`), the parser hands off to the plan-as-FILE surface
|
|
473
|
-
// instead of the mode-toggle. This keeps both feature sets under
|
|
474
|
-
// one `/plan` namespace without overloading the verb table.
|
|
475
|
-
const tokens = tail.length === 0 ? [] : tail.split(/\s+/).filter((s) => s.length > 0);
|
|
476
|
-
const head = tokens[0];
|
|
477
|
-
if (head === 'show' || head === 'list' || head === 'diff' || head === 'prune') {
|
|
478
|
-
return parsePlanArtifactSubcommand(head, tokens.slice(1));
|
|
479
|
-
}
|
|
480
|
-
let back = false;
|
|
481
|
-
let persist = false;
|
|
482
|
-
let autoBack = false;
|
|
483
|
-
const promptTokens = [];
|
|
484
|
-
for (const token of tokens) {
|
|
485
|
-
if (token === '--back') {
|
|
486
|
-
back = true;
|
|
487
|
-
}
|
|
488
|
-
else if (token === '--persist') {
|
|
489
|
-
persist = true;
|
|
490
|
-
}
|
|
491
|
-
else if (token === '--auto-back') {
|
|
492
|
-
autoBack = true;
|
|
493
|
-
}
|
|
494
|
-
else {
|
|
495
|
-
promptTokens.push(token);
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
const prompt = promptTokens.join(' ');
|
|
499
|
-
if (back && prompt.length > 0) {
|
|
500
|
-
return {
|
|
501
|
-
kind: 'error',
|
|
502
|
-
message: '/plan --back does not accept a prompt; revert first, then dispatch.',
|
|
503
|
-
};
|
|
504
|
-
}
|
|
505
|
-
if (back && autoBack) {
|
|
506
|
-
return {
|
|
507
|
-
kind: 'error',
|
|
508
|
-
message: '/plan --back and --auto-back cannot be combined.',
|
|
509
|
-
};
|
|
510
|
-
}
|
|
511
|
-
return { kind: 'plan', back, persist, autoBack, prompt };
|
|
512
|
-
}
|
|
513
|
-
case 'model': {
|
|
514
|
-
// BT 8 (the upstream tool parity): `/model [<slug>]`. Bare form
|
|
515
|
-
// prints the tier-gated model menu + current selection; with a
|
|
516
|
-
// slug it flips workspace selection. Slug grammar (loose): alnum
|
|
517
|
-
// + dash + dot + slash. Anything outside that range becomes an
|
|
518
|
-
// error verdict so the operator sees a clear message instead of a
|
|
519
|
-
// silent no-op. Whitespace inside the tail = multiple tokens = we
|
|
520
|
-
// take the first; the help gloss documents single-slug usage.
|
|
521
|
-
const trimmedTail = tail.trim();
|
|
522
|
-
if (trimmedTail.length === 0) {
|
|
523
|
-
return { kind: 'model', slug: undefined };
|
|
524
|
-
}
|
|
525
|
-
const firstToken = trimmedTail.split(/\s+/)[0] ?? '';
|
|
526
|
-
if (!/^[A-Za-z0-9][A-Za-z0-9._\-\/]{0,63}$/.test(firstToken)) {
|
|
527
|
-
return {
|
|
528
|
-
kind: 'error',
|
|
529
|
-
message: `/model: invalid slug '${firstToken}'. Use letters / digits / '-' / '.' / '/' only.`,
|
|
530
|
-
};
|
|
531
|
-
}
|
|
532
|
-
return { kind: 'model', slug: firstToken };
|
|
533
|
-
}
|
|
534
|
-
case 'mcp': {
|
|
535
|
-
// β4 Sl7: tokenize the tail. Empty tail -> `list` (matches CLI).
|
|
536
|
-
// Quoting / shell-escapes are NOT supported — the slash surface is
|
|
537
|
-
// intentionally simple; complex installs (env vars, multi-word
|
|
538
|
-
// args) go through `pugi mcp install` from a fresh shell.
|
|
539
|
-
const tokens = tail.length === 0 ? [] : tail.split(/\s+/).filter((s) => s.length > 0);
|
|
540
|
-
return { kind: 'mcp', args: tokens };
|
|
541
|
-
}
|
|
542
|
-
case 'style':
|
|
543
|
-
case 'output-style': {
|
|
544
|
-
// forward the tokenized tail unchanged so
|
|
545
|
-
// the slash + top-level CLI surfaces share one parser inside
|
|
546
|
-
// `runStyleCommand`. Quoting / multi-word args are not used (the
|
|
547
|
-
// preset slugs are single tokens by contract).
|
|
548
|
-
const tokens = tail.length === 0 ? [] : tail.split(/\s+/).filter((s) => s.length > 0);
|
|
549
|
-
return { kind: 'style', args: tokens };
|
|
550
|
-
}
|
|
551
|
-
case 'theme':
|
|
552
|
-
case 'palette':
|
|
553
|
-
case 'colors': {
|
|
554
|
-
// forward the tokenized tail unchanged so
|
|
555
|
-
// the slash + top-level `pugi theme` surfaces share one parser
|
|
556
|
-
// inside `runThemeCommand`. Aliases `/palette` and `/colors`
|
|
557
|
-
// exist because the leak-landscape audit found operators reach
|
|
558
|
-
// for either word interchangeably — same surface, same handler.
|
|
559
|
-
const tokens = tail.length === 0 ? [] : tail.split(/\s+/).filter((s) => s.length > 0);
|
|
560
|
-
return { kind: 'theme', args: tokens };
|
|
561
|
-
}
|
|
562
|
-
case 'onboarding':
|
|
563
|
-
case 'onboard':
|
|
564
|
-
case 'setup': {
|
|
565
|
-
// forward the tokenized tail unchanged.
|
|
566
|
-
// The slash always routes through the non-interactive snapshot
|
|
567
|
-
// path (the REPL already owns the Ink tree); the runner picks
|
|
568
|
-
// it up from `ctx.interactive = false` in the session
|
|
569
|
-
// dispatcher.
|
|
570
|
-
const tokens = tail.length === 0 ? [] : tail.split(/\s+/).filter((s) => s.length > 0);
|
|
571
|
-
return { kind: 'onboarding', args: tokens };
|
|
572
|
-
}
|
|
573
|
-
case 'vim': {
|
|
574
|
-
// forward the tokenized tail unchanged so
|
|
575
|
-
// the slash + top-level CLI surfaces share one parser inside
|
|
576
|
-
// `runVimCommand`. Subcommands are single tokens (on / off /
|
|
577
|
-
// status); a bare `/vim` toggles.
|
|
578
|
-
const tokens = tail.length === 0 ? [] : tail.split(/\s+/).filter((s) => s.length > 0);
|
|
579
|
-
return { kind: 'vim', args: tokens };
|
|
580
|
-
}
|
|
581
|
-
case 'doctor':
|
|
582
|
-
case 'health': {
|
|
583
|
-
// L17 : run the probe sweep inline. Tail is ignored —
|
|
584
|
-
// the doctor command has no operator-facing arguments (every
|
|
585
|
-
// probe runs unconditionally; per-probe disable lives on the CLI
|
|
586
|
-
// shell surface, not the slash one).
|
|
587
|
-
return { kind: 'doctor' };
|
|
588
|
-
}
|
|
589
|
-
case 'prd-check':
|
|
590
|
-
case 'prdcheck': {
|
|
591
|
-
// : tokenise the tail and forward verbatim
|
|
592
|
-
// so the slash + shell surfaces share one `parsePrdCheckArgs`.
|
|
593
|
-
// Supports `<prd-path>`, `--all`, and `--json`.
|
|
594
|
-
const tokens = tail.length === 0 ? [] : tail.split(/\s+/).filter((s) => s.length > 0);
|
|
595
|
-
return { kind: 'prd-check', args: tokens };
|
|
596
|
-
}
|
|
597
|
-
case 'chain': {
|
|
598
|
-
// : forward the tokenized argv to
|
|
599
|
-
// `runChainCommand` via the session module. Subcommands are
|
|
600
|
-
// single tokens (new / status / next / show / export / list);
|
|
601
|
-
// the `new` subcommand accepts the intent as the joined tail so
|
|
602
|
-
// operators can write `/chain new add auth flow` без quoting.
|
|
603
|
-
const tokens = tail.length === 0 ? [] : tail.split(/\s+/).filter((s) => s.length > 0);
|
|
604
|
-
return { kind: 'chain', args: tokens };
|
|
605
|
-
}
|
|
606
|
-
case 'codegraph-status':
|
|
607
|
-
case 'codegraph': {
|
|
608
|
-
// BT 9 Phase 2 : forward the tokenized argv
|
|
609
|
-
// to `runCodegraphStatusCommand`. Flags handled by the runner:
|
|
610
|
-
// --install — merge codegraph into .pugi/mcp.json (accept)
|
|
611
|
-
// --reindex — stamp lastIndexedAt + hint runtime to refresh
|
|
612
|
-
// --offer — surface the install prompt even after a decline
|
|
613
|
-
// `/codegraph` is the short alias; same handler.
|
|
614
|
-
const tokens = tail.length === 0 ? [] : tail.split(/\s+/).filter((s) => s.length > 0);
|
|
615
|
-
return { kind: 'codegraph-status', args: tokens };
|
|
616
|
-
}
|
|
617
|
-
case 'compact': {
|
|
618
|
-
// graduated from stub. The session module
|
|
619
|
-
// owns the summariser round-trip. BT 8: `--force` overrides
|
|
620
|
-
// the noop-empty guard. Unknown flags fall through silently per
|
|
621
|
-
// the existing tail-tolerance behaviour (operators wanting a
|
|
622
|
-
// per-session compact run `pugi compact --session <id>` from a
|
|
623
|
-
// fresh shell).
|
|
624
|
-
const tokens = tail.length === 0 ? [] : tail.split(/\s+/).filter((s) => s.length > 0);
|
|
625
|
-
const force = tokens.some((t) => t === '--force' || t === '-f');
|
|
626
|
-
return { kind: 'compact', force };
|
|
627
|
-
}
|
|
628
|
-
case 'rewind': {
|
|
629
|
-
// `/rewind [N | --to <id>]`. Tokenize the
|
|
630
|
-
// tail unchanged so `runRewindCommand` (in `runtime/commands/
|
|
631
|
-
// rewind.ts`) handles every mode (picker / turns / to-event)
|
|
632
|
-
// through one parser. The slash + top-level CLI surfaces stay
|
|
633
|
-
// single-sourced — same separation as `/compact`.
|
|
634
|
-
const tokens = tail.length === 0 ? [] : tail.split(/\s+/).filter((s) => s.length > 0);
|
|
635
|
-
return { kind: 'rewind', args: tokens };
|
|
636
|
-
}
|
|
637
|
-
case 'stickers': {
|
|
638
|
-
// brand-personality gimmick. Tail args
|
|
639
|
-
// are ignored — the surface is intentionally parameterless. The
|
|
640
|
-
// session module delegates to the shared `runStickersCommand`
|
|
641
|
-
// so the slash + top-level paths stay single-sourced.
|
|
642
|
-
return { kind: 'stickers' };
|
|
643
|
-
}
|
|
644
|
-
case 'feedback': {
|
|
645
|
-
// in-CLI feedback collector. The wizard
|
|
646
|
-
// collects category/rating/comment/context/confirm interactively
|
|
647
|
-
// so the slash surface is parameterless. Tail args are reserved
|
|
648
|
-
// for a future `--message=...` quick-path; today they are
|
|
649
|
-
// accepted but ignored so the operator-level UX matches
|
|
650
|
-
// the upstream tool's `/feedback`.
|
|
651
|
-
return { kind: 'feedback' };
|
|
652
|
-
}
|
|
653
|
-
case 'share': {
|
|
654
|
-
// forward the tokenized arg list verbatim
|
|
655
|
-
// so the session module (which owns the network + readline
|
|
656
|
-
// affordances) can hand them to runShareCommand. Defaults: no
|
|
657
|
-
// tokens means "auto-pick target + prompt for confirmation".
|
|
658
|
-
const tokens = tail.length === 0 ? [] : tail.split(/\s+/).filter((s) => s.length > 0);
|
|
659
|
-
return { kind: 'share', args: tokens };
|
|
660
|
-
}
|
|
661
|
-
case 'repo-map':
|
|
662
|
-
case 'repomap': {
|
|
663
|
-
// build + show the AST-light symbol
|
|
664
|
-
// summary. Accepts `refresh` as a positional или `--refresh`
|
|
665
|
-
// flag so muscle memory from both shells lands the same way.
|
|
666
|
-
const tokens = tail.length === 0 ? [] : tail.split(/\s+/).filter((s) => s.length > 0);
|
|
667
|
-
const refresh = tokens.includes('--refresh') || tokens.includes('refresh') || tokens.includes('-r');
|
|
668
|
-
return { kind: 'repo-map', refresh };
|
|
669
|
-
}
|
|
670
|
-
case 'release-notes':
|
|
671
|
-
case 'releasenotes':
|
|
672
|
-
case 'changelog': {
|
|
673
|
-
// changelog diff between last-seen +
|
|
674
|
-
// installed CLI version. Tail args are tokenized so `--reset`
|
|
675
|
-
// can flip the marker-clear bit; no other flags are honoured —
|
|
676
|
-
// the surface mirrors the CLI top-level's intentional minimalism.
|
|
677
|
-
// `changelog` alias matches operator muscle memory from npm /
|
|
678
|
-
// cargo / brew, all of which ship `changelog` subcommands.
|
|
679
|
-
const tokens = tail.length === 0 ? [] : tail.split(/\s+/).filter((s) => s.length > 0);
|
|
680
|
-
const reset = tokens.includes('--reset') || tokens.includes('-r');
|
|
681
|
-
return { kind: 'release-notes', reset };
|
|
682
|
-
}
|
|
683
|
-
case 'update': {
|
|
684
|
-
// forward the tokenized argv to the
|
|
685
|
-
// session module which delegates to `runUpdateCommand`. The
|
|
686
|
-
// dispatcher owns argv validation (unknown channel / flag) so
|
|
687
|
-
// the slash parser stays as thin as the rest of the surface.
|
|
688
|
-
// The slash form does NOT support `--apply` because spawning
|
|
689
|
-
// `npm install -g` from inside a running REPL session would
|
|
690
|
-
// corrupt the operator's running binary — the dispatcher treats
|
|
691
|
-
// `--apply` from a slash as a non-interactive offer (probe +
|
|
692
|
-
// install command, no shell-out). Top-level `pugi update --apply`
|
|
693
|
-
// remains the recommended path for the actual install.
|
|
694
|
-
const tokens = tail.length === 0 ? [] : tail.split(/\s+/).filter((s) => s.length > 0);
|
|
695
|
-
return { kind: 'update', args: tokens };
|
|
696
|
-
}
|
|
697
|
-
case 'undo': {
|
|
698
|
-
// final : graduated from stub. Tail args are
|
|
699
|
-
// ignored — `runUndoCommand` is parameterless (single-step revert
|
|
700
|
-
// of the most recent successful mutating tool result). Multiple
|
|
701
|
-
// undos = stack of single-step undos. `/redo` is the counterpart
|
|
702
|
-
// — operators ping-pong через undo/redo on the
|
|
703
|
-
// event-log stack without re-running the underlying tool.
|
|
704
|
-
return { kind: 'undo' };
|
|
705
|
-
}
|
|
706
|
-
case 'redo': {
|
|
707
|
-
// cleanup : counterpart к /undo. Tail args
|
|
708
|
-
// are ignored — `runRedoCommand` is parameterless. Each /redo
|
|
709
|
-
// pops one entry from the LIFO undo stack (the runner tracks
|
|
710
|
-
// which undos have already been consumed by previous redos so
|
|
711
|
-
// double-/redo is a noop, not a double-write).
|
|
712
|
-
return { kind: 'redo' };
|
|
713
|
-
}
|
|
714
|
-
case 'memory':
|
|
715
|
-
case 'config':
|
|
716
|
-
case 'budget': {
|
|
717
|
-
const stubName = name;
|
|
718
|
-
return {
|
|
719
|
-
kind: 'stub',
|
|
720
|
-
name: stubName,
|
|
721
|
-
message: SLASH_STUB_MESSAGES[stubName],
|
|
722
|
-
};
|
|
723
|
-
}
|
|
724
|
-
default: {
|
|
725
|
-
return {
|
|
726
|
-
kind: 'error',
|
|
727
|
-
message: `Unknown command /${head}. Try /help for the palette.`,
|
|
728
|
-
};
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
/**
|
|
733
|
-
* Filter SLASH_COMMAND_HELP rows whose name starts with the typed
|
|
734
|
-
* prefix. The REPL input box uses this to render an inline palette
|
|
735
|
-
* after the operator types `/`.
|
|
736
|
-
*
|
|
737
|
-
* Matching is case-insensitive; the prefix is normalized to lowercase
|
|
738
|
-
* before comparison so the operator can type `/HELP` and still see
|
|
739
|
-
* suggestions.
|
|
740
|
-
*/
|
|
741
|
-
export function matchSlashPrefix(prefix) {
|
|
742
|
-
const normalized = prefix.toLowerCase().replace(/^\//, '');
|
|
743
|
-
if (normalized.length === 0)
|
|
744
|
-
return SLASH_COMMAND_HELP;
|
|
745
|
-
return SLASH_COMMAND_HELP.filter((row) => row.name.startsWith(normalized));
|
|
746
|
-
}
|
|
747
|
-
//# sourceMappingURL=slash-commands.js.map
|