@travisennis/acai 0.0.9 → 0.0.11
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/README.md +51 -760
- package/bin/acai +52 -0
- package/dist/agent/index.d.ts +12 -2
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +380 -199
- package/dist/agent/sub-agent.d.ts +23 -0
- package/dist/agent/sub-agent.d.ts.map +1 -0
- package/dist/agent/sub-agent.js +109 -0
- package/dist/cli/index.d.ts +26 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/{cli.js → cli/index.js} +84 -77
- package/dist/{stdin.d.ts → cli/stdin.d.ts} +2 -1
- package/dist/cli/stdin.d.ts.map +1 -0
- package/dist/{stdin.js → cli/stdin.js} +11 -0
- package/dist/commands/copy/index.js +2 -2
- package/dist/commands/copy/utils.d.ts.map +1 -1
- package/dist/commands/copy/utils.js +15 -13
- package/dist/commands/generate-rules/index.d.ts +1 -1
- package/dist/commands/generate-rules/index.d.ts.map +1 -1
- package/dist/commands/generate-rules/index.js +16 -101
- package/dist/commands/generate-rules/service.d.ts +22 -0
- package/dist/commands/generate-rules/service.d.ts.map +1 -0
- package/dist/commands/generate-rules/service.js +103 -0
- package/dist/commands/handoff/index.js +2 -2
- package/dist/commands/health/index.js +1 -1
- package/dist/commands/health/utils.d.ts +3 -2
- package/dist/commands/health/utils.d.ts.map +1 -1
- package/dist/commands/health/utils.js +6 -0
- package/dist/commands/history/index.d.ts +1 -1
- package/dist/commands/history/index.d.ts.map +1 -1
- package/dist/commands/history/index.js +17 -18
- package/dist/commands/history/types.d.ts +38 -0
- package/dist/commands/history/types.d.ts.map +1 -1
- package/dist/commands/history/utils.d.ts.map +1 -1
- package/dist/commands/history/utils.js +63 -58
- package/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +3 -8
- package/dist/commands/init-project/index.d.ts.map +1 -1
- package/dist/commands/init-project/index.js +3 -3
- package/dist/commands/init-project/utils.d.ts +2 -1
- package/dist/commands/init-project/utils.d.ts.map +1 -1
- package/dist/commands/init-project/utils.js +10 -2
- package/dist/commands/list-tools/index.d.ts.map +1 -1
- package/dist/commands/list-tools/index.js +7 -31
- package/dist/commands/manager.d.ts +2 -2
- package/dist/commands/manager.d.ts.map +1 -1
- package/dist/commands/manager.js +55 -33
- package/dist/commands/model/index.d.ts.map +1 -1
- package/dist/commands/model/index.js +20 -151
- package/dist/commands/model/model-panel.d.ts +4 -0
- package/dist/commands/model/model-panel.d.ts.map +1 -0
- package/dist/commands/model/model-panel.js +144 -0
- package/dist/commands/paste/index.d.ts.map +1 -1
- package/dist/commands/paste/index.js +59 -62
- package/dist/commands/paste/utils.d.ts.map +1 -1
- package/dist/commands/paste/utils.js +88 -58
- package/dist/commands/pickup/index.d.ts.map +1 -1
- package/dist/commands/pickup/index.js +6 -3
- package/dist/commands/pickup/utils.js +3 -3
- package/dist/commands/resources/index.d.ts.map +1 -1
- package/dist/commands/resources/index.js +33 -50
- package/dist/commands/review/index.d.ts.map +1 -1
- package/dist/commands/review/index.js +3 -117
- package/dist/commands/review/review-panel.d.ts +3 -0
- package/dist/commands/review/review-panel.d.ts.map +1 -0
- package/dist/commands/review/review-panel.js +186 -0
- package/dist/commands/review/utils.d.ts +15 -1
- package/dist/commands/review/utils.d.ts.map +1 -1
- package/dist/commands/review/utils.js +127 -68
- package/dist/commands/session/index.d.ts +1 -1
- package/dist/commands/session/index.d.ts.map +1 -1
- package/dist/commands/session/index.js +124 -135
- package/dist/commands/shell/index.d.ts.map +1 -1
- package/dist/commands/shell/index.js +16 -1
- package/dist/commands/types.d.ts +2 -2
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/{config.d.ts → config/index.d.ts} +20 -9
- package/dist/config/index.d.ts.map +1 -0
- package/dist/{config.js → config/index.js} +43 -42
- package/dist/execution/index.d.ts.map +1 -1
- package/dist/execution/index.js +75 -55
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +148 -141
- package/dist/middleware/cache.d.ts.map +1 -1
- package/dist/middleware/cache.js +18 -36
- package/dist/models/ai-config.d.ts +1 -0
- package/dist/models/ai-config.d.ts.map +1 -1
- package/dist/models/ai-config.js +4 -3
- package/dist/models/anthropic-provider.d.ts +2 -5
- package/dist/models/anthropic-provider.d.ts.map +1 -1
- package/dist/models/anthropic-provider.js +3 -70
- package/dist/models/deepseek-provider.d.ts +1 -0
- package/dist/models/deepseek-provider.d.ts.map +1 -1
- package/dist/models/google-provider.d.ts +2 -3
- package/dist/models/google-provider.d.ts.map +1 -1
- package/dist/models/google-provider.js +0 -26
- package/dist/models/groq-provider.d.ts +1 -0
- package/dist/models/groq-provider.d.ts.map +1 -1
- package/dist/models/manager.d.ts +13 -2
- package/dist/models/manager.d.ts.map +1 -1
- package/dist/models/manager.js +20 -8
- package/dist/models/openai-provider.d.ts +2 -5
- package/dist/models/openai-provider.d.ts.map +1 -1
- package/dist/models/openai-provider.js +0 -52
- package/dist/models/opencode-go-provider.d.ts +25 -0
- package/dist/models/opencode-go-provider.d.ts.map +1 -0
- package/dist/models/opencode-go-provider.js +78 -0
- package/dist/models/opencode-zen-provider.d.ts +7 -3
- package/dist/models/opencode-zen-provider.d.ts.map +1 -1
- package/dist/models/opencode-zen-provider.js +49 -10
- package/dist/models/openrouter-provider.d.ts +27 -31
- package/dist/models/openrouter-provider.d.ts.map +1 -1
- package/dist/models/openrouter-provider.js +121 -180
- package/dist/models/providers.d.ts +3 -3
- package/dist/models/providers.d.ts.map +1 -1
- package/dist/models/providers.js +6 -0
- package/dist/models/xai-provider.d.ts +4 -3
- package/dist/models/xai-provider.d.ts.map +1 -1
- package/dist/models/xai-provider.js +18 -18
- package/dist/modes/manager.d.ts +24 -0
- package/dist/modes/manager.d.ts.map +1 -0
- package/dist/modes/manager.js +77 -0
- package/dist/modes/prompts.d.ts +2 -0
- package/dist/modes/prompts.d.ts.map +1 -0
- package/dist/modes/prompts.js +142 -0
- package/dist/prompts/mentions.d.ts +11 -0
- package/dist/prompts/mentions.d.ts.map +1 -0
- package/dist/{mentions.js → prompts/mentions.js} +55 -85
- package/dist/{prompts.d.ts → prompts/system-prompt.d.ts} +7 -2
- package/dist/prompts/system-prompt.d.ts.map +1 -0
- package/dist/{prompts.js → prompts/system-prompt.js} +31 -16
- package/dist/repl/index.d.ts +174 -0
- package/dist/repl/index.d.ts.map +1 -0
- package/dist/{repl-new.js → repl/index.js} +397 -76
- package/dist/repl/project-status.d.ts +1 -0
- package/dist/repl/project-status.d.ts.map +1 -1
- package/dist/repl/project-status.js +4 -1
- package/dist/sessions/manager.d.ts +92 -0
- package/dist/sessions/manager.d.ts.map +1 -1
- package/dist/sessions/manager.js +262 -9
- package/dist/sessions/summary.d.ts +4 -0
- package/dist/sessions/summary.d.ts.map +1 -0
- package/dist/sessions/summary.js +30 -0
- package/dist/skills/index.d.ts +29 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +294 -0
- package/dist/subagents/index.d.ts +16 -0
- package/dist/subagents/index.d.ts.map +1 -0
- package/dist/subagents/index.js +231 -0
- package/dist/terminal/control.d.ts +1 -1
- package/dist/terminal/control.d.ts.map +1 -1
- package/dist/terminal/control.js +3 -3
- package/dist/terminal/east-asian-width.d.ts.map +1 -1
- package/dist/terminal/east-asian-width.js +404 -351
- package/dist/terminal/keys.d.ts +17 -0
- package/dist/terminal/keys.d.ts.map +1 -1
- package/dist/terminal/keys.js +37 -0
- package/dist/terminal/select-prompt.d.ts.map +1 -1
- package/dist/terminal/select-prompt.js +24 -12
- package/dist/terminal/string-width.d.ts.map +1 -1
- package/dist/terminal/string-width.js +25 -27
- package/dist/terminal/style.d.ts.map +1 -1
- package/dist/terminal/style.js +4 -7
- package/dist/terminal/supports-color.d.ts.map +1 -1
- package/dist/terminal/supports-color.js +41 -27
- package/dist/terminal/table/cell.d.ts +12 -0
- package/dist/terminal/table/cell.d.ts.map +1 -1
- package/dist/terminal/table/cell.js +40 -25
- package/dist/terminal/table/layout-manager.d.ts.map +1 -1
- package/dist/terminal/table/layout-manager.js +100 -68
- package/dist/terminal/table/utils.d.ts +1 -1
- package/dist/terminal/table/utils.d.ts.map +1 -1
- package/dist/terminal/table/utils.js +17 -10
- package/dist/terminal/wrap-ansi.d.ts.map +1 -1
- package/dist/terminal/wrap-ansi.js +174 -105
- package/dist/tokens/tracker.d.ts +1 -0
- package/dist/tokens/tracker.d.ts.map +1 -1
- package/dist/tokens/tracker.js +3 -0
- package/dist/tools/agent.d.ts +27 -0
- package/dist/tools/agent.d.ts.map +1 -0
- package/dist/tools/agent.js +81 -0
- package/dist/tools/apply-patch.d.ts +62 -0
- package/dist/tools/apply-patch.d.ts.map +1 -0
- package/dist/tools/apply-patch.js +377 -0
- package/dist/tools/bash.d.ts +4 -3
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +349 -141
- package/dist/tools/directory-tree.d.ts +3 -3
- package/dist/tools/directory-tree.d.ts.map +1 -1
- package/dist/tools/directory-tree.js +8 -5
- package/dist/tools/dynamic-tool-loader.d.ts +3 -6
- package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
- package/dist/tools/dynamic-tool-loader.js +20 -4
- package/dist/tools/edit-file.d.ts +7 -7
- package/dist/tools/edit-file.d.ts.map +1 -1
- package/dist/tools/edit-file.js +292 -85
- package/dist/tools/glob.d.ts +6 -6
- package/dist/tools/glob.d.ts.map +1 -1
- package/dist/tools/glob.js +110 -63
- package/dist/tools/grep.d.ts +15 -12
- package/dist/tools/grep.d.ts.map +1 -1
- package/dist/tools/grep.js +315 -193
- package/dist/tools/index.d.ts +114 -9
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +39 -24
- package/dist/tools/ls.d.ts +2 -2
- package/dist/tools/ls.d.ts.map +1 -1
- package/dist/tools/ls.js +7 -5
- package/dist/tools/read-file.d.ts +4 -6
- package/dist/tools/read-file.d.ts.map +1 -1
- package/dist/tools/read-file.js +84 -39
- package/dist/tools/save-file.d.ts +3 -3
- package/dist/tools/save-file.d.ts.map +1 -1
- package/dist/tools/save-file.js +36 -31
- package/dist/tools/skill.d.ts +23 -0
- package/dist/tools/skill.d.ts.map +1 -0
- package/dist/tools/skill.js +65 -0
- package/dist/tools/think.d.ts.map +1 -1
- package/dist/tools/think.js +2 -9
- package/dist/tools/utils.d.ts +2 -0
- package/dist/tools/utils.d.ts.map +1 -1
- package/dist/tools/utils.js +12 -0
- package/dist/tools/web-fetch.d.ts +50 -0
- package/dist/tools/web-fetch.d.ts.map +1 -0
- package/dist/tools/web-fetch.js +446 -0
- package/dist/tools/web-search.d.ts +44 -0
- package/dist/tools/web-search.d.ts.map +1 -0
- package/dist/tools/web-search.js +226 -0
- package/dist/tui/autocomplete/attachment-provider.d.ts +3 -6
- package/dist/tui/autocomplete/attachment-provider.d.ts.map +1 -1
- package/dist/tui/autocomplete/attachment-provider.js +25 -78
- package/dist/tui/autocomplete/base-provider.d.ts +1 -0
- package/dist/tui/autocomplete/base-provider.d.ts.map +1 -1
- package/dist/tui/autocomplete/combined-provider.d.ts +1 -4
- package/dist/tui/autocomplete/combined-provider.d.ts.map +1 -1
- package/dist/tui/autocomplete/combined-provider.js +3 -17
- package/dist/tui/autocomplete/command-provider.d.ts +1 -0
- package/dist/tui/autocomplete/command-provider.d.ts.map +1 -1
- package/dist/tui/autocomplete/command-provider.js +3 -0
- package/dist/tui/autocomplete/file-search-provider.d.ts +2 -1
- package/dist/tui/autocomplete/file-search-provider.d.ts.map +1 -1
- package/dist/tui/autocomplete/file-search-provider.js +37 -17
- package/dist/tui/autocomplete/skill-provider.d.ts +17 -0
- package/dist/tui/autocomplete/skill-provider.d.ts.map +1 -0
- package/dist/tui/autocomplete/skill-provider.js +49 -0
- package/dist/tui/autocomplete/utils.d.ts +2 -1
- package/dist/tui/autocomplete/utils.d.ts.map +1 -1
- package/dist/tui/autocomplete/utils.js +25 -23
- package/dist/tui/autocomplete.d.ts +2 -2
- package/dist/tui/autocomplete.d.ts.map +1 -1
- package/dist/tui/autocomplete.js +3 -5
- package/dist/tui/components/assistant-message.d.ts.map +1 -1
- package/dist/tui/components/assistant-message.js +0 -4
- package/dist/tui/components/editor.d.ts +18 -3
- package/dist/tui/components/editor.d.ts.map +1 -1
- package/dist/tui/components/editor.js +211 -237
- package/dist/tui/components/footer.d.ts +6 -4
- package/dist/tui/components/footer.d.ts.map +1 -1
- package/dist/tui/components/footer.js +49 -25
- package/dist/tui/components/markdown.d.ts +10 -7
- package/dist/tui/components/markdown.d.ts.map +1 -1
- package/dist/tui/components/markdown.js +57 -39
- package/dist/tui/components/modal.d.ts.map +1 -1
- package/dist/tui/components/modal.js +35 -33
- package/dist/tui/components/notification.d.ts +13 -2
- package/dist/tui/components/notification.d.ts.map +1 -1
- package/dist/tui/components/notification.js +36 -2
- package/dist/tui/components/progress-bar.js +1 -1
- package/dist/tui/components/select-list.d.ts +1 -0
- package/dist/tui/components/select-list.d.ts.map +1 -1
- package/dist/tui/components/select-list.js +14 -11
- package/dist/tui/components/text.d.ts +16 -0
- package/dist/tui/components/text.d.ts.map +1 -1
- package/dist/tui/components/text.js +72 -57
- package/dist/tui/components/thinking-block.d.ts +9 -0
- package/dist/tui/components/thinking-block.d.ts.map +1 -1
- package/dist/tui/components/thinking-block.js +43 -11
- package/dist/tui/components/tool-execution.d.ts +5 -1
- package/dist/tui/components/tool-execution.d.ts.map +1 -1
- package/dist/tui/components/tool-execution.js +19 -10
- package/dist/tui/components/user-message.d.ts.map +1 -1
- package/dist/tui/components/user-message.js +0 -3
- package/dist/tui/components/welcome.d.ts +2 -1
- package/dist/tui/components/welcome.d.ts.map +1 -1
- package/dist/tui/components/welcome.js +2 -2
- package/dist/tui/editor-launcher.d.ts +3 -2
- package/dist/tui/editor-launcher.d.ts.map +1 -1
- package/dist/tui/index.d.ts +0 -1
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/terminal.d.ts.map +1 -1
- package/dist/tui/terminal.js +10 -2
- package/dist/tui/tui.d.ts +43 -0
- package/dist/tui/tui.d.ts.map +1 -1
- package/dist/tui/tui.js +166 -41
- package/dist/tui/utils.d.ts +1 -5
- package/dist/tui/utils.d.ts.map +1 -1
- package/dist/tui/utils.js +271 -44
- package/dist/utils/bash/parse.d.ts +19 -0
- package/dist/utils/bash/parse.d.ts.map +1 -0
- package/dist/utils/bash/parse.js +223 -0
- package/dist/utils/bash/quote.d.ts +6 -0
- package/dist/utils/bash/quote.d.ts.map +1 -0
- package/dist/utils/bash/quote.js +23 -0
- package/dist/utils/bash.d.ts.map +1 -1
- package/dist/utils/bash.js +211 -126
- package/dist/utils/command-protection.d.ts +28 -0
- package/dist/utils/command-protection.d.ts.map +1 -0
- package/dist/utils/command-protection.js +324 -0
- package/dist/utils/dedent.d.ts.map +1 -0
- package/dist/utils/env-expand.d.ts +2 -0
- package/dist/utils/env-expand.d.ts.map +1 -0
- package/dist/utils/env-expand.js +8 -0
- package/dist/utils/filesystem/path-display.d.ts +11 -0
- package/dist/utils/filesystem/path-display.d.ts.map +1 -0
- package/dist/utils/filesystem/path-display.js +32 -0
- package/dist/utils/filesystem/security.d.ts +2 -2
- package/dist/utils/filesystem/security.d.ts.map +1 -1
- package/dist/utils/filesystem/security.js +28 -30
- package/dist/utils/formatting.d.ts.map +1 -0
- package/dist/{formatting.js → utils/formatting.js} +1 -1
- package/dist/utils/git.d.ts +4 -0
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +30 -0
- package/dist/utils/glob.d.ts +1 -1
- package/dist/utils/glob.d.ts.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/{logger.js → utils/logger.js} +1 -1
- package/dist/utils/parsing.d.ts.map +1 -0
- package/dist/utils/process.d.ts.map +1 -1
- package/dist/utils/process.js +90 -37
- package/dist/utils/templates.d.ts +2 -0
- package/dist/utils/templates.d.ts.map +1 -0
- package/dist/utils/templates.js +24 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/{version.js → utils/version.js} +1 -1
- package/package.json +35 -26
- package/dist/cli.d.ts +0 -23
- package/dist/cli.d.ts.map +0 -1
- package/dist/commands/add-directory/types.d.ts +0 -6
- package/dist/commands/add-directory/types.d.ts.map +0 -1
- package/dist/commands/add-directory/types.js +0 -1
- package/dist/commands/copy/types.d.ts +0 -3
- package/dist/commands/copy/types.d.ts.map +0 -1
- package/dist/commands/copy/types.js +0 -1
- package/dist/commands/exit/index.d.ts +0 -10
- package/dist/commands/exit/index.d.ts.map +0 -1
- package/dist/commands/exit/index.js +0 -21
- package/dist/commands/exit/types.d.ts +0 -8
- package/dist/commands/exit/types.d.ts.map +0 -1
- package/dist/commands/exit/types.js +0 -1
- package/dist/commands/exit/utils.d.ts +0 -2
- package/dist/commands/exit/utils.d.ts.map +0 -1
- package/dist/commands/exit/utils.js +0 -13
- package/dist/commands/prompt/index.d.ts +0 -5
- package/dist/commands/prompt/index.d.ts.map +0 -1
- package/dist/commands/prompt/index.js +0 -122
- package/dist/commands/prompt/types.d.ts +0 -15
- package/dist/commands/prompt/types.d.ts.map +0 -1
- package/dist/commands/prompt/types.js +0 -1
- package/dist/commands/prompt/utils.d.ts +0 -12
- package/dist/commands/prompt/utils.d.ts.map +0 -1
- package/dist/commands/prompt/utils.js +0 -107
- package/dist/commands/reset/index.d.ts +0 -3
- package/dist/commands/reset/index.d.ts.map +0 -1
- package/dist/commands/reset/index.js +0 -25
- package/dist/commands/reset/types.d.ts +0 -1
- package/dist/commands/reset/types.d.ts.map +0 -1
- package/dist/commands/reset/types.js +0 -3
- package/dist/commands/review/types.d.ts +0 -12
- package/dist/commands/review/types.d.ts.map +0 -1
- package/dist/commands/review/types.js +0 -1
- package/dist/commands/save/index.d.ts +0 -3
- package/dist/commands/save/index.d.ts.map +0 -1
- package/dist/commands/save/index.js +0 -19
- package/dist/config.d.ts.map +0 -1
- package/dist/dedent.d.ts.map +0 -1
- package/dist/formatting.d.ts.map +0 -1
- package/dist/logger.d.ts.map +0 -1
- package/dist/mentions.d.ts +0 -14
- package/dist/mentions.d.ts.map +0 -1
- package/dist/parsing.d.ts.map +0 -1
- package/dist/prompts.d.ts.map +0 -1
- package/dist/repl-new.d.ts +0 -65
- package/dist/repl-new.d.ts.map +0 -1
- package/dist/skills.d.ts +0 -16
- package/dist/skills.d.ts.map +0 -1
- package/dist/skills.js +0 -233
- package/dist/stdin.d.ts.map +0 -1
- package/dist/tui/autocomplete/path-provider.d.ts +0 -21
- package/dist/tui/autocomplete/path-provider.d.ts.map +0 -1
- package/dist/tui/autocomplete/path-provider.js +0 -164
- package/dist/utils/iterables.d.ts +0 -2
- package/dist/utils/iterables.d.ts.map +0 -1
- package/dist/utils/iterables.js +0 -6
- package/dist/version.d.ts.map +0 -1
- /package/dist/{dedent.d.ts → utils/dedent.d.ts} +0 -0
- /package/dist/{dedent.js → utils/dedent.js} +0 -0
- /package/dist/{formatting.d.ts → utils/formatting.d.ts} +0 -0
- /package/dist/{logger.d.ts → utils/logger.d.ts} +0 -0
- /package/dist/{parsing.d.ts → utils/parsing.d.ts} +0 -0
- /package/dist/{parsing.js → utils/parsing.js} +0 -0
- /package/dist/{version.d.ts → utils/version.d.ts} +0 -0
|
@@ -182,6 +182,12 @@ export class Editor {
|
|
|
182
182
|
};
|
|
183
183
|
this.borderColor = this.theme.borderColor;
|
|
184
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Get the current history (for testing purposes).
|
|
187
|
+
*/
|
|
188
|
+
getHistory() {
|
|
189
|
+
return this.history;
|
|
190
|
+
}
|
|
185
191
|
/**
|
|
186
192
|
* Add a prompt to history for up/down arrow navigation.
|
|
187
193
|
* Called after successful submission.
|
|
@@ -324,198 +330,247 @@ export class Editor {
|
|
|
324
330
|
return result;
|
|
325
331
|
}
|
|
326
332
|
handleInput(data) {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
return;
|
|
339
|
-
}
|
|
340
|
-
// If we're in a paste, buffer the data
|
|
341
|
-
if (this.isInPaste) {
|
|
342
|
-
// Append data to buffer first (end marker could be split across chunks)
|
|
343
|
-
this.pasteBuffer += data;
|
|
344
|
-
// Check if the accumulated buffer contains the end marker
|
|
345
|
-
const endIndex = this.pasteBuffer.indexOf("\x1b[201~");
|
|
346
|
-
if (endIndex !== -1) {
|
|
347
|
-
// Extract content before the end marker
|
|
348
|
-
const pasteContent = this.pasteBuffer.substring(0, endIndex);
|
|
349
|
-
// Process the complete paste
|
|
350
|
-
this.handlePaste(pasteContent);
|
|
351
|
-
// Reset paste state
|
|
352
|
-
this.isInPaste = false;
|
|
353
|
-
// Process any remaining data after the end marker
|
|
354
|
-
const remaining = this.pasteBuffer.substring(endIndex + 6); // 6 = length of \x1b[201~
|
|
355
|
-
this.pasteBuffer = "";
|
|
356
|
-
if (remaining.length > 0) {
|
|
357
|
-
this.handleInput(remaining);
|
|
333
|
+
const pasteStart = "\x1b[200~";
|
|
334
|
+
const pasteEnd = "\x1b[201~";
|
|
335
|
+
let input = data;
|
|
336
|
+
while (input.length > 0) {
|
|
337
|
+
if (!this.isInPaste) {
|
|
338
|
+
const startIndex = input.indexOf(pasteStart);
|
|
339
|
+
if (startIndex === -1)
|
|
340
|
+
break;
|
|
341
|
+
const before = input.slice(0, startIndex);
|
|
342
|
+
if (before.length > 0) {
|
|
343
|
+
this.processInputData(before);
|
|
358
344
|
}
|
|
359
|
-
|
|
345
|
+
this.isInPaste = true;
|
|
346
|
+
this.pasteBuffer = "";
|
|
347
|
+
input = input.slice(startIndex + pasteStart.length);
|
|
348
|
+
continue;
|
|
360
349
|
}
|
|
361
|
-
|
|
362
|
-
|
|
350
|
+
this.pasteBuffer += input;
|
|
351
|
+
const endIndex = this.pasteBuffer.indexOf(pasteEnd);
|
|
352
|
+
if (endIndex === -1)
|
|
353
|
+
return;
|
|
354
|
+
const pasteContent = this.pasteBuffer.slice(0, endIndex);
|
|
355
|
+
const remaining = this.pasteBuffer.slice(endIndex + pasteEnd.length);
|
|
356
|
+
this.handlePaste(pasteContent);
|
|
357
|
+
this.isInPaste = false;
|
|
358
|
+
this.pasteBuffer = "";
|
|
359
|
+
input = remaining;
|
|
363
360
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
if (isEscape(
|
|
361
|
+
if (input.length === 0)
|
|
362
|
+
return;
|
|
363
|
+
if (isEscape(input) && this.onEscape && !this.isShowingAutocomplete()) {
|
|
367
364
|
this.onEscape();
|
|
368
365
|
return;
|
|
369
366
|
}
|
|
370
|
-
|
|
371
|
-
if (isCtrlC(data)) {
|
|
367
|
+
if (isCtrlC(input)) {
|
|
372
368
|
return;
|
|
373
369
|
}
|
|
374
|
-
|
|
375
|
-
this.processInputData(data);
|
|
370
|
+
this.processInputData(input);
|
|
376
371
|
}
|
|
377
372
|
processInputData(data) {
|
|
378
|
-
// Handle special key combinations first
|
|
379
373
|
// Ctrl+C - Exit (let parent handle this)
|
|
380
374
|
if (data.charCodeAt(0) === 3) {
|
|
381
375
|
return;
|
|
382
376
|
}
|
|
383
|
-
//
|
|
384
|
-
if (this.
|
|
385
|
-
|
|
386
|
-
|
|
377
|
+
// Delegate to specialized handlers - return true if input was handled
|
|
378
|
+
if (this.handleAutocompleteInput(data))
|
|
379
|
+
return;
|
|
380
|
+
if (this.handleTabKey(data))
|
|
381
|
+
return;
|
|
382
|
+
if (this.handleExternalEditor(data))
|
|
383
|
+
return;
|
|
384
|
+
if (this.handleControlKey(data))
|
|
385
|
+
return;
|
|
386
|
+
if (this.handlePlainEnter(data))
|
|
387
|
+
return;
|
|
388
|
+
if (this.handleModifiedEnterKey(data))
|
|
389
|
+
return;
|
|
390
|
+
if (this.handleBackspaceKey(data))
|
|
391
|
+
return;
|
|
392
|
+
if (this.handleHomeEndKeys(data))
|
|
393
|
+
return;
|
|
394
|
+
if (this.handleForwardDeleteKey(data))
|
|
395
|
+
return;
|
|
396
|
+
if (this.handleWordNavigation(data))
|
|
397
|
+
return;
|
|
398
|
+
if (this.handleArrowKeys(data))
|
|
399
|
+
return;
|
|
400
|
+
// Default: insert printable character
|
|
401
|
+
if (data.charCodeAt(0) >= 32) {
|
|
402
|
+
this.insertCharacter(data);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
handleAutocompleteInput(data) {
|
|
406
|
+
if (!this.isAutocompleting || !this.autocompleteList) {
|
|
407
|
+
return false;
|
|
408
|
+
}
|
|
409
|
+
// Escape - cancel autocomplete
|
|
410
|
+
if (isEscape(data)) {
|
|
411
|
+
this.cancelAutocomplete();
|
|
412
|
+
return true;
|
|
413
|
+
}
|
|
414
|
+
// Enter - apply selection
|
|
415
|
+
if (isEnter(data)) {
|
|
416
|
+
const selected = this.autocompleteList.getSelectedItem();
|
|
417
|
+
if (selected && this.autocompleteProvider) {
|
|
418
|
+
const result = this.autocompleteProvider.applyCompletion(this.state.lines, this.state.cursorLine, this.state.cursorCol, selected, this.autocompletePrefix);
|
|
419
|
+
this.state.lines = result.lines;
|
|
420
|
+
this.state.cursorLine = result.cursorLine;
|
|
421
|
+
this.state.cursorCol = result.cursorCol;
|
|
387
422
|
this.cancelAutocomplete();
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
// Enter - apply selection
|
|
391
|
-
if (isEnter(data)) {
|
|
392
|
-
const selected = this.autocompleteList.getSelectedItem();
|
|
393
|
-
if (selected && this.autocompleteProvider) {
|
|
394
|
-
const result = this.autocompleteProvider.applyCompletion(this.state.lines, this.state.cursorLine, this.state.cursorCol, selected, this.autocompletePrefix);
|
|
395
|
-
this.state.lines = result.lines;
|
|
396
|
-
this.state.cursorLine = result.cursorLine;
|
|
397
|
-
this.state.cursorCol = result.cursorCol;
|
|
398
|
-
this.cancelAutocomplete();
|
|
399
|
-
if (this.onChange) {
|
|
400
|
-
this.onChange(this.getText());
|
|
401
|
-
}
|
|
423
|
+
if (this.onChange) {
|
|
424
|
+
this.onChange(this.getText());
|
|
402
425
|
}
|
|
403
|
-
return;
|
|
404
|
-
}
|
|
405
|
-
// Navigation keys (arrows, Tab, Shift+Tab) - pass to autocomplete list
|
|
406
|
-
if (isNavigationKey(data)) {
|
|
407
|
-
this.autocompleteList.handleInput(data);
|
|
408
|
-
return;
|
|
409
426
|
}
|
|
410
|
-
|
|
411
|
-
// Let them fall through to normal character handling
|
|
427
|
+
return true;
|
|
412
428
|
}
|
|
413
|
-
//
|
|
429
|
+
// Navigation keys (arrows, Tab, Shift+Tab) - pass to autocomplete list
|
|
430
|
+
if (isNavigationKey(data)) {
|
|
431
|
+
this.autocompleteList.handleInput(data);
|
|
432
|
+
return true;
|
|
433
|
+
}
|
|
434
|
+
return false;
|
|
435
|
+
}
|
|
436
|
+
handleTabKey(data) {
|
|
414
437
|
if (isTab(data) && !this.isAutocompleting) {
|
|
415
438
|
void this.handleTabCompletion();
|
|
416
|
-
return;
|
|
439
|
+
return true;
|
|
417
440
|
}
|
|
418
|
-
|
|
441
|
+
return false;
|
|
442
|
+
}
|
|
443
|
+
handleExternalEditor(data) {
|
|
419
444
|
if (isCtrlG(data) && this.onExternalEditor) {
|
|
420
445
|
void this.launchExternalEditor();
|
|
421
|
-
return;
|
|
446
|
+
return true;
|
|
422
447
|
}
|
|
423
|
-
|
|
448
|
+
return false;
|
|
449
|
+
}
|
|
450
|
+
handleControlKey(data) {
|
|
451
|
+
const charCode = data.charCodeAt(0);
|
|
424
452
|
// Ctrl+K - Delete to end of line
|
|
425
|
-
if (
|
|
453
|
+
if (charCode === 11) {
|
|
426
454
|
this.deleteToEndOfLine();
|
|
455
|
+
return true;
|
|
427
456
|
}
|
|
428
457
|
// Ctrl+U - Delete to start of line
|
|
429
|
-
|
|
458
|
+
if (charCode === 21) {
|
|
430
459
|
this.deleteToStartOfLine();
|
|
460
|
+
return true;
|
|
431
461
|
}
|
|
432
462
|
// Ctrl+W - Delete word backwards
|
|
433
|
-
|
|
463
|
+
if (charCode === 23) {
|
|
434
464
|
this.deleteWordBackwards();
|
|
465
|
+
return true;
|
|
435
466
|
}
|
|
436
467
|
// Option/Alt+Backspace (e.g. Ghostty sends ESC + DEL)
|
|
437
|
-
|
|
468
|
+
if (data === "\x1b\x7f") {
|
|
438
469
|
this.deleteWordBackwards();
|
|
470
|
+
return true;
|
|
439
471
|
}
|
|
440
472
|
// Ctrl+A - Move to start of line
|
|
441
|
-
|
|
473
|
+
if (charCode === 1) {
|
|
442
474
|
this.moveToLineStart();
|
|
475
|
+
return true;
|
|
443
476
|
}
|
|
444
477
|
// Ctrl+E - Move to end of line
|
|
445
|
-
|
|
478
|
+
if (charCode === 5) {
|
|
446
479
|
this.moveToLineEnd();
|
|
480
|
+
return true;
|
|
447
481
|
}
|
|
482
|
+
return false;
|
|
483
|
+
}
|
|
484
|
+
handlePlainEnter(data) {
|
|
448
485
|
// Plain Enter (char code 13 for CR) - create new line
|
|
449
|
-
|
|
486
|
+
if (data.charCodeAt(0) === 13 && data.length === 1) {
|
|
450
487
|
this.addNewLine();
|
|
488
|
+
return true;
|
|
451
489
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
//
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
490
|
+
return false;
|
|
491
|
+
}
|
|
492
|
+
handleModifiedEnterKey(data) {
|
|
493
|
+
if (!this.isModifiedEnter(data)) {
|
|
494
|
+
return false;
|
|
495
|
+
}
|
|
496
|
+
// If submit is disabled, do nothing
|
|
497
|
+
if (this.disableSubmit) {
|
|
498
|
+
return true;
|
|
499
|
+
}
|
|
500
|
+
// Get text and substitute paste markers with actual content
|
|
501
|
+
let result = this.state.lines.join("\n").trim();
|
|
502
|
+
// Replace all [paste #N +xxx lines] or [paste #N xxx chars] markers with actual paste content
|
|
503
|
+
for (const [pasteId, pasteContent] of this.pastes) {
|
|
504
|
+
// Match formats: [paste #N], [paste #N +xxx lines], or [paste #N xxx chars]
|
|
505
|
+
const markerRegex = new RegExp(`\\[paste #${pasteId}( (\\+\\d+ lines|\\d+ chars))?\\]`, "g");
|
|
506
|
+
result = result.replace(markerRegex, pasteContent);
|
|
507
|
+
}
|
|
508
|
+
// Reset editor and clear pastes
|
|
509
|
+
this.state = {
|
|
510
|
+
lines: [""],
|
|
511
|
+
cursorLine: 0,
|
|
512
|
+
cursorCol: 0,
|
|
513
|
+
};
|
|
514
|
+
this.pastes.clear();
|
|
515
|
+
this.pasteCounter = 0;
|
|
516
|
+
this.historyIndex = -1; // Exit history browsing mode
|
|
517
|
+
this.addToHistory(result); // Save submitted text to history
|
|
518
|
+
// Notify that editor is now empty
|
|
519
|
+
if (this.onChange) {
|
|
520
|
+
this.onChange("");
|
|
521
|
+
}
|
|
522
|
+
if (this.onSubmit) {
|
|
523
|
+
void this.onSubmit(result);
|
|
482
524
|
}
|
|
483
|
-
|
|
484
|
-
|
|
525
|
+
return true;
|
|
526
|
+
}
|
|
527
|
+
handleBackspaceKey(data) {
|
|
528
|
+
if (data.charCodeAt(0) === 127 || data.charCodeAt(0) === 8) {
|
|
485
529
|
this.handleBackspace();
|
|
530
|
+
return true;
|
|
486
531
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
532
|
+
return false;
|
|
533
|
+
}
|
|
534
|
+
handleHomeEndKeys(data) {
|
|
535
|
+
// Home key: \x1b[H, \x1b[1~, or \x1b[7~
|
|
536
|
+
if (data === "\x1b[H" || data === "\x1b[1~" || data === "\x1b[7~") {
|
|
490
537
|
this.moveToLineStart();
|
|
538
|
+
return true;
|
|
491
539
|
}
|
|
492
|
-
|
|
493
|
-
|
|
540
|
+
// End key: \x1b[F, \x1b[4~, or \x1b[8~
|
|
541
|
+
if (data === "\x1b[F" || data === "\x1b[4~" || data === "\x1b[8~") {
|
|
494
542
|
this.moveToLineEnd();
|
|
543
|
+
return true;
|
|
495
544
|
}
|
|
545
|
+
return false;
|
|
546
|
+
}
|
|
547
|
+
handleForwardDeleteKey(data) {
|
|
496
548
|
// Forward delete (Fn+Backspace or Delete key)
|
|
497
|
-
|
|
498
|
-
// Delete key
|
|
549
|
+
if (data === "\x1b[3~") {
|
|
499
550
|
this.handleForwardDelete();
|
|
551
|
+
return true;
|
|
500
552
|
}
|
|
553
|
+
return false;
|
|
554
|
+
}
|
|
555
|
+
handleWordNavigation(data) {
|
|
501
556
|
// Word navigation (Option/Alt + Arrow or Ctrl + Arrow)
|
|
502
557
|
// Option+Left: \x1b[1;3D or \x1bb
|
|
503
558
|
// Option+Right: \x1b[1;3C or \x1bf
|
|
504
559
|
// Ctrl+Left: \x1b[1;5D
|
|
505
560
|
// Ctrl+Right: \x1b[1;5C
|
|
506
|
-
|
|
507
|
-
// Word left
|
|
561
|
+
if (data === "\x1b[1;3D" || data === "\x1bb" || data === "\x1b[1;5D") {
|
|
508
562
|
this.moveWordBackwards();
|
|
563
|
+
return true;
|
|
509
564
|
}
|
|
510
|
-
|
|
511
|
-
data === "\x1bf" ||
|
|
512
|
-
data === "\x1b[1;5C") {
|
|
513
|
-
// Word right
|
|
565
|
+
if (data === "\x1b[1;3C" || data === "\x1bf" || data === "\x1b[1;5C") {
|
|
514
566
|
this.moveWordForwards();
|
|
567
|
+
return true;
|
|
515
568
|
}
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
569
|
+
return false;
|
|
570
|
+
}
|
|
571
|
+
handleArrowKeys(data) {
|
|
572
|
+
// Up arrow
|
|
573
|
+
if (data === "\x1b[A") {
|
|
519
574
|
if (this.isEditorEmpty()) {
|
|
520
575
|
this.navigateHistory(-1); // Start browsing history
|
|
521
576
|
}
|
|
@@ -525,28 +580,29 @@ export class Editor {
|
|
|
525
580
|
else {
|
|
526
581
|
this.moveCursor(-1, 0); // Cursor movement (within text or history entry)
|
|
527
582
|
}
|
|
583
|
+
return true;
|
|
528
584
|
}
|
|
529
|
-
|
|
530
|
-
|
|
585
|
+
// Down arrow
|
|
586
|
+
if (data === "\x1b[B") {
|
|
531
587
|
if (this.historyIndex > -1 && this.isOnLastVisualLine()) {
|
|
532
588
|
this.navigateHistory(1); // Navigate to newer history entry or clear
|
|
533
589
|
}
|
|
534
590
|
else {
|
|
535
591
|
this.moveCursor(1, 0); // Cursor movement (within text or history entry)
|
|
536
592
|
}
|
|
593
|
+
return true;
|
|
537
594
|
}
|
|
538
|
-
|
|
539
|
-
|
|
595
|
+
// Right arrow
|
|
596
|
+
if (data === "\x1b[C") {
|
|
540
597
|
this.moveCursor(0, 1);
|
|
598
|
+
return true;
|
|
541
599
|
}
|
|
542
|
-
|
|
543
|
-
|
|
600
|
+
// Left arrow
|
|
601
|
+
if (data === "\x1b[D") {
|
|
544
602
|
this.moveCursor(0, -1);
|
|
603
|
+
return true;
|
|
545
604
|
}
|
|
546
|
-
|
|
547
|
-
else if (data.charCodeAt(0) >= 32) {
|
|
548
|
-
this.insertCharacter(data);
|
|
549
|
-
}
|
|
605
|
+
return false;
|
|
550
606
|
}
|
|
551
607
|
layoutText(contentWidth) {
|
|
552
608
|
const layoutLines = [];
|
|
@@ -628,7 +684,7 @@ export class Editor {
|
|
|
628
684
|
this.setTextInternal(text);
|
|
629
685
|
}
|
|
630
686
|
// All the editor methods from before...
|
|
631
|
-
insertCharacter(char) {
|
|
687
|
+
insertCharacter(char, suppressAutocomplete = false) {
|
|
632
688
|
this.historyIndex = -1; // Exit history browsing mode
|
|
633
689
|
const line = this.state.lines[this.state.cursorLine] || "";
|
|
634
690
|
const before = line.slice(0, this.state.cursorCol);
|
|
@@ -638,50 +694,16 @@ export class Editor {
|
|
|
638
694
|
if (this.onChange) {
|
|
639
695
|
this.onChange(this.getText());
|
|
640
696
|
}
|
|
697
|
+
// Skip autocomplete triggering during paste operations
|
|
698
|
+
if (suppressAutocomplete) {
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
641
701
|
// Check if we should trigger or update autocomplete
|
|
642
702
|
if (!this.isAutocompleting) {
|
|
643
|
-
|
|
644
|
-
if (char === "/" && this.isAtStartOfMessage()) {
|
|
645
|
-
void this.tryTriggerAutocomplete();
|
|
646
|
-
}
|
|
647
|
-
// Auto-trigger for "@" file reference (fuzzy search)
|
|
648
|
-
else if (char === "@") {
|
|
703
|
+
if (this.autocompleteProvider) {
|
|
649
704
|
const currentLine = this.state.lines[this.state.cursorLine] || "";
|
|
650
705
|
const textBeforeCursor = currentLine.slice(0, this.state.cursorCol);
|
|
651
|
-
|
|
652
|
-
const charBeforeAt = textBeforeCursor[textBeforeCursor.length - 2];
|
|
653
|
-
if (textBeforeCursor.length === 1 ||
|
|
654
|
-
charBeforeAt === " " ||
|
|
655
|
-
charBeforeAt === "\t") {
|
|
656
|
-
void this.tryTriggerAutocomplete();
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
// Auto-trigger for "#" file search
|
|
660
|
-
else if (char === "#") {
|
|
661
|
-
const currentLine = this.state.lines[this.state.cursorLine] || "";
|
|
662
|
-
const textBeforeCursor = currentLine.slice(0, this.state.cursorCol);
|
|
663
|
-
// Only trigger if # is after whitespace or at start of line
|
|
664
|
-
const charBeforeHash = textBeforeCursor[textBeforeCursor.length - 2];
|
|
665
|
-
if (textBeforeCursor.length === 1 ||
|
|
666
|
-
charBeforeHash === " " ||
|
|
667
|
-
charBeforeHash === "\t") {
|
|
668
|
-
void this.tryTriggerAutocomplete();
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
// Also auto-trigger when typing letters in a slash command context
|
|
672
|
-
else if (/[a-zA-Z0-9]/.test(char)) {
|
|
673
|
-
const currentLine = this.state.lines[this.state.cursorLine] || "";
|
|
674
|
-
const textBeforeCursor = currentLine.slice(0, this.state.cursorCol);
|
|
675
|
-
// Check if we're in a slash command (with or without space for arguments)
|
|
676
|
-
if (textBeforeCursor.trimStart().startsWith("/")) {
|
|
677
|
-
void this.tryTriggerAutocomplete();
|
|
678
|
-
}
|
|
679
|
-
// Check if we're in an @ file reference context
|
|
680
|
-
else if (textBeforeCursor.match(/(?:^|[\s])@[^\s]*$/)) {
|
|
681
|
-
void this.tryTriggerAutocomplete();
|
|
682
|
-
}
|
|
683
|
-
// Check if we're in a # file search context
|
|
684
|
-
else if (textBeforeCursor.match(/(?:^|[\s])#[^\s]*$/)) {
|
|
706
|
+
if (this.autocompleteProvider.matchesContext(textBeforeCursor)) {
|
|
685
707
|
void this.tryTriggerAutocomplete();
|
|
686
708
|
}
|
|
687
709
|
}
|
|
@@ -714,7 +736,7 @@ export class Editor {
|
|
|
714
736
|
? `[paste #${pasteId} +${pastedLines.length} lines]`
|
|
715
737
|
: `[paste #${pasteId} ${totalChars} chars]`;
|
|
716
738
|
for (const char of marker) {
|
|
717
|
-
this.insertCharacter(char);
|
|
739
|
+
this.insertCharacter(char, true);
|
|
718
740
|
}
|
|
719
741
|
return;
|
|
720
742
|
}
|
|
@@ -722,7 +744,7 @@ export class Editor {
|
|
|
722
744
|
// Single line - just insert each character
|
|
723
745
|
const text = pastedLines[0] || "";
|
|
724
746
|
for (const char of text) {
|
|
725
|
-
this.insertCharacter(char);
|
|
747
|
+
this.insertCharacter(char, true);
|
|
726
748
|
}
|
|
727
749
|
return;
|
|
728
750
|
}
|
|
@@ -797,12 +819,10 @@ export class Editor {
|
|
|
797
819
|
if (this.isAutocompleting) {
|
|
798
820
|
void this.updateAutocomplete();
|
|
799
821
|
}
|
|
800
|
-
else {
|
|
801
|
-
// Check if we should trigger autocomplete after backspace in slash command context
|
|
822
|
+
else if (this.autocompleteProvider) {
|
|
802
823
|
const currentLine = this.state.lines[this.state.cursorLine] || "";
|
|
803
824
|
const textBeforeCursor = currentLine.slice(0, this.state.cursorCol);
|
|
804
|
-
|
|
805
|
-
if (textBeforeCursor.startsWith("/") && !textBeforeCursor.includes(" ")) {
|
|
825
|
+
if (this.autocompleteProvider.matchesContext(textBeforeCursor)) {
|
|
806
826
|
void this.tryTriggerAutocomplete();
|
|
807
827
|
}
|
|
808
828
|
}
|
|
@@ -1081,13 +1101,6 @@ export class Editor {
|
|
|
1081
1101
|
}
|
|
1082
1102
|
this.state.cursorCol = newCol;
|
|
1083
1103
|
}
|
|
1084
|
-
// Helper method to check if cursor is at start of message (for slash command detection)
|
|
1085
|
-
isAtStartOfMessage() {
|
|
1086
|
-
const currentLine = this.state.lines[this.state.cursorLine] || "";
|
|
1087
|
-
const beforeCursor = currentLine.slice(0, this.state.cursorCol);
|
|
1088
|
-
// At start if line is empty, only contains whitespace, or is just "/"
|
|
1089
|
-
return beforeCursor.trim() === "" || beforeCursor.trim() === "/";
|
|
1090
|
-
}
|
|
1091
1104
|
// Autocomplete methods
|
|
1092
1105
|
async tryTriggerAutocomplete(explicitTab = false) {
|
|
1093
1106
|
if (!this.autocompleteProvider)
|
|
@@ -1129,41 +1142,12 @@ export class Editor {
|
|
|
1129
1142
|
if (beforeCursor.trimStart().startsWith("/")) {
|
|
1130
1143
|
await this.handleSlashCommandCompletion();
|
|
1131
1144
|
}
|
|
1132
|
-
else {
|
|
1133
|
-
await this.forceFileAutocomplete();
|
|
1134
|
-
}
|
|
1135
1145
|
}
|
|
1136
1146
|
async handleSlashCommandCompletion() {
|
|
1137
1147
|
// For now, fall back to regular autocomplete (slash commands)
|
|
1138
1148
|
// This can be extended later to handle command-specific argument completion
|
|
1139
1149
|
await this.tryTriggerAutocomplete(true);
|
|
1140
1150
|
}
|
|
1141
|
-
async forceFileAutocomplete() {
|
|
1142
|
-
if (!this.autocompleteProvider)
|
|
1143
|
-
return;
|
|
1144
|
-
// Check if provider has the force method
|
|
1145
|
-
const provider = this.autocompleteProvider;
|
|
1146
|
-
if (!provider.getForceFileSuggestions) {
|
|
1147
|
-
await this.tryTriggerAutocomplete(true);
|
|
1148
|
-
return;
|
|
1149
|
-
}
|
|
1150
|
-
const suggestions = await provider.getForceFileSuggestions(this.state.lines, this.state.cursorLine, this.state.cursorCol);
|
|
1151
|
-
if (suggestions && suggestions.items.length > 0) {
|
|
1152
|
-
this.autocompletePrefix = suggestions.prefix;
|
|
1153
|
-
if (this.autocompleteList) {
|
|
1154
|
-
this.autocompleteList.updateItems(suggestions.items);
|
|
1155
|
-
}
|
|
1156
|
-
else {
|
|
1157
|
-
this.autocompleteList = new SelectList(suggestions.items, 5, this.theme.selectList);
|
|
1158
|
-
}
|
|
1159
|
-
this.isAutocompleting = true;
|
|
1160
|
-
// Request re-render to show autocomplete list
|
|
1161
|
-
this.onRenderRequested?.();
|
|
1162
|
-
}
|
|
1163
|
-
else {
|
|
1164
|
-
this.cancelAutocomplete();
|
|
1165
|
-
}
|
|
1166
|
-
}
|
|
1167
1151
|
cancelAutocomplete() {
|
|
1168
1152
|
this.isAutocompleting = false;
|
|
1169
1153
|
this.autocompleteList = undefined;
|
|
@@ -1176,28 +1160,18 @@ export class Editor {
|
|
|
1176
1160
|
isShowingAutocomplete() {
|
|
1177
1161
|
return this.isAutocompleting;
|
|
1178
1162
|
}
|
|
1163
|
+
wantsNavigationKeys() {
|
|
1164
|
+
return this.isAutocompleting;
|
|
1165
|
+
}
|
|
1179
1166
|
async updateAutocomplete() {
|
|
1180
1167
|
if (!this.isAutocompleting || !this.autocompleteProvider)
|
|
1181
1168
|
return;
|
|
1182
1169
|
// Check if the current text still matches our autocomplete context
|
|
1183
|
-
// This prevents unnecessary updates when typing unrelated text
|
|
1184
1170
|
const currentLine = this.state.lines[this.state.cursorLine] || "";
|
|
1185
1171
|
const textBeforeCursor = currentLine.slice(0, this.state.cursorCol);
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
if (textBeforeCursor.startsWith("/") ||
|
|
1190
|
-
textBeforeCursor.match(/(?:^|[\s])@[^\s]*$/) ||
|
|
1191
|
-
textBeforeCursor.match(/(?:^|[\s])#[^\s]*$/)) {
|
|
1192
|
-
// For slash commands, @ file attachments, and # file search,
|
|
1193
|
-
// continue autocomplete as long as we're in the right context
|
|
1194
|
-
}
|
|
1195
|
-
else {
|
|
1196
|
-
// For other file paths, check if we're still in the same path context
|
|
1197
|
-
if (!textBeforeCursor.endsWith(this.autocompletePrefix)) {
|
|
1198
|
-
this.cancelAutocomplete();
|
|
1199
|
-
return;
|
|
1200
|
-
}
|
|
1172
|
+
if (!this.autocompleteProvider.matchesContext(textBeforeCursor)) {
|
|
1173
|
+
this.cancelAutocomplete();
|
|
1174
|
+
return;
|
|
1201
1175
|
}
|
|
1202
1176
|
// Clear any existing debounce timer
|
|
1203
1177
|
if (this.autocompleteDebounceTimer) {
|
|
@@ -1,24 +1,26 @@
|
|
|
1
|
-
import type { LanguageModelUsage } from "ai";
|
|
2
1
|
import type { AgentState } from "../../agent/index.ts";
|
|
3
2
|
import type { ModelManager } from "../../models/manager.ts";
|
|
4
3
|
import type { ProjectStatusData } from "../../repl/project-status.ts";
|
|
4
|
+
import type { TokenTracker } from "../../tokens/tracker.ts";
|
|
5
5
|
import { type Component } from "../tui.ts";
|
|
6
6
|
type State = {
|
|
7
7
|
projectStatus: ProjectStatusData;
|
|
8
8
|
currentContextWindow: number;
|
|
9
9
|
contextWindow: number;
|
|
10
|
-
usage?: LanguageModelUsage;
|
|
11
10
|
agentState?: AgentState;
|
|
11
|
+
currentMode?: string;
|
|
12
12
|
};
|
|
13
13
|
export declare class FooterComponent implements Component {
|
|
14
14
|
private modelManager;
|
|
15
|
+
private tokenTracker?;
|
|
15
16
|
private state;
|
|
16
17
|
private progressBar;
|
|
17
|
-
private usage?;
|
|
18
18
|
private agentState?;
|
|
19
|
-
|
|
19
|
+
private currentMode;
|
|
20
|
+
constructor(modelManager: ModelManager, tokenTracker: TokenTracker | undefined, state: State);
|
|
20
21
|
setState(state: State): void;
|
|
21
22
|
resetState(): void;
|
|
23
|
+
getProjectStatus(): ProjectStatusData;
|
|
22
24
|
render(width: number): string[];
|
|
23
25
|
}
|
|
24
26
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../source/tui/components/footer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../source/tui/components/footer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,WAAW,CAAC;AAGzD,KAAK,KAAK,GAAG;IACX,aAAa,EAAE,iBAAiB,CAAC;IACjC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AA2CF,qBAAa,eAAgB,YAAW,SAAS;IAC/C,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,UAAU,CAAC,CAAa;IAChC,OAAO,CAAC,WAAW,CAAY;gBAE7B,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,YAAY,GAAG,SAAS,EACtC,KAAK,EAAE,KAAK;IAad,QAAQ,CAAC,KAAK,EAAE,KAAK;IAYrB,UAAU;IAIV,gBAAgB,IAAI,iBAAiB;IAIrC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAiFhC"}
|