@stigmer/react 3.1.1 → 3.1.2
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/composer/SessionComposer.d.ts +24 -1
- package/composer/SessionComposer.d.ts.map +1 -1
- package/composer/SessionComposer.js +19 -8
- package/composer/SessionComposer.js.map +1 -1
- package/execution/ArtifactContentRenderer.d.ts +11 -1
- package/execution/ArtifactContentRenderer.d.ts.map +1 -1
- package/execution/ArtifactContentRenderer.js +39 -15
- package/execution/ArtifactContentRenderer.js.map +1 -1
- package/execution/FilePathContext.d.ts +8 -1
- package/execution/FilePathContext.d.ts.map +1 -1
- package/execution/FilePathContext.js.map +1 -1
- package/execution/FilePathLink.d.ts.map +1 -1
- package/execution/FilePathLink.js +21 -6
- package/execution/FilePathLink.js.map +1 -1
- package/execution/MessageEntry.d.ts +29 -0
- package/execution/MessageEntry.d.ts.map +1 -1
- package/execution/MessageEntry.js +29 -5
- package/execution/MessageEntry.js.map +1 -1
- package/execution/MessageThread.d.ts +76 -13
- package/execution/MessageThread.d.ts.map +1 -1
- package/execution/MessageThread.js +178 -24
- package/execution/MessageThread.js.map +1 -1
- package/execution/PlanArtifactCard.d.ts +27 -18
- package/execution/PlanArtifactCard.d.ts.map +1 -1
- package/execution/PlanArtifactCard.js +13 -23
- package/execution/PlanArtifactCard.js.map +1 -1
- package/execution/PlanDocumentMessage.d.ts +32 -0
- package/execution/PlanDocumentMessage.d.ts.map +1 -0
- package/execution/PlanDocumentMessage.js +37 -0
- package/execution/PlanDocumentMessage.js.map +1 -0
- package/execution/PlanStreamingCard.d.ts +45 -0
- package/execution/PlanStreamingCard.d.ts.map +1 -0
- package/execution/PlanStreamingCard.js +35 -0
- package/execution/PlanStreamingCard.js.map +1 -0
- package/execution/index.d.ts +5 -1
- package/execution/index.d.ts.map +1 -1
- package/execution/index.js +2 -0
- package/execution/index.js.map +1 -1
- package/execution/useCreateAgentExecution.d.ts +10 -0
- package/execution/useCreateAgentExecution.d.ts.map +1 -1
- package/execution/useCreateAgentExecution.js +5 -1
- package/execution/useCreateAgentExecution.js.map +1 -1
- package/github/decodeGitHubContent.d.ts +29 -0
- package/github/decodeGitHubContent.d.ts.map +1 -0
- package/github/decodeGitHubContent.js +72 -0
- package/github/decodeGitHubContent.js.map +1 -0
- package/github/index.d.ts +1 -0
- package/github/index.d.ts.map +1 -1
- package/github/index.js +1 -0
- package/github/index.js.map +1 -1
- package/github/useGitHubFileReader.d.ts +26 -0
- package/github/useGitHubFileReader.d.ts.map +1 -0
- package/github/useGitHubFileReader.js +106 -0
- package/github/useGitHubFileReader.js.map +1 -0
- package/github/useGitHubTreeLister.d.ts.map +1 -1
- package/github/useGitHubTreeLister.js +6 -2
- package/github/useGitHubTreeLister.js.map +1 -1
- package/index.d.ts +9 -9
- package/index.d.ts.map +1 -1
- package/index.js +5 -5
- package/index.js.map +1 -1
- package/internal/ResizableSplit.d.ts +72 -22
- package/internal/ResizableSplit.d.ts.map +1 -1
- package/internal/ResizableSplit.js +96 -38
- package/internal/ResizableSplit.js.map +1 -1
- package/internal/VirtualizedThread.d.ts +5 -3
- package/internal/VirtualizedThread.d.ts.map +1 -1
- package/internal/VirtualizedThread.js +6 -4
- package/internal/VirtualizedThread.js.map +1 -1
- package/internal/file-icons/index.d.ts +17 -0
- package/internal/file-icons/index.d.ts.map +1 -0
- package/internal/file-icons/index.js +60 -0
- package/internal/file-icons/index.js.map +1 -0
- package/internal/file-tree/FileTreeNode.d.ts +18 -1
- package/internal/file-tree/FileTreeNode.d.ts.map +1 -1
- package/internal/file-tree/FileTreeNode.js +11 -2
- package/internal/file-tree/FileTreeNode.js.map +1 -1
- package/internal/markdown-components.d.ts +38 -1
- package/internal/markdown-components.d.ts.map +1 -1
- package/internal/markdown-components.js +86 -11
- package/internal/markdown-components.js.map +1 -1
- package/{workflow → internal}/motion-preference.d.ts +7 -4
- package/internal/motion-preference.d.ts.map +1 -0
- package/{workflow → internal}/motion-preference.js +7 -4
- package/internal/motion-preference.js.map +1 -0
- package/internal/store/index.d.ts +33 -0
- package/internal/store/index.d.ts.map +1 -1
- package/internal/store/index.js +59 -0
- package/internal/store/index.js.map +1 -1
- package/internal/store/workspace-editors-store.d.ts +145 -0
- package/internal/store/workspace-editors-store.d.ts.map +1 -0
- package/internal/store/workspace-editors-store.js +208 -0
- package/internal/store/workspace-editors-store.js.map +1 -0
- package/internal/store/workspace-file-selection-store.d.ts +38 -0
- package/internal/store/workspace-file-selection-store.d.ts.map +1 -0
- package/internal/store/workspace-file-selection-store.js +62 -0
- package/internal/store/workspace-file-selection-store.js.map +1 -0
- package/internal/useRevealLine.d.ts +49 -0
- package/internal/useRevealLine.d.ts.map +1 -0
- package/internal/useRevealLine.js +43 -0
- package/internal/useRevealLine.js.map +1 -0
- package/library/detect-plan-artifact.d.ts +21 -0
- package/library/detect-plan-artifact.d.ts.map +1 -1
- package/library/detect-plan-artifact.js +20 -0
- package/library/detect-plan-artifact.js.map +1 -1
- package/library/detect-streaming-plan.d.ts +45 -0
- package/library/detect-streaming-plan.d.ts.map +1 -0
- package/library/detect-streaming-plan.js +83 -0
- package/library/detect-streaming-plan.js.map +1 -0
- package/library/index.d.ts +4 -1
- package/library/index.d.ts.map +1 -1
- package/library/index.js +2 -1
- package/library/index.js.map +1 -1
- package/package.json +4 -4
- package/session/NewSessionViewer.d.ts +19 -4
- package/session/NewSessionViewer.d.ts.map +1 -1
- package/session/NewSessionViewer.js +52 -25
- package/session/NewSessionViewer.js.map +1 -1
- package/session/PlanEditor.d.ts +55 -0
- package/session/PlanEditor.d.ts.map +1 -0
- package/session/PlanEditor.js +88 -0
- package/session/PlanEditor.js.map +1 -0
- package/session/PlanStreamingDocument.d.ts +30 -0
- package/session/PlanStreamingDocument.d.ts.map +1 -0
- package/session/PlanStreamingDocument.js +37 -0
- package/session/PlanStreamingDocument.js.map +1 -0
- package/session/SessionPanelChip.d.ts +26 -0
- package/session/SessionPanelChip.d.ts.map +1 -0
- package/session/SessionPanelChip.js +40 -0
- package/session/SessionPanelChip.js.map +1 -0
- package/session/SessionViewer.d.ts +34 -7
- package/session/SessionViewer.d.ts.map +1 -1
- package/session/SessionViewer.js +315 -33
- package/session/SessionViewer.js.map +1 -1
- package/session/{inspector → facets}/ArtifactsTab.d.ts +10 -2
- package/session/facets/ArtifactsTab.d.ts.map +1 -0
- package/session/{inspector → facets}/ArtifactsTab.js +8 -3
- package/session/facets/ArtifactsTab.js.map +1 -0
- package/session/{inspector → facets}/ChangesTab.d.ts +3 -3
- package/session/facets/ChangesTab.d.ts.map +1 -0
- package/session/{inspector → facets}/ChangesTab.js +3 -3
- package/session/facets/ChangesTab.js.map +1 -0
- package/session/facets/InspectTab.d.ts.map +1 -0
- package/session/facets/InspectTab.js.map +1 -0
- package/session/{inspector → facets}/SetupTab.d.ts +11 -2
- package/session/facets/SetupTab.d.ts.map +1 -0
- package/session/{inspector → facets}/SetupTab.js +4 -3
- package/session/facets/SetupTab.js.map +1 -0
- package/session/{inspector → facets}/UsageTab.d.ts +1 -1
- package/session/facets/UsageTab.d.ts.map +1 -0
- package/session/{inspector → facets}/UsageTab.js +1 -1
- package/session/facets/UsageTab.js.map +1 -0
- package/session/{inspector → facets}/index.d.ts +0 -6
- package/session/facets/index.d.ts.map +1 -0
- package/session/{inspector → facets}/index.js +0 -3
- package/session/facets/index.js.map +1 -0
- package/session/index.d.ts +11 -2
- package/session/index.d.ts.map +1 -1
- package/session/index.js +15 -2
- package/session/index.js.map +1 -1
- package/session/plan-document.d.ts +9 -0
- package/session/plan-document.d.ts.map +1 -0
- package/session/plan-document.js +17 -0
- package/session/plan-document.js.map +1 -0
- package/session/useOpenFileChange.d.ts +20 -0
- package/session/useOpenFileChange.d.ts.map +1 -0
- package/session/useOpenFileChange.js +31 -0
- package/session/useOpenFileChange.js.map +1 -0
- package/session/usePlanDraft.d.ts +52 -0
- package/session/usePlanDraft.d.ts.map +1 -0
- package/session/usePlanDraft.js +63 -0
- package/session/usePlanDraft.js.map +1 -0
- package/session/useSessionConversation.d.ts +6 -0
- package/session/useSessionConversation.d.ts.map +1 -1
- package/session/useSessionConversation.js +1 -0
- package/session/useSessionConversation.js.map +1 -1
- package/session/useSessionPageFlow.d.ts.map +1 -1
- package/session/useSessionPageFlow.js +1 -0
- package/session/useSessionPageFlow.js.map +1 -1
- package/session/useSessionPanel.d.ts +120 -0
- package/session/useSessionPanel.d.ts.map +1 -0
- package/session/useSessionPanel.js +130 -0
- package/session/useSessionPanel.js.map +1 -0
- package/session/useSessionRailViews.d.ts +45 -0
- package/session/useSessionRailViews.d.ts.map +1 -0
- package/session/useSessionRailViews.js +105 -0
- package/session/useSessionRailViews.js.map +1 -0
- package/src/composer/SessionComposer.tsx +52 -10
- package/src/composer/__tests__/SessionComposer-contract.test.tsx +58 -4
- package/src/execution/ArtifactContentRenderer.tsx +101 -24
- package/src/execution/FilePathContext.tsx +8 -1
- package/src/execution/FilePathLink.tsx +22 -6
- package/src/execution/MessageEntry.tsx +111 -1
- package/src/execution/MessageThread.tsx +291 -36
- package/src/execution/PlanArtifactCard.tsx +63 -31
- package/src/execution/PlanDocumentMessage.tsx +96 -0
- package/src/execution/PlanStreamingCard.tsx +137 -0
- package/src/execution/__tests__/ArtifactContentRenderer.test.tsx +80 -1
- package/src/execution/__tests__/FilePathLink.test.tsx +87 -0
- package/src/execution/__tests__/MessageThread.test.tsx +101 -0
- package/src/execution/__tests__/PlanArtifactCard.test.tsx +66 -12
- package/src/execution/__tests__/PlanDocumentMessage.test.tsx +55 -0
- package/src/execution/__tests__/PlanStreamingCard.test.tsx +49 -0
- package/src/execution/__tests__/buildThreadItems-plan-completion.test.ts +504 -22
- package/src/execution/__tests__/message-entry.test.tsx +48 -0
- package/src/execution/__tests__/useCreateAgentExecution.test.tsx +85 -0
- package/src/execution/index.ts +7 -1
- package/src/execution/useCreateAgentExecution.ts +16 -1
- package/src/github/__tests__/decodeGitHubContent.test.ts +102 -0
- package/src/github/__tests__/useGitHubFileReader.test.ts +183 -0
- package/src/github/decodeGitHubContent.ts +83 -0
- package/src/github/index.ts +1 -0
- package/src/github/useGitHubFileReader.ts +152 -0
- package/src/github/useGitHubTreeLister.ts +6 -2
- package/src/index.ts +63 -9
- package/src/internal/ResizableSplit.tsx +184 -51
- package/src/internal/VirtualizedThread.tsx +12 -4
- package/src/internal/__tests__/ResizableSplit.test.tsx +125 -3
- package/src/internal/__tests__/markdown-components.test.tsx +68 -0
- package/src/internal/__tests__/useRevealLine.test.tsx +97 -0
- package/src/internal/file-icons/__tests__/file-icons.test.tsx +35 -0
- package/src/internal/file-icons/index.tsx +137 -0
- package/src/internal/file-tree/FileTreeNode.tsx +43 -3
- package/src/internal/file-tree/__tests__/FileTreeNode-explorer.test.tsx +86 -0
- package/src/internal/markdown-components.tsx +116 -11
- package/src/{workflow → internal}/motion-preference.ts +7 -4
- package/src/internal/store/__tests__/workspace-editors-store.test.ts +216 -0
- package/src/internal/store/__tests__/workspace-file-selection-store.test.ts +118 -0
- package/src/internal/store/index.ts +94 -0
- package/src/internal/store/workspace-editors-store.ts +315 -0
- package/src/internal/store/workspace-file-selection-store.ts +88 -0
- package/src/internal/useRevealLine.ts +81 -0
- package/src/library/__tests__/detect-plan-artifact.test.ts +48 -0
- package/src/library/__tests__/detect-streaming-plan.test.ts +234 -0
- package/src/library/detect-plan-artifact.ts +35 -0
- package/src/library/detect-streaming-plan.ts +108 -0
- package/src/library/index.ts +5 -0
- package/src/session/NewSessionViewer.tsx +123 -55
- package/src/session/PlanEditor.tsx +361 -0
- package/src/session/PlanStreamingDocument.tsx +97 -0
- package/src/session/SessionPanelChip.tsx +103 -0
- package/src/session/SessionViewer.tsx +617 -90
- package/src/session/__tests__/NewSessionViewer.test.tsx +148 -0
- package/src/session/__tests__/PlanEditor.test.tsx +217 -0
- package/src/session/__tests__/PlanStreamingDocument.test.tsx +50 -0
- package/src/session/__tests__/SessionPanelChip.test.tsx +42 -0
- package/src/session/__tests__/SessionViewer-fileReviewDock.test.tsx +9 -4
- package/src/session/__tests__/SessionViewer-transcriptFileOpen.test.tsx +205 -0
- package/src/session/__tests__/audienceWiring.test.tsx +55 -19
- package/src/session/__tests__/useOpenFileChange.test.tsx +82 -0
- package/src/session/__tests__/usePlanDraft.test.ts +102 -0
- package/src/session/__tests__/useSessionPanel.test.ts +298 -0
- package/src/session/__tests__/useSessionRailViews.test.tsx +124 -0
- package/src/session/{inspector → facets}/ArtifactsTab.tsx +27 -5
- package/src/session/{inspector → facets}/ChangesTab.tsx +3 -3
- package/src/session/{inspector → facets}/SetupTab.tsx +13 -1
- package/src/session/{inspector → facets}/UsageTab.tsx +1 -1
- package/src/session/{inspector → facets}/__tests__/ArtifactsTab.test.tsx +35 -1
- package/src/session/facets/__tests__/SetupTab.test.tsx +44 -0
- package/src/session/{inspector → facets}/index.ts +0 -16
- package/src/session/index.ts +30 -13
- package/src/session/plan-document.ts +19 -0
- package/src/session/useOpenFileChange.ts +53 -0
- package/src/session/usePlanDraft.ts +109 -0
- package/src/session/useSessionConversation.ts +7 -0
- package/src/session/useSessionPageFlow.ts +1 -0
- package/src/session/useSessionPanel.ts +288 -0
- package/src/session/useSessionRailViews.tsx +200 -0
- package/src/workflow/WorkflowExecutionGraph.tsx +1 -1
- package/src/workflow/index.ts +1 -1
- package/src/workflow/useFollowExecution.ts +1 -1
- package/src/workspace/EditorTabs.tsx +145 -0
- package/src/workspace/ExplorerTree.tsx +247 -0
- package/src/workspace/FileViewer.tsx +516 -0
- package/src/workspace/WorkspaceContentSearch.tsx +478 -0
- package/src/workspace/WorkspaceContentSearcher.ts +70 -0
- package/src/workspace/WorkspaceFileLister.ts +11 -0
- package/src/workspace/WorkspaceFileReader.ts +57 -0
- package/src/workspace/WorkspaceFileSearch.tsx +429 -0
- package/src/workspace/WorkspaceSurface.tsx +781 -0
- package/src/workspace/__tests__/EditorTabs.test.tsx +100 -0
- package/src/workspace/__tests__/ExplorerTree.test.tsx +152 -0
- package/src/workspace/__tests__/FileViewer.test.tsx +421 -0
- package/src/workspace/__tests__/WorkspaceContentSearch.test.tsx +196 -0
- package/src/workspace/__tests__/WorkspaceFileSearch.test.tsx +206 -0
- package/src/workspace/__tests__/WorkspaceSurface.test.tsx +348 -0
- package/src/workspace/__tests__/findChangeForSelection.test.ts +132 -0
- package/src/workspace/__tests__/matchContentPreview.test.ts +55 -0
- package/src/workspace/__tests__/matchWorkspaceFiles.test.ts +104 -0
- package/src/workspace/__tests__/resolveWorkspaceFileSelection.test.ts +135 -0
- package/src/workspace/__tests__/useWorkspaceContentSearch.test.tsx +196 -0
- package/src/workspace/__tests__/useWorkspaceFileContent.test.tsx +190 -0
- package/src/workspace/__tests__/useWorkspaceFileSearch.test.tsx +162 -0
- package/src/workspace/findChangeForSelection.ts +61 -0
- package/src/workspace/index.ts +56 -2
- package/src/workspace/matchContentPreview.ts +51 -0
- package/src/workspace/matchWorkspaceFiles.ts +86 -0
- package/src/workspace/resolveWorkspaceFileSelection.ts +119 -0
- package/src/workspace/useWorkspaceContentSearch.ts +228 -0
- package/src/workspace/useWorkspaceFileContent.ts +129 -0
- package/src/workspace/useWorkspaceFileSearch.ts +184 -0
- package/src/workspace/useWorkspaceFiles.ts +27 -27
- package/src/workspace/workspaceListingCache.ts +93 -0
- package/styles.css +1 -1
- package/workflow/WorkflowExecutionGraph.js +1 -1
- package/workflow/WorkflowExecutionGraph.js.map +1 -1
- package/workflow/index.d.ts +1 -1
- package/workflow/index.d.ts.map +1 -1
- package/workflow/index.js +1 -1
- package/workflow/index.js.map +1 -1
- package/workflow/useFollowExecution.js +1 -1
- package/workflow/useFollowExecution.js.map +1 -1
- package/workspace/EditorTabs.d.ts +29 -0
- package/workspace/EditorTabs.d.ts.map +1 -0
- package/workspace/EditorTabs.js +66 -0
- package/workspace/EditorTabs.js.map +1 -0
- package/workspace/ExplorerTree.d.ts +32 -0
- package/workspace/ExplorerTree.d.ts.map +1 -0
- package/workspace/ExplorerTree.js +45 -0
- package/workspace/ExplorerTree.js.map +1 -0
- package/workspace/FileViewer.d.ts +93 -0
- package/workspace/FileViewer.d.ts.map +1 -0
- package/workspace/FileViewer.js +182 -0
- package/workspace/FileViewer.js.map +1 -0
- package/workspace/WorkspaceContentSearch.d.ts +41 -0
- package/workspace/WorkspaceContentSearch.d.ts.map +1 -0
- package/workspace/WorkspaceContentSearch.js +195 -0
- package/workspace/WorkspaceContentSearch.js.map +1 -0
- package/workspace/WorkspaceContentSearcher.d.ts +59 -0
- package/workspace/WorkspaceContentSearcher.d.ts.map +1 -0
- package/workspace/WorkspaceContentSearcher.js +7 -0
- package/workspace/WorkspaceContentSearcher.js.map +1 -0
- package/workspace/WorkspaceFileLister.d.ts +11 -0
- package/workspace/WorkspaceFileLister.d.ts.map +1 -1
- package/workspace/WorkspaceFileReader.d.ts +48 -0
- package/workspace/WorkspaceFileReader.d.ts.map +1 -0
- package/workspace/WorkspaceFileReader.js +11 -0
- package/workspace/WorkspaceFileReader.js.map +1 -0
- package/workspace/WorkspaceFileSearch.d.ts +32 -0
- package/workspace/WorkspaceFileSearch.d.ts.map +1 -0
- package/workspace/WorkspaceFileSearch.js +155 -0
- package/workspace/WorkspaceFileSearch.js.map +1 -0
- package/workspace/WorkspaceSurface.d.ts +151 -0
- package/workspace/WorkspaceSurface.d.ts.map +1 -0
- package/workspace/WorkspaceSurface.js +184 -0
- package/workspace/WorkspaceSurface.js.map +1 -0
- package/workspace/findChangeForSelection.d.ts +19 -0
- package/workspace/findChangeForSelection.d.ts.map +1 -0
- package/workspace/findChangeForSelection.js +46 -0
- package/workspace/findChangeForSelection.js.map +1 -0
- package/workspace/index.d.ts +24 -2
- package/workspace/index.d.ts.map +1 -1
- package/workspace/index.js +13 -1
- package/workspace/index.js.map +1 -1
- package/workspace/matchContentPreview.d.ts +21 -0
- package/workspace/matchContentPreview.d.ts.map +1 -0
- package/workspace/matchContentPreview.js +36 -0
- package/workspace/matchContentPreview.js.map +1 -0
- package/workspace/matchWorkspaceFiles.d.ts +30 -0
- package/workspace/matchWorkspaceFiles.d.ts.map +1 -0
- package/workspace/matchWorkspaceFiles.js +58 -0
- package/workspace/matchWorkspaceFiles.js.map +1 -0
- package/workspace/resolveWorkspaceFileSelection.d.ts +19 -0
- package/workspace/resolveWorkspaceFileSelection.d.ts.map +1 -0
- package/workspace/resolveWorkspaceFileSelection.js +115 -0
- package/workspace/resolveWorkspaceFileSelection.js.map +1 -0
- package/workspace/useWorkspaceContentSearch.d.ts +69 -0
- package/workspace/useWorkspaceContentSearch.d.ts.map +1 -0
- package/workspace/useWorkspaceContentSearch.js +154 -0
- package/workspace/useWorkspaceContentSearch.js.map +1 -0
- package/workspace/useWorkspaceFileContent.d.ts +73 -0
- package/workspace/useWorkspaceFileContent.d.ts.map +1 -0
- package/workspace/useWorkspaceFileContent.js +57 -0
- package/workspace/useWorkspaceFileContent.js.map +1 -0
- package/workspace/useWorkspaceFileSearch.d.ts +61 -0
- package/workspace/useWorkspaceFileSearch.d.ts.map +1 -0
- package/workspace/useWorkspaceFileSearch.js +119 -0
- package/workspace/useWorkspaceFileSearch.js.map +1 -0
- package/workspace/useWorkspaceFiles.d.ts +13 -5
- package/workspace/useWorkspaceFiles.d.ts.map +1 -1
- package/workspace/useWorkspaceFiles.js +18 -19
- package/workspace/useWorkspaceFiles.js.map +1 -1
- package/workspace/workspaceListingCache.d.ts +47 -0
- package/workspace/workspaceListingCache.d.ts.map +1 -0
- package/workspace/workspaceListingCache.js +55 -0
- package/workspace/workspaceListingCache.js.map +1 -0
- package/session/inspector/ArtifactsTab.d.ts.map +0 -1
- package/session/inspector/ArtifactsTab.js.map +0 -1
- package/session/inspector/ChangesTab.d.ts.map +0 -1
- package/session/inspector/ChangesTab.js.map +0 -1
- package/session/inspector/InspectTab.d.ts.map +0 -1
- package/session/inspector/InspectTab.js.map +0 -1
- package/session/inspector/SessionInspector.d.ts +0 -64
- package/session/inspector/SessionInspector.d.ts.map +0 -1
- package/session/inspector/SessionInspector.js +0 -53
- package/session/inspector/SessionInspector.js.map +0 -1
- package/session/inspector/SetupTab.d.ts.map +0 -1
- package/session/inspector/SetupTab.js.map +0 -1
- package/session/inspector/UsageTab.d.ts.map +0 -1
- package/session/inspector/UsageTab.js.map +0 -1
- package/session/inspector/WorkspaceTab.d.ts +0 -35
- package/session/inspector/WorkspaceTab.d.ts.map +0 -1
- package/session/inspector/WorkspaceTab.js +0 -75
- package/session/inspector/WorkspaceTab.js.map +0 -1
- package/session/inspector/index.d.ts.map +0 -1
- package/session/inspector/index.js.map +0 -1
- package/session/inspector/useSessionInspector.d.ts +0 -49
- package/session/inspector/useSessionInspector.d.ts.map +0 -1
- package/session/inspector/useSessionInspector.js +0 -122
- package/session/inspector/useSessionInspector.js.map +0 -1
- package/src/session/inspector/SessionInspector.tsx +0 -162
- package/src/session/inspector/WorkspaceTab.tsx +0 -245
- package/src/session/inspector/__tests__/useSessionInspector.test.ts +0 -251
- package/src/session/inspector/useSessionInspector.ts +0 -178
- package/src/workspace/WorkspaceEntryFiles.tsx +0 -196
- package/workflow/motion-preference.d.ts.map +0 -1
- package/workflow/motion-preference.js.map +0 -1
- package/workspace/WorkspaceEntryFiles.d.ts +0 -22
- package/workspace/WorkspaceEntryFiles.d.ts.map +0 -1
- package/workspace/WorkspaceEntryFiles.js +0 -58
- package/workspace/WorkspaceEntryFiles.js.map +0 -1
- /package/session/{inspector → facets}/InspectTab.d.ts +0 -0
- /package/session/{inspector → facets}/InspectTab.js +0 -0
- /package/src/{workflow → internal}/__tests__/motion-preference.test.ts +0 -0
- /package/src/session/{inspector → facets}/InspectTab.tsx +0 -0
- /package/src/session/{inspector → facets}/__tests__/ChangesTab.test.tsx +0 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { create } from "@bufbuild/protobuf";
|
|
3
|
+
import {
|
|
4
|
+
AgentExecutionSchema,
|
|
5
|
+
AgentExecutionStatusSchema,
|
|
6
|
+
type AgentExecution,
|
|
7
|
+
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
8
|
+
import {
|
|
9
|
+
AgentExecutionSpecSchema,
|
|
10
|
+
ExecutionConfigSchema,
|
|
11
|
+
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/spec_pb";
|
|
12
|
+
import { AgentMessageSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
|
|
13
|
+
import {
|
|
14
|
+
ExecutionPhase,
|
|
15
|
+
InteractionMode,
|
|
16
|
+
MessageType,
|
|
17
|
+
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
18
|
+
import { findStreamingPlan } from "../detect-streaming-plan";
|
|
19
|
+
|
|
20
|
+
function makeMessage(type: MessageType, content: string) {
|
|
21
|
+
const msg = create(AgentMessageSchema);
|
|
22
|
+
msg.type = type;
|
|
23
|
+
msg.content = content;
|
|
24
|
+
return msg;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function makeExecution(opts: {
|
|
28
|
+
phase?: ExecutionPhase;
|
|
29
|
+
interactionMode?: InteractionMode;
|
|
30
|
+
messages?: ReturnType<typeof makeMessage>[];
|
|
31
|
+
}): AgentExecution {
|
|
32
|
+
const exec = create(AgentExecutionSchema);
|
|
33
|
+
|
|
34
|
+
const spec = create(AgentExecutionSpecSchema);
|
|
35
|
+
if (opts.interactionMode !== undefined) {
|
|
36
|
+
const config = create(ExecutionConfigSchema);
|
|
37
|
+
config.interactionMode = opts.interactionMode;
|
|
38
|
+
spec.executionConfig = config;
|
|
39
|
+
}
|
|
40
|
+
exec.spec = spec;
|
|
41
|
+
|
|
42
|
+
const status = create(AgentExecutionStatusSchema);
|
|
43
|
+
status.phase = opts.phase ?? ExecutionPhase.EXECUTION_IN_PROGRESS;
|
|
44
|
+
if (opts.messages) {
|
|
45
|
+
status.messages = opts.messages;
|
|
46
|
+
}
|
|
47
|
+
exec.status = status;
|
|
48
|
+
|
|
49
|
+
return exec;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** A live Plan-mode execution with the given messages — the common case. */
|
|
53
|
+
function livePlanExecution(...messages: ReturnType<typeof makeMessage>[]) {
|
|
54
|
+
return makeExecution({
|
|
55
|
+
phase: ExecutionPhase.EXECUTION_IN_PROGRESS,
|
|
56
|
+
interactionMode: InteractionMode.PLAN,
|
|
57
|
+
messages,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
describe("findStreamingPlan — mode and phase gating", () => {
|
|
62
|
+
const planMessage = makeMessage(MessageType.MESSAGE_AI, "# The Plan\n\nBody");
|
|
63
|
+
|
|
64
|
+
it("detects a plan on a live Plan-mode execution", () => {
|
|
65
|
+
const plan = findStreamingPlan(livePlanExecution(planMessage));
|
|
66
|
+
expect(plan).toBeDefined();
|
|
67
|
+
expect(plan!.messageIndex).toBe(0);
|
|
68
|
+
expect(plan!.displayText).toBe("# The Plan\n\nBody");
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("returns undefined for null/undefined executions", () => {
|
|
72
|
+
expect(findStreamingPlan(null)).toBeUndefined();
|
|
73
|
+
expect(findStreamingPlan(undefined)).toBeUndefined();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("returns undefined for an Agent-mode execution, even with a plan-shaped message", () => {
|
|
77
|
+
const exec = makeExecution({
|
|
78
|
+
phase: ExecutionPhase.EXECUTION_IN_PROGRESS,
|
|
79
|
+
interactionMode: InteractionMode.AGENT,
|
|
80
|
+
messages: [planMessage],
|
|
81
|
+
});
|
|
82
|
+
expect(findStreamingPlan(exec)).toBeUndefined();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("returns undefined when no interaction mode is set", () => {
|
|
86
|
+
const exec = makeExecution({
|
|
87
|
+
phase: ExecutionPhase.EXECUTION_IN_PROGRESS,
|
|
88
|
+
messages: [planMessage],
|
|
89
|
+
});
|
|
90
|
+
expect(findStreamingPlan(exec)).toBeUndefined();
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it.each([
|
|
94
|
+
ExecutionPhase.EXECUTION_COMPLETED,
|
|
95
|
+
ExecutionPhase.EXECUTION_FAILED,
|
|
96
|
+
ExecutionPhase.EXECUTION_CANCELLED,
|
|
97
|
+
ExecutionPhase.EXECUTION_TERMINATED,
|
|
98
|
+
])("returns undefined for terminal phase %s", (phase) => {
|
|
99
|
+
const exec = makeExecution({
|
|
100
|
+
phase,
|
|
101
|
+
interactionMode: InteractionMode.PLAN,
|
|
102
|
+
messages: [planMessage],
|
|
103
|
+
});
|
|
104
|
+
expect(findStreamingPlan(exec)).toBeUndefined();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("detects during a non-terminal wait (approval gate mid-turn)", () => {
|
|
108
|
+
const exec = makeExecution({
|
|
109
|
+
phase: ExecutionPhase.EXECUTION_WAITING_FOR_APPROVAL,
|
|
110
|
+
interactionMode: InteractionMode.PLAN,
|
|
111
|
+
messages: [planMessage],
|
|
112
|
+
});
|
|
113
|
+
expect(findStreamingPlan(exec)).toBeDefined();
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
describe("findStreamingPlan — candidate selection", () => {
|
|
118
|
+
it("considers only the LAST content-bearing AI message", () => {
|
|
119
|
+
// The earlier plan-shaped message is settled narration once a later AI
|
|
120
|
+
// message exists — falling back to it would promote the wrong text.
|
|
121
|
+
const exec = livePlanExecution(
|
|
122
|
+
makeMessage(MessageType.MESSAGE_AI, "# Early heading in narration"),
|
|
123
|
+
makeMessage(MessageType.MESSAGE_AI, "Now let me check the tests."),
|
|
124
|
+
);
|
|
125
|
+
expect(findStreamingPlan(exec)).toBeUndefined();
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("skips trailing empty AI messages (extractFinalPlanText's rule)", () => {
|
|
129
|
+
const exec = livePlanExecution(
|
|
130
|
+
makeMessage(MessageType.MESSAGE_AI, "# The Plan\n\nBody"),
|
|
131
|
+
makeMessage(MessageType.MESSAGE_AI, " "),
|
|
132
|
+
);
|
|
133
|
+
expect(findStreamingPlan(exec)?.messageIndex).toBe(0);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it("ignores non-AI message types when selecting the candidate", () => {
|
|
137
|
+
const exec = livePlanExecution(
|
|
138
|
+
makeMessage(MessageType.MESSAGE_AI, "# The Plan\n\nBody"),
|
|
139
|
+
makeMessage(MessageType.MESSAGE_THINKING, "hmm, one more thing"),
|
|
140
|
+
makeMessage(MessageType.MESSAGE_TOOL, "tool output"),
|
|
141
|
+
);
|
|
142
|
+
expect(findStreamingPlan(exec)?.messageIndex).toBe(0);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("returns undefined when there are no messages", () => {
|
|
146
|
+
expect(findStreamingPlan(livePlanExecution())).toBeUndefined();
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
describe("findStreamingPlan — H1 convention", () => {
|
|
151
|
+
it("does not detect narration (no leading H1)", () => {
|
|
152
|
+
const exec = livePlanExecution(
|
|
153
|
+
makeMessage(MessageType.MESSAGE_AI, "Let me explore the codebase."),
|
|
154
|
+
);
|
|
155
|
+
expect(findStreamingPlan(exec)).toBeUndefined();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it("does not detect a lone '#' first token (title not started yet)", () => {
|
|
159
|
+
const exec = livePlanExecution(makeMessage(MessageType.MESSAGE_AI, "#"));
|
|
160
|
+
expect(findStreamingPlan(exec)).toBeUndefined();
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it("detects the moment the H1 gains its first title character", () => {
|
|
164
|
+
const exec = livePlanExecution(makeMessage(MessageType.MESSAGE_AI, "# T"));
|
|
165
|
+
expect(findStreamingPlan(exec)?.displayText).toBe("# T");
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it("does not detect an H2-led message (## is a section, not a plan title)", () => {
|
|
169
|
+
const exec = livePlanExecution(
|
|
170
|
+
makeMessage(MessageType.MESSAGE_AI, "## Notes\n\nSome section"),
|
|
171
|
+
);
|
|
172
|
+
expect(findStreamingPlan(exec)).toBeUndefined();
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it("tolerates leading blank lines before the H1", () => {
|
|
176
|
+
const exec = livePlanExecution(
|
|
177
|
+
makeMessage(MessageType.MESSAGE_AI, "\n\n# The Plan\n\nBody"),
|
|
178
|
+
);
|
|
179
|
+
expect(findStreamingPlan(exec)).toBeDefined();
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
describe("findStreamingPlan — unterminated-fence tolerance", () => {
|
|
184
|
+
it("unwraps an unterminated ```markdown fence", () => {
|
|
185
|
+
const exec = livePlanExecution(
|
|
186
|
+
makeMessage(MessageType.MESSAGE_AI, "```markdown\n# The Plan\n\nBody"),
|
|
187
|
+
);
|
|
188
|
+
expect(findStreamingPlan(exec)?.displayText).toBe("# The Plan\n\nBody");
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it("unwraps an unterminated ```md fence", () => {
|
|
192
|
+
const exec = livePlanExecution(
|
|
193
|
+
makeMessage(MessageType.MESSAGE_AI, "```md\n# The Plan"),
|
|
194
|
+
);
|
|
195
|
+
expect(findStreamingPlan(exec)?.displayText).toBe("# The Plan");
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it("unwraps an unterminated bare ``` fence (plan surfaces are markdown by contract)", () => {
|
|
199
|
+
const exec = livePlanExecution(
|
|
200
|
+
makeMessage(MessageType.MESSAGE_AI, "```\n# The Plan"),
|
|
201
|
+
);
|
|
202
|
+
expect(findStreamingPlan(exec)?.displayText).toBe("# The Plan");
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it("strips the closing fence once it streams in as the final line", () => {
|
|
206
|
+
const exec = livePlanExecution(
|
|
207
|
+
makeMessage(MessageType.MESSAGE_AI, "```markdown\n# The Plan\n\nBody\n```"),
|
|
208
|
+
);
|
|
209
|
+
expect(findStreamingPlan(exec)?.displayText).toBe("# The Plan\n\nBody");
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it("keeps a code-block fence inside the plan intact", () => {
|
|
213
|
+
const content = "```markdown\n# The Plan\n\n```ts\nconst x = 1;\n```\n\nMore";
|
|
214
|
+
const exec = livePlanExecution(makeMessage(MessageType.MESSAGE_AI, content));
|
|
215
|
+
// Only the ENCLOSING fence is stripped; the ts block's fences are content.
|
|
216
|
+
expect(findStreamingPlan(exec)?.displayText).toBe(
|
|
217
|
+
"# The Plan\n\n```ts\nconst x = 1;\n```\n\nMore",
|
|
218
|
+
);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it("never unwraps a fence with another language tag (a real code block)", () => {
|
|
222
|
+
const exec = livePlanExecution(
|
|
223
|
+
makeMessage(MessageType.MESSAGE_AI, "```python\n# not a heading, a comment"),
|
|
224
|
+
);
|
|
225
|
+
expect(findStreamingPlan(exec)).toBeUndefined();
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it("does not detect a fenced message whose body has no H1", () => {
|
|
229
|
+
const exec = livePlanExecution(
|
|
230
|
+
makeMessage(MessageType.MESSAGE_AI, "```\nplain fenced text"),
|
|
231
|
+
);
|
|
232
|
+
expect(findStreamingPlan(exec)).toBeUndefined();
|
|
233
|
+
});
|
|
234
|
+
});
|
|
@@ -2,6 +2,18 @@ import type { AgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexe
|
|
|
2
2
|
import type { ExecutionArtifact } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/artifact_pb";
|
|
3
3
|
import { ExecutionArtifactKind } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* The session's current plan: the published `plan.md` artifact of the most
|
|
7
|
+
* recent execution that produced one, plus the execution it belongs to
|
|
8
|
+
* (artifact content RPCs are execution-scoped).
|
|
9
|
+
*/
|
|
10
|
+
export interface SessionPlan {
|
|
11
|
+
/** ID of the execution that published the plan. */
|
|
12
|
+
readonly executionId: string;
|
|
13
|
+
/** The published `plan.md` artifact. */
|
|
14
|
+
readonly artifact: ExecutionArtifact;
|
|
15
|
+
}
|
|
16
|
+
|
|
5
17
|
/**
|
|
6
18
|
* Canonical filename a Plan-mode execution publishes its plan under. Kept in
|
|
7
19
|
* sync with the runner's `publishPlanArtifact` (shared/plan-artifact.ts).
|
|
@@ -41,3 +53,26 @@ export function findPlanArtifact(
|
|
|
41
53
|
}
|
|
42
54
|
return undefined;
|
|
43
55
|
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Finds the session's LATEST plan across all executions — the plan the panel's
|
|
59
|
+
* plan document tab edits and "Build from plan" implements. Executions are
|
|
60
|
+
* scanned newest-first (the array is chronological), mirroring the thread's
|
|
61
|
+
* latest-plan-owns-the-build-action rule so every surface agrees on which
|
|
62
|
+
* plan is current.
|
|
63
|
+
*
|
|
64
|
+
* Returns `undefined` when no execution in the session published a plan.
|
|
65
|
+
*/
|
|
66
|
+
export function findLatestSessionPlan(
|
|
67
|
+
executions: readonly AgentExecution[],
|
|
68
|
+
): SessionPlan | undefined {
|
|
69
|
+
for (let i = executions.length - 1; i >= 0; i--) {
|
|
70
|
+
const execution = executions[i];
|
|
71
|
+
const artifact = findPlanArtifact(execution);
|
|
72
|
+
const executionId = execution.metadata?.id;
|
|
73
|
+
if (artifact && executionId) {
|
|
74
|
+
return { executionId, artifact };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { AgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
2
|
+
import {
|
|
3
|
+
InteractionMode,
|
|
4
|
+
MessageType,
|
|
5
|
+
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
6
|
+
import { isTerminalPhase } from "@stigmer/sdk";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A plan being written by a live Plan-mode execution, detected mid-stream so
|
|
10
|
+
* the UI can promote it to a document surface (panel plan tab + compact thread
|
|
11
|
+
* card) instead of letting it dump into the chat as a giant streaming bubble.
|
|
12
|
+
*/
|
|
13
|
+
export interface StreamingPlan {
|
|
14
|
+
/** Index of the plan message in `execution.status.messages`. */
|
|
15
|
+
readonly messageIndex: number;
|
|
16
|
+
/**
|
|
17
|
+
* The plan text to render on document surfaces: the message content with
|
|
18
|
+
* any enclosing plan fence stripped, streaming-tolerantly (an unterminated
|
|
19
|
+
* opening fence is stripped too — see {@link findStreamingPlan}). Purely a
|
|
20
|
+
* display projection; the stored message is never mutated.
|
|
21
|
+
*/
|
|
22
|
+
readonly displayText: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Opening line of a whole-message plan fence: ``` with no language tag, or
|
|
27
|
+
* tagged `markdown`/`md`. Any other tag (```python …) means the message opens
|
|
28
|
+
* with a genuine code block, not a wrapped plan, and is never unwrapped —
|
|
29
|
+
* mirroring `unwrapEnclosingMarkdownFence`'s tag rules.
|
|
30
|
+
*/
|
|
31
|
+
const OPENING_PLAN_FENCE_RE = /^(`{3,})(?:markdown|md)?[ \t]*\r?\n/;
|
|
32
|
+
|
|
33
|
+
/** A streaming plan message qualifies when it opens with an `# H1` title. */
|
|
34
|
+
const LEADING_H1_RE = /^#[ \t]/;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Streaming-tolerant unwrap of a whole-message plan fence.
|
|
38
|
+
*
|
|
39
|
+
* `unwrapEnclosingMarkdownFence` deliberately no-ops until the closing fence
|
|
40
|
+
* arrives (transcripts must stay faithful while a genuine code block is still
|
|
41
|
+
* open). A plan surface can't wait: mid-stream the closing fence hasn't
|
|
42
|
+
* streamed yet, and rendering the fence as-is turns the whole live plan into
|
|
43
|
+
* one giant code block. Because Plan mode's output IS a markdown document by
|
|
44
|
+
* contract, a message that OPENS with a bare/markdown fence is a wrapped plan
|
|
45
|
+
* — so this strips the opening fence immediately and the closing fence
|
|
46
|
+
* whenever it shows up as the final line.
|
|
47
|
+
*/
|
|
48
|
+
function unwrapStreamingPlanFence(content: string): string {
|
|
49
|
+
const trimmed = content.trim();
|
|
50
|
+
const open = OPENING_PLAN_FENCE_RE.exec(trimmed);
|
|
51
|
+
if (!open) return content;
|
|
52
|
+
const body = trimmed.slice(open[0].length);
|
|
53
|
+
// Strip the closing fence only when it is the final line (same backtick
|
|
54
|
+
// run); a fence anywhere else belongs to a code block inside the plan.
|
|
55
|
+
const close = new RegExp(`(?:^|\\r?\\n)${open[1]}[ \\t]*$`);
|
|
56
|
+
const closeMatch = close.exec(body);
|
|
57
|
+
return closeMatch ? body.slice(0, closeMatch.index) : body;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Detects the plan a live Plan-mode execution is currently writing, or
|
|
62
|
+
* `undefined` when the execution has no recognizable plan in flight.
|
|
63
|
+
*
|
|
64
|
+
* This is the third leg of the plan convention, alongside the runner's prompt
|
|
65
|
+
* directive ("your FINAL message IS the plan, starting with a single `#`
|
|
66
|
+
* title" — `plan-mode-prompt.ts`) and the completion-time artifact detection
|
|
67
|
+
* by filename ({@link isPlanArtifact}). Completion makes the plan unambiguous
|
|
68
|
+
* (the published `plan.md` artifact); mid-stream it must be inferred, and the
|
|
69
|
+
* directive's mandated shape is the inference:
|
|
70
|
+
*
|
|
71
|
+
* - the execution runs in Plan mode and is **non-terminal** (a completed turn
|
|
72
|
+
* is owned by the artifact path; a stopped/failed turn has no live plan),
|
|
73
|
+
* - the candidate is the **last content-bearing `MESSAGE_AI`** — the exact
|
|
74
|
+
* selection rule the runner's `extractFinalPlanText` and the thread's
|
|
75
|
+
* `findPlanMessageIndex` share, so all three stay in lockstep,
|
|
76
|
+
* - and that candidate opens with an `# H1` title (after tolerating an
|
|
77
|
+
* enclosing plan fence, see {@link unwrapStreamingPlanFence}) — the shape
|
|
78
|
+
* the directive mandates and narration essentially never has.
|
|
79
|
+
*
|
|
80
|
+
* Degradation is graceful by design: a model that ignores the directive
|
|
81
|
+
* simply streams its plan in the thread as before, and the completion-time
|
|
82
|
+
* pipeline is unaffected either way. Only the LAST content-bearing AI message
|
|
83
|
+
* is ever considered — an earlier message is settled narration, and falling
|
|
84
|
+
* back to it would promote the wrong text.
|
|
85
|
+
*/
|
|
86
|
+
export function findStreamingPlan(
|
|
87
|
+
execution: AgentExecution | null | undefined,
|
|
88
|
+
): StreamingPlan | undefined {
|
|
89
|
+
if (
|
|
90
|
+
execution?.spec?.executionConfig?.interactionMode !== InteractionMode.PLAN
|
|
91
|
+
) {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
const phase = execution.status?.phase;
|
|
95
|
+
if (phase === undefined || isTerminalPhase(phase)) return undefined;
|
|
96
|
+
|
|
97
|
+
const messages = execution.status?.messages ?? [];
|
|
98
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
99
|
+
const msg = messages[i];
|
|
100
|
+
if (msg.type !== MessageType.MESSAGE_AI) continue;
|
|
101
|
+
if (msg.content.trim().length === 0) continue;
|
|
102
|
+
const displayText = unwrapStreamingPlanFence(msg.content);
|
|
103
|
+
return LEADING_H1_RE.test(displayText.trimStart())
|
|
104
|
+
? { messageIndex: i, displayText }
|
|
105
|
+
: undefined;
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
package/src/library/index.ts
CHANGED
|
@@ -27,8 +27,13 @@ export type { SkillPackageDetection } from "./detect-skill-package.js";
|
|
|
27
27
|
export {
|
|
28
28
|
isPlanArtifact,
|
|
29
29
|
findPlanArtifact,
|
|
30
|
+
findLatestSessionPlan,
|
|
30
31
|
PLAN_ARTIFACT_NAME,
|
|
31
32
|
} from "./detect-plan-artifact.js";
|
|
33
|
+
export type { SessionPlan } from "./detect-plan-artifact.js";
|
|
34
|
+
|
|
35
|
+
export { findStreamingPlan } from "./detect-streaming-plan.js";
|
|
36
|
+
export type { StreamingPlan } from "./detect-streaming-plan.js";
|
|
32
37
|
|
|
33
38
|
export { useDetectSkillPackage } from "./useDetectSkillPackage.js";
|
|
34
39
|
export type { UseDetectSkillPackageReturn } from "./useDetectSkillPackage.js";
|
|
@@ -5,13 +5,19 @@ import { cn } from "@stigmer/theme";
|
|
|
5
5
|
import type { ResourceRef } from "@stigmer/sdk";
|
|
6
6
|
import type { UseGitHubConnectionReturn } from "../github/useGitHubConnection.js";
|
|
7
7
|
import type { WorkspaceFileLister } from "../workspace/WorkspaceFileLister.js";
|
|
8
|
+
import type { WorkspaceFileReader } from "../workspace/WorkspaceFileReader.js";
|
|
9
|
+
import type { WorkspaceContentSearcher } from "../workspace/WorkspaceContentSearcher.js";
|
|
8
10
|
import type { InteractionModeOption } from "../composer/index.js";
|
|
9
11
|
import { SessionComposer } from "../composer/index.js";
|
|
10
12
|
import type { HarnessOption } from "../models/harness.js";
|
|
11
13
|
import { ResizableSplit } from "../internal/ResizableSplit.js";
|
|
12
|
-
import {
|
|
13
|
-
import
|
|
14
|
+
import { useWorkspaceEditors } from "../internal/store/index.js";
|
|
15
|
+
import { WorkspaceSurface } from "../workspace/WorkspaceSurface.js";
|
|
16
|
+
import type { SetupTabProps } from "./facets/SetupTab.js";
|
|
14
17
|
import { useNewSessionFlow } from "./useNewSessionFlow.js";
|
|
18
|
+
import { useSessionPanel } from "./useSessionPanel.js";
|
|
19
|
+
import { useSessionRailViews } from "./useSessionRailViews.js";
|
|
20
|
+
import { SessionPanelChip } from "./SessionPanelChip.js";
|
|
15
21
|
import type { RuntimeEnvProvider } from "./runtime-env.js";
|
|
16
22
|
import type { SessionAudience } from "./audience.js";
|
|
17
23
|
|
|
@@ -47,6 +53,20 @@ export interface NewSessionViewerProps {
|
|
|
47
53
|
*/
|
|
48
54
|
readonly workspaceFileLister?: WorkspaceFileLister;
|
|
49
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Platform-injected content reader for the read-only file viewer. When set,
|
|
58
|
+
* clicking a file in the Workspace tree opens it in a contextual "Viewer"
|
|
59
|
+
* tab — the same capability `SessionViewer` accepts (DD-016 parity).
|
|
60
|
+
*/
|
|
61
|
+
readonly workspaceFileReader?: WorkspaceFileReader;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Platform-injected content (text) searcher — the same capability
|
|
65
|
+
* `SessionViewer` accepts (DD-016 parity). Desktop injects a native
|
|
66
|
+
* ripgrep-backed searcher; web leaves it undefined (DD-09).
|
|
67
|
+
*/
|
|
68
|
+
readonly workspaceContentSearcher?: WorkspaceContentSearcher;
|
|
69
|
+
|
|
50
70
|
/**
|
|
51
71
|
* Supplies host-app environment variables for the session's first
|
|
52
72
|
* execution (e.g. short-lived credentials for MCP tools, minted as
|
|
@@ -119,9 +139,10 @@ export interface NewSessionViewerProps {
|
|
|
119
139
|
* Owns `useNewSessionFlow` internally and composes:
|
|
120
140
|
* - **Centered composer** (primary pane): `SessionComposer` with all
|
|
121
141
|
* context pickers (agent, workspace, MCP servers, skills)
|
|
122
|
-
* - **
|
|
123
|
-
*
|
|
124
|
-
*
|
|
142
|
+
* - **Session panel** (secondary pane): the unified `WorkspaceSurface` with a
|
|
143
|
+
* Config rail view — collapsed by default behind a persistent top-right chip
|
|
144
|
+
* and homing on the Config facet when opened. Same layout model as
|
|
145
|
+
* `SessionViewer` (DD-016).
|
|
125
146
|
*
|
|
126
147
|
* Framework-agnostic — no Next.js, no Tauri, no routing deps. Host
|
|
127
148
|
* apps inject platform-specific values via props (DD-004/DD-016).
|
|
@@ -156,6 +177,8 @@ export function NewSessionViewer({
|
|
|
156
177
|
enableLocal = false,
|
|
157
178
|
onBrowseLocalFolder,
|
|
158
179
|
workspaceFileLister,
|
|
180
|
+
workspaceFileReader,
|
|
181
|
+
workspaceContentSearcher,
|
|
159
182
|
getRuntimeEnv,
|
|
160
183
|
audience = "integrator",
|
|
161
184
|
defaultHarness,
|
|
@@ -179,12 +202,25 @@ export function NewSessionViewer({
|
|
|
179
202
|
const [interactionMode, setInteractionMode] = useState<InteractionModeOption>("agent");
|
|
180
203
|
const isEndUser = audience === "endUser";
|
|
181
204
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
205
|
+
// The unified-panel controller (shared with SessionViewer, DD-016). The
|
|
206
|
+
// launcher has no execution yet, so the FSM inputs are static. It has no
|
|
207
|
+
// streaming column to isolate either, so subscribing to the editor group in
|
|
208
|
+
// the body is harmless — unlike `SessionViewer`, which subscribes one level
|
|
209
|
+
// down. Homes on Config: pre-session the Explorer is empty, while Config
|
|
210
|
+
// carries the run defaults (harness/model) worth seeing before starting.
|
|
211
|
+
const panel = useSessionPanel({
|
|
212
|
+
phase: null,
|
|
213
|
+
hasChanges: false,
|
|
214
|
+
defaultView: "configure",
|
|
215
|
+
});
|
|
216
|
+
const { editors, activeKey, activeFile, reveal } = useWorkspaceEditors(
|
|
217
|
+
panel.editorsStore,
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
// Honor a jump-to-line reveal only while it targets the active editor
|
|
221
|
+
// (DD-016 parity with SessionViewer).
|
|
222
|
+
const activeReveal =
|
|
223
|
+
reveal && reveal.key === activeKey ? reveal : undefined;
|
|
188
224
|
|
|
189
225
|
const handleRemoveAgent = useCallback(() => {
|
|
190
226
|
flow.setAgentRef(null);
|
|
@@ -240,26 +276,34 @@ export function NewSessionViewer({
|
|
|
240
276
|
],
|
|
241
277
|
);
|
|
242
278
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
)
|
|
279
|
+
// Launcher facets: Config only — no executions exist yet, so the
|
|
280
|
+
// execution-derived facets (Changes/Artifacts/Usage) don't apply.
|
|
281
|
+
const railViews = useSessionRailViews({
|
|
282
|
+
allExecutions: [],
|
|
283
|
+
org,
|
|
284
|
+
sessionConfig,
|
|
285
|
+
selectedItem: null,
|
|
286
|
+
includeExecutionFacets: false,
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
// Explorer-footer folder attach (desktop only — needs the native picker).
|
|
290
|
+
const canAddLocalFolder = enableLocal && !!onBrowseLocalFolder;
|
|
291
|
+
const handleAddLocalFolder = useCallback(async () => {
|
|
292
|
+
const path = await onBrowseLocalFolder?.();
|
|
293
|
+
if (path) flow.workspace.addLocalPath(path);
|
|
294
|
+
}, [onBrowseLocalFolder, flow.workspace.addLocalPath]);
|
|
256
295
|
|
|
257
296
|
const composerNode = (
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
297
|
+
// `my-auto` centers the composer vertically whether or not context is
|
|
298
|
+
// attached — safe-centering, not a special case: auto margins absorb free
|
|
299
|
+
// space when the composer is shorter than the pane and collapse to zero
|
|
300
|
+
// when it outgrows it, degrading to a normal top-aligned scroll. The
|
|
301
|
+
// scroll container's `py-6` keeps breathing room in that overflow case.
|
|
302
|
+
// Do NOT reintroduce a context-driven position flip: the composer must not
|
|
303
|
+
// move as context is attached (DD-16's layout-stability rationale — chrome
|
|
304
|
+
// that shifts with attached context reads as instability).
|
|
305
|
+
<div className="flex h-full flex-col items-center overflow-y-auto px-4 py-6">
|
|
306
|
+
<div className="my-auto w-full max-w-2xl space-y-6">
|
|
263
307
|
<h1 className="text-center text-lg font-medium text-foreground">
|
|
264
308
|
{heading}
|
|
265
309
|
</h1>
|
|
@@ -308,38 +352,62 @@ export function NewSessionViewer({
|
|
|
308
352
|
</div>
|
|
309
353
|
);
|
|
310
354
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
355
|
+
return (
|
|
356
|
+
<div className={cn("relative flex h-full w-full flex-col", className)}>
|
|
357
|
+
{/* Persistent chrome: the chip is always mounted, matching SessionViewer
|
|
358
|
+
(DD-016) rather than the launcher's earlier progressively-revealed
|
|
359
|
+
inspector. A toggle that appears/disappears with attached context
|
|
360
|
+
reads as instability and, worse, unmounts the open panel's only
|
|
361
|
+
collapse control when the last context item is removed. Always-on is
|
|
362
|
+
the predictable, discoverable shape; opening homes on the Config
|
|
363
|
+
facet, which carries useful defaults (harness/model) pre-session. */}
|
|
364
|
+
<div className="absolute top-2 right-6 z-10">
|
|
365
|
+
<SessionPanelChip
|
|
366
|
+
isOpen={panel.isOpen}
|
|
367
|
+
onToggle={panel.isOpen ? panel.closePanel : panel.openPanel}
|
|
368
|
+
/>
|
|
315
369
|
</div>
|
|
316
|
-
);
|
|
317
|
-
}
|
|
318
370
|
|
|
319
|
-
|
|
320
|
-
|
|
371
|
+
{/* Same unified-panel layout as SessionViewer (DD-016): collapsed by
|
|
372
|
+
default (composer fills the row); opening makes the composer the
|
|
373
|
+
fixed narrow pane and hands the flexible region to the surface.
|
|
374
|
+
Collapse goes through the split's `collapsedPane` (CSS, not
|
|
375
|
+
conditional structure), so the composer never remounts across an
|
|
376
|
+
open/close toggle. */}
|
|
321
377
|
<ResizableSplit
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
378
|
+
resizablePane="primary"
|
|
379
|
+
collapsedPane={panel.isOpen ? "none" : "secondary"}
|
|
380
|
+
defaultSize={420}
|
|
381
|
+
minSize={320}
|
|
382
|
+
maxSize={640}
|
|
383
|
+
storageKey="stgm-new-session-chat-width"
|
|
384
|
+
responsiveCollapse={panel.isOpen ? "primary" : "none"}
|
|
385
|
+
ariaLabel="Resize composer panel"
|
|
386
|
+
className="min-h-0 flex-1"
|
|
330
387
|
primary={composerNode}
|
|
331
388
|
secondary={
|
|
332
|
-
|
|
333
|
-
<
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
389
|
+
panel.isOpen ? (
|
|
390
|
+
<WorkspaceSurface
|
|
391
|
+
entries={flow.workspace.entries}
|
|
392
|
+
lister={workspaceFileLister}
|
|
393
|
+
reader={workspaceFileReader}
|
|
394
|
+
searcher={workspaceContentSearcher}
|
|
395
|
+
view={panel.view}
|
|
396
|
+
onViewChange={panel.setView}
|
|
397
|
+
extraViews={railViews}
|
|
398
|
+
onRemoveEntry={flow.workspace.remove}
|
|
399
|
+
onAddLocalFolder={canAddLocalFolder ? handleAddLocalFolder : undefined}
|
|
400
|
+
editors={editors}
|
|
401
|
+
selectedFile={activeFile}
|
|
402
|
+
onOpenFile={panel.openFile}
|
|
403
|
+
onActivateEditor={panel.activateEditor}
|
|
404
|
+
onPinEditor={panel.pinEditor}
|
|
405
|
+
onCloseEditor={panel.closeEditor}
|
|
406
|
+
onCollapse={panel.closePanel}
|
|
407
|
+
reveal={activeReveal}
|
|
408
|
+
className="h-full"
|
|
341
409
|
/>
|
|
342
|
-
|
|
410
|
+
) : null
|
|
343
411
|
}
|
|
344
412
|
/>
|
|
345
413
|
</div>
|