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,792 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* KeypressContext — raw stdin keypress parser and event system.
|
|
4
|
+
*
|
|
5
|
+
* Bypasses Ink's useInput entirely and parses raw stdin data using a generator
|
|
6
|
+
* (emitKeys), identical to the approach in the CLI reference implementation.
|
|
7
|
+
*
|
|
8
|
+
* Data flow:
|
|
9
|
+
* stdin.on('data')
|
|
10
|
+
* → createDataListener (buffers chars, drives emitKeys generator)
|
|
11
|
+
* → emitKeys* (ANSI escape sequence parser → Key objects)
|
|
12
|
+
* → bufferPaste (bracketed paste → single 'paste' event)
|
|
13
|
+
* → bufferBackslashEnter (backslash+return → shift+return)
|
|
14
|
+
* → [optional] bufferFastReturn (quick returns → newline in non-Kitty mode)
|
|
15
|
+
* → nonKeyboardEventFilter (drop mouse / focus events)
|
|
16
|
+
* → broadcast (priority-ordered handlers)
|
|
17
|
+
*/
|
|
18
|
+
import { useStdin } from 'ink';
|
|
19
|
+
import { createContext, useCallback, useContext, useEffect, useRef, } from 'react';
|
|
20
|
+
// ── Constants ──────────────────────────────────────────
|
|
21
|
+
const ESC = '\u001B';
|
|
22
|
+
export const BACKSLASH_ENTER_TIMEOUT = 5;
|
|
23
|
+
export const ESC_TIMEOUT = 50;
|
|
24
|
+
export const PASTE_TIMEOUT = 30_000;
|
|
25
|
+
export const FAST_RETURN_TIMEOUT = 30;
|
|
26
|
+
// ── Priority enum ──────────────────────────────────────
|
|
27
|
+
export var KeypressPriority;
|
|
28
|
+
(function (KeypressPriority) {
|
|
29
|
+
KeypressPriority[KeypressPriority["Low"] = -100] = "Low";
|
|
30
|
+
KeypressPriority[KeypressPriority["Normal"] = 0] = "Normal";
|
|
31
|
+
KeypressPriority[KeypressPriority["High"] = 100] = "High";
|
|
32
|
+
KeypressPriority[KeypressPriority["Critical"] = 200] = "Critical";
|
|
33
|
+
})(KeypressPriority || (KeypressPriority = {}));
|
|
34
|
+
// ── KEY_INFO_MAP ───────────────────────────────────────
|
|
35
|
+
const KEY_INFO_MAP = {
|
|
36
|
+
'[200~': { name: 'paste-start' },
|
|
37
|
+
'[201~': { name: 'paste-end' },
|
|
38
|
+
'[[A': { name: 'f1' },
|
|
39
|
+
'[[B': { name: 'f2' },
|
|
40
|
+
'[[C': { name: 'f3' },
|
|
41
|
+
'[[D': { name: 'f4' },
|
|
42
|
+
'[[E': { name: 'f5' },
|
|
43
|
+
'[1~': { name: 'home' },
|
|
44
|
+
'[2~': { name: 'insert' },
|
|
45
|
+
'[3~': { name: 'delete' },
|
|
46
|
+
'[4~': { name: 'end' },
|
|
47
|
+
'[5~': { name: 'pageup' },
|
|
48
|
+
'[6~': { name: 'pagedown' },
|
|
49
|
+
'[7~': { name: 'home' },
|
|
50
|
+
'[8~': { name: 'end' },
|
|
51
|
+
'[11~': { name: 'f1' },
|
|
52
|
+
'[12~': { name: 'f2' },
|
|
53
|
+
'[13~': { name: 'f3' },
|
|
54
|
+
'[14~': { name: 'f4' },
|
|
55
|
+
'[15~': { name: 'f5' },
|
|
56
|
+
'[17~': { name: 'f6' },
|
|
57
|
+
'[18~': { name: 'f7' },
|
|
58
|
+
'[19~': { name: 'f8' },
|
|
59
|
+
'[20~': { name: 'f9' },
|
|
60
|
+
'[21~': { name: 'f10' },
|
|
61
|
+
'[23~': { name: 'f11' },
|
|
62
|
+
'[24~': { name: 'f12' },
|
|
63
|
+
'[A': { name: 'up' },
|
|
64
|
+
'[B': { name: 'down' },
|
|
65
|
+
'[C': { name: 'right' },
|
|
66
|
+
'[D': { name: 'left' },
|
|
67
|
+
'[E': { name: 'clear' },
|
|
68
|
+
'[F': { name: 'end' },
|
|
69
|
+
'[H': { name: 'home' },
|
|
70
|
+
'[P': { name: 'f1' },
|
|
71
|
+
'[Q': { name: 'f2' },
|
|
72
|
+
'[R': { name: 'f3' },
|
|
73
|
+
'[S': { name: 'f4' },
|
|
74
|
+
OA: { name: 'up' },
|
|
75
|
+
OB: { name: 'down' },
|
|
76
|
+
OC: { name: 'right' },
|
|
77
|
+
OD: { name: 'left' },
|
|
78
|
+
OE: { name: 'clear' },
|
|
79
|
+
OF: { name: 'end' },
|
|
80
|
+
OH: { name: 'home' },
|
|
81
|
+
OP: { name: 'f1' },
|
|
82
|
+
OQ: { name: 'f2' },
|
|
83
|
+
OR: { name: 'f3' },
|
|
84
|
+
OS: { name: 'f4' },
|
|
85
|
+
OZ: { name: 'tab', shift: true },
|
|
86
|
+
'[[5~': { name: 'pageup' },
|
|
87
|
+
'[[6~': { name: 'pagedown' },
|
|
88
|
+
'[9u': { name: 'tab' },
|
|
89
|
+
'[13u': { name: 'return' },
|
|
90
|
+
'[27u': { name: 'escape' },
|
|
91
|
+
'[32u': { name: 'space' },
|
|
92
|
+
'[127u': { name: 'backspace' },
|
|
93
|
+
'[57414u': { name: 'return' }, // Numpad Enter
|
|
94
|
+
'[a': { name: 'up', shift: true },
|
|
95
|
+
'[b': { name: 'down', shift: true },
|
|
96
|
+
'[c': { name: 'right', shift: true },
|
|
97
|
+
'[d': { name: 'left', shift: true },
|
|
98
|
+
'[e': { name: 'clear', shift: true },
|
|
99
|
+
'[2$': { name: 'insert', shift: true },
|
|
100
|
+
'[3$': { name: 'delete', shift: true },
|
|
101
|
+
'[5$': { name: 'pageup', shift: true },
|
|
102
|
+
'[6$': { name: 'pagedown', shift: true },
|
|
103
|
+
'[7$': { name: 'home', shift: true },
|
|
104
|
+
'[8$': { name: 'end', shift: true },
|
|
105
|
+
'[Z': { name: 'tab', shift: true },
|
|
106
|
+
Oa: { name: 'up', ctrl: true },
|
|
107
|
+
Ob: { name: 'down', ctrl: true },
|
|
108
|
+
Oc: { name: 'right', ctrl: true },
|
|
109
|
+
Od: { name: 'left', ctrl: true },
|
|
110
|
+
Oe: { name: 'clear', ctrl: true },
|
|
111
|
+
'[2^': { name: 'insert', ctrl: true },
|
|
112
|
+
'[3^': { name: 'delete', ctrl: true },
|
|
113
|
+
'[5^': { name: 'pageup', ctrl: true },
|
|
114
|
+
'[6^': { name: 'pagedown', ctrl: true },
|
|
115
|
+
'[7^': { name: 'home', ctrl: true },
|
|
116
|
+
'[8^': { name: 'end', ctrl: true },
|
|
117
|
+
};
|
|
118
|
+
const NUMPAD_MAP = {
|
|
119
|
+
Oj: '*', Ok: '+', Om: '-', Oo: '/',
|
|
120
|
+
Op: '0', Oq: '1', Or: '2', Os: '3', Ot: '4',
|
|
121
|
+
Ou: '5', Ov: '6', Ow: '7', Ox: '8', Oy: '9',
|
|
122
|
+
On: '.',
|
|
123
|
+
};
|
|
124
|
+
const MAC_ALT_KEY_CHARACTER_MAP = {
|
|
125
|
+
'\u222B': 'b', // "∫" back one word
|
|
126
|
+
'\u0192': 'f', // "ƒ" forward one word
|
|
127
|
+
'\u00B5': 'm', // "µ"
|
|
128
|
+
'\u03A9': 'z', // "Ω" Option+z
|
|
129
|
+
'\u00B8': 'Z', // "¸" Option+Shift+z
|
|
130
|
+
'\u2202': 'd', // "∂" delete word forward
|
|
131
|
+
};
|
|
132
|
+
// ── Helpers ────────────────────────────────────────────
|
|
133
|
+
const kUTF16SurrogateThreshold = 0x10000;
|
|
134
|
+
function charLengthAt(str, i) {
|
|
135
|
+
if (str.length <= i)
|
|
136
|
+
return 1;
|
|
137
|
+
const code = str.codePointAt(i);
|
|
138
|
+
return code !== undefined && code >= kUTF16SurrogateThreshold ? 2 : 1;
|
|
139
|
+
}
|
|
140
|
+
// ── SGR / X11 mouse sequence detection ─────────────────
|
|
141
|
+
const SGR_MOUSE_REGEX = /^\x1b\[<(\d+);(\d+);(\d+)([mM])/;
|
|
142
|
+
const X11_MOUSE_REGEX = /^\x1b\[M([\s\S]{3})/;
|
|
143
|
+
const FOCUS_IN = `${ESC}[I`;
|
|
144
|
+
const FOCUS_OUT = `${ESC}[O`;
|
|
145
|
+
function isMouseSequence(seq) {
|
|
146
|
+
return SGR_MOUSE_REGEX.test(seq) || X11_MOUSE_REGEX.test(seq);
|
|
147
|
+
}
|
|
148
|
+
// ── Filter pipeline ────────────────────────────────────
|
|
149
|
+
function nonKeyboardEventFilter(keypressHandler) {
|
|
150
|
+
return (key) => {
|
|
151
|
+
if (!isMouseSequence(key.sequence) && key.sequence !== FOCUS_IN && key.sequence !== FOCUS_OUT) {
|
|
152
|
+
return keypressHandler(key);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function bufferFastReturn(keypressHandler) {
|
|
157
|
+
let lastKeyTime = 0;
|
|
158
|
+
return (key) => {
|
|
159
|
+
const now = Date.now();
|
|
160
|
+
if (key.name === 'return' && now - lastKeyTime <= FAST_RETURN_TIMEOUT) {
|
|
161
|
+
return keypressHandler({
|
|
162
|
+
...key,
|
|
163
|
+
name: 'return',
|
|
164
|
+
shift: true,
|
|
165
|
+
alt: false,
|
|
166
|
+
ctrl: false,
|
|
167
|
+
cmd: false,
|
|
168
|
+
sequence: '\r',
|
|
169
|
+
insertable: true,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
const result = keypressHandler(key);
|
|
174
|
+
lastKeyTime = now;
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function bufferBackslashEnter(keypressHandler) {
|
|
180
|
+
const bufferer = (function* () {
|
|
181
|
+
while (true) {
|
|
182
|
+
const key = yield;
|
|
183
|
+
if (key == null)
|
|
184
|
+
continue;
|
|
185
|
+
if (key.sequence !== '\\') {
|
|
186
|
+
keypressHandler(key);
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
const timeoutId = setTimeout(() => bufferer.next(null), BACKSLASH_ENTER_TIMEOUT);
|
|
190
|
+
const nextKey = yield;
|
|
191
|
+
clearTimeout(timeoutId);
|
|
192
|
+
if (nextKey === null) {
|
|
193
|
+
keypressHandler(key);
|
|
194
|
+
}
|
|
195
|
+
else if (nextKey.name === 'return') {
|
|
196
|
+
keypressHandler({ ...nextKey, shift: true, sequence: '\r' });
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
keypressHandler(key);
|
|
200
|
+
keypressHandler(nextKey);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
})();
|
|
204
|
+
bufferer.next();
|
|
205
|
+
return (key) => { bufferer.next(key); };
|
|
206
|
+
}
|
|
207
|
+
function bufferPaste(keypressHandler) {
|
|
208
|
+
const bufferer = (function* () {
|
|
209
|
+
while (true) {
|
|
210
|
+
let key = yield;
|
|
211
|
+
if (key === null)
|
|
212
|
+
continue;
|
|
213
|
+
if (key.name !== 'paste-start') {
|
|
214
|
+
keypressHandler(key);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
// Collect paste content. Note: createDataListener already extracts
|
|
218
|
+
// bracketed paste at the string level, so this loop is only a fallback
|
|
219
|
+
// for edge cases (e.g. OSC 52 paste or generator-based paste-start).
|
|
220
|
+
// Use a single timeout for the entire paste, not per character.
|
|
221
|
+
let buffer = '';
|
|
222
|
+
const timeoutId = setTimeout(() => bufferer.next(null), PASTE_TIMEOUT);
|
|
223
|
+
while (true) {
|
|
224
|
+
key = yield;
|
|
225
|
+
if (key === null)
|
|
226
|
+
break;
|
|
227
|
+
if (key.name === 'paste-end')
|
|
228
|
+
break;
|
|
229
|
+
buffer += key.sequence;
|
|
230
|
+
}
|
|
231
|
+
clearTimeout(timeoutId);
|
|
232
|
+
if (buffer.length > 0) {
|
|
233
|
+
keypressHandler({
|
|
234
|
+
name: 'paste',
|
|
235
|
+
shift: false, alt: false, ctrl: false, cmd: false,
|
|
236
|
+
insertable: true,
|
|
237
|
+
sequence: buffer,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
})();
|
|
242
|
+
bufferer.next();
|
|
243
|
+
return (key) => { bufferer.next(key); };
|
|
244
|
+
}
|
|
245
|
+
// ── emitKeys generator ─────────────────────────────────
|
|
246
|
+
// Bracketed paste markers (byte-level constants for raw Buffer matching)
|
|
247
|
+
const PASTE_START_BUF = Buffer.from('\x1b[200~');
|
|
248
|
+
const PASTE_END_BUF = Buffer.from('\x1b[201~');
|
|
249
|
+
// Threshold for synthetic paste detection (no bracketed paste markers)
|
|
250
|
+
const SYNTHETIC_PASTE_THRESHOLD = 20;
|
|
251
|
+
/**
|
|
252
|
+
* Creates the stdin data listener that operates on **raw Buffers**.
|
|
253
|
+
*
|
|
254
|
+
* Ink's setRawMode calls stdin.setEncoding('utf8'), which installs a
|
|
255
|
+
* StringDecoder that permanently corrupts ANSI escape sequences at multi-byte
|
|
256
|
+
* UTF-8 chunk boundaries (e.g. PASTE_END \x1b[201~ gets destroyed when \x1b
|
|
257
|
+
* is merged with preceding incomplete CJK bytes → U+FFFD).
|
|
258
|
+
*
|
|
259
|
+
* We patch stdin.setEncoding to a no-op before setRawMode, so stdin delivers
|
|
260
|
+
* raw Buffers. We then find paste markers at the byte level before decoding
|
|
261
|
+
* to UTF-8, which avoids the corruption entirely.
|
|
262
|
+
*/
|
|
263
|
+
function createDataListener(keypressHandler) {
|
|
264
|
+
const parser = emitKeys(keypressHandler);
|
|
265
|
+
parser.next();
|
|
266
|
+
let timeoutId;
|
|
267
|
+
// When a bracketed paste spans multiple data chunks, we accumulate raw bytes.
|
|
268
|
+
let pasteAccumulator = null;
|
|
269
|
+
let pasteTimeoutId;
|
|
270
|
+
const emitPaste = (content) => {
|
|
271
|
+
const str = content.toString('utf8');
|
|
272
|
+
if (str.length > 0) {
|
|
273
|
+
keypressHandler({
|
|
274
|
+
name: 'paste',
|
|
275
|
+
shift: false, alt: false, ctrl: false, cmd: false,
|
|
276
|
+
insertable: true,
|
|
277
|
+
sequence: str,
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
/** Feed a string through the emitKeys generator character by character. */
|
|
282
|
+
const feedParser = (str) => {
|
|
283
|
+
for (const char of str) {
|
|
284
|
+
parser.next(char);
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
/** Flush the paste accumulator, stripping any trailing partial PASTE_END bytes. */
|
|
288
|
+
const flushAccumulator = () => {
|
|
289
|
+
if (pasteAccumulator === null)
|
|
290
|
+
return;
|
|
291
|
+
const content = Buffer.concat(pasteAccumulator);
|
|
292
|
+
pasteAccumulator = null;
|
|
293
|
+
const trimmed = stripTrailingPartialMarker(content, PASTE_END_BUF);
|
|
294
|
+
emitPaste(trimmed);
|
|
295
|
+
};
|
|
296
|
+
/**
|
|
297
|
+
* Search for PASTE_END_BUF in a combined buffer that spans the junction of
|
|
298
|
+
* prevTail (last N bytes of previous accumulator chunk) and newBuf.
|
|
299
|
+
*
|
|
300
|
+
* Returns:
|
|
301
|
+
* { found: true, prevKeep: number, newSkip: number }
|
|
302
|
+
* — prevKeep: how many bytes of prevTail to keep (before the marker)
|
|
303
|
+
* — newSkip: how many bytes into newBuf the marker ends
|
|
304
|
+
* { found: false } — no cross-boundary match
|
|
305
|
+
*/
|
|
306
|
+
const findCrossBoundaryEnd = (prevTail, newBuf) => {
|
|
307
|
+
const marker = PASTE_END_BUF;
|
|
308
|
+
// The marker could start at any offset within prevTail, as long as part
|
|
309
|
+
// of it falls in newBuf. Check each possible split point.
|
|
310
|
+
for (let splitAt = 1; splitAt < marker.length; splitAt++) {
|
|
311
|
+
// splitAt bytes of the marker are at the end of prevTail,
|
|
312
|
+
// (marker.length - splitAt) bytes are at the start of newBuf.
|
|
313
|
+
const tailPortion = marker.subarray(0, splitAt);
|
|
314
|
+
const headPortion = marker.subarray(splitAt);
|
|
315
|
+
if (prevTail.length < splitAt)
|
|
316
|
+
continue;
|
|
317
|
+
if (newBuf.length < headPortion.length)
|
|
318
|
+
continue;
|
|
319
|
+
const tailMatch = prevTail
|
|
320
|
+
.subarray(prevTail.length - splitAt)
|
|
321
|
+
.equals(tailPortion);
|
|
322
|
+
const headMatch = newBuf
|
|
323
|
+
.subarray(0, headPortion.length)
|
|
324
|
+
.equals(headPortion);
|
|
325
|
+
if (tailMatch && headMatch) {
|
|
326
|
+
return {
|
|
327
|
+
found: true,
|
|
328
|
+
prevKeep: prevTail.length - splitAt,
|
|
329
|
+
newSkip: headPortion.length,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return { found: false };
|
|
334
|
+
};
|
|
335
|
+
return (data) => {
|
|
336
|
+
const buf = Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
337
|
+
clearTimeout(timeoutId);
|
|
338
|
+
// ── Fast path: currently accumulating a multi-chunk bracketed paste ──
|
|
339
|
+
if (pasteAccumulator !== null) {
|
|
340
|
+
clearTimeout(pasteTimeoutId);
|
|
341
|
+
// First: check if PASTE_END spans the boundary between previous chunk
|
|
342
|
+
// tail and the start of this new chunk.
|
|
343
|
+
const lastChunk = pasteAccumulator[pasteAccumulator.length - 1];
|
|
344
|
+
const tailLen = Math.min(lastChunk.length, PASTE_END_BUF.length - 1);
|
|
345
|
+
const prevTail = lastChunk.subarray(lastChunk.length - tailLen);
|
|
346
|
+
const crossResult = findCrossBoundaryEnd(prevTail, buf);
|
|
347
|
+
if (crossResult.found) {
|
|
348
|
+
if (crossResult.prevKeep < tailLen) {
|
|
349
|
+
const trimmed = lastChunk.subarray(0, lastChunk.length - tailLen + crossResult.prevKeep);
|
|
350
|
+
pasteAccumulator[pasteAccumulator.length - 1] = trimmed;
|
|
351
|
+
}
|
|
352
|
+
// Emit the accumulated paste content
|
|
353
|
+
const content = Buffer.concat(pasteAccumulator);
|
|
354
|
+
pasteAccumulator = null;
|
|
355
|
+
emitPaste(content);
|
|
356
|
+
// Process anything after the marker in this chunk
|
|
357
|
+
const remainder = buf.subarray(crossResult.newSkip);
|
|
358
|
+
if (remainder.length > 0) {
|
|
359
|
+
feedParser(remainder.toString('utf8'));
|
|
360
|
+
timeoutId = setTimeout(() => parser.next(''), ESC_TIMEOUT);
|
|
361
|
+
}
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
// Check for full PASTE_END within this chunk
|
|
365
|
+
const endIdx = buf.indexOf(PASTE_END_BUF);
|
|
366
|
+
if (endIdx !== -1) {
|
|
367
|
+
if (endIdx > 0)
|
|
368
|
+
pasteAccumulator.push(buf.subarray(0, endIdx));
|
|
369
|
+
const content = Buffer.concat(pasteAccumulator);
|
|
370
|
+
pasteAccumulator = null;
|
|
371
|
+
emitPaste(content);
|
|
372
|
+
// Process anything after the paste-end marker
|
|
373
|
+
const remainder = buf.subarray(endIdx + PASTE_END_BUF.length);
|
|
374
|
+
if (remainder.length > 0) {
|
|
375
|
+
feedParser(remainder.toString('utf8'));
|
|
376
|
+
timeoutId = setTimeout(() => parser.next(''), ESC_TIMEOUT);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
pasteAccumulator.push(Buffer.from(buf));
|
|
381
|
+
pasteTimeoutId = setTimeout(flushAccumulator, PASTE_TIMEOUT);
|
|
382
|
+
}
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
// ── Check for bracketed paste start in this chunk ──
|
|
386
|
+
const startIdx = buf.indexOf(PASTE_START_BUF);
|
|
387
|
+
if (startIdx !== -1) {
|
|
388
|
+
// Process any data before the paste-start marker normally
|
|
389
|
+
if (startIdx > 0) {
|
|
390
|
+
feedParser(buf.subarray(0, startIdx).toString('utf8'));
|
|
391
|
+
}
|
|
392
|
+
const afterStart = buf.subarray(startIdx + PASTE_START_BUF.length);
|
|
393
|
+
const endIdx = afterStart.indexOf(PASTE_END_BUF);
|
|
394
|
+
if (endIdx !== -1) {
|
|
395
|
+
emitPaste(afterStart.subarray(0, endIdx));
|
|
396
|
+
// Process anything after paste-end
|
|
397
|
+
const remainder = afterStart.subarray(endIdx + PASTE_END_BUF.length);
|
|
398
|
+
if (remainder.length > 0) {
|
|
399
|
+
feedParser(remainder.toString('utf8'));
|
|
400
|
+
timeoutId = setTimeout(() => parser.next(''), ESC_TIMEOUT);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
pasteAccumulator = [Buffer.from(afterStart)];
|
|
405
|
+
pasteTimeoutId = setTimeout(flushAccumulator, PASTE_TIMEOUT);
|
|
406
|
+
}
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
// ── Decode to string for non-paste paths ──
|
|
410
|
+
const str = buf.toString('utf8');
|
|
411
|
+
// ── Synthetic paste detection (no bracketed paste markers) ──
|
|
412
|
+
if (str.length >= SYNTHETIC_PASTE_THRESHOLD) {
|
|
413
|
+
const escapeCount = (str.match(/\x1b/g) || []).length;
|
|
414
|
+
const printableRatio = 1 - (escapeCount / str.length);
|
|
415
|
+
if (printableRatio > 0.8) {
|
|
416
|
+
const cleaned = str.replace(/\x1b(?:\[[0-9;?]*[a-zA-Z~]|.)/g, '');
|
|
417
|
+
if (cleaned.length > 0) {
|
|
418
|
+
emitPaste(Buffer.from(cleaned, 'utf8'));
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
// ── Normal path: feed through emitKeys generator ──
|
|
424
|
+
feedParser(str);
|
|
425
|
+
if (str.length !== 0) {
|
|
426
|
+
timeoutId = setTimeout(() => parser.next(''), ESC_TIMEOUT);
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Strip any trailing bytes that are a prefix of the given marker.
|
|
432
|
+
* Used when flush-by-timeout fires and the tail might hold a partial PASTE_END.
|
|
433
|
+
*/
|
|
434
|
+
function stripTrailingPartialMarker(buf, marker) {
|
|
435
|
+
// Check for partial marker at the tail: from longest possible prefix down to 1 byte.
|
|
436
|
+
for (let len = marker.length - 1; len >= 1; len--) {
|
|
437
|
+
if (buf.length < len)
|
|
438
|
+
continue;
|
|
439
|
+
if (buf.subarray(buf.length - len).equals(marker.subarray(0, len))) {
|
|
440
|
+
return buf.subarray(0, buf.length - len);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
return buf;
|
|
444
|
+
}
|
|
445
|
+
function* emitKeys(keypressHandler) {
|
|
446
|
+
const lang = process.env['LANG'] || '';
|
|
447
|
+
const lcAll = process.env['LC_ALL'] || '';
|
|
448
|
+
const isGreek = lang.startsWith('el') || lcAll.startsWith('el');
|
|
449
|
+
while (true) {
|
|
450
|
+
let ch = yield;
|
|
451
|
+
let sequence = ch;
|
|
452
|
+
let escaped = false;
|
|
453
|
+
let name = undefined;
|
|
454
|
+
let shift = false;
|
|
455
|
+
let alt = false;
|
|
456
|
+
let ctrl = false;
|
|
457
|
+
let cmd = false;
|
|
458
|
+
let code = undefined;
|
|
459
|
+
let insertable = false;
|
|
460
|
+
if (ch === ESC) {
|
|
461
|
+
escaped = true;
|
|
462
|
+
ch = yield;
|
|
463
|
+
sequence += ch;
|
|
464
|
+
if (ch === ESC) {
|
|
465
|
+
ch = yield;
|
|
466
|
+
sequence += ch;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
if (escaped && (ch === 'O' || ch === '[' || ch === ']')) {
|
|
470
|
+
code = ch;
|
|
471
|
+
let modifier = 0;
|
|
472
|
+
if (ch === ']') {
|
|
473
|
+
// OSC sequence
|
|
474
|
+
let buffer = '';
|
|
475
|
+
while (true) {
|
|
476
|
+
const next = yield;
|
|
477
|
+
if (next === '' || next === '\u0007')
|
|
478
|
+
break;
|
|
479
|
+
if (next === ESC) {
|
|
480
|
+
const afterEsc = yield;
|
|
481
|
+
if (afterEsc === '' || afterEsc === '\\')
|
|
482
|
+
break;
|
|
483
|
+
buffer += next + afterEsc;
|
|
484
|
+
continue;
|
|
485
|
+
}
|
|
486
|
+
buffer += next;
|
|
487
|
+
}
|
|
488
|
+
// Check for OSC 52 (clipboard)
|
|
489
|
+
const match = /^52;[cp];(.*)$/.exec(buffer);
|
|
490
|
+
if (match) {
|
|
491
|
+
try {
|
|
492
|
+
const decoded = Buffer.from(match[1], 'base64').toString('utf-8');
|
|
493
|
+
keypressHandler({
|
|
494
|
+
name: 'paste', shift: false, alt: false, ctrl: false, cmd: false,
|
|
495
|
+
insertable: true, sequence: decoded,
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
catch { /* ignore */ }
|
|
499
|
+
}
|
|
500
|
+
continue;
|
|
501
|
+
}
|
|
502
|
+
else if (ch === 'O') {
|
|
503
|
+
ch = yield;
|
|
504
|
+
sequence += ch;
|
|
505
|
+
if (ch >= '0' && ch <= '9') {
|
|
506
|
+
modifier = parseInt(ch, 10) - 1;
|
|
507
|
+
ch = yield;
|
|
508
|
+
sequence += ch;
|
|
509
|
+
}
|
|
510
|
+
code += ch;
|
|
511
|
+
}
|
|
512
|
+
else if (ch === '[') {
|
|
513
|
+
ch = yield;
|
|
514
|
+
sequence += ch;
|
|
515
|
+
if (ch === '[') {
|
|
516
|
+
code += ch;
|
|
517
|
+
ch = yield;
|
|
518
|
+
sequence += ch;
|
|
519
|
+
}
|
|
520
|
+
const cmdStart = sequence.length - 1;
|
|
521
|
+
while (ch >= '0' && ch <= '9') {
|
|
522
|
+
ch = yield;
|
|
523
|
+
sequence += ch;
|
|
524
|
+
}
|
|
525
|
+
if (ch === ';') {
|
|
526
|
+
while (ch === ';') {
|
|
527
|
+
ch = yield;
|
|
528
|
+
sequence += ch;
|
|
529
|
+
while (ch >= '0' && ch <= '9') {
|
|
530
|
+
ch = yield;
|
|
531
|
+
sequence += ch;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
else if (ch === '<') {
|
|
536
|
+
// SGR mouse mode
|
|
537
|
+
ch = yield;
|
|
538
|
+
sequence += ch;
|
|
539
|
+
while (ch === '' || ch === ';' || (ch >= '0' && ch <= '9')) {
|
|
540
|
+
ch = yield;
|
|
541
|
+
sequence += ch;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
else if (ch === 'M') {
|
|
545
|
+
// X11 mouse
|
|
546
|
+
ch = yield;
|
|
547
|
+
sequence += ch;
|
|
548
|
+
ch = yield;
|
|
549
|
+
sequence += ch;
|
|
550
|
+
ch = yield;
|
|
551
|
+
sequence += ch;
|
|
552
|
+
}
|
|
553
|
+
const cmd = sequence.slice(cmdStart);
|
|
554
|
+
let match;
|
|
555
|
+
if ((match = /^(\d+)(?:;(\d+))?(?:;(\d+))?([~^$u])$/.exec(cmd))) {
|
|
556
|
+
if (match[1] === '27' && match[3] && match[4] === '~') {
|
|
557
|
+
code += match[3] + 'u';
|
|
558
|
+
modifier = parseInt(match[2] ?? '1', 10) - 1;
|
|
559
|
+
}
|
|
560
|
+
else {
|
|
561
|
+
code += match[1] + match[4];
|
|
562
|
+
modifier = parseInt(match[2] ?? '1', 10) - 1;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
else if ((match = /^(\d+)?(?:;(\d+))?([A-Za-z])$/.exec(cmd))) {
|
|
566
|
+
code += match[3];
|
|
567
|
+
modifier = parseInt(match[2] ?? match[1] ?? '1', 10) - 1;
|
|
568
|
+
}
|
|
569
|
+
else {
|
|
570
|
+
code += cmd;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
shift = !!(modifier & 1);
|
|
574
|
+
alt = !!(modifier & 2);
|
|
575
|
+
ctrl = !!(modifier & 4);
|
|
576
|
+
cmd = !!(modifier & 8);
|
|
577
|
+
const keyInfo = KEY_INFO_MAP[code];
|
|
578
|
+
if (keyInfo) {
|
|
579
|
+
name = keyInfo.name;
|
|
580
|
+
if (keyInfo.shift)
|
|
581
|
+
shift = true;
|
|
582
|
+
if (keyInfo.ctrl)
|
|
583
|
+
ctrl = true;
|
|
584
|
+
if (name === 'space' && !ctrl && !cmd && !alt) {
|
|
585
|
+
sequence = ' ';
|
|
586
|
+
insertable = true;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
590
|
+
const numpadChar = NUMPAD_MAP[code];
|
|
591
|
+
if (numpadChar) {
|
|
592
|
+
name = numpadChar;
|
|
593
|
+
if (!ctrl && !cmd && !alt) {
|
|
594
|
+
sequence = numpadChar;
|
|
595
|
+
insertable = true;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
else {
|
|
599
|
+
name = 'undefined';
|
|
600
|
+
if ((ctrl || cmd || alt) && (code.endsWith('u') || code.endsWith('~'))) {
|
|
601
|
+
const codeNumber = parseInt(code.slice(1, -1), 10);
|
|
602
|
+
if (codeNumber >= 'a'.charCodeAt(0) && codeNumber <= 'z'.charCodeAt(0)) {
|
|
603
|
+
name = String.fromCharCode(codeNumber);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
else if (ch === '\r') {
|
|
610
|
+
name = 'return';
|
|
611
|
+
alt = escaped;
|
|
612
|
+
}
|
|
613
|
+
else if (escaped && ch === '\n') {
|
|
614
|
+
name = 'return';
|
|
615
|
+
alt = escaped;
|
|
616
|
+
}
|
|
617
|
+
else if (ch === '\t') {
|
|
618
|
+
name = 'tab';
|
|
619
|
+
alt = escaped;
|
|
620
|
+
}
|
|
621
|
+
else if (ch === '\b' || ch === '\x7f') {
|
|
622
|
+
name = 'backspace';
|
|
623
|
+
alt = escaped;
|
|
624
|
+
}
|
|
625
|
+
else if (ch === ESC) {
|
|
626
|
+
name = 'escape';
|
|
627
|
+
alt = escaped;
|
|
628
|
+
}
|
|
629
|
+
else if (ch === ' ') {
|
|
630
|
+
name = 'space';
|
|
631
|
+
alt = escaped;
|
|
632
|
+
insertable = true;
|
|
633
|
+
}
|
|
634
|
+
else if (!escaped && ch <= '\x1a') {
|
|
635
|
+
name = String.fromCharCode(ch.charCodeAt(0) + 'a'.charCodeAt(0) - 1);
|
|
636
|
+
ctrl = true;
|
|
637
|
+
}
|
|
638
|
+
else if (/^[0-9A-Za-z]$/.exec(ch) !== null) {
|
|
639
|
+
name = ch.toLowerCase();
|
|
640
|
+
shift = /^[A-Z]$/.exec(ch) !== null;
|
|
641
|
+
alt = escaped;
|
|
642
|
+
insertable = true;
|
|
643
|
+
}
|
|
644
|
+
else if (MAC_ALT_KEY_CHARACTER_MAP[ch]) {
|
|
645
|
+
if (isGreek && ch === '\u03A9') {
|
|
646
|
+
insertable = true;
|
|
647
|
+
}
|
|
648
|
+
else {
|
|
649
|
+
const mapped = MAC_ALT_KEY_CHARACTER_MAP[ch];
|
|
650
|
+
name = mapped.toLowerCase();
|
|
651
|
+
shift = mapped !== name;
|
|
652
|
+
alt = true;
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
else if (sequence === `${ESC}${ESC}`) {
|
|
656
|
+
name = 'escape';
|
|
657
|
+
alt = true;
|
|
658
|
+
keypressHandler({
|
|
659
|
+
name: 'escape', shift, alt, ctrl, cmd, insertable: false, sequence: ESC,
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
else if (escaped) {
|
|
663
|
+
name = ch.length ? undefined : 'escape';
|
|
664
|
+
alt = true;
|
|
665
|
+
}
|
|
666
|
+
else {
|
|
667
|
+
insertable = true;
|
|
668
|
+
}
|
|
669
|
+
if ((sequence.length !== 0 && (name !== undefined || escaped)) ||
|
|
670
|
+
charLengthAt(sequence, 0) === sequence.length) {
|
|
671
|
+
keypressHandler({
|
|
672
|
+
name: name || '',
|
|
673
|
+
shift, alt, ctrl, cmd, insertable, sequence,
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
const KeypressContext = createContext(undefined);
|
|
679
|
+
export function useKeypressContext() {
|
|
680
|
+
const context = useContext(KeypressContext);
|
|
681
|
+
if (!context) {
|
|
682
|
+
throw new Error('useKeypressContext must be used within a KeypressProvider');
|
|
683
|
+
}
|
|
684
|
+
return context;
|
|
685
|
+
}
|
|
686
|
+
// ── Provider ───────────────────────────────────────────
|
|
687
|
+
export function KeypressProvider({ children }) {
|
|
688
|
+
const { stdin, setRawMode } = useStdin();
|
|
689
|
+
// Simple priority map: Map<priority, Set<handler>>
|
|
690
|
+
const subscribersToPriority = useRef(new Map()).current;
|
|
691
|
+
const priorityToHandlers = useRef(new Map()).current;
|
|
692
|
+
const sortedPriorities = useRef([]);
|
|
693
|
+
const subscribe = useCallback((handler, priority = KeypressPriority.Normal) => {
|
|
694
|
+
const p = typeof priority === 'boolean'
|
|
695
|
+
? (priority ? KeypressPriority.High : KeypressPriority.Normal)
|
|
696
|
+
: priority;
|
|
697
|
+
subscribersToPriority.set(handler, p);
|
|
698
|
+
let set = priorityToHandlers.get(p);
|
|
699
|
+
if (!set) {
|
|
700
|
+
set = new Set();
|
|
701
|
+
priorityToHandlers.set(p, set);
|
|
702
|
+
sortedPriorities.current = Array.from(priorityToHandlers.keys()).sort((a, b) => b - a);
|
|
703
|
+
}
|
|
704
|
+
set.add(handler);
|
|
705
|
+
}, [subscribersToPriority, priorityToHandlers]);
|
|
706
|
+
const unsubscribe = useCallback((handler) => {
|
|
707
|
+
const p = subscribersToPriority.get(handler);
|
|
708
|
+
if (p !== undefined) {
|
|
709
|
+
const set = priorityToHandlers.get(p);
|
|
710
|
+
if (set) {
|
|
711
|
+
set.delete(handler);
|
|
712
|
+
if (set.size === 0) {
|
|
713
|
+
priorityToHandlers.delete(p);
|
|
714
|
+
sortedPriorities.current = Array.from(priorityToHandlers.keys()).sort((a, b) => b - a);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
subscribersToPriority.delete(handler);
|
|
718
|
+
}
|
|
719
|
+
}, [subscribersToPriority, priorityToHandlers]);
|
|
720
|
+
const broadcast = useCallback((key) => {
|
|
721
|
+
for (const p of sortedPriorities.current) {
|
|
722
|
+
const set = priorityToHandlers.get(p);
|
|
723
|
+
if (!set)
|
|
724
|
+
continue;
|
|
725
|
+
// Stack behavior: last subscribed handler runs first
|
|
726
|
+
const handlers = Array.from(set).reverse();
|
|
727
|
+
for (const handler of handlers) {
|
|
728
|
+
if (handler(key) === true)
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
}, [priorityToHandlers]);
|
|
733
|
+
useEffect(() => {
|
|
734
|
+
// Prevent Ink from installing StringDecoder on stdin.
|
|
735
|
+
// Ink's handleSetRawMode calls stdin.setEncoding('utf8'), which permanently
|
|
736
|
+
// installs a StringDecoder that corrupts ANSI escape sequences at multi-byte
|
|
737
|
+
// UTF-8 chunk boundaries (PASTE_END \x1b[201~ is destroyed when \x1b is
|
|
738
|
+
// merged with preceding incomplete CJK bytes → U+FFFD). By patching
|
|
739
|
+
// setEncoding to a no-op BEFORE setRawMode, stdin delivers raw Buffers.
|
|
740
|
+
const origSetEncoding = stdin.setEncoding.bind(stdin);
|
|
741
|
+
stdin.setEncoding = (() => stdin);
|
|
742
|
+
const wasRaw = stdin.isRaw;
|
|
743
|
+
if (!wasRaw)
|
|
744
|
+
setRawMode(true);
|
|
745
|
+
// Remove Ink's internal 'readable' listener on stdin.
|
|
746
|
+
// Ink's App component attaches a 'readable' listener when setRawMode(true) is
|
|
747
|
+
// called. That listener runs parseKeypresses() → emitInput() for every character,
|
|
748
|
+
// causing thousands of synchronous parse+emit cycles for large pastes.
|
|
749
|
+
const readableListeners = stdin.listeners('readable');
|
|
750
|
+
const removedReadableListeners = [...readableListeners];
|
|
751
|
+
for (const listener of removedReadableListeners) {
|
|
752
|
+
stdin.removeListener('readable', listener);
|
|
753
|
+
}
|
|
754
|
+
// Enable bracketed paste mode so the terminal wraps pasted content
|
|
755
|
+
// with \x1b[200~ ... \x1b[201~ markers.
|
|
756
|
+
process.stdout.write('\x1b[?2004h');
|
|
757
|
+
// Ensure terminal state is restored on unexpected exit
|
|
758
|
+
const cleanupTerminal = () => {
|
|
759
|
+
try {
|
|
760
|
+
process.stdout.write('\x1b[?2004l');
|
|
761
|
+
}
|
|
762
|
+
catch { /* ignore */ }
|
|
763
|
+
};
|
|
764
|
+
process.on('exit', cleanupTerminal);
|
|
765
|
+
// Build the filter pipeline (innermost applied first)
|
|
766
|
+
let processor = nonKeyboardEventFilter(broadcast);
|
|
767
|
+
processor = bufferFastReturn(processor);
|
|
768
|
+
processor = bufferBackslashEnter(processor);
|
|
769
|
+
processor = bufferPaste(processor);
|
|
770
|
+
const dataListener = createDataListener(processor);
|
|
771
|
+
stdin.on('data', dataListener);
|
|
772
|
+
// After removing Ink's 'readable' listener, the stream may be stuck in
|
|
773
|
+
// paused mode (flowing=false). Explicitly resume so 'data' events fire
|
|
774
|
+
// for all incoming bytes — without this, the PTY can deliver partial data.
|
|
775
|
+
stdin.resume();
|
|
776
|
+
return () => {
|
|
777
|
+
stdin.removeListener('data', dataListener);
|
|
778
|
+
// Restore Ink's listeners and encoding function on cleanup
|
|
779
|
+
stdin.setEncoding = origSetEncoding;
|
|
780
|
+
for (const listener of removedReadableListeners) {
|
|
781
|
+
stdin.addListener('readable', listener);
|
|
782
|
+
}
|
|
783
|
+
process.removeListener('exit', cleanupTerminal);
|
|
784
|
+
// Disable bracketed paste mode
|
|
785
|
+
process.stdout.write('\x1b[?2004l');
|
|
786
|
+
if (!wasRaw)
|
|
787
|
+
setRawMode(false);
|
|
788
|
+
};
|
|
789
|
+
}, [stdin, setRawMode, broadcast]);
|
|
790
|
+
return (_jsx(KeypressContext.Provider, { value: { subscribe, unsubscribe }, children: children }));
|
|
791
|
+
}
|
|
792
|
+
//# sourceMappingURL=KeypressContext.js.map
|