@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
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { create } from "@bufbuild/protobuf";
|
|
3
|
+
import {
|
|
4
|
+
AgentExecutionSchema,
|
|
5
|
+
AgentExecutionStatusSchema,
|
|
6
|
+
type AgentExecution,
|
|
7
|
+
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
8
|
+
import {
|
|
9
|
+
AgentExecutionSpecSchema,
|
|
10
|
+
ExecutionConfigSchema,
|
|
11
|
+
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/spec_pb";
|
|
12
|
+
import { AgentMessageSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
|
|
13
|
+
import {
|
|
14
|
+
ExecutionPhase,
|
|
15
|
+
InteractionMode,
|
|
16
|
+
MessageType,
|
|
17
|
+
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
18
|
+
import { findStreamingPlan } from "../detect-streaming-plan";
|
|
19
|
+
|
|
20
|
+
function makeMessage(type: MessageType, content: string) {
|
|
21
|
+
const msg = create(AgentMessageSchema);
|
|
22
|
+
msg.type = type;
|
|
23
|
+
msg.content = content;
|
|
24
|
+
return msg;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function makeExecution(opts: {
|
|
28
|
+
phase?: ExecutionPhase;
|
|
29
|
+
interactionMode?: InteractionMode;
|
|
30
|
+
messages?: ReturnType<typeof makeMessage>[];
|
|
31
|
+
}): AgentExecution {
|
|
32
|
+
const exec = create(AgentExecutionSchema);
|
|
33
|
+
|
|
34
|
+
const spec = create(AgentExecutionSpecSchema);
|
|
35
|
+
if (opts.interactionMode !== undefined) {
|
|
36
|
+
const config = create(ExecutionConfigSchema);
|
|
37
|
+
config.interactionMode = opts.interactionMode;
|
|
38
|
+
spec.executionConfig = config;
|
|
39
|
+
}
|
|
40
|
+
exec.spec = spec;
|
|
41
|
+
|
|
42
|
+
const status = create(AgentExecutionStatusSchema);
|
|
43
|
+
status.phase = opts.phase ?? ExecutionPhase.EXECUTION_IN_PROGRESS;
|
|
44
|
+
if (opts.messages) {
|
|
45
|
+
status.messages = opts.messages;
|
|
46
|
+
}
|
|
47
|
+
exec.status = status;
|
|
48
|
+
|
|
49
|
+
return exec;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** A live Plan-mode execution with the given messages — the common case. */
|
|
53
|
+
function livePlanExecution(...messages: ReturnType<typeof makeMessage>[]) {
|
|
54
|
+
return makeExecution({
|
|
55
|
+
phase: ExecutionPhase.EXECUTION_IN_PROGRESS,
|
|
56
|
+
interactionMode: InteractionMode.PLAN,
|
|
57
|
+
messages,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
describe("findStreamingPlan — mode and phase gating", () => {
|
|
62
|
+
const planMessage = makeMessage(MessageType.MESSAGE_AI, "# The Plan\n\nBody");
|
|
63
|
+
|
|
64
|
+
it("detects a plan on a live Plan-mode execution", () => {
|
|
65
|
+
const plan = findStreamingPlan(livePlanExecution(planMessage));
|
|
66
|
+
expect(plan).toBeDefined();
|
|
67
|
+
expect(plan!.messageIndex).toBe(0);
|
|
68
|
+
expect(plan!.displayText).toBe("# The Plan\n\nBody");
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("returns undefined for null/undefined executions", () => {
|
|
72
|
+
expect(findStreamingPlan(null)).toBeUndefined();
|
|
73
|
+
expect(findStreamingPlan(undefined)).toBeUndefined();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("returns undefined for an Agent-mode execution, even with a plan-shaped message", () => {
|
|
77
|
+
const exec = makeExecution({
|
|
78
|
+
phase: ExecutionPhase.EXECUTION_IN_PROGRESS,
|
|
79
|
+
interactionMode: InteractionMode.AGENT,
|
|
80
|
+
messages: [planMessage],
|
|
81
|
+
});
|
|
82
|
+
expect(findStreamingPlan(exec)).toBeUndefined();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("returns undefined when no interaction mode is set", () => {
|
|
86
|
+
const exec = makeExecution({
|
|
87
|
+
phase: ExecutionPhase.EXECUTION_IN_PROGRESS,
|
|
88
|
+
messages: [planMessage],
|
|
89
|
+
});
|
|
90
|
+
expect(findStreamingPlan(exec)).toBeUndefined();
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it.each([
|
|
94
|
+
ExecutionPhase.EXECUTION_COMPLETED,
|
|
95
|
+
ExecutionPhase.EXECUTION_FAILED,
|
|
96
|
+
ExecutionPhase.EXECUTION_CANCELLED,
|
|
97
|
+
ExecutionPhase.EXECUTION_TERMINATED,
|
|
98
|
+
])("returns undefined for terminal phase %s", (phase) => {
|
|
99
|
+
const exec = makeExecution({
|
|
100
|
+
phase,
|
|
101
|
+
interactionMode: InteractionMode.PLAN,
|
|
102
|
+
messages: [planMessage],
|
|
103
|
+
});
|
|
104
|
+
expect(findStreamingPlan(exec)).toBeUndefined();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("detects during a non-terminal wait (approval gate mid-turn)", () => {
|
|
108
|
+
const exec = makeExecution({
|
|
109
|
+
phase: ExecutionPhase.EXECUTION_WAITING_FOR_APPROVAL,
|
|
110
|
+
interactionMode: InteractionMode.PLAN,
|
|
111
|
+
messages: [planMessage],
|
|
112
|
+
});
|
|
113
|
+
expect(findStreamingPlan(exec)).toBeDefined();
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
describe("findStreamingPlan — candidate selection", () => {
|
|
118
|
+
it("considers only the LAST content-bearing AI message", () => {
|
|
119
|
+
// The earlier plan-shaped message is settled narration once a later AI
|
|
120
|
+
// message exists — falling back to it would promote the wrong text.
|
|
121
|
+
const exec = livePlanExecution(
|
|
122
|
+
makeMessage(MessageType.MESSAGE_AI, "# Early heading in narration"),
|
|
123
|
+
makeMessage(MessageType.MESSAGE_AI, "Now let me check the tests."),
|
|
124
|
+
);
|
|
125
|
+
expect(findStreamingPlan(exec)).toBeUndefined();
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("skips trailing empty AI messages (extractFinalPlanText's rule)", () => {
|
|
129
|
+
const exec = livePlanExecution(
|
|
130
|
+
makeMessage(MessageType.MESSAGE_AI, "# The Plan\n\nBody"),
|
|
131
|
+
makeMessage(MessageType.MESSAGE_AI, " "),
|
|
132
|
+
);
|
|
133
|
+
expect(findStreamingPlan(exec)?.messageIndex).toBe(0);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it("ignores non-AI message types when selecting the candidate", () => {
|
|
137
|
+
const exec = livePlanExecution(
|
|
138
|
+
makeMessage(MessageType.MESSAGE_AI, "# The Plan\n\nBody"),
|
|
139
|
+
makeMessage(MessageType.MESSAGE_THINKING, "hmm, one more thing"),
|
|
140
|
+
makeMessage(MessageType.MESSAGE_TOOL, "tool output"),
|
|
141
|
+
);
|
|
142
|
+
expect(findStreamingPlan(exec)?.messageIndex).toBe(0);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("returns undefined when there are no messages", () => {
|
|
146
|
+
expect(findStreamingPlan(livePlanExecution())).toBeUndefined();
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
describe("findStreamingPlan — H1 convention", () => {
|
|
151
|
+
it("does not detect narration (no leading H1)", () => {
|
|
152
|
+
const exec = livePlanExecution(
|
|
153
|
+
makeMessage(MessageType.MESSAGE_AI, "Let me explore the codebase."),
|
|
154
|
+
);
|
|
155
|
+
expect(findStreamingPlan(exec)).toBeUndefined();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it("does not detect a lone '#' first token (title not started yet)", () => {
|
|
159
|
+
const exec = livePlanExecution(makeMessage(MessageType.MESSAGE_AI, "#"));
|
|
160
|
+
expect(findStreamingPlan(exec)).toBeUndefined();
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it("detects the moment the H1 gains its first title character", () => {
|
|
164
|
+
const exec = livePlanExecution(makeMessage(MessageType.MESSAGE_AI, "# T"));
|
|
165
|
+
expect(findStreamingPlan(exec)?.displayText).toBe("# T");
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it("does not detect an H2-led message (## is a section, not a plan title)", () => {
|
|
169
|
+
const exec = livePlanExecution(
|
|
170
|
+
makeMessage(MessageType.MESSAGE_AI, "## Notes\n\nSome section"),
|
|
171
|
+
);
|
|
172
|
+
expect(findStreamingPlan(exec)).toBeUndefined();
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it("tolerates leading blank lines before the H1", () => {
|
|
176
|
+
const exec = livePlanExecution(
|
|
177
|
+
makeMessage(MessageType.MESSAGE_AI, "\n\n# The Plan\n\nBody"),
|
|
178
|
+
);
|
|
179
|
+
expect(findStreamingPlan(exec)).toBeDefined();
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
describe("findStreamingPlan — unterminated-fence tolerance", () => {
|
|
184
|
+
it("unwraps an unterminated ```markdown fence", () => {
|
|
185
|
+
const exec = livePlanExecution(
|
|
186
|
+
makeMessage(MessageType.MESSAGE_AI, "```markdown\n# The Plan\n\nBody"),
|
|
187
|
+
);
|
|
188
|
+
expect(findStreamingPlan(exec)?.displayText).toBe("# The Plan\n\nBody");
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it("unwraps an unterminated ```md fence", () => {
|
|
192
|
+
const exec = livePlanExecution(
|
|
193
|
+
makeMessage(MessageType.MESSAGE_AI, "```md\n# The Plan"),
|
|
194
|
+
);
|
|
195
|
+
expect(findStreamingPlan(exec)?.displayText).toBe("# The Plan");
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it("unwraps an unterminated bare ``` fence (plan surfaces are markdown by contract)", () => {
|
|
199
|
+
const exec = livePlanExecution(
|
|
200
|
+
makeMessage(MessageType.MESSAGE_AI, "```\n# The Plan"),
|
|
201
|
+
);
|
|
202
|
+
expect(findStreamingPlan(exec)?.displayText).toBe("# The Plan");
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it("strips the closing fence once it streams in as the final line", () => {
|
|
206
|
+
const exec = livePlanExecution(
|
|
207
|
+
makeMessage(MessageType.MESSAGE_AI, "```markdown\n# The Plan\n\nBody\n```"),
|
|
208
|
+
);
|
|
209
|
+
expect(findStreamingPlan(exec)?.displayText).toBe("# The Plan\n\nBody");
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it("keeps a code-block fence inside the plan intact", () => {
|
|
213
|
+
const content = "```markdown\n# The Plan\n\n```ts\nconst x = 1;\n```\n\nMore";
|
|
214
|
+
const exec = livePlanExecution(makeMessage(MessageType.MESSAGE_AI, content));
|
|
215
|
+
// Only the ENCLOSING fence is stripped; the ts block's fences are content.
|
|
216
|
+
expect(findStreamingPlan(exec)?.displayText).toBe(
|
|
217
|
+
"# The Plan\n\n```ts\nconst x = 1;\n```\n\nMore",
|
|
218
|
+
);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it("never unwraps a fence with another language tag (a real code block)", () => {
|
|
222
|
+
const exec = livePlanExecution(
|
|
223
|
+
makeMessage(MessageType.MESSAGE_AI, "```python\n# not a heading, a comment"),
|
|
224
|
+
);
|
|
225
|
+
expect(findStreamingPlan(exec)).toBeUndefined();
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it("does not detect a fenced message whose body has no H1", () => {
|
|
229
|
+
const exec = livePlanExecution(
|
|
230
|
+
makeMessage(MessageType.MESSAGE_AI, "```\nplain fenced text"),
|
|
231
|
+
);
|
|
232
|
+
expect(findStreamingPlan(exec)).toBeUndefined();
|
|
233
|
+
});
|
|
234
|
+
});
|
|
@@ -3,14 +3,48 @@ import type { ExecutionArtifact } from "@stigmer/protos/ai/stigmer/agentic/agent
|
|
|
3
3
|
import { ExecutionArtifactKind } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* The session's current plan: the published plan artifact (a `*.plan.md` FILE)
|
|
7
|
+
* of the most recent execution that produced one, plus the execution it belongs
|
|
8
|
+
* to (artifact content RPCs are execution-scoped).
|
|
9
|
+
*/
|
|
10
|
+
export interface SessionPlan {
|
|
11
|
+
/** ID of the execution that published the plan. */
|
|
12
|
+
readonly executionId: string;
|
|
13
|
+
/** The published plan artifact (`*.plan.md`). */
|
|
14
|
+
readonly artifact: ExecutionArtifact;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Legacy plan filename. Detection-only: {@link isPlanArtifactName} still
|
|
19
|
+
* accepts this exact name so plans published before named artifacts existed
|
|
20
|
+
* keep working. The runner never freshly emits it (a titleless plan falls back
|
|
21
|
+
* to a bare `<id>.plan.md`). Kept in sync with the runner's
|
|
22
|
+
* `PLAN_ARTIFACT_NAME` (shared/plan-artifact.ts).
|
|
8
23
|
*/
|
|
9
24
|
export const PLAN_ARTIFACT_NAME = "plan.md";
|
|
10
25
|
|
|
11
26
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
27
|
+
* Suffix every named plan artifact carries (`<slug>_<id>.plan.md`, or a bare
|
|
28
|
+
* `<id>.plan.md` when untitled). The runner derives the slug from the plan's
|
|
29
|
+
* title and the `<id>` from its content hash; detection keys on this suffix.
|
|
30
|
+
* Kept in sync with the runner's `PLAN_ARTIFACT_SUFFIX` (shared/plan-artifact.ts)
|
|
31
|
+
* — the runner and browser SDK have disjoint module graphs, so the constant is
|
|
32
|
+
* duplicated by design, mirroring {@link PLAN_ARTIFACT_NAME}.
|
|
33
|
+
*/
|
|
34
|
+
export const PLAN_ARTIFACT_SUFFIX = ".plan.md";
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Returns `true` when a filename is a plan's: the legacy exact `plan.md`, or
|
|
38
|
+
* any `*.plan.md`. Accepting the legacy name keeps plans published before named
|
|
39
|
+
* artifacts existed detectable.
|
|
40
|
+
*/
|
|
41
|
+
export function isPlanArtifactName(name: string): boolean {
|
|
42
|
+
return name === PLAN_ARTIFACT_NAME || name.endsWith(PLAN_ARTIFACT_SUFFIX);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Returns `true` when an artifact is the published plan: a FILE artifact whose
|
|
47
|
+
* name satisfies {@link isPlanArtifactName}.
|
|
14
48
|
*
|
|
15
49
|
* Detection is by convention — the same lightweight, content-free approach used
|
|
16
50
|
* for skill packages ({@link isSkillPackage}) — so the UI never needs an extra
|
|
@@ -20,7 +54,7 @@ export const PLAN_ARTIFACT_NAME = "plan.md";
|
|
|
20
54
|
export function isPlanArtifact(artifact: ExecutionArtifact): boolean {
|
|
21
55
|
return (
|
|
22
56
|
artifact.kind === ExecutionArtifactKind.FILE &&
|
|
23
|
-
artifact.name
|
|
57
|
+
isPlanArtifactName(artifact.name)
|
|
24
58
|
);
|
|
25
59
|
}
|
|
26
60
|
|
|
@@ -41,3 +75,26 @@ export function findPlanArtifact(
|
|
|
41
75
|
}
|
|
42
76
|
return undefined;
|
|
43
77
|
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Finds the session's LATEST plan across all executions — the plan the panel's
|
|
81
|
+
* plan document tab edits and the "Build" action implements. Executions are
|
|
82
|
+
* scanned newest-first (the array is chronological), mirroring the thread's
|
|
83
|
+
* latest-plan-owns-the-build-action rule so every surface agrees on which
|
|
84
|
+
* plan is current.
|
|
85
|
+
*
|
|
86
|
+
* Returns `undefined` when no execution in the session published a plan.
|
|
87
|
+
*/
|
|
88
|
+
export function findLatestSessionPlan(
|
|
89
|
+
executions: readonly AgentExecution[],
|
|
90
|
+
): SessionPlan | undefined {
|
|
91
|
+
for (let i = executions.length - 1; i >= 0; i--) {
|
|
92
|
+
const execution = executions[i];
|
|
93
|
+
const artifact = findPlanArtifact(execution);
|
|
94
|
+
const executionId = execution.metadata?.id;
|
|
95
|
+
if (artifact && executionId) {
|
|
96
|
+
return { executionId, artifact };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { AgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
2
|
+
import {
|
|
3
|
+
InteractionMode,
|
|
4
|
+
MessageType,
|
|
5
|
+
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
6
|
+
import { isTerminalPhase } from "@stigmer/sdk";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A plan being written by a live Plan-mode execution, detected mid-stream so
|
|
10
|
+
* the UI can promote it to a document surface (panel plan tab + compact thread
|
|
11
|
+
* card) instead of letting it dump into the chat as a giant streaming bubble.
|
|
12
|
+
*/
|
|
13
|
+
export interface StreamingPlan {
|
|
14
|
+
/** Index of the plan message in `execution.status.messages`. */
|
|
15
|
+
readonly messageIndex: number;
|
|
16
|
+
/**
|
|
17
|
+
* The plan text to render on document surfaces: the message content with
|
|
18
|
+
* any enclosing plan fence stripped, streaming-tolerantly (an unterminated
|
|
19
|
+
* opening fence is stripped too — see {@link findStreamingPlan}). Purely a
|
|
20
|
+
* display projection; the stored message is never mutated.
|
|
21
|
+
*/
|
|
22
|
+
readonly displayText: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Opening line of a whole-message plan fence: ``` with no language tag, or
|
|
27
|
+
* tagged `markdown`/`md`. Any other tag (```python …) means the message opens
|
|
28
|
+
* with a genuine code block, not a wrapped plan, and is never unwrapped —
|
|
29
|
+
* mirroring `unwrapEnclosingMarkdownFence`'s tag rules.
|
|
30
|
+
*/
|
|
31
|
+
const OPENING_PLAN_FENCE_RE = /^(`{3,})(?:markdown|md)?[ \t]*\r?\n/;
|
|
32
|
+
|
|
33
|
+
/** A streaming plan message qualifies when it opens with an `# H1` title. */
|
|
34
|
+
const LEADING_H1_RE = /^#[ \t]/;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Streaming-tolerant unwrap of a whole-message plan fence.
|
|
38
|
+
*
|
|
39
|
+
* `unwrapEnclosingMarkdownFence` deliberately no-ops until the closing fence
|
|
40
|
+
* arrives (transcripts must stay faithful while a genuine code block is still
|
|
41
|
+
* open). A plan surface can't wait: mid-stream the closing fence hasn't
|
|
42
|
+
* streamed yet, and rendering the fence as-is turns the whole live plan into
|
|
43
|
+
* one giant code block. Because Plan mode's output IS a markdown document by
|
|
44
|
+
* contract, a message that OPENS with a bare/markdown fence is a wrapped plan
|
|
45
|
+
* — so this strips the opening fence immediately and the closing fence
|
|
46
|
+
* whenever it shows up as the final line.
|
|
47
|
+
*/
|
|
48
|
+
function unwrapStreamingPlanFence(content: string): string {
|
|
49
|
+
const trimmed = content.trim();
|
|
50
|
+
const open = OPENING_PLAN_FENCE_RE.exec(trimmed);
|
|
51
|
+
if (!open) return content;
|
|
52
|
+
const body = trimmed.slice(open[0].length);
|
|
53
|
+
// Strip the closing fence only when it is the final line (same backtick
|
|
54
|
+
// run); a fence anywhere else belongs to a code block inside the plan.
|
|
55
|
+
const close = new RegExp(`(?:^|\\r?\\n)${open[1]}[ \\t]*$`);
|
|
56
|
+
const closeMatch = close.exec(body);
|
|
57
|
+
return closeMatch ? body.slice(0, closeMatch.index) : body;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Detects the plan a live Plan-mode execution is currently writing, or
|
|
62
|
+
* `undefined` when the execution has no recognizable plan in flight.
|
|
63
|
+
*
|
|
64
|
+
* This is the third leg of the plan convention, alongside the runner's prompt
|
|
65
|
+
* directive ("your FINAL message IS the plan, starting with a single `#`
|
|
66
|
+
* title" — `plan-mode-prompt.ts`) and the completion-time artifact detection
|
|
67
|
+
* by filename ({@link isPlanArtifact}). Completion makes the plan unambiguous
|
|
68
|
+
* (the published `plan.md` artifact); mid-stream it must be inferred, and the
|
|
69
|
+
* directive's mandated shape is the inference:
|
|
70
|
+
*
|
|
71
|
+
* - the execution runs in Plan mode and is **non-terminal** (a completed turn
|
|
72
|
+
* is owned by the artifact path; a stopped/failed turn has no live plan),
|
|
73
|
+
* - the candidate is the **last content-bearing `MESSAGE_AI`** — the exact
|
|
74
|
+
* selection rule the runner's `extractFinalPlanText` and the thread's
|
|
75
|
+
* `findPlanMessageIndex` share, so all three stay in lockstep,
|
|
76
|
+
* - and that candidate opens with an `# H1` title (after tolerating an
|
|
77
|
+
* enclosing plan fence, see {@link unwrapStreamingPlanFence}) — the shape
|
|
78
|
+
* the directive mandates and narration essentially never has.
|
|
79
|
+
*
|
|
80
|
+
* Degradation is graceful by design: a model that ignores the directive
|
|
81
|
+
* simply streams its plan in the thread as before, and the completion-time
|
|
82
|
+
* pipeline is unaffected either way. Only the LAST content-bearing AI message
|
|
83
|
+
* is ever considered — an earlier message is settled narration, and falling
|
|
84
|
+
* back to it would promote the wrong text.
|
|
85
|
+
*/
|
|
86
|
+
export function findStreamingPlan(
|
|
87
|
+
execution: AgentExecution | null | undefined,
|
|
88
|
+
): StreamingPlan | undefined {
|
|
89
|
+
if (
|
|
90
|
+
execution?.spec?.executionConfig?.interactionMode !== InteractionMode.PLAN
|
|
91
|
+
) {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
const phase = execution.status?.phase;
|
|
95
|
+
if (phase === undefined || isTerminalPhase(phase)) return undefined;
|
|
96
|
+
|
|
97
|
+
const messages = execution.status?.messages ?? [];
|
|
98
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
99
|
+
const msg = messages[i];
|
|
100
|
+
if (msg.type !== MessageType.MESSAGE_AI) continue;
|
|
101
|
+
if (msg.content.trim().length === 0) continue;
|
|
102
|
+
const displayText = unwrapStreamingPlanFence(msg.content);
|
|
103
|
+
return LEADING_H1_RE.test(displayText.trimStart())
|
|
104
|
+
? { messageIndex: i, displayText }
|
|
105
|
+
: undefined;
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
package/src/library/index.ts
CHANGED
|
@@ -26,9 +26,16 @@ export type { SkillPackageDetection } from "./detect-skill-package.js";
|
|
|
26
26
|
|
|
27
27
|
export {
|
|
28
28
|
isPlanArtifact,
|
|
29
|
+
isPlanArtifactName,
|
|
29
30
|
findPlanArtifact,
|
|
31
|
+
findLatestSessionPlan,
|
|
30
32
|
PLAN_ARTIFACT_NAME,
|
|
33
|
+
PLAN_ARTIFACT_SUFFIX,
|
|
31
34
|
} from "./detect-plan-artifact.js";
|
|
35
|
+
export type { SessionPlan } from "./detect-plan-artifact.js";
|
|
36
|
+
|
|
37
|
+
export { findStreamingPlan } from "./detect-streaming-plan.js";
|
|
38
|
+
export type { StreamingPlan } from "./detect-streaming-plan.js";
|
|
32
39
|
|
|
33
40
|
export { useDetectSkillPackage } from "./useDetectSkillPackage.js";
|
|
34
41
|
export type { UseDetectSkillPackageReturn } from "./useDetectSkillPackage.js";
|