npcts 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/LICENSE +21 -0
- package/README.md +139 -0
- package/dist/adapters/base.d.ts +13 -0
- package/dist/adapters/base.js +1 -0
- package/dist/adapters/electron/bridge.d.ts +4 -0
- package/dist/adapters/electron/bridge.js +88 -0
- package/dist/adapters/index.d.ts +2 -0
- package/dist/adapters/index.js +3 -0
- package/dist/core/browser.d.ts +25 -0
- package/dist/core/browser.js +1 -0
- package/dist/core/chat.d.ts +41 -0
- package/dist/core/chat.js +1 -0
- package/dist/core/database.d.ts +56 -0
- package/dist/core/database.js +50 -0
- package/dist/core/files.d.ts +24 -0
- package/dist/core/files.js +15 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.js +10 -0
- package/dist/core/jobs.d.ts +20 -0
- package/dist/core/jobs.js +1 -0
- package/dist/core/layout.d.ts +30 -0
- package/dist/core/layout.js +41 -0
- package/dist/core/stream.d.ts +10 -0
- package/dist/core/stream.js +1 -0
- package/dist/core/types.d.ts +23 -0
- package/dist/core/types.js +1 -0
- package/dist/core/utils.d.ts +19 -0
- package/dist/core/utils.js +19 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +29 -0
- package/dist/ui/chat/components/ChatHeaderBar.d.ts +13 -0
- package/dist/ui/chat/components/ChatHeaderBar.js +32 -0
- package/dist/ui/chat/components/ChatInterface.d.ts +10 -0
- package/dist/ui/chat/components/ChatInterface.js +19 -0
- package/dist/ui/chat/components/ChatMessage.d.ts +7 -0
- package/dist/ui/chat/components/ChatMessage.js +10 -0
- package/dist/ui/chat/components/ChatPane.d.ts +20 -0
- package/dist/ui/chat/components/ChatPane.js +20 -0
- package/dist/ui/chat/components/ChatView.d.ts +10 -0
- package/dist/ui/chat/components/ChatView.js +36 -0
- package/dist/ui/chat/components/ConversationList.d.ts +28 -0
- package/dist/ui/chat/components/ConversationList.js +113 -0
- package/dist/ui/chat/components/InPaneSearchBar.d.ts +12 -0
- package/dist/ui/chat/components/InPaneSearchBar.js +44 -0
- package/dist/ui/chat/components/InputArea.d.ts +7 -0
- package/dist/ui/chat/components/InputArea.js +46 -0
- package/dist/ui/chat/components/MessageAttachments.d.ts +5 -0
- package/dist/ui/chat/components/MessageAttachments.js +6 -0
- package/dist/ui/chat/components/MessageItem.d.ts +28 -0
- package/dist/ui/chat/components/MessageItem.js +43 -0
- package/dist/ui/chat/components/PredictiveTextOverlay.d.ts +10 -0
- package/dist/ui/chat/components/PredictiveTextOverlay.js +75 -0
- package/dist/ui/chat/context/ChatContext.d.ts +33 -0
- package/dist/ui/chat/context/ChatContext.js +157 -0
- package/dist/ui/chat/hooks/useAutoScroll.d.ts +1 -0
- package/dist/ui/chat/hooks/useAutoScroll.js +11 -0
- package/dist/ui/chat/index.d.ts +7 -0
- package/dist/ui/chat/index.js +7 -0
- package/dist/ui/dashboard/ChartWidget.d.ts +18 -0
- package/dist/ui/dashboard/ChartWidget.js +98 -0
- package/dist/ui/dashboard/QueryWidget.d.ts +29 -0
- package/dist/ui/dashboard/QueryWidget.js +117 -0
- package/dist/ui/dashboard/TableWidget.d.ts +14 -0
- package/dist/ui/dashboard/TableWidget.js +117 -0
- package/dist/ui/dashboard/Widget.d.ts +40 -0
- package/dist/ui/dashboard/Widget.js +26 -0
- package/dist/ui/dashboard/WidgetBuilder.d.ts +47 -0
- package/dist/ui/dashboard/WidgetBuilder.js +286 -0
- package/dist/ui/dashboard/WidgetGrid.d.ts +19 -0
- package/dist/ui/dashboard/WidgetGrid.js +11 -0
- package/dist/ui/dashboard/index.d.ts +8 -0
- package/dist/ui/dashboard/index.js +4 -0
- package/dist/ui/dialogs/BrowserUrlDialog.d.ts +8 -0
- package/dist/ui/dialogs/BrowserUrlDialog.js +203 -0
- package/dist/ui/dialogs/index.d.ts +1 -0
- package/dist/ui/dialogs/index.js +1 -0
- package/dist/ui/editors/ImageEditor.d.ts +49 -0
- package/dist/ui/editors/ImageEditor.js +264 -0
- package/dist/ui/editors/index.d.ts +2 -0
- package/dist/ui/editors/index.js +1 -0
- package/dist/ui/execution/ExecutionFilters.d.ts +11 -0
- package/dist/ui/execution/ExecutionFilters.js +27 -0
- package/dist/ui/execution/ExecutionHistoryList.d.ts +19 -0
- package/dist/ui/execution/ExecutionHistoryList.js +35 -0
- package/dist/ui/execution/index.d.ts +3 -0
- package/dist/ui/execution/index.js +2 -0
- package/dist/ui/files/components/FileTree.d.ts +18 -0
- package/dist/ui/files/components/FileTree.js +61 -0
- package/dist/ui/files/components/Sidebar.d.ts +18 -0
- package/dist/ui/files/components/Sidebar.js +67 -0
- package/dist/ui/files/components/index.d.ts +2 -0
- package/dist/ui/files/components/index.js +2 -0
- package/dist/ui/files/context/FileSystemContext.d.ts +23 -0
- package/dist/ui/files/context/FileSystemContext.js +65 -0
- package/dist/ui/files/context/index.d.ts +1 -0
- package/dist/ui/files/context/index.js +1 -0
- package/dist/ui/files/index.d.ts +2 -0
- package/dist/ui/files/index.js +2 -0
- package/dist/ui/hooks/index.d.ts +4 -0
- package/dist/ui/hooks/index.js +3 -0
- package/dist/ui/hooks/useDebounce.d.ts +8 -0
- package/dist/ui/hooks/useDebounce.js +18 -0
- package/dist/ui/hooks/usePaneTracking.d.ts +15 -0
- package/dist/ui/hooks/usePaneTracking.js +20 -0
- package/dist/ui/hooks/useQuery.d.ts +25 -0
- package/dist/ui/hooks/useQuery.js +71 -0
- package/dist/ui/index.d.ts +19 -0
- package/dist/ui/index.js +20 -0
- package/dist/ui/jinx/JinxEditor.d.ts +20 -0
- package/dist/ui/jinx/JinxEditor.js +34 -0
- package/dist/ui/jinx/JinxTree.d.ts +14 -0
- package/dist/ui/jinx/JinxTree.js +65 -0
- package/dist/ui/jinx/index.d.ts +3 -0
- package/dist/ui/jinx/index.js +2 -0
- package/dist/ui/knowledge-graph/KGControls.d.ts +12 -0
- package/dist/ui/knowledge-graph/KGControls.js +21 -0
- package/dist/ui/knowledge-graph/KGStats.d.ts +13 -0
- package/dist/ui/knowledge-graph/KGStats.js +18 -0
- package/dist/ui/knowledge-graph/KnowledgeGraphViewer.d.ts +22 -0
- package/dist/ui/knowledge-graph/KnowledgeGraphViewer.js +16 -0
- package/dist/ui/knowledge-graph/index.d.ts +4 -0
- package/dist/ui/knowledge-graph/index.js +3 -0
- package/dist/ui/layout/components/AppShell.d.ts +8 -0
- package/dist/ui/layout/components/AppShell.js +19 -0
- package/dist/ui/layout/components/ContentPaneContainer.d.ts +8 -0
- package/dist/ui/layout/components/ContentPaneContainer.js +95 -0
- package/dist/ui/layout/components/LayoutNode.d.ts +8 -0
- package/dist/ui/layout/components/LayoutNode.js +12 -0
- package/dist/ui/layout/components/PaneHeader.d.ts +17 -0
- package/dist/ui/layout/components/PaneHeader.js +40 -0
- package/dist/ui/layout/components/SplitView.d.ts +8 -0
- package/dist/ui/layout/components/SplitView.js +51 -0
- package/dist/ui/layout/components/Studio.d.ts +7 -0
- package/dist/ui/layout/components/Studio.js +12 -0
- package/dist/ui/layout/components/contextMenus/BrowserContextMenu.d.ts +13 -0
- package/dist/ui/layout/components/contextMenus/BrowserContextMenu.js +23 -0
- package/dist/ui/layout/components/contextMenus/EditorContextMenu.d.ts +15 -0
- package/dist/ui/layout/components/contextMenus/EditorContextMenu.js +32 -0
- package/dist/ui/layout/components/contextMenus/FileContextMenu.d.ts +15 -0
- package/dist/ui/layout/components/contextMenus/FileContextMenu.js +33 -0
- package/dist/ui/layout/components/contextMenus/PdfContextMenu.d.ts +13 -0
- package/dist/ui/layout/components/contextMenus/PdfContextMenu.js +23 -0
- package/dist/ui/layout/components/contextMenus/index.d.ts +4 -0
- package/dist/ui/layout/components/contextMenus/index.js +4 -0
- package/dist/ui/layout/components/index.d.ts +8 -0
- package/dist/ui/layout/components/index.js +8 -0
- package/dist/ui/layout/components/modals/AIEditModal.d.ts +9 -0
- package/dist/ui/layout/components/modals/AIEditModal.js +33 -0
- package/dist/ui/layout/components/modals/MemoryApprovalModal.d.ts +15 -0
- package/dist/ui/layout/components/modals/MemoryApprovalModal.js +23 -0
- package/dist/ui/layout/components/modals/PromptModal.d.ts +11 -0
- package/dist/ui/layout/components/modals/PromptModal.js +20 -0
- package/dist/ui/layout/components/modals/ResendModal.d.ts +16 -0
- package/dist/ui/layout/components/modals/ResendModal.js +22 -0
- package/dist/ui/layout/components/modals/index.d.ts +4 -0
- package/dist/ui/layout/components/modals/index.js +4 -0
- package/dist/ui/layout/context/LayoutContext.d.ts +32 -0
- package/dist/ui/layout/context/LayoutContext.js +144 -0
- package/dist/ui/layout/index.d.ts +2 -0
- package/dist/ui/layout/index.js +2 -0
- package/dist/ui/markdown/Markdown.d.ts +4 -0
- package/dist/ui/markdown/Markdown.js +4 -0
- package/dist/ui/memory/MemoryFilters.d.ts +12 -0
- package/dist/ui/memory/MemoryFilters.js +23 -0
- package/dist/ui/memory/MemoryList.d.ts +19 -0
- package/dist/ui/memory/MemoryList.js +36 -0
- package/dist/ui/memory/index.d.ts +3 -0
- package/dist/ui/memory/index.js +2 -0
- package/dist/ui/models/ModelCard.d.ts +16 -0
- package/dist/ui/models/ModelCard.js +30 -0
- package/dist/ui/models/ModelSelector.d.ts +13 -0
- package/dist/ui/models/ModelSelector.js +6 -0
- package/dist/ui/models/index.d.ts +3 -0
- package/dist/ui/models/index.js +2 -0
- package/dist/ui/npc/McpServerMenu.d.ts +15 -0
- package/dist/ui/npc/McpServerMenu.js +48 -0
- package/dist/ui/npc/NPCEditor.d.ts +21 -0
- package/dist/ui/npc/NPCEditor.js +17 -0
- package/dist/ui/npc/NPCList.d.ts +19 -0
- package/dist/ui/npc/NPCList.js +28 -0
- package/dist/ui/npc/index.d.ts +3 -0
- package/dist/ui/npc/index.js +2 -0
- package/dist/ui/photo/GalleryGrid.d.ts +25 -0
- package/dist/ui/photo/GalleryGrid.js +46 -0
- package/dist/ui/photo/ImageAdjustmentSliders.d.ts +37 -0
- package/dist/ui/photo/ImageAdjustmentSliders.js +56 -0
- package/dist/ui/photo/ImageLabelingCanvas.d.ts +47 -0
- package/dist/ui/photo/ImageLabelingCanvas.js +174 -0
- package/dist/ui/photo/ImageSourceTabs.d.ts +28 -0
- package/dist/ui/photo/ImageSourceTabs.js +46 -0
- package/dist/ui/photo/LayerPanel.d.ts +87 -0
- package/dist/ui/photo/LayerPanel.js +70 -0
- package/dist/ui/photo/Lightbox.d.ts +12 -0
- package/dist/ui/photo/Lightbox.js +90 -0
- package/dist/ui/photo/index.d.ts +6 -0
- package/dist/ui/photo/index.js +7 -0
- package/dist/ui/primitives/AutosizeTextarea.d.ts +8 -0
- package/dist/ui/primitives/AutosizeTextarea.js +17 -0
- package/dist/ui/primitives/Button.d.ts +7 -0
- package/dist/ui/primitives/Button.js +17 -0
- package/dist/ui/primitives/Card.d.ts +12 -0
- package/dist/ui/primitives/Card.js +8 -0
- package/dist/ui/primitives/Chart.d.ts +34 -0
- package/dist/ui/primitives/Chart.js +140 -0
- package/dist/ui/primitives/ContextMenu.d.ts +17 -0
- package/dist/ui/primitives/ContextMenu.js +33 -0
- package/dist/ui/primitives/DataTable.d.ts +13 -0
- package/dist/ui/primitives/DataTable.js +13 -0
- package/dist/ui/primitives/FileUpload.d.ts +10 -0
- package/dist/ui/primitives/FileUpload.js +24 -0
- package/dist/ui/primitives/ImageGrid.d.ts +21 -0
- package/dist/ui/primitives/ImageGrid.js +29 -0
- package/dist/ui/primitives/Input.d.ts +7 -0
- package/dist/ui/primitives/Input.js +10 -0
- package/dist/ui/primitives/Lightbox.d.ts +12 -0
- package/dist/ui/primitives/Lightbox.js +36 -0
- package/dist/ui/primitives/Modal.d.ts +10 -0
- package/dist/ui/primitives/Modal.js +33 -0
- package/dist/ui/primitives/RangeSlider.d.ts +13 -0
- package/dist/ui/primitives/RangeSlider.js +6 -0
- package/dist/ui/primitives/Select.d.ts +11 -0
- package/dist/ui/primitives/Select.js +10 -0
- package/dist/ui/primitives/Slider.d.ts +13 -0
- package/dist/ui/primitives/Slider.js +8 -0
- package/dist/ui/primitives/SortableList.d.ts +9 -0
- package/dist/ui/primitives/SortableList.js +19 -0
- package/dist/ui/primitives/Spinner.d.ts +2 -0
- package/dist/ui/primitives/Spinner.js +2 -0
- package/dist/ui/primitives/StarRating.d.ts +10 -0
- package/dist/ui/primitives/StarRating.js +10 -0
- package/dist/ui/primitives/Tabs.d.ts +15 -0
- package/dist/ui/primitives/Tabs.js +11 -0
- package/dist/ui/primitives/TagInput.d.ts +10 -0
- package/dist/ui/primitives/TagInput.js +25 -0
- package/dist/ui/primitives/index.d.ts +20 -0
- package/dist/ui/primitives/index.js +19 -0
- package/dist/ui/specialized/DiskUsageAnalyzer.d.ts +12 -0
- package/dist/ui/specialized/DiskUsageAnalyzer.js +38 -0
- package/dist/ui/specialized/OllamaModelManager.d.ts +2 -0
- package/dist/ui/specialized/OllamaModelManager.js +48 -0
- package/dist/ui/specialized/RichTextEditor.d.ts +8 -0
- package/dist/ui/specialized/RichTextEditor.js +64 -0
- package/dist/ui/specialized/SlideCanvas.d.ts +24 -0
- package/dist/ui/specialized/SlideCanvas.js +31 -0
- package/dist/ui/specialized/SpreadsheetGrid.d.ts +18 -0
- package/dist/ui/specialized/SpreadsheetGrid.js +28 -0
- package/dist/ui/specialized/StepEditor.d.ts +12 -0
- package/dist/ui/specialized/StepEditor.js +22 -0
- package/dist/ui/specialized/TerminalEmbed.d.ts +13 -0
- package/dist/ui/specialized/TerminalEmbed.js +50 -0
- package/dist/ui/specialized/index.d.ts +7 -0
- package/dist/ui/specialized/index.js +7 -0
- package/dist/ui/sql/SQLQueryEditor.d.ts +9 -0
- package/dist/ui/sql/SQLQueryEditor.js +10 -0
- package/dist/ui/sql/SQLResultsTable.d.ts +6 -0
- package/dist/ui/sql/SQLResultsTable.js +12 -0
- package/dist/ui/sql/SQLSchemaViewer.d.ts +14 -0
- package/dist/ui/sql/SQLSchemaViewer.js +18 -0
- package/dist/ui/sql/index.d.ts +3 -0
- package/dist/ui/sql/index.js +3 -0
- package/dist/ui/utils/cn.d.ts +1 -0
- package/dist/ui/utils/cn.js +1 -0
- package/dist/ui/utils/fileIcons.d.ts +2 -0
- package/dist/ui/utils/fileIcons.js +24 -0
- package/dist/ui/utils/fileUtils.d.ts +4 -0
- package/dist/ui/utils/fileUtils.js +11 -0
- package/dist/ui/utils/index.d.ts +3 -0
- package/dist/ui/utils/index.js +3 -0
- package/dist/ui/viewers/components/BrowserViewer.d.ts +9 -0
- package/dist/ui/viewers/components/BrowserViewer.js +44 -0
- package/dist/ui/viewers/components/CodeEditor.d.ts +11 -0
- package/dist/ui/viewers/components/CodeEditor.js +115 -0
- package/dist/ui/viewers/components/CsvViewer.d.ts +7 -0
- package/dist/ui/viewers/components/CsvViewer.js +18 -0
- package/dist/ui/viewers/components/ImageViewer.d.ts +7 -0
- package/dist/ui/viewers/components/ImageViewer.js +23 -0
- package/dist/ui/viewers/components/PdfViewer.d.ts +7 -0
- package/dist/ui/viewers/components/PdfViewer.js +29 -0
- package/dist/ui/viewers/components/Terminal.d.ts +7 -0
- package/dist/ui/viewers/components/Terminal.js +31 -0
- package/dist/ui/viewers/components/index.d.ts +6 -0
- package/dist/ui/viewers/components/index.js +6 -0
- package/dist/ui/viewers/index.d.ts +1 -0
- package/dist/ui/viewers/index.js +1 -0
- package/package.json +76 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 NPC Worldwide
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# npcts
|
|
2
|
+
|
|
3
|
+
TypeScript library for building NPC-powered applications with split-pane
|
|
4
|
+
layouts, file editors, terminals, chat interfaces, and file management.
|
|
5
|
+
|
|
6
|
+
## Architecture
|
|
7
|
+
|
|
8
|
+
### Core Interfaces
|
|
9
|
+
- `core/types.ts` - Base types (ModelInfo, Attachment, ToolCall)
|
|
10
|
+
- `core/chat.ts` - Chat client interface
|
|
11
|
+
- `core/files.ts` - File system client interface
|
|
12
|
+
- `core/browser.ts` - Browser client interface
|
|
13
|
+
- `core/jobs.ts` - Jobs/cron client interface
|
|
14
|
+
- `core/layout.ts` - Layout node types
|
|
15
|
+
|
|
16
|
+
### Adapters
|
|
17
|
+
Platform-specific implementations of core interfaces:
|
|
18
|
+
- `adapters/base.ts` - AppServices interface definition
|
|
19
|
+
- `adapters/electron/bridge.ts` - Electron/window.api implementation
|
|
20
|
+
|
|
21
|
+
### UI Components
|
|
22
|
+
|
|
23
|
+
#### Layout System
|
|
24
|
+
- `LayoutProvider` - Context for split pane state management
|
|
25
|
+
- `LayoutNodeComponent` - Recursive layout tree renderer
|
|
26
|
+
- `SplitView` - Resizable horizontal/vertical splits
|
|
27
|
+
- `PaneHeader` - Pane title bar with close/rename
|
|
28
|
+
- `ContentPaneContainer` - Content type router
|
|
29
|
+
- `AppShell` - Complete application with sidebar + layout
|
|
30
|
+
|
|
31
|
+
#### File Management
|
|
32
|
+
- `FileSystemProvider` - File operations context
|
|
33
|
+
- `FileTree` - Recursive directory tree
|
|
34
|
+
- `Sidebar` - Workspace sidebar with search
|
|
35
|
+
|
|
36
|
+
#### Content Viewers
|
|
37
|
+
- `CodeEditor` - CodeMirror-based editor with syntax highlighting
|
|
38
|
+
- `Terminal` - Basic terminal emulator
|
|
39
|
+
- `BrowserViewer` - Embedded browser frame
|
|
40
|
+
- `PdfViewer` - PDF document viewer
|
|
41
|
+
- `CsvViewer` - Spreadsheet table view
|
|
42
|
+
- `ImageViewer` - Image display with zoom/rotate
|
|
43
|
+
|
|
44
|
+
#### Chat
|
|
45
|
+
- `ChatProvider` - Chat state management with streaming
|
|
46
|
+
- `ChatInterface` - Complete chat UI
|
|
47
|
+
- `ChatView` - Message list with auto-scroll
|
|
48
|
+
- `InputArea` - Message input with file attachments
|
|
49
|
+
- `ConversationList` - Conversation sidebar
|
|
50
|
+
|
|
51
|
+
#### Primitives
|
|
52
|
+
- `AutosizeTextarea` - Auto-growing textarea
|
|
53
|
+
- `Spinner` - Loading indicator
|
|
54
|
+
|
|
55
|
+
## Quick Start
|
|
56
|
+
|
|
57
|
+
### With Electron
|
|
58
|
+
```typescript
|
|
59
|
+
import { createElectronAdapter, AppShell } from "npcts";
|
|
60
|
+
|
|
61
|
+
const services = createElectronAdapter(window.api);
|
|
62
|
+
|
|
63
|
+
function App() {
|
|
64
|
+
return (
|
|
65
|
+
<AppShell
|
|
66
|
+
services={services}
|
|
67
|
+
workspacePath="/path/to/workspace"
|
|
68
|
+
/>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Custom Adapter
|
|
74
|
+
```typescript
|
|
75
|
+
import type { AppServices, ChatClient, FileSystemClient } from "npcts";
|
|
76
|
+
|
|
77
|
+
const customServices: AppServices = {
|
|
78
|
+
chat: customChatClient,
|
|
79
|
+
files: customFileClient,
|
|
80
|
+
browser: customBrowserClient,
|
|
81
|
+
jobs: customJobsClient,
|
|
82
|
+
};
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Layout Only
|
|
86
|
+
```typescript
|
|
87
|
+
import { LayoutProvider, Studio } from "npcts";
|
|
88
|
+
|
|
89
|
+
function App() {
|
|
90
|
+
return <Studio services={services} />;
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Project Structure
|
|
95
|
+
```
|
|
96
|
+
src/
|
|
97
|
+
├── adapters/ # Platform implementations
|
|
98
|
+
│ ├── base.ts
|
|
99
|
+
│ └── electron/
|
|
100
|
+
├── core/ # Core interface definitions
|
|
101
|
+
│ ├── types.ts
|
|
102
|
+
│ ├── chat.ts
|
|
103
|
+
│ ├── files.ts
|
|
104
|
+
│ ├── browser.ts
|
|
105
|
+
│ ├── jobs.ts
|
|
106
|
+
│ └── layout.ts
|
|
107
|
+
└── ui/ # React components
|
|
108
|
+
├── chat/ # Chat UI components
|
|
109
|
+
├── layout/ # Split pane system
|
|
110
|
+
├── viewers/ # Content viewers
|
|
111
|
+
├── files/ # File management
|
|
112
|
+
├── primitives/ # Base components
|
|
113
|
+
└── markdown/ # Markdown rendering
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Development
|
|
117
|
+
```bash
|
|
118
|
+
npm install # Install dependencies
|
|
119
|
+
npm run build # Compile TypeScript
|
|
120
|
+
npm run dev # Watch mode
|
|
121
|
+
npm run check # Type check only
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Features
|
|
125
|
+
|
|
126
|
+
- 🎨 Split-pane layout system with drag-to-split
|
|
127
|
+
- 📁 File tree navigation with context menus
|
|
128
|
+
- 💬 Real-time chat with streaming support
|
|
129
|
+
- ✏️ Code editor with syntax highlighting
|
|
130
|
+
- 🖥️ Terminal emulator
|
|
131
|
+
- 🌐 Browser viewer
|
|
132
|
+
- 📄 PDF, CSV, and image viewers
|
|
133
|
+
- 🔌 Pluggable adapter system
|
|
134
|
+
- 📦 TypeScript-first with full type safety
|
|
135
|
+
- ⚛️ React 18+ compatible
|
|
136
|
+
|
|
137
|
+
## License
|
|
138
|
+
|
|
139
|
+
MIT
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BrowserClient } from "../core/browser";
|
|
2
|
+
import type { ChatClient } from "../core/chat";
|
|
3
|
+
import type { FileSystemClient } from "../core/files";
|
|
4
|
+
import type { JobClient } from "../core/jobs";
|
|
5
|
+
import type { DatabaseClient } from "../core/database";
|
|
6
|
+
export interface AppServices {
|
|
7
|
+
chat: ChatClient;
|
|
8
|
+
files: FileSystemClient;
|
|
9
|
+
jobs?: JobClient;
|
|
10
|
+
browser?: BrowserClient;
|
|
11
|
+
database?: DatabaseClient;
|
|
12
|
+
}
|
|
13
|
+
export type AdapterFactory<T = unknown> = (bridge: T) => AppServices;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
const ensureApi = (api) => {
|
|
2
|
+
if (!api)
|
|
3
|
+
throw new Error("Electron preload api is not available on window.api");
|
|
4
|
+
return api;
|
|
5
|
+
};
|
|
6
|
+
const createChatClient = (rawApi) => {
|
|
7
|
+
const api = ensureApi(rawApi);
|
|
8
|
+
return {
|
|
9
|
+
listConversations: (workspacePath) => {
|
|
10
|
+
if (api.getConversationsInDirectory && workspacePath) {
|
|
11
|
+
return api.getConversationsInDirectory(workspacePath);
|
|
12
|
+
}
|
|
13
|
+
return api.getConversations?.(workspacePath ?? "") ?? Promise.resolve([]);
|
|
14
|
+
},
|
|
15
|
+
createConversation: (workspacePath) => api.createConversation?.({ directory_path: workspacePath }) ??
|
|
16
|
+
Promise.reject(new Error("createConversation not implemented")),
|
|
17
|
+
deleteConversation: (conversationId) => api.deleteConversation?.(conversationId) ?? Promise.resolve(),
|
|
18
|
+
listMessages: (conversationId) => api.getConversationMessages?.(conversationId) ?? Promise.resolve([]),
|
|
19
|
+
sendMessage: async (request) => {
|
|
20
|
+
const modelId = typeof request.model === "string" ? request.model : request.model.id;
|
|
21
|
+
if (request.stream && api.onStreamData) {
|
|
22
|
+
// The host should expose a stream API that yields chunks; we forward the generator when available.
|
|
23
|
+
const generator = api.executeCommandStream?.({
|
|
24
|
+
commandstr: request.prompt,
|
|
25
|
+
conversationId: request.conversationId,
|
|
26
|
+
model: modelId,
|
|
27
|
+
});
|
|
28
|
+
if (generator)
|
|
29
|
+
return generator;
|
|
30
|
+
}
|
|
31
|
+
const msg = await api.sendMessage?.({
|
|
32
|
+
conversationId: request.conversationId,
|
|
33
|
+
message: request.prompt,
|
|
34
|
+
model: modelId,
|
|
35
|
+
attachments: request.attachments,
|
|
36
|
+
});
|
|
37
|
+
return msg;
|
|
38
|
+
},
|
|
39
|
+
deleteMessage: (conversationId, messageId) => api.deleteMessage?.({ conversationId, messageId }) ?? Promise.resolve(),
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
const createFileSystemClient = (rawApi) => {
|
|
43
|
+
const api = ensureApi(rawApi);
|
|
44
|
+
return {
|
|
45
|
+
readDirectoryStructure: (dirPath) => api.readDirectoryStructure(dirPath),
|
|
46
|
+
readFileContent: (path) => api.readFileContent(path),
|
|
47
|
+
writeFileContent: (path, content) => api.writeFileContent(path, content),
|
|
48
|
+
createDirectory: (path) => api.createDirectory(path),
|
|
49
|
+
deleteFile: (path) => api.deleteFile(path),
|
|
50
|
+
deleteDirectory: (path) => api.deleteDirectory(path),
|
|
51
|
+
rename: (oldPath, newPath) => api.renameFile(oldPath, newPath),
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
const createJobClient = (rawApi) => {
|
|
55
|
+
const api = ensureApi(rawApi);
|
|
56
|
+
return {
|
|
57
|
+
listCronJobs: () => api.getCronDaemons(),
|
|
58
|
+
addCronJob: (job) => api.addCronJob(job),
|
|
59
|
+
removeCronJob: (id) => api.removeCronJob(id),
|
|
60
|
+
listDaemons: () => api.getCronDaemons(),
|
|
61
|
+
addDaemon: (daemon) => api.addDaemon(daemon),
|
|
62
|
+
removeDaemon: (id) => api.removeDaemon(id),
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
const createBrowserClient = (rawApi) => {
|
|
66
|
+
const api = ensureApi(rawApi);
|
|
67
|
+
return {
|
|
68
|
+
navigate: (url) => api.browserNavigate({ url }),
|
|
69
|
+
back: () => api.browserBack({}),
|
|
70
|
+
forward: () => api.browserForward({}),
|
|
71
|
+
refresh: () => api.browserRefresh({}),
|
|
72
|
+
getSelectedText: () => api.browserGetSelectedText({}),
|
|
73
|
+
listHistory: () => api.browserGetHistory({}),
|
|
74
|
+
addHistory: (entry) => api.browserAddToHistory(entry),
|
|
75
|
+
clearHistory: () => api.browserClearHistory({}),
|
|
76
|
+
listBookmarks: () => api.browserGetBookmarks({}),
|
|
77
|
+
addBookmark: (bookmark) => api.browserAddBookmark(bookmark),
|
|
78
|
+
deleteBookmark: (id) => api.browserDeleteBookmark({ id }),
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
export const createElectronAdapter = (bridge) => {
|
|
82
|
+
return {
|
|
83
|
+
chat: createChatClient(bridge),
|
|
84
|
+
files: createFileSystemClient(bridge),
|
|
85
|
+
jobs: createJobClient(bridge),
|
|
86
|
+
browser: createBrowserClient(bridge),
|
|
87
|
+
};
|
|
88
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface BrowserHistoryEntry {
|
|
2
|
+
id: string;
|
|
3
|
+
title?: string;
|
|
4
|
+
url: string;
|
|
5
|
+
visitedAt: string;
|
|
6
|
+
}
|
|
7
|
+
export interface Bookmark {
|
|
8
|
+
id: string;
|
|
9
|
+
title: string;
|
|
10
|
+
url: string;
|
|
11
|
+
folder?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface BrowserClient {
|
|
14
|
+
navigate(url: string): Promise<void>;
|
|
15
|
+
back(): Promise<void>;
|
|
16
|
+
forward(): Promise<void>;
|
|
17
|
+
refresh(): Promise<void>;
|
|
18
|
+
getSelectedText(): Promise<string | null>;
|
|
19
|
+
listHistory(): Promise<BrowserHistoryEntry[]>;
|
|
20
|
+
addHistory(entry: Omit<BrowserHistoryEntry, "id" | "visitedAt">): Promise<BrowserHistoryEntry>;
|
|
21
|
+
clearHistory(): Promise<void>;
|
|
22
|
+
listBookmarks(): Promise<Bookmark[]>;
|
|
23
|
+
addBookmark(bookmark: Omit<Bookmark, "id">): Promise<Bookmark>;
|
|
24
|
+
deleteBookmark(id: string): Promise<void>;
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Attachment, ModelInfo, ToolCall } from "./types";
|
|
2
|
+
export interface Conversation {
|
|
3
|
+
id: string;
|
|
4
|
+
title?: string;
|
|
5
|
+
workspacePath?: string;
|
|
6
|
+
createdAt?: string;
|
|
7
|
+
updatedAt?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ChatMessage {
|
|
10
|
+
id: string;
|
|
11
|
+
role: "user" | "assistant" | "system" | "tool";
|
|
12
|
+
content: string;
|
|
13
|
+
createdAt?: string;
|
|
14
|
+
attachments?: Attachment[];
|
|
15
|
+
toolCalls?: ToolCall[];
|
|
16
|
+
parentId?: string;
|
|
17
|
+
metadata?: Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
export interface ChatStreamChunk {
|
|
20
|
+
id: string;
|
|
21
|
+
conversationId: string;
|
|
22
|
+
messageId: string;
|
|
23
|
+
delta: string;
|
|
24
|
+
done?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface ChatSendRequest {
|
|
27
|
+
conversationId: string;
|
|
28
|
+
prompt: string;
|
|
29
|
+
model: ModelInfo | string;
|
|
30
|
+
attachments?: Attachment[];
|
|
31
|
+
context?: Record<string, unknown>;
|
|
32
|
+
stream?: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface ChatClient {
|
|
35
|
+
listConversations(workspacePath?: string): Promise<Conversation[]>;
|
|
36
|
+
createConversation(workspacePath?: string): Promise<Conversation>;
|
|
37
|
+
deleteConversation(conversationId: string): Promise<void>;
|
|
38
|
+
listMessages(conversationId: string): Promise<ChatMessage[]>;
|
|
39
|
+
sendMessage(request: ChatSendRequest): Promise<ChatMessage | AsyncGenerator<ChatStreamChunk>>;
|
|
40
|
+
deleteMessage(conversationId: string, messageId: string): Promise<void>;
|
|
41
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export interface QueryResult<T = Record<string, unknown>> {
|
|
2
|
+
result?: T[];
|
|
3
|
+
data?: T[];
|
|
4
|
+
error?: string;
|
|
5
|
+
rowsAffected?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface TableInfo {
|
|
8
|
+
name: string;
|
|
9
|
+
type: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ColumnInfo {
|
|
12
|
+
name: string;
|
|
13
|
+
type: string;
|
|
14
|
+
nullable?: boolean;
|
|
15
|
+
primaryKey?: boolean;
|
|
16
|
+
defaultValue?: unknown;
|
|
17
|
+
}
|
|
18
|
+
export interface DatabaseClient {
|
|
19
|
+
/**
|
|
20
|
+
* Execute a SQL query and return results
|
|
21
|
+
*/
|
|
22
|
+
executeSQL(query: string, params?: unknown[]): Promise<QueryResult>;
|
|
23
|
+
/**
|
|
24
|
+
* Get list of tables in the database
|
|
25
|
+
*/
|
|
26
|
+
getTables(): Promise<string[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Get schema information for a specific table
|
|
29
|
+
*/
|
|
30
|
+
getTableSchema(tableName: string): Promise<ColumnInfo[]>;
|
|
31
|
+
/**
|
|
32
|
+
* Execute multiple queries in a transaction
|
|
33
|
+
*/
|
|
34
|
+
transaction?(queries: string[]): Promise<QueryResult[]>;
|
|
35
|
+
}
|
|
36
|
+
export interface DatabaseConfig {
|
|
37
|
+
type: 'sqlite' | 'postgres' | 'mysql' | 'custom';
|
|
38
|
+
connectionString?: string;
|
|
39
|
+
database?: string;
|
|
40
|
+
host?: string;
|
|
41
|
+
port?: number;
|
|
42
|
+
user?: string;
|
|
43
|
+
password?: string;
|
|
44
|
+
}
|
|
45
|
+
export declare function normalizeQueryResult<T = Record<string, unknown>>(response: QueryResult<T> | T[] | {
|
|
46
|
+
rows?: T[];
|
|
47
|
+
data?: T[];
|
|
48
|
+
result?: T[];
|
|
49
|
+
}): T[];
|
|
50
|
+
export declare function createWindowApiDatabaseClient(api: {
|
|
51
|
+
executeSQL?: (params: {
|
|
52
|
+
query: string;
|
|
53
|
+
}) => Promise<QueryResult>;
|
|
54
|
+
getTables?: () => Promise<string[]>;
|
|
55
|
+
getTableSchema?: (table: string) => Promise<ColumnInfo[]>;
|
|
56
|
+
}): DatabaseClient;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Database abstraction for configurable backends
|
|
2
|
+
// Helper to normalize query results from different backends
|
|
3
|
+
export function normalizeQueryResult(response) {
|
|
4
|
+
if (Array.isArray(response)) {
|
|
5
|
+
return response;
|
|
6
|
+
}
|
|
7
|
+
if ('rows' in response && Array.isArray(response.rows)) {
|
|
8
|
+
return response.rows;
|
|
9
|
+
}
|
|
10
|
+
if ('data' in response && Array.isArray(response.data)) {
|
|
11
|
+
return response.data;
|
|
12
|
+
}
|
|
13
|
+
if ('result' in response && Array.isArray(response.result)) {
|
|
14
|
+
return response.result;
|
|
15
|
+
}
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
// Create a database client from window.api (common pattern)
|
|
19
|
+
export function createWindowApiDatabaseClient(api) {
|
|
20
|
+
return {
|
|
21
|
+
async executeSQL(query, _params) {
|
|
22
|
+
if (!api.executeSQL) {
|
|
23
|
+
return { error: 'executeSQL not available' };
|
|
24
|
+
}
|
|
25
|
+
return api.executeSQL({ query });
|
|
26
|
+
},
|
|
27
|
+
async getTables() {
|
|
28
|
+
if (api.getTables) {
|
|
29
|
+
return api.getTables();
|
|
30
|
+
}
|
|
31
|
+
// Fallback: try to query sqlite_master
|
|
32
|
+
const result = await this.executeSQL("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'");
|
|
33
|
+
return normalizeQueryResult(result).map((r) => r.name || '');
|
|
34
|
+
},
|
|
35
|
+
async getTableSchema(tableName) {
|
|
36
|
+
if (api.getTableSchema) {
|
|
37
|
+
return api.getTableSchema(tableName);
|
|
38
|
+
}
|
|
39
|
+
// Fallback: PRAGMA for SQLite
|
|
40
|
+
const result = await this.executeSQL(`PRAGMA table_info(${tableName})`);
|
|
41
|
+
return normalizeQueryResult(result).map((r) => ({
|
|
42
|
+
name: r.name || '',
|
|
43
|
+
type: r.type || 'unknown',
|
|
44
|
+
nullable: !r.notnull,
|
|
45
|
+
primaryKey: !!r.pk,
|
|
46
|
+
defaultValue: r.dflt_value
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface FileNode {
|
|
2
|
+
path: string;
|
|
3
|
+
name: string;
|
|
4
|
+
isDirectory: boolean;
|
|
5
|
+
sizeBytes?: number;
|
|
6
|
+
modifiedAt?: string;
|
|
7
|
+
children?: FileNode[];
|
|
8
|
+
}
|
|
9
|
+
export interface FileSystemClient {
|
|
10
|
+
readDirectoryStructure(path: string): Promise<FileNode>;
|
|
11
|
+
readFileContent(path: string): Promise<string>;
|
|
12
|
+
writeFileContent(path: string, content: string): Promise<void>;
|
|
13
|
+
createDirectory(path: string): Promise<void>;
|
|
14
|
+
deleteFile(path: string): Promise<void>;
|
|
15
|
+
deleteDirectory(path: string): Promise<void>;
|
|
16
|
+
rename(oldPath: string, newPath: string): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Normalize a file path by converting backslashes to forward slashes
|
|
20
|
+
* and removing trailing slashes
|
|
21
|
+
* @param path - The path to normalize (can be null/undefined)
|
|
22
|
+
* @returns Normalized path string, or empty string if input is null/undefined
|
|
23
|
+
*/
|
|
24
|
+
export declare const normalizePath: (path: string | null | undefined) => string;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalize a file path by converting backslashes to forward slashes
|
|
3
|
+
* and removing trailing slashes
|
|
4
|
+
* @param path - The path to normalize (can be null/undefined)
|
|
5
|
+
* @returns Normalized path string, or empty string if input is null/undefined
|
|
6
|
+
*/
|
|
7
|
+
export const normalizePath = (path) => {
|
|
8
|
+
if (!path)
|
|
9
|
+
return '';
|
|
10
|
+
let normalizedPath = path.replace(/\\/g, '/');
|
|
11
|
+
if (normalizedPath.endsWith('/') && normalizedPath.length > 1) {
|
|
12
|
+
normalizedPath = normalizedPath.slice(0, -1);
|
|
13
|
+
}
|
|
14
|
+
return normalizedPath;
|
|
15
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Core module exports
|
|
2
|
+
export * from './types';
|
|
3
|
+
export * from './layout';
|
|
4
|
+
export * from './files';
|
|
5
|
+
export * from './utils';
|
|
6
|
+
export * from './chat';
|
|
7
|
+
export * from './stream';
|
|
8
|
+
export * from './browser';
|
|
9
|
+
export * from './jobs';
|
|
10
|
+
export * from './database';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface CronJob {
|
|
2
|
+
id: string;
|
|
3
|
+
schedule: string;
|
|
4
|
+
command: string;
|
|
5
|
+
label?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface Daemon {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
command: string;
|
|
11
|
+
status: "running" | "stopped" | "unknown";
|
|
12
|
+
}
|
|
13
|
+
export interface JobClient {
|
|
14
|
+
listCronJobs(): Promise<CronJob[]>;
|
|
15
|
+
addCronJob(job: Omit<CronJob, "id">): Promise<CronJob>;
|
|
16
|
+
removeCronJob(id: string): Promise<void>;
|
|
17
|
+
listDaemons(): Promise<Daemon[]>;
|
|
18
|
+
addDaemon(daemon: Omit<Daemon, "id" | "status">): Promise<Daemon>;
|
|
19
|
+
removeDaemon(id: string): Promise<void>;
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type SplitDirection = 'horizontal' | 'vertical';
|
|
2
|
+
export interface SplitNode {
|
|
3
|
+
type: 'split';
|
|
4
|
+
id: string;
|
|
5
|
+
direction: SplitDirection;
|
|
6
|
+
children: LayoutNode[];
|
|
7
|
+
sizes: number[];
|
|
8
|
+
}
|
|
9
|
+
export interface ContentNode {
|
|
10
|
+
type: 'content';
|
|
11
|
+
id: string;
|
|
12
|
+
contentType: string;
|
|
13
|
+
data?: any;
|
|
14
|
+
}
|
|
15
|
+
export type LayoutNode = SplitNode | ContentNode;
|
|
16
|
+
/**
|
|
17
|
+
* Find a node in the layout tree by following a path of indices
|
|
18
|
+
* @param node - The root layout node to search from
|
|
19
|
+
* @param path - Array of child indices to follow
|
|
20
|
+
* @returns The node at the specified path, or null if not found
|
|
21
|
+
*/
|
|
22
|
+
export declare const findNodeByPath: (node: LayoutNode | null, path: number[]) => LayoutNode | null;
|
|
23
|
+
/**
|
|
24
|
+
* Find the path to a node with the given ID in the layout tree
|
|
25
|
+
* @param node - The root layout node to search from
|
|
26
|
+
* @param id - The ID of the node to find
|
|
27
|
+
* @param currentPath - The current path (used internally for recursion)
|
|
28
|
+
* @returns Array of indices representing the path to the node, or null if not found
|
|
29
|
+
*/
|
|
30
|
+
export declare const findNodePath: (node: LayoutNode | null, id: string, currentPath?: number[]) => number[] | null;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Find a node in the layout tree by following a path of indices
|
|
3
|
+
* @param node - The root layout node to search from
|
|
4
|
+
* @param path - Array of child indices to follow
|
|
5
|
+
* @returns The node at the specified path, or null if not found
|
|
6
|
+
*/
|
|
7
|
+
export const findNodeByPath = (node, path) => {
|
|
8
|
+
if (!node || !path)
|
|
9
|
+
return null;
|
|
10
|
+
let currentNode = node;
|
|
11
|
+
for (const index of path) {
|
|
12
|
+
if (currentNode && currentNode.type === 'split' && currentNode.children && currentNode.children[index]) {
|
|
13
|
+
currentNode = currentNode.children[index];
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return currentNode;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Find the path to a node with the given ID in the layout tree
|
|
23
|
+
* @param node - The root layout node to search from
|
|
24
|
+
* @param id - The ID of the node to find
|
|
25
|
+
* @param currentPath - The current path (used internally for recursion)
|
|
26
|
+
* @returns Array of indices representing the path to the node, or null if not found
|
|
27
|
+
*/
|
|
28
|
+
export const findNodePath = (node, id, currentPath = []) => {
|
|
29
|
+
if (!node)
|
|
30
|
+
return null;
|
|
31
|
+
if (node.id === id)
|
|
32
|
+
return currentPath;
|
|
33
|
+
if (node.type === 'split') {
|
|
34
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
35
|
+
const result = findNodePath(node.children[i], id, [...currentPath, i]);
|
|
36
|
+
if (result)
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type StreamStatus = "idle" | "streaming" | "error";
|
|
2
|
+
export interface StreamController {
|
|
3
|
+
streamId: string;
|
|
4
|
+
abort(): Promise<void> | void;
|
|
5
|
+
}
|
|
6
|
+
export interface StreamHandlers<TChunk> {
|
|
7
|
+
onChunk: (chunk: TChunk) => void;
|
|
8
|
+
onComplete?: () => void;
|
|
9
|
+
onError?: (error: unknown) => void;
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type Provider = "openai" | "ollama" | "anthropic" | "local" | string;
|
|
2
|
+
export interface Attachment {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
path: string;
|
|
6
|
+
mime?: string;
|
|
7
|
+
sizeBytes?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface ModelInfo {
|
|
10
|
+
id: string;
|
|
11
|
+
provider: Provider;
|
|
12
|
+
displayName?: string;
|
|
13
|
+
contextWindow?: number;
|
|
14
|
+
supportsImages?: boolean;
|
|
15
|
+
supportsTools?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface ToolCall {
|
|
18
|
+
id: string;
|
|
19
|
+
name: string;
|
|
20
|
+
arguments: Record<string, unknown>;
|
|
21
|
+
status?: "pending" | "running" | "succeeded" | "failed";
|
|
22
|
+
output?: string;
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|