@nanocollective/nanocoder 1.23.0 → 1.24.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/LICENSE.md +1 -15
- package/README.md +25 -884
- package/assets/nanocoder-vscode.vsix +0 -0
- package/dist/ai-sdk-client/ai-sdk-client.d.ts +3 -2
- package/dist/ai-sdk-client/ai-sdk-client.d.ts.map +1 -1
- package/dist/ai-sdk-client/ai-sdk-client.js +16 -2
- package/dist/ai-sdk-client/ai-sdk-client.js.map +1 -1
- package/dist/ai-sdk-client/chat/chat-handler.d.ts +2 -1
- package/dist/ai-sdk-client/chat/chat-handler.d.ts.map +1 -1
- package/dist/ai-sdk-client/chat/chat-handler.js +37 -70
- package/dist/ai-sdk-client/chat/chat-handler.js.map +1 -1
- package/dist/ai-sdk-client/chat/streaming-handler.d.ts +2 -2
- package/dist/ai-sdk-client/chat/streaming-handler.d.ts.map +1 -1
- package/dist/ai-sdk-client/chat/streaming-handler.js +4 -23
- package/dist/ai-sdk-client/chat/streaming-handler.js.map +1 -1
- package/dist/ai-sdk-client/error-handling/error-parser.d.ts.map +1 -1
- package/dist/ai-sdk-client/error-handling/error-parser.js +7 -2
- package/dist/ai-sdk-client/error-handling/error-parser.js.map +1 -1
- package/dist/ai-sdk-client/providers/provider-factory.d.ts +2 -1
- package/dist/ai-sdk-client/providers/provider-factory.d.ts.map +1 -1
- package/dist/ai-sdk-client/providers/provider-factory.js +55 -0
- package/dist/ai-sdk-client/providers/provider-factory.js.map +1 -1
- package/dist/app/App.d.ts +1 -1
- package/dist/app/App.d.ts.map +1 -1
- package/dist/app/App.js +66 -50
- package/dist/app/App.js.map +1 -1
- package/dist/app/components/chat-input.d.ts +4 -1
- package/dist/app/components/chat-input.d.ts.map +1 -1
- package/dist/app/components/chat-input.js +4 -3
- package/dist/app/components/chat-input.js.map +1 -1
- package/dist/app/components/modal-selectors.d.ts +6 -7
- package/dist/app/components/modal-selectors.d.ts.map +1 -1
- package/dist/app/components/modal-selectors.js +11 -7
- package/dist/app/components/modal-selectors.js.map +1 -1
- package/dist/app/components/settings-selector.d.ts.map +1 -1
- package/dist/app/components/settings-selector.js +3 -3
- package/dist/app/components/settings-selector.js.map +1 -1
- package/dist/app/helpers.d.ts.map +1 -1
- package/dist/app/helpers.js +2 -4
- package/dist/app/helpers.js.map +1 -1
- package/dist/app/index.d.ts +0 -1
- package/dist/app/index.d.ts.map +1 -1
- package/dist/app/index.js +0 -1
- package/dist/app/index.js.map +1 -1
- package/dist/app/types.d.ts +2 -0
- package/dist/app/types.d.ts.map +1 -1
- package/dist/app/utils/app-util.d.ts +1 -5
- package/dist/app/utils/app-util.d.ts.map +1 -1
- package/dist/app/utils/app-util.js +60 -460
- package/dist/app/utils/app-util.js.map +1 -1
- package/dist/app/utils/handlers/compact-handler.d.ts +6 -0
- package/dist/app/utils/handlers/compact-handler.d.ts.map +1 -0
- package/dist/app/utils/handlers/compact-handler.js +148 -0
- package/dist/app/utils/handlers/compact-handler.js.map +1 -0
- package/dist/app/utils/handlers/context-max-handler.d.ts +11 -0
- package/dist/app/utils/handlers/context-max-handler.d.ts.map +1 -0
- package/dist/app/utils/handlers/context-max-handler.js +102 -0
- package/dist/app/utils/handlers/context-max-handler.js.map +1 -0
- package/dist/app/utils/handlers/create-handler.d.ts +17 -0
- package/dist/app/utils/handlers/create-handler.d.ts.map +1 -0
- package/dist/app/utils/handlers/create-handler.js +112 -0
- package/dist/app/utils/handlers/create-handler.js.map +1 -0
- package/dist/app/utils/handlers/session-handler.d.ts +8 -0
- package/dist/app/utils/handlers/session-handler.d.ts.map +1 -0
- package/dist/app/utils/handlers/session-handler.js +99 -0
- package/dist/app/utils/handlers/session-handler.js.map +1 -0
- package/dist/auth/github-copilot.d.ts +44 -0
- package/dist/auth/github-copilot.d.ts.map +1 -0
- package/dist/auth/github-copilot.js +178 -0
- package/dist/auth/github-copilot.js.map +1 -0
- package/dist/cli.js +64 -3
- package/dist/cli.js.map +1 -1
- package/dist/client-factory.d.ts +1 -1
- package/dist/client-factory.d.ts.map +1 -1
- package/dist/client-factory.js +39 -8
- package/dist/client-factory.js.map +1 -1
- package/dist/commands/compact.d.ts +1 -6
- package/dist/commands/compact.d.ts.map +1 -1
- package/dist/commands/compact.js +2 -13
- package/dist/commands/compact.js.map +1 -1
- package/dist/commands/context-max.d.ts +1 -2
- package/dist/commands/context-max.d.ts.map +1 -1
- package/dist/commands/context-max.js +2 -9
- package/dist/commands/context-max.js.map +1 -1
- package/dist/commands/copilot-login-command.d.ts +3 -0
- package/dist/commands/copilot-login-command.d.ts.map +1 -0
- package/dist/commands/copilot-login-command.js +9 -0
- package/dist/commands/copilot-login-command.js.map +1 -0
- package/dist/commands/copilot-login.d.ts +9 -0
- package/dist/commands/copilot-login.d.ts.map +1 -0
- package/dist/commands/copilot-login.js +70 -0
- package/dist/commands/copilot-login.js.map +1 -0
- package/dist/commands/create-stub-command.d.ts +8 -0
- package/dist/commands/create-stub-command.d.ts.map +1 -0
- package/dist/commands/create-stub-command.js +14 -0
- package/dist/commands/create-stub-command.js.map +1 -0
- package/dist/commands/explorer.d.ts +1 -2
- package/dist/commands/explorer.d.ts.map +1 -1
- package/dist/commands/explorer.js +2 -9
- package/dist/commands/explorer.js.map +1 -1
- package/dist/commands/help.d.ts.map +1 -1
- package/dist/commands/help.js +1 -1
- package/dist/commands/help.js.map +1 -1
- package/dist/commands/ide.d.ts +1 -2
- package/dist/commands/ide.d.ts.map +1 -1
- package/dist/commands/ide.js +2 -9
- package/dist/commands/ide.js.map +1 -1
- package/dist/commands/index.d.ts +2 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +2 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +2 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/model.d.ts +1 -2
- package/dist/commands/model.d.ts.map +1 -1
- package/dist/commands/model.js +2 -10
- package/dist/commands/model.js.map +1 -1
- package/dist/commands/provider.d.ts +1 -2
- package/dist/commands/provider.d.ts.map +1 -1
- package/dist/commands/provider.js +2 -10
- package/dist/commands/provider.js.map +1 -1
- package/dist/commands/resume.d.ts +8 -0
- package/dist/commands/resume.d.ts.map +1 -0
- package/dist/commands/resume.js +11 -0
- package/dist/commands/resume.js.map +1 -0
- package/dist/commands/settings.d.ts +1 -2
- package/dist/commands/settings.d.ts.map +1 -1
- package/dist/commands/settings.js +2 -10
- package/dist/commands/settings.js.map +1 -1
- package/dist/commands/status.d.ts +1 -2
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +2 -10
- package/dist/commands/status.js.map +1 -1
- package/dist/components/assistant-message.d.ts.map +1 -1
- package/dist/components/assistant-message.js +2 -27
- package/dist/components/assistant-message.js.map +1 -1
- package/dist/components/provider-selector.d.ts.map +1 -1
- package/dist/components/provider-selector.js +4 -3
- package/dist/components/provider-selector.js.map +1 -1
- package/dist/components/session-selector.d.ts +12 -0
- package/dist/components/session-selector.d.ts.map +1 -0
- package/dist/components/session-selector.js +108 -0
- package/dist/components/session-selector.js.map +1 -0
- package/dist/components/tool-confirmation.d.ts.map +1 -1
- package/dist/components/tool-confirmation.js +9 -6
- package/dist/components/tool-confirmation.js.map +1 -1
- package/dist/components/ui/styled-title.js +2 -2
- package/dist/components/ui/styled-title.js.map +1 -1
- package/dist/components/user-input.d.ts +3 -1
- package/dist/components/user-input.d.ts.map +1 -1
- package/dist/components/user-input.js +35 -23
- package/dist/components/user-input.js.map +1 -1
- package/dist/components/user-message.d.ts.map +1 -1
- package/dist/components/user-message.js +1 -23
- package/dist/components/user-message.js.map +1 -1
- package/dist/components/vscode-extension-prompt.d.ts +6 -1
- package/dist/components/vscode-extension-prompt.d.ts.map +1 -1
- package/dist/components/vscode-extension-prompt.js +80 -36
- package/dist/components/vscode-extension-prompt.js.map +1 -1
- package/dist/config/copilot-credentials.d.ts +27 -0
- package/dist/config/copilot-credentials.d.ts.map +1 -0
- package/dist/config/copilot-credentials.js +81 -0
- package/dist/config/copilot-credentials.js.map +1 -0
- package/dist/config/index.d.ts +0 -2
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +63 -27
- package/dist/config/index.js.map +1 -1
- package/dist/config/mcp-config-loader.d.ts +2 -3
- package/dist/config/mcp-config-loader.d.ts.map +1 -1
- package/dist/config/mcp-config-loader.js +136 -181
- package/dist/config/mcp-config-loader.js.map +1 -1
- package/dist/config/nanocoder-tools-config.js +2 -2
- package/dist/config/nanocoder-tools-config.js.map +1 -1
- package/dist/config/themes.d.ts.map +1 -1
- package/dist/config/themes.js +9 -766
- package/dist/config/themes.js.map +1 -1
- package/dist/config/validation.d.ts.map +1 -1
- package/dist/config/validation.js +0 -19
- package/dist/config/validation.js.map +1 -1
- package/dist/custom-commands/parser.d.ts.map +1 -1
- package/dist/custom-commands/parser.js +0 -9
- package/dist/custom-commands/parser.js.map +1 -1
- package/dist/hooks/chat-handler/conversation/conversation-loop.d.ts +5 -0
- package/dist/hooks/chat-handler/conversation/conversation-loop.d.ts.map +1 -1
- package/dist/hooks/chat-handler/conversation/conversation-loop.js +78 -97
- package/dist/hooks/chat-handler/conversation/conversation-loop.js.map +1 -1
- package/dist/hooks/chat-handler/conversation/tool-executor.d.ts +7 -2
- package/dist/hooks/chat-handler/conversation/tool-executor.d.ts.map +1 -1
- package/dist/hooks/chat-handler/conversation/tool-executor.js +109 -41
- package/dist/hooks/chat-handler/conversation/tool-executor.js.map +1 -1
- package/dist/hooks/chat-handler/types.d.ts +3 -0
- package/dist/hooks/chat-handler/types.d.ts.map +1 -1
- package/dist/hooks/chat-handler/useChatHandler.d.ts +1 -1
- package/dist/hooks/chat-handler/useChatHandler.d.ts.map +1 -1
- package/dist/hooks/chat-handler/useChatHandler.js +7 -1
- package/dist/hooks/chat-handler/useChatHandler.js.map +1 -1
- package/dist/hooks/useAppHandlers.d.ts +8 -1
- package/dist/hooks/useAppHandlers.d.ts.map +1 -1
- package/dist/hooks/useAppHandlers.js +119 -13
- package/dist/hooks/useAppHandlers.js.map +1 -1
- package/dist/hooks/useAppInitialization.d.ts +5 -3
- package/dist/hooks/useAppInitialization.d.ts.map +1 -1
- package/dist/hooks/useAppInitialization.js +51 -30
- package/dist/hooks/useAppInitialization.js.map +1 -1
- package/dist/hooks/useAppState.d.ts +15 -10
- package/dist/hooks/useAppState.d.ts.map +1 -1
- package/dist/hooks/useAppState.js +37 -28
- package/dist/hooks/useAppState.js.map +1 -1
- package/dist/hooks/useModeHandlers.d.ts +8 -14
- package/dist/hooks/useModeHandlers.d.ts.map +1 -1
- package/dist/hooks/useModeHandlers.js +31 -101
- package/dist/hooks/useModeHandlers.js.map +1 -1
- package/dist/hooks/useNonInteractiveMode.d.ts +7 -0
- package/dist/hooks/useNonInteractiveMode.d.ts.map +1 -1
- package/dist/hooks/useNonInteractiveMode.js +39 -2
- package/dist/hooks/useNonInteractiveMode.js.map +1 -1
- package/dist/hooks/useSessionAutosave.d.ts +16 -0
- package/dist/hooks/useSessionAutosave.d.ts.map +1 -0
- package/dist/hooks/useSessionAutosave.js +133 -0
- package/dist/hooks/useSessionAutosave.js.map +1 -0
- package/dist/hooks/useToolHandler.d.ts +2 -1
- package/dist/hooks/useToolHandler.d.ts.map +1 -1
- package/dist/hooks/useToolHandler.js +9 -3
- package/dist/hooks/useToolHandler.js.map +1 -1
- package/dist/mcp/mcp-client.d.ts.map +1 -1
- package/dist/mcp/mcp-client.js +3 -2
- package/dist/mcp/mcp-client.js.map +1 -1
- package/dist/mcp/transport-factory.d.ts.map +1 -1
- package/dist/mcp/transport-factory.js +4 -36
- package/dist/mcp/transport-factory.js.map +1 -1
- package/dist/models/models-dev-client.d.ts.map +1 -1
- package/dist/models/models-dev-client.js +21 -14
- package/dist/models/models-dev-client.js.map +1 -1
- package/dist/session/session-manager.d.ts +57 -0
- package/dist/session/session-manager.d.ts.map +1 -0
- package/dist/session/session-manager.js +361 -0
- package/dist/session/session-manager.js.map +1 -0
- package/dist/test-utils/render-with-theme.d.ts.map +1 -1
- package/dist/test-utils/render-with-theme.js +2 -1
- package/dist/test-utils/render-with-theme.js.map +1 -1
- package/dist/tool-calling/tool-parser.d.ts +3 -2
- package/dist/tool-calling/tool-parser.d.ts.map +1 -1
- package/dist/tool-calling/tool-parser.js +6 -27
- package/dist/tool-calling/tool-parser.js.map +1 -1
- package/dist/tools/execute-bash.d.ts.map +1 -1
- package/dist/tools/execute-bash.js +5 -0
- package/dist/tools/execute-bash.js.map +1 -1
- package/dist/tools/fetch-url.d.ts.map +1 -1
- package/dist/tools/fetch-url.js +11 -2
- package/dist/tools/fetch-url.js.map +1 -1
- package/dist/tools/file-ops/copy-file.d.ts.map +1 -1
- package/dist/tools/file-ops/copy-file.js +6 -36
- package/dist/tools/file-ops/copy-file.js.map +1 -1
- package/dist/tools/file-ops/create-directory.d.ts.map +1 -1
- package/dist/tools/file-ops/create-directory.js +2 -19
- package/dist/tools/file-ops/create-directory.js.map +1 -1
- package/dist/tools/file-ops/delete-file.d.ts.map +1 -1
- package/dist/tools/file-ops/delete-file.js +6 -20
- package/dist/tools/file-ops/delete-file.js.map +1 -1
- package/dist/tools/file-ops/move-file.d.ts.map +1 -1
- package/dist/tools/file-ops/move-file.js +6 -36
- package/dist/tools/file-ops/move-file.js.map +1 -1
- package/dist/tools/file-ops/string-replace-preview.d.ts +10 -0
- package/dist/tools/file-ops/string-replace-preview.d.ts.map +1 -0
- package/dist/tools/file-ops/string-replace-preview.js +171 -0
- package/dist/tools/file-ops/string-replace-preview.js.map +1 -0
- package/dist/tools/file-ops/string-replace.d.ts.map +1 -1
- package/dist/tools/file-ops/string-replace.js +9 -292
- package/dist/tools/file-ops/string-replace.js.map +1 -1
- package/dist/tools/file-ops/write-file.d.ts.map +1 -1
- package/dist/tools/file-ops/write-file.js +7 -66
- package/dist/tools/file-ops/write-file.js.map +1 -1
- package/dist/tools/find-files.d.ts.map +1 -1
- package/dist/tools/find-files.js +1 -0
- package/dist/tools/find-files.js.map +1 -1
- package/dist/tools/git/git-diff.d.ts.map +1 -1
- package/dist/tools/git/git-diff.js +1 -0
- package/dist/tools/git/git-diff.js.map +1 -1
- package/dist/tools/git/git-log.d.ts.map +1 -1
- package/dist/tools/git/git-log.js +1 -0
- package/dist/tools/git/git-log.js.map +1 -1
- package/dist/tools/git/git-status.d.ts.map +1 -1
- package/dist/tools/git/git-status.js +1 -0
- package/dist/tools/git/git-status.js.map +1 -1
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +7 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/list-directory.d.ts.map +1 -1
- package/dist/tools/list-directory.js +2 -1
- package/dist/tools/list-directory.js.map +1 -1
- package/dist/tools/lsp-get-diagnostics.d.ts.map +1 -1
- package/dist/tools/lsp-get-diagnostics.js +1 -5
- package/dist/tools/lsp-get-diagnostics.js.map +1 -1
- package/dist/tools/read-file.d.ts.map +1 -1
- package/dist/tools/read-file.js +1 -0
- package/dist/tools/read-file.js.map +1 -1
- package/dist/tools/search-file-contents.d.ts.map +1 -1
- package/dist/tools/search-file-contents.js +1 -0
- package/dist/tools/search-file-contents.js.map +1 -1
- package/dist/tools/tasks/list-tasks.d.ts.map +1 -1
- package/dist/tools/tasks/list-tasks.js +1 -0
- package/dist/tools/tasks/list-tasks.js.map +1 -1
- package/dist/tools/tool-manager.d.ts +10 -0
- package/dist/tools/tool-manager.d.ts.map +1 -1
- package/dist/tools/tool-manager.js +16 -2
- package/dist/tools/tool-manager.js.map +1 -1
- package/dist/tools/tool-registry.d.ts +9 -1
- package/dist/tools/tool-registry.d.ts.map +1 -1
- package/dist/tools/tool-registry.js +17 -1
- package/dist/tools/tool-registry.js.map +1 -1
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +1 -0
- package/dist/tools/web-search.js.map +1 -1
- package/dist/types/app.d.ts +3 -0
- package/dist/types/app.d.ts.map +1 -1
- package/dist/types/commands.d.ts +1 -2
- package/dist/types/commands.d.ts.map +1 -1
- package/dist/types/config.d.ts +11 -15
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/core.d.ts +13 -3
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/core.js.map +1 -1
- package/dist/types/markdown-parser.d.ts +2 -10
- package/dist/types/markdown-parser.d.ts.map +1 -1
- package/dist/types/mcp.d.ts +2 -28
- package/dist/types/mcp.d.ts.map +1 -1
- package/dist/types/ui.d.ts +1 -1
- package/dist/types/ui.d.ts.map +1 -1
- package/dist/utils/ansi-truncate.d.ts +6 -0
- package/dist/utils/ansi-truncate.d.ts.map +1 -0
- package/dist/utils/ansi-truncate.js +39 -0
- package/dist/utils/ansi-truncate.js.map +1 -0
- package/dist/utils/installation-detector.d.ts +6 -0
- package/dist/utils/installation-detector.d.ts.map +1 -1
- package/dist/utils/installation-detector.js +33 -19
- package/dist/utils/installation-detector.js.map +1 -1
- package/dist/utils/logging/health-monitor/checks/memory-check.d.ts.map +1 -1
- package/dist/utils/logging/health-monitor/checks/memory-check.js +2 -1
- package/dist/utils/logging/health-monitor/checks/memory-check.js.map +1 -1
- package/dist/utils/logging/health-monitor/core/health-monitor.d.ts.map +1 -1
- package/dist/utils/logging/health-monitor/core/health-monitor.js +3 -2
- package/dist/utils/logging/health-monitor/core/health-monitor.js.map +1 -1
- package/dist/utils/logging/performance.d.ts.map +1 -1
- package/dist/utils/logging/performance.js +21 -17
- package/dist/utils/logging/performance.js.map +1 -1
- package/dist/utils/logging/pino-logger.d.ts.map +1 -1
- package/dist/utils/logging/pino-logger.js +7 -8
- package/dist/utils/logging/pino-logger.js.map +1 -1
- package/dist/utils/logging/redaction.d.ts.map +1 -1
- package/dist/utils/logging/redaction.js +2 -0
- package/dist/utils/logging/redaction.js.map +1 -1
- package/dist/utils/logging/request-tracker.d.ts.map +1 -1
- package/dist/utils/logging/request-tracker.js +6 -5
- package/dist/utils/logging/request-tracker.js.map +1 -1
- package/dist/utils/logging/safe-process.d.ts +16 -0
- package/dist/utils/logging/safe-process.d.ts.map +1 -0
- package/dist/utils/logging/safe-process.js +37 -0
- package/dist/utils/logging/safe-process.js.map +1 -0
- package/dist/utils/logging/types.d.ts +0 -3
- package/dist/utils/logging/types.d.ts.map +1 -1
- package/dist/utils/message-builder.d.ts +0 -5
- package/dist/utils/message-builder.d.ts.map +1 -1
- package/dist/utils/message-builder.js +0 -8
- package/dist/utils/message-builder.js.map +1 -1
- package/dist/utils/path-validation.d.ts.map +1 -1
- package/dist/utils/path-validation.js +3 -1
- package/dist/utils/path-validation.js.map +1 -1
- package/dist/utils/path-validators.d.ts +16 -0
- package/dist/utils/path-validators.d.ts.map +1 -0
- package/dist/utils/path-validators.js +55 -0
- package/dist/utils/path-validators.js.map +1 -0
- package/dist/utils/response-formatter.d.ts.map +1 -1
- package/dist/utils/response-formatter.js +2 -17
- package/dist/utils/response-formatter.js.map +1 -1
- package/dist/utils/text-wrapping.d.ts +8 -0
- package/dist/utils/text-wrapping.d.ts.map +1 -0
- package/dist/utils/text-wrapping.js +29 -0
- package/dist/utils/text-wrapping.js.map +1 -0
- package/dist/utils/tool-approval.d.ts +6 -0
- package/dist/utils/tool-approval.d.ts.map +1 -0
- package/dist/utils/tool-approval.js +15 -0
- package/dist/utils/tool-approval.js.map +1 -0
- package/dist/utils/tool-result-display.d.ts +15 -1
- package/dist/utils/tool-result-display.d.ts.map +1 -1
- package/dist/utils/tool-result-display.js +93 -3
- package/dist/utils/tool-result-display.js.map +1 -1
- package/dist/vscode/extension-installer.d.ts +34 -7
- package/dist/vscode/extension-installer.d.ts.map +1 -1
- package/dist/vscode/extension-installer.js +151 -64
- package/dist/vscode/extension-installer.js.map +1 -1
- package/dist/vscode/index.d.ts +1 -1
- package/dist/vscode/index.d.ts.map +1 -1
- package/dist/vscode/index.js +1 -1
- package/dist/vscode/index.js.map +1 -1
- package/dist/wizards/mcp-wizard.d.ts.map +1 -1
- package/dist/wizards/mcp-wizard.js +2 -1
- package/dist/wizards/mcp-wizard.js.map +1 -1
- package/dist/wizards/provider-wizard.d.ts.map +1 -1
- package/dist/wizards/provider-wizard.js +4 -2
- package/dist/wizards/provider-wizard.js.map +1 -1
- package/dist/wizards/steps/location-step.d.ts.map +1 -1
- package/dist/wizards/steps/location-step.js +2 -1
- package/dist/wizards/steps/location-step.js.map +1 -1
- package/dist/wizards/steps/mcp-step.d.ts.map +1 -1
- package/dist/wizards/steps/mcp-step.js +2 -1
- package/dist/wizards/steps/mcp-step.js.map +1 -1
- package/dist/wizards/steps/provider-step.d.ts.map +1 -1
- package/dist/wizards/steps/provider-step.js +4 -1
- package/dist/wizards/steps/provider-step.js.map +1 -1
- package/dist/wizards/steps/summary-step.d.ts.map +1 -1
- package/dist/wizards/steps/summary-step.js +2 -1
- package/dist/wizards/steps/summary-step.js.map +1 -1
- package/dist/wizards/templates/mcp-templates.d.ts +0 -8
- package/dist/wizards/templates/mcp-templates.d.ts.map +1 -1
- package/dist/wizards/templates/mcp-templates.js.map +1 -1
- package/dist/wizards/templates/provider-templates.d.ts.map +1 -1
- package/dist/wizards/templates/provider-templates.js +59 -0
- package/dist/wizards/templates/provider-templates.js.map +1 -1
- package/dist/wizards/validation.d.ts.map +1 -1
- package/dist/wizards/validation.js +0 -1
- package/dist/wizards/validation.js.map +1 -1
- package/package.json +20 -12
- package/source/config/themes.json +787 -0
- package/dist/ai-sdk-client/chat/tool-processor.d.ts +0 -10
- package/dist/ai-sdk-client/chat/tool-processor.d.ts.map +0 -1
- package/dist/ai-sdk-client/chat/tool-processor.js +0 -58
- package/dist/ai-sdk-client/chat/tool-processor.js.map +0 -1
- package/dist/tool-calling/json-parser.d.ts +0 -28
- package/dist/tool-calling/json-parser.d.ts.map +0 -1
- package/dist/tool-calling/json-parser.js +0 -219
- package/dist/tool-calling/json-parser.js.map +0 -1
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
1
|
import React from 'react';
|
|
4
2
|
import { parseInput } from '../../command-parser.js';
|
|
5
3
|
import { commandRegistry } from '../../commands.js';
|
|
4
|
+
import { CopilotLogin } from '../../commands/copilot-login.js';
|
|
6
5
|
import BashProgress from '../../components/bash-progress.js';
|
|
7
6
|
import { ErrorMessage, InfoMessage, SuccessMessage, } from '../../components/message-box.js';
|
|
8
7
|
import { DELAY_COMMAND_COMPLETE_MS } from '../../constants.js';
|
|
9
|
-
import { getModelContextLimit, getSessionContextLimit, resetSessionContextLimit, setSessionContextLimit, } from '../../models/index.js';
|
|
10
8
|
import { CheckpointManager } from '../../services/checkpoint-manager.js';
|
|
11
|
-
import { createTokenizer } from '../../tokenization/index.js';
|
|
12
9
|
import { executeBashCommand, formatBashResultForLLM } from '../../tools/execute-bash.js';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
10
|
+
import { handleCompactCommand } from './handlers/compact-handler.js';
|
|
11
|
+
import { handleContextMaxCommand } from './handlers/context-max-handler.js';
|
|
12
|
+
import { handleCommandCreate, handleScheduleCreate, handleScheduleStart, } from './handlers/create-handler.js';
|
|
13
|
+
import { handleResumeCommand } from './handlers/session-handler.js';
|
|
14
|
+
// Re-export for consumers that import parseContextLimit from here
|
|
15
|
+
export { parseContextLimit } from './handlers/context-max-handler.js';
|
|
17
16
|
/** Command names that require special handling in the app */
|
|
18
17
|
const SPECIAL_COMMANDS = {
|
|
19
18
|
CLEAR: 'clear',
|
|
@@ -27,8 +26,6 @@ const SPECIAL_COMMANDS = {
|
|
|
27
26
|
CHECKPOINT: 'checkpoint',
|
|
28
27
|
EXPLORER: 'explorer',
|
|
29
28
|
IDE: 'ide',
|
|
30
|
-
SCHEDULE: 'schedule',
|
|
31
|
-
COMMANDS: 'commands',
|
|
32
29
|
};
|
|
33
30
|
/** Checkpoint subcommands */
|
|
34
31
|
const CHECKPOINT_SUBCOMMANDS = {
|
|
@@ -43,25 +40,19 @@ function getErrorMessage(error, fallback = 'Unknown error') {
|
|
|
43
40
|
}
|
|
44
41
|
/**
|
|
45
42
|
* Handles bash commands prefixed with !
|
|
46
|
-
* Uses the unified bash executor service for real-time progress updates
|
|
47
43
|
*/
|
|
48
44
|
async function handleBashCommand(bashCommand, options) {
|
|
49
45
|
const { onAddToChatQueue, setLiveComponent, setIsToolExecuting, onCommandComplete, getNextComponentKey, setMessages, messages, } = options;
|
|
50
|
-
// Block user input while executing
|
|
51
46
|
setIsToolExecuting(true);
|
|
52
47
|
try {
|
|
53
|
-
// Start execution and get the execution ID
|
|
54
48
|
const { executionId, promise } = executeBashCommand(bashCommand);
|
|
55
|
-
// Set as live component for real-time updates (renders outside Static)
|
|
56
49
|
setLiveComponent(React.createElement(BashProgress, {
|
|
57
50
|
key: `bash-progress-live-${getNextComponentKey()}`,
|
|
58
51
|
executionId,
|
|
59
52
|
command: bashCommand,
|
|
60
53
|
isLive: true,
|
|
61
54
|
}));
|
|
62
|
-
// Wait for execution to complete
|
|
63
55
|
const result = await promise;
|
|
64
|
-
// Clear live component and add static completed version to chat queue
|
|
65
56
|
setLiveComponent(null);
|
|
66
57
|
onAddToChatQueue(React.createElement(BashProgress, {
|
|
67
58
|
key: `bash-progress-complete-${getNextComponentKey()}`,
|
|
@@ -69,9 +60,7 @@ async function handleBashCommand(bashCommand, options) {
|
|
|
69
60
|
command: bashCommand,
|
|
70
61
|
completedState: result,
|
|
71
62
|
}));
|
|
72
|
-
// Format result for LLM context
|
|
73
63
|
const llmContext = formatBashResultForLLM(result);
|
|
74
|
-
// Add the output to the LLM context for future interactions
|
|
75
64
|
if (llmContext) {
|
|
76
65
|
const userMessage = {
|
|
77
66
|
role: 'user',
|
|
@@ -81,24 +70,20 @@ async function handleBashCommand(bashCommand, options) {
|
|
|
81
70
|
}
|
|
82
71
|
}
|
|
83
72
|
catch (error) {
|
|
84
|
-
// Clear live component on error
|
|
85
73
|
setLiveComponent(null);
|
|
86
|
-
// Show error message if command fails
|
|
87
74
|
onAddToChatQueue(React.createElement(ErrorMessage, {
|
|
88
75
|
key: `bash-error-${getNextComponentKey()}`,
|
|
89
76
|
message: `Error executing command: ${getErrorMessage(error, String(error))}`,
|
|
90
77
|
}));
|
|
91
78
|
}
|
|
92
79
|
finally {
|
|
93
|
-
// Re-enable user input
|
|
94
80
|
setIsToolExecuting(false);
|
|
95
|
-
// Signal completion for non-interactive mode
|
|
96
81
|
onCommandComplete?.();
|
|
97
82
|
}
|
|
98
83
|
}
|
|
99
84
|
/**
|
|
100
|
-
* Handles custom user-defined commands
|
|
101
|
-
* Returns true if a custom command was found and handled
|
|
85
|
+
* Handles custom user-defined commands.
|
|
86
|
+
* Returns true if a custom command was found and handled.
|
|
102
87
|
*/
|
|
103
88
|
async function handleCustomCommand(message, commandName, options) {
|
|
104
89
|
const { customCommandCache, customCommandLoader, customCommandExecutor, onHandleChatMessage, onCommandComplete, } = options;
|
|
@@ -107,40 +92,34 @@ async function handleCustomCommand(message, commandName, options) {
|
|
|
107
92
|
if (!customCommand) {
|
|
108
93
|
return false;
|
|
109
94
|
}
|
|
110
|
-
// Execute custom command with any arguments
|
|
111
|
-
// Slice past '/' + commandName + space to get the arguments
|
|
112
95
|
const args = message
|
|
113
96
|
.slice(commandName.length + 2)
|
|
114
97
|
.trim()
|
|
115
98
|
.split(/\s+/)
|
|
116
99
|
.filter(arg => arg);
|
|
117
100
|
const processedPrompt = customCommandExecutor?.execute(customCommand, args);
|
|
118
|
-
// Send the processed prompt to the AI
|
|
119
101
|
if (processedPrompt) {
|
|
120
102
|
await onHandleChatMessage(processedPrompt);
|
|
121
103
|
}
|
|
122
104
|
else {
|
|
123
|
-
// Custom command didn't generate a prompt, signal completion
|
|
124
105
|
onCommandComplete?.();
|
|
125
106
|
}
|
|
126
107
|
return true;
|
|
127
108
|
}
|
|
128
109
|
/**
|
|
129
110
|
* Handles special commands that need app state access (/clear, /model, etc.)
|
|
130
|
-
* Returns true if a special command was handled
|
|
111
|
+
* Returns true if a special command was handled.
|
|
131
112
|
*/
|
|
132
113
|
async function handleSpecialCommand(commandName, options) {
|
|
133
114
|
const { onClearMessages, onEnterModelSelectionMode, onEnterProviderSelectionMode, onEnterModelDatabaseMode, onEnterConfigWizardMode, onEnterSettingsMode, onEnterMcpWizardMode, onEnterExplorerMode, onShowStatus, onCommandComplete, onAddToChatQueue, getNextComponentKey, } = options;
|
|
134
115
|
switch (commandName) {
|
|
135
116
|
case SPECIAL_COMMANDS.CLEAR:
|
|
136
117
|
await onClearMessages();
|
|
137
|
-
// Show success message
|
|
138
118
|
onAddToChatQueue(React.createElement(SuccessMessage, {
|
|
139
119
|
key: `clear-success-${getNextComponentKey()}`,
|
|
140
120
|
message: 'Chat cleared.',
|
|
141
121
|
hideBox: true,
|
|
142
122
|
}));
|
|
143
|
-
// Give React time to render before signaling completion
|
|
144
123
|
setTimeout(() => onCommandComplete?.(), DELAY_COMMAND_COMPLETE_MS);
|
|
145
124
|
return true;
|
|
146
125
|
case SPECIAL_COMMANDS.MODEL:
|
|
@@ -169,7 +148,6 @@ async function handleSpecialCommand(commandName, options) {
|
|
|
169
148
|
return true;
|
|
170
149
|
case SPECIAL_COMMANDS.STATUS:
|
|
171
150
|
onShowStatus();
|
|
172
|
-
// Status adds to queue synchronously, give React time to render
|
|
173
151
|
setTimeout(() => onCommandComplete?.(), DELAY_COMMAND_COMPLETE_MS);
|
|
174
152
|
return true;
|
|
175
153
|
case SPECIAL_COMMANDS.EXPLORER:
|
|
@@ -185,402 +163,11 @@ async function handleSpecialCommand(commandName, options) {
|
|
|
185
163
|
}
|
|
186
164
|
}
|
|
187
165
|
/**
|
|
188
|
-
* Handles
|
|
189
|
-
*
|
|
190
|
-
* Returns true if handled.
|
|
191
|
-
*/
|
|
192
|
-
async function handleScheduleStart(commandParts, options) {
|
|
193
|
-
if (commandParts[0] !== SPECIAL_COMMANDS.SCHEDULE ||
|
|
194
|
-
commandParts[1] !== 'start') {
|
|
195
|
-
return false;
|
|
196
|
-
}
|
|
197
|
-
const { onEnterSchedulerMode, onCommandComplete } = options;
|
|
198
|
-
if (onEnterSchedulerMode) {
|
|
199
|
-
onEnterSchedulerMode();
|
|
200
|
-
onCommandComplete?.();
|
|
201
|
-
}
|
|
202
|
-
else {
|
|
203
|
-
options.onAddToChatQueue(React.createElement(ErrorMessage, {
|
|
204
|
-
key: `schedule-error-${options.getNextComponentKey()}`,
|
|
205
|
-
message: 'Scheduler mode is not available.',
|
|
206
|
-
}));
|
|
207
|
-
onCommandComplete?.();
|
|
208
|
-
}
|
|
209
|
-
return true;
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* Handles /schedule create — creates the schedule file and prompts the AI to help write it.
|
|
213
|
-
* Returns true if handled.
|
|
214
|
-
*/
|
|
215
|
-
async function handleScheduleCreate(commandParts, options) {
|
|
216
|
-
if (commandParts[0] !== SPECIAL_COMMANDS.SCHEDULE ||
|
|
217
|
-
commandParts[1] !== 'create') {
|
|
218
|
-
return false;
|
|
219
|
-
}
|
|
220
|
-
const { onAddToChatQueue, onHandleChatMessage, onCommandComplete, getNextComponentKey, } = options;
|
|
221
|
-
const fileName = commandParts[2];
|
|
222
|
-
if (!fileName) {
|
|
223
|
-
onAddToChatQueue(React.createElement(ErrorMessage, {
|
|
224
|
-
key: `schedule-create-error-${getNextComponentKey()}`,
|
|
225
|
-
message: 'Usage: /schedule create <name>\nExample: /schedule create deps-update',
|
|
226
|
-
}));
|
|
227
|
-
onCommandComplete?.();
|
|
228
|
-
return true;
|
|
229
|
-
}
|
|
230
|
-
const safeName = fileName.endsWith('.md') ? fileName : `${fileName}.md`;
|
|
231
|
-
const schedulesDir = join(process.cwd(), '.nanocoder', 'schedules');
|
|
232
|
-
const filePath = join(schedulesDir, safeName);
|
|
233
|
-
if (existsSync(filePath)) {
|
|
234
|
-
onAddToChatQueue(React.createElement(ErrorMessage, {
|
|
235
|
-
key: `schedule-create-exists-${getNextComponentKey()}`,
|
|
236
|
-
message: `Schedule file already exists: .nanocoder/schedules/${safeName}`,
|
|
237
|
-
}));
|
|
238
|
-
onCommandComplete?.();
|
|
239
|
-
return true;
|
|
240
|
-
}
|
|
241
|
-
mkdirSync(schedulesDir, { recursive: true });
|
|
242
|
-
const template = `---
|
|
243
|
-
description: ${safeName.replace(/\.md$/, '')} scheduled command
|
|
244
|
-
---
|
|
245
|
-
|
|
246
|
-
`;
|
|
247
|
-
writeFileSync(filePath, template, 'utf-8');
|
|
248
|
-
onAddToChatQueue(React.createElement(SuccessMessage, {
|
|
249
|
-
key: `schedule-created-${getNextComponentKey()}`,
|
|
250
|
-
message: `Created schedule file: .nanocoder/schedules/${safeName}`,
|
|
251
|
-
hideBox: true,
|
|
252
|
-
}));
|
|
253
|
-
// Ask the AI to help write the schedule command content
|
|
254
|
-
await onHandleChatMessage(`I just created a new schedule command file at .nanocoder/schedules/${safeName}. Help me write the content for this scheduled task. Ask me what I want this scheduled job to do, then write the markdown prompt into the file using the write_file tool. The file should contain a clear prompt that instructs the AI agent what to do when this schedule runs. Keep the YAML frontmatter at the top with the description field.`);
|
|
255
|
-
return true;
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* Handles /commands create — creates the command file and prompts the AI to help write it.
|
|
259
|
-
* Returns true if handled.
|
|
260
|
-
*/
|
|
261
|
-
async function handleCommandCreate(commandParts, options) {
|
|
262
|
-
if ((commandParts[0] !== SPECIAL_COMMANDS.COMMANDS &&
|
|
263
|
-
commandParts[0] !== 'custom-commands') ||
|
|
264
|
-
commandParts[1] !== 'create') {
|
|
265
|
-
return false;
|
|
266
|
-
}
|
|
267
|
-
const { onAddToChatQueue, onHandleChatMessage, onCommandComplete, getNextComponentKey, } = options;
|
|
268
|
-
const fileName = commandParts[2];
|
|
269
|
-
if (!fileName) {
|
|
270
|
-
onAddToChatQueue(React.createElement(ErrorMessage, {
|
|
271
|
-
key: `commands-create-error-${getNextComponentKey()}`,
|
|
272
|
-
message: 'Usage: /commands create <name>\nExample: /commands create review-code',
|
|
273
|
-
}));
|
|
274
|
-
onCommandComplete?.();
|
|
275
|
-
return true;
|
|
276
|
-
}
|
|
277
|
-
const safeName = fileName.endsWith('.md') ? fileName : `${fileName}.md`;
|
|
278
|
-
const commandsDir = join(process.cwd(), '.nanocoder', 'commands');
|
|
279
|
-
const filePath = join(commandsDir, safeName);
|
|
280
|
-
if (existsSync(filePath)) {
|
|
281
|
-
onAddToChatQueue(React.createElement(ErrorMessage, {
|
|
282
|
-
key: `commands-create-exists-${getNextComponentKey()}`,
|
|
283
|
-
message: `Command file already exists: .nanocoder/commands/${safeName}`,
|
|
284
|
-
}));
|
|
285
|
-
onCommandComplete?.();
|
|
286
|
-
return true;
|
|
287
|
-
}
|
|
288
|
-
mkdirSync(commandsDir, { recursive: true });
|
|
289
|
-
const template = `---
|
|
290
|
-
description: ${safeName.replace(/\.md$/, '')} custom command
|
|
291
|
-
---
|
|
292
|
-
|
|
293
|
-
`;
|
|
294
|
-
writeFileSync(filePath, template, 'utf-8');
|
|
295
|
-
onAddToChatQueue(React.createElement(SuccessMessage, {
|
|
296
|
-
key: `commands-created-${getNextComponentKey()}`,
|
|
297
|
-
message: `Created command file: .nanocoder/commands/${safeName}`,
|
|
298
|
-
hideBox: true,
|
|
299
|
-
}));
|
|
300
|
-
// Ask the AI to help write the custom command content
|
|
301
|
-
const commandBaseName = safeName.replace(/\.md$/, '');
|
|
302
|
-
await onHandleChatMessage(`I just created a new custom command file at .nanocoder/commands/${safeName}. Help me write the content for this command. Ask me what I want this command to do, then write the markdown prompt into the file using the write_file tool. The file should contain a clear prompt that instructs the AI what to do when this command is invoked via /${commandBaseName}. Keep the YAML frontmatter at the top.
|
|
303
|
-
|
|
304
|
-
Here is an example of the frontmatter format with all available fields:
|
|
305
|
-
|
|
306
|
-
---
|
|
307
|
-
description: Generate unit tests for a file
|
|
308
|
-
aliases: [test, unittest]
|
|
309
|
-
parameters: [filename]
|
|
310
|
-
tags: [testing, quality]
|
|
311
|
-
triggers: [write tests, unit test]
|
|
312
|
-
estimated-tokens: 2000
|
|
313
|
-
resources: true
|
|
314
|
-
category: testing
|
|
315
|
-
version: 1.0.0
|
|
316
|
-
author: user
|
|
317
|
-
examples:
|
|
318
|
-
- /gen-tests src/utils.ts
|
|
319
|
-
- /gen-tests lib/parser.ts
|
|
320
|
-
references: [docs/testing-guide.md]
|
|
321
|
-
dependencies: [lint]
|
|
322
|
-
---
|
|
323
|
-
Generate comprehensive unit tests for {{filename}}...
|
|
324
|
-
|
|
325
|
-
All fields are optional except description. Use whichever fields are appropriate for the user's needs. Parameters defined here can be used as {{param}} placeholders in the prompt body.`);
|
|
326
|
-
return true;
|
|
327
|
-
}
|
|
328
|
-
// Handles compact command, Returns true if compact command was handled
|
|
329
|
-
async function handleCompactCommand(commandParts, options) {
|
|
330
|
-
const { onAddToChatQueue, onCommandComplete, getNextComponentKey, messages, setMessages, provider, model, } = options;
|
|
331
|
-
// Check if this is a compact command
|
|
332
|
-
if (commandParts[0] !== 'compact') {
|
|
333
|
-
return false;
|
|
334
|
-
}
|
|
335
|
-
// Parse arguments
|
|
336
|
-
const args = commandParts.slice(1);
|
|
337
|
-
let mode = 'default';
|
|
338
|
-
let preview = false;
|
|
339
|
-
for (let i = 0; i < args.length; i++) {
|
|
340
|
-
const arg = args[i];
|
|
341
|
-
if (arg === '--aggressive') {
|
|
342
|
-
mode = 'aggressive';
|
|
343
|
-
}
|
|
344
|
-
else if (arg === '--conservative') {
|
|
345
|
-
mode = 'conservative';
|
|
346
|
-
}
|
|
347
|
-
else if (arg === '--preview') {
|
|
348
|
-
preview = true;
|
|
349
|
-
}
|
|
350
|
-
else if (arg === '--default') {
|
|
351
|
-
mode = 'default';
|
|
352
|
-
}
|
|
353
|
-
else if (arg === '--restore') {
|
|
354
|
-
// Restore messages from backup
|
|
355
|
-
const restored = compressionBackup.restore();
|
|
356
|
-
if (restored) {
|
|
357
|
-
setMessages(restored);
|
|
358
|
-
onAddToChatQueue(React.createElement(SuccessMessage, {
|
|
359
|
-
key: `compact-restore-${getNextComponentKey()}`,
|
|
360
|
-
message: `Restored ${restored.length} messages from backup.`,
|
|
361
|
-
hideBox: true,
|
|
362
|
-
}));
|
|
363
|
-
compressionBackup.clearBackup();
|
|
364
|
-
}
|
|
365
|
-
else {
|
|
366
|
-
onAddToChatQueue(React.createElement(ErrorMessage, {
|
|
367
|
-
key: `compact-restore-error-${getNextComponentKey()}`,
|
|
368
|
-
message: 'No backup available to restore.',
|
|
369
|
-
hideBox: true,
|
|
370
|
-
}));
|
|
371
|
-
}
|
|
372
|
-
setTimeout(() => onCommandComplete?.(), DELAY_COMMAND_COMPLETE_MS);
|
|
373
|
-
return true;
|
|
374
|
-
}
|
|
375
|
-
else if (arg === '--auto-on') {
|
|
376
|
-
// Enable auto-compact for current session
|
|
377
|
-
setAutoCompactEnabled(true);
|
|
378
|
-
onAddToChatQueue(React.createElement(SuccessMessage, {
|
|
379
|
-
key: `compact-auto-on-${getNextComponentKey()}`,
|
|
380
|
-
message: 'Auto-compact enabled for this session.',
|
|
381
|
-
hideBox: true,
|
|
382
|
-
}));
|
|
383
|
-
setTimeout(() => onCommandComplete?.(), DELAY_COMMAND_COMPLETE_MS);
|
|
384
|
-
return true;
|
|
385
|
-
}
|
|
386
|
-
else if (arg === '--auto-off') {
|
|
387
|
-
// Disable auto compact for current session
|
|
388
|
-
setAutoCompactEnabled(false);
|
|
389
|
-
onAddToChatQueue(React.createElement(SuccessMessage, {
|
|
390
|
-
key: `compact-auto-off-${getNextComponentKey()}`,
|
|
391
|
-
message: 'Auto-compact disabled for this session.',
|
|
392
|
-
hideBox: true,
|
|
393
|
-
}));
|
|
394
|
-
setTimeout(() => onCommandComplete?.(), DELAY_COMMAND_COMPLETE_MS);
|
|
395
|
-
return true;
|
|
396
|
-
}
|
|
397
|
-
else if (arg === '--threshold' && i + 1 < args.length) {
|
|
398
|
-
// Set threshold for current session
|
|
399
|
-
const thresholdValue = Number.parseFloat(args[i + 1]);
|
|
400
|
-
if (Number.isNaN(thresholdValue) ||
|
|
401
|
-
thresholdValue < 50 ||
|
|
402
|
-
thresholdValue > 95) {
|
|
403
|
-
onAddToChatQueue(React.createElement(ErrorMessage, {
|
|
404
|
-
key: `compact-threshold-error-${getNextComponentKey()}`,
|
|
405
|
-
message: 'Threshold must be a number between 50 and 95.',
|
|
406
|
-
hideBox: true,
|
|
407
|
-
}));
|
|
408
|
-
setTimeout(() => onCommandComplete?.(), DELAY_COMMAND_COMPLETE_MS);
|
|
409
|
-
return true;
|
|
410
|
-
}
|
|
411
|
-
setAutoCompactThreshold(Math.round(thresholdValue));
|
|
412
|
-
onAddToChatQueue(React.createElement(SuccessMessage, {
|
|
413
|
-
key: `compact-threshold-${getNextComponentKey()}`,
|
|
414
|
-
message: `Auto-compact threshold set to ${Math.round(thresholdValue)}% for this session.`,
|
|
415
|
-
hideBox: true,
|
|
416
|
-
}));
|
|
417
|
-
setTimeout(() => onCommandComplete?.(), DELAY_COMMAND_COMPLETE_MS);
|
|
418
|
-
return true;
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
try {
|
|
422
|
-
if (messages.length === 0) {
|
|
423
|
-
onAddToChatQueue(React.createElement(InfoMessage, {
|
|
424
|
-
key: `compact-info-${getNextComponentKey()}`,
|
|
425
|
-
message: 'No messages to compact.',
|
|
426
|
-
hideBox: true,
|
|
427
|
-
}));
|
|
428
|
-
onCommandComplete?.();
|
|
429
|
-
return true;
|
|
430
|
-
}
|
|
431
|
-
// Create tokenizer
|
|
432
|
-
const tokenizer = createTokenizer(provider, model);
|
|
433
|
-
// Include system message in token calculations for consistency with /status and auto-compact
|
|
434
|
-
const systemPrompt = processPromptTemplate();
|
|
435
|
-
const systemMessage = { role: 'system', content: systemPrompt };
|
|
436
|
-
const allMessages = [systemMessage, ...messages];
|
|
437
|
-
// Perform compression (includes system message for accurate token counting)
|
|
438
|
-
const result = compressMessages(allMessages, tokenizer, { mode });
|
|
439
|
-
// Clean up tokenizer
|
|
440
|
-
if (tokenizer.free) {
|
|
441
|
-
tokenizer.free();
|
|
442
|
-
}
|
|
443
|
-
if (preview) {
|
|
444
|
-
// Preview mode: show what would be compressed without applying
|
|
445
|
-
const message = `Preview: Context would be compacted: ${result.originalTokenCount.toLocaleString()} tokens → ${result.compressedTokenCount.toLocaleString()} tokens (${Math.round(result.reductionPercentage)}% reduction)\n\nPreserved:\n• ${result.preservedInfo.keyDecisions} key decisions\n• ${result.preservedInfo.fileModifications} file modifications\n• ${result.preservedInfo.toolResults} tool results\n• ${result.preservedInfo.recentMessages} recent messages at full detail`;
|
|
446
|
-
onAddToChatQueue(React.createElement(InfoMessage, {
|
|
447
|
-
key: `compact-preview-${getNextComponentKey()}`,
|
|
448
|
-
message,
|
|
449
|
-
hideBox: false,
|
|
450
|
-
}));
|
|
451
|
-
}
|
|
452
|
-
else {
|
|
453
|
-
// Apply compression and store backup before compression
|
|
454
|
-
compressionBackup.storeBackup(messages);
|
|
455
|
-
// Filter out system messages from compressed result (they're managed separately)
|
|
456
|
-
const compressedUserMessages = result.compressedMessages.filter(msg => msg.role !== 'system');
|
|
457
|
-
setMessages(compressedUserMessages);
|
|
458
|
-
// Show success message
|
|
459
|
-
const message = `Context Compacted: ${result.originalTokenCount.toLocaleString()} tokens → ${result.compressedTokenCount.toLocaleString()} tokens (${Math.round(result.reductionPercentage)}% reduction)\n\nPreserved:\n• ${result.preservedInfo.keyDecisions} key decisions\n• ${result.preservedInfo.fileModifications} file modifications\n• ${result.preservedInfo.toolResults} tool results\n• ${result.preservedInfo.recentMessages} recent messages at full detail`;
|
|
460
|
-
onAddToChatQueue(React.createElement(SuccessMessage, {
|
|
461
|
-
key: `compact-success-${getNextComponentKey()}`,
|
|
462
|
-
message,
|
|
463
|
-
hideBox: false,
|
|
464
|
-
}));
|
|
465
|
-
}
|
|
466
|
-
setTimeout(() => onCommandComplete?.(), DELAY_COMMAND_COMPLETE_MS);
|
|
467
|
-
return true;
|
|
468
|
-
}
|
|
469
|
-
catch (error) {
|
|
470
|
-
onAddToChatQueue(React.createElement(ErrorMessage, {
|
|
471
|
-
key: `compact-error-${getNextComponentKey()}`,
|
|
472
|
-
message: `Failed to compact messages: ${getErrorMessage(error)}`,
|
|
473
|
-
hideBox: true,
|
|
474
|
-
}));
|
|
475
|
-
onCommandComplete?.();
|
|
476
|
-
return true;
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
/**
|
|
480
|
-
* Parses a context limit value string, supporting k/K suffix.
|
|
481
|
-
* e.g. "8192" -> 8192, "128k" -> 128000, "128K" -> 128000
|
|
482
|
-
*/
|
|
483
|
-
export function parseContextLimit(value) {
|
|
484
|
-
const trimmed = value.trim().toLowerCase();
|
|
485
|
-
let multiplier = 1;
|
|
486
|
-
let numStr = trimmed;
|
|
487
|
-
if (trimmed.endsWith('k')) {
|
|
488
|
-
multiplier = 1000;
|
|
489
|
-
numStr = trimmed.slice(0, -1);
|
|
490
|
-
}
|
|
491
|
-
const parsed = Number.parseFloat(numStr);
|
|
492
|
-
if (Number.isNaN(parsed) || parsed <= 0) {
|
|
493
|
-
return null;
|
|
494
|
-
}
|
|
495
|
-
return Math.round(parsed * multiplier);
|
|
496
|
-
}
|
|
497
|
-
// Handles /context-max command. Returns true if handled.
|
|
498
|
-
async function handleContextMaxCommand(commandParts, options) {
|
|
499
|
-
const { onAddToChatQueue, onCommandComplete, getNextComponentKey, model } = options;
|
|
500
|
-
if (commandParts[0] !== 'context-max') {
|
|
501
|
-
return false;
|
|
502
|
-
}
|
|
503
|
-
const args = commandParts.slice(1);
|
|
504
|
-
// /context-max --reset — clear session override
|
|
505
|
-
if (args[0] === '--reset') {
|
|
506
|
-
resetSessionContextLimit();
|
|
507
|
-
onAddToChatQueue(React.createElement(SuccessMessage, {
|
|
508
|
-
key: `context-max-reset-${getNextComponentKey()}`,
|
|
509
|
-
message: 'Session context limit override cleared.',
|
|
510
|
-
hideBox: true,
|
|
511
|
-
}));
|
|
512
|
-
setTimeout(() => onCommandComplete?.(), DELAY_COMMAND_COMPLETE_MS);
|
|
513
|
-
return true;
|
|
514
|
-
}
|
|
515
|
-
// /context-max <number> — set session context limit
|
|
516
|
-
if (args.length > 0) {
|
|
517
|
-
const limit = parseContextLimit(args[0]);
|
|
518
|
-
if (limit === null) {
|
|
519
|
-
onAddToChatQueue(React.createElement(ErrorMessage, {
|
|
520
|
-
key: `context-max-error-${getNextComponentKey()}`,
|
|
521
|
-
message: 'Invalid context limit. Use a positive number, e.g. /context-max 8192 or /context-max 128k',
|
|
522
|
-
}));
|
|
523
|
-
setTimeout(() => onCommandComplete?.(), DELAY_COMMAND_COMPLETE_MS);
|
|
524
|
-
return true;
|
|
525
|
-
}
|
|
526
|
-
setSessionContextLimit(limit);
|
|
527
|
-
onAddToChatQueue(React.createElement(SuccessMessage, {
|
|
528
|
-
key: `context-max-set-${getNextComponentKey()}`,
|
|
529
|
-
message: `Session context limit set to ${limit.toLocaleString()} tokens.`,
|
|
530
|
-
hideBox: true,
|
|
531
|
-
}));
|
|
532
|
-
setTimeout(() => onCommandComplete?.(), DELAY_COMMAND_COMPLETE_MS);
|
|
533
|
-
return true;
|
|
534
|
-
}
|
|
535
|
-
// /context-max (no args) — show current effective context limit
|
|
536
|
-
const sessionLimit = getSessionContextLimit();
|
|
537
|
-
if (sessionLimit !== null) {
|
|
538
|
-
onAddToChatQueue(React.createElement(InfoMessage, {
|
|
539
|
-
key: `context-max-info-${getNextComponentKey()}`,
|
|
540
|
-
message: `Context limit: ${sessionLimit.toLocaleString()} tokens (session override)`,
|
|
541
|
-
hideBox: true,
|
|
542
|
-
}));
|
|
543
|
-
setTimeout(() => onCommandComplete?.(), DELAY_COMMAND_COMPLETE_MS);
|
|
544
|
-
return true;
|
|
545
|
-
}
|
|
546
|
-
const envLimit = process.env.NANOCODER_CONTEXT_LIMIT;
|
|
547
|
-
if (envLimit) {
|
|
548
|
-
const parsed = Number.parseInt(envLimit, 10);
|
|
549
|
-
if (!Number.isNaN(parsed) && parsed > 0) {
|
|
550
|
-
onAddToChatQueue(React.createElement(InfoMessage, {
|
|
551
|
-
key: `context-max-info-${getNextComponentKey()}`,
|
|
552
|
-
message: `Context limit: ${parsed.toLocaleString()} tokens (NANOCODER_CONTEXT_LIMIT env)`,
|
|
553
|
-
hideBox: true,
|
|
554
|
-
}));
|
|
555
|
-
setTimeout(() => onCommandComplete?.(), DELAY_COMMAND_COMPLETE_MS);
|
|
556
|
-
return true;
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
const modelLimit = await getModelContextLimit(model);
|
|
560
|
-
if (modelLimit !== null) {
|
|
561
|
-
onAddToChatQueue(React.createElement(InfoMessage, {
|
|
562
|
-
key: `context-max-info-${getNextComponentKey()}`,
|
|
563
|
-
message: `Context limit: ${modelLimit.toLocaleString()} tokens (model lookup)`,
|
|
564
|
-
hideBox: true,
|
|
565
|
-
}));
|
|
566
|
-
}
|
|
567
|
-
else {
|
|
568
|
-
onAddToChatQueue(React.createElement(InfoMessage, {
|
|
569
|
-
key: `context-max-info-${getNextComponentKey()}`,
|
|
570
|
-
message: 'Context limit: Unknown. Use /context-max <number> to set one.',
|
|
571
|
-
hideBox: true,
|
|
572
|
-
}));
|
|
573
|
-
}
|
|
574
|
-
setTimeout(() => onCommandComplete?.(), DELAY_COMMAND_COMPLETE_MS);
|
|
575
|
-
return true;
|
|
576
|
-
}
|
|
577
|
-
/**
|
|
578
|
-
* Handles interactive checkpoint load command
|
|
579
|
-
* Returns true if checkpoint load was handled
|
|
166
|
+
* Handles interactive checkpoint load command.
|
|
167
|
+
* Returns true if checkpoint load was handled.
|
|
580
168
|
*/
|
|
581
169
|
async function handleCheckpointLoad(commandParts, options) {
|
|
582
170
|
const { onAddToChatQueue, onEnterCheckpointLoadMode, onCommandComplete, getNextComponentKey, messages, } = options;
|
|
583
|
-
// Check if this is an interactive checkpoint load command
|
|
584
171
|
const isCheckpointLoad = commandParts[0] === SPECIAL_COMMANDS.CHECKPOINT &&
|
|
585
172
|
(commandParts[1] === CHECKPOINT_SUBCOMMANDS.LOAD ||
|
|
586
173
|
commandParts[1] === CHECKPOINT_SUBCOMMANDS.RESTORE) &&
|
|
@@ -614,7 +201,42 @@ async function handleCheckpointLoad(commandParts, options) {
|
|
|
614
201
|
}
|
|
615
202
|
}
|
|
616
203
|
/**
|
|
617
|
-
* Handles
|
|
204
|
+
* Handles /copilot-login as a live component.
|
|
205
|
+
* Returns true if handled.
|
|
206
|
+
*/
|
|
207
|
+
function handleCopilotLogin(commandParts, options) {
|
|
208
|
+
if (commandParts[0] !== 'copilot-login') {
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
const { setLiveComponent, setIsToolExecuting, onAddToChatQueue, onCommandComplete, getNextComponentKey, } = options;
|
|
212
|
+
const providerName = commandParts[1]?.trim() || 'GitHub Copilot';
|
|
213
|
+
setIsToolExecuting(true);
|
|
214
|
+
setLiveComponent(React.createElement(CopilotLogin, {
|
|
215
|
+
key: `copilot-login-live-${getNextComponentKey()}`,
|
|
216
|
+
providerName,
|
|
217
|
+
onDone: result => {
|
|
218
|
+
setLiveComponent(null);
|
|
219
|
+
setIsToolExecuting(false);
|
|
220
|
+
if (result.success) {
|
|
221
|
+
onAddToChatQueue(React.createElement(SuccessMessage, {
|
|
222
|
+
key: `copilot-login-done-${getNextComponentKey()}`,
|
|
223
|
+
message: `Logged in. Credential saved for "${providerName}".`,
|
|
224
|
+
hideBox: true,
|
|
225
|
+
}));
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
onAddToChatQueue(React.createElement(ErrorMessage, {
|
|
229
|
+
key: `copilot-login-error-${getNextComponentKey()}`,
|
|
230
|
+
message: result.error ?? 'Login failed.',
|
|
231
|
+
}));
|
|
232
|
+
}
|
|
233
|
+
onCommandComplete?.();
|
|
234
|
+
},
|
|
235
|
+
}));
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Handles built-in commands via the command registry.
|
|
618
240
|
*/
|
|
619
241
|
async function handleBuiltInCommand(message, options) {
|
|
620
242
|
const { onAddToChatQueue, onCommandComplete, getNextComponentKey, messages } = options;
|
|
@@ -629,19 +251,15 @@ async function handleBuiltInCommand(message, options) {
|
|
|
629
251
|
onCommandComplete?.();
|
|
630
252
|
return;
|
|
631
253
|
}
|
|
632
|
-
// Handle React element result
|
|
633
254
|
if (React.isValidElement(result)) {
|
|
634
|
-
// Defer adding to chat queue to avoid "Cannot update a component while rendering" error
|
|
635
255
|
queueMicrotask(() => {
|
|
636
256
|
onAddToChatQueue(result);
|
|
637
257
|
});
|
|
638
|
-
// Give React time to render before signaling completion
|
|
639
258
|
setTimeout(() => {
|
|
640
259
|
onCommandComplete?.();
|
|
641
260
|
}, DELAY_COMMAND_COMPLETE_MS);
|
|
642
261
|
return;
|
|
643
262
|
}
|
|
644
|
-
// Handle string result
|
|
645
263
|
if (typeof result === 'string' && result.trim()) {
|
|
646
264
|
queueMicrotask(() => {
|
|
647
265
|
onAddToChatQueue(React.createElement(InfoMessage, {
|
|
@@ -650,54 +268,40 @@ async function handleBuiltInCommand(message, options) {
|
|
|
650
268
|
hideBox: true,
|
|
651
269
|
}));
|
|
652
270
|
});
|
|
653
|
-
// Give React time to render before signaling completion
|
|
654
271
|
setTimeout(() => {
|
|
655
272
|
onCommandComplete?.();
|
|
656
273
|
}, DELAY_COMMAND_COMPLETE_MS);
|
|
657
274
|
return;
|
|
658
275
|
}
|
|
659
|
-
// No output to display, signal completion immediately
|
|
660
276
|
onCommandComplete?.();
|
|
661
277
|
}
|
|
662
278
|
/**
|
|
663
|
-
* Handles slash commands (prefixed with /)
|
|
279
|
+
* Handles slash commands (prefixed with /).
|
|
664
280
|
*/
|
|
665
281
|
async function handleSlashCommand(message, options) {
|
|
666
282
|
const commandName = message.slice(1).split(/\s+/)[0];
|
|
667
|
-
// Try custom command first
|
|
668
283
|
if (await handleCustomCommand(message, commandName, options)) {
|
|
669
284
|
return;
|
|
670
285
|
}
|
|
671
|
-
// Try compact command
|
|
672
286
|
const commandParts = message.slice(1).trim().split(/\s+/);
|
|
673
|
-
if (await handleCompactCommand(commandParts, options))
|
|
287
|
+
if (await handleCompactCommand(commandParts, options))
|
|
674
288
|
return;
|
|
675
|
-
|
|
676
|
-
// Try context-max command
|
|
677
|
-
if (await handleContextMaxCommand(commandParts, options)) {
|
|
289
|
+
if (await handleContextMaxCommand(commandParts, options))
|
|
678
290
|
return;
|
|
679
|
-
|
|
680
|
-
// Try /schedule start (enters scheduler mode)
|
|
681
|
-
if (await handleScheduleStart(commandParts, options)) {
|
|
291
|
+
if (await handleScheduleStart(commandParts, options))
|
|
682
292
|
return;
|
|
683
|
-
|
|
684
|
-
// Try /schedule create (creates file + AI assistance)
|
|
685
|
-
if (await handleScheduleCreate(commandParts, options)) {
|
|
293
|
+
if (await handleScheduleCreate(commandParts, options))
|
|
686
294
|
return;
|
|
687
|
-
|
|
688
|
-
// Try /commands create (creates file + AI assistance)
|
|
689
|
-
if (await handleCommandCreate(commandParts, options)) {
|
|
295
|
+
if (await handleCommandCreate(commandParts, options))
|
|
690
296
|
return;
|
|
691
|
-
|
|
692
|
-
// Try special command
|
|
693
|
-
if (await handleSpecialCommand(commandName, options)) {
|
|
297
|
+
if (await handleSpecialCommand(commandName, options))
|
|
694
298
|
return;
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
if (await
|
|
299
|
+
if (await handleCheckpointLoad(commandParts, options))
|
|
300
|
+
return;
|
|
301
|
+
if (await handleResumeCommand(commandParts, options))
|
|
302
|
+
return;
|
|
303
|
+
if (handleCopilotLogin(commandParts, options))
|
|
698
304
|
return;
|
|
699
|
-
}
|
|
700
|
-
// Fall back to built-in command
|
|
701
305
|
await handleBuiltInCommand(message, options);
|
|
702
306
|
}
|
|
703
307
|
/**
|
|
@@ -706,22 +310,18 @@ async function handleSlashCommand(message, options) {
|
|
|
706
310
|
*/
|
|
707
311
|
export async function handleMessageSubmission(message, options) {
|
|
708
312
|
const parsedInput = parseInput(message);
|
|
709
|
-
// Handle bash commands (prefixed with !)
|
|
710
313
|
if (parsedInput.isBashCommand && parsedInput.bashCommand) {
|
|
711
314
|
await handleBashCommand(parsedInput.bashCommand, options);
|
|
712
315
|
return;
|
|
713
316
|
}
|
|
714
|
-
// Handle slash commands (prefixed with /)
|
|
715
317
|
if (message.startsWith('/')) {
|
|
716
318
|
await handleSlashCommand(message, options);
|
|
717
319
|
return;
|
|
718
320
|
}
|
|
719
|
-
// Regular chat message - process with AI
|
|
720
321
|
await options.onHandleChatMessage(message);
|
|
721
322
|
}
|
|
722
323
|
export function createClearMessagesHandler(setMessages, client) {
|
|
723
324
|
return async () => {
|
|
724
|
-
// Clear message history and client context
|
|
725
325
|
setMessages([]);
|
|
726
326
|
if (client) {
|
|
727
327
|
await client.clearContext();
|