@travisennis/acai 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.acai/acai.json +9 -0
- package/.acai/prompts/add-openrouter-model.md +13 -0
- package/.acai/prompts/project-status.md +4 -0
- package/.acai/prompts/update-architecture-document.md +9 -0
- package/.acai/rules/learned-rules.md +9 -0
- package/.ai/docs/available-tools.txt +3 -0
- package/.ai/docs/cognitive_complexity_refactoring_progress.md +65 -0
- package/.ai/docs/deleted_tools.md +168 -0
- package/.ai/docs/deleted_tools_88ced9ef.md +56 -0
- package/.ai/docs/image-pasting.md +46 -0
- package/.ai/docs/initialize-app.md +117 -0
- package/.ai/docs/issue-4-plan.md +44 -0
- package/.ai/docs/marked-renderer-debug.md +15 -0
- package/.ai/docs/marked-renderer-refactor-plan.md +64 -0
- package/.ai/docs/memory-use-cases.md +55 -0
- package/.ai/docs/prompt-consistency.md +31 -0
- package/.ai/docs/refactoring-tools.md +98 -0
- package/.ai/docs/system-prompt-update.md +174 -0
- package/.ai/docs/system_prompt.txt +210 -0
- package/.ai/docs/tasks.md +49 -0
- package/.ai/plan.md +131 -0
- package/.ai/prompt.md +1 -0
- package/.ai/scripts/fetch_models.js +27 -0
- package/.ai/scripts/generateSystemPrompt.ts +15 -0
- package/.ai/scripts/list-tools.mjs +4 -0
- package/.ai/scripts/p5_geometric_shapes.js +149 -0
- package/.husky/commit-msg +1 -0
- package/.husky/pre-commit +3 -0
- package/.husky/pre-push +1 -0
- package/.ignore +4 -0
- package/AGENTS.md +25 -0
- package/ARCHITECTURE.md +304 -0
- package/LICENSE +21 -0
- package/README.md +392 -0
- package/TODO.md +2 -0
- package/biome.json +61 -0
- package/commitlint.config.js +3 -0
- package/dist/cli.d.ts +19 -0
- package/dist/cli.js +116 -0
- package/dist/commands/application-log-command.d.ts +2 -0
- package/dist/commands/application-log-command.js +43 -0
- package/dist/commands/clear-command.d.ts +2 -0
- package/dist/commands/clear-command.js +12 -0
- package/dist/commands/compact-command.d.ts +2 -0
- package/dist/commands/compact-command.js +51 -0
- package/dist/commands/copy-command.d.ts +2 -0
- package/dist/commands/copy-command.js +51 -0
- package/dist/commands/edit-command.d.ts +2 -0
- package/dist/commands/edit-command.js +53 -0
- package/dist/commands/edit-prompt-command.d.ts +2 -0
- package/dist/commands/edit-prompt-command.js +25 -0
- package/dist/commands/exit-command.d.ts +2 -0
- package/dist/commands/exit-command.js +14 -0
- package/dist/commands/files-command.d.ts +2 -0
- package/dist/commands/files-command.js +63 -0
- package/dist/commands/generate-rules-command.d.ts +2 -0
- package/dist/commands/generate-rules-command.js +61 -0
- package/dist/commands/help-command.d.ts +2 -0
- package/dist/commands/help-command.js +19 -0
- package/dist/commands/init-command.d.ts +2 -0
- package/dist/commands/init-command.js +40 -0
- package/dist/commands/last-log-command.d.ts +2 -0
- package/dist/commands/last-log-command.js +76 -0
- package/dist/commands/manager.d.ts +22 -0
- package/dist/commands/manager.js +123 -0
- package/dist/commands/model-command.d.ts +2 -0
- package/dist/commands/model-command.js +84 -0
- package/dist/commands/paste-command.d.ts +2 -0
- package/dist/commands/paste-command.js +40 -0
- package/dist/commands/prompt-command.d.ts +2 -0
- package/dist/commands/prompt-command.js +111 -0
- package/dist/commands/reset-command.d.ts +2 -0
- package/dist/commands/reset-command.js +16 -0
- package/dist/commands/rules-command.d.ts +2 -0
- package/dist/commands/rules-command.js +68 -0
- package/dist/commands/save-command.d.ts +2 -0
- package/dist/commands/save-command.js +14 -0
- package/dist/commands/types.d.ts +26 -0
- package/dist/commands/types.js +1 -0
- package/dist/commands/usage-command.d.ts +2 -0
- package/dist/commands/usage-command.js +21 -0
- package/dist/config.d.ts +60 -0
- package/dist/config.js +193 -0
- package/dist/conversation-analyzer.d.ts +10 -0
- package/dist/conversation-analyzer.js +88 -0
- package/dist/dedent.d.ts +3 -0
- package/dist/dedent.js +38 -0
- package/dist/formatting.d.ts +17 -0
- package/dist/formatting.js +103 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +213 -0
- package/dist/logger.d.ts +2 -0
- package/dist/logger.js +24 -0
- package/dist/mentions.d.ts +9 -0
- package/dist/mentions.js +182 -0
- package/dist/messages.d.ts +69 -0
- package/dist/messages.js +261 -0
- package/dist/middleware/audit-message.d.ts +5 -0
- package/dist/middleware/audit-message.js +95 -0
- package/dist/middleware/index.d.ts +2 -0
- package/dist/middleware/index.js +2 -0
- package/dist/middleware/rate-limit.d.ts +4 -0
- package/dist/middleware/rate-limit.js +17 -0
- package/dist/models/ai-config.d.ts +12 -0
- package/dist/models/ai-config.js +87 -0
- package/dist/models/anthropic-provider.d.ts +25 -0
- package/dist/models/anthropic-provider.js +184 -0
- package/dist/models/deepseek-provider.d.ts +20 -0
- package/dist/models/deepseek-provider.js +42 -0
- package/dist/models/google-provider.d.ts +19 -0
- package/dist/models/google-provider.js +56 -0
- package/dist/models/manager.d.ts +15 -0
- package/dist/models/manager.js +48 -0
- package/dist/models/openai-provider.d.ts +22 -0
- package/dist/models/openai-provider.js +70 -0
- package/dist/models/openrouter-provider.d.ts +36 -0
- package/dist/models/openrouter-provider.js +276 -0
- package/dist/models/providers.d.ts +33 -0
- package/dist/models/providers.js +116 -0
- package/dist/models/xai-provider.d.ts +20 -0
- package/dist/models/xai-provider.js +47 -0
- package/dist/parsing.d.ts +2 -0
- package/dist/parsing.js +18 -0
- package/dist/prompts/manager.d.ts +19 -0
- package/dist/prompts/manager.js +71 -0
- package/dist/prompts.d.ts +4 -0
- package/dist/prompts.js +158 -0
- package/dist/repl-prompt.d.ts +14 -0
- package/dist/repl-prompt.js +147 -0
- package/dist/repl.d.ts +27 -0
- package/dist/repl.js +431 -0
- package/dist/source/cli.d.ts +19 -0
- package/dist/source/cli.js +116 -0
- package/dist/source/commands/application-log-command.d.ts +2 -0
- package/dist/source/commands/application-log-command.js +43 -0
- package/dist/source/commands/clear-command.d.ts +2 -0
- package/dist/source/commands/clear-command.js +12 -0
- package/dist/source/commands/compact-command.d.ts +2 -0
- package/dist/source/commands/compact-command.js +51 -0
- package/dist/source/commands/copy-command.d.ts +2 -0
- package/dist/source/commands/copy-command.js +51 -0
- package/dist/source/commands/edit-command.d.ts +2 -0
- package/dist/source/commands/edit-command.js +53 -0
- package/dist/source/commands/edit-prompt-command.d.ts +2 -0
- package/dist/source/commands/edit-prompt-command.js +25 -0
- package/dist/source/commands/exit-command.d.ts +2 -0
- package/dist/source/commands/exit-command.js +14 -0
- package/dist/source/commands/files-command.d.ts +2 -0
- package/dist/source/commands/files-command.js +63 -0
- package/dist/source/commands/generate-rules-command.d.ts +2 -0
- package/dist/source/commands/generate-rules-command.js +61 -0
- package/dist/source/commands/help-command.d.ts +2 -0
- package/dist/source/commands/help-command.js +19 -0
- package/dist/source/commands/init-command.d.ts +2 -0
- package/dist/source/commands/init-command.js +40 -0
- package/dist/source/commands/last-log-command.d.ts +2 -0
- package/dist/source/commands/last-log-command.js +76 -0
- package/dist/source/commands/manager.d.ts +22 -0
- package/dist/source/commands/manager.js +123 -0
- package/dist/source/commands/model-command.d.ts +2 -0
- package/dist/source/commands/model-command.js +84 -0
- package/dist/source/commands/paste-command.d.ts +2 -0
- package/dist/source/commands/paste-command.js +40 -0
- package/dist/source/commands/prompt-command.d.ts +2 -0
- package/dist/source/commands/prompt-command.js +111 -0
- package/dist/source/commands/reset-command.d.ts +2 -0
- package/dist/source/commands/reset-command.js +16 -0
- package/dist/source/commands/rules-command.d.ts +2 -0
- package/dist/source/commands/rules-command.js +68 -0
- package/dist/source/commands/save-command.d.ts +2 -0
- package/dist/source/commands/save-command.js +14 -0
- package/dist/source/commands/types.d.ts +26 -0
- package/dist/source/commands/types.js +1 -0
- package/dist/source/commands/usage-command.d.ts +2 -0
- package/dist/source/commands/usage-command.js +21 -0
- package/dist/source/config.d.ts +60 -0
- package/dist/source/config.js +193 -0
- package/dist/source/conversation-analyzer.d.ts +10 -0
- package/dist/source/conversation-analyzer.js +88 -0
- package/dist/source/dedent.d.ts +3 -0
- package/dist/source/dedent.js +38 -0
- package/dist/source/formatting.d.ts +17 -0
- package/dist/source/formatting.js +103 -0
- package/dist/source/index.d.ts +18 -0
- package/dist/source/index.js +213 -0
- package/dist/source/logger.d.ts +2 -0
- package/dist/source/logger.js +24 -0
- package/dist/source/mentions.d.ts +9 -0
- package/dist/source/mentions.js +182 -0
- package/dist/source/messages.d.ts +69 -0
- package/dist/source/messages.js +261 -0
- package/dist/source/middleware/audit-message.d.ts +5 -0
- package/dist/source/middleware/audit-message.js +95 -0
- package/dist/source/middleware/index.d.ts +2 -0
- package/dist/source/middleware/index.js +2 -0
- package/dist/source/middleware/rate-limit.d.ts +4 -0
- package/dist/source/middleware/rate-limit.js +17 -0
- package/dist/source/models/ai-config.d.ts +12 -0
- package/dist/source/models/ai-config.js +87 -0
- package/dist/source/models/anthropic-provider.d.ts +25 -0
- package/dist/source/models/anthropic-provider.js +184 -0
- package/dist/source/models/deepseek-provider.d.ts +20 -0
- package/dist/source/models/deepseek-provider.js +42 -0
- package/dist/source/models/google-provider.d.ts +19 -0
- package/dist/source/models/google-provider.js +56 -0
- package/dist/source/models/manager.d.ts +15 -0
- package/dist/source/models/manager.js +48 -0
- package/dist/source/models/openai-provider.d.ts +22 -0
- package/dist/source/models/openai-provider.js +70 -0
- package/dist/source/models/openrouter-provider.d.ts +36 -0
- package/dist/source/models/openrouter-provider.js +276 -0
- package/dist/source/models/providers.d.ts +33 -0
- package/dist/source/models/providers.js +116 -0
- package/dist/source/models/xai-provider.d.ts +20 -0
- package/dist/source/models/xai-provider.js +47 -0
- package/dist/source/parsing.d.ts +2 -0
- package/dist/source/parsing.js +18 -0
- package/dist/source/prompts/manager.d.ts +19 -0
- package/dist/source/prompts/manager.js +71 -0
- package/dist/source/prompts.d.ts +4 -0
- package/dist/source/prompts.js +158 -0
- package/dist/source/repl-prompt.d.ts +14 -0
- package/dist/source/repl-prompt.js +147 -0
- package/dist/source/repl.d.ts +27 -0
- package/dist/source/repl.js +431 -0
- package/dist/source/terminal/formatting.d.ts +37 -0
- package/dist/source/terminal/formatting.js +106 -0
- package/dist/source/terminal/index.d.ts +94 -0
- package/dist/source/terminal/index.js +420 -0
- package/dist/source/terminal/markdown-utils.d.ts +2 -0
- package/dist/source/terminal/markdown-utils.js +81 -0
- package/dist/source/terminal/markdown.d.ts +1 -0
- package/dist/source/terminal/markdown.js +111 -0
- package/dist/source/terminal/types.d.ts +71 -0
- package/dist/source/terminal/types.js +1 -0
- package/dist/source/terminal-output.d.ts +8 -0
- package/dist/source/terminal-output.js +213 -0
- package/dist/source/terminal-output.test.d.ts +8 -0
- package/dist/source/terminal-output.test.js +213 -0
- package/dist/source/token-tracker.d.ts +14 -0
- package/dist/source/token-tracker.js +53 -0
- package/dist/source/token-utils.d.ts +7 -0
- package/dist/source/token-utils.js +13 -0
- package/dist/source/tools/agent.d.ts +17 -0
- package/dist/source/tools/agent.js +87 -0
- package/dist/source/tools/bash.d.ts +19 -0
- package/dist/source/tools/bash.js +294 -0
- package/dist/source/tools/code-interpreter.d.ts +12 -0
- package/dist/source/tools/code-interpreter.js +131 -0
- package/dist/source/tools/command-validation.d.ts +8 -0
- package/dist/source/tools/command-validation.js +69 -0
- package/dist/source/tools/delete-file.d.ts +12 -0
- package/dist/source/tools/delete-file.js +56 -0
- package/dist/source/tools/directory-tree.d.ts +12 -0
- package/dist/source/tools/directory-tree.js +38 -0
- package/dist/source/tools/edit-file.d.ts +19 -0
- package/dist/source/tools/edit-file.js +107 -0
- package/dist/source/tools/filesystem-utils.d.ts +22 -0
- package/dist/source/tools/filesystem-utils.js +191 -0
- package/dist/source/tools/git-utils.d.ts +14 -0
- package/dist/source/tools/git-utils.js +64 -0
- package/dist/source/tools/grep.d.ts +17 -0
- package/dist/source/tools/grep.js +138 -0
- package/dist/source/tools/index.d.ts +161 -0
- package/dist/source/tools/index.js +209 -0
- package/dist/source/tools/memory-read.d.ts +13 -0
- package/dist/source/tools/memory-read.js +135 -0
- package/dist/source/tools/memory-write.d.ts +12 -0
- package/dist/source/tools/memory-write.js +83 -0
- package/dist/source/tools/move-file.d.ts +13 -0
- package/dist/source/tools/move-file.js +44 -0
- package/dist/source/tools/read-file.d.ts +17 -0
- package/dist/source/tools/read-file.js +86 -0
- package/dist/source/tools/read-multiple-files.d.ts +14 -0
- package/dist/source/tools/read-multiple-files.js +55 -0
- package/dist/source/tools/save-file.d.ts +17 -0
- package/dist/source/tools/save-file.js +98 -0
- package/dist/source/tools/think.d.ts +11 -0
- package/dist/source/tools/think.js +45 -0
- package/dist/source/tools/types.d.ts +29 -0
- package/dist/source/tools/types.js +14 -0
- package/dist/source/tools/web-fetch.d.ts +47 -0
- package/dist/source/tools/web-fetch.js +246 -0
- package/dist/source/tools/web-search.d.ts +13 -0
- package/dist/source/tools/web-search.js +80 -0
- package/dist/source/utils/process.d.ts +36 -0
- package/dist/source/utils/process.js +75 -0
- package/dist/source/version.d.ts +1 -0
- package/dist/source/version.js +21 -0
- package/dist/terminal/formatting.d.ts +37 -0
- package/dist/terminal/formatting.js +106 -0
- package/dist/terminal/index.d.ts +94 -0
- package/dist/terminal/index.js +420 -0
- package/dist/terminal/markdown-utils.d.ts +2 -0
- package/dist/terminal/markdown-utils.js +81 -0
- package/dist/terminal/markdown.d.ts +1 -0
- package/dist/terminal/markdown.js +111 -0
- package/dist/terminal/types.d.ts +71 -0
- package/dist/terminal/types.js +1 -0
- package/dist/terminal-output.d.ts +8 -0
- package/dist/terminal-output.js +213 -0
- package/dist/token-tracker.d.ts +14 -0
- package/dist/token-tracker.js +53 -0
- package/dist/token-utils.d.ts +7 -0
- package/dist/token-utils.js +13 -0
- package/dist/tools/agent.d.ts +17 -0
- package/dist/tools/agent.js +87 -0
- package/dist/tools/bash.d.ts +19 -0
- package/dist/tools/bash.js +294 -0
- package/dist/tools/code-interpreter.d.ts +12 -0
- package/dist/tools/code-interpreter.js +131 -0
- package/dist/tools/command-validation.d.ts +8 -0
- package/dist/tools/command-validation.js +69 -0
- package/dist/tools/delete-file.d.ts +12 -0
- package/dist/tools/delete-file.js +56 -0
- package/dist/tools/directory-tree.d.ts +12 -0
- package/dist/tools/directory-tree.js +38 -0
- package/dist/tools/edit-file.d.ts +19 -0
- package/dist/tools/edit-file.js +107 -0
- package/dist/tools/filesystem-utils.d.ts +22 -0
- package/dist/tools/filesystem-utils.js +191 -0
- package/dist/tools/git-utils.d.ts +14 -0
- package/dist/tools/git-utils.js +64 -0
- package/dist/tools/grep.d.ts +17 -0
- package/dist/tools/grep.js +138 -0
- package/dist/tools/index.d.ts +161 -0
- package/dist/tools/index.js +209 -0
- package/dist/tools/memory-read.d.ts +13 -0
- package/dist/tools/memory-read.js +135 -0
- package/dist/tools/memory-write.d.ts +12 -0
- package/dist/tools/memory-write.js +83 -0
- package/dist/tools/move-file.d.ts +13 -0
- package/dist/tools/move-file.js +44 -0
- package/dist/tools/read-file.d.ts +17 -0
- package/dist/tools/read-file.js +86 -0
- package/dist/tools/read-multiple-files.d.ts +14 -0
- package/dist/tools/read-multiple-files.js +55 -0
- package/dist/tools/save-file.d.ts +17 -0
- package/dist/tools/save-file.js +98 -0
- package/dist/tools/think.d.ts +11 -0
- package/dist/tools/think.js +45 -0
- package/dist/tools/types.d.ts +29 -0
- package/dist/tools/types.js +14 -0
- package/dist/tools/web-fetch.d.ts +47 -0
- package/dist/tools/web-fetch.js +246 -0
- package/dist/tools/web-search.d.ts +13 -0
- package/dist/tools/web-search.js +80 -0
- package/dist/utils/process.d.ts +36 -0
- package/dist/utils/process.js +75 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +21 -0
- package/knip.json +5 -0
- package/package.json +83 -0
- package/source/cli.ts +172 -0
- package/source/commands/application-log-command.ts +53 -0
- package/source/commands/clear-command.ts +14 -0
- package/source/commands/compact-command.ts +64 -0
- package/source/commands/copy-command.ts +55 -0
- package/source/commands/edit-command.ts +63 -0
- package/source/commands/edit-prompt-command.ts +31 -0
- package/source/commands/exit-command.ts +18 -0
- package/source/commands/files-command.ts +85 -0
- package/source/commands/generate-rules-command.ts +82 -0
- package/source/commands/help-command.ts +27 -0
- package/source/commands/init-command.ts +48 -0
- package/source/commands/last-log-command.ts +88 -0
- package/source/commands/manager.ts +151 -0
- package/source/commands/model-command.ts +123 -0
- package/source/commands/paste-command.ts +62 -0
- package/source/commands/prompt-command.ts +150 -0
- package/source/commands/reset-command.ts +22 -0
- package/source/commands/rules-command.ts +76 -0
- package/source/commands/save-command.ts +20 -0
- package/source/commands/types.ts +28 -0
- package/source/commands/usage-command.ts +26 -0
- package/source/config.ts +223 -0
- package/source/conversation-analyzer.ts +115 -0
- package/source/dedent.ts +53 -0
- package/source/formatting.ts +132 -0
- package/source/index.ts +240 -0
- package/source/logger.ts +29 -0
- package/source/mentions.ts +227 -0
- package/source/messages.ts +360 -0
- package/source/middleware/audit-message.ts +133 -0
- package/source/middleware/index.ts +2 -0
- package/source/middleware/rate-limit.ts +24 -0
- package/source/models/ai-config.ts +109 -0
- package/source/models/anthropic-provider.ts +199 -0
- package/source/models/deepseek-provider.ts +53 -0
- package/source/models/google-provider.ts +68 -0
- package/source/models/manager.ts +84 -0
- package/source/models/openai-provider.ts +81 -0
- package/source/models/openrouter-provider.ts +288 -0
- package/source/models/providers.ts +197 -0
- package/source/models/xai-provider.ts +59 -0
- package/source/parsing.ts +20 -0
- package/source/prompts/manager.ts +90 -0
- package/source/prompts.ts +172 -0
- package/source/repl-prompt.ts +196 -0
- package/source/repl.ts +572 -0
- package/source/terminal/formatting.ts +121 -0
- package/source/terminal/index.ts +518 -0
- package/source/terminal/markdown-utils.ts +89 -0
- package/source/terminal/markdown.ts +155 -0
- package/source/terminal/types.ts +84 -0
- package/source/terminal-output.test.ts +266 -0
- package/source/token-tracker.ts +78 -0
- package/source/token-utils.ts +17 -0
- package/source/tools/agent.ts +107 -0
- package/source/tools/bash.ts +367 -0
- package/source/tools/code-interpreter.ts +172 -0
- package/source/tools/command-validation.ts +81 -0
- package/source/tools/delete-file.ts +71 -0
- package/source/tools/directory-tree.ts +54 -0
- package/source/tools/edit-file.ts +155 -0
- package/source/tools/filesystem-utils.ts +265 -0
- package/source/tools/git-utils.ts +70 -0
- package/source/tools/grep.ts +184 -0
- package/source/tools/index.ts +278 -0
- package/source/tools/memory-read.ts +174 -0
- package/source/tools/memory-write.ts +105 -0
- package/source/tools/move-file.ts +59 -0
- package/source/tools/read-file.ts +129 -0
- package/source/tools/read-multiple-files.ts +80 -0
- package/source/tools/save-file.ts +147 -0
- package/source/tools/think.ts +51 -0
- package/source/tools/types.ts +58 -0
- package/source/tools/web-fetch.ts +327 -0
- package/source/tools/web-search.ts +101 -0
- package/source/utils/process.ts +121 -0
- package/source/version.ts +21 -0
- package/test/commands/copy-command.test.ts +69 -0
- package/test/config.test.ts +200 -0
- package/test/terminal/markdown-utils.test.ts +124 -0
- package/test/tools/bash-tool.test.ts +58 -0
- package/test/tools/code-interpreter.test.ts +91 -0
- package/test/tools/command-validation.test.ts +48 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.json +30 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { formatModelInfo, getModelsByCategory, isValidModel, modelRegistry, models, providers, } from "../models/providers.js";
|
|
2
|
+
export function modelCommand(options) {
|
|
3
|
+
const { terminal, modelManager } = options;
|
|
4
|
+
function switchModel(newModelName) {
|
|
5
|
+
try {
|
|
6
|
+
// Get current and new model configs
|
|
7
|
+
const currentModelConfig = modelManager.getModelMetadata("repl");
|
|
8
|
+
const newModelConfig = modelRegistry[newModelName]; // Ensure modelRegistry is available
|
|
9
|
+
if (!newModelConfig) {
|
|
10
|
+
terminal.error(`Model configuration not found for: ${newModelName}`);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
// Check for capability differences
|
|
14
|
+
if (currentModelConfig.supportsToolCalling &&
|
|
15
|
+
!newModelConfig.supportsToolCalling) {
|
|
16
|
+
terminal.warn("The new model doesn't support tool calling, which may limit functionality.");
|
|
17
|
+
}
|
|
18
|
+
if (currentModelConfig.supportsReasoning &&
|
|
19
|
+
!newModelConfig.supportsReasoning) {
|
|
20
|
+
terminal.warn("The new model doesn't support reasoning, which may change response quality.");
|
|
21
|
+
}
|
|
22
|
+
// Update model in ModelManager
|
|
23
|
+
modelManager.setModel("repl", newModelName);
|
|
24
|
+
// Assuming ModelManager handles the actual model instance switching internally.
|
|
25
|
+
terminal.info(`Model set to ${newModelName}.`); // Simplified message
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
terminal.error(`Failed to switch model: ${error.message}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
command: "/model",
|
|
33
|
+
description: "List available models or switch to a different model. Usage: /model [provider:model-name|category|provider]",
|
|
34
|
+
result: "continue",
|
|
35
|
+
getSubCommands: () => Promise.resolve(models),
|
|
36
|
+
async execute(args) {
|
|
37
|
+
const arg = args.join(" ").trim();
|
|
38
|
+
const modelConfig = modelManager.getModelMetadata("repl");
|
|
39
|
+
// No args - display current model and list available models by category
|
|
40
|
+
if (!arg) {
|
|
41
|
+
const currentModel = modelConfig.id;
|
|
42
|
+
terminal.header(`Current model: ${currentModel}`);
|
|
43
|
+
terminal.header("Available models by category:");
|
|
44
|
+
// Display models by category
|
|
45
|
+
for (const category of ["fast", "balanced", "powerful"]) {
|
|
46
|
+
// Use 'as const' for stricter typing
|
|
47
|
+
terminal.writeln(`\n${category.charAt(0).toUpperCase() + category.slice(1)} models:`);
|
|
48
|
+
for (const model of getModelsByCategory(category)) {
|
|
49
|
+
terminal.writeln(formatModelInfo(model));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
// Switch to a specific model
|
|
55
|
+
if (isValidModel(arg)) {
|
|
56
|
+
// Call the standalone switchModel function
|
|
57
|
+
switchModel(arg);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// Display models by category
|
|
61
|
+
const categories = ["fast", "balanced", "powerful"];
|
|
62
|
+
if (categories.includes(arg)) {
|
|
63
|
+
terminal.header(`${arg.charAt(0).toUpperCase() + arg.slice(1)} models:`);
|
|
64
|
+
// Need to assert arg is a valid category if the check passes
|
|
65
|
+
for (const model of getModelsByCategory(arg)) {
|
|
66
|
+
terminal.writeln(formatModelInfo(model));
|
|
67
|
+
}
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// Display models by provider
|
|
71
|
+
if (providers.includes(arg)) {
|
|
72
|
+
terminal.header(`Models from ${arg}:`);
|
|
73
|
+
// Need to ensure modelRegistry is accessible and correctly typed
|
|
74
|
+
for (const model of Object.values(modelRegistry).filter((m) => m.provider === arg)) {
|
|
75
|
+
terminal.writeln(formatModelInfo(model));
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// Invalid model name
|
|
80
|
+
terminal.error(`Invalid model name or category: ${arg}`);
|
|
81
|
+
terminal.info("Usage: /model [provider:model-name|category|provider]");
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import Clipboard from "@crosscopy/clipboard";
|
|
2
|
+
import { formatBlock } from "../formatting.js";
|
|
3
|
+
import { logger } from "../logger.js";
|
|
4
|
+
const base64UrlRegex = /^data:(.*?);base64,/;
|
|
5
|
+
export const pasteCommand = ({ terminal, modelManager, promptManager, }) => {
|
|
6
|
+
return {
|
|
7
|
+
command: "/paste",
|
|
8
|
+
description: "Pastes image or text content from the clipboard into the next prompt.",
|
|
9
|
+
result: "continue",
|
|
10
|
+
getSubCommands: () => Promise.resolve([]),
|
|
11
|
+
execute: async () => {
|
|
12
|
+
try {
|
|
13
|
+
if (Clipboard.hasImage()) {
|
|
14
|
+
const base64DataUrl = await Clipboard.getImageBase64();
|
|
15
|
+
const mimeTypeMatch = base64DataUrl.match(base64UrlRegex);
|
|
16
|
+
const mimeType = mimeTypeMatch ? mimeTypeMatch[1] : "image/png";
|
|
17
|
+
promptManager.addContext({
|
|
18
|
+
type: "image",
|
|
19
|
+
image: base64DataUrl,
|
|
20
|
+
mediaType: mimeType,
|
|
21
|
+
});
|
|
22
|
+
terminal.success("Image from clipboard will be added to your next prompt.");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const clipboardContent = await Clipboard.getText();
|
|
26
|
+
if (!clipboardContent || clipboardContent.trim() === "") {
|
|
27
|
+
terminal.warn("Clipboard is empty.");
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
promptManager.addContext(formatBlock(clipboardContent, "clipboard", modelManager.getModelMetadata("repl").promptFormat));
|
|
31
|
+
terminal.success("Clipboard content will be added to your next prompt.");
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
35
|
+
terminal.error(`Error processing clipboard content: ${message}`);
|
|
36
|
+
logger.error(error, "Paste command error:");
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
2
|
+
import path, { basename } from "node:path";
|
|
3
|
+
import { processPrompt } from "../mentions.js";
|
|
4
|
+
export const promptCommand = ({ terminal, modelManager, promptManager, config, }) => {
|
|
5
|
+
return {
|
|
6
|
+
command: "/prompt",
|
|
7
|
+
description: "Loads and executes prompts. Project prompts override user prompts with the same name.",
|
|
8
|
+
result: "use",
|
|
9
|
+
getSubCommands: async () => {
|
|
10
|
+
const getPromptNamesFromDir = async (dirPath) => {
|
|
11
|
+
try {
|
|
12
|
+
const dirents = await readdir(dirPath, { withFileTypes: true });
|
|
13
|
+
return dirents
|
|
14
|
+
.filter((dirent) => dirent.isFile() && dirent.name.endsWith(".md"))
|
|
15
|
+
.map((dirent) => basename(dirent.name, ".md"));
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
if (error.code === "ENOENT") {
|
|
19
|
+
return []; // Directory doesn't exist, return empty array
|
|
20
|
+
}
|
|
21
|
+
terminal.error(`Error reading prompts from ${dirPath}: ${error}`);
|
|
22
|
+
return []; // Return empty on other errors too, but log them
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
const userPromptDir = config.app.ensurePathSync("prompts"); // User prompts are global (~/.acai/prompts)
|
|
26
|
+
const projectPromptDir = config.project.ensurePathSync("prompts"); // Project prompts are local (./.acai/prompts)
|
|
27
|
+
const userPrompts = await getPromptNamesFromDir(userPromptDir);
|
|
28
|
+
const projectPrompts = await getPromptNamesFromDir(projectPromptDir);
|
|
29
|
+
// Combine and deduplicate, with project prompts taking precedence
|
|
30
|
+
const allPrompts = new Set([...userPrompts, ...projectPrompts]);
|
|
31
|
+
return Array.from(allPrompts).sort();
|
|
32
|
+
},
|
|
33
|
+
execute: async (args) => {
|
|
34
|
+
const promptName = args?.[0];
|
|
35
|
+
if (!promptName) {
|
|
36
|
+
terminal.warn("Please provide a prompt name. Usage: /prompt <prompt-name> [input...]");
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
// Check for old format and provide helpful error
|
|
40
|
+
if (promptName.includes(":")) {
|
|
41
|
+
terminal.warn("The old format (user:name or project:name) is no longer supported. Use: /prompt <prompt-name> [input...]");
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const promptResult = await findPrompt(promptName, config);
|
|
46
|
+
if (!promptResult) {
|
|
47
|
+
terminal.error(`Prompt not found: ${promptName}. Available prompts can be seen with tab completion.`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
let promptContent;
|
|
51
|
+
try {
|
|
52
|
+
promptContent = await readFile(promptResult.path, "utf8");
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
if (error.code === "ENOENT") {
|
|
56
|
+
terminal.error(`Prompt file not found: ${promptName} at ${promptResult.path}`);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
// Combine remaining arguments into a single string for input
|
|
62
|
+
const inputArgs = args.slice(1);
|
|
63
|
+
const inputString = inputArgs.join(" ");
|
|
64
|
+
// Replace {{INPUT}} placeholder with the input string
|
|
65
|
+
if (promptContent.includes("{{INPUT}}")) {
|
|
66
|
+
promptContent = promptContent.replace(/{{INPUT}}/g, inputString);
|
|
67
|
+
}
|
|
68
|
+
terminal.info(`Loaded ${promptResult.type} prompt: ${promptName}`);
|
|
69
|
+
if (inputArgs.length > 0) {
|
|
70
|
+
terminal.info(`Input: "${inputString}"`);
|
|
71
|
+
}
|
|
72
|
+
const processedPrompt = await processPrompt(promptContent, {
|
|
73
|
+
baseDir: process.cwd(),
|
|
74
|
+
model: modelManager.getModelMetadata("repl"),
|
|
75
|
+
});
|
|
76
|
+
for (const context of processedPrompt.context) {
|
|
77
|
+
promptManager.addContext(context);
|
|
78
|
+
}
|
|
79
|
+
promptManager.set(processedPrompt.message);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
terminal.error(`Error loading prompt: ${error.message}`);
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
async function findPrompt(promptName, config) {
|
|
88
|
+
// Check project prompts first (they take precedence)
|
|
89
|
+
const projectPath = path.join(config.project.ensurePathSync("prompts"), `${promptName}.md`);
|
|
90
|
+
try {
|
|
91
|
+
await readFile(projectPath, "utf8");
|
|
92
|
+
return { path: projectPath, type: "project" };
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
if (error.code !== "ENOENT") {
|
|
96
|
+
throw error; // Re-throw non-file-not-found errors
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Check user prompts if not found in project
|
|
100
|
+
const userPath = path.join(config.app.ensurePathSync("prompts"), `${promptName}.md`);
|
|
101
|
+
try {
|
|
102
|
+
await readFile(userPath, "utf8");
|
|
103
|
+
return { path: userPath, type: "user" };
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
if (error.code !== "ENOENT") {
|
|
107
|
+
throw error; // Re-throw non-file-not-found errors
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return null; // Prompt not found in either location
|
|
111
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const resetCommand = ({ terminal, messageHistory, }) => {
|
|
2
|
+
return {
|
|
3
|
+
command: "/reset",
|
|
4
|
+
description: "Saves the chat history and then resets it.",
|
|
5
|
+
result: "continue",
|
|
6
|
+
getSubCommands: () => Promise.resolve([]),
|
|
7
|
+
execute: async () => {
|
|
8
|
+
if (!messageHistory.isEmpty()) {
|
|
9
|
+
await messageHistory.save();
|
|
10
|
+
messageHistory.clear();
|
|
11
|
+
}
|
|
12
|
+
terminal.setTitle(`acai: ${process.cwd()}`);
|
|
13
|
+
terminal.clear();
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { editor } from "@inquirer/prompts";
|
|
2
|
+
import { config } from "../config.js";
|
|
3
|
+
export const rulesCommand = ({ terminal }) => {
|
|
4
|
+
return {
|
|
5
|
+
command: "/rules",
|
|
6
|
+
description: "View, add, or edit rules. Usage: /rules [view|add <text>|edit]",
|
|
7
|
+
result: "continue",
|
|
8
|
+
getSubCommands: () => Promise.resolve(["view", "add", "edit"]),
|
|
9
|
+
execute: async (args) => {
|
|
10
|
+
const subCommand = args[0] ?? "view"; // Default to 'view'
|
|
11
|
+
const commandArgs = args.slice(1).join(" ");
|
|
12
|
+
try {
|
|
13
|
+
switch (subCommand) {
|
|
14
|
+
case "view": {
|
|
15
|
+
const currentContent = await config.readAgentsFile();
|
|
16
|
+
if (currentContent) {
|
|
17
|
+
terminal.writeln("--- Current Rules ---");
|
|
18
|
+
terminal.writeln(currentContent);
|
|
19
|
+
terminal.writeln("---------------------");
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
terminal.writeln("No rules defined yet. Use '/rules add' or '/rules edit'.");
|
|
23
|
+
}
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
case "add": {
|
|
27
|
+
const newMemory = commandArgs.trim();
|
|
28
|
+
if (!newMemory) {
|
|
29
|
+
terminal.error("Error: Memory text cannot be empty for 'add'.");
|
|
30
|
+
terminal.writeln("Usage: /memory add <new memory text>");
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const currentContent = await config.readAgentsFile();
|
|
34
|
+
const updatedContent = currentContent
|
|
35
|
+
? `${currentContent.trim()}\n- ${newMemory}` // Ensure space after dash
|
|
36
|
+
: `- ${newMemory}`; // Start with dash if new file
|
|
37
|
+
await config.writeAgentsFile(updatedContent);
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
case "edit": {
|
|
41
|
+
const currentContent = await config.readAgentsFile();
|
|
42
|
+
const updatedContent = await editor({
|
|
43
|
+
message: "Edit rules:",
|
|
44
|
+
postfix: "md",
|
|
45
|
+
default: currentContent,
|
|
46
|
+
});
|
|
47
|
+
// Check if the user cancelled the edit (editor returns the original content)
|
|
48
|
+
// Or if the content is actually different
|
|
49
|
+
if (updatedContent !== currentContent) {
|
|
50
|
+
await config.writeAgentsFile(updatedContent);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
terminal.writeln("Edit cancelled or no changes made.");
|
|
54
|
+
}
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
default:
|
|
58
|
+
terminal.writeln("Invalid subcommand. Usage: /rules [view|add <text>|edit]");
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (_error) {
|
|
63
|
+
// Errors from read/write helpers are already logged
|
|
64
|
+
terminal.error("Failed to execute memory command.");
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const saveCommand = ({ messageHistory, terminal, }) => {
|
|
2
|
+
return {
|
|
3
|
+
command: "/save",
|
|
4
|
+
description: "Saves the chat history.",
|
|
5
|
+
result: "continue",
|
|
6
|
+
getSubCommands: () => Promise.resolve([]),
|
|
7
|
+
execute: async () => {
|
|
8
|
+
if (!messageHistory.isEmpty()) {
|
|
9
|
+
await messageHistory.save();
|
|
10
|
+
}
|
|
11
|
+
terminal.info("Message history saved.");
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ConfigManager } from "../config.ts";
|
|
2
|
+
import type { MessageHistory } from "../messages.ts";
|
|
3
|
+
import type { ModelManager } from "../models/manager.ts";
|
|
4
|
+
import type { PromptManager } from "../prompts/manager.ts";
|
|
5
|
+
import type { Terminal } from "../terminal/index.ts";
|
|
6
|
+
import type { TokenTracker } from "../token-tracker.ts";
|
|
7
|
+
import type { TokenCounter } from "../token-utils.ts";
|
|
8
|
+
import type { Message } from "../tools/types.ts";
|
|
9
|
+
export interface ReplCommand {
|
|
10
|
+
command: string;
|
|
11
|
+
aliases?: string[];
|
|
12
|
+
description: string;
|
|
13
|
+
result: "break" | "continue" | "use";
|
|
14
|
+
getSubCommands: () => Promise<string[]>;
|
|
15
|
+
execute: (args: string[]) => Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export interface CommandOptions {
|
|
18
|
+
promptManager: PromptManager;
|
|
19
|
+
modelManager: ModelManager;
|
|
20
|
+
terminal: Terminal;
|
|
21
|
+
messageHistory: MessageHistory;
|
|
22
|
+
tokenTracker: TokenTracker;
|
|
23
|
+
config: ConfigManager;
|
|
24
|
+
tokenCounter: TokenCounter;
|
|
25
|
+
toolEvents: Map<string, Message[]>;
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function usageCommand({ terminal, tokenTracker, }) {
|
|
2
|
+
return {
|
|
3
|
+
command: "/usage",
|
|
4
|
+
description: "Show token usage breakdown",
|
|
5
|
+
result: "continue",
|
|
6
|
+
getSubCommands: () => Promise.resolve([]),
|
|
7
|
+
execute() {
|
|
8
|
+
const entries = Object.entries(tokenTracker.getUsageBreakdown());
|
|
9
|
+
if (entries.length === 0) {
|
|
10
|
+
terminal.info("No usage yet.");
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
terminal.table(entries, {
|
|
14
|
+
header: ["App", "Tokens"],
|
|
15
|
+
colWidths: [30, 70],
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return Promise.resolve();
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare class DirectoryProvider {
|
|
3
|
+
private baseDir;
|
|
4
|
+
constructor(baseDir: string);
|
|
5
|
+
getPath(subdir?: string): string;
|
|
6
|
+
ensurePath(subdir?: string): Promise<string>;
|
|
7
|
+
ensurePathSync(subdir?: string): string;
|
|
8
|
+
}
|
|
9
|
+
export declare class ConfigManager {
|
|
10
|
+
readonly project: DirectoryProvider;
|
|
11
|
+
readonly app: DirectoryProvider;
|
|
12
|
+
constructor();
|
|
13
|
+
private _readConfig;
|
|
14
|
+
readProjectConfig(): Promise<ProjectConfig>;
|
|
15
|
+
readAgentsFile(): Promise<string>;
|
|
16
|
+
writeAgentsFile(rules: string): Promise<void>;
|
|
17
|
+
readProjectLearnedRulesFile(): Promise<string>;
|
|
18
|
+
writeProjectLearnedRulesFile(rules: string): Promise<void>;
|
|
19
|
+
readCachedLearnedRulesFile(): Promise<string>;
|
|
20
|
+
writeCachedLearnedRulesFile(rules: string): Promise<void>;
|
|
21
|
+
readAppConfig(configName: string): Promise<Record<PropertyKey, unknown>>;
|
|
22
|
+
ensureAppConfig(configName: string): Promise<Record<PropertyKey, unknown>>;
|
|
23
|
+
writeAppConfig(configName: string, data: Record<PropertyKey, unknown>): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
declare const ProjectConfigSchema: z.ZodObject<{
|
|
26
|
+
logs: z.ZodOptional<z.ZodObject<{
|
|
27
|
+
path: z.ZodString;
|
|
28
|
+
}, "strip", z.ZodTypeAny, {
|
|
29
|
+
path: string;
|
|
30
|
+
}, {
|
|
31
|
+
path: string;
|
|
32
|
+
}>>;
|
|
33
|
+
tools: z.ZodDefault<z.ZodOptional<z.ZodObject<{
|
|
34
|
+
maxTokens: z.ZodDefault<z.ZodNumber>;
|
|
35
|
+
}, "strip", z.ZodTypeAny, {
|
|
36
|
+
maxTokens: number;
|
|
37
|
+
}, {
|
|
38
|
+
maxTokens?: number | undefined;
|
|
39
|
+
}>>>;
|
|
40
|
+
notify: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
41
|
+
}, "strip", z.ZodTypeAny, {
|
|
42
|
+
tools: {
|
|
43
|
+
maxTokens: number;
|
|
44
|
+
};
|
|
45
|
+
notify: boolean;
|
|
46
|
+
logs?: {
|
|
47
|
+
path: string;
|
|
48
|
+
} | undefined;
|
|
49
|
+
}, {
|
|
50
|
+
logs?: {
|
|
51
|
+
path: string;
|
|
52
|
+
} | undefined;
|
|
53
|
+
tools?: {
|
|
54
|
+
maxTokens?: number | undefined;
|
|
55
|
+
} | undefined;
|
|
56
|
+
notify?: boolean | undefined;
|
|
57
|
+
}>;
|
|
58
|
+
export type ProjectConfig = z.infer<typeof ProjectConfigSchema>;
|
|
59
|
+
export declare const config: ConfigManager;
|
|
60
|
+
export {};
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { mkdirSync } from "node:fs";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { jsonParser } from "./parsing.js";
|
|
7
|
+
export class DirectoryProvider {
|
|
8
|
+
baseDir;
|
|
9
|
+
constructor(baseDir) {
|
|
10
|
+
this.baseDir = baseDir;
|
|
11
|
+
}
|
|
12
|
+
getPath(subdir) {
|
|
13
|
+
return subdir ? path.join(this.baseDir, subdir) : this.baseDir;
|
|
14
|
+
}
|
|
15
|
+
// Async-by-default: prefer non-blocking filesystem operations.
|
|
16
|
+
async ensurePath(subdir) {
|
|
17
|
+
const dirPath = this.getPath(subdir);
|
|
18
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
19
|
+
return dirPath;
|
|
20
|
+
}
|
|
21
|
+
// Synchronous helper for call-sites that require immediate directory availability.
|
|
22
|
+
ensurePathSync(subdir) {
|
|
23
|
+
const dirPath = this.getPath(subdir);
|
|
24
|
+
mkdirSync(dirPath, { recursive: true });
|
|
25
|
+
return dirPath;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export class ConfigManager {
|
|
29
|
+
project;
|
|
30
|
+
app;
|
|
31
|
+
constructor() {
|
|
32
|
+
this.project = new DirectoryProvider(path.join(process.cwd(), ".acai"));
|
|
33
|
+
this.app = new DirectoryProvider(path.join(homedir(), ".acai"));
|
|
34
|
+
}
|
|
35
|
+
async _readConfig(configPath) {
|
|
36
|
+
try {
|
|
37
|
+
const data = await fs.readFile(configPath, "utf8");
|
|
38
|
+
return jsonParser(ProjectConfigSchema).parse(data);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
if (error.code === "ENOENT") {
|
|
42
|
+
return {};
|
|
43
|
+
}
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Project config helpers
|
|
48
|
+
async readProjectConfig() {
|
|
49
|
+
const appConfigPath = path.join(this.app.getPath(), "acai.json");
|
|
50
|
+
const projectConfigPath = path.join(this.project.getPath(), "acai.json");
|
|
51
|
+
const appConfig = await this._readConfig(appConfigPath);
|
|
52
|
+
const projectConfig = await this._readConfig(projectConfigPath);
|
|
53
|
+
const mergedConfig = {
|
|
54
|
+
...appConfig,
|
|
55
|
+
...projectConfig,
|
|
56
|
+
};
|
|
57
|
+
return ProjectConfigSchema.parse(mergedConfig);
|
|
58
|
+
}
|
|
59
|
+
async readAgentsFile() {
|
|
60
|
+
const agentsPath = path.join(process.cwd(), "AGENTS.md");
|
|
61
|
+
try {
|
|
62
|
+
return await fs.readFile(agentsPath, "utf8");
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
if (error.code === "ENOENT") {
|
|
66
|
+
return "";
|
|
67
|
+
}
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async writeAgentsFile(rules) {
|
|
72
|
+
const agentsPath = path.join(process.cwd(), "AGENTS.md");
|
|
73
|
+
try {
|
|
74
|
+
return await fs.writeFile(agentsPath, rules, "utf8");
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
if (error.code === "ENOENT") {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Project-specific learned rules
|
|
84
|
+
async readProjectLearnedRulesFile() {
|
|
85
|
+
const rulesPath = path.join(this.project.getPath("rules"), "learned-rules.md");
|
|
86
|
+
try {
|
|
87
|
+
return await fs.readFile(rulesPath, "utf8");
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
if (error.code === "ENOENT") {
|
|
91
|
+
return "";
|
|
92
|
+
}
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async writeProjectLearnedRulesFile(rules) {
|
|
97
|
+
const rulesDir = await this.project.ensurePath("rules");
|
|
98
|
+
const rulesPath = path.join(rulesDir, "learned-rules.md");
|
|
99
|
+
try {
|
|
100
|
+
return await fs.writeFile(rulesPath, rules, "utf8");
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
if (error.code === "ENOENT") {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// App-cached learned rules (used during conversation analysis)
|
|
110
|
+
async readCachedLearnedRulesFile() {
|
|
111
|
+
const rulesPath = path.join(this.app.getPath("rules"), "learned-rules.md");
|
|
112
|
+
try {
|
|
113
|
+
return await fs.readFile(rulesPath, "utf8");
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
if (error.code === "ENOENT") {
|
|
117
|
+
return "";
|
|
118
|
+
}
|
|
119
|
+
throw error;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async writeCachedLearnedRulesFile(rules) {
|
|
123
|
+
const rulesDir = await this.app.ensurePath("rules");
|
|
124
|
+
const rulesPath = path.join(rulesDir, "learned-rules.md");
|
|
125
|
+
try {
|
|
126
|
+
return await fs.writeFile(rulesPath, rules, "utf8");
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
if (error.code === "ENOENT") {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// App config helpers
|
|
136
|
+
async readAppConfig(configName) {
|
|
137
|
+
const configPath = path.join(this.app.getPath(), `${configName}.json`);
|
|
138
|
+
try {
|
|
139
|
+
const data = await fs.readFile(configPath, "utf8");
|
|
140
|
+
return JSON.parse(data);
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
if (error.code === "ENOENT") {
|
|
144
|
+
return {};
|
|
145
|
+
}
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
async ensureAppConfig(configName) {
|
|
150
|
+
const configPath = path.join(this.app.getPath(), `${configName}.json`);
|
|
151
|
+
try {
|
|
152
|
+
await fs.access(configPath);
|
|
153
|
+
return await this.readAppConfig(configName);
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
// Create directory and default config if missing
|
|
157
|
+
await this.app.ensurePath();
|
|
158
|
+
const defaultConfig = {
|
|
159
|
+
logs: {
|
|
160
|
+
path: path.join(this.app.getPath(), "logs", "current.log"),
|
|
161
|
+
},
|
|
162
|
+
tools: {
|
|
163
|
+
maxTokens: 30000,
|
|
164
|
+
},
|
|
165
|
+
notify: true,
|
|
166
|
+
};
|
|
167
|
+
await fs.writeFile(configPath, JSON.stringify(defaultConfig, null, 2));
|
|
168
|
+
return defaultConfig;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
async writeAppConfig(configName, data) {
|
|
172
|
+
await this.app.ensurePath();
|
|
173
|
+
const configPath = path.join(this.app.getPath(), `${configName}.json`);
|
|
174
|
+
await fs.writeFile(configPath, JSON.stringify(data, null, 2));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Type definitions
|
|
178
|
+
const ProjectConfigSchema = z.object({
|
|
179
|
+
logs: z
|
|
180
|
+
.object({
|
|
181
|
+
path: z.string(),
|
|
182
|
+
})
|
|
183
|
+
.optional(),
|
|
184
|
+
tools: z
|
|
185
|
+
.object({
|
|
186
|
+
maxTokens: z.number().default(30000),
|
|
187
|
+
})
|
|
188
|
+
.optional()
|
|
189
|
+
.default({ maxTokens: 30000 }),
|
|
190
|
+
notify: z.boolean().optional().default(true),
|
|
191
|
+
});
|
|
192
|
+
// Create a singleton instance
|
|
193
|
+
export const config = new ConfigManager();
|