@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,361 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useMemo, useState } from "react";
|
|
4
|
+
import Markdown from "react-markdown";
|
|
5
|
+
import { cn } from "@stigmer/theme";
|
|
6
|
+
import {
|
|
7
|
+
PLAN_DOCUMENT_MARKDOWN_COMPONENTS,
|
|
8
|
+
REMARK_PLUGINS,
|
|
9
|
+
extractLeadingH1,
|
|
10
|
+
unwrapEnclosingMarkdownFence,
|
|
11
|
+
} from "../internal/markdown-components.js";
|
|
12
|
+
import { useArtifactContent } from "../execution/useArtifactContent.js";
|
|
13
|
+
import { useBuildFromPlanHotkey } from "../execution/use-build-from-plan-hotkey.js";
|
|
14
|
+
import { formatArtifactSize } from "../execution/artifact-utils.js";
|
|
15
|
+
import type { SessionPlan } from "../library/detect-plan-artifact.js";
|
|
16
|
+
import type { PlanDraftController } from "./usePlanDraft.js";
|
|
17
|
+
|
|
18
|
+
/** Props for {@link PlanEditor}. */
|
|
19
|
+
export interface PlanEditorProps {
|
|
20
|
+
/** The plan to display (latest, or a superseded plan opened from its card). */
|
|
21
|
+
readonly plan: SessionPlan;
|
|
22
|
+
/**
|
|
23
|
+
* Draft controller owned by the viewer (survives panel collapse/unmounts).
|
|
24
|
+
* Consulted only when editable — a read-only (superseded) plan renders its
|
|
25
|
+
* own artifact text, never the current plan's draft.
|
|
26
|
+
*/
|
|
27
|
+
readonly draft?: PlanDraftController;
|
|
28
|
+
/** Builds from the plan — the same action as the thread card's primary. */
|
|
29
|
+
readonly onBuildFromPlan?: () => void;
|
|
30
|
+
/** Disables the Build action (execution in flight, or build submitting). */
|
|
31
|
+
readonly buildDisabled?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Renders the plan as a historical, read-only document: no Edit view, no
|
|
34
|
+
* Build action, and a "superseded" notice. Used when the user opens a plan
|
|
35
|
+
* that a newer plan has since replaced.
|
|
36
|
+
*/
|
|
37
|
+
readonly readOnly?: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
type PlanEditorView = "rendered" | "source" | "edit";
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The plan document for the workspace surface's editor area — the wide-pane
|
|
44
|
+
* successor of the retired Plan sidebar facet, mounted as a virtual document
|
|
45
|
+
* (`SurfaceVirtualDocument`) under the {@link PLAN_DOCUMENT_ENTRY_ID} tab.
|
|
46
|
+
*
|
|
47
|
+
* Three views over one text:
|
|
48
|
+
* - **Rendered** — the plan as a document (same typography as the thread's
|
|
49
|
+
* plan rendering, title lifted from the leading H1).
|
|
50
|
+
* - **Source** — the raw markdown.
|
|
51
|
+
* - **Edit** — a plain-textarea editor over a LOCAL draft
|
|
52
|
+
* ({@link PlanDraftController}); the published artifact is never mutated.
|
|
53
|
+
* Building from an edited plan delivers the draft to the implement
|
|
54
|
+
* execution (edit-as-input).
|
|
55
|
+
*
|
|
56
|
+
* All views show the *effective* plan — the draft when one exists, the
|
|
57
|
+
* published artifact otherwise — so what the user reviews is exactly what
|
|
58
|
+
* Build will implement. An "Edited" indicator plus Revert makes the overlay
|
|
59
|
+
* visible and reversible.
|
|
60
|
+
*
|
|
61
|
+
* Editing is disabled for truncated content (the content RPC caps at 512 KB):
|
|
62
|
+
* editing a truncated plan would silently drop its tail on handoff. The
|
|
63
|
+
* document still renders read-only with the truncation notice.
|
|
64
|
+
*
|
|
65
|
+
* Holds no must-survive local state: the panel region unmounts wholesale on
|
|
66
|
+
* collapse, so anything that must outlive it (the draft, the fetched content
|
|
67
|
+
* cache) is owned above. The view pick resetting to Rendered on reopen is
|
|
68
|
+
* deliberate.
|
|
69
|
+
*
|
|
70
|
+
* All visual properties flow through `--stgm-*` tokens.
|
|
71
|
+
*/
|
|
72
|
+
export function PlanEditor({
|
|
73
|
+
plan,
|
|
74
|
+
draft,
|
|
75
|
+
onBuildFromPlan,
|
|
76
|
+
buildDisabled,
|
|
77
|
+
readOnly,
|
|
78
|
+
}: PlanEditorProps) {
|
|
79
|
+
const [view, setView] = useState<PlanEditorView>("rendered");
|
|
80
|
+
const canBuild = !readOnly && onBuildFromPlan !== undefined;
|
|
81
|
+
const handleKeyDown = useBuildFromPlanHotkey(
|
|
82
|
+
canBuild ? onBuildFromPlan : undefined,
|
|
83
|
+
buildDisabled,
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
const { content, isTruncated, isLoading, error, refetch } =
|
|
87
|
+
useArtifactContent(
|
|
88
|
+
plan.executionId,
|
|
89
|
+
plan.artifact.storageKey,
|
|
90
|
+
undefined,
|
|
91
|
+
plan.artifact.contentHash,
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
const activeDraft = readOnly ? undefined : draft;
|
|
95
|
+
const effectiveText = activeDraft?.draftText ?? content;
|
|
96
|
+
// A read-only plan (or one without a draft controller) never offers Edit;
|
|
97
|
+
// a truncated plan only keeps it while an existing draft needs rescuing.
|
|
98
|
+
const canEdit = activeDraft !== undefined && (!isTruncated || activeDraft.isEdited);
|
|
99
|
+
const activeView: PlanEditorView = view === "edit" && !canEdit ? "rendered" : view;
|
|
100
|
+
|
|
101
|
+
if (isLoading) {
|
|
102
|
+
return (
|
|
103
|
+
<PlanEditorFrame>
|
|
104
|
+
<PlanEditorSkeleton />
|
|
105
|
+
</PlanEditorFrame>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (error || effectiveText === null) {
|
|
110
|
+
return (
|
|
111
|
+
<PlanEditorFrame>
|
|
112
|
+
<div className="flex flex-col items-center gap-2 px-4 py-8 text-center">
|
|
113
|
+
<p className="text-xs text-muted-foreground">
|
|
114
|
+
Couldn’t load the plan{error ? `: ${error.message}` : "."}
|
|
115
|
+
</p>
|
|
116
|
+
<button
|
|
117
|
+
type="button"
|
|
118
|
+
onClick={refetch}
|
|
119
|
+
className="rounded text-xs font-medium text-foreground underline-offset-2 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
120
|
+
>
|
|
121
|
+
Retry
|
|
122
|
+
</button>
|
|
123
|
+
</div>
|
|
124
|
+
</PlanEditorFrame>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return (
|
|
129
|
+
<PlanEditorFrame onKeyDown={handleKeyDown}>
|
|
130
|
+
{/* Toolbar: view tabs lead; state + the one primary action trail.
|
|
131
|
+
Narrow panes are first-class: rows wrap (flex-wrap) and every item
|
|
132
|
+
can shrink (min-w-0 + truncating labels), so the toolbar reflows
|
|
133
|
+
instead of forcing the document pane to scroll sideways. */}
|
|
134
|
+
<div className="flex min-w-0 flex-wrap items-center gap-2">
|
|
135
|
+
<div
|
|
136
|
+
className="inline-flex shrink-0 rounded-md bg-muted p-0.5"
|
|
137
|
+
role="tablist"
|
|
138
|
+
aria-label="Plan view"
|
|
139
|
+
>
|
|
140
|
+
<ViewTab
|
|
141
|
+
active={activeView === "rendered"}
|
|
142
|
+
onClick={() => setView("rendered")}
|
|
143
|
+
label="Rendered"
|
|
144
|
+
/>
|
|
145
|
+
<ViewTab
|
|
146
|
+
active={activeView === "source"}
|
|
147
|
+
onClick={() => setView("source")}
|
|
148
|
+
label="Source"
|
|
149
|
+
/>
|
|
150
|
+
{activeDraft !== undefined && (
|
|
151
|
+
<ViewTab
|
|
152
|
+
active={activeView === "edit"}
|
|
153
|
+
onClick={() => setView("edit")}
|
|
154
|
+
label="Edit"
|
|
155
|
+
disabled={!canEdit}
|
|
156
|
+
title={
|
|
157
|
+
!canEdit
|
|
158
|
+
? "This plan is too large to edit in place — download it instead."
|
|
159
|
+
: undefined
|
|
160
|
+
}
|
|
161
|
+
/>
|
|
162
|
+
)}
|
|
163
|
+
</div>
|
|
164
|
+
<span className="text-[0.65rem] tabular-nums text-muted-foreground-faint">
|
|
165
|
+
{formatArtifactSize(plan.artifact.sizeBytes)}
|
|
166
|
+
</span>
|
|
167
|
+
|
|
168
|
+
<div className="ml-auto flex min-w-0 flex-wrap items-center gap-3">
|
|
169
|
+
{activeDraft?.isEdited && (
|
|
170
|
+
<span className="inline-flex items-center gap-2">
|
|
171
|
+
<span className="rounded-md bg-accent px-1.5 py-0.5 text-[0.65rem] font-medium text-muted-foreground">
|
|
172
|
+
Edited
|
|
173
|
+
</span>
|
|
174
|
+
<button
|
|
175
|
+
type="button"
|
|
176
|
+
onClick={() => activeDraft.setDraft(null)}
|
|
177
|
+
className="rounded text-[0.65rem] font-medium text-muted-foreground underline-offset-2 hover:text-foreground hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
178
|
+
>
|
|
179
|
+
Revert
|
|
180
|
+
</button>
|
|
181
|
+
</span>
|
|
182
|
+
)}
|
|
183
|
+
{readOnly ? (
|
|
184
|
+
<span
|
|
185
|
+
role="status"
|
|
186
|
+
className="rounded-md bg-muted px-2 py-0.5 text-[0.65rem] font-medium text-muted-foreground"
|
|
187
|
+
>
|
|
188
|
+
Superseded by a newer plan
|
|
189
|
+
</span>
|
|
190
|
+
) : (
|
|
191
|
+
onBuildFromPlan && (
|
|
192
|
+
<button
|
|
193
|
+
type="button"
|
|
194
|
+
disabled={buildDisabled}
|
|
195
|
+
onClick={onBuildFromPlan}
|
|
196
|
+
className={cn(
|
|
197
|
+
"inline-flex min-w-0 items-center gap-1.5 rounded-md px-3 py-1.5",
|
|
198
|
+
"text-xs font-medium transition-colors",
|
|
199
|
+
"bg-primary text-primary-foreground hover:bg-primary-hover",
|
|
200
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
201
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
202
|
+
)}
|
|
203
|
+
>
|
|
204
|
+
<ImplementIcon />
|
|
205
|
+
<span className="truncate">
|
|
206
|
+
{buildDisabled ? "Starting build…" : "Build from plan"}
|
|
207
|
+
</span>
|
|
208
|
+
</button>
|
|
209
|
+
)
|
|
210
|
+
)}
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
213
|
+
|
|
214
|
+
{activeView === "rendered" && <RenderedPlan text={effectiveText} />}
|
|
215
|
+
{activeView === "source" && (
|
|
216
|
+
<pre className="overflow-x-auto rounded-md bg-muted p-3 font-mono text-xs whitespace-pre-wrap text-foreground">
|
|
217
|
+
{effectiveText}
|
|
218
|
+
</pre>
|
|
219
|
+
)}
|
|
220
|
+
{activeView === "edit" && activeDraft !== undefined && (
|
|
221
|
+
<textarea
|
|
222
|
+
value={effectiveText}
|
|
223
|
+
onChange={(e) => activeDraft.setDraft(e.target.value)}
|
|
224
|
+
aria-label="Edit plan"
|
|
225
|
+
spellCheck={false}
|
|
226
|
+
rows={28}
|
|
227
|
+
className={cn(
|
|
228
|
+
"w-full flex-1 resize-y rounded-md border border-border bg-card p-3",
|
|
229
|
+
"font-mono text-xs leading-relaxed text-foreground",
|
|
230
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
231
|
+
)}
|
|
232
|
+
/>
|
|
233
|
+
)}
|
|
234
|
+
|
|
235
|
+
{isTruncated && (
|
|
236
|
+
<p role="status" className="text-[0.65rem] text-muted-foreground">
|
|
237
|
+
Preview truncated — download the artifact for the full plan.
|
|
238
|
+
</p>
|
|
239
|
+
)}
|
|
240
|
+
</PlanEditorFrame>
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* The editor-area envelope: a centered document column so the plan reads as a
|
|
246
|
+
* page rather than stretching across the full pane width.
|
|
247
|
+
*/
|
|
248
|
+
function PlanEditorFrame({
|
|
249
|
+
children,
|
|
250
|
+
onKeyDown,
|
|
251
|
+
}: {
|
|
252
|
+
readonly children: React.ReactNode;
|
|
253
|
+
readonly onKeyDown?: React.KeyboardEventHandler<HTMLDivElement>;
|
|
254
|
+
}) {
|
|
255
|
+
return (
|
|
256
|
+
<div
|
|
257
|
+
role="article"
|
|
258
|
+
aria-label="Plan document"
|
|
259
|
+
onKeyDown={onKeyDown}
|
|
260
|
+
className="mx-auto flex w-full max-w-3xl flex-col gap-3 px-4 py-3"
|
|
261
|
+
>
|
|
262
|
+
{children}
|
|
263
|
+
</div>
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* The plan document: title lifted from the leading H1, body in the shared
|
|
269
|
+
* plan-document typography — identical treatment to the thread's plan
|
|
270
|
+
* rendering, so the plan reads the same on every surface.
|
|
271
|
+
*/
|
|
272
|
+
function RenderedPlan({ text }: { readonly text: string }) {
|
|
273
|
+
const { title, body } = useMemo(
|
|
274
|
+
() => extractLeadingH1(unwrapEnclosingMarkdownFence(text, true)),
|
|
275
|
+
[text],
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
return (
|
|
279
|
+
<div className="overflow-hidden rounded-lg border border-border-muted bg-card">
|
|
280
|
+
{title && (
|
|
281
|
+
<header className="border-b border-border-muted bg-muted-faint px-4 py-2.5">
|
|
282
|
+
<span className="block truncate text-sm font-semibold text-foreground">
|
|
283
|
+
{title}
|
|
284
|
+
</span>
|
|
285
|
+
</header>
|
|
286
|
+
)}
|
|
287
|
+
<div className="stgm-prose px-4 py-4">
|
|
288
|
+
<Markdown
|
|
289
|
+
remarkPlugins={REMARK_PLUGINS}
|
|
290
|
+
components={PLAN_DOCUMENT_MARKDOWN_COMPONENTS}
|
|
291
|
+
>
|
|
292
|
+
{body}
|
|
293
|
+
</Markdown>
|
|
294
|
+
</div>
|
|
295
|
+
</div>
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function PlanEditorSkeleton() {
|
|
300
|
+
return (
|
|
301
|
+
<div className="space-y-2 py-2" aria-hidden="true">
|
|
302
|
+
<div className="h-8 w-full animate-pulse rounded-md bg-muted" />
|
|
303
|
+
<div className="h-4 w-2/3 animate-pulse rounded bg-muted" />
|
|
304
|
+
<div className="h-4 w-full animate-pulse rounded bg-muted" />
|
|
305
|
+
<div className="h-4 w-5/6 animate-pulse rounded bg-muted" />
|
|
306
|
+
</div>
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
function ViewTab({
|
|
311
|
+
active,
|
|
312
|
+
onClick,
|
|
313
|
+
label,
|
|
314
|
+
disabled,
|
|
315
|
+
title,
|
|
316
|
+
}: {
|
|
317
|
+
readonly active: boolean;
|
|
318
|
+
readonly onClick: () => void;
|
|
319
|
+
readonly label: string;
|
|
320
|
+
readonly disabled?: boolean;
|
|
321
|
+
readonly title?: string;
|
|
322
|
+
}) {
|
|
323
|
+
return (
|
|
324
|
+
<button
|
|
325
|
+
type="button"
|
|
326
|
+
role="tab"
|
|
327
|
+
aria-selected={active}
|
|
328
|
+
onClick={onClick}
|
|
329
|
+
disabled={disabled}
|
|
330
|
+
title={title}
|
|
331
|
+
className={cn(
|
|
332
|
+
"rounded px-2 py-0.5 text-[0.65rem] font-medium transition-colors",
|
|
333
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
334
|
+
active
|
|
335
|
+
? "bg-card text-foreground shadow-sm"
|
|
336
|
+
: "text-muted-foreground hover:text-foreground",
|
|
337
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
338
|
+
)}
|
|
339
|
+
>
|
|
340
|
+
{label}
|
|
341
|
+
</button>
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
function ImplementIcon() {
|
|
346
|
+
return (
|
|
347
|
+
<svg
|
|
348
|
+
width="12"
|
|
349
|
+
height="12"
|
|
350
|
+
viewBox="0 0 12 12"
|
|
351
|
+
fill="none"
|
|
352
|
+
stroke="currentColor"
|
|
353
|
+
strokeWidth="1.5"
|
|
354
|
+
strokeLinecap="round"
|
|
355
|
+
strokeLinejoin="round"
|
|
356
|
+
aria-hidden="true"
|
|
357
|
+
>
|
|
358
|
+
<path d="M2 6h8M7 3l3 3-3 3" />
|
|
359
|
+
</svg>
|
|
360
|
+
);
|
|
361
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
import { Streamdown } from "streamdown";
|
|
5
|
+
import {
|
|
6
|
+
PLAN_DOCUMENT_MARKDOWN_COMPONENTS,
|
|
7
|
+
extractLeadingH1,
|
|
8
|
+
} from "../internal/markdown-components.js";
|
|
9
|
+
|
|
10
|
+
/** Props for {@link PlanStreamingDocument}. */
|
|
11
|
+
export interface PlanStreamingDocumentProps {
|
|
12
|
+
/**
|
|
13
|
+
* The live plan text, already fence-stripped by `findStreamingPlan`
|
|
14
|
+
* (`StreamingPlan.displayText`). Grows on every stream commit.
|
|
15
|
+
*/
|
|
16
|
+
readonly displayText: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The plan document tab's LIVE view: renders the plan as it streams, before
|
|
21
|
+
* any artifact exists. The streaming counterpart of {@link PlanEditor} — same
|
|
22
|
+
* centered document column, same header-lifted title, same plan-document
|
|
23
|
+
* typography — so the moment the turn completes and the artifact-backed
|
|
24
|
+
* editor takes over, the document simply stops moving rather than changing
|
|
25
|
+
* shape.
|
|
26
|
+
*
|
|
27
|
+
* Deliberately capability-free: no view tabs, no Edit, no Build — a plan in
|
|
28
|
+
* flight cannot be edited or implemented, and offering dead controls would
|
|
29
|
+
* misstate the turn's state. A "Writing…" status pill stands where the
|
|
30
|
+
* editor's toolbar will appear.
|
|
31
|
+
*
|
|
32
|
+
* Rendering goes through `Streamdown` (the same streaming-aware renderer the
|
|
33
|
+
* thread's `AiMessage` uses: block-level memoization, incomplete-syntax
|
|
34
|
+
* healing, animated caret) rather than `PlanEditor`'s static markdown — this
|
|
35
|
+
* component re-renders on every stream commit by design.
|
|
36
|
+
*
|
|
37
|
+
* All visual properties flow through `--stgm-*` tokens.
|
|
38
|
+
*/
|
|
39
|
+
export function PlanStreamingDocument({
|
|
40
|
+
displayText,
|
|
41
|
+
}: PlanStreamingDocumentProps) {
|
|
42
|
+
const { title, body } = useMemo(
|
|
43
|
+
() => extractLeadingH1(displayText),
|
|
44
|
+
[displayText],
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<div
|
|
49
|
+
role="article"
|
|
50
|
+
aria-label="Plan document"
|
|
51
|
+
aria-busy="true"
|
|
52
|
+
className="mx-auto flex w-full max-w-3xl flex-col gap-3 px-4 py-3"
|
|
53
|
+
>
|
|
54
|
+
<div className="flex min-w-0 flex-wrap items-center gap-2">
|
|
55
|
+
<span
|
|
56
|
+
role="status"
|
|
57
|
+
className="inline-flex items-center gap-1.5 rounded-md bg-muted px-2 py-0.5 text-[0.65rem] font-medium text-muted-foreground"
|
|
58
|
+
>
|
|
59
|
+
<WritingDot />
|
|
60
|
+
Writing…
|
|
61
|
+
</span>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<div className="overflow-hidden rounded-lg border border-border-muted bg-card">
|
|
65
|
+
{title && (
|
|
66
|
+
<header className="border-b border-border-muted bg-muted-faint px-4 py-2.5">
|
|
67
|
+
<span className="block truncate text-sm font-semibold text-foreground">
|
|
68
|
+
{title}
|
|
69
|
+
</span>
|
|
70
|
+
</header>
|
|
71
|
+
)}
|
|
72
|
+
<div className="stgm-prose px-4 py-4">
|
|
73
|
+
<Streamdown
|
|
74
|
+
components={PLAN_DOCUMENT_MARKDOWN_COMPONENTS}
|
|
75
|
+
isAnimating
|
|
76
|
+
caret="block"
|
|
77
|
+
>
|
|
78
|
+
{body}
|
|
79
|
+
</Streamdown>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* The pill's pulsing dot — a CSS animation inside `.stgm`, covered by the
|
|
88
|
+
* stylesheet's global `prefers-reduced-motion` rule (DD-015).
|
|
89
|
+
*/
|
|
90
|
+
function WritingDot() {
|
|
91
|
+
return (
|
|
92
|
+
<span
|
|
93
|
+
aria-hidden="true"
|
|
94
|
+
className="size-1.5 animate-pulse rounded-full bg-primary"
|
|
95
|
+
/>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef } from "react";
|
|
4
|
+
import { cn } from "@stigmer/theme";
|
|
5
|
+
|
|
6
|
+
/** Props for {@link SessionPanelChip}. */
|
|
7
|
+
export interface SessionPanelChipProps {
|
|
8
|
+
/** Whether the panel is currently expanded. */
|
|
9
|
+
readonly isOpen: boolean;
|
|
10
|
+
/** Toggles the panel open/collapsed. */
|
|
11
|
+
readonly onToggle: () => void;
|
|
12
|
+
/**
|
|
13
|
+
* Aggregate count of facet items (write-backs + artifacts) awaiting the
|
|
14
|
+
* user. Rendered as a dot-count while collapsed — the panel's only "something
|
|
15
|
+
* arrived" signal, since arrivals never auto-open the panel.
|
|
16
|
+
*/
|
|
17
|
+
readonly badgeCount?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The always-mounted top-right toggle for the unified session panel — the
|
|
22
|
+
* Cursor "Show panel" chip. Collapsed, it carries the pending-item count;
|
|
23
|
+
* open, it is the hide affordance. Being a small leaf, it is also the one
|
|
24
|
+
* place that may safely carry per-arrival re-renders while the panel subtree
|
|
25
|
+
* is unmounted. Execution status deliberately does not surface here (or
|
|
26
|
+
* anywhere else in the viewer chrome) — the thread itself communicates run
|
|
27
|
+
* state.
|
|
28
|
+
*
|
|
29
|
+
* All visual properties flow through `--stgm-*` tokens (DD-005).
|
|
30
|
+
*/
|
|
31
|
+
export function SessionPanelChip({
|
|
32
|
+
isOpen,
|
|
33
|
+
onToggle,
|
|
34
|
+
badgeCount,
|
|
35
|
+
}: SessionPanelChipProps) {
|
|
36
|
+
const showCount = !isOpen && badgeCount != null && badgeCount > 0;
|
|
37
|
+
|
|
38
|
+
// Focus restoration: collapsing unmounts the panel subtree, so keyboard
|
|
39
|
+
// focus that lived inside it (rail, tabs, viewer) falls to <body>. Reclaim
|
|
40
|
+
// it here — the chip is the collapse's logical origin. Focus resting
|
|
41
|
+
// anywhere else (e.g. the composer) is respected. Opening deliberately does
|
|
42
|
+
// NOT move focus: the chip is a standard disclosure trigger.
|
|
43
|
+
const buttonRef = useRef<HTMLButtonElement>(null);
|
|
44
|
+
const prevOpenRef = useRef(isOpen);
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (prevOpenRef.current && !isOpen && document.activeElement === document.body) {
|
|
47
|
+
buttonRef.current?.focus();
|
|
48
|
+
}
|
|
49
|
+
prevOpenRef.current = isOpen;
|
|
50
|
+
}, [isOpen]);
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<button
|
|
54
|
+
ref={buttonRef}
|
|
55
|
+
type="button"
|
|
56
|
+
onClick={onToggle}
|
|
57
|
+
aria-expanded={isOpen}
|
|
58
|
+
aria-label={isOpen ? "Hide panel" : "Show panel"}
|
|
59
|
+
title={isOpen ? "Hide panel" : "Show panel"}
|
|
60
|
+
className={cn(
|
|
61
|
+
"flex items-center gap-1.5 rounded-md border border-border bg-card px-1.5 py-1",
|
|
62
|
+
"text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
63
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
64
|
+
)}
|
|
65
|
+
>
|
|
66
|
+
{showCount && (
|
|
67
|
+
<span
|
|
68
|
+
aria-label={`${badgeCount} new items`}
|
|
69
|
+
className="inline-flex min-w-[1rem] items-center justify-center rounded-full bg-primary px-1 py-px text-[10px] font-medium leading-none text-primary-foreground"
|
|
70
|
+
>
|
|
71
|
+
{badgeCount}
|
|
72
|
+
</span>
|
|
73
|
+
)}
|
|
74
|
+
<PanelIcon open={isOpen} />
|
|
75
|
+
</button>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Panel-layout glyph: a frame with its right region filled while the panel is
|
|
81
|
+
* open, hollow while collapsed — mirroring the state it toggles to at a glance.
|
|
82
|
+
*/
|
|
83
|
+
function PanelIcon({ open }: { readonly open: boolean }) {
|
|
84
|
+
return (
|
|
85
|
+
<svg
|
|
86
|
+
width="16"
|
|
87
|
+
height="16"
|
|
88
|
+
viewBox="0 0 16 16"
|
|
89
|
+
fill="none"
|
|
90
|
+
stroke="currentColor"
|
|
91
|
+
strokeWidth="1.3"
|
|
92
|
+
strokeLinecap="round"
|
|
93
|
+
strokeLinejoin="round"
|
|
94
|
+
aria-hidden="true"
|
|
95
|
+
>
|
|
96
|
+
<rect x="1.5" y="2.5" width="13" height="11" rx="1.5" />
|
|
97
|
+
<path d="M9.5 2.5v11" />
|
|
98
|
+
{open && (
|
|
99
|
+
<rect x="9.5" y="2.5" width="5" height="11" rx="1.5" fill="currentColor" stroke="none" />
|
|
100
|
+
)}
|
|
101
|
+
</svg>
|
|
102
|
+
);
|
|
103
|
+
}
|