@pugi/cli 0.1.0-beta.9 → 0.1.0-beta.90
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 +132 -0
- package/LICENSE +1 -1
- package/assets/pugi-prozr2-mascot.ansi +9 -0
- package/bin/run.js +33 -1
- package/dist/commands/deploy.js +40 -40
- package/dist/commands/flatten.js +191 -0
- package/dist/commands/jobs-watch.js +201 -0
- package/dist/commands/jobs.js +42 -27
- package/dist/commands/smoke.js +133 -0
- package/dist/core/agent-progress/cleanup.js +134 -0
- package/dist/core/agent-progress/schema.js +144 -0
- package/dist/core/agent-progress/writer.js +101 -0
- package/dist/core/agents/adaptive-router.js +330 -0
- package/dist/core/agents/query-decomposer.js +297 -0
- package/dist/core/agents/registry.js +3 -3
- package/dist/core/approvals/shortcut-resolver.js +98 -0
- package/dist/core/artifact-chain/dispatcher.js +148 -0
- package/dist/core/artifact-chain/exporter.js +164 -0
- package/dist/core/artifact-chain/state.js +243 -0
- package/dist/core/artifact-chain/steps.js +169 -0
- package/dist/core/ask-user/question.js +92 -0
- package/dist/core/audit/audit-trail.js +275 -0
- package/dist/core/auth/ensure-authenticated.js +129 -0
- package/dist/core/auth/env-provider.js +238 -0
- package/dist/core/auto-open-browser.js +4 -4
- package/dist/core/auto-update/channels.js +122 -0
- package/dist/core/auto-update/checker.js +241 -0
- package/dist/core/auto-update/state.js +235 -0
- package/dist/core/bare-mode/index.js +107 -0
- package/dist/core/bash/redirect.js +281 -0
- package/dist/core/bash-classifier.js +436 -40
- package/dist/core/checkpoint/resumer.js +149 -0
- package/dist/core/checkpoint/rewinder.js +291 -0
- package/dist/core/checkpoints/shadow-git.js +670 -0
- package/dist/core/citations/parser.js +109 -0
- package/dist/core/classifier/yolo-classifier.js +88 -0
- package/dist/core/codegraph/decision-store.js +248 -0
- package/dist/core/codegraph/detect-repo.js +459 -0
- package/dist/core/codegraph/install.js +134 -0
- package/dist/core/codegraph/offer-hook.js +220 -0
- package/dist/core/compact/auto-trigger.js +96 -0
- package/dist/core/compact/buffer-rewriter.js +115 -0
- package/dist/core/compact/summarizer.js +208 -0
- package/dist/core/compact/token-counter.js +108 -0
- package/dist/core/consensus/anvil-fanout.js +25 -25
- package/dist/core/consensus/diff-capture.js +121 -12
- package/dist/core/consensus/rubric.js +21 -21
- package/dist/core/context/builder.js +6 -6
- package/dist/core/context/compaction-events.js +8 -8
- package/dist/core/context/compaction.js +31 -31
- package/dist/core/context/index.js +15 -8
- package/dist/core/context/invariants.js +51 -51
- package/dist/core/context/markdown-loader.js +28 -10
- package/dist/core/context/markdown-traverse.js +255 -0
- package/dist/core/context/pugiignore.js +41 -41
- package/dist/core/context/repo-skeleton.js +37 -37
- package/dist/core/context/tool-eviction.js +55 -0
- package/dist/core/context/watcher.js +32 -32
- package/dist/core/context/working-set.js +23 -23
- package/dist/core/coordinator/agent-tools.js +77 -0
- package/dist/core/coordinator/agent-toolset.js +65 -0
- package/dist/core/coordinator/fsm.js +73 -0
- package/dist/core/coordinator/mode-fsm.js +70 -0
- package/dist/core/cost/rate-card.js +129 -0
- package/dist/core/cost/tracker.js +221 -0
- package/dist/core/credentials.js +13 -13
- package/dist/core/cron/scheduler.js +138 -0
- package/dist/core/denial-tracking/index.js +8 -0
- package/dist/core/denial-tracking/state.js +264 -0
- package/dist/core/diagnostics/probe-runner.js +93 -0
- package/dist/core/diagnostics/probes/api.js +46 -0
- package/dist/core/diagnostics/probes/auth.js +93 -0
- package/dist/core/diagnostics/probes/bare-mode.js +42 -0
- package/dist/core/diagnostics/probes/cli-version.js +127 -0
- package/dist/core/diagnostics/probes/config.js +72 -0
- package/dist/core/diagnostics/probes/denial-tracking.js +57 -0
- package/dist/core/diagnostics/probes/disk.js +81 -0
- package/dist/core/diagnostics/probes/engine-live.js +46 -0
- package/dist/core/diagnostics/probes/git.js +65 -0
- package/dist/core/diagnostics/probes/hooks.js +118 -0
- package/dist/core/diagnostics/probes/mcp.js +75 -0
- package/dist/core/diagnostics/probes/node.js +59 -0
- package/dist/core/diagnostics/probes/pnpm.js +36 -0
- package/dist/core/diagnostics/probes/pugi-md.js +89 -0
- package/dist/core/diagnostics/probes/sandbox.js +40 -0
- package/dist/core/diagnostics/probes/session.js +74 -0
- package/dist/core/diagnostics/probes/status-snapshot.js +488 -0
- package/dist/core/diagnostics/probes/workspace.js +63 -0
- package/dist/core/diagnostics/types.js +70 -0
- package/dist/core/dispatch/cache-cleanup.js +197 -0
- package/dist/core/dispatch/cache-handoff.js +295 -0
- package/dist/core/edits/apply-patch-layer-e.js +189 -0
- package/dist/core/edits/dispatch.js +333 -7
- package/dist/core/edits/format-detector.js +260 -0
- package/dist/core/edits/format-matrix.js +26 -0
- package/dist/core/edits/fuzzy-ladder.js +650 -0
- package/dist/core/edits/index.js +5 -1
- package/dist/core/edits/journal.js +199 -0
- package/dist/core/edits/layer-a-apply.js +15 -15
- package/dist/core/edits/layer-a-fuzzy-apply.js +198 -0
- package/dist/core/edits/layer-b-apply.js +9 -9
- package/dist/core/edits/layer-c-apply.js +6 -6
- package/dist/core/edits/layer-d-ast.js +557 -14
- package/dist/core/edits/marker-parser.js +12 -12
- package/dist/core/edits/security-gate.js +27 -27
- package/dist/core/edits/verify-hook.js +273 -0
- package/dist/core/edits/worktree.js +29 -29
- package/dist/core/engine/anvil-client.js +214 -26
- package/dist/core/engine/auto-compact.js +179 -0
- package/dist/core/engine/budgets.js +186 -0
- package/dist/core/engine/context-prefix.js +155 -0
- package/dist/core/engine/index.js +1 -1
- package/dist/core/engine/intensity.js +158 -0
- package/dist/core/engine/intent.js +260 -0
- package/dist/core/engine/native-pugi.js +1295 -227
- package/dist/core/engine/prompts.js +129 -19
- package/dist/core/engine/strip-internal-fields.js +124 -0
- package/dist/core/engine/tool-bridge.js +1731 -59
- package/dist/core/evaluation/golden-dataset.js +293 -0
- package/dist/core/feedback/queue.js +177 -0
- package/dist/core/feedback/submitter.js +145 -0
- package/dist/core/file-cache.js +113 -1
- package/dist/core/flatten/flatten-repo.js +439 -0
- package/dist/core/format/osc8-link.js +28 -0
- package/dist/core/hook-chains.js +392 -0
- package/dist/core/hooks/citation-verify-hook.js +138 -0
- package/dist/core/hooks/citation-verify.js +112 -0
- package/dist/core/hooks/events.js +46 -0
- package/dist/core/hooks/index.js +15 -0
- package/dist/core/hooks/registry.js +216 -0
- package/dist/core/hooks/runner.js +236 -0
- package/dist/core/hooks/v2/event-emitter.js +115 -0
- package/dist/core/hooks/v2/executor.js +282 -0
- package/dist/core/hooks/v2/index.js +25 -0
- package/dist/core/hooks/v2/lifecycle.js +104 -0
- package/dist/core/hooks/v2/loader.js +216 -0
- package/dist/core/hooks/v2/matcher.js +125 -0
- package/dist/core/hooks/v2/trust.js +143 -0
- package/dist/core/hooks/v2/types.js +86 -0
- package/dist/core/hooks/worktree-events.js +158 -0
- package/dist/core/image/renderer.js +71 -0
- package/dist/core/init/detector.js +582 -0
- package/dist/core/init/template-renderer.js +242 -0
- package/dist/core/jobs/registry.js +18 -18
- package/dist/core/ledger/results-tsv.js +142 -0
- package/dist/core/log-discipline/stdout-redirect.js +51 -0
- package/dist/core/lsp/cache.js +105 -0
- package/dist/core/lsp/client.js +551 -41
- package/dist/core/lsp/language-detect.js +66 -0
- package/dist/core/lsp/post-edit-diagnostics.js +171 -0
- package/dist/core/lsp/server-detect.js +173 -0
- package/dist/core/lsp/symbol-cache.js +162 -0
- package/dist/core/lsp/symbol-tools.js +664 -0
- package/dist/core/mcp/client.js +97 -28
- package/dist/core/mcp/http-server.js +553 -0
- package/dist/core/mcp/orchestrator-tools.js +662 -0
- package/dist/core/mcp/permission.js +190 -0
- package/dist/core/mcp/registry.js +39 -17
- package/dist/core/mcp/server-tools.js +219 -0
- package/dist/core/mcp/server.js +397 -0
- package/dist/core/mcp/trust.js +10 -10
- package/dist/core/memory/dual-write.js +416 -0
- package/dist/core/memory/passive-extract.js +130 -0
- package/dist/core/memory/phase1-kinds.js +20 -0
- package/dist/core/memory/secret-scanner.js +304 -0
- package/dist/core/memory-sync/queue.js +170 -0
- package/dist/core/metrics/extract.js +113 -0
- package/dist/core/modes/roo-modes.js +68 -0
- package/dist/core/onboarding/ensure-initialized.js +133 -0
- package/dist/core/onboarding/marker.js +111 -0
- package/dist/core/onboarding/telemetry-state.js +108 -0
- package/dist/core/output-style/presets.js +176 -0
- package/dist/core/output-style/state.js +185 -0
- package/dist/core/path-security.js +287 -5
- package/dist/core/permission.js +82 -22
- package/dist/core/permissions/auto-classifier.js +124 -0
- package/dist/core/permissions/bash-parser.js +371 -0
- package/dist/core/permissions/circuit-breaker.js +83 -0
- package/dist/core/permissions/constrained-edit.js +91 -0
- package/dist/core/permissions/gate.js +278 -0
- package/dist/core/permissions/index.js +20 -0
- package/dist/core/permissions/mode.js +174 -0
- package/dist/core/permissions/network-egress.js +137 -0
- package/dist/core/permissions/state.js +241 -0
- package/dist/core/permissions/tool-class.js +93 -0
- package/dist/core/plan-mode/ui-state.js +51 -0
- package/dist/core/plans/plan-artifact.js +721 -0
- package/dist/core/policy-limits/etag-store.js +122 -0
- package/dist/core/prd-check/parser.js +215 -0
- package/dist/core/prd-check/reporter.js +127 -0
- package/dist/core/prd-check/session-review.js +557 -0
- package/dist/core/prd-check/verifiers.js +223 -0
- package/dist/core/prompt-cache/client-cache.js +99 -0
- package/dist/core/prompts/assembly.js +29 -0
- package/dist/core/prompts/registry.js +364 -0
- package/dist/core/pugi-md/cc-compat-rules.js +735 -0
- package/dist/core/pugi-md/context-injector.js +76 -0
- package/dist/core/pugi-md/walk-up.js +207 -0
- package/dist/core/python/uv-installer.js +270 -0
- package/dist/core/python/uv-resolver.js +83 -0
- package/dist/core/rate-limit/narrator.js +146 -0
- package/dist/core/recipes/cli-types.js +20 -0
- package/dist/core/recipes/loader.js +103 -0
- package/dist/core/recipes/runner.js +345 -0
- package/dist/core/recipes/schema.js +587 -0
- package/dist/core/release-notes/parser.js +241 -0
- package/dist/core/release-notes/state.js +116 -0
- package/dist/core/repl/ask.js +37 -37
- package/dist/core/repl/cancellation.js +26 -26
- package/dist/core/repl/cap-warning.js +4 -4
- package/dist/core/repl/clipboard-read.js +11 -11
- package/dist/core/repl/dispatch-fsm.js +12 -12
- package/dist/core/repl/history-search.js +15 -15
- package/dist/core/repl/history.js +28 -18
- package/dist/core/repl/kill-ring.js +5 -5
- package/dist/core/repl/model-pricing.js +135 -0
- package/dist/core/repl/privacy-banner.js +22 -22
- package/dist/core/repl/session.js +2148 -217
- package/dist/core/repl/slash-commands.js +501 -41
- package/dist/core/repl/store/index.js +1 -1
- package/dist/core/repl/store/jsonl-log.js +22 -22
- package/dist/core/repl/store/lockfile.js +10 -10
- package/dist/core/repl/store/session-store.js +136 -107
- package/dist/core/repl/store/types.js +15 -15
- package/dist/core/repl/store/uuid-v7.js +12 -12
- package/dist/core/repl/workspace-context.js +43 -21
- package/dist/core/repo-map/build.js +125 -0
- package/dist/core/repo-map/cache.js +185 -0
- package/dist/core/repo-map/extractor.js +254 -0
- package/dist/core/repo-map/formatter.js +145 -0
- package/dist/core/repo-map/page-rank.js +105 -0
- package/dist/core/repo-map/scanner.js +211 -0
- package/dist/core/retry-budget/budget.js +284 -0
- package/dist/core/retry-budget/index.js +5 -0
- package/dist/core/retry-budget/retry-cap.js +74 -0
- package/dist/core/routing/lead-worker.js +43 -0
- package/dist/core/routing/pre-flight-estimator.js +108 -0
- package/dist/core/runs/run-tree.js +103 -0
- package/dist/core/security/injection-scanner.js +367 -0
- package/dist/core/security/output-filter.js +418 -0
- package/dist/core/session/env-file.js +105 -0
- package/dist/core/session/section-budgets.js +140 -0
- package/dist/core/session.js +92 -0
- package/dist/core/settings.js +324 -5
- package/dist/core/share/formatter.js +271 -0
- package/dist/core/share/redactor.js +221 -0
- package/dist/core/share/uploader.js +267 -0
- package/dist/core/skills/defaults.js +30 -30
- package/dist/core/skills/loader.js +22 -22
- package/dist/core/skills/sources.js +27 -27
- package/dist/core/smoke/headless-driver.js +174 -0
- package/dist/core/smoke/orchestrator.js +194 -0
- package/dist/core/smoke/runner.js +238 -0
- package/dist/core/smoke/scenario-parser.js +316 -0
- package/dist/core/statusline.js +99 -0
- package/dist/core/subagents/dispatcher-real.js +600 -0
- package/dist/core/subagents/dispatcher.js +132 -43
- package/dist/core/subagents/index.js +19 -6
- package/dist/core/subagents/isolation-matrix.js +213 -0
- package/dist/core/subagents/spawn.js +19 -4
- package/dist/core/telemetry/emitter.js +229 -0
- package/dist/core/telemetry/queue.js +251 -0
- package/dist/core/theme/context.js +91 -0
- package/dist/core/theme/presets.js +228 -0
- package/dist/core/theme/state.js +181 -0
- package/dist/core/todos/invariant.js +10 -0
- package/dist/core/todos/state.js +177 -0
- package/dist/core/tool-schema/compressor.js +89 -0
- package/dist/core/transport/version-interceptor.js +166 -0
- package/dist/core/trust.js +2 -2
- package/dist/core/tui/thinking-block.js +64 -0
- package/dist/core/vim/keymap.js +288 -0
- package/dist/core/vim/state.js +92 -0
- package/dist/core/watch-markers/marker-watcher.js +133 -0
- package/dist/core/worktree/include-parser.js +249 -0
- package/dist/core/worktree-manager/cleanup.js +123 -0
- package/dist/core/worktree-manager/manager.js +303 -0
- package/dist/index.js +36 -0
- package/dist/runtime/bootstrap.js +190 -0
- package/dist/runtime/cli.js +4185 -549
- package/dist/runtime/commands/agents.js +31 -31
- package/dist/runtime/commands/budget.js +5 -5
- package/dist/runtime/commands/cancel.js +231 -0
- package/dist/runtime/commands/chain.js +489 -0
- package/dist/runtime/commands/codegraph-status.js +227 -0
- package/dist/runtime/commands/compact.js +297 -0
- package/dist/runtime/commands/config.js +73 -39
- package/dist/runtime/commands/cost.js +199 -0
- package/dist/runtime/commands/delegate.js +27 -4
- package/dist/runtime/commands/dispatch.js +126 -0
- package/dist/runtime/commands/doctor.js +579 -0
- package/dist/runtime/commands/feedback.js +184 -0
- package/dist/runtime/commands/hooks.js +187 -0
- package/dist/runtime/commands/init.js +254 -0
- package/dist/runtime/commands/lsp.js +200 -38
- package/dist/runtime/commands/mcp.js +879 -0
- package/dist/runtime/commands/memory.js +582 -0
- package/dist/runtime/commands/model.js +237 -0
- package/dist/runtime/commands/onboarding.js +275 -0
- package/dist/runtime/commands/patch.js +12 -12
- package/dist/runtime/commands/permissions.js +112 -0
- package/dist/runtime/commands/plan.js +143 -0
- package/dist/runtime/commands/prd-check.js +285 -0
- package/dist/runtime/commands/privacy.js +17 -17
- package/dist/runtime/commands/recipe.js +325 -0
- package/dist/runtime/commands/redo-blob-store.js +92 -0
- package/dist/runtime/commands/redo.js +361 -0
- package/dist/runtime/commands/release-notes.js +229 -0
- package/dist/runtime/commands/repo-map.js +95 -0
- package/dist/runtime/commands/report.js +299 -0
- package/dist/runtime/commands/resume.js +118 -0
- package/dist/runtime/commands/review-consensus.js +68 -53
- package/dist/runtime/commands/rewind.js +333 -0
- package/dist/runtime/commands/roster.js +14 -14
- package/dist/runtime/commands/sessions.js +163 -0
- package/dist/runtime/commands/share.js +316 -0
- package/dist/runtime/commands/skills.js +31 -31
- package/dist/runtime/commands/status.js +186 -0
- package/dist/runtime/commands/stickers.js +82 -0
- package/dist/runtime/commands/style.js +194 -0
- package/dist/runtime/commands/theme.js +196 -0
- package/dist/runtime/commands/undo.js +54 -22
- package/dist/runtime/commands/update.js +289 -0
- package/dist/runtime/commands/vim.js +140 -0
- package/dist/runtime/commands/worktree.js +8 -8
- package/dist/runtime/commands/worktrees.js +155 -0
- package/dist/runtime/headless-repl.js +195 -0
- package/dist/runtime/headless.js +543 -0
- package/dist/runtime/load-hooks-or-exit.js +71 -0
- package/dist/runtime/plan-decompose.js +22 -22
- package/dist/runtime/sigint-guard.js +272 -0
- package/dist/runtime/update-check.js +28 -28
- package/dist/runtime/version.js +65 -0
- package/dist/runtime/worktree-bootstrap.js +579 -0
- package/dist/skills/bundled/batch.js +617 -0
- package/dist/skills/bundled/index.js +45 -0
- package/dist/skills/bundled/loop.js +358 -0
- package/dist/skills/bundled/remember.js +383 -0
- package/dist/skills/bundled/simplify.js +289 -0
- package/dist/skills/bundled/skillify.js +373 -0
- package/dist/skills/bundled/stuck.js +558 -0
- package/dist/skills/bundled/verify.js +439 -0
- package/dist/testing/vcr.js +486 -0
- package/dist/tools/agent-tool.js +229 -0
- package/dist/tools/apply-patch.js +89 -28
- package/dist/tools/ask-user-question.js +337 -0
- package/dist/tools/ask-user.js +115 -0
- package/dist/tools/bash.js +624 -46
- package/dist/tools/brief.js +224 -0
- package/dist/tools/enter-worktree.js +250 -0
- package/dist/tools/exit-worktree.js +147 -0
- package/dist/tools/file-tools.js +161 -44
- package/dist/tools/lsp-tools.js +377 -1
- package/dist/tools/mcp-tool.js +260 -0
- package/dist/tools/multi-edit.js +361 -0
- package/dist/tools/powershell.js +268 -0
- package/dist/tools/registry.js +86 -4
- package/dist/tools/skill-tool.js +96 -0
- package/dist/tools/sleep.js +99 -0
- package/dist/tools/synthetic-output.js +133 -0
- package/dist/tools/tasks.js +208 -0
- package/dist/tools/todo-write.js +184 -0
- package/dist/tools/verify-plan-execution.js +295 -0
- package/dist/tools/web-fetch-injection-scanner.js +207 -0
- package/dist/tools/web-fetch.js +195 -10
- package/dist/tools/web-search.js +458 -0
- package/dist/tui/agent-progress-card.js +111 -0
- package/dist/tui/agent-tree.js +11 -1
- package/dist/tui/ask-modal.js +14 -14
- package/dist/tui/ask-user-question-chips.js +315 -0
- package/dist/tui/ask-user-question-prompt.js +203 -0
- package/dist/tui/compact-banner.js +81 -0
- package/dist/tui/conversation-pane.js +85 -11
- package/dist/tui/cost-table.js +111 -0
- package/dist/tui/device-flow.js +2 -2
- package/dist/tui/doctor-table.js +46 -0
- package/dist/tui/feedback-prompt.js +156 -0
- package/dist/tui/input-box.js +247 -32
- package/dist/tui/login-picker.js +3 -3
- package/dist/tui/markdown-render.js +6 -6
- package/dist/tui/onboarding-wizard.js +240 -0
- package/dist/tui/permissions-picker.js +86 -0
- package/dist/tui/render.js +36 -1
- package/dist/tui/repl-render.js +176 -25
- package/dist/tui/repl-splash-art.js +16 -16
- package/dist/tui/repl-splash-mascot.js +48 -24
- package/dist/tui/repl-splash.js +22 -22
- package/dist/tui/repl.js +125 -45
- package/dist/tui/slash-palette.js +6 -6
- package/dist/tui/splash.js +2 -2
- package/dist/tui/status-bar.js +109 -31
- package/dist/tui/status-table.js +7 -0
- package/dist/tui/stickers-art.js +136 -0
- package/dist/tui/style-table.js +28 -0
- package/dist/tui/theme-table.js +29 -0
- package/dist/tui/thinking-spinner.js +123 -0
- package/dist/tui/tool-stream-pane.js +53 -4
- package/dist/tui/update-banner.js +27 -2
- package/dist/tui/vim-input.js +267 -0
- package/dist/tui/welcome-banner.js +107 -0
- package/dist/tui/welcome-data.js +293 -0
- package/dist/tui/workspace-context.js +2 -2
- package/package.json +31 -16
- package/test/scenarios/codegen-create-file.scenario.txt +13 -0
- package/test/scenarios/compact-force.scenario.txt +12 -0
- package/test/scenarios/identity.scenario.txt +12 -0
- package/test/scenarios/persona-handoff.scenario.txt +12 -0
- package/test/scenarios/walkback.scenario.txt +12 -0
- package/dist/core/engine/compaction-hook.js +0 -154
package/dist/tui/input-box.js
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
|
-
* REPL input box - Sprint
|
|
3
|
+
* REPL input box - Sprint (REPL UX P0 wave 1).
|
|
4
4
|
*
|
|
5
|
-
* Bordered, cursor-aware input box matching
|
|
6
|
-
* aesthetics. Layered upgrade over
|
|
5
|
+
* Bordered, cursor-aware input box matching the upstream tool / peer CLI
|
|
6
|
+
* aesthetics. Layered upgrade over :
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
8
|
+
* - Top divider (full-width cyan rule) anchors the input below the
|
|
9
|
+
* main pane and gives the operator a clear visual seam.
|
|
10
|
+
* - Rounded cyan border wraps the prompt + line + cursor.
|
|
11
|
+
* - Cursor follows the caret position (left/right arrows + Home/End
|
|
12
|
+
* reposition without losing the trailing text).
|
|
13
|
+
* - Single-arrow `›` prompt in brand cyan; dim continuation prompt
|
|
14
|
+
* `┊` when the input wraps past the available width so the operator
|
|
15
|
+
* sees that they are still inside one logical line.
|
|
16
|
+
* - History navigation (↑/↓), slash palette inline suggestion, Esc
|
|
17
|
+
* cancel, Ctrl+C ×2 exit remain wired identically to .
|
|
18
18
|
*
|
|
19
19
|
* State that belongs in this component:
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
20
|
+
* - `line` (string) - current buffer
|
|
21
|
+
* - `cursor` (number) - caret offset into `line`
|
|
22
|
+
* - `history` (string[]) - session-local; persistence lands in
|
|
23
|
+
* commit 2 (per-workspace JSONL).
|
|
24
|
+
* - `historyIndex` (number) - -1 when not navigating
|
|
25
25
|
*
|
|
26
26
|
* Brand voice gate: no forbidden words. ASCII-only glyphs.
|
|
27
27
|
*/
|
|
@@ -33,6 +33,14 @@ import { SlashPalette, completePalette, filterPalette, } from './slash-palette.j
|
|
|
33
33
|
import { EMPTY_KILL_RING, killToLineEnd, killToLineStart, killWordBackward, yankAtCursor, } from '../core/repl/kill-ring.js';
|
|
34
34
|
import { readClipboard } from '../core/repl/clipboard-read.js';
|
|
35
35
|
const CTRL_C_DOUBLE_TAP_MS = 1_000;
|
|
36
|
+
/**
|
|
37
|
+
* BT 8 (the upstream tool parity): Esc-Esc walks the conversation back
|
|
38
|
+
* one turn. 500ms is tight enough that an operator clearing the buffer +
|
|
39
|
+
* later changing their mind does NOT accidentally pop a turn, while
|
|
40
|
+
* still feeling like one motion. Matches the upstream tool's documented
|
|
41
|
+
* double-Esc window.
|
|
42
|
+
*/
|
|
43
|
+
const ESCAPE_DOUBLE_TAP_MS = 500;
|
|
36
44
|
/** Width subtracted from the terminal width so the border + padding fit. */
|
|
37
45
|
const FRAME_OVERHEAD_COLUMNS = 4;
|
|
38
46
|
/** Fallback width when ink cannot read stdout (e.g. test harness). */
|
|
@@ -75,6 +83,18 @@ export function InputBox(props) {
|
|
|
75
83
|
const [history, setHistory] = useState(seededHistory);
|
|
76
84
|
const [historyIndex, setHistoryIndex] = useState(-1);
|
|
77
85
|
const [lastCtrlCAt, setLastCtrlCAt] = useState(undefined);
|
|
86
|
+
// CEO P0 #2 : the upstream tool parity — surface а visible
|
|
87
|
+
// "Press Ctrl+C again to exit" toast on the first Ctrl+C press so
|
|
88
|
+
// the operator knows the second press will terminate the REPL.
|
|
89
|
+
// Auto-clears after CTRL_C_DOUBLE_TAP_MS so it never lingers past
|
|
90
|
+
// the double-tap window.
|
|
91
|
+
const [ctrlCToast, setCtrlCToast] = useState(null);
|
|
92
|
+
const ctrlCToastTimerRef = useRef(null);
|
|
93
|
+
// BT 8: Esc-Esc walkback double-tap window. Tracks the epoch
|
|
94
|
+
// ms of the most recent Esc press so the next Esc within
|
|
95
|
+
// ESCAPE_DOUBLE_TAP_MS triggers the walkback handler instead of
|
|
96
|
+
// re-clearing the buffer.
|
|
97
|
+
const [lastEscapeAt, setLastEscapeAt] = useState(undefined);
|
|
78
98
|
const [cursorVisible, setCursorVisible] = useState(true);
|
|
79
99
|
// Ctrl+R / Ctrl+S reverse-search mode. Undefined when idle, a
|
|
80
100
|
// HistorySearchState while the operator is searching.
|
|
@@ -94,6 +114,11 @@ export function InputBox(props) {
|
|
|
94
114
|
// panes when Ctrl+L wipes the terminal (the parent React tree is
|
|
95
115
|
// otherwise stable and would not redraw on a stdout.write alone).
|
|
96
116
|
const [, setRedrawTick] = useState(0);
|
|
117
|
+
// Shift+Tab toast — flashed for 2s after a mode cycle so the
|
|
118
|
+
// operator sees `Mode → acceptEdits` под the input divider. Cleared
|
|
119
|
+
// by a setTimeout so a quick second Shift+Tab refreshes the toast.
|
|
120
|
+
const [modeCycleToast, setModeCycleToast] = useState(null);
|
|
121
|
+
const modeCycleTimerRef = useRef(null);
|
|
97
122
|
const now = props.now ?? Date.now;
|
|
98
123
|
const { stdout } = useStdout();
|
|
99
124
|
const columns = stdout?.columns ?? FALLBACK_COLUMNS;
|
|
@@ -131,7 +156,7 @@ export function InputBox(props) {
|
|
|
131
156
|
useInput((input, key) => {
|
|
132
157
|
if (key.ctrl && input === 'c') {
|
|
133
158
|
const t = now();
|
|
134
|
-
//
|
|
159
|
+
// : the upstream tool-style double-press semantics. First Ctrl+C
|
|
135
160
|
// ALWAYS attempts to cancel an in-flight dispatch (when the
|
|
136
161
|
// session reports non-idle); second Ctrl+C within 1s exits the
|
|
137
162
|
// process. If onCancel is omitted (legacy callers, tests), the
|
|
@@ -140,7 +165,7 @@ export function InputBox(props) {
|
|
|
140
165
|
const withinDoubleTapWindow = typeof lastCtrlCAt === 'number' && t - lastCtrlCAt <= CTRL_C_DOUBLE_TAP_MS;
|
|
141
166
|
if (withinDoubleTapWindow) {
|
|
142
167
|
// Second press inside the window — always exit. This matches
|
|
143
|
-
//
|
|
168
|
+
// the upstream tool: even mid-dispatch, the second Ctrl+C wins so
|
|
144
169
|
// the operator can always escape a stuck REPL.
|
|
145
170
|
props.onExit();
|
|
146
171
|
return;
|
|
@@ -152,13 +177,13 @@ export function InputBox(props) {
|
|
|
152
177
|
// tool is running).
|
|
153
178
|
//
|
|
154
179
|
// Three-valued onCancel return (see prop docstring):
|
|
155
|
-
//
|
|
156
|
-
//
|
|
157
|
-
//
|
|
158
|
-
//
|
|
159
|
-
//
|
|
160
|
-
//
|
|
161
|
-
//
|
|
180
|
+
// - true → dispatch cancelled, keep buffer, arm exit timer
|
|
181
|
+
// - false → idle, clear buffer (legacy), arm exit timer
|
|
182
|
+
// - undefined → handler bypassed (modal owns input); NO state
|
|
183
|
+
// change at all. Buffer stays, exit timer NOT
|
|
184
|
+
// armed (otherwise the modal would silently
|
|
185
|
+
// promote a Ctrl+C to "press again to exit",
|
|
186
|
+
// which is wrong context for a modal cancel).
|
|
162
187
|
let cancelResult;
|
|
163
188
|
if (props.onCancel) {
|
|
164
189
|
cancelResult = props.onCancel();
|
|
@@ -173,6 +198,28 @@ export function InputBox(props) {
|
|
|
173
198
|
return;
|
|
174
199
|
}
|
|
175
200
|
setLastCtrlCAt(t);
|
|
201
|
+
// CEO P0 #2 : surface the "Press Ctrl+C again to
|
|
202
|
+
// exit" toast on the first press so the operator sees the
|
|
203
|
+
// double-tap semantics in the UI, not just в the bottom hint
|
|
204
|
+
// line. Mirrors the standard tool's exit affordance verbatim. The
|
|
205
|
+
// toast string varies by which branch fired (cancel vs idle
|
|
206
|
+
// clear) so the operator learns what the press just did:
|
|
207
|
+
//
|
|
208
|
+
// - cancelResult === true → "Aborted. Press Ctrl+C again to exit."
|
|
209
|
+
// - cancelResult === false → "Press Ctrl+C again to exit."
|
|
210
|
+
//
|
|
211
|
+
// (The undefined branch already returned above — а modal owns
|
|
212
|
+
// input и the toast is suppressed.)
|
|
213
|
+
const toastCopy = cancelResult === true
|
|
214
|
+
? 'Aborted. Press Ctrl+C again to exit.'
|
|
215
|
+
: 'Press Ctrl+C again to exit.';
|
|
216
|
+
setCtrlCToast(toastCopy);
|
|
217
|
+
if (ctrlCToastTimerRef.current)
|
|
218
|
+
clearTimeout(ctrlCToastTimerRef.current);
|
|
219
|
+
ctrlCToastTimerRef.current = setTimeout(() => {
|
|
220
|
+
setCtrlCToast(null);
|
|
221
|
+
ctrlCToastTimerRef.current = null;
|
|
222
|
+
}, CTRL_C_DOUBLE_TAP_MS);
|
|
176
223
|
// Legacy behaviour: on idle (or no onCancel wired), clear the
|
|
177
224
|
// buffer + reset search so the operator's screen is calm before
|
|
178
225
|
// they confirm exit. When we DID cancel a live dispatch, keep
|
|
@@ -184,6 +231,24 @@ export function InputBox(props) {
|
|
|
184
231
|
}
|
|
185
232
|
return;
|
|
186
233
|
}
|
|
234
|
+
// — the upstream tool parity: Shift+Tab cycles permission mode.
|
|
235
|
+
// The host owns the cycle logic + persistence; we just intercept
|
|
236
|
+
// the chord and surface a one-line toast on success. Place this
|
|
237
|
+
// BEFORE the search-mode and palette branches so a Shift+Tab fires
|
|
238
|
+
// even while reverse-search is active (operator habit-driven).
|
|
239
|
+
if (key.shift && key.tab && props.onCyclePermissionMode) {
|
|
240
|
+
const nextMode = props.onCyclePermissionMode();
|
|
241
|
+
if (nextMode) {
|
|
242
|
+
setModeCycleToast(`Mode → ${nextMode}`);
|
|
243
|
+
if (modeCycleTimerRef.current)
|
|
244
|
+
clearTimeout(modeCycleTimerRef.current);
|
|
245
|
+
modeCycleTimerRef.current = setTimeout(() => {
|
|
246
|
+
setModeCycleToast(null);
|
|
247
|
+
modeCycleTimerRef.current = null;
|
|
248
|
+
}, 2_000);
|
|
249
|
+
}
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
187
252
|
// Search-mode key handling. Ctrl+R / Ctrl+S cycle, Enter accepts,
|
|
188
253
|
// Esc cancels (restoring the pre-search draft), backspace shortens
|
|
189
254
|
// the query, typed characters extend it.
|
|
@@ -202,7 +267,9 @@ export function InputBox(props) {
|
|
|
202
267
|
setCursor(draftBeforeSearch.length);
|
|
203
268
|
return;
|
|
204
269
|
}
|
|
205
|
-
|
|
270
|
+
// Bare LF accepts the focused match, same as CR (`key.return`).
|
|
271
|
+
// See the post-search block below for the rationale.
|
|
272
|
+
if (key.return || (input === '\n' && !key.meta && !key.ctrl && !key.shift)) {
|
|
206
273
|
const picked = currentBrief(search);
|
|
207
274
|
setSearch(undefined);
|
|
208
275
|
if (picked !== null) {
|
|
@@ -221,6 +288,11 @@ export function InputBox(props) {
|
|
|
221
288
|
return;
|
|
222
289
|
}
|
|
223
290
|
if (input && !key.meta && !key.ctrl) {
|
|
291
|
+
// Drop a bare LF from the search query — the Enter-accept
|
|
292
|
+
// branch above already handled it; falling through here would
|
|
293
|
+
// splice a newline into the search string.
|
|
294
|
+
if (input === '\n')
|
|
295
|
+
return;
|
|
224
296
|
const nextQuery = search.query + input;
|
|
225
297
|
setSearch(applyQuery(search, nextQuery, history));
|
|
226
298
|
return;
|
|
@@ -243,6 +315,118 @@ export function InputBox(props) {
|
|
|
243
315
|
setSearch(initialSearchState(history));
|
|
244
316
|
return;
|
|
245
317
|
}
|
|
318
|
+
// P0 fix (CEO dogfood, second iteration): bare LF (`\n`)
|
|
319
|
+
// MUST submit the brief, same as bare CR (`\r`). Ink's parseKeypress
|
|
320
|
+
// maps `\r` to `key.return` and `\n` to `key.name === 'enter'`
|
|
321
|
+
// WITHOUT setting `key.return`. Most real terminals deliver CR for
|
|
322
|
+
// Enter (ICRNL on by default), so the `key.return` branch below
|
|
323
|
+
// catches them. But when stdin is a PTY whose parent writes raw
|
|
324
|
+
// `\n` (Python's `pty.fork` + `os.write(fd, b"\n")`, automation
|
|
325
|
+
// harnesses, certain SSH multiplexers), the LF arrives as a
|
|
326
|
+
// printable char.
|
|
327
|
+
//
|
|
328
|
+
// PR (beta.45) fixed the case where `input === '\n'` exactly.
|
|
329
|
+
// CEO PTY smoke surfaced the REAL shape: when the parent
|
|
330
|
+
// writes the brief AND the Enter as separate `os.write` calls (or
|
|
331
|
+
// even when it doesn't), Node's stdin buffer COALESCES them into
|
|
332
|
+
// ONE chunk before Ink delivers the `useInput` event. The repro
|
|
333
|
+
// confirmed via stderr instrumentation: typing `hi\n` arrives in
|
|
334
|
+
// input-box as `bytes=[68 69 0a] len=3 flags=-` — a SINGLE 3-char
|
|
335
|
+
// chunk "hi\n" with no key flags. The PR branch (`input ===
|
|
336
|
+
// '\n'`) does not match, so `hi\n` falls through to the printable-
|
|
337
|
+
// char branch and the literal newline lands in the buffer as
|
|
338
|
+
// `› hi\n █` (multi-line composer, brief never dispatches, status
|
|
339
|
+
// stays `idle` forever).
|
|
340
|
+
//
|
|
341
|
+
// Fix: detect a TRAILING `\n` in a printable chunk with no
|
|
342
|
+
// modifiers — type the prefix into the buffer, then submit. The
|
|
343
|
+
// discriminator that keeps multi-line paste working: the chunk
|
|
344
|
+
// must contain EXACTLY ONE `\n` (the trailing one) and no other
|
|
345
|
+
// newlines. Multi-line pastes have ≥2 `\n` characters (or arrive
|
|
346
|
+
// wrapped in bracketed-paste markers handled below), so they
|
|
347
|
+
// still preserve interior newlines via the printable-char branch.
|
|
348
|
+
//
|
|
349
|
+
// Detection contract:
|
|
350
|
+
// - `input` ends with `\n`
|
|
351
|
+
// - no Ctrl / Meta / Shift modifiers
|
|
352
|
+
// - exactly ONE `\n` in the chunk (the trailing one)
|
|
353
|
+
// - chunk is not bracketed-paste wrapped (markers stripped below)
|
|
354
|
+
//
|
|
355
|
+
// Edge cases covered by `test/input-box-lf-submit.spec.tsx`:
|
|
356
|
+
// - bare `\n` → submit empty (no-op on empty buf)
|
|
357
|
+
// - `hi\n` → splice `hi` + submit
|
|
358
|
+
// - `hi\nthere\n` (multi-line) → printable branch, preserves \n
|
|
359
|
+
// - `\r` (CR) → key.return branch unchanged
|
|
360
|
+
// - `hi\r\n` (CRLF) → key.return branch (CR wins first)
|
|
361
|
+
const endsWithLf = input.length > 0 && input.charCodeAt(input.length - 1) === 0x0a;
|
|
362
|
+
const newlineCount = (input.match(/\n/g) || []).length;
|
|
363
|
+
if (endsWithLf
|
|
364
|
+
&& newlineCount === 1
|
|
365
|
+
&& !key.meta
|
|
366
|
+
&& !key.ctrl
|
|
367
|
+
&& !key.shift) {
|
|
368
|
+
// Splice the prefix (everything before the trailing `\n`) into
|
|
369
|
+
// the buffer at the cursor, then run the canonical submit path.
|
|
370
|
+
// Refs (cursorRef / lineRef) hold the latest committed values so
|
|
371
|
+
// the splice runs against the operator's most recent edits even
|
|
372
|
+
// if a previous async paste / setState is still mid-flight.
|
|
373
|
+
const prefix = input.slice(0, -1);
|
|
374
|
+
let mergedLine = lineRef.current;
|
|
375
|
+
let mergedCursor = cursorRef.current;
|
|
376
|
+
if (prefix.length > 0) {
|
|
377
|
+
// Same sanitisation as the printable-char branch below — strip
|
|
378
|
+
// bracketed-paste markers so a stray escape sequence never
|
|
379
|
+
// lands in the submitted brief.
|
|
380
|
+
const stripped = prefix
|
|
381
|
+
.replace(/\x1b\[200~/g, '')
|
|
382
|
+
.replace(/\x1b\[201~/g, '')
|
|
383
|
+
.replace(/\[200~/g, '')
|
|
384
|
+
.replace(/\[201~/g, '');
|
|
385
|
+
if (stripped.length > 0) {
|
|
386
|
+
mergedLine =
|
|
387
|
+
mergedLine.slice(0, mergedCursor) + stripped + mergedLine.slice(mergedCursor);
|
|
388
|
+
mergedCursor = mergedCursor + stripped.length;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
// Synthesise the same payload-shape the `key.return` branch
|
|
392
|
+
// below uses so palette completion + history dedup + onSubmit
|
|
393
|
+
// dispatch all run identically.
|
|
394
|
+
const paletteHere = !paletteSuppressed
|
|
395
|
+
? filterPalette(mergedLine)
|
|
396
|
+
: { rows: [], totalBeforeLimit: 0 };
|
|
397
|
+
const paletteOpenHere = paletteHere.rows.length > 0;
|
|
398
|
+
const paletteFocusedIndexHere = paletteHere.rows.length === 0
|
|
399
|
+
? 0
|
|
400
|
+
: Math.min(paletteIndex, paletteHere.rows.length - 1);
|
|
401
|
+
let payload = mergedLine;
|
|
402
|
+
if (paletteOpenHere) {
|
|
403
|
+
const completed = completePalette(mergedLine, paletteHere.rows, paletteFocusedIndexHere);
|
|
404
|
+
if (completed !== null)
|
|
405
|
+
payload = completed;
|
|
406
|
+
}
|
|
407
|
+
const trimmed = payload.trim();
|
|
408
|
+
if (trimmed.length > 0) {
|
|
409
|
+
setHistory((prev) => {
|
|
410
|
+
if (prev[prev.length - 1] === trimmed)
|
|
411
|
+
return prev;
|
|
412
|
+
return [...prev, trimmed];
|
|
413
|
+
});
|
|
414
|
+
setHistoryIndex(-1);
|
|
415
|
+
if (props.workspaceSlug) {
|
|
416
|
+
appendHistory({
|
|
417
|
+
home: props.historyHome,
|
|
418
|
+
workspaceSlug: props.workspaceSlug,
|
|
419
|
+
brief: trimmed,
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
props.onSubmit(trimmed);
|
|
423
|
+
}
|
|
424
|
+
setLine('');
|
|
425
|
+
setCursor(0);
|
|
426
|
+
setPaletteSuppressed(false);
|
|
427
|
+
setPaletteIndex(0);
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
246
430
|
// Readline-style kill ring shortcuts. All four kills push the
|
|
247
431
|
// removed slice onto the ring; Ctrl+Y yanks the most recent.
|
|
248
432
|
if (key.ctrl && input === 'u') {
|
|
@@ -375,10 +559,41 @@ export function InputBox(props) {
|
|
|
375
559
|
if (key.escape) {
|
|
376
560
|
if (paletteOpen) {
|
|
377
561
|
// Close the palette without clearing the buffer so the operator
|
|
378
|
-
// can still send `/help` as plain text if they want.
|
|
562
|
+
// can still send `/help` as plain text if they want. Palette
|
|
563
|
+
// takes precedence over walkback because the operator's mental
|
|
564
|
+
// model is "Esc closes the visible overlay first".
|
|
379
565
|
setPaletteSuppressed(true);
|
|
566
|
+
setLastEscapeAt(undefined);
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
// BT 8: Esc-Esc walkback. Two presses within
|
|
570
|
+
// ESCAPE_DOUBLE_TAP_MS step the conversation back by one turn.
|
|
571
|
+
// First press still clears the buffer (legacy behaviour for the
|
|
572
|
+
// single-Esc cancel UX); the second press calls the host's
|
|
573
|
+
// walkback handler. Buffer-clear on the first press is what makes
|
|
574
|
+
// the double-tap feel "free" - the operator did not have to
|
|
575
|
+
// memorise a new chord; they just have to keep pressing.
|
|
576
|
+
const tEsc = now();
|
|
577
|
+
const withinEscapeWindow = typeof lastEscapeAt === 'number'
|
|
578
|
+
&& tEsc - lastEscapeAt <= ESCAPE_DOUBLE_TAP_MS;
|
|
579
|
+
if (withinEscapeWindow && props.onWalkback) {
|
|
580
|
+
// Second tap inside the window. Buffer was already cleared on
|
|
581
|
+
// the first press, so the host sees a clean input box AND the
|
|
582
|
+
// walkback result. We clear the window so a third tap restarts
|
|
583
|
+
// the cycle (no run-on walkbacks from a stuck Esc key).
|
|
584
|
+
const verdict = props.onWalkback();
|
|
585
|
+
setLastEscapeAt(undefined);
|
|
586
|
+
if (verdict !== 'walked-back') {
|
|
587
|
+
// Host refused (dispatch in flight, no turns to pop). The
|
|
588
|
+
// host owns the refusal copy via its own writeOutput path;
|
|
589
|
+
// we do not double-message here.
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
380
592
|
return;
|
|
381
593
|
}
|
|
594
|
+
// First Esc (or no walkback wired). Arm the window + clear the
|
|
595
|
+
// buffer per the long-standing single-Esc cancel contract.
|
|
596
|
+
setLastEscapeAt(tEsc);
|
|
382
597
|
setLine('');
|
|
383
598
|
setCursor(0);
|
|
384
599
|
setHistoryIndex(-1);
|
|
@@ -442,7 +657,7 @@ export function InputBox(props) {
|
|
|
442
657
|
// Read cursor via ref inside the updater so the slice indices come
|
|
443
658
|
// from the latest committed value, not the closure-captured one.
|
|
444
659
|
// Same React-18 strict-mode race that bit the Ctrl+V paste path
|
|
445
|
-
// (Claude P1 on PR
|
|
660
|
+
// (Claude P1 on PR wave 1): updaters run twice under strict
|
|
446
661
|
// mode, and a stale closure `cursor` produces a double-edit on the
|
|
447
662
|
// second invocation. cursorRef is the canonical fix — do NOT
|
|
448
663
|
// re-introduce closure `cursor` inside setLine updaters.
|
|
@@ -479,7 +694,7 @@ export function InputBox(props) {
|
|
|
479
694
|
// Read cursor via ref inside the updater so the splice indices come
|
|
480
695
|
// from the latest committed value, not the closure-captured one.
|
|
481
696
|
// Same React-18 strict-mode race that bit the Ctrl+V paste path
|
|
482
|
-
// (Claude P1 on PR
|
|
697
|
+
// (Claude P1 on PR wave 1): updaters run twice under strict
|
|
483
698
|
// mode, and a stale closure `cursor` produces a duplicated insert
|
|
484
699
|
// on the second invocation. cursorRef is the canonical fix — do
|
|
485
700
|
// NOT re-introduce closure `cursor` inside setLine updaters.
|
|
@@ -499,7 +714,7 @@ export function InputBox(props) {
|
|
|
499
714
|
: Math.min(paletteIndex, paletteView.rows.length - 1);
|
|
500
715
|
const divider = '─'.repeat(innerWidth);
|
|
501
716
|
const focusedMatch = search ? search.matches[search.focusedIndex] : undefined;
|
|
502
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "
|
|
717
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "#3da9fc", dimColor: true, children: divider }), _jsx(Box, { paddingX: 1, flexDirection: "column", children: search ? (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: "#3da9fc", children: '(reverse-i-search) ' }), _jsx(Text, { children: `\`${search.query}\`: ` }), _jsx(Text, { color: "yellow", children: focusedMatch ? focusedMatch.brief : '(no match)' })] }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: `Ctrl+R next · Ctrl+S prev · Enter accept · Esc cancel · ${search.matches.length} match${search.matches.length === 1 ? '' : 'es'}` }) })] })) : (_jsxs(Box, { children: [_jsx(Text, { color: "#3da9fc", children: '› ' }), _jsx(Text, { children: renderLineWithCursor(line, cursor, cursorVisible) })] })) }), _jsx(Text, { color: "#3da9fc", dimColor: true, children: divider }), modeCycleToast ? (_jsx(Box, { children: _jsx(Text, { color: "#3da9fc", bold: true, children: ` ${modeCycleToast}` }) })) : null, ctrlCToast ? (_jsx(Box, { children: _jsx(Text, { color: "yellow", bold: true, children: ` ${ctrlCToast}` }) })) : null, line.length > innerWidth - 4 ? (_jsxs(Box, { children: [_jsx(Text, { color: "gray", children: '┊ ' }), _jsx(Text, { dimColor: true, children: 'line wraps - Enter still submits' })] })) : null, _jsx(SlashPalette, { rows: paletteView.rows, focusedIndex: clampedPaletteIndex, totalBeforeLimit: paletteView.totalBeforeLimit }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: '↑/↓ history · Ctrl+R search · / commands · Shift+Tab mode · Enter brief · Esc cancel · Ctrl+C abort / ×2 exit' }) })] }));
|
|
503
718
|
}
|
|
504
719
|
/**
|
|
505
720
|
* Render the line with the cursor glyph inserted at `cursor`. The cursor
|
package/dist/tui/login-picker.js
CHANGED
|
@@ -54,15 +54,15 @@ export function LoginPicker(props) {
|
|
|
54
54
|
if (input === '3')
|
|
55
55
|
props.onSelect('env');
|
|
56
56
|
});
|
|
57
|
-
return (_jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [_jsxs(Box, { children: [_jsx(Text, { bold: true, children: "Sign in to Pugi" }), _jsx(Text, { dimColor: true, children: `
|
|
57
|
+
return (_jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [_jsxs(Box, { children: [_jsx(Text, { bold: true, children: "Sign in to Pugi" }), _jsx(Text, { dimColor: true, children: ` (endpoint: ${props.apiUrl})` })] }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: ITEMS.map((item, itemIndex) => {
|
|
58
58
|
const isSelected = itemIndex === index;
|
|
59
59
|
return (_jsx(PickerRow, { isSelected: isSelected, title: item.title, hint: item.hint }, item.provider));
|
|
60
|
-
}) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: '↑/↓ select
|
|
60
|
+
}) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: '↑/↓ select Enter confirm Esc cancel' }) })] }));
|
|
61
61
|
}
|
|
62
62
|
function PickerRow({ isSelected, title, hint, }) {
|
|
63
63
|
// Arrow glyph + padded title so highlighted and dim rows share
|
|
64
64
|
// column alignment.
|
|
65
|
-
const indicator = isSelected ? '▸ ' : '
|
|
65
|
+
const indicator = isSelected ? '▸ ' : ' ';
|
|
66
66
|
const padded = title.padEnd(22, ' ');
|
|
67
67
|
return (_jsxs(Text, { children: [_jsxs(Text, { color: isSelected ? 'cyan' : undefined, bold: isSelected, children: [indicator, padded] }), _jsx(Text, { dimColor: true, children: hint })] }));
|
|
68
68
|
}
|
|
@@ -95,7 +95,7 @@ function parseBlocks(source) {
|
|
|
95
95
|
return blocks;
|
|
96
96
|
}
|
|
97
97
|
/* ------------------------------------------------------------------ */
|
|
98
|
-
/* Block renderers
|
|
98
|
+
/* Block renderers */
|
|
99
99
|
/* ------------------------------------------------------------------ */
|
|
100
100
|
function renderBlock(block, key) {
|
|
101
101
|
switch (block.kind) {
|
|
@@ -107,9 +107,9 @@ function renderBlock(block, key) {
|
|
|
107
107
|
case 'paragraph':
|
|
108
108
|
return (_jsx(Text, { children: renderInline(block.text) }, key));
|
|
109
109
|
case 'bullet':
|
|
110
|
-
return (_jsxs(Box, { children: [_jsx(Text, { color: "
|
|
110
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: "#3da9fc", children: '• ' }), _jsx(Text, { children: renderInline(block.text) })] }, key));
|
|
111
111
|
case 'ordered':
|
|
112
|
-
return (_jsxs(Box, { children: [_jsx(Text, { color: "
|
|
112
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: "#3da9fc", children: `${block.index}. ` }), _jsx(Text, { children: renderInline(block.text) })] }, key));
|
|
113
113
|
case 'code':
|
|
114
114
|
return renderCodeBlock(block.lang, block.body, key);
|
|
115
115
|
case 'blank':
|
|
@@ -148,7 +148,7 @@ function renderCodeLine(line, keywords) {
|
|
|
148
148
|
spans.push(_jsx(Text, { color: "green", children: tok }, key));
|
|
149
149
|
}
|
|
150
150
|
else if (keywords.includes(tok)) {
|
|
151
|
-
spans.push(_jsx(Text, { color: "
|
|
151
|
+
spans.push(_jsx(Text, { color: "#3da9fc", bold: true, children: tok }, key));
|
|
152
152
|
}
|
|
153
153
|
else {
|
|
154
154
|
spans.push(_jsx(Text, { children: tok }, key));
|
|
@@ -184,7 +184,7 @@ function findCommentStart(line) {
|
|
|
184
184
|
return -1;
|
|
185
185
|
}
|
|
186
186
|
/* ------------------------------------------------------------------ */
|
|
187
|
-
/* Inline tokeniser
|
|
187
|
+
/* Inline tokeniser */
|
|
188
188
|
/* ------------------------------------------------------------------ */
|
|
189
189
|
/**
|
|
190
190
|
* Parse one paragraph line into a list of inline spans, then render
|
|
@@ -260,7 +260,7 @@ function renderSpan(span, key) {
|
|
|
260
260
|
case 'code':
|
|
261
261
|
return _jsx(Text, { color: "green", children: span.text }, key);
|
|
262
262
|
case 'link':
|
|
263
|
-
return (_jsxs(Text, { children: [_jsx(Text, { color: "
|
|
263
|
+
return (_jsxs(Text, { children: [_jsx(Text, { color: "#3da9fc", underline: true, children: span.text }), _jsx(Text, { dimColor: true, children: ` (${span.url})` })] }, key));
|
|
264
264
|
}
|
|
265
265
|
}
|
|
266
266
|
//# sourceMappingURL=markdown-render.js.map
|