@stigmer/react 3.0.9-dev.20260616060535 → 3.1.0
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/execution/ApprovalCard.d.ts +47 -3
- package/execution/ApprovalCard.d.ts.map +1 -1
- package/execution/ApprovalCard.js +138 -70
- package/execution/ApprovalCard.js.map +1 -1
- package/execution/ApprovalContext.d.ts +72 -0
- package/execution/ApprovalContext.d.ts.map +1 -0
- package/execution/ApprovalContext.js +41 -0
- package/execution/ApprovalContext.js.map +1 -0
- package/execution/ArtifactCard.d.ts.map +1 -1
- package/execution/ArtifactCard.js +3 -1
- package/execution/ArtifactCard.js.map +1 -1
- package/execution/ArtifactPreviewModal.d.ts.map +1 -1
- package/execution/ArtifactPreviewModal.js +5 -3
- package/execution/ArtifactPreviewModal.js.map +1 -1
- package/execution/EmptyChangeNotice.d.ts +38 -0
- package/execution/EmptyChangeNotice.d.ts.map +1 -0
- package/execution/EmptyChangeNotice.js +27 -0
- package/execution/EmptyChangeNotice.js.map +1 -0
- package/execution/FileChangesView.d.ts +81 -0
- package/execution/FileChangesView.d.ts.map +1 -0
- package/execution/FileChangesView.js +164 -0
- package/execution/FileChangesView.js.map +1 -0
- package/execution/FilePathLink.d.ts +24 -4
- package/execution/FilePathLink.d.ts.map +1 -1
- package/execution/FilePathLink.js +31 -9
- package/execution/FilePathLink.js.map +1 -1
- package/execution/FileReviewCard.d.ts +111 -0
- package/execution/FileReviewCard.d.ts.map +1 -0
- package/execution/FileReviewCard.js +558 -0
- package/execution/FileReviewCard.js.map +1 -0
- package/execution/FileReviewContext.d.ts +35 -0
- package/execution/FileReviewContext.d.ts.map +1 -0
- package/execution/FileReviewContext.js +23 -0
- package/execution/FileReviewContext.js.map +1 -0
- package/execution/FileReviewDock.d.ts +73 -0
- package/execution/FileReviewDock.d.ts.map +1 -0
- package/execution/FileReviewDock.js +65 -0
- package/execution/FileReviewDock.js.map +1 -0
- package/execution/McpToolDetail.d.ts.map +1 -1
- package/execution/McpToolDetail.js +38 -5
- package/execution/McpToolDetail.js.map +1 -1
- package/execution/MessageThread.d.ts +42 -3
- package/execution/MessageThread.d.ts.map +1 -1
- package/execution/MessageThread.js +263 -18
- package/execution/MessageThread.js.map +1 -1
- package/execution/PlanArtifactCard.d.ts.map +1 -1
- package/execution/PlanArtifactCard.js +3 -1
- package/execution/PlanArtifactCard.js.map +1 -1
- package/execution/PlanCompletionCard.d.ts +1 -1
- package/execution/PlanCompletionCard.js +1 -1
- package/execution/ResultView.d.ts +19 -1
- package/execution/ResultView.d.ts.map +1 -1
- package/execution/ResultView.js +141 -40
- package/execution/ResultView.js.map +1 -1
- package/execution/SubAgentSection.d.ts.map +1 -1
- package/execution/SubAgentSection.js +45 -6
- package/execution/SubAgentSection.js.map +1 -1
- package/execution/TerminalSession.d.ts +34 -0
- package/execution/TerminalSession.d.ts.map +1 -0
- package/execution/TerminalSession.js +34 -0
- package/execution/TerminalSession.js.map +1 -0
- package/execution/TodoCard.d.ts +53 -0
- package/execution/TodoCard.d.ts.map +1 -0
- package/execution/TodoCard.js +77 -0
- package/execution/TodoCard.js.map +1 -0
- package/execution/ToolArgsView.d.ts +7 -1
- package/execution/ToolArgsView.d.ts.map +1 -1
- package/execution/ToolArgsView.js +10 -9
- package/execution/ToolArgsView.js.map +1 -1
- package/execution/ToolCallDetail.d.ts +10 -1
- package/execution/ToolCallDetail.d.ts.map +1 -1
- package/execution/ToolCallDetail.js +66 -19
- package/execution/ToolCallDetail.js.map +1 -1
- package/execution/ToolCallGroup.d.ts +28 -18
- package/execution/ToolCallGroup.d.ts.map +1 -1
- package/execution/ToolCallGroup.js +39 -148
- package/execution/ToolCallGroup.js.map +1 -1
- package/execution/ToolCallItem.d.ts +36 -8
- package/execution/ToolCallItem.d.ts.map +1 -1
- package/execution/ToolCallItem.js +140 -21
- package/execution/ToolCallItem.js.map +1 -1
- package/execution/ToolRunGroup.d.ts +48 -0
- package/execution/ToolRunGroup.d.ts.map +1 -0
- package/execution/ToolRunGroup.js +168 -0
- package/execution/ToolRunGroup.js.map +1 -0
- package/execution/approval-provenance.d.ts +2 -0
- package/execution/approval-provenance.d.ts.map +1 -0
- package/execution/approval-provenance.js +6 -0
- package/execution/approval-provenance.js.map +1 -0
- package/execution/artifact-utils.d.ts +0 -10
- package/execution/artifact-utils.d.ts.map +1 -1
- package/execution/artifact-utils.js +0 -17
- package/execution/artifact-utils.js.map +1 -1
- package/execution/execution-phases.d.ts +1 -6
- package/execution/execution-phases.d.ts.map +1 -1
- package/execution/execution-phases.js +4 -14
- package/execution/execution-phases.js.map +1 -1
- package/execution/file-path-resolver.d.ts +28 -0
- package/execution/file-path-resolver.d.ts.map +1 -1
- package/execution/file-path-resolver.js +24 -0
- package/execution/file-path-resolver.js.map +1 -1
- package/execution/file-review-status.d.ts +127 -0
- package/execution/file-review-status.d.ts.map +1 -0
- package/execution/file-review-status.js +135 -0
- package/execution/file-review-status.js.map +1 -0
- package/execution/index.d.ts +39 -5
- package/execution/index.d.ts.map +1 -1
- package/execution/index.js +23 -3
- package/execution/index.js.map +1 -1
- package/execution/segment-tool-calls.d.ts +46 -0
- package/execution/segment-tool-calls.d.ts.map +1 -0
- package/execution/segment-tool-calls.js +71 -0
- package/execution/segment-tool-calls.js.map +1 -0
- package/execution/tool-categories.d.ts +62 -1
- package/execution/tool-categories.d.ts.map +1 -1
- package/execution/tool-categories.js +96 -2
- package/execution/tool-categories.js.map +1 -1
- package/execution/tool-presenter.d.ts +38 -2
- package/execution/tool-presenter.d.ts.map +1 -1
- package/execution/tool-presenter.js +23 -1
- package/execution/tool-presenter.js.map +1 -1
- package/execution/tool-rendering-primitives.d.ts.map +1 -1
- package/execution/tool-rendering-primitives.js +3 -2
- package/execution/tool-rendering-primitives.js.map +1 -1
- package/execution/useArtifactDownload.d.ts +44 -0
- package/execution/useArtifactDownload.d.ts.map +1 -0
- package/execution/useArtifactDownload.js +80 -0
- package/execution/useArtifactDownload.js.map +1 -0
- package/execution/useArtifactDownloadUrl.d.ts +67 -0
- package/execution/useArtifactDownloadUrl.d.ts.map +1 -0
- package/execution/useArtifactDownloadUrl.js +59 -0
- package/execution/useArtifactDownloadUrl.js.map +1 -0
- package/execution/useFileChangeContent.d.ts +61 -0
- package/execution/useFileChangeContent.d.ts.map +1 -0
- package/execution/useFileChangeContent.js +89 -0
- package/execution/useFileChangeContent.js.map +1 -0
- package/execution/useFileReview.d.ts +89 -0
- package/execution/useFileReview.d.ts.map +1 -0
- package/execution/useFileReview.js +106 -0
- package/execution/useFileReview.js.map +1 -0
- package/execution/useSubmitApproval.d.ts +17 -2
- package/execution/useSubmitApproval.d.ts.map +1 -1
- package/execution/useSubmitApproval.js +27 -23
- package/execution/useSubmitApproval.js.map +1 -1
- package/execution/useToolOutputContent.d.ts +44 -0
- package/execution/useToolOutputContent.d.ts.map +1 -0
- package/execution/useToolOutputContent.js +31 -0
- package/execution/useToolOutputContent.js.map +1 -0
- package/index.d.ts +6 -6
- package/index.d.ts.map +1 -1
- package/index.js +3 -3
- package/index.js.map +1 -1
- package/internal/ApprovalPeekBar.d.ts +23 -0
- package/internal/ApprovalPeekBar.d.ts.map +1 -0
- package/internal/ApprovalPeekBar.js +25 -0
- package/internal/ApprovalPeekBar.js.map +1 -0
- package/internal/BoundedContent.d.ts +49 -0
- package/internal/BoundedContent.d.ts.map +1 -0
- package/internal/BoundedContent.js +50 -0
- package/internal/BoundedContent.js.map +1 -0
- package/internal/DecisionButton.d.ts +47 -0
- package/internal/DecisionButton.d.ts.map +1 -0
- package/internal/DecisionButton.js +42 -0
- package/internal/DecisionButton.js.map +1 -0
- package/internal/InCardDecisionError.d.ts +31 -0
- package/internal/InCardDecisionError.d.ts.map +1 -0
- package/internal/InCardDecisionError.js +23 -0
- package/internal/InCardDecisionError.js.map +1 -0
- package/internal/RevealToggle.d.ts +36 -0
- package/internal/RevealToggle.d.ts.map +1 -0
- package/internal/RevealToggle.js +32 -0
- package/internal/RevealToggle.js.map +1 -0
- package/internal/VirtualizedThread.d.ts +7 -1
- package/internal/VirtualizedThread.d.ts.map +1 -1
- package/internal/VirtualizedThread.js +7 -3
- package/internal/VirtualizedThread.js.map +1 -1
- package/internal/useAutoDisclosure.d.ts +34 -0
- package/internal/useAutoDisclosure.d.ts.map +1 -0
- package/internal/useAutoDisclosure.js +53 -0
- package/internal/useAutoDisclosure.js.map +1 -0
- package/internal/useElapsedSince.d.ts +30 -0
- package/internal/useElapsedSince.d.ts.map +1 -0
- package/internal/useElapsedSince.js +70 -0
- package/internal/useElapsedSince.js.map +1 -0
- package/internal/useIsOverflowing.d.ts +30 -0
- package/internal/useIsOverflowing.d.ts.map +1 -0
- package/internal/useIsOverflowing.js +47 -0
- package/internal/useIsOverflowing.js.map +1 -0
- package/internal/useIsTextTruncated.d.ts +24 -0
- package/internal/useIsTextTruncated.d.ts.map +1 -0
- package/internal/useIsTextTruncated.js +41 -0
- package/internal/useIsTextTruncated.js.map +1 -0
- package/internal/useKeyedSubmission.d.ts +49 -0
- package/internal/useKeyedSubmission.d.ts.map +1 -0
- package/internal/useKeyedSubmission.js +67 -0
- package/internal/useKeyedSubmission.js.map +1 -0
- package/package.json +4 -4
- package/session/SessionViewer.d.ts +2 -2
- package/session/SessionViewer.d.ts.map +1 -1
- package/session/SessionViewer.js +10 -4
- package/session/SessionViewer.js.map +1 -1
- package/session/index.d.ts +2 -0
- package/session/index.d.ts.map +1 -1
- package/session/index.js +1 -0
- package/session/index.js.map +1 -1
- package/session/inspector/ChangesTab.d.ts +8 -5
- package/session/inspector/ChangesTab.d.ts.map +1 -1
- package/session/inspector/ChangesTab.js +11 -8
- package/session/inspector/ChangesTab.js.map +1 -1
- package/session/inspector/SessionInspector.d.ts +4 -4
- package/session/inspector/SessionInspector.d.ts.map +1 -1
- package/session/inspector/SessionInspector.js +4 -4
- package/session/inspector/SessionInspector.js.map +1 -1
- package/session/inspector/index.d.ts +0 -2
- package/session/inspector/index.d.ts.map +1 -1
- package/session/inspector/index.js +0 -1
- package/session/inspector/index.js.map +1 -1
- package/session/inspector/useSessionInspector.d.ts +8 -4
- package/session/inspector/useSessionInspector.d.ts.map +1 -1
- package/session/inspector/useSessionInspector.js +27 -20
- package/session/inspector/useSessionInspector.js.map +1 -1
- package/session/useSessionConversation.d.ts +37 -3
- package/session/useSessionConversation.d.ts.map +1 -1
- package/session/useSessionConversation.js +18 -2
- package/session/useSessionConversation.js.map +1 -1
- package/session/useSessionFileChanges.d.ts +74 -0
- package/session/useSessionFileChanges.d.ts.map +1 -0
- package/session/useSessionFileChanges.js +178 -0
- package/session/useSessionFileChanges.js.map +1 -0
- package/src/__tests__/styles-border-layer-invariant.test.ts +105 -0
- package/src/execution/ApprovalCard.tsx +368 -230
- package/src/execution/ApprovalContext.ts +109 -0
- package/src/execution/ArtifactCard.tsx +10 -6
- package/src/execution/ArtifactPreviewModal.tsx +12 -6
- package/src/execution/EmptyChangeNotice.tsx +62 -0
- package/src/execution/FileChangesView.tsx +383 -0
- package/src/execution/FilePathLink.tsx +65 -12
- package/src/execution/FileReviewCard.tsx +1118 -0
- package/src/execution/FileReviewContext.ts +53 -0
- package/src/execution/FileReviewDock.tsx +157 -0
- package/src/execution/McpToolDetail.tsx +98 -32
- package/src/execution/MessageThread.tsx +374 -9
- package/src/execution/PlanArtifactCard.tsx +9 -6
- package/src/execution/PlanCompletionCard.tsx +1 -1
- package/src/execution/ResultView.tsx +333 -162
- package/src/execution/SubAgentSection.tsx +58 -11
- package/src/execution/TerminalSession.tsx +91 -0
- package/src/execution/TodoCard.tsx +186 -0
- package/src/execution/ToolArgsView.tsx +28 -17
- package/src/execution/ToolCallDetail.tsx +137 -26
- package/src/execution/ToolCallGroup.tsx +68 -296
- package/src/execution/ToolCallItem.tsx +265 -67
- package/src/execution/ToolRunGroup.tsx +302 -0
- package/src/execution/__tests__/ApprovalCard.test.tsx +395 -5
- package/src/execution/__tests__/ArtifactPreviewModal.test.tsx +0 -1
- package/src/execution/__tests__/EmptyChangeNotice.test.tsx +24 -0
- package/src/execution/__tests__/FileChangesView.test.tsx +296 -0
- package/src/execution/__tests__/FilePathLink.test.tsx +92 -0
- package/src/execution/__tests__/FileReviewCard.test.tsx +1044 -0
- package/src/execution/__tests__/FileReviewDock.test.tsx +134 -0
- package/src/execution/__tests__/McpToolDetail.test.tsx +79 -0
- package/src/execution/__tests__/MessageThread.test.tsx +324 -0
- package/src/execution/__tests__/PlanArtifactCard.test.tsx +37 -16
- package/src/execution/__tests__/ResultView.test.tsx +280 -2
- package/src/execution/__tests__/SubAgentSection.test.tsx +180 -0
- package/src/execution/__tests__/TerminalSession.test.tsx +72 -0
- package/src/execution/__tests__/TodoCard.test.tsx +102 -0
- package/src/execution/__tests__/ToolArgsView.test.tsx +48 -0
- package/src/execution/__tests__/ToolCallDetail.test.tsx +195 -0
- package/src/execution/__tests__/ToolCallGroup.test.tsx +132 -0
- package/src/execution/__tests__/ToolCallItem.test.tsx +521 -0
- package/src/execution/__tests__/ToolRunGroup.test.tsx +137 -0
- package/src/execution/__tests__/blanked-narration.test.tsx +149 -0
- package/src/execution/__tests__/buildThreadItems-approvals.test.ts +304 -0
- package/src/execution/__tests__/buildThreadItems-file-review.test.ts +331 -0
- package/src/execution/__tests__/file-path-resolver.test.ts +44 -0
- package/src/execution/__tests__/file-review-status.test.ts +343 -0
- package/src/execution/__tests__/segment-tool-calls.test.ts +124 -0
- package/src/execution/__tests__/subagent-file-review-badge.test.tsx +273 -0
- package/src/execution/__tests__/thread-keys.test.ts +195 -0
- package/src/execution/__tests__/tool-presenter.test.tsx +95 -0
- package/src/execution/__tests__/useArtifactDownload.test.tsx +67 -0
- package/src/execution/__tests__/useArtifactDownloadUrl.test.tsx +51 -0
- package/src/execution/__tests__/useFileChangeContent.test.tsx +240 -0
- package/src/execution/__tests__/useFileReview.test.tsx +236 -0
- package/src/execution/__tests__/useSubmitApproval.test.tsx +165 -0
- package/src/execution/__tests__/useToolOutputContent.test.tsx +82 -0
- package/src/execution/approval-provenance.ts +8 -0
- package/src/execution/artifact-utils.ts +0 -18
- package/src/execution/execution-phases.ts +4 -16
- package/src/execution/file-path-resolver.ts +38 -0
- package/src/execution/file-review-status.ts +219 -0
- package/src/execution/index.ts +84 -4
- package/src/execution/segment-tool-calls.ts +101 -0
- package/src/execution/tool-categories.ts +128 -1
- package/src/execution/tool-presenter.ts +58 -3
- package/src/execution/tool-rendering-primitives.tsx +11 -14
- package/src/execution/useArtifactDownload.ts +109 -0
- package/src/execution/useArtifactDownloadUrl.ts +116 -0
- package/src/execution/useFileChangeContent.ts +149 -0
- package/src/execution/useFileReview.ts +197 -0
- package/src/execution/useSubmitApproval.ts +49 -27
- package/src/execution/useToolOutputContent.ts +70 -0
- package/src/index.ts +60 -1
- package/src/internal/ApprovalPeekBar.tsx +73 -0
- package/src/internal/BoundedContent.tsx +97 -0
- package/src/internal/DecisionButton.tsx +127 -0
- package/src/internal/InCardDecisionError.tsx +47 -0
- package/src/internal/RevealToggle.tsx +91 -0
- package/src/internal/VirtualizedThread.tsx +28 -2
- package/src/internal/__tests__/ApprovalPeekBar.test.tsx +34 -0
- package/src/internal/__tests__/BoundedContent.test.tsx +92 -0
- package/src/internal/__tests__/DecisionButton.test.tsx +107 -0
- package/src/internal/__tests__/RevealToggle.test.tsx +61 -0
- package/src/internal/__tests__/useAutoDisclosure.test.ts +74 -0
- package/src/internal/__tests__/useElapsedSince.test.tsx +68 -0
- package/src/internal/__tests__/useIsOverflowing.test.ts +36 -0
- package/src/internal/__tests__/useKeyedSubmission.test.tsx +126 -0
- package/src/internal/useAutoDisclosure.ts +58 -0
- package/src/internal/useElapsedSince.ts +72 -0
- package/src/internal/useIsOverflowing.ts +61 -0
- package/src/internal/useIsTextTruncated.ts +55 -0
- package/src/internal/useKeyedSubmission.ts +101 -0
- package/src/session/SessionViewer.tsx +21 -4
- package/src/session/__tests__/SessionViewer-fileReviewDock.test.tsx +198 -0
- package/src/session/__tests__/audienceWiring.test.tsx +4 -0
- package/src/session/__tests__/useSessionFileChanges.test.ts +303 -0
- package/src/session/index.ts +3 -0
- package/src/session/inspector/ChangesTab.tsx +20 -17
- package/src/session/inspector/SessionInspector.tsx +12 -10
- package/src/session/inspector/__tests__/ArtifactsTab.test.tsx +0 -1
- package/src/session/inspector/__tests__/ChangesTab.test.tsx +38 -0
- package/src/session/inspector/__tests__/useSessionInspector.test.ts +46 -61
- package/src/session/inspector/index.ts +0 -3
- package/src/session/inspector/useSessionInspector.ts +27 -20
- package/src/session/useSessionConversation.ts +80 -3
- package/src/session/useSessionFileChanges.ts +207 -0
- package/src/styles.css +35 -10
- package/src/version-history/DiffViewer.tsx +10 -7
- package/src/version-history/UnifiedDiffView.tsx +66 -0
- package/src/version-history/__tests__/DiffViewer.test.tsx +57 -0
- package/src/version-history/__tests__/UnifiedDiffView.test.tsx +50 -0
- package/src/version-history/__tests__/computeDiff.test.ts +35 -0
- package/src/version-history/__tests__/parseUnifiedDiff.test.ts +82 -0
- package/src/version-history/computeDiff.ts +6 -37
- package/src/version-history/diff-hunks.ts +63 -0
- package/src/version-history/index.ts +1 -0
- package/src/version-history/parseUnifiedDiff.ts +34 -0
- package/src/workflow/WorkflowExecutionApprovalCard.tsx +49 -24
- package/src/workflow/WorkflowExecutionTimeline.tsx +15 -4
- package/src/workflow/WorkflowExecutionTimelineEvent.tsx +8 -3
- package/src/workflow/WorkflowExecutionViewer.tsx +72 -28
- package/src/workflow/WorkflowFileReviewList.tsx +152 -0
- package/src/workflow/WorkflowTaskApprovalCard.tsx +37 -85
- package/src/workflow/__tests__/ExecutionInspector.test.tsx +30 -2
- package/src/workflow/__tests__/WorkflowExecutionApprovalCard.test.tsx +129 -0
- package/src/workflow/__tests__/WorkflowFileReviewList.test.tsx +129 -0
- package/src/workflow/__tests__/WorkflowTaskApprovalCard.test.tsx +43 -11
- package/src/workflow/__tests__/useWorkflowExecutionActions.test.tsx +276 -0
- package/src/workflow/execution-inspector/ExecutionInspector.tsx +42 -18
- package/src/workflow/index.ts +5 -0
- package/src/workflow/useWorkflowExecutionActions.ts +177 -29
- package/styles.css +1 -1
- package/version-history/DiffViewer.d.ts.map +1 -1
- package/version-history/DiffViewer.js +9 -3
- package/version-history/DiffViewer.js.map +1 -1
- package/version-history/UnifiedDiffView.d.ts +29 -0
- package/version-history/UnifiedDiffView.d.ts.map +1 -0
- package/version-history/UnifiedDiffView.js +36 -0
- package/version-history/UnifiedDiffView.js.map +1 -0
- package/version-history/computeDiff.d.ts +3 -1
- package/version-history/computeDiff.d.ts.map +1 -1
- package/version-history/computeDiff.js +5 -35
- package/version-history/computeDiff.js.map +1 -1
- package/version-history/diff-hunks.d.ts +21 -0
- package/version-history/diff-hunks.d.ts.map +1 -0
- package/version-history/diff-hunks.js +58 -0
- package/version-history/diff-hunks.js.map +1 -0
- package/version-history/index.d.ts +1 -0
- package/version-history/index.d.ts.map +1 -1
- package/version-history/index.js +1 -0
- package/version-history/index.js.map +1 -1
- package/version-history/parseUnifiedDiff.d.ts +22 -0
- package/version-history/parseUnifiedDiff.d.ts.map +1 -0
- package/version-history/parseUnifiedDiff.js +34 -0
- package/version-history/parseUnifiedDiff.js.map +1 -0
- package/workflow/WorkflowExecutionApprovalCard.d.ts +8 -1
- package/workflow/WorkflowExecutionApprovalCard.d.ts.map +1 -1
- package/workflow/WorkflowExecutionApprovalCard.js +17 -3
- package/workflow/WorkflowExecutionApprovalCard.js.map +1 -1
- package/workflow/WorkflowExecutionTimeline.d.ts +11 -2
- package/workflow/WorkflowExecutionTimeline.d.ts.map +1 -1
- package/workflow/WorkflowExecutionTimeline.js +2 -2
- package/workflow/WorkflowExecutionTimeline.js.map +1 -1
- package/workflow/WorkflowExecutionTimelineEvent.d.ts +4 -1
- package/workflow/WorkflowExecutionTimelineEvent.d.ts.map +1 -1
- package/workflow/WorkflowExecutionTimelineEvent.js +2 -2
- package/workflow/WorkflowExecutionTimelineEvent.js.map +1 -1
- package/workflow/WorkflowExecutionViewer.d.ts.map +1 -1
- package/workflow/WorkflowExecutionViewer.js +18 -10
- package/workflow/WorkflowExecutionViewer.js.map +1 -1
- package/workflow/WorkflowFileReviewList.d.ts +46 -0
- package/workflow/WorkflowFileReviewList.d.ts.map +1 -0
- package/workflow/WorkflowFileReviewList.js +48 -0
- package/workflow/WorkflowFileReviewList.js.map +1 -0
- package/workflow/WorkflowTaskApprovalCard.d.ts +8 -1
- package/workflow/WorkflowTaskApprovalCard.d.ts.map +1 -1
- package/workflow/WorkflowTaskApprovalCard.js +12 -19
- package/workflow/WorkflowTaskApprovalCard.js.map +1 -1
- package/workflow/execution-inspector/ExecutionInspector.d.ts +21 -4
- package/workflow/execution-inspector/ExecutionInspector.d.ts.map +1 -1
- package/workflow/execution-inspector/ExecutionInspector.js +6 -3
- package/workflow/execution-inspector/ExecutionInspector.js.map +1 -1
- package/workflow/index.d.ts +1 -0
- package/workflow/index.d.ts.map +1 -1
- package/workflow/index.js +1 -0
- package/workflow/index.js.map +1 -1
- package/workflow/useWorkflowExecutionActions.d.ts +62 -4
- package/workflow/useWorkflowExecutionActions.d.ts.map +1 -1
- package/workflow/useWorkflowExecutionActions.js +94 -18
- package/workflow/useWorkflowExecutionActions.js.map +1 -1
- package/session/inspector/PlanTab.d.ts +0 -15
- package/session/inspector/PlanTab.d.ts.map +0 -1
- package/session/inspector/PlanTab.js +0 -19
- package/session/inspector/PlanTab.js.map +0 -1
- package/src/session/inspector/PlanTab.tsx +0 -31
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { StructuredPatchHunk } from "diff";
|
|
2
|
+
import type { DiffHunk, DiffLine } from "./types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Maps the `diff` library's structured-patch hunks into our presentation
|
|
6
|
+
* {@link DiffHunk} shape, assigning running old/new line numbers per line.
|
|
7
|
+
*
|
|
8
|
+
* This is the single source of truth for the hunk mapping, shared by
|
|
9
|
+
* {@link computeDiff} (which feeds it `structuredPatch` output computed from
|
|
10
|
+
* before/after text) and `parseUnifiedDiff` (which feeds it `parsePatch` output
|
|
11
|
+
* parsed from a unified-diff string). Both functions in the `diff` library emit
|
|
12
|
+
* the identical {@link StructuredPatchHunk} shape, so one mapper serves both and
|
|
13
|
+
* the two diff sources can never drift in how a `+`/`-`/context line becomes a
|
|
14
|
+
* {@link DiffLine}.
|
|
15
|
+
*
|
|
16
|
+
* `` markers are skipped: they are diff metadata, not
|
|
17
|
+
* content, and would otherwise be mis-rendered as a spurious context line.
|
|
18
|
+
*
|
|
19
|
+
* Pure function — no side effects, safe to call outside React.
|
|
20
|
+
*/
|
|
21
|
+
export function mapPatchHunks(
|
|
22
|
+
hunks: readonly StructuredPatchHunk[],
|
|
23
|
+
): readonly DiffHunk[] {
|
|
24
|
+
return hunks.map((hunk) => {
|
|
25
|
+
const lines: DiffLine[] = [];
|
|
26
|
+
let oldLine = hunk.oldStart;
|
|
27
|
+
let newLine = hunk.newStart;
|
|
28
|
+
|
|
29
|
+
for (const raw of hunk.lines) {
|
|
30
|
+
// "" is a metadata marker, not a real line.
|
|
31
|
+
if (raw.startsWith("\\")) continue;
|
|
32
|
+
|
|
33
|
+
const prefix = raw[0];
|
|
34
|
+
const content = raw.slice(1);
|
|
35
|
+
|
|
36
|
+
if (prefix === "+") {
|
|
37
|
+
lines.push({ type: "added", content, newLineNumber: newLine });
|
|
38
|
+
newLine++;
|
|
39
|
+
} else if (prefix === "-") {
|
|
40
|
+
lines.push({ type: "removed", content, oldLineNumber: oldLine });
|
|
41
|
+
oldLine++;
|
|
42
|
+
} else {
|
|
43
|
+
// A context line (leading space) or an empty raw line.
|
|
44
|
+
lines.push({
|
|
45
|
+
type: "context",
|
|
46
|
+
content,
|
|
47
|
+
oldLineNumber: oldLine,
|
|
48
|
+
newLineNumber: newLine,
|
|
49
|
+
});
|
|
50
|
+
oldLine++;
|
|
51
|
+
newLine++;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
oldStart: hunk.oldStart,
|
|
57
|
+
oldLines: hunk.oldLines,
|
|
58
|
+
newStart: hunk.newStart,
|
|
59
|
+
newLines: hunk.newLines,
|
|
60
|
+
lines,
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
}
|
|
@@ -9,6 +9,7 @@ export type { DiffSummaryProps } from "./DiffSummary";
|
|
|
9
9
|
export { MultiFileDiffView } from "./MultiFileDiffView";
|
|
10
10
|
export type { MultiFileDiffViewProps } from "./MultiFileDiffView";
|
|
11
11
|
export { computeDiff } from "./computeDiff";
|
|
12
|
+
export { parseUnifiedDiff } from "./parseUnifiedDiff";
|
|
12
13
|
export { computeMultiFileDiff } from "./computeMultiFileDiff";
|
|
13
14
|
export type {
|
|
14
15
|
VersionEntry,
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { parsePatch } from "diff";
|
|
2
|
+
import { mapPatchHunks } from "./diff-hunks";
|
|
3
|
+
import type { DiffHunk } from "./types";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Parses a unified-diff patch *string* into presentation {@link DiffHunk}s.
|
|
7
|
+
*
|
|
8
|
+
* This is the bridge that lets a harness which only emits a ready unified diff
|
|
9
|
+
* (the Cursor harness's `diffString` -> `view.unifiedDiff` / `FileChange.
|
|
10
|
+
* unifiedDiff`) render through the same accessible {@link DiffViewer} table as a
|
|
11
|
+
* computed before/after diff — instead of being dumped as a raw `<pre>` with the
|
|
12
|
+
* `--- /dev/null`, `+++ b/...`, `@@` preamble and inline `+`/`-` prefixes.
|
|
13
|
+
*
|
|
14
|
+
* The `---`/`+++` file headers parse into metadata and are discarded; only the
|
|
15
|
+
* hunks survive, mapped through the shared {@link mapPatchHunks}. A diff input is
|
|
16
|
+
* a single file's patch, but `parsePatch` can return multiple file entries, so
|
|
17
|
+
* their hunks are flattened defensively.
|
|
18
|
+
*
|
|
19
|
+
* Returns `[]` for an empty or unparseable patch, so callers can fall back to a
|
|
20
|
+
* truthful raw rendering rather than showing a misleading "No changes".
|
|
21
|
+
*
|
|
22
|
+
* Pure function — no side effects, safe to call outside React.
|
|
23
|
+
*/
|
|
24
|
+
export function parseUnifiedDiff(patch: string): readonly DiffHunk[] {
|
|
25
|
+
if (!patch) return [];
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
return parsePatch(patch).flatMap((file) => mapPatchHunks(file.hunks));
|
|
29
|
+
} catch {
|
|
30
|
+
// parsePatch can throw on a badly malformed patch; degrade to "no hunks" so
|
|
31
|
+
// the caller renders its raw fallback instead of crashing the thread.
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { memo, useCallback, useState } from "react";
|
|
3
|
+
import { memo, useCallback, useEffect, useState } from "react";
|
|
4
4
|
import type { ApprovalAction } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
5
5
|
import { cn } from "@stigmer/theme";
|
|
6
|
+
import { DecisionButton } from "../internal/DecisionButton";
|
|
7
|
+
import { InCardDecisionError } from "../internal/InCardDecisionError";
|
|
6
8
|
|
|
7
9
|
/** Props for {@link WorkflowExecutionApprovalCard}. */
|
|
8
10
|
export interface WorkflowExecutionApprovalCardProps {
|
|
@@ -20,8 +22,15 @@ export interface WorkflowExecutionApprovalCardProps {
|
|
|
20
22
|
action: ApprovalAction,
|
|
21
23
|
comment?: string,
|
|
22
24
|
) => Promise<unknown>;
|
|
23
|
-
/** `true` while
|
|
25
|
+
/** `true` while this gate's submission is in flight. */
|
|
24
26
|
readonly isSubmitting: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* This gate's last failed decision, or `null`. Surfaced in-card beside the
|
|
29
|
+
* actions (via the shared {@link InCardDecisionError}) — supply
|
|
30
|
+
* {@link useWorkflowExecutionActions}'s `approvalErrorsByToolCallId` for this
|
|
31
|
+
* `toolCallId`.
|
|
32
|
+
*/
|
|
33
|
+
readonly error?: Error | null;
|
|
25
34
|
/** Additional CSS class names. */
|
|
26
35
|
readonly className?: string;
|
|
27
36
|
}
|
|
@@ -40,16 +49,26 @@ export const WorkflowExecutionApprovalCard = memo(function WorkflowExecutionAppr
|
|
|
40
49
|
timeoutSeconds,
|
|
41
50
|
onSubmitApproval,
|
|
42
51
|
isSubmitting,
|
|
52
|
+
error,
|
|
43
53
|
className,
|
|
44
54
|
}: WorkflowExecutionApprovalCardProps) {
|
|
45
55
|
const [comment, setComment] = useState("");
|
|
56
|
+
// Which action is in flight, so the spinner lands on the clicked button —
|
|
57
|
+
// matching ApprovalCard / WorkflowTaskApprovalCard. Reset once the RPC settles.
|
|
58
|
+
const [active, setActive] = useState<"approve" | "reject" | null>(null);
|
|
59
|
+
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
if (!isSubmitting) setActive(null);
|
|
62
|
+
}, [isSubmitting]);
|
|
46
63
|
|
|
47
64
|
// ApprovalAction enum values: 0=UNSPECIFIED, 1=APPROVE, 2=SKIP, 3=REJECT
|
|
48
65
|
const handleApprove = useCallback(() => {
|
|
66
|
+
setActive("approve");
|
|
49
67
|
onSubmitApproval(toolCallId, 1 as ApprovalAction, comment || undefined);
|
|
50
68
|
}, [toolCallId, comment, onSubmitApproval]);
|
|
51
69
|
|
|
52
70
|
const handleReject = useCallback(() => {
|
|
71
|
+
setActive("reject");
|
|
53
72
|
onSubmitApproval(toolCallId, 3 as ApprovalAction, comment || undefined);
|
|
54
73
|
}, [toolCallId, comment, onSubmitApproval]);
|
|
55
74
|
|
|
@@ -57,8 +76,10 @@ export const WorkflowExecutionApprovalCard = memo(function WorkflowExecutionAppr
|
|
|
57
76
|
<div
|
|
58
77
|
role="alert"
|
|
59
78
|
aria-label="Approval required"
|
|
79
|
+
// Neutral card + 2px warning left accent — the quiet Cursor-grade chrome
|
|
80
|
+
// shared with ApprovalCard. (Replaces the old amber `bg-warning/5` fill.)
|
|
60
81
|
className={cn(
|
|
61
|
-
"my-1 rounded-lg border border-
|
|
82
|
+
"my-1 rounded-lg border border-border-prominent border-l-2 border-l-warning p-3",
|
|
62
83
|
className,
|
|
63
84
|
)}
|
|
64
85
|
>
|
|
@@ -92,30 +113,34 @@ export const WorkflowExecutionApprovalCard = memo(function WorkflowExecutionAppr
|
|
|
92
113
|
</div>
|
|
93
114
|
|
|
94
115
|
<div className="mt-2 flex gap-2">
|
|
95
|
-
<
|
|
96
|
-
|
|
116
|
+
<DecisionButton
|
|
117
|
+
label="Approve"
|
|
118
|
+
variant="primary"
|
|
97
119
|
onClick={handleApprove}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
>
|
|
105
|
-
Approve
|
|
106
|
-
</button>
|
|
107
|
-
<button
|
|
108
|
-
type="button"
|
|
120
|
+
isActive={active === "approve"}
|
|
121
|
+
isSubmitting={isSubmitting}
|
|
122
|
+
/>
|
|
123
|
+
<DecisionButton
|
|
124
|
+
label="Reject"
|
|
125
|
+
variant="danger"
|
|
109
126
|
onClick={handleReject}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
"hover:bg-destructive/10 disabled:pointer-events-none disabled:opacity-50",
|
|
114
|
-
)}
|
|
115
|
-
>
|
|
116
|
-
Reject
|
|
117
|
-
</button>
|
|
127
|
+
isActive={active === "reject"}
|
|
128
|
+
isSubmitting={isSubmitting}
|
|
129
|
+
/>
|
|
118
130
|
</div>
|
|
131
|
+
|
|
132
|
+
{/* A failed decision surfaces HERE, beside this gate's actions — not in the
|
|
133
|
+
viewer's lifecycle banner. A workflow can hold many gates at once, so a
|
|
134
|
+
failure must name the one it belongs to; the optimistic spinner has
|
|
135
|
+
already reverted, and this explains the snap-back. Shared with the
|
|
136
|
+
agent ApprovalCard / FileReviewCard via InCardDecisionError. */}
|
|
137
|
+
{error && (
|
|
138
|
+
<InCardDecisionError
|
|
139
|
+
error={error}
|
|
140
|
+
leadIn="submit decision"
|
|
141
|
+
cursorTarget="wf-approval-error"
|
|
142
|
+
/>
|
|
143
|
+
)}
|
|
119
144
|
</div>
|
|
120
145
|
);
|
|
121
146
|
});
|
|
@@ -23,8 +23,17 @@ export interface WorkflowExecutionTimelineProps {
|
|
|
23
23
|
formData?: Record<string, unknown>,
|
|
24
24
|
comment?: string,
|
|
25
25
|
) => Promise<unknown>;
|
|
26
|
-
/**
|
|
27
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Task names whose human_input approval is currently in flight, keyed by
|
|
28
|
+
* `taskName` so deciding one gate never spins another. Supply
|
|
29
|
+
* {@link useWorkflowExecutionActions}'s `taskApprovalSubmittingTaskNames`.
|
|
30
|
+
*/
|
|
31
|
+
readonly taskApprovalSubmittingTaskNames?: ReadonlySet<string>;
|
|
32
|
+
/**
|
|
33
|
+
* Per-gate human_input approval failures, keyed by `taskName`. Supply
|
|
34
|
+
* {@link useWorkflowExecutionActions}'s `taskApprovalErrorsByTaskName`.
|
|
35
|
+
*/
|
|
36
|
+
readonly taskApprovalErrorsByTaskName?: ReadonlyMap<string, Error>;
|
|
28
37
|
/** Additional CSS class names. */
|
|
29
38
|
readonly className?: string;
|
|
30
39
|
}
|
|
@@ -47,7 +56,8 @@ export const WorkflowExecutionTimeline = memo(function WorkflowExecutionTimeline
|
|
|
47
56
|
onNavigateToAgentExecution,
|
|
48
57
|
taskStates,
|
|
49
58
|
onSubmitTaskApproval,
|
|
50
|
-
|
|
59
|
+
taskApprovalSubmittingTaskNames,
|
|
60
|
+
taskApprovalErrorsByTaskName,
|
|
51
61
|
className,
|
|
52
62
|
}: WorkflowExecutionTimelineProps) {
|
|
53
63
|
const scrollRef = useRef<HTMLDivElement>(null);
|
|
@@ -112,7 +122,8 @@ export const WorkflowExecutionTimeline = memo(function WorkflowExecutionTimeline
|
|
|
112
122
|
onNavigateToAgentExecution={onNavigateToAgentExecution}
|
|
113
123
|
taskStates={taskStates}
|
|
114
124
|
onSubmitTaskApproval={onSubmitTaskApproval}
|
|
115
|
-
|
|
125
|
+
taskApprovalSubmittingTaskNames={taskApprovalSubmittingTaskNames}
|
|
126
|
+
taskApprovalErrorsByTaskName={taskApprovalErrorsByTaskName}
|
|
116
127
|
/>
|
|
117
128
|
))}
|
|
118
129
|
|
|
@@ -19,7 +19,10 @@ interface TimelineEventProps {
|
|
|
19
19
|
formData?: Record<string, unknown>,
|
|
20
20
|
comment?: string,
|
|
21
21
|
) => Promise<unknown>;
|
|
22
|
-
|
|
22
|
+
/** Task names whose human_input approval is in flight, keyed by `taskName`. */
|
|
23
|
+
readonly taskApprovalSubmittingTaskNames?: ReadonlySet<string>;
|
|
24
|
+
/** Per-gate human_input approval failures, keyed by `taskName`. */
|
|
25
|
+
readonly taskApprovalErrorsByTaskName?: ReadonlyMap<string, Error>;
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
/**
|
|
@@ -37,7 +40,8 @@ export const WorkflowExecutionTimelineEvent = memo(function WorkflowExecutionTim
|
|
|
37
40
|
onNavigateToAgentExecution,
|
|
38
41
|
taskStates,
|
|
39
42
|
onSubmitTaskApproval,
|
|
40
|
-
|
|
43
|
+
taskApprovalSubmittingTaskNames,
|
|
44
|
+
taskApprovalErrorsByTaskName,
|
|
41
45
|
}: TimelineEventProps) {
|
|
42
46
|
const timestamp = formatTimestamp(event.occurredAt);
|
|
43
47
|
const p = event.payload;
|
|
@@ -277,7 +281,8 @@ export const WorkflowExecutionTimelineEvent = memo(function WorkflowExecutionTim
|
|
|
277
281
|
? (p.value.formSchema as unknown as Record<string, unknown>)
|
|
278
282
|
: undefined}
|
|
279
283
|
onSubmit={onSubmitTaskApproval}
|
|
280
|
-
isSubmitting={
|
|
284
|
+
isSubmitting={taskApprovalSubmittingTaskNames?.has(event.taskName) ?? false}
|
|
285
|
+
error={taskApprovalErrorsByTaskName?.get(event.taskName) ?? null}
|
|
281
286
|
/>
|
|
282
287
|
)}
|
|
283
288
|
</EventRow>
|
|
@@ -20,7 +20,8 @@ import { ExecutionInspector } from "./execution-inspector";
|
|
|
20
20
|
import { ExecutionComparisonPicker } from "./execution-comparison/ExecutionComparisonPicker";
|
|
21
21
|
import { ExecutionComparisonView } from "./execution-comparison/ExecutionComparisonView";
|
|
22
22
|
import { WorkflowExecutionApprovalCard } from "./WorkflowExecutionApprovalCard";
|
|
23
|
-
import type
|
|
23
|
+
import { WorkflowFileReviewList, type WorkflowFileDecisionSubmit } from "./WorkflowFileReviewList";
|
|
24
|
+
import type { WorkflowPendingApproval, WorkflowPendingFileReview } from "@stigmer/protos/ai/stigmer/agentic/workflowexecution/v1/api_pb";
|
|
24
25
|
import type { ApprovalAction } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
25
26
|
import { ResizableSplit } from "../internal/ResizableSplit";
|
|
26
27
|
|
|
@@ -287,7 +288,9 @@ export const WorkflowExecutionViewer = memo(function WorkflowExecutionViewer({
|
|
|
287
288
|
onClose={handleCloseComparePicker}
|
|
288
289
|
/>
|
|
289
290
|
|
|
290
|
-
{/* Action error banner
|
|
291
|
+
{/* Action error banner — lifecycle actions only (cancel/terminate/pause/
|
|
292
|
+
resume/recover). Approval failures are per-gate and surface in-card on
|
|
293
|
+
the failing approval card, never here. */}
|
|
291
294
|
{actions.error && (
|
|
292
295
|
<div className="flex items-center gap-2 border-b border-destructive/20 bg-destructive/5 px-4 py-2">
|
|
293
296
|
<p className="flex-1 text-xs text-destructive">{actions.error.message}</p>
|
|
@@ -365,9 +368,11 @@ export const WorkflowExecutionViewer = memo(function WorkflowExecutionViewer({
|
|
|
365
368
|
onNavigateToAgentExecution={onNavigateToAgentExecution}
|
|
366
369
|
pendingApprovals={execution?.status?.pendingApprovals}
|
|
367
370
|
onSubmitApproval={actions.submitApproval}
|
|
368
|
-
|
|
371
|
+
approvalSubmittingToolCallIds={actions.approvalSubmittingToolCallIds}
|
|
372
|
+
approvalErrorsByToolCallId={actions.approvalErrorsByToolCallId}
|
|
369
373
|
onSubmitTaskApproval={actions.submitTaskApproval}
|
|
370
|
-
|
|
374
|
+
taskApprovalSubmittingTaskNames={actions.taskApprovalSubmittingTaskNames}
|
|
375
|
+
taskApprovalErrorsByTaskName={actions.taskApprovalErrorsByTaskName}
|
|
371
376
|
className="min-h-0 flex-1"
|
|
372
377
|
/>
|
|
373
378
|
|
|
@@ -403,9 +408,16 @@ export const WorkflowExecutionViewer = memo(function WorkflowExecutionViewer({
|
|
|
403
408
|
onNavigateToAgentExecution={onNavigateToAgentExecution}
|
|
404
409
|
taskStates={effectiveTaskStates}
|
|
405
410
|
onSubmitTaskApproval={actions.submitTaskApproval}
|
|
406
|
-
|
|
411
|
+
taskApprovalSubmittingTaskNames={actions.taskApprovalSubmittingTaskNames}
|
|
412
|
+
taskApprovalErrorsByTaskName={actions.taskApprovalErrorsByTaskName}
|
|
407
413
|
pendingApprovals={execution?.status?.pendingApprovals}
|
|
408
414
|
onSubmitApproval={actions.submitApproval}
|
|
415
|
+
approvalSubmittingToolCallIds={actions.approvalSubmittingToolCallIds}
|
|
416
|
+
approvalErrorsByToolCallId={actions.approvalErrorsByToolCallId}
|
|
417
|
+
pendingFileReviews={execution?.status?.pendingFileReviews}
|
|
418
|
+
onSubmitFileDecision={actions.submitFileDecision}
|
|
419
|
+
fileDecisionSubmittingKeys={actions.fileDecisionSubmittingKeys}
|
|
420
|
+
fileDecisionErrorsByKey={actions.fileDecisionErrorsByKey}
|
|
409
421
|
/>
|
|
410
422
|
</div>
|
|
411
423
|
</>
|
|
@@ -449,9 +461,16 @@ function ExecutionBottomPanel({
|
|
|
449
461
|
onNavigateToAgentExecution,
|
|
450
462
|
taskStates,
|
|
451
463
|
onSubmitTaskApproval,
|
|
452
|
-
|
|
464
|
+
taskApprovalSubmittingTaskNames,
|
|
465
|
+
taskApprovalErrorsByTaskName,
|
|
453
466
|
pendingApprovals,
|
|
454
467
|
onSubmitApproval,
|
|
468
|
+
approvalSubmittingToolCallIds,
|
|
469
|
+
approvalErrorsByToolCallId,
|
|
470
|
+
pendingFileReviews,
|
|
471
|
+
onSubmitFileDecision,
|
|
472
|
+
fileDecisionSubmittingKeys,
|
|
473
|
+
fileDecisionErrorsByKey,
|
|
455
474
|
}: {
|
|
456
475
|
events: WorkflowExecutionTimelineProps["events"];
|
|
457
476
|
streamState: WorkflowExecutionTimelineProps["streamState"];
|
|
@@ -462,28 +481,39 @@ function ExecutionBottomPanel({
|
|
|
462
481
|
onNavigateToAgentExecution?: (id: string) => void;
|
|
463
482
|
taskStates: ReadonlyMap<string, DerivedTaskState>;
|
|
464
483
|
onSubmitTaskApproval: WorkflowExecutionTimelineProps["onSubmitTaskApproval"];
|
|
465
|
-
|
|
484
|
+
taskApprovalSubmittingTaskNames: ReadonlySet<string>;
|
|
485
|
+
taskApprovalErrorsByTaskName: ReadonlyMap<string, Error>;
|
|
466
486
|
pendingApprovals?: readonly WorkflowPendingApproval[];
|
|
467
487
|
onSubmitApproval?: (toolCallId: string, action: ApprovalAction, comment?: string) => Promise<unknown>;
|
|
488
|
+
approvalSubmittingToolCallIds: ReadonlySet<string>;
|
|
489
|
+
approvalErrorsByToolCallId: ReadonlyMap<string, Error>;
|
|
490
|
+
pendingFileReviews?: readonly WorkflowPendingFileReview[];
|
|
491
|
+
onSubmitFileDecision: WorkflowFileDecisionSubmit;
|
|
492
|
+
fileDecisionSubmittingKeys: ReadonlySet<string>;
|
|
493
|
+
fileDecisionErrorsByKey: ReadonlyMap<string, Error>;
|
|
468
494
|
}) {
|
|
469
495
|
const [collapsed, setCollapsed] = useState(false);
|
|
470
496
|
const [activeTab, setActiveTab] = useState<BottomTab>("waterfall");
|
|
471
|
-
const
|
|
497
|
+
const prevHitlCountRef = useRef(0);
|
|
472
498
|
|
|
473
499
|
const approvalCount = pendingApprovals?.length ?? 0;
|
|
474
|
-
const
|
|
500
|
+
const fileReviewCount = pendingFileReviews?.length ?? 0;
|
|
501
|
+
// Both HITL kinds (tool approvals + file reviews) share the one "Approvals" tab.
|
|
502
|
+
const hitlCount = approvalCount + fileReviewCount;
|
|
503
|
+
const hasHitl = hitlCount > 0;
|
|
475
504
|
|
|
476
|
-
// Auto-switch to Approvals tab when new
|
|
505
|
+
// Auto-switch to the Approvals tab when a new HITL gate (approval or file
|
|
506
|
+
// review) arrives; leave it when everything is resolved.
|
|
477
507
|
useEffect(() => {
|
|
478
|
-
if (
|
|
508
|
+
if (hitlCount > prevHitlCountRef.current && hitlCount > 0) {
|
|
479
509
|
setActiveTab("approvals");
|
|
480
510
|
setCollapsed(false);
|
|
481
511
|
}
|
|
482
|
-
if (
|
|
512
|
+
if (hitlCount === 0 && activeTab === "approvals") {
|
|
483
513
|
setActiveTab("waterfall");
|
|
484
514
|
}
|
|
485
|
-
|
|
486
|
-
}, [
|
|
515
|
+
prevHitlCountRef.current = hitlCount;
|
|
516
|
+
}, [hitlCount, activeTab]);
|
|
487
517
|
|
|
488
518
|
return (
|
|
489
519
|
<div className="border-t border-[var(--stgm-border,#e5e5e5)]">
|
|
@@ -516,9 +546,9 @@ function ExecutionBottomPanel({
|
|
|
516
546
|
isActive={activeTab === "events"}
|
|
517
547
|
onClick={() => { setActiveTab("events"); setCollapsed(false); }}
|
|
518
548
|
/>
|
|
519
|
-
{
|
|
549
|
+
{hasHitl && (
|
|
520
550
|
<TabButton
|
|
521
|
-
label={`Approvals (${
|
|
551
|
+
label={`Approvals (${hitlCount})`}
|
|
522
552
|
isActive={activeTab === "approvals"}
|
|
523
553
|
onClick={() => { setActiveTab("approvals"); setCollapsed(false); }}
|
|
524
554
|
/>
|
|
@@ -546,24 +576,38 @@ function ExecutionBottomPanel({
|
|
|
546
576
|
onNavigateToAgentExecution={onNavigateToAgentExecution}
|
|
547
577
|
taskStates={taskStates}
|
|
548
578
|
onSubmitTaskApproval={onSubmitTaskApproval}
|
|
549
|
-
|
|
579
|
+
taskApprovalSubmittingTaskNames={taskApprovalSubmittingTaskNames}
|
|
580
|
+
taskApprovalErrorsByTaskName={taskApprovalErrorsByTaskName}
|
|
550
581
|
className="h-full"
|
|
551
582
|
/>
|
|
552
583
|
)}
|
|
553
|
-
{activeTab === "approvals" &&
|
|
584
|
+
{activeTab === "approvals" && (
|
|
554
585
|
<div className="h-full overflow-y-auto px-4 py-3">
|
|
555
586
|
<div className="space-y-3">
|
|
556
|
-
{pendingApprovals.map((pa) =>
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
587
|
+
{pendingApprovals && onSubmitApproval && pendingApprovals.map((pa) => {
|
|
588
|
+
const toolCallId = pa.approval?.toolCallId ?? "";
|
|
589
|
+
return (
|
|
590
|
+
<WorkflowExecutionApprovalCard
|
|
591
|
+
key={toolCallId || pa.childAgentExecutionId}
|
|
592
|
+
prompt={pa.approval?.message || `Tool "${pa.approval?.toolName}" requires approval`}
|
|
593
|
+
toolCallId={toolCallId}
|
|
594
|
+
approvers={[]}
|
|
595
|
+
timeoutSeconds={0}
|
|
596
|
+
onSubmitApproval={onSubmitApproval}
|
|
597
|
+
isSubmitting={approvalSubmittingToolCallIds.has(toolCallId)}
|
|
598
|
+
error={approvalErrorsByToolCallId.get(toolCallId) ?? null}
|
|
599
|
+
/>
|
|
600
|
+
);
|
|
601
|
+
})}
|
|
602
|
+
{pendingFileReviews && pendingFileReviews.length > 0 && (
|
|
603
|
+
<WorkflowFileReviewList
|
|
604
|
+
pendingFileReviews={pendingFileReviews}
|
|
605
|
+
onSubmitFileDecision={onSubmitFileDecision}
|
|
606
|
+
submittingDecisionKeys={fileDecisionSubmittingKeys}
|
|
607
|
+
decisionErrors={fileDecisionErrorsByKey}
|
|
608
|
+
onNavigateToAgentExecution={onNavigateToAgentExecution}
|
|
565
609
|
/>
|
|
566
|
-
)
|
|
610
|
+
)}
|
|
567
611
|
</div>
|
|
568
612
|
</div>
|
|
569
613
|
)}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
import {
|
|
5
|
+
FileChangeSetStatus,
|
|
6
|
+
type FileDecisionAction,
|
|
7
|
+
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
8
|
+
import type { WorkflowPendingFileReview } from "@stigmer/protos/ai/stigmer/agentic/workflowexecution/v1/api_pb";
|
|
9
|
+
import { displayFileChangeSets } from "@stigmer/sdk";
|
|
10
|
+
import { cn } from "@stigmer/theme";
|
|
11
|
+
import { FileReviewCard } from "../execution/FileReviewCard";
|
|
12
|
+
import type { FileDecisionOptions } from "../execution/useFileReview";
|
|
13
|
+
import { useExecutionStream } from "../execution/useExecutionStream";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Submit handler for a workflow-level file decision, matching
|
|
17
|
+
* `useWorkflowExecutionActions().submitFileDecision`. The child id is bound per
|
|
18
|
+
* card so the surface only needs the card-level `(action, options)`.
|
|
19
|
+
*/
|
|
20
|
+
export type WorkflowFileDecisionSubmit = (
|
|
21
|
+
childAgentExecutionId: string,
|
|
22
|
+
changeSetId: string,
|
|
23
|
+
action: FileDecisionAction,
|
|
24
|
+
options?: FileDecisionOptions,
|
|
25
|
+
) => void;
|
|
26
|
+
|
|
27
|
+
/** Props for {@link WorkflowFileReviewList}. */
|
|
28
|
+
export interface WorkflowFileReviewListProps {
|
|
29
|
+
/**
|
|
30
|
+
* The parent workflow's surfaced file-review references
|
|
31
|
+
* (`status.pending_file_reviews`) — one entry per child agent execution.
|
|
32
|
+
*/
|
|
33
|
+
readonly pendingFileReviews: readonly WorkflowPendingFileReview[];
|
|
34
|
+
/** Forwards a decision to the child (see {@link WorkflowFileDecisionSubmit}). */
|
|
35
|
+
readonly onSubmitFileDecision: WorkflowFileDecisionSubmit;
|
|
36
|
+
/** In-flight decision keys (pass `fileDecisionSubmittingKeys` straight through). */
|
|
37
|
+
readonly submittingDecisionKeys?: ReadonlySet<string>;
|
|
38
|
+
/** Per-decision failures (pass `fileDecisionErrorsByKey` straight through). */
|
|
39
|
+
readonly decisionErrors?: ReadonlyMap<string, Error>;
|
|
40
|
+
/**
|
|
41
|
+
* Optional deep-link to open the child agent execution in its own view. When
|
|
42
|
+
* provided, each child's review renders a "View agent execution" affordance.
|
|
43
|
+
* Routing is the host's responsibility (DD-004).
|
|
44
|
+
*/
|
|
45
|
+
readonly onNavigateToAgentExecution?: (agentExecutionId: string) => void;
|
|
46
|
+
/** Additional CSS class names for the root container. */
|
|
47
|
+
readonly className?: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Renders the child agent file reviews surfaced on a parent WorkflowExecution.
|
|
52
|
+
*
|
|
53
|
+
* Reference-only, derive-from-child: the parent status carries only
|
|
54
|
+
* {@link WorkflowPendingFileReview} references (child id + change set ids). This
|
|
55
|
+
* list mounts one {@link WorkflowChildFileReview} per referenced child, which
|
|
56
|
+
* streams that child's execution and reuses the agent-level {@link FileReviewCard}
|
|
57
|
+
* to render the actual diff — the heavy content stays single-sourced on the child.
|
|
58
|
+
* A decision is forwarded to the child via `WorkflowExecution.submitFileDecision`.
|
|
59
|
+
*
|
|
60
|
+
* This is the file-review sibling of the workflow tool-approval surface
|
|
61
|
+
* (`WorkflowExecutionApprovalCard`). Empty `pendingFileReviews` renders nothing.
|
|
62
|
+
*/
|
|
63
|
+
export function WorkflowFileReviewList({
|
|
64
|
+
pendingFileReviews,
|
|
65
|
+
onSubmitFileDecision,
|
|
66
|
+
submittingDecisionKeys,
|
|
67
|
+
decisionErrors,
|
|
68
|
+
onNavigateToAgentExecution,
|
|
69
|
+
className,
|
|
70
|
+
}: WorkflowFileReviewListProps): React.ReactElement | null {
|
|
71
|
+
if (pendingFileReviews.length === 0) return null;
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<div className={cn("stgm space-y-3", className)}>
|
|
75
|
+
{pendingFileReviews.map((ref) => (
|
|
76
|
+
<WorkflowChildFileReview
|
|
77
|
+
key={ref.childAgentExecutionId}
|
|
78
|
+
reference={ref}
|
|
79
|
+
onSubmitFileDecision={onSubmitFileDecision}
|
|
80
|
+
submittingDecisionKeys={submittingDecisionKeys}
|
|
81
|
+
decisionErrors={decisionErrors}
|
|
82
|
+
onNavigateToAgentExecution={onNavigateToAgentExecution}
|
|
83
|
+
/>
|
|
84
|
+
))}
|
|
85
|
+
</div>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
interface WorkflowChildFileReviewProps {
|
|
90
|
+
readonly reference: WorkflowPendingFileReview;
|
|
91
|
+
readonly onSubmitFileDecision: WorkflowFileDecisionSubmit;
|
|
92
|
+
readonly submittingDecisionKeys?: ReadonlySet<string>;
|
|
93
|
+
readonly decisionErrors?: ReadonlyMap<string, Error>;
|
|
94
|
+
readonly onNavigateToAgentExecution?: (agentExecutionId: string) => void;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Streams a single referenced child agent execution and renders its
|
|
99
|
+
* AWAITING_REVIEW change sets (intersected with the parent's surfaced reference,
|
|
100
|
+
* so a decision always targets a gate the workflow has actually surfaced).
|
|
101
|
+
*/
|
|
102
|
+
function WorkflowChildFileReview({
|
|
103
|
+
reference,
|
|
104
|
+
onSubmitFileDecision,
|
|
105
|
+
submittingDecisionKeys,
|
|
106
|
+
decisionErrors,
|
|
107
|
+
onNavigateToAgentExecution,
|
|
108
|
+
}: WorkflowChildFileReviewProps): React.ReactElement | null {
|
|
109
|
+
const childId = reference.childAgentExecutionId;
|
|
110
|
+
const { execution } = useExecutionStream(childId);
|
|
111
|
+
|
|
112
|
+
const changeSets = useMemo(() => {
|
|
113
|
+
const referenced = new Set(reference.changeSetId);
|
|
114
|
+
return displayFileChangeSets(execution?.status).filter(
|
|
115
|
+
(cs) =>
|
|
116
|
+
cs.status === FileChangeSetStatus.AWAITING_REVIEW &&
|
|
117
|
+
referenced.has(cs.id) &&
|
|
118
|
+
cs.changes.length > 0,
|
|
119
|
+
);
|
|
120
|
+
}, [execution?.status, reference.changeSetId]);
|
|
121
|
+
|
|
122
|
+
// Nothing to show yet (child still loading, or its projection has not caught up
|
|
123
|
+
// to the reference). The parent list already signals "review pending" for this
|
|
124
|
+
// child by virtue of the reference existing.
|
|
125
|
+
if (changeSets.length === 0) return null;
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<div className="space-y-2">
|
|
129
|
+
{onNavigateToAgentExecution && (
|
|
130
|
+
<button
|
|
131
|
+
type="button"
|
|
132
|
+
onClick={() => onNavigateToAgentExecution(childId)}
|
|
133
|
+
className="text-xs text-muted-foreground hover:text-foreground underline underline-offset-2"
|
|
134
|
+
>
|
|
135
|
+
View agent execution
|
|
136
|
+
</button>
|
|
137
|
+
)}
|
|
138
|
+
{changeSets.map((changeSet) => (
|
|
139
|
+
<FileReviewCard
|
|
140
|
+
key={changeSet.id}
|
|
141
|
+
fileChangeSet={changeSet}
|
|
142
|
+
interactive
|
|
143
|
+
submittingDecisionKeys={submittingDecisionKeys}
|
|
144
|
+
decisionErrors={decisionErrors}
|
|
145
|
+
onSubmit={(action, options) =>
|
|
146
|
+
onSubmitFileDecision(childId, changeSet.id, action, options)
|
|
147
|
+
}
|
|
148
|
+
/>
|
|
149
|
+
))}
|
|
150
|
+
</div>
|
|
151
|
+
);
|
|
152
|
+
}
|