@stigmer/react 3.1.1 → 3.1.3
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 +25 -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/ArtifactPreviewModal.d.ts +5 -5
- package/execution/ArtifactPreviewModal.js +4 -4
- package/execution/ArtifactPreviewModal.js.map +1 -1
- package/execution/FileChangeProgressBar.d.ts +47 -0
- package/execution/FileChangeProgressBar.d.ts.map +1 -0
- package/execution/FileChangeProgressBar.js +49 -0
- package/execution/FileChangeProgressBar.js.map +1 -0
- package/execution/FileChangesView.d.ts.map +1 -1
- package/execution/FileChangesView.js +19 -4
- package/execution/FileChangesView.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/FileReviewAtoms.d.ts +27 -0
- package/execution/FileReviewAtoms.d.ts.map +1 -0
- package/execution/FileReviewAtoms.js +64 -0
- package/execution/FileReviewAtoms.js.map +1 -0
- package/execution/FileReviewCard.d.ts +2 -2
- package/execution/FileReviewCard.d.ts.map +1 -1
- package/execution/FileReviewCard.js +32 -62
- package/execution/FileReviewCard.js.map +1 -1
- package/execution/MessageEntry.d.ts +20 -0
- package/execution/MessageEntry.d.ts.map +1 -1
- package/execution/MessageEntry.js +19 -5
- package/execution/MessageEntry.js.map +1 -1
- package/execution/MessageThread.d.ts +75 -13
- package/execution/MessageThread.d.ts.map +1 -1
- package/execution/MessageThread.js +195 -27
- package/execution/MessageThread.js.map +1 -1
- package/execution/PlanArtifactCard.d.ts +36 -21
- package/execution/PlanArtifactCard.d.ts.map +1 -1
- package/execution/PlanArtifactCard.js +39 -25
- package/execution/PlanArtifactCard.js.map +1 -1
- package/execution/PlanCompletionCard.d.ts +4 -4
- package/execution/PlanCompletionCard.d.ts.map +1 -1
- package/execution/PlanCompletionCard.js +4 -4
- package/execution/PlanCompletionCard.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 +50 -0
- package/execution/PlanStreamingCard.d.ts.map +1 -0
- package/execution/PlanStreamingCard.js +40 -0
- package/execution/PlanStreamingCard.js.map +1 -0
- package/execution/index.d.ts +9 -1
- package/execution/index.d.ts.map +1 -1
- package/execution/index.js +4 -0
- package/execution/index.js.map +1 -1
- package/execution/use-build-from-plan-hotkey.d.ts +1 -1
- package/execution/use-build-from-plan-hotkey.js +1 -1
- package/execution/useArtifactCopy.d.ts +51 -0
- package/execution/useArtifactCopy.d.ts.map +1 -0
- package/execution/useArtifactCopy.js +75 -0
- package/execution/useArtifactCopy.js.map +1 -0
- package/execution/useArtifactDownload.d.ts.map +1 -1
- package/execution/useArtifactDownload.js +17 -5
- package/execution/useArtifactDownload.js.map +1 -1
- package/execution/useCreateAgentExecution.d.ts +12 -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 +43 -4
- package/library/detect-plan-artifact.d.ts.map +1 -1
- package/library/detect-plan-artifact.js +45 -5
- 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 +334 -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 +21 -0
- package/session/plan-document.d.ts.map +1 -0
- package/session/plan-document.js +28 -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 +14 -1
- package/session/useSessionConversation.d.ts.map +1 -1
- package/session/useSessionConversation.js +20 -2
- 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 +53 -10
- package/src/composer/__tests__/SessionComposer-contract.test.tsx +58 -4
- package/src/execution/ArtifactContentRenderer.tsx +101 -24
- package/src/execution/ArtifactPreviewModal.tsx +9 -9
- package/src/execution/FileChangeProgressBar.tsx +121 -0
- package/src/execution/FileChangesView.tsx +18 -4
- package/src/execution/FilePathContext.tsx +8 -1
- package/src/execution/FilePathLink.tsx +22 -6
- package/src/execution/FileReviewAtoms.tsx +89 -0
- package/src/execution/FileReviewCard.tsx +57 -90
- package/src/execution/MessageEntry.tsx +49 -1
- package/src/execution/MessageThread.tsx +308 -39
- package/src/execution/PlanArtifactCard.tsx +174 -64
- package/src/execution/PlanCompletionCard.tsx +5 -5
- package/src/execution/PlanDocumentMessage.tsx +96 -0
- package/src/execution/PlanStreamingCard.tsx +141 -0
- package/src/execution/__tests__/ArtifactContentRenderer.test.tsx +80 -1
- package/src/execution/__tests__/ArtifactPreviewModal.test.tsx +6 -6
- package/src/execution/__tests__/FileChangeProgressBar.test.tsx +125 -0
- package/src/execution/__tests__/FilePathLink.test.tsx +87 -0
- package/src/execution/__tests__/FileReviewCard.test.tsx +66 -7
- package/src/execution/__tests__/MessageThread.test.tsx +102 -1
- package/src/execution/__tests__/PlanArtifactCard.test.tsx +114 -26
- package/src/execution/__tests__/PlanCompletionCard.test.tsx +2 -2
- package/src/execution/__tests__/PlanDocumentMessage.test.tsx +55 -0
- package/src/execution/__tests__/PlanStreamingCard.test.tsx +56 -0
- package/src/execution/__tests__/buildThreadItems-plan-completion.test.ts +600 -22
- package/src/execution/__tests__/message-entry.test.tsx +17 -0
- package/src/execution/__tests__/useArtifactCopy.test.tsx +90 -0
- package/src/execution/__tests__/useArtifactDownload.test.tsx +2 -0
- package/src/execution/__tests__/useCreateAgentExecution.test.tsx +85 -0
- package/src/execution/index.ts +13 -1
- package/src/execution/use-build-from-plan-hotkey.ts +1 -1
- package/src/execution/useArtifactCopy.ts +109 -0
- package/src/execution/useArtifactDownload.ts +17 -5
- package/src/execution/useCreateAgentExecution.ts +18 -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 +69 -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 +56 -5
- 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 +69 -0
- package/src/library/__tests__/detect-streaming-plan.test.ts +234 -0
- package/src/library/detect-plan-artifact.ts +62 -5
- package/src/library/detect-streaming-plan.ts +108 -0
- package/src/library/index.ts +7 -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 +655 -96
- 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 +66 -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__/useSessionConversation.test.tsx +44 -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 +42 -8
- 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 +30 -0
- package/src/session/useOpenFileChange.ts +53 -0
- package/src/session/usePlanDraft.ts +109 -0
- package/src/session/useSessionConversation.ts +38 -3
- 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 +174 -0
- package/src/workspace/ExplorerTree.tsx +253 -0
- package/src/workspace/FileViewer.tsx +537 -0
- package/src/workspace/WorkspaceContentSearch.tsx +502 -0
- package/src/workspace/WorkspaceContentSearcher.ts +70 -0
- package/src/workspace/WorkspaceEditor.tsx +19 -16
- package/src/workspace/WorkspaceFileLister.ts +11 -0
- package/src/workspace/WorkspaceFileReader.ts +57 -0
- package/src/workspace/WorkspaceFileSearch.tsx +452 -0
- package/src/workspace/WorkspaceSurface.tsx +839 -0
- package/src/workspace/__tests__/EditorTabs.test.tsx +102 -0
- package/src/workspace/__tests__/ExplorerTree.test.tsx +204 -0
- package/src/workspace/__tests__/FileViewer.test.tsx +439 -0
- package/src/workspace/__tests__/WorkspaceContentSearch.test.tsx +229 -0
- package/src/workspace/__tests__/WorkspaceEditor-initialPanel.test.tsx +19 -0
- package/src/workspace/__tests__/WorkspaceFileSearch.test.tsx +227 -0
- package/src/workspace/__tests__/WorkspaceSurface.test.tsx +418 -0
- package/src/workspace/__tests__/a11y/harness.tsx +140 -0
- package/src/workspace/__tests__/a11y/mock-capabilities.ts +138 -0
- package/src/workspace/__tests__/a11y/workspace-editor.a11y.test.tsx +65 -0
- package/src/workspace/__tests__/a11y/workspace-explorer-search.a11y.test.tsx +112 -0
- package/src/workspace/__tests__/a11y/workspace-viewer-tabs.a11y.test.tsx +69 -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 +47 -0
- package/workspace/EditorTabs.d.ts.map +1 -0
- package/workspace/EditorTabs.js +78 -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 +49 -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 +193 -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 +216 -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/WorkspaceEditor.d.ts.map +1 -1
- package/workspace/WorkspaceEditor.js +8 -10
- package/workspace/WorkspaceEditor.js.map +1 -1
- 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 +175 -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 +220 -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
|
@@ -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>
|
|
@@ -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"}
|
|
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
|
+
}
|