@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
|
@@ -125,7 +125,7 @@ describe("SessionComposer — public contract", () => {
|
|
|
125
125
|
});
|
|
126
126
|
});
|
|
127
127
|
|
|
128
|
-
describe("SessionComposer — imperative submit (
|
|
128
|
+
describe("SessionComposer — imperative submit (Build from plan)", () => {
|
|
129
129
|
it("submits a message with the interactionMode override, even when the picker is 'plan'", async () => {
|
|
130
130
|
const ref = createRef<SessionComposerHandle>();
|
|
131
131
|
const { onSubmit } = renderComposer({
|
|
@@ -134,13 +134,13 @@ describe("SessionComposer — imperative submit (Implement plan)", () => {
|
|
|
134
134
|
interactionMode: "plan",
|
|
135
135
|
});
|
|
136
136
|
|
|
137
|
-
ref.current!.submit("
|
|
137
|
+
ref.current!.submit("Build from plan", { interactionMode: "agent" });
|
|
138
138
|
|
|
139
139
|
await waitFor(() => {
|
|
140
140
|
expect(onSubmit).toHaveBeenCalledOnce();
|
|
141
141
|
});
|
|
142
142
|
const [message, , context] = onSubmit.mock.calls[0];
|
|
143
|
-
expect(message).toBe("
|
|
143
|
+
expect(message).toBe("Build from plan");
|
|
144
144
|
// The override must win over the current picker value ("plan") so the
|
|
145
145
|
// implement run executes in Agent mode regardless of render timing.
|
|
146
146
|
expect(context?.interactionMode).toBe("agent");
|
|
@@ -150,7 +150,7 @@ describe("SessionComposer — imperative submit (Implement plan)", () => {
|
|
|
150
150
|
const ref = createRef<SessionComposerHandle>();
|
|
151
151
|
const { onSubmit } = renderComposer({ ref, disabled: true });
|
|
152
152
|
|
|
153
|
-
ref.current!.submit("
|
|
153
|
+
ref.current!.submit("Build from plan", { interactionMode: "agent" });
|
|
154
154
|
|
|
155
155
|
expect(onSubmit).not.toHaveBeenCalled();
|
|
156
156
|
});
|
|
@@ -163,4 +163,58 @@ describe("SessionComposer — imperative submit (Implement plan)", () => {
|
|
|
163
163
|
|
|
164
164
|
expect(onSubmit).not.toHaveBeenCalled();
|
|
165
165
|
});
|
|
166
|
+
|
|
167
|
+
it("carries caller-supplied attachments into the submit context (approved plan.md)", async () => {
|
|
168
|
+
const ref = createRef<SessionComposerHandle>();
|
|
169
|
+
const { onSubmit } = renderComposer({ ref });
|
|
170
|
+
|
|
171
|
+
const planAttachment = {
|
|
172
|
+
filename: "plan.md",
|
|
173
|
+
storageKey: "attachments/01ABC/plan.md",
|
|
174
|
+
mountPath: ".stigmer/inputs/plan.md",
|
|
175
|
+
contentType: "text/markdown",
|
|
176
|
+
};
|
|
177
|
+
ref.current!.submit("Build from plan", {
|
|
178
|
+
interactionMode: "agent",
|
|
179
|
+
attachments: [planAttachment],
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
await waitFor(() => {
|
|
183
|
+
expect(onSubmit).toHaveBeenCalledOnce();
|
|
184
|
+
});
|
|
185
|
+
const [, , context] = onSubmit.mock.calls[0];
|
|
186
|
+
expect(context?.attachments).toEqual([planAttachment]);
|
|
187
|
+
expect(context?.interactionMode).toBe("agent");
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it("carries the buildFromPlan flag into the submit context", async () => {
|
|
191
|
+
const ref = createRef<SessionComposerHandle>();
|
|
192
|
+
const { onSubmit } = renderComposer({ ref });
|
|
193
|
+
|
|
194
|
+
ref.current!.submit("Build from plan", {
|
|
195
|
+
interactionMode: "agent",
|
|
196
|
+
buildFromPlan: true,
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
await waitFor(() => {
|
|
200
|
+
expect(onSubmit).toHaveBeenCalledOnce();
|
|
201
|
+
});
|
|
202
|
+
const [, , context] = onSubmit.mock.calls[0];
|
|
203
|
+
expect(context?.buildFromPlan).toBe(true);
|
|
204
|
+
expect(context?.interactionMode).toBe("agent");
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it("leaves buildFromPlan unset for ordinary submissions", async () => {
|
|
208
|
+
const { onSubmit } = renderComposer();
|
|
209
|
+
|
|
210
|
+
const textarea = screen.getByRole("textbox");
|
|
211
|
+
fireEvent.change(textarea, { target: { value: "Hello world" } });
|
|
212
|
+
fireEvent.keyDown(textarea, { key: "Enter", shiftKey: false });
|
|
213
|
+
|
|
214
|
+
await waitFor(() => {
|
|
215
|
+
expect(onSubmit).toHaveBeenCalledOnce();
|
|
216
|
+
});
|
|
217
|
+
const [, , context] = onSubmit.mock.calls[0];
|
|
218
|
+
expect(context?.buildFromPlan).toBeUndefined();
|
|
219
|
+
});
|
|
166
220
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useMemo, useState, type ReactNode } from "react";
|
|
3
|
+
import { useEffect, useMemo, useState, type ReactNode } from "react";
|
|
4
4
|
import Markdown from "react-markdown";
|
|
5
5
|
import { cn } from "@stigmer/theme";
|
|
6
6
|
import {
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
REMARK_PLUGINS,
|
|
9
9
|
unwrapEnclosingMarkdownFence,
|
|
10
10
|
} from "../internal/markdown-components.js";
|
|
11
|
+
import { useRevealLine, type RevealTarget } from "../internal/useRevealLine.js";
|
|
11
12
|
import {
|
|
12
13
|
getArtifactRenderMode,
|
|
13
14
|
type ArtifactRenderMode,
|
|
@@ -29,6 +30,15 @@ export interface ArtifactContentRendererProps {
|
|
|
29
30
|
readonly contentType?: string | null;
|
|
30
31
|
/** When `true`, shows a truncation warning below the content. */
|
|
31
32
|
readonly isTruncated?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Optional jump-to-line request. When set, the content is rendered
|
|
35
|
+
* **line-faithfully** so the line number maps to the file's real rows —
|
|
36
|
+
* Markdown defaults to its Source view (a line only exists in source) and
|
|
37
|
+
* JSON renders raw rather than pretty-printed (reformatting would shift line
|
|
38
|
+
* numbers) — and the target line is scrolled into view and highlighted. Absent
|
|
39
|
+
* (the default), rendering is unchanged. See {@link RevealTarget}.
|
|
40
|
+
*/
|
|
41
|
+
readonly reveal?: RevealTarget;
|
|
32
42
|
/** Additional CSS classes for the root element. */
|
|
33
43
|
readonly className?: string;
|
|
34
44
|
}
|
|
@@ -76,6 +86,7 @@ export function ArtifactContentRenderer({
|
|
|
76
86
|
fileName,
|
|
77
87
|
contentType,
|
|
78
88
|
isTruncated = false,
|
|
89
|
+
reveal,
|
|
79
90
|
className,
|
|
80
91
|
}: ArtifactContentRendererProps) {
|
|
81
92
|
const mode = getArtifactRenderMode(fileName, contentType);
|
|
@@ -83,13 +94,19 @@ export function ArtifactContentRenderer({
|
|
|
83
94
|
return (
|
|
84
95
|
<div className={cn(className)}>
|
|
85
96
|
{mode === "markdown" ? (
|
|
86
|
-
<MarkdownView content={content} />
|
|
97
|
+
<MarkdownView content={content} reveal={reveal} />
|
|
87
98
|
) : mode === "yaml" ? (
|
|
88
|
-
<YamlView content={content} />
|
|
99
|
+
<YamlView content={content} reveal={reveal} />
|
|
89
100
|
) : mode === "json" ? (
|
|
90
|
-
|
|
101
|
+
// A reveal needs raw, line-faithful JSON: pretty-printing reformats the
|
|
102
|
+
// file and would shift the target line off its real row.
|
|
103
|
+
reveal ? (
|
|
104
|
+
<LineNumberedPre content={content} reveal={reveal} />
|
|
105
|
+
) : (
|
|
106
|
+
<JsonView content={content} />
|
|
107
|
+
)
|
|
91
108
|
) : (
|
|
92
|
-
<PlainTextView content={content} />
|
|
109
|
+
<PlainTextView content={content} reveal={reveal} />
|
|
93
110
|
)}
|
|
94
111
|
|
|
95
112
|
{isTruncated && <TruncationWarning />}
|
|
@@ -103,8 +120,21 @@ export function ArtifactContentRenderer({
|
|
|
103
120
|
|
|
104
121
|
type MarkdownTab = "rendered" | "source";
|
|
105
122
|
|
|
106
|
-
function MarkdownView({
|
|
107
|
-
|
|
123
|
+
function MarkdownView({
|
|
124
|
+
content,
|
|
125
|
+
reveal,
|
|
126
|
+
}: {
|
|
127
|
+
readonly content: string;
|
|
128
|
+
readonly reveal?: RevealTarget;
|
|
129
|
+
}) {
|
|
130
|
+
// A reveal targets a source line (the rendered HTML has no line concept), so
|
|
131
|
+
// default to — and, on every new reveal, return to — the Source view.
|
|
132
|
+
const [tab, setTab] = useState<MarkdownTab>(reveal ? "source" : "rendered");
|
|
133
|
+
// Keyed on the reveal nonce: each fresh jump-to-line returns to Source (where
|
|
134
|
+
// the line exists); switching to Rendered afterward sticks until the next hit.
|
|
135
|
+
useEffect(() => {
|
|
136
|
+
if (reveal) setTab("source");
|
|
137
|
+
}, [reveal?.nonce]);
|
|
108
138
|
|
|
109
139
|
// A `.md` whose entire body is one ```markdown fence (e.g. a model-wrapped
|
|
110
140
|
// plan) would render flat. Unwrap for the Rendered view only — Source stays
|
|
@@ -145,7 +175,7 @@ function MarkdownView({ content }: { readonly content: string }) {
|
|
|
145
175
|
</Markdown>
|
|
146
176
|
</div>
|
|
147
177
|
) : (
|
|
148
|
-
<LineNumberedPre content={content} />
|
|
178
|
+
<LineNumberedPre content={content} reveal={reveal} />
|
|
149
179
|
)}
|
|
150
180
|
</div>
|
|
151
181
|
);
|
|
@@ -197,15 +227,6 @@ function TabButton({
|
|
|
197
227
|
*
|
|
198
228
|
* Values and block scalar content render in the default `text-foreground`.
|
|
199
229
|
*/
|
|
200
|
-
function highlightYaml(content: string): ReactNode {
|
|
201
|
-
return content.split("\n").map((line, i) => (
|
|
202
|
-
<span key={i}>
|
|
203
|
-
{i > 0 && "\n"}
|
|
204
|
-
{highlightYamlLine(line)}
|
|
205
|
-
</span>
|
|
206
|
-
));
|
|
207
|
-
}
|
|
208
|
-
|
|
209
230
|
function highlightYamlLine(line: string): ReactNode {
|
|
210
231
|
if (!line.trim()) return line;
|
|
211
232
|
|
|
@@ -253,10 +274,38 @@ function highlightYamlValue(value: string): ReactNode {
|
|
|
253
274
|
return <>{value}</>;
|
|
254
275
|
}
|
|
255
276
|
|
|
256
|
-
function YamlView({
|
|
277
|
+
function YamlView({
|
|
278
|
+
content,
|
|
279
|
+
reveal,
|
|
280
|
+
}: {
|
|
281
|
+
readonly content: string;
|
|
282
|
+
readonly reveal?: RevealTarget;
|
|
283
|
+
}) {
|
|
284
|
+
const { containerRef, isRevealed } = useRevealLine(reveal);
|
|
285
|
+
const lines = content.split("\n");
|
|
286
|
+
|
|
257
287
|
return (
|
|
258
288
|
<pre className="overflow-x-auto p-4 font-mono text-xs leading-relaxed text-foreground">
|
|
259
|
-
<code
|
|
289
|
+
<code ref={containerRef}>
|
|
290
|
+
{lines.map((line, i) => (
|
|
291
|
+
<span
|
|
292
|
+
key={i}
|
|
293
|
+
data-line={i + 1}
|
|
294
|
+
className={cn(
|
|
295
|
+
// Transparent left border by default so revealing a line only
|
|
296
|
+
// changes its color — never shifts the text (no layout jump).
|
|
297
|
+
"block border-l-2 border-transparent",
|
|
298
|
+
isRevealed(i + 1) && "border-primary bg-primary-subtle",
|
|
299
|
+
)}
|
|
300
|
+
>
|
|
301
|
+
{/* whitespace-pre inner + `\n` fallback preserves indentation and
|
|
302
|
+
the height of blank lines, mirroring LineNumberedPre. */}
|
|
303
|
+
<span className="whitespace-pre">
|
|
304
|
+
{line.trim() ? highlightYamlLine(line) : "\n"}
|
|
305
|
+
</span>
|
|
306
|
+
</span>
|
|
307
|
+
))}
|
|
308
|
+
</code>
|
|
260
309
|
</pre>
|
|
261
310
|
);
|
|
262
311
|
}
|
|
@@ -345,19 +394,47 @@ function JsonView({ content }: { readonly content: string }) {
|
|
|
345
394
|
// Plain text view (monospace + line numbers)
|
|
346
395
|
// ---------------------------------------------------------------------------
|
|
347
396
|
|
|
348
|
-
function PlainTextView({
|
|
349
|
-
|
|
397
|
+
function PlainTextView({
|
|
398
|
+
content,
|
|
399
|
+
reveal,
|
|
400
|
+
}: {
|
|
401
|
+
readonly content: string;
|
|
402
|
+
readonly reveal?: RevealTarget;
|
|
403
|
+
}) {
|
|
404
|
+
return <LineNumberedPre content={content} reveal={reveal} />;
|
|
350
405
|
}
|
|
351
406
|
|
|
352
|
-
|
|
407
|
+
/**
|
|
408
|
+
* Line-numbered monospace view. The single line-faithful primitive behind plain
|
|
409
|
+
* text, Markdown Source, and reveal-mode JSON: every row is addressable
|
|
410
|
+
* (`data-line`), so a {@link RevealTarget} can scroll to and highlight a line
|
|
411
|
+
* (via {@link useRevealLine}). Absent a reveal it renders exactly as before.
|
|
412
|
+
*/
|
|
413
|
+
function LineNumberedPre({
|
|
414
|
+
content,
|
|
415
|
+
reveal,
|
|
416
|
+
}: {
|
|
417
|
+
readonly content: string;
|
|
418
|
+
readonly reveal?: RevealTarget;
|
|
419
|
+
}) {
|
|
420
|
+
const { containerRef, isRevealed } = useRevealLine(reveal);
|
|
353
421
|
const lines = content.split("\n");
|
|
354
422
|
const gutterWidth = String(lines.length).length;
|
|
355
423
|
|
|
356
424
|
return (
|
|
357
425
|
<pre className="overflow-x-auto font-mono text-xs leading-relaxed text-foreground">
|
|
358
|
-
<code>
|
|
426
|
+
<code ref={containerRef}>
|
|
359
427
|
{lines.map((line, i) => (
|
|
360
|
-
<span
|
|
428
|
+
<span
|
|
429
|
+
key={i}
|
|
430
|
+
data-line={i + 1}
|
|
431
|
+
className={cn(
|
|
432
|
+
// Transparent left border by default so a reveal only recolors the
|
|
433
|
+
// row — never shifts its text (no layout jump).
|
|
434
|
+
"flex border-l-2 border-transparent",
|
|
435
|
+
isRevealed(i + 1) && "border-primary bg-primary-subtle",
|
|
436
|
+
)}
|
|
437
|
+
>
|
|
361
438
|
<span
|
|
362
439
|
className="sticky left-0 select-none bg-background pr-4 text-right text-muted-foreground"
|
|
363
440
|
style={{ minWidth: `${gutterWidth + 2}ch` }}
|
|
@@ -18,11 +18,18 @@ export interface FilePathContextValue {
|
|
|
18
18
|
* `FilePathLink` delegates to this callback instead of opening
|
|
19
19
|
* a URL or copying to clipboard. Platform builders use this to
|
|
20
20
|
* integrate their own file viewer or navigation.
|
|
21
|
+
*
|
|
22
|
+
* Return `false` to **decline** a specific path — `FilePathLink` then falls
|
|
23
|
+
* back to its default action (open the GitHub link / copy the path), so a
|
|
24
|
+
* handler that can only open *some* paths (e.g. resolvable workspace files)
|
|
25
|
+
* leaves the rest behaving as before. Returning `true` or `void` means the
|
|
26
|
+
* click was fully handled and the default is suppressed — preserving the
|
|
27
|
+
* behavior of existing `void`-returning handlers.
|
|
21
28
|
*/
|
|
22
29
|
readonly onFilePathClick?: (
|
|
23
30
|
path: string,
|
|
24
31
|
resolved: ResolvedPathAction,
|
|
25
|
-
) => void;
|
|
32
|
+
) => boolean | void;
|
|
26
33
|
}
|
|
27
34
|
|
|
28
35
|
const DEFAULT_VALUE: FilePathContextValue = {
|
|
@@ -92,15 +92,26 @@ export function FilePathLink({
|
|
|
92
92
|
// (ToolCallItem's role=button header); copying/opening a path must not
|
|
93
93
|
// also expand the row.
|
|
94
94
|
e.stopPropagation();
|
|
95
|
+
|
|
96
|
+
// Offer the click to the injected handler first. It returns `false` to
|
|
97
|
+
// DECLINE (e.g. an in-app viewer that can't open this particular path),
|
|
98
|
+
// in which case we fall through to the default action below. A `true`/
|
|
99
|
+
// `void` return means it fully handled the click.
|
|
95
100
|
if (onFilePathClick) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
101
|
+
const handled = onFilePathClick(path, resolved);
|
|
102
|
+
if (handled !== false) {
|
|
103
|
+
// For a link, also stop the browser from navigating (the file opened
|
|
104
|
+
// in-app instead). A modifier/middle-click bypasses this onClick, so
|
|
105
|
+
// the real <a href> still opens the target in a new tab.
|
|
106
|
+
if (resolved.action === "link") e.preventDefault();
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
99
109
|
}
|
|
110
|
+
|
|
100
111
|
if (resolved.action === "copy") {
|
|
101
112
|
handleCopy();
|
|
102
113
|
}
|
|
103
|
-
// For "link"
|
|
114
|
+
// For a declined/un-handled "link", the <a>'s native navigation runs.
|
|
104
115
|
},
|
|
105
116
|
[onFilePathClick, path, resolved, handleCopy],
|
|
106
117
|
);
|
|
@@ -125,13 +136,18 @@ export function FilePathLink({
|
|
|
125
136
|
</>
|
|
126
137
|
);
|
|
127
138
|
|
|
128
|
-
|
|
139
|
+
// A link-action path always renders a real anchor — even when an
|
|
140
|
+
// `onFilePathClick` handler is present — so native link affordances
|
|
141
|
+
// (middle-click, open-in-new-tab, copy-link-address) survive. `handleClick`
|
|
142
|
+
// intercepts a plain left-click to route it through the handler (e.g. into an
|
|
143
|
+
// in-app viewer) and only calls `preventDefault` when the handler took it.
|
|
144
|
+
if (resolved.action === "link") {
|
|
129
145
|
return (
|
|
130
146
|
<a
|
|
131
147
|
href={resolved.url}
|
|
132
148
|
target="_blank"
|
|
133
149
|
rel="noopener noreferrer"
|
|
134
|
-
onClick={
|
|
150
|
+
onClick={handleClick}
|
|
135
151
|
aria-label={ariaLabel}
|
|
136
152
|
title={title}
|
|
137
153
|
className={cn(sharedClasses, "group/fpl")}
|
|
@@ -3,12 +3,17 @@
|
|
|
3
3
|
import { memo, useMemo, useState } from "react";
|
|
4
4
|
import { Streamdown } from "streamdown";
|
|
5
5
|
import type { AgentMessage } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
MessageType,
|
|
8
|
+
type InteractionMode,
|
|
9
|
+
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
7
10
|
import { cn } from "@stigmer/theme";
|
|
8
11
|
import {
|
|
9
12
|
MARKDOWN_COMPONENTS,
|
|
10
13
|
unwrapEnclosingMarkdownFence,
|
|
11
14
|
} from "../internal/markdown-components.js";
|
|
15
|
+
import { InteractionModeBadge } from "./InteractionModeBadge.js";
|
|
16
|
+
import { PlanDocumentMessage } from "./PlanDocumentMessage.js";
|
|
12
17
|
import { useRenderTracer } from "../internal/dev/index.js";
|
|
13
18
|
|
|
14
19
|
/** Props for {@link MessageEntry}. */
|
|
@@ -24,6 +29,34 @@ export interface MessageEntryProps {
|
|
|
24
29
|
* this message for editing. Ignored for non-human messages.
|
|
25
30
|
*/
|
|
26
31
|
readonly onEdit?: () => void;
|
|
32
|
+
/**
|
|
33
|
+
* Renders a `MESSAGE_AI` entry as a first-class plan document
|
|
34
|
+
* ({@link PlanDocumentMessage}) instead of a chat bubble. Set by the thread
|
|
35
|
+
* builder only on the NO-ARTIFACT fallback path: a completed Plan turn that
|
|
36
|
+
* never published `plan.md` (older executions, failed upload) keeps its
|
|
37
|
+
* plan inline — the message is the only copy of the plan. A turn that
|
|
38
|
+
* published the artifact collapses the message into the compact plan card
|
|
39
|
+
* instead (the document lives in the panel's plan tab). Ignored for non-AI
|
|
40
|
+
* messages.
|
|
41
|
+
*/
|
|
42
|
+
readonly isPlanDocument?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* The turn's interaction mode, stamped by the thread builder on the
|
|
45
|
+
* synthetic prompt bubble (`MESSAGE_HUMAN`). Renders the
|
|
46
|
+
* {@link InteractionModeBadge} for non-default modes (a "Plan" pill), so
|
|
47
|
+
* the transcript reads unambiguously after mode switches. Ignored for
|
|
48
|
+
* non-human messages.
|
|
49
|
+
*/
|
|
50
|
+
readonly interactionMode?: InteractionMode;
|
|
51
|
+
/**
|
|
52
|
+
* Renders a `MESSAGE_HUMAN` entry as a compact "Build from plan" chip
|
|
53
|
+
* instead of a prompt bubble. Stamped by the thread builder from
|
|
54
|
+
* `execution_config.build_from_plan`: the turn's message is a short label
|
|
55
|
+
* (the implement instruction is runner-injected), so a full-width bubble
|
|
56
|
+
* would dignify machine plumbing as user prose. Ignored for non-human
|
|
57
|
+
* messages.
|
|
58
|
+
*/
|
|
59
|
+
readonly isBuildFromPlan?: boolean;
|
|
27
60
|
}
|
|
28
61
|
|
|
29
62
|
/**
|
|
@@ -54,6 +87,9 @@ export const MessageEntry = memo(function MessageEntry({
|
|
|
54
87
|
message,
|
|
55
88
|
className,
|
|
56
89
|
onEdit,
|
|
90
|
+
isPlanDocument,
|
|
91
|
+
interactionMode,
|
|
92
|
+
isBuildFromPlan,
|
|
57
93
|
}: MessageEntryProps) {
|
|
58
94
|
useRenderTracer("MessageEntry", {
|
|
59
95
|
messageType: message.type,
|
|
@@ -63,14 +99,27 @@ export const MessageEntry = memo(function MessageEntry({
|
|
|
63
99
|
|
|
64
100
|
switch (message.type) {
|
|
65
101
|
case MessageType.MESSAGE_HUMAN:
|
|
102
|
+
if (isBuildFromPlan) {
|
|
103
|
+
return (
|
|
104
|
+
<BuildFromPlanChip content={message.content} className={className} />
|
|
105
|
+
);
|
|
106
|
+
}
|
|
66
107
|
return (
|
|
67
108
|
<HumanMessage
|
|
68
109
|
content={message.content}
|
|
69
110
|
className={className}
|
|
70
111
|
onEdit={onEdit}
|
|
112
|
+
interactionMode={interactionMode}
|
|
71
113
|
/>
|
|
72
114
|
);
|
|
73
115
|
case MessageType.MESSAGE_AI:
|
|
116
|
+
// A completed Plan turn's plan is a document, not a bubble. The flag is
|
|
117
|
+
// only ever set on a settled message, so the streaming path is untouched.
|
|
118
|
+
if (isPlanDocument) {
|
|
119
|
+
return (
|
|
120
|
+
<PlanDocumentMessage content={message.content} className={className} />
|
|
121
|
+
);
|
|
122
|
+
}
|
|
74
123
|
return (
|
|
75
124
|
<AiMessage
|
|
76
125
|
content={message.content}
|
|
@@ -97,10 +146,12 @@ function HumanMessage({
|
|
|
97
146
|
content,
|
|
98
147
|
className,
|
|
99
148
|
onEdit,
|
|
149
|
+
interactionMode,
|
|
100
150
|
}: {
|
|
101
151
|
content: string;
|
|
102
152
|
className?: string;
|
|
103
153
|
onEdit?: () => void;
|
|
154
|
+
interactionMode?: InteractionMode;
|
|
104
155
|
}) {
|
|
105
156
|
return (
|
|
106
157
|
<div
|
|
@@ -111,6 +162,11 @@ function HumanMessage({
|
|
|
111
162
|
className,
|
|
112
163
|
)}
|
|
113
164
|
>
|
|
165
|
+
{/* The badge renders only for non-default modes (a "Plan" pill), so
|
|
166
|
+
ordinary Agent turns carry no extra chrome. */}
|
|
167
|
+
{interactionMode !== undefined && (
|
|
168
|
+
<InteractionModeBadge mode={interactionMode} className="mb-1.5" />
|
|
169
|
+
)}
|
|
114
170
|
<p className="text-sm text-foreground whitespace-pre-wrap">{content}</p>
|
|
115
171
|
{onEdit && (
|
|
116
172
|
<button
|
|
@@ -133,6 +189,60 @@ function HumanMessage({
|
|
|
133
189
|
);
|
|
134
190
|
}
|
|
135
191
|
|
|
192
|
+
/**
|
|
193
|
+
* The Build-from-plan turn's user entry: a compact pill in the user-turn
|
|
194
|
+
* position (right-aligned, like the prompt bubble it replaces) carrying the
|
|
195
|
+
* plan glyph and the turn's short label. Deliberately not editable — the
|
|
196
|
+
* label is not user prose to rephrase; refining the plan happens in the plan
|
|
197
|
+
* document, and the build is re-triggered from its card.
|
|
198
|
+
*/
|
|
199
|
+
function BuildFromPlanChip({
|
|
200
|
+
content,
|
|
201
|
+
className,
|
|
202
|
+
}: {
|
|
203
|
+
content: string;
|
|
204
|
+
className?: string;
|
|
205
|
+
}) {
|
|
206
|
+
return (
|
|
207
|
+
<div
|
|
208
|
+
role="article"
|
|
209
|
+
aria-label="Build from plan"
|
|
210
|
+
className={cn("flex justify-end", className)}
|
|
211
|
+
>
|
|
212
|
+
<span
|
|
213
|
+
className={cn(
|
|
214
|
+
"inline-flex items-center gap-1.5 rounded-full border border-border",
|
|
215
|
+
"bg-muted-subtle px-3 py-1.5 text-xs font-medium text-foreground",
|
|
216
|
+
)}
|
|
217
|
+
>
|
|
218
|
+
<BuildFromPlanIcon />
|
|
219
|
+
{content}
|
|
220
|
+
</span>
|
|
221
|
+
</div>
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** The plan-card glyph (document lines + implement arrow) at chip scale. */
|
|
226
|
+
function BuildFromPlanIcon() {
|
|
227
|
+
return (
|
|
228
|
+
<svg
|
|
229
|
+
width="13"
|
|
230
|
+
height="13"
|
|
231
|
+
viewBox="0 0 16 16"
|
|
232
|
+
fill="none"
|
|
233
|
+
stroke="currentColor"
|
|
234
|
+
strokeWidth="1.5"
|
|
235
|
+
strokeLinecap="round"
|
|
236
|
+
strokeLinejoin="round"
|
|
237
|
+
className="shrink-0 text-muted-foreground"
|
|
238
|
+
aria-hidden="true"
|
|
239
|
+
>
|
|
240
|
+
<path d="M3 4h10M3 8h7M3 12h8" />
|
|
241
|
+
<path d="M12.5 10.5l1.5 1.5-1.5 1.5" />
|
|
242
|
+
</svg>
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
|
|
136
246
|
function EditIcon() {
|
|
137
247
|
return (
|
|
138
248
|
<svg
|