mistagent 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/src/api/auth.d.ts +7 -0
- package/dist/src/api/auth.d.ts.map +1 -0
- package/dist/src/api/auth.js +16 -0
- package/dist/src/api/auth.js.map +1 -0
- package/dist/src/api/chat.d.ts +8 -0
- package/dist/src/api/chat.d.ts.map +1 -0
- package/dist/src/api/chat.js +14 -0
- package/dist/src/api/chat.js.map +1 -0
- package/dist/src/api/client.d.ts +22 -0
- package/dist/src/api/client.d.ts.map +1 -0
- package/dist/src/api/client.js +140 -0
- package/dist/src/api/client.js.map +1 -0
- package/dist/src/api/commands.d.ts +8 -0
- package/dist/src/api/commands.d.ts.map +1 -0
- package/dist/src/api/commands.js +13 -0
- package/dist/src/api/commands.js.map +1 -0
- package/dist/src/api/models.d.ts +9 -0
- package/dist/src/api/models.d.ts.map +1 -0
- package/dist/src/api/models.js +13 -0
- package/dist/src/api/models.js.map +1 -0
- package/dist/src/api/sessions.d.ts +25 -0
- package/dist/src/api/sessions.d.ts.map +1 -0
- package/dist/src/api/sessions.js +26 -0
- package/dist/src/api/sessions.js.map +1 -0
- package/dist/src/api/tools.d.ts +7 -0
- package/dist/src/api/tools.d.ts.map +1 -0
- package/dist/src/api/tools.js +8 -0
- package/dist/src/api/tools.js.map +1 -0
- package/dist/src/components/App.d.ts +22 -0
- package/dist/src/components/App.d.ts.map +1 -0
- package/dist/src/components/App.js +61 -0
- package/dist/src/components/App.js.map +1 -0
- package/dist/src/components/AppLayout.d.ts +8 -0
- package/dist/src/components/AppLayout.d.ts.map +1 -0
- package/dist/src/components/AppLayout.js +18 -0
- package/dist/src/components/AppLayout.js.map +1 -0
- package/dist/src/components/Composer.d.ts +8 -0
- package/dist/src/components/Composer.d.ts.map +1 -0
- package/dist/src/components/Composer.js +294 -0
- package/dist/src/components/Composer.js.map +1 -0
- package/dist/src/components/Footer.d.ts +10 -0
- package/dist/src/components/Footer.d.ts.map +1 -0
- package/dist/src/components/Footer.js +34 -0
- package/dist/src/components/Footer.js.map +1 -0
- package/dist/src/components/Header.d.ts +3 -0
- package/dist/src/components/Header.d.ts.map +1 -0
- package/dist/src/components/Header.js +99 -0
- package/dist/src/components/Header.js.map +1 -0
- package/dist/src/components/HistoryItemDisplay.d.ts +8 -0
- package/dist/src/components/HistoryItemDisplay.d.ts.map +1 -0
- package/dist/src/components/HistoryItemDisplay.js +32 -0
- package/dist/src/components/HistoryItemDisplay.js.map +1 -0
- package/dist/src/components/InputPrompt.d.ts +11 -0
- package/dist/src/components/InputPrompt.d.ts.map +1 -0
- package/dist/src/components/InputPrompt.js +12 -0
- package/dist/src/components/InputPrompt.js.map +1 -0
- package/dist/src/components/LoadingIndicator.d.ts +8 -0
- package/dist/src/components/LoadingIndicator.d.ts.map +1 -0
- package/dist/src/components/LoadingIndicator.js +17 -0
- package/dist/src/components/LoadingIndicator.js.map +1 -0
- package/dist/src/components/LoginPrompt.d.ts +8 -0
- package/dist/src/components/LoginPrompt.d.ts.map +1 -0
- package/dist/src/components/LoginPrompt.js +76 -0
- package/dist/src/components/LoginPrompt.js.map +1 -0
- package/dist/src/components/MainContent.d.ts +3 -0
- package/dist/src/components/MainContent.d.ts.map +1 -0
- package/dist/src/components/MainContent.js +22 -0
- package/dist/src/components/MainContent.js.map +1 -0
- package/dist/src/components/ModelPicker.d.ts +3 -0
- package/dist/src/components/ModelPicker.d.ts.map +1 -0
- package/dist/src/components/ModelPicker.js +119 -0
- package/dist/src/components/ModelPicker.js.map +1 -0
- package/dist/src/components/MultiLineInput.d.ts +19 -0
- package/dist/src/components/MultiLineInput.d.ts.map +1 -0
- package/dist/src/components/MultiLineInput.js +108 -0
- package/dist/src/components/MultiLineInput.js.map +1 -0
- package/dist/src/components/SessionPicker.d.ts +3 -0
- package/dist/src/components/SessionPicker.d.ts.map +1 -0
- package/dist/src/components/SessionPicker.js +131 -0
- package/dist/src/components/SessionPicker.js.map +1 -0
- package/dist/src/components/SuggestionsDisplay.d.ts +16 -0
- package/dist/src/components/SuggestionsDisplay.d.ts.map +1 -0
- package/dist/src/components/SuggestionsDisplay.js +34 -0
- package/dist/src/components/SuggestionsDisplay.js.map +1 -0
- package/dist/src/components/messages/AssistantMessage.d.ts +8 -0
- package/dist/src/components/messages/AssistantMessage.d.ts.map +1 -0
- package/dist/src/components/messages/AssistantMessage.js +9 -0
- package/dist/src/components/messages/AssistantMessage.js.map +1 -0
- package/dist/src/components/messages/CommandResult.d.ts +8 -0
- package/dist/src/components/messages/CommandResult.d.ts.map +1 -0
- package/dist/src/components/messages/CommandResult.js +7 -0
- package/dist/src/components/messages/CommandResult.js.map +1 -0
- package/dist/src/components/messages/ErrorMessage.d.ts +7 -0
- package/dist/src/components/messages/ErrorMessage.d.ts.map +1 -0
- package/dist/src/components/messages/ErrorMessage.js +7 -0
- package/dist/src/components/messages/ErrorMessage.js.map +1 -0
- package/dist/src/components/messages/InfoMessage.d.ts +9 -0
- package/dist/src/components/messages/InfoMessage.d.ts.map +1 -0
- package/dist/src/components/messages/InfoMessage.js +8 -0
- package/dist/src/components/messages/InfoMessage.js.map +1 -0
- package/dist/src/components/messages/ModelMessage.d.ts +8 -0
- package/dist/src/components/messages/ModelMessage.d.ts.map +1 -0
- package/dist/src/components/messages/ModelMessage.js +7 -0
- package/dist/src/components/messages/ModelMessage.js.map +1 -0
- package/dist/src/components/messages/SessionMessage.d.ts +8 -0
- package/dist/src/components/messages/SessionMessage.d.ts.map +1 -0
- package/dist/src/components/messages/SessionMessage.js +12 -0
- package/dist/src/components/messages/SessionMessage.js.map +1 -0
- package/dist/src/components/messages/ToolCallMessage.d.ts +9 -0
- package/dist/src/components/messages/ToolCallMessage.d.ts.map +1 -0
- package/dist/src/components/messages/ToolCallMessage.js +14 -0
- package/dist/src/components/messages/ToolCallMessage.js.map +1 -0
- package/dist/src/components/messages/UserMessage.d.ts +7 -0
- package/dist/src/components/messages/UserMessage.d.ts.map +1 -0
- package/dist/src/components/messages/UserMessage.js +9 -0
- package/dist/src/components/messages/UserMessage.js.map +1 -0
- package/dist/src/components/shared/HorizontalLine.d.ts +11 -0
- package/dist/src/components/shared/HorizontalLine.d.ts.map +1 -0
- package/dist/src/components/shared/HorizontalLine.js +10 -0
- package/dist/src/components/shared/HorizontalLine.js.map +1 -0
- package/dist/src/components/shared/MarkdownRenderer.d.ts +7 -0
- package/dist/src/components/shared/MarkdownRenderer.d.ts.map +1 -0
- package/dist/src/components/shared/MarkdownRenderer.js +33 -0
- package/dist/src/components/shared/MarkdownRenderer.js.map +1 -0
- package/dist/src/components/shared/Spinner.d.ts +8 -0
- package/dist/src/components/shared/Spinner.d.ts.map +1 -0
- package/dist/src/components/shared/Spinner.js +7 -0
- package/dist/src/components/shared/Spinner.js.map +1 -0
- package/dist/src/components/shared/TextInput.d.ts +10 -0
- package/dist/src/components/shared/TextInput.d.ts.map +1 -0
- package/dist/src/components/shared/TextInput.js +110 -0
- package/dist/src/components/shared/TextInput.js.map +1 -0
- package/dist/src/contexts/AppContext.d.ts +21 -0
- package/dist/src/contexts/AppContext.d.ts.map +1 -0
- package/dist/src/contexts/AppContext.js +16 -0
- package/dist/src/contexts/AppContext.js.map +1 -0
- package/dist/src/contexts/ChatContext.d.ts +68 -0
- package/dist/src/contexts/ChatContext.d.ts.map +1 -0
- package/dist/src/contexts/ChatContext.js +158 -0
- package/dist/src/contexts/ChatContext.js.map +1 -0
- package/dist/src/contexts/KeypressContext.d.ts +47 -0
- package/dist/src/contexts/KeypressContext.d.ts.map +1 -0
- package/dist/src/contexts/KeypressContext.js +792 -0
- package/dist/src/contexts/KeypressContext.js.map +1 -0
- package/dist/src/contexts/ModelContext.d.ts +20 -0
- package/dist/src/contexts/ModelContext.d.ts.map +1 -0
- package/dist/src/contexts/ModelContext.js +42 -0
- package/dist/src/contexts/ModelContext.js.map +1 -0
- package/dist/src/contexts/PasteContext.d.ts +8 -0
- package/dist/src/contexts/PasteContext.d.ts.map +1 -0
- package/dist/src/contexts/PasteContext.js +12 -0
- package/dist/src/contexts/PasteContext.js.map +1 -0
- package/dist/src/contexts/SessionContext.d.ts +19 -0
- package/dist/src/contexts/SessionContext.d.ts.map +1 -0
- package/dist/src/contexts/SessionContext.js +56 -0
- package/dist/src/contexts/SessionContext.js.map +1 -0
- package/dist/src/contexts/UIContext.d.ts +15 -0
- package/dist/src/contexts/UIContext.d.ts.map +1 -0
- package/dist/src/contexts/UIContext.js +16 -0
- package/dist/src/contexts/UIContext.js.map +1 -0
- package/dist/src/hooks/useChat.d.ts +11 -0
- package/dist/src/hooks/useChat.d.ts.map +1 -0
- package/dist/src/hooks/useChat.js +146 -0
- package/dist/src/hooks/useChat.js.map +1 -0
- package/dist/src/hooks/useFileCompletion.d.ts +8 -0
- package/dist/src/hooks/useFileCompletion.d.ts.map +1 -0
- package/dist/src/hooks/useFileCompletion.js +75 -0
- package/dist/src/hooks/useFileCompletion.js.map +1 -0
- package/dist/src/hooks/useInputHistory.d.ts +6 -0
- package/dist/src/hooks/useInputHistory.d.ts.map +1 -0
- package/dist/src/hooks/useInputHistory.js +46 -0
- package/dist/src/hooks/useInputHistory.js.map +1 -0
- package/dist/src/hooks/useKeypress.d.ts +16 -0
- package/dist/src/hooks/useKeypress.d.ts.map +1 -0
- package/dist/src/hooks/useKeypress.js +23 -0
- package/dist/src/hooks/useKeypress.js.map +1 -0
- package/dist/src/hooks/useLoadingIndicator.d.ts +5 -0
- package/dist/src/hooks/useLoadingIndicator.d.ts.map +1 -0
- package/dist/src/hooks/useLoadingIndicator.js +31 -0
- package/dist/src/hooks/useLoadingIndicator.js.map +1 -0
- package/dist/src/hooks/useMultiLineInput.d.ts +37 -0
- package/dist/src/hooks/useMultiLineInput.d.ts.map +1 -0
- package/dist/src/hooks/useMultiLineInput.js +202 -0
- package/dist/src/hooks/useMultiLineInput.js.map +1 -0
- package/dist/src/hooks/usePasteBuffer.d.ts +10 -0
- package/dist/src/hooks/usePasteBuffer.d.ts.map +1 -0
- package/dist/src/hooks/usePasteBuffer.js +90 -0
- package/dist/src/hooks/usePasteBuffer.js.map +1 -0
- package/dist/src/hooks/useSlashCommand.d.ts +6 -0
- package/dist/src/hooks/useSlashCommand.d.ts.map +1 -0
- package/dist/src/hooks/useSlashCommand.js +198 -0
- package/dist/src/hooks/useSlashCommand.js.map +1 -0
- package/dist/src/hooks/useStdinInterceptor.d.ts +2 -0
- package/dist/src/hooks/useStdinInterceptor.d.ts.map +1 -0
- package/dist/src/hooks/useStdinInterceptor.js +85 -0
- package/dist/src/hooks/useStdinInterceptor.js.map +1 -0
- package/dist/src/hooks/useSymbolCompletion.d.ts +10 -0
- package/dist/src/hooks/useSymbolCompletion.d.ts.map +1 -0
- package/dist/src/hooks/useSymbolCompletion.js +65 -0
- package/dist/src/hooks/useSymbolCompletion.js.map +1 -0
- package/dist/src/hooks/useTextBuffer.d.ts +37 -0
- package/dist/src/hooks/useTextBuffer.d.ts.map +1 -0
- package/dist/src/hooks/useTextBuffer.js +627 -0
- package/dist/src/hooks/useTextBuffer.js.map +1 -0
- package/dist/src/main.d.ts +2 -0
- package/dist/src/main.d.ts.map +1 -0
- package/dist/src/main.js +152 -0
- package/dist/src/main.js.map +1 -0
- package/dist/src/tools/code-analyzer/config/ignore-service.d.ts +2 -0
- package/dist/src/tools/code-analyzer/config/ignore-service.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/config/ignore-service.js +209 -0
- package/dist/src/tools/code-analyzer/config/ignore-service.js.map +1 -0
- package/dist/src/tools/code-analyzer/config/supported-languages.d.ts +13 -0
- package/dist/src/tools/code-analyzer/config/supported-languages.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/config/supported-languages.js +17 -0
- package/dist/src/tools/code-analyzer/config/supported-languages.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/graph/graph.d.ts +3 -0
- package/dist/src/tools/code-analyzer/core/graph/graph.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/graph/graph.js +67 -0
- package/dist/src/tools/code-analyzer/core/graph/graph.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/graph/types.d.ts +62 -0
- package/dist/src/tools/code-analyzer/core/graph/types.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/graph/types.js +2 -0
- package/dist/src/tools/code-analyzer/core/graph/types.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/ast-cache.d.ts +12 -0
- package/dist/src/tools/code-analyzer/core/ingestion/ast-cache.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/ast-cache.js +35 -0
- package/dist/src/tools/code-analyzer/core/ingestion/ast-cache.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/call-processor.d.ts +16 -0
- package/dist/src/tools/code-analyzer/core/ingestion/call-processor.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/call-processor.js +328 -0
- package/dist/src/tools/code-analyzer/core/ingestion/call-processor.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/community-processor.d.ts +40 -0
- package/dist/src/tools/code-analyzer/core/ingestion/community-processor.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/community-processor.js +328 -0
- package/dist/src/tools/code-analyzer/core/ingestion/community-processor.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/entry-point-scoring.d.ts +40 -0
- package/dist/src/tools/code-analyzer/core/ingestion/entry-point-scoring.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/entry-point-scoring.js +236 -0
- package/dist/src/tools/code-analyzer/core/ingestion/entry-point-scoring.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/filesystem-walker.d.ts +29 -0
- package/dist/src/tools/code-analyzer/core/ingestion/filesystem-walker.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/filesystem-walker.js +81 -0
- package/dist/src/tools/code-analyzer/core/ingestion/filesystem-walker.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/framework-detection.d.ts +39 -0
- package/dist/src/tools/code-analyzer/core/ingestion/framework-detection.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/framework-detection.js +184 -0
- package/dist/src/tools/code-analyzer/core/ingestion/framework-detection.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/heritage-processor.d.ts +21 -0
- package/dist/src/tools/code-analyzer/core/ingestion/heritage-processor.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/heritage-processor.js +198 -0
- package/dist/src/tools/code-analyzer/core/ingestion/heritage-processor.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/import-processor.d.ts +39 -0
- package/dist/src/tools/code-analyzer/core/ingestion/import-processor.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/import-processor.js +791 -0
- package/dist/src/tools/code-analyzer/core/ingestion/import-processor.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/parsing-processor.d.ts +16 -0
- package/dist/src/tools/code-analyzer/core/ingestion/parsing-processor.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/parsing-processor.js +296 -0
- package/dist/src/tools/code-analyzer/core/ingestion/parsing-processor.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/pipeline.d.ts +3 -0
- package/dist/src/tools/code-analyzer/core/ingestion/pipeline.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/pipeline.js +309 -0
- package/dist/src/tools/code-analyzer/core/ingestion/pipeline.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/process-processor.d.ts +52 -0
- package/dist/src/tools/code-analyzer/core/ingestion/process-processor.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/process-processor.js +310 -0
- package/dist/src/tools/code-analyzer/core/ingestion/process-processor.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/structure-processor.d.ts +3 -0
- package/dist/src/tools/code-analyzer/core/ingestion/structure-processor.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/structure-processor.js +37 -0
- package/dist/src/tools/code-analyzer/core/ingestion/structure-processor.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/symbol-table.d.ts +34 -0
- package/dist/src/tools/code-analyzer/core/ingestion/symbol-table.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/symbol-table.js +39 -0
- package/dist/src/tools/code-analyzer/core/ingestion/symbol-table.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/tree-sitter-queries.d.ts +13 -0
- package/dist/src/tools/code-analyzer/core/ingestion/tree-sitter-queries.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/tree-sitter-queries.js +355 -0
- package/dist/src/tools/code-analyzer/core/ingestion/tree-sitter-queries.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/utils.d.ts +11 -0
- package/dist/src/tools/code-analyzer/core/ingestion/utils.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/utils.js +48 -0
- package/dist/src/tools/code-analyzer/core/ingestion/utils.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/workers/parse-worker.d.ts +59 -0
- package/dist/src/tools/code-analyzer/core/ingestion/workers/parse-worker.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/workers/parse-worker.js +538 -0
- package/dist/src/tools/code-analyzer/core/ingestion/workers/parse-worker.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/workers/worker-pool.d.ts +17 -0
- package/dist/src/tools/code-analyzer/core/ingestion/workers/worker-pool.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/ingestion/workers/worker-pool.js +121 -0
- package/dist/src/tools/code-analyzer/core/ingestion/workers/worker-pool.js.map +1 -0
- package/dist/src/tools/code-analyzer/core/tree-sitter/parser-loader.d.ts +5 -0
- package/dist/src/tools/code-analyzer/core/tree-sitter/parser-loader.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/core/tree-sitter/parser-loader.js +45 -0
- package/dist/src/tools/code-analyzer/core/tree-sitter/parser-loader.js.map +1 -0
- package/dist/src/tools/code-analyzer/index.d.ts +17 -0
- package/dist/src/tools/code-analyzer/index.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/index.js +15 -0
- package/dist/src/tools/code-analyzer/index.js.map +1 -0
- package/dist/src/tools/code-analyzer/lib/utils.d.ts +2 -0
- package/dist/src/tools/code-analyzer/lib/utils.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/lib/utils.js +4 -0
- package/dist/src/tools/code-analyzer/lib/utils.js.map +1 -0
- package/dist/src/tools/code-analyzer/types/pipeline.d.ts +33 -0
- package/dist/src/tools/code-analyzer/types/pipeline.d.ts.map +1 -0
- package/dist/src/tools/code-analyzer/types/pipeline.js +19 -0
- package/dist/src/tools/code-analyzer/types/pipeline.js.map +1 -0
- package/dist/src/types/api.d.ts +124 -0
- package/dist/src/types/api.d.ts.map +1 -0
- package/dist/src/types/api.js +3 -0
- package/dist/src/types/api.js.map +1 -0
- package/dist/src/types/history.d.ts +49 -0
- package/dist/src/types/history.d.ts.map +1 -0
- package/dist/src/types/history.js +10 -0
- package/dist/src/types/history.js.map +1 -0
- package/dist/src/utils/colors.d.ts +40 -0
- package/dist/src/utils/colors.d.ts.map +1 -0
- package/dist/src/utils/colors.js +48 -0
- package/dist/src/utils/colors.js.map +1 -0
- package/dist/src/utils/config.d.ts +13 -0
- package/dist/src/utils/config.d.ts.map +1 -0
- package/dist/src/utils/config.js +74 -0
- package/dist/src/utils/config.js.map +1 -0
- package/dist/src/utils/constants.d.ts +8 -0
- package/dist/src/utils/constants.d.ts.map +1 -0
- package/dist/src/utils/constants.js +48 -0
- package/dist/src/utils/constants.js.map +1 -0
- package/dist/src/utils/fileRef.d.ts +26 -0
- package/dist/src/utils/fileRef.d.ts.map +1 -0
- package/dist/src/utils/fileRef.js +305 -0
- package/dist/src/utils/fileRef.js.map +1 -0
- package/dist/src/utils/formatters.d.ts +4 -0
- package/dist/src/utils/formatters.d.ts.map +1 -0
- package/dist/src/utils/formatters.js +18 -0
- package/dist/src/utils/formatters.js.map +1 -0
- package/dist/src/utils/pasteTransform.d.ts +37 -0
- package/dist/src/utils/pasteTransform.d.ts.map +1 -0
- package/dist/src/utils/pasteTransform.js +161 -0
- package/dist/src/utils/pasteTransform.js.map +1 -0
- package/dist/src/utils/pasteUtils.d.ts +7 -0
- package/dist/src/utils/pasteUtils.d.ts.map +1 -0
- package/dist/src/utils/pasteUtils.js +33 -0
- package/dist/src/utils/pasteUtils.js.map +1 -0
- package/dist/src/utils/textUtils.d.ts +25 -0
- package/dist/src/utils/textUtils.d.ts.map +1 -0
- package/dist/src/utils/textUtils.js +107 -0
- package/dist/src/utils/textUtils.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,791 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import Parser from 'tree-sitter';
|
|
4
|
+
import { loadParser, loadLanguage } from '../tree-sitter/parser-loader.js';
|
|
5
|
+
import { LANGUAGE_QUERIES } from './tree-sitter-queries.js';
|
|
6
|
+
import { generateId } from '../../lib/utils.js';
|
|
7
|
+
import { getLanguageFromFilename, yieldToEventLoop } from './utils.js';
|
|
8
|
+
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
9
|
+
const isDev = process.env.NODE_ENV === 'development';
|
|
10
|
+
export const createImportMap = () => new Map();
|
|
11
|
+
/** Max entries in the resolve cache. Beyond this, the cache is cleared to bound memory.
|
|
12
|
+
* 100K entries ≈ 15MB — covers the most common import patterns. */
|
|
13
|
+
const RESOLVE_CACHE_CAP = 100_000;
|
|
14
|
+
export function buildImportResolutionContext(allPaths) {
|
|
15
|
+
const allFileList = allPaths;
|
|
16
|
+
const normalizedFileList = allFileList.map(p => p.replace(/\\/g, '/'));
|
|
17
|
+
const allFilePaths = new Set(allFileList);
|
|
18
|
+
const suffixIndex = buildSuffixIndex(normalizedFileList, allFileList);
|
|
19
|
+
return { allFilePaths, allFileList, normalizedFileList, suffixIndex, resolveCache: new Map() };
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Parse tsconfig.json to extract path aliases.
|
|
23
|
+
* Tries tsconfig.json, tsconfig.app.json, tsconfig.base.json in order.
|
|
24
|
+
*/
|
|
25
|
+
async function loadTsconfigPaths(repoRoot) {
|
|
26
|
+
const candidates = ['tsconfig.json', 'tsconfig.app.json', 'tsconfig.base.json'];
|
|
27
|
+
for (const filename of candidates) {
|
|
28
|
+
try {
|
|
29
|
+
const tsconfigPath = path.join(repoRoot, filename);
|
|
30
|
+
const raw = await fs.readFile(tsconfigPath, 'utf-8');
|
|
31
|
+
// Strip JSON comments (// and /* */ style) for robustness
|
|
32
|
+
const stripped = raw.replace(/\/\/.*$/gm, '').replace(/\/\*[\s\S]*?\*\//g, '');
|
|
33
|
+
const tsconfig = JSON.parse(stripped);
|
|
34
|
+
const compilerOptions = tsconfig.compilerOptions;
|
|
35
|
+
if (!compilerOptions?.paths)
|
|
36
|
+
continue;
|
|
37
|
+
const baseUrl = compilerOptions.baseUrl || '.';
|
|
38
|
+
const aliases = new Map();
|
|
39
|
+
for (const [pattern, targets] of Object.entries(compilerOptions.paths)) {
|
|
40
|
+
if (!Array.isArray(targets) || targets.length === 0)
|
|
41
|
+
continue;
|
|
42
|
+
const target = targets[0];
|
|
43
|
+
// Convert glob patterns: "@/*" -> "@/", "src/*" -> "src/"
|
|
44
|
+
const aliasPrefix = pattern.endsWith('/*') ? pattern.slice(0, -1) : pattern;
|
|
45
|
+
const targetPrefix = target.endsWith('/*') ? target.slice(0, -1) : target;
|
|
46
|
+
aliases.set(aliasPrefix, targetPrefix);
|
|
47
|
+
}
|
|
48
|
+
if (aliases.size > 0) {
|
|
49
|
+
if (isDev) {
|
|
50
|
+
console.log(`📦 Loaded ${aliases.size} path aliases from ${filename}`);
|
|
51
|
+
}
|
|
52
|
+
return { aliases, baseUrl };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// File doesn't exist or isn't valid JSON - try next
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Parse go.mod to extract module path.
|
|
63
|
+
*/
|
|
64
|
+
async function loadGoModulePath(repoRoot) {
|
|
65
|
+
try {
|
|
66
|
+
const goModPath = path.join(repoRoot, 'go.mod');
|
|
67
|
+
const content = await fs.readFile(goModPath, 'utf-8');
|
|
68
|
+
const match = content.match(/^module\s+(\S+)/m);
|
|
69
|
+
if (match) {
|
|
70
|
+
if (isDev) {
|
|
71
|
+
console.log(`📦 Loaded Go module path: ${match[1]}`);
|
|
72
|
+
}
|
|
73
|
+
return { modulePath: match[1] };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// No go.mod
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Parse Solidity remappings from remappings.txt or foundry.toml.
|
|
83
|
+
* Format: context:prefix=target or prefix=target
|
|
84
|
+
* e.g., @openzeppelin/=node_modules/@openzeppelin/
|
|
85
|
+
*/
|
|
86
|
+
async function loadSolidityRemappings(repoRoot) {
|
|
87
|
+
const remappings = new Map();
|
|
88
|
+
// Try remappings.txt first (Hardhat / standard format)
|
|
89
|
+
try {
|
|
90
|
+
const remappingsPath = path.join(repoRoot, 'remappings.txt');
|
|
91
|
+
const content = await fs.readFile(remappingsPath, 'utf-8');
|
|
92
|
+
for (const line of content.split('\n')) {
|
|
93
|
+
const trimmed = line.trim();
|
|
94
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
95
|
+
continue;
|
|
96
|
+
// Format: [context:]prefix=target
|
|
97
|
+
const eqIdx = trimmed.indexOf('=');
|
|
98
|
+
if (eqIdx < 0)
|
|
99
|
+
continue;
|
|
100
|
+
let prefix = trimmed.slice(0, eqIdx);
|
|
101
|
+
const target = trimmed.slice(eqIdx + 1);
|
|
102
|
+
// Strip optional context (e.g., "src:@oz/=..." -> "@oz/")
|
|
103
|
+
const colonIdx = prefix.indexOf(':');
|
|
104
|
+
if (colonIdx >= 0)
|
|
105
|
+
prefix = prefix.slice(colonIdx + 1);
|
|
106
|
+
if (prefix && target)
|
|
107
|
+
remappings.set(prefix, target);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// No remappings.txt
|
|
112
|
+
}
|
|
113
|
+
// Try foundry.toml if no remappings.txt found
|
|
114
|
+
if (remappings.size === 0) {
|
|
115
|
+
try {
|
|
116
|
+
const foundryPath = path.join(repoRoot, 'foundry.toml');
|
|
117
|
+
const content = await fs.readFile(foundryPath, 'utf-8');
|
|
118
|
+
// Simple TOML parse for remappings = ["@oz/=lib/oz/", ...]
|
|
119
|
+
const match = content.match(/remappings\s*=\s*\[([\s\S]*?)\]/);
|
|
120
|
+
if (match) {
|
|
121
|
+
const entries = match[1].match(/"([^"]+)"/g) || match[1].match(/'([^']+)'/g);
|
|
122
|
+
if (entries) {
|
|
123
|
+
for (const entry of entries) {
|
|
124
|
+
const cleaned = entry.replace(/['"]/g, '');
|
|
125
|
+
const eqIdx = cleaned.indexOf('=');
|
|
126
|
+
if (eqIdx < 0)
|
|
127
|
+
continue;
|
|
128
|
+
const prefix = cleaned.slice(0, eqIdx);
|
|
129
|
+
const target = cleaned.slice(eqIdx + 1);
|
|
130
|
+
if (prefix && target)
|
|
131
|
+
remappings.set(prefix, target);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
// No foundry.toml
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (remappings.size > 0) {
|
|
141
|
+
if (isDev) {
|
|
142
|
+
console.log(`📦 Loaded ${remappings.size} Solidity remappings`);
|
|
143
|
+
}
|
|
144
|
+
return { remappings };
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
// ============================================================================
|
|
149
|
+
// IMPORT PATH RESOLUTION
|
|
150
|
+
// ============================================================================
|
|
151
|
+
/** All file extensions to try during resolution */
|
|
152
|
+
const EXTENSIONS = [
|
|
153
|
+
'',
|
|
154
|
+
// TypeScript/JavaScript
|
|
155
|
+
'.tsx', '.ts', '.jsx', '.js', '/index.tsx', '/index.ts', '/index.jsx', '/index.js',
|
|
156
|
+
// Python
|
|
157
|
+
'.py', '/__init__.py',
|
|
158
|
+
// Java
|
|
159
|
+
'.java',
|
|
160
|
+
// C/C++
|
|
161
|
+
'.c', '.h', '.cpp', '.hpp', '.cc', '.cxx', '.hxx', '.hh',
|
|
162
|
+
// C#
|
|
163
|
+
'.cs',
|
|
164
|
+
// Go
|
|
165
|
+
'.go',
|
|
166
|
+
// Rust
|
|
167
|
+
'.rs', '/mod.rs',
|
|
168
|
+
// Solidity
|
|
169
|
+
'.sol',
|
|
170
|
+
];
|
|
171
|
+
/**
|
|
172
|
+
* Try to match a path (with extensions) against the known file set.
|
|
173
|
+
* Returns the matched file path or null.
|
|
174
|
+
*/
|
|
175
|
+
function tryResolveWithExtensions(basePath, allFiles) {
|
|
176
|
+
for (const ext of EXTENSIONS) {
|
|
177
|
+
const candidate = basePath + ext;
|
|
178
|
+
if (allFiles.has(candidate))
|
|
179
|
+
return candidate;
|
|
180
|
+
}
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
function buildSuffixIndex(normalizedFileList, allFileList) {
|
|
184
|
+
// Map: normalized suffix -> original file path
|
|
185
|
+
const exactMap = new Map();
|
|
186
|
+
// Map: lowercase suffix -> original file path
|
|
187
|
+
const lowerMap = new Map();
|
|
188
|
+
// Map: directory suffix -> list of file paths in that directory
|
|
189
|
+
const dirMap = new Map();
|
|
190
|
+
for (let i = 0; i < normalizedFileList.length; i++) {
|
|
191
|
+
const normalized = normalizedFileList[i];
|
|
192
|
+
const original = allFileList[i];
|
|
193
|
+
const parts = normalized.split('/');
|
|
194
|
+
// Index all suffixes: "a/b/c.java" -> ["c.java", "b/c.java", "a/b/c.java"]
|
|
195
|
+
for (let j = parts.length - 1; j >= 0; j--) {
|
|
196
|
+
const suffix = parts.slice(j).join('/');
|
|
197
|
+
// Only store first match (longest path wins for ambiguous suffixes)
|
|
198
|
+
if (!exactMap.has(suffix)) {
|
|
199
|
+
exactMap.set(suffix, original);
|
|
200
|
+
}
|
|
201
|
+
const lower = suffix.toLowerCase();
|
|
202
|
+
if (!lowerMap.has(lower)) {
|
|
203
|
+
lowerMap.set(lower, original);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// Index directory membership
|
|
207
|
+
const lastSlash = normalized.lastIndexOf('/');
|
|
208
|
+
if (lastSlash >= 0) {
|
|
209
|
+
// Build all directory suffixes
|
|
210
|
+
const dirParts = parts.slice(0, -1);
|
|
211
|
+
const fileName = parts[parts.length - 1];
|
|
212
|
+
const ext = fileName.substring(fileName.lastIndexOf('.'));
|
|
213
|
+
for (let j = dirParts.length - 1; j >= 0; j--) {
|
|
214
|
+
const dirSuffix = dirParts.slice(j).join('/');
|
|
215
|
+
const key = `${dirSuffix}:${ext}`;
|
|
216
|
+
let list = dirMap.get(key);
|
|
217
|
+
if (!list) {
|
|
218
|
+
list = [];
|
|
219
|
+
dirMap.set(key, list);
|
|
220
|
+
}
|
|
221
|
+
list.push(original);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
get: (suffix) => exactMap.get(suffix),
|
|
227
|
+
getInsensitive: (suffix) => lowerMap.get(suffix.toLowerCase()),
|
|
228
|
+
getFilesInDir: (dirSuffix, extension) => {
|
|
229
|
+
return dirMap.get(`${dirSuffix}:${extension}`) || [];
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Suffix-based resolution using index. O(1) per lookup instead of O(files).
|
|
235
|
+
*/
|
|
236
|
+
function suffixResolve(pathParts, normalizedFileList, allFileList, index) {
|
|
237
|
+
if (index) {
|
|
238
|
+
for (let i = 0; i < pathParts.length; i++) {
|
|
239
|
+
const suffix = pathParts.slice(i).join('/');
|
|
240
|
+
for (const ext of EXTENSIONS) {
|
|
241
|
+
const suffixWithExt = suffix + ext;
|
|
242
|
+
const result = index.get(suffixWithExt) || index.getInsensitive(suffixWithExt);
|
|
243
|
+
if (result)
|
|
244
|
+
return result;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
// Fallback: linear scan (for backward compatibility)
|
|
250
|
+
for (let i = 0; i < pathParts.length; i++) {
|
|
251
|
+
const suffix = pathParts.slice(i).join('/');
|
|
252
|
+
for (const ext of EXTENSIONS) {
|
|
253
|
+
const suffixWithExt = suffix + ext;
|
|
254
|
+
const suffixPattern = '/' + suffixWithExt;
|
|
255
|
+
const matchIdx = normalizedFileList.findIndex(filePath => filePath.endsWith(suffixPattern) || filePath.toLowerCase().endsWith(suffixPattern.toLowerCase()));
|
|
256
|
+
if (matchIdx !== -1) {
|
|
257
|
+
return allFileList[matchIdx];
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Resolve an import path to a file path in the repository.
|
|
265
|
+
*
|
|
266
|
+
* Language-specific preprocessing is applied before the generic resolution:
|
|
267
|
+
* - TypeScript/JavaScript: rewrites tsconfig path aliases
|
|
268
|
+
* - Rust: converts crate::/super::/self:: to relative paths
|
|
269
|
+
*
|
|
270
|
+
* Java wildcards and Go package imports are handled separately in processImports
|
|
271
|
+
* because they resolve to multiple files.
|
|
272
|
+
*/
|
|
273
|
+
const resolveImportPath = (currentFile, importPath, allFiles, allFileList, normalizedFileList, resolveCache, language, tsconfigPaths, index, solidityRemappings) => {
|
|
274
|
+
const cacheKey = `${currentFile}::${importPath}`;
|
|
275
|
+
if (resolveCache.has(cacheKey))
|
|
276
|
+
return resolveCache.get(cacheKey) ?? null;
|
|
277
|
+
const cache = (result) => {
|
|
278
|
+
// Evict oldest 20% when cap is reached instead of clearing all
|
|
279
|
+
if (resolveCache.size >= RESOLVE_CACHE_CAP) {
|
|
280
|
+
const evictCount = Math.floor(RESOLVE_CACHE_CAP * 0.2);
|
|
281
|
+
const iter = resolveCache.keys();
|
|
282
|
+
for (let i = 0; i < evictCount; i++) {
|
|
283
|
+
const key = iter.next().value;
|
|
284
|
+
if (key !== undefined)
|
|
285
|
+
resolveCache.delete(key);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
resolveCache.set(cacheKey, result);
|
|
289
|
+
return result;
|
|
290
|
+
};
|
|
291
|
+
// ---- TypeScript/JavaScript: rewrite path aliases ----
|
|
292
|
+
if ((language === SupportedLanguages.TypeScript || language === SupportedLanguages.JavaScript) &&
|
|
293
|
+
tsconfigPaths &&
|
|
294
|
+
!importPath.startsWith('.')) {
|
|
295
|
+
for (const [aliasPrefix, targetPrefix] of tsconfigPaths.aliases) {
|
|
296
|
+
if (importPath.startsWith(aliasPrefix)) {
|
|
297
|
+
const remainder = importPath.slice(aliasPrefix.length);
|
|
298
|
+
// Build the rewritten path relative to baseUrl
|
|
299
|
+
const rewritten = tsconfigPaths.baseUrl === '.'
|
|
300
|
+
? targetPrefix + remainder
|
|
301
|
+
: tsconfigPaths.baseUrl + '/' + targetPrefix + remainder;
|
|
302
|
+
// Try direct resolution from repo root
|
|
303
|
+
const resolved = tryResolveWithExtensions(rewritten, allFiles);
|
|
304
|
+
if (resolved)
|
|
305
|
+
return cache(resolved);
|
|
306
|
+
// Try suffix matching as fallback
|
|
307
|
+
const parts = rewritten.split('/').filter(Boolean);
|
|
308
|
+
const suffixResult = suffixResolve(parts, normalizedFileList, allFileList, index);
|
|
309
|
+
if (suffixResult)
|
|
310
|
+
return cache(suffixResult);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
// ---- Solidity: rewrite remapped imports ----
|
|
315
|
+
if (language === SupportedLanguages.Solidity && solidityRemappings && !importPath.startsWith('.')) {
|
|
316
|
+
for (const [prefix, target] of solidityRemappings.remappings) {
|
|
317
|
+
if (importPath.startsWith(prefix)) {
|
|
318
|
+
const remainder = importPath.slice(prefix.length);
|
|
319
|
+
const rewritten = target + remainder;
|
|
320
|
+
// Try direct resolution
|
|
321
|
+
const resolved = tryResolveWithExtensions(rewritten, allFiles);
|
|
322
|
+
if (resolved)
|
|
323
|
+
return cache(resolved);
|
|
324
|
+
// Try suffix matching as fallback
|
|
325
|
+
const parts = rewritten.split('/').filter(Boolean);
|
|
326
|
+
const suffixResult = suffixResolve(parts, normalizedFileList, allFileList, index);
|
|
327
|
+
if (suffixResult)
|
|
328
|
+
return cache(suffixResult);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
// ---- Rust: convert module path syntax to file paths ----
|
|
333
|
+
if (language === SupportedLanguages.Rust) {
|
|
334
|
+
const rustResult = resolveRustImport(currentFile, importPath, allFiles);
|
|
335
|
+
if (rustResult)
|
|
336
|
+
return cache(rustResult);
|
|
337
|
+
// Fall through to generic resolution if Rust-specific didn't match
|
|
338
|
+
}
|
|
339
|
+
// ---- Generic relative import resolution (./ and ../) ----
|
|
340
|
+
const currentDir = currentFile.split('/').slice(0, -1);
|
|
341
|
+
const parts = importPath.split('/');
|
|
342
|
+
for (const part of parts) {
|
|
343
|
+
if (part === '.')
|
|
344
|
+
continue;
|
|
345
|
+
if (part === '..') {
|
|
346
|
+
currentDir.pop();
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
currentDir.push(part);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
const basePath = currentDir.join('/');
|
|
353
|
+
if (importPath.startsWith('.')) {
|
|
354
|
+
const resolved = tryResolveWithExtensions(basePath, allFiles);
|
|
355
|
+
return cache(resolved);
|
|
356
|
+
}
|
|
357
|
+
// ---- Generic package/absolute import resolution (suffix matching) ----
|
|
358
|
+
// Java wildcards are handled in processImports, not here
|
|
359
|
+
if (importPath.endsWith('.*')) {
|
|
360
|
+
return cache(null);
|
|
361
|
+
}
|
|
362
|
+
const pathLike = importPath.includes('/')
|
|
363
|
+
? importPath
|
|
364
|
+
: importPath.replace(/\./g, '/');
|
|
365
|
+
const pathParts = pathLike.split('/').filter(Boolean);
|
|
366
|
+
const resolved = suffixResolve(pathParts, normalizedFileList, allFileList, index);
|
|
367
|
+
return cache(resolved);
|
|
368
|
+
};
|
|
369
|
+
// ============================================================================
|
|
370
|
+
// RUST MODULE RESOLUTION
|
|
371
|
+
// ============================================================================
|
|
372
|
+
/**
|
|
373
|
+
* Resolve Rust use-path to a file.
|
|
374
|
+
* Handles crate::, super::, self:: prefixes and :: path separators.
|
|
375
|
+
*/
|
|
376
|
+
function resolveRustImport(currentFile, importPath, allFiles) {
|
|
377
|
+
let rustPath;
|
|
378
|
+
if (importPath.startsWith('crate::')) {
|
|
379
|
+
// crate:: resolves from src/ directory (standard Rust layout)
|
|
380
|
+
rustPath = importPath.slice(7).replace(/::/g, '/');
|
|
381
|
+
// Try from src/ (standard layout)
|
|
382
|
+
const fromSrc = tryRustModulePath('src/' + rustPath, allFiles);
|
|
383
|
+
if (fromSrc)
|
|
384
|
+
return fromSrc;
|
|
385
|
+
// Try from repo root (non-standard)
|
|
386
|
+
const fromRoot = tryRustModulePath(rustPath, allFiles);
|
|
387
|
+
if (fromRoot)
|
|
388
|
+
return fromRoot;
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
if (importPath.startsWith('super::')) {
|
|
392
|
+
// super:: = parent directory of current file's module
|
|
393
|
+
const currentDir = currentFile.split('/').slice(0, -1);
|
|
394
|
+
currentDir.pop(); // Go up one level for super::
|
|
395
|
+
rustPath = importPath.slice(7).replace(/::/g, '/');
|
|
396
|
+
const fullPath = [...currentDir, rustPath].join('/');
|
|
397
|
+
return tryRustModulePath(fullPath, allFiles);
|
|
398
|
+
}
|
|
399
|
+
if (importPath.startsWith('self::')) {
|
|
400
|
+
// self:: = current module's directory
|
|
401
|
+
const currentDir = currentFile.split('/').slice(0, -1);
|
|
402
|
+
rustPath = importPath.slice(6).replace(/::/g, '/');
|
|
403
|
+
const fullPath = [...currentDir, rustPath].join('/');
|
|
404
|
+
return tryRustModulePath(fullPath, allFiles);
|
|
405
|
+
}
|
|
406
|
+
// Bare path without prefix (e.g., from a use in a nested module)
|
|
407
|
+
// Convert :: to / and try suffix matching
|
|
408
|
+
if (importPath.includes('::')) {
|
|
409
|
+
rustPath = importPath.replace(/::/g, '/');
|
|
410
|
+
return tryRustModulePath(rustPath, allFiles);
|
|
411
|
+
}
|
|
412
|
+
return null;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Try to resolve a Rust module path to a file.
|
|
416
|
+
* Tries: path.rs, path/mod.rs, and with the last segment stripped
|
|
417
|
+
* (last segment might be a symbol name, not a module).
|
|
418
|
+
*/
|
|
419
|
+
function tryRustModulePath(modulePath, allFiles) {
|
|
420
|
+
// Try direct: path.rs
|
|
421
|
+
if (allFiles.has(modulePath + '.rs'))
|
|
422
|
+
return modulePath + '.rs';
|
|
423
|
+
// Try directory: path/mod.rs
|
|
424
|
+
if (allFiles.has(modulePath + '/mod.rs'))
|
|
425
|
+
return modulePath + '/mod.rs';
|
|
426
|
+
// Try path/lib.rs (for crate root)
|
|
427
|
+
if (allFiles.has(modulePath + '/lib.rs'))
|
|
428
|
+
return modulePath + '/lib.rs';
|
|
429
|
+
// The last segment might be a symbol (function, struct, etc.), not a module.
|
|
430
|
+
// Strip it and try again.
|
|
431
|
+
const lastSlash = modulePath.lastIndexOf('/');
|
|
432
|
+
if (lastSlash > 0) {
|
|
433
|
+
const parentPath = modulePath.substring(0, lastSlash);
|
|
434
|
+
if (allFiles.has(parentPath + '.rs'))
|
|
435
|
+
return parentPath + '.rs';
|
|
436
|
+
if (allFiles.has(parentPath + '/mod.rs'))
|
|
437
|
+
return parentPath + '/mod.rs';
|
|
438
|
+
}
|
|
439
|
+
return null;
|
|
440
|
+
}
|
|
441
|
+
// ============================================================================
|
|
442
|
+
// JAVA MULTI-FILE RESOLUTION
|
|
443
|
+
// ============================================================================
|
|
444
|
+
/**
|
|
445
|
+
* Resolve a Java wildcard import (com.example.*) to all matching .java files.
|
|
446
|
+
* Returns an array of file paths.
|
|
447
|
+
*/
|
|
448
|
+
function resolveJavaWildcard(importPath, normalizedFileList, allFileList, index) {
|
|
449
|
+
// "com.example.util.*" -> "com/example/util"
|
|
450
|
+
const packagePath = importPath.slice(0, -2).replace(/\./g, '/');
|
|
451
|
+
if (index) {
|
|
452
|
+
// Use directory index: get all .java files in this package directory
|
|
453
|
+
const candidates = index.getFilesInDir(packagePath, '.java');
|
|
454
|
+
// Filter to only direct children (no subdirectories)
|
|
455
|
+
const packageSuffix = '/' + packagePath + '/';
|
|
456
|
+
return candidates.filter(f => {
|
|
457
|
+
const normalized = f.replace(/\\/g, '/');
|
|
458
|
+
const idx = normalized.indexOf(packageSuffix);
|
|
459
|
+
if (idx < 0)
|
|
460
|
+
return false;
|
|
461
|
+
const afterPkg = normalized.substring(idx + packageSuffix.length);
|
|
462
|
+
return !afterPkg.includes('/');
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
// Fallback: linear scan
|
|
466
|
+
const packageSuffix = '/' + packagePath + '/';
|
|
467
|
+
const matches = [];
|
|
468
|
+
for (let i = 0; i < normalizedFileList.length; i++) {
|
|
469
|
+
const normalized = normalizedFileList[i];
|
|
470
|
+
if (normalized.includes(packageSuffix) && normalized.endsWith('.java')) {
|
|
471
|
+
const afterPackage = normalized.substring(normalized.indexOf(packageSuffix) + packageSuffix.length);
|
|
472
|
+
if (!afterPackage.includes('/')) {
|
|
473
|
+
matches.push(allFileList[i]);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
return matches;
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Try to resolve a Java static import by stripping the member name.
|
|
481
|
+
* "com.example.Constants.VALUE" -> resolve "com.example.Constants"
|
|
482
|
+
*/
|
|
483
|
+
function resolveJavaStaticImport(importPath, normalizedFileList, allFileList, index) {
|
|
484
|
+
// Static imports look like: com.example.Constants.VALUE or com.example.Constants.*
|
|
485
|
+
// The last segment is a member name (field/method) if it starts with lowercase or is ALL_CAPS
|
|
486
|
+
const segments = importPath.split('.');
|
|
487
|
+
if (segments.length < 3)
|
|
488
|
+
return null;
|
|
489
|
+
const lastSeg = segments[segments.length - 1];
|
|
490
|
+
// If last segment is a wildcard or ALL_CAPS constant or starts with lowercase, strip it
|
|
491
|
+
if (lastSeg === '*' || /^[a-z]/.test(lastSeg) || /^[A-Z_]+$/.test(lastSeg)) {
|
|
492
|
+
const classPath = segments.slice(0, -1).join('/');
|
|
493
|
+
const classSuffix = classPath + '.java';
|
|
494
|
+
if (index) {
|
|
495
|
+
return index.get(classSuffix) || index.getInsensitive(classSuffix) || null;
|
|
496
|
+
}
|
|
497
|
+
// Fallback: linear scan
|
|
498
|
+
const fullSuffix = '/' + classSuffix;
|
|
499
|
+
for (let i = 0; i < normalizedFileList.length; i++) {
|
|
500
|
+
if (normalizedFileList[i].endsWith(fullSuffix) ||
|
|
501
|
+
normalizedFileList[i].toLowerCase().endsWith(fullSuffix.toLowerCase())) {
|
|
502
|
+
return allFileList[i];
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
return null;
|
|
507
|
+
}
|
|
508
|
+
// ============================================================================
|
|
509
|
+
// GO PACKAGE RESOLUTION
|
|
510
|
+
// ============================================================================
|
|
511
|
+
/**
|
|
512
|
+
* Resolve a Go internal package import to all .go files in the package directory.
|
|
513
|
+
* Returns an array of file paths.
|
|
514
|
+
*/
|
|
515
|
+
function resolveGoPackage(importPath, goModule, normalizedFileList, allFileList) {
|
|
516
|
+
if (!importPath.startsWith(goModule.modulePath))
|
|
517
|
+
return [];
|
|
518
|
+
// Strip module path to get relative package path
|
|
519
|
+
const relativePkg = importPath.slice(goModule.modulePath.length + 1); // e.g., "internal/auth"
|
|
520
|
+
if (!relativePkg)
|
|
521
|
+
return [];
|
|
522
|
+
const pkgSuffix = '/' + relativePkg + '/';
|
|
523
|
+
const matches = [];
|
|
524
|
+
for (let i = 0; i < normalizedFileList.length; i++) {
|
|
525
|
+
const normalized = normalizedFileList[i];
|
|
526
|
+
// File must be directly in the package directory (not a subdirectory)
|
|
527
|
+
if (normalized.includes(pkgSuffix) && normalized.endsWith('.go') && !normalized.endsWith('_test.go')) {
|
|
528
|
+
const afterPkg = normalized.substring(normalized.indexOf(pkgSuffix) + pkgSuffix.length);
|
|
529
|
+
if (!afterPkg.includes('/')) {
|
|
530
|
+
matches.push(allFileList[i]);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
return matches;
|
|
535
|
+
}
|
|
536
|
+
// ============================================================================
|
|
537
|
+
// MAIN IMPORT PROCESSOR
|
|
538
|
+
// ============================================================================
|
|
539
|
+
export const processImports = async (graph, files, astCache, importMap, onProgress, repoRoot, allPaths) => {
|
|
540
|
+
// Use allPaths (full repo) when available for cross-chunk resolution, else fall back to chunk files
|
|
541
|
+
const allFileList = allPaths ?? files.map(f => f.path);
|
|
542
|
+
const allFilePaths = new Set(allFileList);
|
|
543
|
+
const parser = await loadParser();
|
|
544
|
+
const resolveCache = new Map();
|
|
545
|
+
// Pre-compute normalized file list once (forward slashes)
|
|
546
|
+
const normalizedFileList = allFileList.map(p => p.replace(/\\/g, '/'));
|
|
547
|
+
// Build suffix index for O(1) lookups
|
|
548
|
+
const index = buildSuffixIndex(normalizedFileList, allFileList);
|
|
549
|
+
// Track import statistics
|
|
550
|
+
let totalImportsFound = 0;
|
|
551
|
+
let totalImportsResolved = 0;
|
|
552
|
+
// Load language-specific configs once before the file loop
|
|
553
|
+
const effectiveRoot = repoRoot || '';
|
|
554
|
+
const tsconfigPaths = await loadTsconfigPaths(effectiveRoot);
|
|
555
|
+
const goModule = await loadGoModulePath(effectiveRoot);
|
|
556
|
+
const solidityRemappings = await loadSolidityRemappings(effectiveRoot);
|
|
557
|
+
// Helper: add an IMPORTS edge + update import map
|
|
558
|
+
const addImportEdge = (filePath, resolvedPath) => {
|
|
559
|
+
const sourceId = generateId('File', filePath);
|
|
560
|
+
const targetId = generateId('File', resolvedPath);
|
|
561
|
+
const relId = generateId('IMPORTS', `${filePath}->${resolvedPath}`);
|
|
562
|
+
totalImportsResolved++;
|
|
563
|
+
graph.addRelationship({
|
|
564
|
+
id: relId,
|
|
565
|
+
sourceId,
|
|
566
|
+
targetId,
|
|
567
|
+
type: 'IMPORTS',
|
|
568
|
+
confidence: 1.0,
|
|
569
|
+
reason: '',
|
|
570
|
+
});
|
|
571
|
+
if (!importMap.has(filePath)) {
|
|
572
|
+
importMap.set(filePath, new Set());
|
|
573
|
+
}
|
|
574
|
+
importMap.get(filePath).add(resolvedPath);
|
|
575
|
+
};
|
|
576
|
+
for (let i = 0; i < files.length; i++) {
|
|
577
|
+
const file = files[i];
|
|
578
|
+
onProgress?.(i + 1, files.length);
|
|
579
|
+
if (i % 20 === 0)
|
|
580
|
+
await yieldToEventLoop();
|
|
581
|
+
// 1. Check language support first
|
|
582
|
+
const language = getLanguageFromFilename(file.path);
|
|
583
|
+
if (!language)
|
|
584
|
+
continue;
|
|
585
|
+
const queryStr = LANGUAGE_QUERIES[language];
|
|
586
|
+
if (!queryStr)
|
|
587
|
+
continue;
|
|
588
|
+
// 2. ALWAYS load the language before querying (parser is stateful)
|
|
589
|
+
await loadLanguage(language, file.path);
|
|
590
|
+
// 3. Get AST (Try Cache First)
|
|
591
|
+
let tree = astCache.get(file.path);
|
|
592
|
+
let wasReparsed = false;
|
|
593
|
+
if (!tree) {
|
|
594
|
+
try {
|
|
595
|
+
tree = parser.parse(file.content, undefined, { bufferSize: 1024 * 256 });
|
|
596
|
+
}
|
|
597
|
+
catch (parseError) {
|
|
598
|
+
continue;
|
|
599
|
+
}
|
|
600
|
+
wasReparsed = true;
|
|
601
|
+
// Cache re-parsed tree so call/heritage phases get hits
|
|
602
|
+
astCache.set(file.path, tree);
|
|
603
|
+
}
|
|
604
|
+
let query;
|
|
605
|
+
let matches;
|
|
606
|
+
try {
|
|
607
|
+
const lang = parser.getLanguage();
|
|
608
|
+
query = new Parser.Query(lang, queryStr);
|
|
609
|
+
matches = query.matches(tree.rootNode);
|
|
610
|
+
}
|
|
611
|
+
catch (queryError) {
|
|
612
|
+
if (isDev) {
|
|
613
|
+
console.group(`🔴 Query Error: ${file.path}`);
|
|
614
|
+
console.log('Language:', language);
|
|
615
|
+
console.log('Query (first 200 chars):', queryStr.substring(0, 200) + '...');
|
|
616
|
+
console.log('Error:', queryError?.message || queryError);
|
|
617
|
+
console.log('File content (first 300 chars):', file.content.substring(0, 300));
|
|
618
|
+
console.log('AST root type:', tree.rootNode?.type);
|
|
619
|
+
console.log('AST has errors:', tree.rootNode?.hasError);
|
|
620
|
+
console.groupEnd();
|
|
621
|
+
}
|
|
622
|
+
if (wasReparsed)
|
|
623
|
+
tree.delete?.();
|
|
624
|
+
continue;
|
|
625
|
+
}
|
|
626
|
+
matches.forEach(match => {
|
|
627
|
+
const captureMap = {};
|
|
628
|
+
match.captures.forEach(c => captureMap[c.name] = c.node);
|
|
629
|
+
if (captureMap['import']) {
|
|
630
|
+
const sourceNode = captureMap['import.source'];
|
|
631
|
+
if (!sourceNode) {
|
|
632
|
+
if (isDev) {
|
|
633
|
+
console.log(`⚠️ Import captured but no source node in ${file.path}`);
|
|
634
|
+
}
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
// Clean path (remove quotes and angle brackets for C/C++ includes)
|
|
638
|
+
const rawImportPath = sourceNode.text.replace(/['"<>]/g, '');
|
|
639
|
+
totalImportsFound++;
|
|
640
|
+
// ---- Java: handle wildcards and static imports specially ----
|
|
641
|
+
if (language === SupportedLanguages.Java) {
|
|
642
|
+
if (rawImportPath.endsWith('.*')) {
|
|
643
|
+
const matchedFiles = resolveJavaWildcard(rawImportPath, normalizedFileList, allFileList, index);
|
|
644
|
+
for (const matchedFile of matchedFiles) {
|
|
645
|
+
addImportEdge(file.path, matchedFile);
|
|
646
|
+
}
|
|
647
|
+
return; // skip single-file resolution
|
|
648
|
+
}
|
|
649
|
+
// Try static import resolution (strip member name)
|
|
650
|
+
const staticResolved = resolveJavaStaticImport(rawImportPath, normalizedFileList, allFileList, index);
|
|
651
|
+
if (staticResolved) {
|
|
652
|
+
addImportEdge(file.path, staticResolved);
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
// Fall through to normal resolution for regular Java imports
|
|
656
|
+
}
|
|
657
|
+
// ---- Go: handle package-level imports ----
|
|
658
|
+
if (language === SupportedLanguages.Go && goModule && rawImportPath.startsWith(goModule.modulePath)) {
|
|
659
|
+
const pkgFiles = resolveGoPackage(rawImportPath, goModule, normalizedFileList, allFileList);
|
|
660
|
+
if (pkgFiles.length > 0) {
|
|
661
|
+
for (const pkgFile of pkgFiles) {
|
|
662
|
+
addImportEdge(file.path, pkgFile);
|
|
663
|
+
}
|
|
664
|
+
return; // skip single-file resolution
|
|
665
|
+
}
|
|
666
|
+
// Fall through if no files found (package might be external)
|
|
667
|
+
}
|
|
668
|
+
// ---- Standard single-file resolution ----
|
|
669
|
+
const resolvedPath = resolveImportPath(file.path, rawImportPath, allFilePaths, allFileList, normalizedFileList, resolveCache, language, tsconfigPaths, index, solidityRemappings);
|
|
670
|
+
if (resolvedPath) {
|
|
671
|
+
addImportEdge(file.path, resolvedPath);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
});
|
|
675
|
+
// Tree is now owned by the LRU cache — no manual delete needed
|
|
676
|
+
}
|
|
677
|
+
if (isDev) {
|
|
678
|
+
console.log(`📊 Import processing complete: ${totalImportsResolved}/${totalImportsFound} imports resolved to graph edges`);
|
|
679
|
+
}
|
|
680
|
+
};
|
|
681
|
+
// ============================================================================
|
|
682
|
+
// FAST PATH: Resolve pre-extracted imports (no parsing needed)
|
|
683
|
+
// ============================================================================
|
|
684
|
+
export const processImportsFromExtracted = async (graph, files, extractedImports, importMap, onProgress, repoRoot, prebuiltCtx) => {
|
|
685
|
+
const ctx = prebuiltCtx ?? buildImportResolutionContext(files.map(f => f.path));
|
|
686
|
+
const { allFilePaths, allFileList, normalizedFileList, suffixIndex: index, resolveCache } = ctx;
|
|
687
|
+
let totalImportsFound = 0;
|
|
688
|
+
let totalImportsResolved = 0;
|
|
689
|
+
const effectiveRoot = repoRoot || '';
|
|
690
|
+
const tsconfigPaths = await loadTsconfigPaths(effectiveRoot);
|
|
691
|
+
const goModule = await loadGoModulePath(effectiveRoot);
|
|
692
|
+
const solidityRemappings = await loadSolidityRemappings(effectiveRoot);
|
|
693
|
+
const addImportEdge = (filePath, resolvedPath) => {
|
|
694
|
+
const sourceId = generateId('File', filePath);
|
|
695
|
+
const targetId = generateId('File', resolvedPath);
|
|
696
|
+
const relId = generateId('IMPORTS', `${filePath}->${resolvedPath}`);
|
|
697
|
+
totalImportsResolved++;
|
|
698
|
+
graph.addRelationship({
|
|
699
|
+
id: relId,
|
|
700
|
+
sourceId,
|
|
701
|
+
targetId,
|
|
702
|
+
type: 'IMPORTS',
|
|
703
|
+
confidence: 1.0,
|
|
704
|
+
reason: '',
|
|
705
|
+
});
|
|
706
|
+
if (!importMap.has(filePath)) {
|
|
707
|
+
importMap.set(filePath, new Set());
|
|
708
|
+
}
|
|
709
|
+
importMap.get(filePath).add(resolvedPath);
|
|
710
|
+
};
|
|
711
|
+
// Group by file for progress reporting (users see file count, not import count)
|
|
712
|
+
const importsByFile = new Map();
|
|
713
|
+
for (const imp of extractedImports) {
|
|
714
|
+
let list = importsByFile.get(imp.filePath);
|
|
715
|
+
if (!list) {
|
|
716
|
+
list = [];
|
|
717
|
+
importsByFile.set(imp.filePath, list);
|
|
718
|
+
}
|
|
719
|
+
list.push(imp);
|
|
720
|
+
}
|
|
721
|
+
const totalFiles = importsByFile.size;
|
|
722
|
+
let filesProcessed = 0;
|
|
723
|
+
// Pre-build a suffix index for O(1) suffix lookups instead of O(n) linear scans
|
|
724
|
+
const suffixIndex = new Map();
|
|
725
|
+
for (let i = 0; i < normalizedFileList.length; i++) {
|
|
726
|
+
const normalized = normalizedFileList[i];
|
|
727
|
+
// Index by last path segment (filename) for fast suffix matching
|
|
728
|
+
const lastSlash = normalized.lastIndexOf('/');
|
|
729
|
+
const filename = lastSlash >= 0 ? normalized.substring(lastSlash + 1) : normalized;
|
|
730
|
+
let list = suffixIndex.get(filename);
|
|
731
|
+
if (!list) {
|
|
732
|
+
list = [];
|
|
733
|
+
suffixIndex.set(filename, list);
|
|
734
|
+
}
|
|
735
|
+
list.push(allFileList[i]);
|
|
736
|
+
}
|
|
737
|
+
for (const [filePath, fileImports] of importsByFile) {
|
|
738
|
+
filesProcessed++;
|
|
739
|
+
if (filesProcessed % 100 === 0) {
|
|
740
|
+
onProgress?.(filesProcessed, totalFiles);
|
|
741
|
+
await yieldToEventLoop();
|
|
742
|
+
}
|
|
743
|
+
for (const { rawImportPath, language } of fileImports) {
|
|
744
|
+
totalImportsFound++;
|
|
745
|
+
// Check resolve cache first
|
|
746
|
+
const cacheKey = `${filePath}::${rawImportPath}`;
|
|
747
|
+
if (resolveCache.has(cacheKey)) {
|
|
748
|
+
const cached = resolveCache.get(cacheKey);
|
|
749
|
+
if (cached)
|
|
750
|
+
addImportEdge(filePath, cached);
|
|
751
|
+
continue;
|
|
752
|
+
}
|
|
753
|
+
// Java: handle wildcards and static imports
|
|
754
|
+
if (language === SupportedLanguages.Java) {
|
|
755
|
+
if (rawImportPath.endsWith('.*')) {
|
|
756
|
+
const matchedFiles = resolveJavaWildcard(rawImportPath, normalizedFileList, allFileList, index);
|
|
757
|
+
for (const matchedFile of matchedFiles) {
|
|
758
|
+
addImportEdge(filePath, matchedFile);
|
|
759
|
+
}
|
|
760
|
+
continue;
|
|
761
|
+
}
|
|
762
|
+
const staticResolved = resolveJavaStaticImport(rawImportPath, normalizedFileList, allFileList, index);
|
|
763
|
+
if (staticResolved) {
|
|
764
|
+
resolveCache.set(cacheKey, staticResolved);
|
|
765
|
+
addImportEdge(filePath, staticResolved);
|
|
766
|
+
continue;
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
// Go: handle package-level imports
|
|
770
|
+
if (language === SupportedLanguages.Go && goModule && rawImportPath.startsWith(goModule.modulePath)) {
|
|
771
|
+
const pkgFiles = resolveGoPackage(rawImportPath, goModule, normalizedFileList, allFileList);
|
|
772
|
+
if (pkgFiles.length > 0) {
|
|
773
|
+
for (const pkgFile of pkgFiles) {
|
|
774
|
+
addImportEdge(filePath, pkgFile);
|
|
775
|
+
}
|
|
776
|
+
continue;
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
// Standard resolution (has its own internal cache)
|
|
780
|
+
const resolvedPath = resolveImportPath(filePath, rawImportPath, allFilePaths, allFileList, normalizedFileList, resolveCache, language, tsconfigPaths, index, solidityRemappings);
|
|
781
|
+
if (resolvedPath) {
|
|
782
|
+
addImportEdge(filePath, resolvedPath);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
onProgress?.(totalFiles, totalFiles);
|
|
787
|
+
if (isDev) {
|
|
788
|
+
console.log(`📊 Import processing (fast path): ${totalImportsResolved}/${totalImportsFound} imports resolved to graph edges`);
|
|
789
|
+
}
|
|
790
|
+
};
|
|
791
|
+
//# sourceMappingURL=import-processor.js.map
|