@nghyane/arcane 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -0
- package/README.md +12 -0
- package/examples/README.md +21 -0
- package/examples/custom-tools/README.md +109 -0
- package/examples/custom-tools/hello/index.ts +20 -0
- package/examples/custom-tools/todo/index.ts +206 -0
- package/examples/extensions/README.md +143 -0
- package/examples/extensions/api-demo.ts +89 -0
- package/examples/extensions/chalk-logger.ts +25 -0
- package/examples/extensions/hello.ts +32 -0
- package/examples/extensions/pirate.ts +43 -0
- package/examples/extensions/plan-mode.ts +550 -0
- package/examples/extensions/reload-runtime.ts +37 -0
- package/examples/extensions/todo.ts +296 -0
- package/examples/extensions/tools.ts +144 -0
- package/examples/extensions/with-deps/index.ts +35 -0
- package/examples/extensions/with-deps/package-lock.json +31 -0
- package/examples/extensions/with-deps/package.json +16 -0
- package/examples/hooks/README.md +56 -0
- package/examples/hooks/auto-commit-on-exit.ts +48 -0
- package/examples/hooks/confirm-destructive.ts +58 -0
- package/examples/hooks/custom-compaction.ts +116 -0
- package/examples/hooks/dirty-repo-guard.ts +51 -0
- package/examples/hooks/file-trigger.ts +40 -0
- package/examples/hooks/git-checkpoint.ts +52 -0
- package/examples/hooks/handoff.ts +150 -0
- package/examples/hooks/permission-gate.ts +33 -0
- package/examples/hooks/protected-paths.ts +29 -0
- package/examples/hooks/qna.ts +119 -0
- package/examples/hooks/status-line.ts +39 -0
- package/examples/sdk/01-minimal.ts +21 -0
- package/examples/sdk/02-custom-model.ts +49 -0
- package/examples/sdk/03-custom-prompt.ts +43 -0
- package/examples/sdk/04-skills.ts +43 -0
- package/examples/sdk/06-extensions.ts +80 -0
- package/examples/sdk/06-hooks.ts +61 -0
- package/examples/sdk/07-context-files.ts +35 -0
- package/examples/sdk/08-prompt-templates.ts +36 -0
- package/examples/sdk/08-slash-commands.ts +41 -0
- package/examples/sdk/09-api-keys-and-oauth.ts +54 -0
- package/examples/sdk/11-sessions.ts +47 -0
- package/examples/sdk/README.md +150 -0
- package/package.json +464 -0
- package/scripts/format-prompts.ts +184 -0
- package/scripts/generate-docs-index.ts +40 -0
- package/scripts/generate-template.ts +32 -0
- package/src/bun-imports.d.ts +22 -0
- package/src/capability/context-file.ts +39 -0
- package/src/capability/extension-module.ts +33 -0
- package/src/capability/extension.ts +47 -0
- package/src/capability/fs.ts +89 -0
- package/src/capability/hook.ts +39 -0
- package/src/capability/index.ts +432 -0
- package/src/capability/instruction.ts +36 -0
- package/src/capability/mcp.ts +60 -0
- package/src/capability/prompt.ts +34 -0
- package/src/capability/rule.ts +223 -0
- package/src/capability/settings.ts +34 -0
- package/src/capability/skill.ts +48 -0
- package/src/capability/slash-command.ts +39 -0
- package/src/capability/ssh.ts +41 -0
- package/src/capability/system-prompt.ts +34 -0
- package/src/capability/tool.ts +37 -0
- package/src/capability/types.ts +156 -0
- package/src/cli/args.ts +259 -0
- package/src/cli/config-cli.ts +357 -0
- package/src/cli/file-processor.ts +124 -0
- package/src/cli/grep-cli.ts +152 -0
- package/src/cli/jupyter-cli.ts +106 -0
- package/src/cli/list-models.ts +103 -0
- package/src/cli/plugin-cli.ts +661 -0
- package/src/cli/session-picker.ts +42 -0
- package/src/cli/setup-cli.ts +376 -0
- package/src/cli/shell-cli.ts +174 -0
- package/src/cli/ssh-cli.ts +179 -0
- package/src/cli/stats-cli.ts +197 -0
- package/src/cli/update-cli.ts +286 -0
- package/src/cli/web-search-cli.ts +143 -0
- package/src/cli.ts +65 -0
- package/src/commands/commit.ts +36 -0
- package/src/commands/config.ts +51 -0
- package/src/commands/grep.ts +41 -0
- package/src/commands/jupyter.ts +32 -0
- package/src/commands/launch.ts +139 -0
- package/src/commands/plugin.ts +70 -0
- package/src/commands/setup.ts +42 -0
- package/src/commands/shell.ts +29 -0
- package/src/commands/ssh.ts +60 -0
- package/src/commands/stats.ts +29 -0
- package/src/commands/update.ts +21 -0
- package/src/commands/web-search.ts +42 -0
- package/src/commit/agentic/agent.ts +311 -0
- package/src/commit/agentic/fallback.ts +96 -0
- package/src/commit/agentic/index.ts +359 -0
- package/src/commit/agentic/prompts/analyze-file.md +22 -0
- package/src/commit/agentic/prompts/session-user.md +25 -0
- package/src/commit/agentic/prompts/split-confirm.md +1 -0
- package/src/commit/agentic/prompts/system.md +38 -0
- package/src/commit/agentic/state.ts +69 -0
- package/src/commit/agentic/tools/analyze-file.ts +118 -0
- package/src/commit/agentic/tools/git-file-diff.ts +194 -0
- package/src/commit/agentic/tools/git-hunk.ts +50 -0
- package/src/commit/agentic/tools/git-overview.ts +84 -0
- package/src/commit/agentic/tools/index.ts +56 -0
- package/src/commit/agentic/tools/propose-changelog.ts +128 -0
- package/src/commit/agentic/tools/propose-commit.ts +154 -0
- package/src/commit/agentic/tools/recent-commits.ts +81 -0
- package/src/commit/agentic/tools/split-commit.ts +280 -0
- package/src/commit/agentic/topo-sort.ts +44 -0
- package/src/commit/agentic/trivial.ts +51 -0
- package/src/commit/agentic/validation.ts +200 -0
- package/src/commit/analysis/conventional.ts +165 -0
- package/src/commit/analysis/index.ts +4 -0
- package/src/commit/analysis/scope.ts +242 -0
- package/src/commit/analysis/summary.ts +112 -0
- package/src/commit/analysis/validation.ts +66 -0
- package/src/commit/changelog/detect.ts +37 -0
- package/src/commit/changelog/generate.ts +110 -0
- package/src/commit/changelog/index.ts +234 -0
- package/src/commit/changelog/parse.ts +44 -0
- package/src/commit/cli.ts +93 -0
- package/src/commit/git/diff.ts +148 -0
- package/src/commit/git/errors.ts +9 -0
- package/src/commit/git/index.ts +211 -0
- package/src/commit/git/operations.ts +54 -0
- package/src/commit/index.ts +5 -0
- package/src/commit/map-reduce/index.ts +64 -0
- package/src/commit/map-reduce/map-phase.ts +178 -0
- package/src/commit/map-reduce/reduce-phase.ts +145 -0
- package/src/commit/map-reduce/utils.ts +9 -0
- package/src/commit/message.ts +11 -0
- package/src/commit/model-selection.ts +69 -0
- package/src/commit/pipeline.ts +243 -0
- package/src/commit/prompts/analysis-system.md +148 -0
- package/src/commit/prompts/analysis-user.md +38 -0
- package/src/commit/prompts/changelog-system.md +50 -0
- package/src/commit/prompts/changelog-user.md +18 -0
- package/src/commit/prompts/file-observer-system.md +24 -0
- package/src/commit/prompts/file-observer-user.md +8 -0
- package/src/commit/prompts/reduce-system.md +50 -0
- package/src/commit/prompts/reduce-user.md +17 -0
- package/src/commit/prompts/summary-retry.md +3 -0
- package/src/commit/prompts/summary-system.md +38 -0
- package/src/commit/prompts/summary-user.md +13 -0
- package/src/commit/prompts/types-description.md +2 -0
- package/src/commit/types.ts +109 -0
- package/src/commit/utils/exclusions.ts +42 -0
- package/src/config/file-lock.ts +121 -0
- package/src/config/keybindings.ts +280 -0
- package/src/config/model-registry.ts +1140 -0
- package/src/config/model-resolver.ts +812 -0
- package/src/config/prompt-templates.ts +526 -0
- package/src/config/resolve-config-value.ts +92 -0
- package/src/config/settings-schema.ts +1236 -0
- package/src/config/settings.ts +706 -0
- package/src/config.ts +414 -0
- package/src/cursor.ts +239 -0
- package/src/debug/index.ts +431 -0
- package/src/debug/log-formatting.ts +60 -0
- package/src/debug/log-viewer.ts +903 -0
- package/src/debug/profiler.ts +158 -0
- package/src/debug/report-bundle.ts +366 -0
- package/src/debug/system-info.ts +112 -0
- package/src/discovery/agents-md.ts +68 -0
- package/src/discovery/agents.ts +199 -0
- package/src/discovery/builtin.ts +815 -0
- package/src/discovery/claude-plugins.ts +205 -0
- package/src/discovery/claude.ts +506 -0
- package/src/discovery/cline.ts +83 -0
- package/src/discovery/codex.ts +532 -0
- package/src/discovery/cursor.ts +218 -0
- package/src/discovery/gemini.ts +395 -0
- package/src/discovery/github.ts +117 -0
- package/src/discovery/helpers.ts +698 -0
- package/src/discovery/index.ts +89 -0
- package/src/discovery/mcp-json.ts +156 -0
- package/src/discovery/opencode.ts +394 -0
- package/src/discovery/ssh.ts +160 -0
- package/src/discovery/vscode.ts +103 -0
- package/src/discovery/windsurf.ts +145 -0
- package/src/exa/company.ts +57 -0
- package/src/exa/index.ts +62 -0
- package/src/exa/linkedin.ts +57 -0
- package/src/exa/mcp-client.ts +289 -0
- package/src/exa/render.ts +244 -0
- package/src/exa/researcher.ts +89 -0
- package/src/exa/search.ts +330 -0
- package/src/exa/types.ts +166 -0
- package/src/exa/websets.ts +247 -0
- package/src/exec/bash-executor.ts +184 -0
- package/src/exec/exec.ts +53 -0
- package/src/export/custom-share.ts +65 -0
- package/src/export/html/index.ts +162 -0
- package/src/export/html/template.css +889 -0
- package/src/export/html/template.generated.ts +2 -0
- package/src/export/html/template.html +45 -0
- package/src/export/html/template.js +1329 -0
- package/src/export/html/template.macro.ts +24 -0
- package/src/export/html/vendor/highlight.min.js +1213 -0
- package/src/export/html/vendor/marked.min.js +6 -0
- package/src/export/ttsr.ts +434 -0
- package/src/extensibility/custom-commands/bundled/review/index.ts +433 -0
- package/src/extensibility/custom-commands/index.ts +15 -0
- package/src/extensibility/custom-commands/loader.ts +231 -0
- package/src/extensibility/custom-commands/types.ts +111 -0
- package/src/extensibility/custom-tools/index.ts +22 -0
- package/src/extensibility/custom-tools/loader.ts +235 -0
- package/src/extensibility/custom-tools/types.ts +226 -0
- package/src/extensibility/custom-tools/wrapper.ts +45 -0
- package/src/extensibility/extensions/index.ts +136 -0
- package/src/extensibility/extensions/loader.ts +520 -0
- package/src/extensibility/extensions/runner.ts +774 -0
- package/src/extensibility/extensions/types.ts +1293 -0
- package/src/extensibility/extensions/wrapper.ts +188 -0
- package/src/extensibility/hooks/index.ts +16 -0
- package/src/extensibility/hooks/loader.ts +273 -0
- package/src/extensibility/hooks/runner.ts +441 -0
- package/src/extensibility/hooks/tool-wrapper.ts +106 -0
- package/src/extensibility/hooks/types.ts +817 -0
- package/src/extensibility/plugins/doctor.ts +65 -0
- package/src/extensibility/plugins/git-url.ts +281 -0
- package/src/extensibility/plugins/index.ts +33 -0
- package/src/extensibility/plugins/installer.ts +192 -0
- package/src/extensibility/plugins/loader.ts +338 -0
- package/src/extensibility/plugins/manager.ts +716 -0
- package/src/extensibility/plugins/parser.ts +105 -0
- package/src/extensibility/plugins/types.ts +190 -0
- package/src/extensibility/skills.ts +385 -0
- package/src/extensibility/slash-commands.ts +287 -0
- package/src/extensibility/tool-proxy.ts +25 -0
- package/src/index.ts +275 -0
- package/src/internal-urls/agent-protocol.ts +136 -0
- package/src/internal-urls/artifact-protocol.ts +97 -0
- package/src/internal-urls/docs-index.generated.ts +54 -0
- package/src/internal-urls/docs-protocol.ts +84 -0
- package/src/internal-urls/index.ts +31 -0
- package/src/internal-urls/json-query.ts +126 -0
- package/src/internal-urls/memory-protocol.ts +133 -0
- package/src/internal-urls/router.ts +70 -0
- package/src/internal-urls/rule-protocol.ts +55 -0
- package/src/internal-urls/skill-protocol.ts +111 -0
- package/src/internal-urls/types.ts +52 -0
- package/src/ipy/executor.ts +556 -0
- package/src/ipy/gateway-coordinator.ts +426 -0
- package/src/ipy/kernel.ts +892 -0
- package/src/ipy/modules.ts +109 -0
- package/src/ipy/prelude.py +831 -0
- package/src/ipy/prelude.ts +3 -0
- package/src/ipy/runtime.ts +222 -0
- package/src/lsp/client.ts +867 -0
- package/src/lsp/clients/biome-client.ts +202 -0
- package/src/lsp/clients/index.ts +50 -0
- package/src/lsp/clients/lsp-linter-client.ts +93 -0
- package/src/lsp/clients/swiftlint-client.ts +120 -0
- package/src/lsp/config.ts +397 -0
- package/src/lsp/defaults.json +464 -0
- package/src/lsp/edits.ts +109 -0
- package/src/lsp/index.ts +1268 -0
- package/src/lsp/lspmux.ts +250 -0
- package/src/lsp/render.ts +689 -0
- package/src/lsp/types.ts +414 -0
- package/src/lsp/utils.ts +549 -0
- package/src/main.ts +773 -0
- package/src/mcp/client.ts +239 -0
- package/src/mcp/config-writer.ts +215 -0
- package/src/mcp/config.ts +363 -0
- package/src/mcp/index.ts +55 -0
- package/src/mcp/json-rpc.ts +84 -0
- package/src/mcp/loader.ts +124 -0
- package/src/mcp/manager.ts +490 -0
- package/src/mcp/oauth-discovery.ts +274 -0
- package/src/mcp/oauth-flow.ts +229 -0
- package/src/mcp/render.ts +123 -0
- package/src/mcp/tool-bridge.ts +372 -0
- package/src/mcp/tool-cache.ts +121 -0
- package/src/mcp/transports/http.ts +332 -0
- package/src/mcp/transports/index.ts +6 -0
- package/src/mcp/transports/stdio.ts +281 -0
- package/src/mcp/types.ts +248 -0
- package/src/memories/index.ts +1099 -0
- package/src/memories/storage.ts +563 -0
- package/src/modes/components/agent-dashboard.ts +1130 -0
- package/src/modes/components/assistant-message.ts +144 -0
- package/src/modes/components/bash-execution.ts +218 -0
- package/src/modes/components/bordered-loader.ts +41 -0
- package/src/modes/components/branch-summary-message.ts +45 -0
- package/src/modes/components/codemode-group.ts +369 -0
- package/src/modes/components/compaction-summary-message.ts +51 -0
- package/src/modes/components/countdown-timer.ts +46 -0
- package/src/modes/components/custom-editor.ts +181 -0
- package/src/modes/components/custom-message.ts +91 -0
- package/src/modes/components/diff.ts +186 -0
- package/src/modes/components/dynamic-border.ts +25 -0
- package/src/modes/components/extensions/extension-dashboard.ts +325 -0
- package/src/modes/components/extensions/extension-list.ts +484 -0
- package/src/modes/components/extensions/index.ts +9 -0
- package/src/modes/components/extensions/inspector-panel.ts +321 -0
- package/src/modes/components/extensions/state-manager.ts +586 -0
- package/src/modes/components/extensions/types.ts +191 -0
- package/src/modes/components/footer.ts +315 -0
- package/src/modes/components/history-search.ts +157 -0
- package/src/modes/components/hook-editor.ts +101 -0
- package/src/modes/components/hook-input.ts +72 -0
- package/src/modes/components/hook-message.ts +100 -0
- package/src/modes/components/hook-selector.ts +155 -0
- package/src/modes/components/index.ts +41 -0
- package/src/modes/components/keybinding-hints.ts +65 -0
- package/src/modes/components/login-dialog.ts +164 -0
- package/src/modes/components/mcp-add-wizard.ts +1295 -0
- package/src/modes/components/model-selector.ts +625 -0
- package/src/modes/components/oauth-selector.ts +210 -0
- package/src/modes/components/plugin-settings.ts +477 -0
- package/src/modes/components/python-execution.ts +196 -0
- package/src/modes/components/queue-mode-selector.ts +56 -0
- package/src/modes/components/read-tool-group.ts +119 -0
- package/src/modes/components/session-selector.ts +242 -0
- package/src/modes/components/settings-defs.ts +340 -0
- package/src/modes/components/settings-selector.ts +529 -0
- package/src/modes/components/show-images-selector.ts +45 -0
- package/src/modes/components/skill-message.ts +90 -0
- package/src/modes/components/status-line/index.ts +4 -0
- package/src/modes/components/status-line/presets.ts +94 -0
- package/src/modes/components/status-line/segments.ts +352 -0
- package/src/modes/components/status-line/separators.ts +55 -0
- package/src/modes/components/status-line/types.ts +75 -0
- package/src/modes/components/status-line-segment-editor.ts +354 -0
- package/src/modes/components/status-line.ts +421 -0
- package/src/modes/components/theme-selector.ts +63 -0
- package/src/modes/components/thinking-selector.ts +64 -0
- package/src/modes/components/todo-display.ts +115 -0
- package/src/modes/components/todo-reminder.ts +40 -0
- package/src/modes/components/tool-execution.ts +703 -0
- package/src/modes/components/tree-selector.ts +904 -0
- package/src/modes/components/ttsr-notification.ts +80 -0
- package/src/modes/components/user-message-selector.ts +146 -0
- package/src/modes/components/user-message.ts +22 -0
- package/src/modes/components/visual-truncate.ts +63 -0
- package/src/modes/components/welcome.ts +247 -0
- package/src/modes/controllers/command-controller.ts +1120 -0
- package/src/modes/controllers/event-controller.ts +479 -0
- package/src/modes/controllers/extension-ui-controller.ts +778 -0
- package/src/modes/controllers/input-controller.ts +671 -0
- package/src/modes/controllers/mcp-command-controller.ts +1315 -0
- package/src/modes/controllers/selector-controller.ts +712 -0
- package/src/modes/controllers/ssh-command-controller.ts +452 -0
- package/src/modes/index.ts +15 -0
- package/src/modes/interactive-mode.ts +1027 -0
- package/src/modes/print-mode.ts +191 -0
- package/src/modes/rpc/rpc-client.ts +583 -0
- package/src/modes/rpc/rpc-mode.ts +700 -0
- package/src/modes/rpc/rpc-types.ts +236 -0
- package/src/modes/theme/dark.json +95 -0
- package/src/modes/theme/defaults/alabaster.json +93 -0
- package/src/modes/theme/defaults/amethyst.json +96 -0
- package/src/modes/theme/defaults/anthracite.json +93 -0
- package/src/modes/theme/defaults/basalt.json +91 -0
- package/src/modes/theme/defaults/birch.json +95 -0
- package/src/modes/theme/defaults/dark-abyss.json +91 -0
- package/src/modes/theme/defaults/dark-arctic.json +104 -0
- package/src/modes/theme/defaults/dark-aurora.json +95 -0
- package/src/modes/theme/defaults/dark-catppuccin.json +107 -0
- package/src/modes/theme/defaults/dark-cavern.json +91 -0
- package/src/modes/theme/defaults/dark-copper.json +95 -0
- package/src/modes/theme/defaults/dark-cosmos.json +90 -0
- package/src/modes/theme/defaults/dark-cyberpunk.json +102 -0
- package/src/modes/theme/defaults/dark-dracula.json +98 -0
- package/src/modes/theme/defaults/dark-eclipse.json +91 -0
- package/src/modes/theme/defaults/dark-ember.json +95 -0
- package/src/modes/theme/defaults/dark-equinox.json +90 -0
- package/src/modes/theme/defaults/dark-forest.json +96 -0
- package/src/modes/theme/defaults/dark-github.json +105 -0
- package/src/modes/theme/defaults/dark-gruvbox.json +112 -0
- package/src/modes/theme/defaults/dark-lavender.json +95 -0
- package/src/modes/theme/defaults/dark-lunar.json +89 -0
- package/src/modes/theme/defaults/dark-midnight.json +95 -0
- package/src/modes/theme/defaults/dark-monochrome.json +94 -0
- package/src/modes/theme/defaults/dark-monokai.json +98 -0
- package/src/modes/theme/defaults/dark-nebula.json +90 -0
- package/src/modes/theme/defaults/dark-nord.json +97 -0
- package/src/modes/theme/defaults/dark-ocean.json +101 -0
- package/src/modes/theme/defaults/dark-one.json +100 -0
- package/src/modes/theme/defaults/dark-rainforest.json +91 -0
- package/src/modes/theme/defaults/dark-reef.json +91 -0
- package/src/modes/theme/defaults/dark-retro.json +92 -0
- package/src/modes/theme/defaults/dark-rose-pine.json +96 -0
- package/src/modes/theme/defaults/dark-sakura.json +95 -0
- package/src/modes/theme/defaults/dark-slate.json +95 -0
- package/src/modes/theme/defaults/dark-solarized.json +97 -0
- package/src/modes/theme/defaults/dark-solstice.json +90 -0
- package/src/modes/theme/defaults/dark-starfall.json +91 -0
- package/src/modes/theme/defaults/dark-sunset.json +99 -0
- package/src/modes/theme/defaults/dark-swamp.json +90 -0
- package/src/modes/theme/defaults/dark-synthwave.json +103 -0
- package/src/modes/theme/defaults/dark-taiga.json +91 -0
- package/src/modes/theme/defaults/dark-terminal.json +95 -0
- package/src/modes/theme/defaults/dark-tokyo-night.json +101 -0
- package/src/modes/theme/defaults/dark-tundra.json +91 -0
- package/src/modes/theme/defaults/dark-twilight.json +91 -0
- package/src/modes/theme/defaults/dark-volcanic.json +91 -0
- package/src/modes/theme/defaults/graphite.json +92 -0
- package/src/modes/theme/defaults/index.ts +195 -0
- package/src/modes/theme/defaults/light-arctic.json +107 -0
- package/src/modes/theme/defaults/light-aurora-day.json +91 -0
- package/src/modes/theme/defaults/light-canyon.json +91 -0
- package/src/modes/theme/defaults/light-catppuccin.json +106 -0
- package/src/modes/theme/defaults/light-cirrus.json +90 -0
- package/src/modes/theme/defaults/light-coral.json +95 -0
- package/src/modes/theme/defaults/light-cyberpunk.json +96 -0
- package/src/modes/theme/defaults/light-dawn.json +90 -0
- package/src/modes/theme/defaults/light-dunes.json +91 -0
- package/src/modes/theme/defaults/light-eucalyptus.json +95 -0
- package/src/modes/theme/defaults/light-forest.json +100 -0
- package/src/modes/theme/defaults/light-frost.json +95 -0
- package/src/modes/theme/defaults/light-github.json +115 -0
- package/src/modes/theme/defaults/light-glacier.json +91 -0
- package/src/modes/theme/defaults/light-gruvbox.json +108 -0
- package/src/modes/theme/defaults/light-haze.json +90 -0
- package/src/modes/theme/defaults/light-honeycomb.json +95 -0
- package/src/modes/theme/defaults/light-lagoon.json +91 -0
- package/src/modes/theme/defaults/light-lavender.json +95 -0
- package/src/modes/theme/defaults/light-meadow.json +91 -0
- package/src/modes/theme/defaults/light-mint.json +95 -0
- package/src/modes/theme/defaults/light-monochrome.json +101 -0
- package/src/modes/theme/defaults/light-ocean.json +99 -0
- package/src/modes/theme/defaults/light-one.json +99 -0
- package/src/modes/theme/defaults/light-opal.json +91 -0
- package/src/modes/theme/defaults/light-orchard.json +91 -0
- package/src/modes/theme/defaults/light-paper.json +95 -0
- package/src/modes/theme/defaults/light-prism.json +90 -0
- package/src/modes/theme/defaults/light-retro.json +98 -0
- package/src/modes/theme/defaults/light-sand.json +95 -0
- package/src/modes/theme/defaults/light-savanna.json +91 -0
- package/src/modes/theme/defaults/light-solarized.json +102 -0
- package/src/modes/theme/defaults/light-soleil.json +90 -0
- package/src/modes/theme/defaults/light-sunset.json +99 -0
- package/src/modes/theme/defaults/light-synthwave.json +98 -0
- package/src/modes/theme/defaults/light-tokyo-night.json +111 -0
- package/src/modes/theme/defaults/light-wetland.json +91 -0
- package/src/modes/theme/defaults/light-zenith.json +89 -0
- package/src/modes/theme/defaults/limestone.json +94 -0
- package/src/modes/theme/defaults/mahogany.json +97 -0
- package/src/modes/theme/defaults/marble.json +93 -0
- package/src/modes/theme/defaults/obsidian.json +91 -0
- package/src/modes/theme/defaults/onyx.json +91 -0
- package/src/modes/theme/defaults/pearl.json +93 -0
- package/src/modes/theme/defaults/porcelain.json +91 -0
- package/src/modes/theme/defaults/quartz.json +96 -0
- package/src/modes/theme/defaults/sandstone.json +95 -0
- package/src/modes/theme/defaults/titanium.json +90 -0
- package/src/modes/theme/light.json +93 -0
- package/src/modes/theme/mermaid-cache.ts +111 -0
- package/src/modes/theme/theme-schema.json +429 -0
- package/src/modes/theme/theme.ts +2333 -0
- package/src/modes/types.ts +216 -0
- package/src/modes/utils/ui-helpers.ts +529 -0
- package/src/patch/applicator.ts +1482 -0
- package/src/patch/diff.ts +425 -0
- package/src/patch/fuzzy.ts +784 -0
- package/src/patch/hashline.ts +972 -0
- package/src/patch/index.ts +964 -0
- package/src/patch/normalize.ts +397 -0
- package/src/patch/normative.ts +72 -0
- package/src/patch/parser.ts +532 -0
- package/src/patch/shared.ts +400 -0
- package/src/patch/types.ts +292 -0
- package/src/priority.json +35 -0
- package/src/prompts/agents/explore.md +48 -0
- package/src/prompts/agents/frontmatter.md +9 -0
- package/src/prompts/agents/init.md +36 -0
- package/src/prompts/agents/librarian.md +53 -0
- package/src/prompts/agents/oracle.md +51 -0
- package/src/prompts/agents/reviewer.md +70 -0
- package/src/prompts/agents/task.md +14 -0
- package/src/prompts/compaction/branch-summary-context.md +5 -0
- package/src/prompts/compaction/branch-summary-preamble.md +2 -0
- package/src/prompts/compaction/branch-summary.md +30 -0
- package/src/prompts/compaction/compaction-short-summary.md +9 -0
- package/src/prompts/compaction/compaction-summary-context.md +5 -0
- package/src/prompts/compaction/compaction-summary.md +38 -0
- package/src/prompts/compaction/compaction-turn-prefix.md +17 -0
- package/src/prompts/compaction/compaction-update-summary.md +45 -0
- package/src/prompts/memories/consolidation.md +30 -0
- package/src/prompts/memories/read_path.md +11 -0
- package/src/prompts/memories/stage_one_input.md +6 -0
- package/src/prompts/memories/stage_one_system.md +21 -0
- package/src/prompts/review-request.md +64 -0
- package/src/prompts/system/agent-creation-architect.md +65 -0
- package/src/prompts/system/agent-creation-user.md +6 -0
- package/src/prompts/system/custom-system-prompt.md +68 -0
- package/src/prompts/system/file-operations.md +10 -0
- package/src/prompts/system/subagent-submit-reminder.md +11 -0
- package/src/prompts/system/subagent-system-prompt.md +31 -0
- package/src/prompts/system/subagent-user-prompt.md +8 -0
- package/src/prompts/system/summarization-system.md +3 -0
- package/src/prompts/system/system-prompt.md +300 -0
- package/src/prompts/system/title-system.md +2 -0
- package/src/prompts/system/ttsr-interrupt.md +7 -0
- package/src/prompts/system/web-search.md +28 -0
- package/src/prompts/tools/ask.md +44 -0
- package/src/prompts/tools/bash.md +24 -0
- package/src/prompts/tools/browser.md +33 -0
- package/src/prompts/tools/calculator.md +12 -0
- package/src/prompts/tools/explore.md +29 -0
- package/src/prompts/tools/fetch.md +16 -0
- package/src/prompts/tools/find.md +18 -0
- package/src/prompts/tools/gemini-image.md +23 -0
- package/src/prompts/tools/grep.md +28 -0
- package/src/prompts/tools/hashline.md +232 -0
- package/src/prompts/tools/librarian.md +24 -0
- package/src/prompts/tools/lsp.md +28 -0
- package/src/prompts/tools/oracle.md +26 -0
- package/src/prompts/tools/patch.md +74 -0
- package/src/prompts/tools/python.md +66 -0
- package/src/prompts/tools/read.md +36 -0
- package/src/prompts/tools/replace.md +38 -0
- package/src/prompts/tools/reviewer.md +41 -0
- package/src/prompts/tools/ssh.md +51 -0
- package/src/prompts/tools/task-summary.md +28 -0
- package/src/prompts/tools/task.md +275 -0
- package/src/prompts/tools/todo-write.md +65 -0
- package/src/prompts/tools/undo-edit.md +7 -0
- package/src/prompts/tools/web-search.md +19 -0
- package/src/prompts/tools/write.md +18 -0
- package/src/sdk.ts +1287 -0
- package/src/secrets/index.ts +116 -0
- package/src/secrets/obfuscator.ts +269 -0
- package/src/secrets/regex.ts +21 -0
- package/src/session/agent-session.ts +4669 -0
- package/src/session/agent-storage.ts +621 -0
- package/src/session/artifacts.ts +132 -0
- package/src/session/auth-storage.ts +1433 -0
- package/src/session/blob-store.ts +103 -0
- package/src/session/compaction/branch-summarization.ts +315 -0
- package/src/session/compaction/compaction.ts +864 -0
- package/src/session/compaction/index.ts +7 -0
- package/src/session/compaction/pruning.ts +91 -0
- package/src/session/compaction/utils.ts +171 -0
- package/src/session/history-storage.ts +170 -0
- package/src/session/messages.ts +317 -0
- package/src/session/session-manager.ts +2276 -0
- package/src/session/session-storage.ts +342 -0
- package/src/session/streaming-output.ts +565 -0
- package/src/slash-commands/builtin-registry.ts +439 -0
- package/src/ssh/config-writer.ts +183 -0
- package/src/ssh/connection-manager.ts +444 -0
- package/src/ssh/ssh-executor.ts +127 -0
- package/src/ssh/sshfs-mount.ts +135 -0
- package/src/stt/downloader.ts +71 -0
- package/src/stt/index.ts +3 -0
- package/src/stt/recorder.ts +351 -0
- package/src/stt/setup.ts +52 -0
- package/src/stt/stt-controller.ts +160 -0
- package/src/stt/transcribe.py +70 -0
- package/src/stt/transcriber.ts +91 -0
- package/src/system-prompt.ts +685 -0
- package/src/task/agents.ts +155 -0
- package/src/task/batch.ts +102 -0
- package/src/task/commands.ts +134 -0
- package/src/task/discovery.ts +126 -0
- package/src/task/executor.ts +908 -0
- package/src/task/index.ts +223 -0
- package/src/task/output-manager.ts +107 -0
- package/src/task/parallel.ts +84 -0
- package/src/task/render.ts +326 -0
- package/src/task/subprocess-tool-registry.ts +88 -0
- package/src/task/template.ts +32 -0
- package/src/task/types.ts +144 -0
- package/src/tools/ask.ts +523 -0
- package/src/tools/bash-interactive.ts +419 -0
- package/src/tools/bash-interceptor.ts +105 -0
- package/src/tools/bash-normalize.ts +107 -0
- package/src/tools/bash-skill-urls.ts +177 -0
- package/src/tools/bash.ts +347 -0
- package/src/tools/browser.ts +1374 -0
- package/src/tools/calculator.ts +537 -0
- package/src/tools/context.ts +39 -0
- package/src/tools/explore.ts +23 -0
- package/src/tools/fetch.ts +1091 -0
- package/src/tools/find.ts +540 -0
- package/src/tools/fs-cache-invalidation.ts +28 -0
- package/src/tools/gemini-image.ts +907 -0
- package/src/tools/grep.ts +489 -0
- package/src/tools/index.ts +337 -0
- package/src/tools/json-tree.ts +231 -0
- package/src/tools/jtd-to-json-schema.ts +247 -0
- package/src/tools/jtd-to-typescript.ts +198 -0
- package/src/tools/librarian.ts +33 -0
- package/src/tools/list-limit.ts +40 -0
- package/src/tools/notebook.ts +287 -0
- package/src/tools/oracle.ts +40 -0
- package/src/tools/output-meta.ts +459 -0
- package/src/tools/output-utils.ts +63 -0
- package/src/tools/path-utils.ts +116 -0
- package/src/tools/puppeteer/00_stealth_tampering.txt +63 -0
- package/src/tools/puppeteer/01_stealth_activity.txt +20 -0
- package/src/tools/puppeteer/02_stealth_hairline.txt +11 -0
- package/src/tools/puppeteer/03_stealth_botd.txt +384 -0
- package/src/tools/puppeteer/04_stealth_iframe.txt +81 -0
- package/src/tools/puppeteer/05_stealth_webgl.txt +75 -0
- package/src/tools/puppeteer/06_stealth_screen.txt +72 -0
- package/src/tools/puppeteer/07_stealth_fonts.txt +97 -0
- package/src/tools/puppeteer/08_stealth_audio.txt +51 -0
- package/src/tools/puppeteer/09_stealth_locale.txt +46 -0
- package/src/tools/puppeteer/10_stealth_plugins.txt +206 -0
- package/src/tools/puppeteer/11_stealth_hardware.txt +8 -0
- package/src/tools/puppeteer/12_stealth_codecs.txt +40 -0
- package/src/tools/puppeteer/13_stealth_worker.txt +74 -0
- package/src/tools/python.ts +1118 -0
- package/src/tools/read.ts +1193 -0
- package/src/tools/render-utils.ts +680 -0
- package/src/tools/renderers.ts +60 -0
- package/src/tools/reviewer-tool.ts +41 -0
- package/src/tools/ssh.ts +326 -0
- package/src/tools/subagent-tool.ts +169 -0
- package/src/tools/submit-result.ts +152 -0
- package/src/tools/todo-write.ts +255 -0
- package/src/tools/tool-errors.ts +92 -0
- package/src/tools/tool-result.ts +86 -0
- package/src/tools/undo-edit.ts +145 -0
- package/src/tools/undo-history.ts +22 -0
- package/src/tools/write.ts +274 -0
- package/src/tui/code-cell.ts +108 -0
- package/src/tui/file-list.ts +47 -0
- package/src/tui/index.ts +11 -0
- package/src/tui/output-block.ts +144 -0
- package/src/tui/status-line.ts +39 -0
- package/src/tui/tree-list.ts +53 -0
- package/src/tui/types.ts +16 -0
- package/src/tui/utils.ts +116 -0
- package/src/utils/changelog.ts +98 -0
- package/src/utils/event-bus.ts +33 -0
- package/src/utils/external-editor.ts +59 -0
- package/src/utils/file-display-mode.ts +36 -0
- package/src/utils/file-mentions.ts +384 -0
- package/src/utils/frontmatter.ts +101 -0
- package/src/utils/fuzzy.ts +108 -0
- package/src/utils/ignore-files.ts +119 -0
- package/src/utils/image-convert.ts +27 -0
- package/src/utils/image-resize.ts +236 -0
- package/src/utils/mime.ts +30 -0
- package/src/utils/open.ts +20 -0
- package/src/utils/shell-snapshot.ts +199 -0
- package/src/utils/timings.ts +26 -0
- package/src/utils/title-generator.ts +167 -0
- package/src/utils/tools-manager.ts +362 -0
- package/src/web/scrapers/artifacthub.ts +215 -0
- package/src/web/scrapers/arxiv.ts +88 -0
- package/src/web/scrapers/aur.ts +175 -0
- package/src/web/scrapers/biorxiv.ts +141 -0
- package/src/web/scrapers/bluesky.ts +284 -0
- package/src/web/scrapers/brew.ts +177 -0
- package/src/web/scrapers/cheatsh.ts +78 -0
- package/src/web/scrapers/chocolatey.ts +158 -0
- package/src/web/scrapers/choosealicense.ts +110 -0
- package/src/web/scrapers/cisa-kev.ts +100 -0
- package/src/web/scrapers/clojars.ts +180 -0
- package/src/web/scrapers/coingecko.ts +184 -0
- package/src/web/scrapers/crates-io.ts +128 -0
- package/src/web/scrapers/crossref.ts +149 -0
- package/src/web/scrapers/devto.ts +177 -0
- package/src/web/scrapers/discogs.ts +307 -0
- package/src/web/scrapers/discourse.ts +221 -0
- package/src/web/scrapers/dockerhub.ts +160 -0
- package/src/web/scrapers/fdroid.ts +158 -0
- package/src/web/scrapers/firefox-addons.ts +214 -0
- package/src/web/scrapers/flathub.ts +239 -0
- package/src/web/scrapers/github-gist.ts +68 -0
- package/src/web/scrapers/github.ts +490 -0
- package/src/web/scrapers/gitlab.ts +456 -0
- package/src/web/scrapers/go-pkg.ts +275 -0
- package/src/web/scrapers/hackage.ts +94 -0
- package/src/web/scrapers/hackernews.ts +208 -0
- package/src/web/scrapers/hex.ts +121 -0
- package/src/web/scrapers/huggingface.ts +385 -0
- package/src/web/scrapers/iacr.ts +86 -0
- package/src/web/scrapers/index.ts +249 -0
- package/src/web/scrapers/jetbrains-marketplace.ts +169 -0
- package/src/web/scrapers/lemmy.ts +220 -0
- package/src/web/scrapers/lobsters.ts +186 -0
- package/src/web/scrapers/mastodon.ts +310 -0
- package/src/web/scrapers/maven.ts +152 -0
- package/src/web/scrapers/mdn.ts +172 -0
- package/src/web/scrapers/metacpan.ts +253 -0
- package/src/web/scrapers/musicbrainz.ts +272 -0
- package/src/web/scrapers/npm.ts +114 -0
- package/src/web/scrapers/nuget.ts +205 -0
- package/src/web/scrapers/nvd.ts +243 -0
- package/src/web/scrapers/ollama.ts +265 -0
- package/src/web/scrapers/open-vsx.ts +119 -0
- package/src/web/scrapers/opencorporates.ts +275 -0
- package/src/web/scrapers/openlibrary.ts +319 -0
- package/src/web/scrapers/orcid.ts +298 -0
- package/src/web/scrapers/osv.ts +192 -0
- package/src/web/scrapers/packagist.ts +174 -0
- package/src/web/scrapers/pub-dev.ts +185 -0
- package/src/web/scrapers/pubmed.ts +177 -0
- package/src/web/scrapers/pypi.ts +129 -0
- package/src/web/scrapers/rawg.ts +124 -0
- package/src/web/scrapers/readthedocs.ts +125 -0
- package/src/web/scrapers/reddit.ts +104 -0
- package/src/web/scrapers/repology.ts +262 -0
- package/src/web/scrapers/rfc.ts +209 -0
- package/src/web/scrapers/rubygems.ts +117 -0
- package/src/web/scrapers/searchcode.ts +217 -0
- package/src/web/scrapers/sec-edgar.ts +274 -0
- package/src/web/scrapers/semantic-scholar.ts +190 -0
- package/src/web/scrapers/snapcraft.ts +200 -0
- package/src/web/scrapers/sourcegraph.ts +373 -0
- package/src/web/scrapers/spdx.ts +121 -0
- package/src/web/scrapers/spotify.ts +217 -0
- package/src/web/scrapers/stackoverflow.ts +124 -0
- package/src/web/scrapers/terraform.ts +304 -0
- package/src/web/scrapers/tldr.ts +51 -0
- package/src/web/scrapers/twitter.ts +97 -0
- package/src/web/scrapers/types.ts +200 -0
- package/src/web/scrapers/utils.ts +142 -0
- package/src/web/scrapers/vimeo.ts +152 -0
- package/src/web/scrapers/vscode-marketplace.ts +195 -0
- package/src/web/scrapers/w3c.ts +163 -0
- package/src/web/scrapers/wikidata.ts +357 -0
- package/src/web/scrapers/wikipedia.ts +95 -0
- package/src/web/scrapers/youtube.ts +312 -0
- package/src/web/search/auth.ts +178 -0
- package/src/web/search/index.ts +598 -0
- package/src/web/search/provider.ts +77 -0
- package/src/web/search/providers/anthropic.ts +284 -0
- package/src/web/search/providers/base.ts +22 -0
- package/src/web/search/providers/brave.ts +165 -0
- package/src/web/search/providers/codex.ts +377 -0
- package/src/web/search/providers/exa.ts +158 -0
- package/src/web/search/providers/gemini.ts +437 -0
- package/src/web/search/providers/jina.ts +99 -0
- package/src/web/search/providers/kimi.ts +196 -0
- package/src/web/search/providers/perplexity.ts +546 -0
- package/src/web/search/providers/synthetic.ts +136 -0
- package/src/web/search/providers/zai.ts +352 -0
- package/src/web/search/render.ts +299 -0
- package/src/web/search/types.ts +437 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the Extension Control Center dashboard.
|
|
3
|
+
*/
|
|
4
|
+
import type { SourceMeta } from "../../../capability/types";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Extension kinds matching capability types.
|
|
8
|
+
*/
|
|
9
|
+
export type ExtensionKind =
|
|
10
|
+
| "extension-module"
|
|
11
|
+
| "skill"
|
|
12
|
+
| "rule"
|
|
13
|
+
| "tool"
|
|
14
|
+
| "mcp"
|
|
15
|
+
| "prompt"
|
|
16
|
+
| "instruction"
|
|
17
|
+
| "context-file"
|
|
18
|
+
| "hook"
|
|
19
|
+
| "slash-command";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Extension state (active, disabled, or shadowed).
|
|
23
|
+
*/
|
|
24
|
+
export type ExtensionState = "active" | "disabled" | "shadowed";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Reason why an extension is disabled.
|
|
28
|
+
*/
|
|
29
|
+
export type DisabledReason = "provider-disabled" | "item-disabled" | "shadowed";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Unified extension representation for the dashboard.
|
|
33
|
+
* Normalizes all capability types into a common shape.
|
|
34
|
+
*/
|
|
35
|
+
export interface Extension {
|
|
36
|
+
/** Unique ID: `${kind}:${name}` */
|
|
37
|
+
id: string;
|
|
38
|
+
/** Extension kind */
|
|
39
|
+
kind: ExtensionKind;
|
|
40
|
+
/** Extension name */
|
|
41
|
+
name: string;
|
|
42
|
+
/** Display name (may differ from name) */
|
|
43
|
+
displayName: string;
|
|
44
|
+
/** Description if available */
|
|
45
|
+
description?: string;
|
|
46
|
+
/** Trigger pattern (slash command, glob, regex) */
|
|
47
|
+
trigger?: string;
|
|
48
|
+
/** Absolute path to source file */
|
|
49
|
+
path: string;
|
|
50
|
+
/** Source metadata */
|
|
51
|
+
source: {
|
|
52
|
+
provider: string;
|
|
53
|
+
providerName: string;
|
|
54
|
+
level: "user" | "project" | "native";
|
|
55
|
+
};
|
|
56
|
+
/** Current state */
|
|
57
|
+
state: ExtensionState;
|
|
58
|
+
/** Reason for disabled state */
|
|
59
|
+
disabledReason?: DisabledReason;
|
|
60
|
+
/** If shadowed, what shadows it */
|
|
61
|
+
shadowedBy?: string;
|
|
62
|
+
/** Raw item data for inspector */
|
|
63
|
+
raw: unknown;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Tree node types for sidebar hierarchy.
|
|
68
|
+
*/
|
|
69
|
+
export type TreeNodeType = "provider" | "kind" | "item";
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Sidebar tree node.
|
|
73
|
+
*/
|
|
74
|
+
export interface TreeNode {
|
|
75
|
+
/** Unique ID */
|
|
76
|
+
id: string;
|
|
77
|
+
/** Display label */
|
|
78
|
+
label: string;
|
|
79
|
+
/** Node type (provider can be toggled, kind groups items) */
|
|
80
|
+
type: TreeNodeType;
|
|
81
|
+
/** Whether this node/provider is enabled */
|
|
82
|
+
enabled: boolean;
|
|
83
|
+
/** Whether collapsed */
|
|
84
|
+
collapsed: boolean;
|
|
85
|
+
/** Child nodes */
|
|
86
|
+
children: TreeNode[];
|
|
87
|
+
/** Extension count (for display) */
|
|
88
|
+
count?: number;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Flattened tree item for navigation.
|
|
93
|
+
*/
|
|
94
|
+
export interface FlatTreeItem {
|
|
95
|
+
node: TreeNode;
|
|
96
|
+
depth: number;
|
|
97
|
+
index: number;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Focus region in the tabbed dashboard.
|
|
102
|
+
*/
|
|
103
|
+
export type FocusRegion = "tabs" | "list";
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Provider tab representation.
|
|
107
|
+
*/
|
|
108
|
+
export interface ProviderTab {
|
|
109
|
+
/** Provider ID (or "all" for the ALL tab) */
|
|
110
|
+
id: string;
|
|
111
|
+
/** Display label */
|
|
112
|
+
label: string;
|
|
113
|
+
/** Whether provider is enabled (always true for "all") */
|
|
114
|
+
enabled: boolean;
|
|
115
|
+
/** Extension count for this provider */
|
|
116
|
+
count: number;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Tabbed dashboard state.
|
|
121
|
+
*/
|
|
122
|
+
export interface DashboardState {
|
|
123
|
+
/** Provider tabs */
|
|
124
|
+
tabs: ProviderTab[];
|
|
125
|
+
/** Active tab index */
|
|
126
|
+
activeTabIndex: number;
|
|
127
|
+
|
|
128
|
+
/** All extensions (unfiltered) */
|
|
129
|
+
extensions: Extension[];
|
|
130
|
+
/** Extensions filtered by active tab */
|
|
131
|
+
tabFiltered: Extension[];
|
|
132
|
+
/** Extensions filtered by search (applied after tab filter) */
|
|
133
|
+
searchFiltered: Extension[];
|
|
134
|
+
/** Current search query */
|
|
135
|
+
searchQuery: string;
|
|
136
|
+
|
|
137
|
+
/** Selected index in main list */
|
|
138
|
+
listIndex: number;
|
|
139
|
+
/** Scroll offset for main list */
|
|
140
|
+
scrollOffset: number;
|
|
141
|
+
|
|
142
|
+
/** Currently selected extension for inspector */
|
|
143
|
+
selected: Extension | null;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* @deprecated Use FocusRegion instead
|
|
148
|
+
*/
|
|
149
|
+
export type FocusPane = "sidebar" | "main" | "inspector";
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Callbacks from dashboard to parent.
|
|
153
|
+
*/
|
|
154
|
+
export interface DashboardCallbacks {
|
|
155
|
+
/** Called when provider is toggled */
|
|
156
|
+
onProviderToggle: (providerId: string, enabled: boolean) => void;
|
|
157
|
+
/** Called when extension item is toggled */
|
|
158
|
+
onExtensionToggle: (extensionId: string, enabled: boolean) => void;
|
|
159
|
+
/** Called when dashboard is closed */
|
|
160
|
+
onClose: () => void;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Create extension ID from kind and name.
|
|
165
|
+
*/
|
|
166
|
+
export function makeExtensionId(kind: ExtensionKind, name: string): string {
|
|
167
|
+
return `${kind}:${name}`;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Parse extension ID into kind and name.
|
|
172
|
+
*/
|
|
173
|
+
export function parseExtensionId(id: string): { kind: ExtensionKind; name: string } | null {
|
|
174
|
+
const colonIdx = id.indexOf(":");
|
|
175
|
+
if (colonIdx === -1) return null;
|
|
176
|
+
return {
|
|
177
|
+
kind: id.slice(0, colonIdx) as ExtensionKind,
|
|
178
|
+
name: id.slice(colonIdx + 1),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Map SourceMeta to extension source shape.
|
|
184
|
+
*/
|
|
185
|
+
export function sourceFromMeta(meta: SourceMeta): Extension["source"] {
|
|
186
|
+
return {
|
|
187
|
+
provider: meta.provider,
|
|
188
|
+
providerName: meta.providerName,
|
|
189
|
+
level: meta.level,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { type Component, padding, truncateToWidth, visibleWidth } from "@nghyane/arcane-tui";
|
|
4
|
+
import { isEnoent } from "@nghyane/arcane-utils";
|
|
5
|
+
import { getProjectDir } from "@nghyane/arcane-utils/dirs";
|
|
6
|
+
import { theme } from "../../modes/theme/theme";
|
|
7
|
+
import type { AgentSession } from "../../session/agent-session";
|
|
8
|
+
import { shortenPath } from "../../tools/render-utils";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Sanitize text for display in a single-line status.
|
|
12
|
+
* Removes newlines, tabs, carriage returns, and other control characters.
|
|
13
|
+
*/
|
|
14
|
+
function sanitizeStatusText(text: string): string {
|
|
15
|
+
// Replace newlines, tabs, carriage returns with space, then collapse multiple spaces
|
|
16
|
+
return text
|
|
17
|
+
.replace(/[\r\n\t]/g, " ")
|
|
18
|
+
.replace(/ +/g, " ")
|
|
19
|
+
.trim();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Find the git root by walking up from cwd. Returns path and content of .git/HEAD if found. */
|
|
23
|
+
async function findGitHeadPath(): Promise<{ path: string; content: string } | null> {
|
|
24
|
+
let dir = getProjectDir();
|
|
25
|
+
while (true) {
|
|
26
|
+
const gitHeadPath = path.join(dir, ".git", "HEAD");
|
|
27
|
+
try {
|
|
28
|
+
const content = await Bun.file(gitHeadPath).text();
|
|
29
|
+
return { path: gitHeadPath, content };
|
|
30
|
+
} catch (err) {
|
|
31
|
+
if (!isEnoent(err)) throw err;
|
|
32
|
+
}
|
|
33
|
+
const parent = path.dirname(dir);
|
|
34
|
+
if (parent === dir) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
dir = parent;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Footer component that shows pwd, token stats, and context usage
|
|
43
|
+
*/
|
|
44
|
+
export class FooterComponent implements Component {
|
|
45
|
+
#cachedBranch: string | null | undefined = undefined; // undefined = not checked yet, null = not in git repo, string = branch name
|
|
46
|
+
#gitWatcher: fs.FSWatcher | null = null;
|
|
47
|
+
#onBranchChange: (() => void) | null = null;
|
|
48
|
+
#autoCompactEnabled: boolean = true;
|
|
49
|
+
#extensionStatuses: Map<string, string> = new Map();
|
|
50
|
+
|
|
51
|
+
constructor(private readonly session: AgentSession) {}
|
|
52
|
+
|
|
53
|
+
setAutoCompactEnabled(enabled: boolean): void {
|
|
54
|
+
this.#autoCompactEnabled = enabled;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Set extension status text to display in the footer.
|
|
59
|
+
* Text is sanitized (newlines/tabs replaced with spaces) and truncated to terminal width.
|
|
60
|
+
* ANSI escape codes for styling are preserved.
|
|
61
|
+
* @param key - Unique key to identify this status
|
|
62
|
+
* @param text - Status text, or undefined to clear
|
|
63
|
+
*/
|
|
64
|
+
setExtensionStatus(key: string, text: string | undefined): void {
|
|
65
|
+
if (text === undefined) {
|
|
66
|
+
this.#extensionStatuses.delete(key);
|
|
67
|
+
} else {
|
|
68
|
+
this.#extensionStatuses.set(key, text);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Set up a file watcher on .git/HEAD to detect branch changes.
|
|
74
|
+
* Call the provided callback when branch changes.
|
|
75
|
+
*/
|
|
76
|
+
watchBranch(onBranchChange: () => void): void {
|
|
77
|
+
this.#onBranchChange = onBranchChange;
|
|
78
|
+
this.#setupGitWatcher();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
#setupGitWatcher(): void {
|
|
82
|
+
// Clean up existing watcher
|
|
83
|
+
if (this.#gitWatcher) {
|
|
84
|
+
this.#gitWatcher.close();
|
|
85
|
+
this.#gitWatcher = null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
findGitHeadPath().then(result => {
|
|
89
|
+
if (!result) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
this.#gitWatcher = fs.watch(result.path, () => {
|
|
95
|
+
this.#cachedBranch = undefined; // Invalidate cache
|
|
96
|
+
if (this.#onBranchChange) {
|
|
97
|
+
this.#onBranchChange();
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
} catch {
|
|
101
|
+
// Silently fail if we can't watch
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Clean up the file watcher
|
|
108
|
+
*/
|
|
109
|
+
dispose(): void {
|
|
110
|
+
if (this.#gitWatcher) {
|
|
111
|
+
this.#gitWatcher.close();
|
|
112
|
+
this.#gitWatcher = null;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
invalidate(): void {
|
|
117
|
+
// Invalidate cached branch so it gets re-read on next render
|
|
118
|
+
this.#cachedBranch = undefined;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Get current git branch by reading .git/HEAD directly.
|
|
123
|
+
* Returns null if not in a git repo, branch name otherwise.
|
|
124
|
+
*/
|
|
125
|
+
#getCurrentBranch(): string | null {
|
|
126
|
+
// Return cached value if available
|
|
127
|
+
if (this.#cachedBranch !== undefined) {
|
|
128
|
+
return this.#cachedBranch;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Note: fire-and-forget async call - will return undefined on first call
|
|
132
|
+
// This is acceptable since it's a cached value that will update on next render
|
|
133
|
+
findGitHeadPath().then(result => {
|
|
134
|
+
if (!result) {
|
|
135
|
+
this.#cachedBranch = null;
|
|
136
|
+
if (this.#onBranchChange) {
|
|
137
|
+
this.#onBranchChange();
|
|
138
|
+
}
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const content = result.content.trim();
|
|
142
|
+
|
|
143
|
+
if (content.startsWith("ref: refs/heads/")) {
|
|
144
|
+
this.#cachedBranch = content.slice(16);
|
|
145
|
+
} else {
|
|
146
|
+
this.#cachedBranch = "detached";
|
|
147
|
+
}
|
|
148
|
+
if (this.#onBranchChange) {
|
|
149
|
+
this.#onBranchChange();
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// Return undefined while loading (will show on next render once loaded)
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
render(width: number): string[] {
|
|
158
|
+
const state = this.session.state;
|
|
159
|
+
|
|
160
|
+
// Calculate cumulative usage from ALL session entries (not just post-compaction messages)
|
|
161
|
+
let totalInput = 0;
|
|
162
|
+
let totalOutput = 0;
|
|
163
|
+
let totalCacheRead = 0;
|
|
164
|
+
let totalCacheWrite = 0;
|
|
165
|
+
let totalCost = 0;
|
|
166
|
+
|
|
167
|
+
for (const entry of this.session.sessionManager.getEntries()) {
|
|
168
|
+
if (entry.type === "message" && entry.message.role === "assistant") {
|
|
169
|
+
totalInput += entry.message.usage.input;
|
|
170
|
+
totalOutput += entry.message.usage.output;
|
|
171
|
+
totalCacheRead += entry.message.usage.cacheRead;
|
|
172
|
+
totalCacheWrite += entry.message.usage.cacheWrite;
|
|
173
|
+
totalCost += entry.message.usage.cost.total;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Calculate context usage from session (handles compaction correctly).
|
|
178
|
+
// After compaction, tokens are unknown until the next LLM response.
|
|
179
|
+
const contextUsage = this.session.getContextUsage();
|
|
180
|
+
const contextWindow = contextUsage?.contextWindow ?? state.model?.contextWindow ?? 0;
|
|
181
|
+
const contextPercentValue = contextUsage?.percent ?? 0;
|
|
182
|
+
const contextPercent = contextUsage?.percent !== null ? contextPercentValue.toFixed(1) : "?";
|
|
183
|
+
|
|
184
|
+
// Format token counts (similar to web-ui)
|
|
185
|
+
const formatTokens = (count: number): string => {
|
|
186
|
+
if (count < 1000) return count.toString();
|
|
187
|
+
if (count < 10000) return `${(count / 1000).toFixed(1)}k`;
|
|
188
|
+
if (count < 1000000) return `${Math.round(count / 1000)}k`;
|
|
189
|
+
if (count < 10000000) return `${(count / 1000000).toFixed(1)}M`;
|
|
190
|
+
return `${Math.round(count / 1000000)}M`;
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// Replace home directory with ~
|
|
194
|
+
let pwd = shortenPath(getProjectDir());
|
|
195
|
+
|
|
196
|
+
// Add git branch if available
|
|
197
|
+
const branch = this.#getCurrentBranch();
|
|
198
|
+
if (branch) {
|
|
199
|
+
pwd = `${pwd} (${branch})`;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Truncate path if too long to fit width
|
|
203
|
+
if (pwd.length > width) {
|
|
204
|
+
const half = Math.floor(width / 2) - 1;
|
|
205
|
+
if (half > 1) {
|
|
206
|
+
const start = pwd.slice(0, half);
|
|
207
|
+
const end = pwd.slice(-(half - 1));
|
|
208
|
+
pwd = `${start}…${end}`;
|
|
209
|
+
} else {
|
|
210
|
+
pwd = pwd.slice(0, Math.max(1, width));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Build stats line
|
|
215
|
+
const statsParts = [];
|
|
216
|
+
if (totalInput) statsParts.push(`↑${formatTokens(totalInput)}`);
|
|
217
|
+
if (totalOutput) statsParts.push(`↓${formatTokens(totalOutput)}`);
|
|
218
|
+
if (totalCacheRead) statsParts.push(`R${formatTokens(totalCacheRead)}`);
|
|
219
|
+
if (totalCacheWrite) statsParts.push(`W${formatTokens(totalCacheWrite)}`);
|
|
220
|
+
|
|
221
|
+
// Show cost with "(sub)" indicator if using OAuth subscription
|
|
222
|
+
const usingSubscription = state.model ? this.session.modelRegistry.isUsingOAuth(state.model) : false;
|
|
223
|
+
if (totalCost || usingSubscription) {
|
|
224
|
+
const costStr = `$${totalCost.toFixed(3)}${usingSubscription ? " (sub)" : ""}`;
|
|
225
|
+
statsParts.push(costStr);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Colorize context percentage based on usage
|
|
229
|
+
let contextPercentStr: string;
|
|
230
|
+
const autoIndicator = this.#autoCompactEnabled ? " (auto)" : "";
|
|
231
|
+
const contextPercentDisplay =
|
|
232
|
+
contextPercent === "?"
|
|
233
|
+
? `?/${formatTokens(contextWindow)}${autoIndicator}`
|
|
234
|
+
: `${contextPercent}%/${formatTokens(contextWindow)}${autoIndicator}`;
|
|
235
|
+
if (contextPercentValue > 90) {
|
|
236
|
+
contextPercentStr = theme.fg("error", contextPercentDisplay);
|
|
237
|
+
} else if (contextPercentValue > 70) {
|
|
238
|
+
contextPercentStr = theme.fg("warning", contextPercentDisplay);
|
|
239
|
+
} else {
|
|
240
|
+
contextPercentStr = contextPercentDisplay;
|
|
241
|
+
}
|
|
242
|
+
statsParts.push(contextPercentStr);
|
|
243
|
+
|
|
244
|
+
let statsLeft = statsParts.join(" ");
|
|
245
|
+
|
|
246
|
+
// Add model name on the right side, plus thinking level if model supports it
|
|
247
|
+
const modelName = state.model?.id || "no-model";
|
|
248
|
+
|
|
249
|
+
// Add thinking level hint if model supports reasoning and thinking is enabled
|
|
250
|
+
let rightSide = modelName;
|
|
251
|
+
if (state.model?.reasoning) {
|
|
252
|
+
const thinkingLevel = state.thinkingLevel || "off";
|
|
253
|
+
if (thinkingLevel !== "off") {
|
|
254
|
+
rightSide = `${modelName} • ${thinkingLevel}`;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
let statsLeftWidth = visibleWidth(statsLeft);
|
|
259
|
+
const rightSideWidth = visibleWidth(rightSide);
|
|
260
|
+
|
|
261
|
+
// If statsLeft is too wide, truncate it
|
|
262
|
+
if (statsLeftWidth > width) {
|
|
263
|
+
// Truncate statsLeft to fit width (no room for right side)
|
|
264
|
+
const plainStatsLeft = statsLeft.replace(/\x1b\[[0-9;]*m/g, "");
|
|
265
|
+
statsLeft = `${plainStatsLeft.substring(0, width - 1)}…`;
|
|
266
|
+
statsLeftWidth = visibleWidth(statsLeft);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Calculate available space for padding (minimum 2 spaces between stats and model)
|
|
270
|
+
const minPadding = 2;
|
|
271
|
+
const totalNeeded = statsLeftWidth + minPadding + rightSideWidth;
|
|
272
|
+
|
|
273
|
+
let statsLine: string;
|
|
274
|
+
if (totalNeeded <= width) {
|
|
275
|
+
// Both fit - add padding to right-align model
|
|
276
|
+
const pad = padding(width - statsLeftWidth - rightSideWidth);
|
|
277
|
+
statsLine = statsLeft + pad + rightSide;
|
|
278
|
+
} else {
|
|
279
|
+
// Need to truncate right side
|
|
280
|
+
const availableForRight = width - statsLeftWidth - minPadding;
|
|
281
|
+
if (availableForRight > 3) {
|
|
282
|
+
// Truncate to fit (strip ANSI codes for length calculation, then truncate raw string)
|
|
283
|
+
const plainRightSide = rightSide.replace(/\x1b\[[0-9;]*m/g, "");
|
|
284
|
+
const truncatedPlain = plainRightSide.substring(0, availableForRight);
|
|
285
|
+
// For simplicity, just use plain truncated version (loses color, but fits)
|
|
286
|
+
const pad = padding(width - statsLeftWidth - truncatedPlain.length);
|
|
287
|
+
statsLine = statsLeft + pad + truncatedPlain;
|
|
288
|
+
} else {
|
|
289
|
+
// Not enough space for right side at all
|
|
290
|
+
statsLine = statsLeft;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Apply dim to each part separately. statsLeft may contain color codes (for context %)
|
|
295
|
+
// that end with a reset, which would clear an outer dim wrapper. So we dim the parts
|
|
296
|
+
// before and after the colored section independently.
|
|
297
|
+
const dimStatsLeft = theme.fg("dim", statsLeft);
|
|
298
|
+
const remainder = statsLine.slice(statsLeft.length); // padding + rightSide
|
|
299
|
+
const dimRemainder = theme.fg("dim", remainder);
|
|
300
|
+
|
|
301
|
+
const lines = [theme.fg("dim", pwd), dimStatsLeft + dimRemainder];
|
|
302
|
+
|
|
303
|
+
// Add extension statuses on a single line, sorted by key alphabetically
|
|
304
|
+
if (this.#extensionStatuses.size > 0) {
|
|
305
|
+
const sortedStatuses = Array.from(this.#extensionStatuses.entries())
|
|
306
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
307
|
+
.map(([, text]) => sanitizeStatusText(text));
|
|
308
|
+
const statusLine = sortedStatuses.join(" ");
|
|
309
|
+
// Truncate to terminal width with dim ellipsis for consistency with footer style
|
|
310
|
+
lines.push(truncateToWidth(statusLine, width));
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return lines;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type Component,
|
|
3
|
+
Container,
|
|
4
|
+
Ellipsis,
|
|
5
|
+
Input,
|
|
6
|
+
matchesKey,
|
|
7
|
+
padding,
|
|
8
|
+
Spacer,
|
|
9
|
+
Text,
|
|
10
|
+
truncateToWidth,
|
|
11
|
+
visibleWidth,
|
|
12
|
+
} from "@nghyane/arcane-tui";
|
|
13
|
+
import { theme } from "../../modes/theme/theme";
|
|
14
|
+
import type { HistoryEntry, HistoryStorage } from "../../session/history-storage";
|
|
15
|
+
import { DynamicBorder } from "./dynamic-border";
|
|
16
|
+
|
|
17
|
+
class HistoryResultsList implements Component {
|
|
18
|
+
#results: HistoryEntry[] = [];
|
|
19
|
+
#selectedIndex = 0;
|
|
20
|
+
#maxVisible = 10;
|
|
21
|
+
|
|
22
|
+
setResults(results: HistoryEntry[], selectedIndex: number): void {
|
|
23
|
+
this.#results = results;
|
|
24
|
+
this.#selectedIndex = selectedIndex;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
setSelectedIndex(selectedIndex: number): void {
|
|
28
|
+
this.#selectedIndex = selectedIndex;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
invalidate(): void {
|
|
32
|
+
// No cached state to invalidate currently
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
render(width: number): string[] {
|
|
36
|
+
const lines: string[] = [];
|
|
37
|
+
|
|
38
|
+
if (this.#results.length === 0) {
|
|
39
|
+
lines.push(theme.fg("muted", " No matching history"));
|
|
40
|
+
return lines;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const startIndex = Math.max(
|
|
44
|
+
0,
|
|
45
|
+
Math.min(this.#selectedIndex - Math.floor(this.#maxVisible / 2), this.#results.length - this.#maxVisible),
|
|
46
|
+
);
|
|
47
|
+
const endIndex = Math.min(startIndex + this.#maxVisible, this.#results.length);
|
|
48
|
+
|
|
49
|
+
for (let i = startIndex; i < endIndex; i++) {
|
|
50
|
+
const entry = this.#results[i];
|
|
51
|
+
const isSelected = i === this.#selectedIndex;
|
|
52
|
+
|
|
53
|
+
const cursorSymbol = `${theme.nav.cursor} `;
|
|
54
|
+
const cursorWidth = visibleWidth(cursorSymbol);
|
|
55
|
+
const cursor = isSelected ? theme.fg("accent", cursorSymbol) : padding(cursorWidth);
|
|
56
|
+
const maxWidth = width - cursorWidth;
|
|
57
|
+
|
|
58
|
+
const normalized = entry.prompt.replace(/\s+/g, " ").trim();
|
|
59
|
+
const truncated = truncateToWidth(normalized, maxWidth);
|
|
60
|
+
lines.push(cursor + (isSelected ? theme.bold(truncated) : truncated));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (startIndex > 0 || endIndex < this.#results.length) {
|
|
64
|
+
const scrollText = ` (${this.#selectedIndex + 1}/${this.#results.length})`;
|
|
65
|
+
lines.push(theme.fg("muted", truncateToWidth(scrollText, width, Ellipsis.Omit)));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return lines;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export class HistorySearchComponent extends Container {
|
|
73
|
+
#historyStorage: HistoryStorage;
|
|
74
|
+
#searchInput: Input;
|
|
75
|
+
#results: HistoryEntry[] = [];
|
|
76
|
+
#selectedIndex = 0;
|
|
77
|
+
#resultsList: HistoryResultsList;
|
|
78
|
+
#onSelect: (prompt: string) => void;
|
|
79
|
+
#onCancel: () => void;
|
|
80
|
+
#resultLimit = 100;
|
|
81
|
+
|
|
82
|
+
constructor(historyStorage: HistoryStorage, onSelect: (prompt: string) => void, onCancel: () => void) {
|
|
83
|
+
super();
|
|
84
|
+
this.#historyStorage = historyStorage;
|
|
85
|
+
this.#onSelect = onSelect;
|
|
86
|
+
this.#onCancel = onCancel;
|
|
87
|
+
|
|
88
|
+
this.#searchInput = new Input();
|
|
89
|
+
this.#searchInput.onSubmit = () => {
|
|
90
|
+
const selected = this.#results[this.#selectedIndex];
|
|
91
|
+
if (selected) {
|
|
92
|
+
this.#onSelect(selected.prompt);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
this.#searchInput.onEscape = () => {
|
|
96
|
+
this.#onCancel();
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
this.#resultsList = new HistoryResultsList();
|
|
100
|
+
|
|
101
|
+
this.addChild(new Spacer(1));
|
|
102
|
+
this.addChild(new Text(theme.bold("Search History (Ctrl+R)"), 1, 0));
|
|
103
|
+
this.addChild(new Spacer(1));
|
|
104
|
+
this.addChild(new DynamicBorder());
|
|
105
|
+
this.addChild(new Spacer(1));
|
|
106
|
+
this.addChild(this.#searchInput);
|
|
107
|
+
this.addChild(new Spacer(1));
|
|
108
|
+
this.addChild(this.#resultsList);
|
|
109
|
+
this.addChild(new Spacer(1));
|
|
110
|
+
this.addChild(new Text(theme.fg("muted", "up/down navigate enter select esc cancel"), 1, 0));
|
|
111
|
+
this.addChild(new Spacer(1));
|
|
112
|
+
this.addChild(new DynamicBorder());
|
|
113
|
+
|
|
114
|
+
this.#updateResults();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
handleInput(keyData: string): void {
|
|
118
|
+
if (matchesKey(keyData, "up")) {
|
|
119
|
+
if (this.#results.length === 0) return;
|
|
120
|
+
this.#selectedIndex = Math.max(0, this.#selectedIndex - 1);
|
|
121
|
+
this.#resultsList.setSelectedIndex(this.#selectedIndex);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (matchesKey(keyData, "down")) {
|
|
126
|
+
if (this.#results.length === 0) return;
|
|
127
|
+
this.#selectedIndex = Math.min(this.#results.length - 1, this.#selectedIndex + 1);
|
|
128
|
+
this.#resultsList.setSelectedIndex(this.#selectedIndex);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (matchesKey(keyData, "enter") || matchesKey(keyData, "return") || keyData === "\n") {
|
|
133
|
+
const selected = this.#results[this.#selectedIndex];
|
|
134
|
+
if (selected) {
|
|
135
|
+
this.#onSelect(selected.prompt);
|
|
136
|
+
}
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (matchesKey(keyData, "escape") || matchesKey(keyData, "esc")) {
|
|
141
|
+
this.#onCancel();
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
this.#searchInput.handleInput(keyData);
|
|
146
|
+
this.#updateResults();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
#updateResults(): void {
|
|
150
|
+
const query = this.#searchInput.getValue().trim();
|
|
151
|
+
this.#results = query
|
|
152
|
+
? this.#historyStorage.search(query, this.#resultLimit)
|
|
153
|
+
: this.#historyStorage.getRecent(this.#resultLimit);
|
|
154
|
+
this.#selectedIndex = 0;
|
|
155
|
+
this.#resultsList.setResults(this.#results, this.#selectedIndex);
|
|
156
|
+
}
|
|
157
|
+
}
|