@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
|
@@ -1,15 +1,165 @@
|
|
|
1
1
|
import { describe, it, expect, afterEach, vi } from "vitest";
|
|
2
|
-
import { render, cleanup, fireEvent } from "@testing-library/react";
|
|
2
|
+
import { render, screen, cleanup, fireEvent } from "@testing-library/react";
|
|
3
3
|
import { create } from "@bufbuild/protobuf";
|
|
4
4
|
import { PendingApprovalSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/approval_pb";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
ApprovalAction,
|
|
7
|
+
ApprovalPolicySource,
|
|
8
|
+
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
6
9
|
import { ToolKind } from "@stigmer/sdk";
|
|
7
10
|
import { ApprovalCard } from "../ApprovalCard";
|
|
8
11
|
|
|
12
|
+
// Under apply-then-review the deny-gate carries no captured `file_changes`
|
|
13
|
+
// (message.proto field 14 was removed in Phase 5 Slice 4); the gate renders the
|
|
14
|
+
// proposed change from the tool args. Captured file review renders via
|
|
15
|
+
// FileReviewCard, tested separately.
|
|
16
|
+
|
|
9
17
|
afterEach(cleanup);
|
|
10
18
|
|
|
11
19
|
const noop = () => {};
|
|
12
20
|
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// Tool classification (ToolArgsView fallback path)
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
describe("ApprovalCard chrome", () => {
|
|
26
|
+
it("renders neutral Cursor-style chrome with a restrained warning accent (no amber fill)", () => {
|
|
27
|
+
const approval = create(PendingApprovalSchema, {
|
|
28
|
+
toolCallId: "tc-chrome",
|
|
29
|
+
toolName: "write_file",
|
|
30
|
+
toolKind: ToolKind.FILE_EDIT,
|
|
31
|
+
argsPreview: '{"path":"src/x.ts","contents":"x"}',
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
render(<ApprovalCard pendingApproval={approval} onSubmit={noop} />);
|
|
35
|
+
|
|
36
|
+
const card = screen.getByRole("alert");
|
|
37
|
+
// Visible neutral line + a restrained 2px warning left accent — never the
|
|
38
|
+
// old amber background fill. (Class presence only; that the line actually
|
|
39
|
+
// RENDERS is proven by the layer-invariant + e2e computed-style guards —
|
|
40
|
+
// happy-dom cannot resolve `@layer`.)
|
|
41
|
+
expect(card.className).toContain("border-border-prominent");
|
|
42
|
+
expect(card.className).toContain("border-l-warning");
|
|
43
|
+
expect(card.className).not.toContain("bg-warning");
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("keeps a destructive red accent for a delete approval (hard safety signal)", () => {
|
|
47
|
+
const approval = create(PendingApprovalSchema, {
|
|
48
|
+
toolCallId: "tc-chrome-del",
|
|
49
|
+
toolName: "delete_file",
|
|
50
|
+
argsPreview: '{"path":"/tmp/x"}',
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
render(<ApprovalCard pendingApproval={approval} onSubmit={noop} />);
|
|
54
|
+
|
|
55
|
+
const card = screen.getByRole("alert");
|
|
56
|
+
expect(card.className).toContain("border-l-destructive");
|
|
57
|
+
expect(card.className).not.toContain("bg-destructive-subtle");
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("shows a shell gate's command in the body terminal session, once, not in the header", () => {
|
|
61
|
+
// The command is decision-relevant, so it leads the body's terminal session
|
|
62
|
+
// (`$ npm test`) — but the header stays minimal and does not restate it, so
|
|
63
|
+
// the command appears exactly once on the card.
|
|
64
|
+
const approval = create(PendingApprovalSchema, {
|
|
65
|
+
toolCallId: "tc-shell-gate",
|
|
66
|
+
toolName: "shell",
|
|
67
|
+
toolKind: ToolKind.SHELL,
|
|
68
|
+
argsPreview: '{"command":"npm test"}',
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const { container } = render(
|
|
72
|
+
<ApprovalCard pendingApproval={approval} onSubmit={noop} />,
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const session = container.querySelector(
|
|
76
|
+
'[data-cursor-target="terminal-session"]',
|
|
77
|
+
);
|
|
78
|
+
expect(session).toBeTruthy();
|
|
79
|
+
expect(session!.textContent).toContain("$ npm test");
|
|
80
|
+
|
|
81
|
+
const occurrences = (container.textContent!.match(/npm test/g) ?? []).length;
|
|
82
|
+
expect(occurrences).toBe(1);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("states on a shell gate that the command's files are covered by the approval (DD-28)", () => {
|
|
86
|
+
// Consent at grant time: approving the command covers its file effects
|
|
87
|
+
// (the approved-command auto-keep), so the card says so up front — the user
|
|
88
|
+
// never discovers a second gate they weren't told about, nor gets one.
|
|
89
|
+
const shellApproval = create(PendingApprovalSchema, {
|
|
90
|
+
toolCallId: "tc-shell-note",
|
|
91
|
+
toolName: "shell",
|
|
92
|
+
toolKind: ToolKind.SHELL,
|
|
93
|
+
argsPreview: '{"command":"seq 1 5000 > big.txt"}',
|
|
94
|
+
});
|
|
95
|
+
render(<ApprovalCard pendingApproval={shellApproval} onSubmit={noop} />);
|
|
96
|
+
expect(screen.getByText(/kept automatically, with no second review/)).toBeTruthy();
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("never shows the auto-keep note on a non-shell gate", () => {
|
|
100
|
+
// A file edit's review model is the FileChangeSet, not the command consent —
|
|
101
|
+
// the note would be false there.
|
|
102
|
+
const editApproval = create(PendingApprovalSchema, {
|
|
103
|
+
toolCallId: "tc-edit-no-note",
|
|
104
|
+
toolName: "write_file",
|
|
105
|
+
toolKind: ToolKind.FILE_EDIT,
|
|
106
|
+
argsPreview: '{"path":"src/x.ts","contents":"x"}',
|
|
107
|
+
});
|
|
108
|
+
render(<ApprovalCard pendingApproval={editApproval} onSubmit={noop} />);
|
|
109
|
+
expect(screen.queryByText(/kept automatically/)).toBeNull();
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
describe("ApprovalCard quiet decision buttons", () => {
|
|
114
|
+
// Class-contract assertions (happy-dom can't resolve `@layer`); the RENDERED
|
|
115
|
+
// quiet treatment is proven by the e2e computed-style guard in
|
|
116
|
+
// tool-card-ux.spec.ts. The shared treatment itself lives in DecisionButton.
|
|
117
|
+
function renderGate() {
|
|
118
|
+
const approval = create(PendingApprovalSchema, {
|
|
119
|
+
toolCallId: "tc-quiet",
|
|
120
|
+
toolName: "write_file",
|
|
121
|
+
toolKind: ToolKind.FILE_EDIT,
|
|
122
|
+
argsPreview: '{"path":"src/x.ts","contents":"x"}',
|
|
123
|
+
});
|
|
124
|
+
return render(<ApprovalCard pendingApproval={approval} onSubmit={noop} />);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
it("Approve is the neutral chip, never the loud success green", () => {
|
|
128
|
+
renderGate();
|
|
129
|
+
const approve = screen.getByRole("button", { name: "Approve" });
|
|
130
|
+
expect(approve.className).toContain("bg-accent");
|
|
131
|
+
expect(approve.className).toContain("border");
|
|
132
|
+
expect(approve.className).not.toContain("bg-success");
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it("Skip and Reject are quiet ghosts with no resting fill", () => {
|
|
136
|
+
renderGate();
|
|
137
|
+
const skip = screen.getByRole("button", { name: "Skip" });
|
|
138
|
+
const reject = screen.getByRole("button", { name: "Reject" });
|
|
139
|
+
expect(skip.className).toContain("text-muted-foreground");
|
|
140
|
+
expect(skip.className).not.toMatch(/(?:^|\s)bg-/); // hover-only wash, no rest fill
|
|
141
|
+
// Reject reveals its danger affordance on hover/focus, not as a red fill.
|
|
142
|
+
expect(reject.className).toContain("hover:text-destructive");
|
|
143
|
+
expect(reject.className).not.toMatch(/(?:^|\s)bg-/);
|
|
144
|
+
expect(reject.className).not.toContain("bg-destructive text-destructive-foreground");
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("demotes Approve-all to the far right (ml-auto) at the lowest weight", () => {
|
|
148
|
+
renderGate();
|
|
149
|
+
const approveAll = screen.getByRole("button", { name: "Approve all file edits" });
|
|
150
|
+
expect(approveAll.className).toContain("ml-auto");
|
|
151
|
+
expect(approveAll.className).toContain("text-muted-foreground");
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it("uses no `bg-token/NN` opacity modifiers on any decision button", () => {
|
|
155
|
+
renderGate();
|
|
156
|
+
for (const name of ["Approve", "Skip", "Reject", "Approve all file edits"]) {
|
|
157
|
+
const btn = screen.getByRole("button", { name });
|
|
158
|
+
expect(btn.className).not.toMatch(/\/\d+(?:\s|$)/);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
13
163
|
describe("ApprovalCard tool classification", () => {
|
|
14
164
|
it("honors the denormalized wire tool_kind for a name not in the fallback map", () => {
|
|
15
165
|
// A future/unknown tool name that the name-based resolver cannot classify —
|
|
@@ -46,8 +196,110 @@ describe("ApprovalCard tool classification", () => {
|
|
|
46
196
|
});
|
|
47
197
|
});
|
|
48
198
|
|
|
199
|
+
describe("ApprovalCard why-gated provenance", () => {
|
|
200
|
+
it("renders the why-gated line from the projected approval_policy_source", () => {
|
|
201
|
+
// The server projects approval_policy_source onto PendingApproval so the card
|
|
202
|
+
// can explain the gate before any decision. AGENT_OVERRIDE → the agent forced
|
|
203
|
+
// this tool to require approval.
|
|
204
|
+
const approval = create(PendingApprovalSchema, {
|
|
205
|
+
toolCallId: "tc-why",
|
|
206
|
+
toolName: "delete_file",
|
|
207
|
+
argsPreview: '{"path":"/tmp/x"}',
|
|
208
|
+
approvalPolicySource: ApprovalPolicySource.AGENT_OVERRIDE,
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
const { getByText } = render(
|
|
212
|
+
<ApprovalCard pendingApproval={approval} onSubmit={noop} />,
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
expect(getByText("required by agent override")).toBeTruthy();
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it("renders no why-gated line for a legacy approval (UNSPECIFIED source)", () => {
|
|
219
|
+
const approval = create(PendingApprovalSchema, {
|
|
220
|
+
toolCallId: "tc-why-legacy",
|
|
221
|
+
toolName: "delete_file",
|
|
222
|
+
argsPreview: '{"path":"/tmp/x"}',
|
|
223
|
+
// approvalPolicySource left UNSPECIFIED — legacy execution.
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
const { queryByText } = render(
|
|
227
|
+
<ApprovalCard pendingApproval={approval} onSubmit={noop} />,
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
expect(queryByText(/required by/)).toBeNull();
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
it("smart-suppresses the everyday default gate reason (built-in tool policy)", () => {
|
|
234
|
+
// The boring default explains nothing the user does not already infer from
|
|
235
|
+
// the tool — it is noise, so the card hides it.
|
|
236
|
+
const approval = create(PendingApprovalSchema, {
|
|
237
|
+
toolCallId: "tc-why-default",
|
|
238
|
+
toolName: "delete_file",
|
|
239
|
+
argsPreview: '{"path":"/tmp/x"}',
|
|
240
|
+
approvalPolicySource: ApprovalPolicySource.BUILTIN_CATEGORY,
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
const { queryByText } = render(
|
|
244
|
+
<ApprovalCard pendingApproval={approval} onSubmit={noop} />,
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
expect(queryByText(/required by/)).toBeNull();
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
it("surfaces an informative gate reason (destructive tighten)", () => {
|
|
251
|
+
const approval = create(PendingApprovalSchema, {
|
|
252
|
+
toolCallId: "tc-why-destructive",
|
|
253
|
+
toolName: "delete_file",
|
|
254
|
+
argsPreview: '{"path":"/tmp/x"}',
|
|
255
|
+
approvalPolicySource: ApprovalPolicySource.ANNOTATION_DESTRUCTIVE_TIGHTEN,
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
const { getByText } = render(
|
|
259
|
+
<ApprovalCard pendingApproval={approval} onSubmit={noop} />,
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
expect(getByText("required: marked destructive by the server")).toBeTruthy();
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
describe("ApprovalCard message redundancy", () => {
|
|
267
|
+
it("suppresses a file tool's message that only restates the header", () => {
|
|
268
|
+
// "Write file: <path>" duplicates the header + diff — the card drops it.
|
|
269
|
+
const approval = create(PendingApprovalSchema, {
|
|
270
|
+
toolCallId: "tc-msg-file",
|
|
271
|
+
toolName: "write_file",
|
|
272
|
+
toolKind: ToolKind.FILE_EDIT,
|
|
273
|
+
message: "Write file: src/x.ts",
|
|
274
|
+
argsPreview: '{"path":"src/x.ts","contents":"x"}',
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
const { queryByText } = render(
|
|
278
|
+
<ApprovalCard pendingApproval={approval} onSubmit={noop} />,
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
expect(queryByText("Write file: src/x.ts")).toBeNull();
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
it("keeps a non-file tool's informative message (e.g. an MCP prompt)", () => {
|
|
285
|
+
const approval = create(PendingApprovalSchema, {
|
|
286
|
+
toolCallId: "tc-msg-mcp",
|
|
287
|
+
toolName: "create_issue",
|
|
288
|
+
mcpServerSlug: "github",
|
|
289
|
+
message: "Create an issue in acme/repo titled 'Bug'",
|
|
290
|
+
argsPreview: "{}",
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
const { getByText } = render(
|
|
294
|
+
<ApprovalCard pendingApproval={approval} onSubmit={noop} />,
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
expect(getByText("Create an issue in acme/repo titled 'Bug'")).toBeTruthy();
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
|
|
49
301
|
describe("ApprovalCard approve-all action", () => {
|
|
50
|
-
it("renders the subordinate
|
|
302
|
+
it("renders the subordinate scope-truthful approve-all action", () => {
|
|
51
303
|
const approval = create(PendingApprovalSchema, {
|
|
52
304
|
toolCallId: "tc3",
|
|
53
305
|
toolName: "delete_file",
|
|
@@ -59,7 +311,42 @@ describe("ApprovalCard approve-all action", () => {
|
|
|
59
311
|
);
|
|
60
312
|
|
|
61
313
|
expect(getByText("Approve")).toBeTruthy();
|
|
62
|
-
|
|
314
|
+
// The label names the leased class (delete), never an unbounded "all".
|
|
315
|
+
expect(getByLabelText("Approve all file deletions")).toBeTruthy();
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
it("labels the approve-all action by the clicked tool's lease scope", () => {
|
|
319
|
+
// delete -> "file deletions"; write/edit collapse to "file edits";
|
|
320
|
+
// shell -> "shell commands"; an MCP tool -> "<server> tools".
|
|
321
|
+
const cases: ReadonlyArray<{
|
|
322
|
+
toolName: string;
|
|
323
|
+
mcpServerSlug?: string;
|
|
324
|
+
expected: string;
|
|
325
|
+
}> = [
|
|
326
|
+
{ toolName: "delete_file", expected: "Approve all file deletions" },
|
|
327
|
+
{ toolName: "write_file", expected: "Approve all file edits" },
|
|
328
|
+
{ toolName: "edit_file", expected: "Approve all file edits" },
|
|
329
|
+
{ toolName: "shell", expected: "Approve all shell commands" },
|
|
330
|
+
{
|
|
331
|
+
toolName: "create_issue",
|
|
332
|
+
mcpServerSlug: "github",
|
|
333
|
+
expected: "Approve all github tools",
|
|
334
|
+
},
|
|
335
|
+
];
|
|
336
|
+
|
|
337
|
+
for (const { toolName, mcpServerSlug, expected } of cases) {
|
|
338
|
+
const approval = create(PendingApprovalSchema, {
|
|
339
|
+
toolCallId: `tc-${toolName}`,
|
|
340
|
+
toolName,
|
|
341
|
+
mcpServerSlug: mcpServerSlug ?? "",
|
|
342
|
+
argsPreview: "{}",
|
|
343
|
+
});
|
|
344
|
+
const { getByLabelText, unmount } = render(
|
|
345
|
+
<ApprovalCard pendingApproval={approval} onSubmit={noop} />,
|
|
346
|
+
);
|
|
347
|
+
expect(getByLabelText(expected)).toBeTruthy();
|
|
348
|
+
unmount();
|
|
349
|
+
}
|
|
63
350
|
});
|
|
64
351
|
|
|
65
352
|
it("submits APPROVE_ALL when the subordinate action is clicked", () => {
|
|
@@ -74,7 +361,7 @@ describe("ApprovalCard approve-all action", () => {
|
|
|
74
361
|
<ApprovalCard pendingApproval={approval} onSubmit={onSubmit} />,
|
|
75
362
|
);
|
|
76
363
|
|
|
77
|
-
fireEvent.click(getByLabelText("Approve
|
|
364
|
+
fireEvent.click(getByLabelText("Approve all file deletions"));
|
|
78
365
|
|
|
79
366
|
expect(onSubmit).toHaveBeenCalledTimes(1);
|
|
80
367
|
expect(onSubmit).toHaveBeenCalledWith(ApprovalAction.APPROVE_ALL);
|
|
@@ -97,3 +384,106 @@ describe("ApprovalCard approve-all action", () => {
|
|
|
97
384
|
expect(onSubmit).toHaveBeenCalledWith(ApprovalAction.APPROVE);
|
|
98
385
|
});
|
|
99
386
|
});
|
|
387
|
+
|
|
388
|
+
// ---------------------------------------------------------------------------
|
|
389
|
+
// Deny-gate preview from tool args (apply-then-review: no captured file_changes)
|
|
390
|
+
// ---------------------------------------------------------------------------
|
|
391
|
+
|
|
392
|
+
describe("ApprovalCard file-change preview", () => {
|
|
393
|
+
it("shows the proposed content (filename only in the header) when the args carry content", () => {
|
|
394
|
+
const approval = create(PendingApprovalSchema, {
|
|
395
|
+
toolCallId: "tc-fallback",
|
|
396
|
+
toolName: "write_file",
|
|
397
|
+
toolKind: ToolKind.FILE_EDIT,
|
|
398
|
+
argsPreview: '{"path":"src/fallback.ts","contents":"x"}',
|
|
399
|
+
// fileChanges intentionally empty.
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
render(<ApprovalCard pendingApproval={approval} onSubmit={noop} />);
|
|
403
|
+
|
|
404
|
+
// The write content still shows via the "Content" collapsible...
|
|
405
|
+
expect(screen.getByText("Content")).toBeTruthy();
|
|
406
|
+
// ...but the filename is shown exactly once (the header) — the body no
|
|
407
|
+
// longer restates the path the header already shows.
|
|
408
|
+
expect(screen.getAllByText("fallback.ts")).toHaveLength(1);
|
|
409
|
+
expect(screen.queryByText(/binary file changed/i)).toBeNull();
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
it("shows a neutral 'no preview' notice for a path-only edit gate (the resume placeholder)", () => {
|
|
413
|
+
// The irreducible case: a ledger denial whose only known arg is the path
|
|
414
|
+
// (no streamed content, no capture). The body must not restate the bare
|
|
415
|
+
// filename nor misrepresent it as an empty file.
|
|
416
|
+
const approval = create(PendingApprovalSchema, {
|
|
417
|
+
toolCallId: "tc-no-preview",
|
|
418
|
+
toolName: "edit_file",
|
|
419
|
+
toolKind: ToolKind.FILE_EDIT,
|
|
420
|
+
argsPreview: '{"path":"notes.md"}',
|
|
421
|
+
// fileChanges intentionally empty; no content in args.
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
render(<ApprovalCard pendingApproval={approval} onSubmit={noop} />);
|
|
425
|
+
|
|
426
|
+
expect(screen.getByText("No preview available for this change")).toBeTruthy();
|
|
427
|
+
// Filename once — header only.
|
|
428
|
+
expect(screen.getAllByText("notes.md")).toHaveLength(1);
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
it("shows a 'new file' notice (not 'no preview') for a content-less FILE_WRITE create gate", () => {
|
|
432
|
+
// The rare residual after the runner's correlation fix: a whole-file write
|
|
433
|
+
// gate that carries only its path (no captured content/diff — a no-stream
|
|
434
|
+
// synthesis). FILE_WRITE is modeled as a create throughout the runner, so the
|
|
435
|
+
// authoritative toolKind lets the gate say plainly that a new file is being
|
|
436
|
+
// written rather than the misleading non-committal "No preview available".
|
|
437
|
+
const approval = create(PendingApprovalSchema, {
|
|
438
|
+
toolCallId: "tc-new-file",
|
|
439
|
+
toolName: "write_file",
|
|
440
|
+
toolKind: ToolKind.FILE_WRITE,
|
|
441
|
+
argsPreview: '{"path":"notes.md"}',
|
|
442
|
+
// fileChanges intentionally empty; no content in args.
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
render(<ApprovalCard pendingApproval={approval} onSubmit={noop} />);
|
|
446
|
+
|
|
447
|
+
expect(screen.getByText("New file — preview unavailable")).toBeTruthy();
|
|
448
|
+
expect(screen.queryByText("No preview available for this change")).toBeNull();
|
|
449
|
+
// Filename once — header only.
|
|
450
|
+
expect(screen.getAllByText("notes.md")).toHaveLength(1);
|
|
451
|
+
});
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
describe("ApprovalCard in-card decision error", () => {
|
|
455
|
+
function makeApproval() {
|
|
456
|
+
return create(PendingApprovalSchema, {
|
|
457
|
+
toolCallId: "tc-err",
|
|
458
|
+
toolName: "delete_file",
|
|
459
|
+
argsPreview: '{"path":"/tmp/x"}',
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
it("surfaces a failed decision in-card, beside the actions (not via a banner)", () => {
|
|
464
|
+
const { container } = render(
|
|
465
|
+
<ApprovalCard
|
|
466
|
+
pendingApproval={makeApproval()}
|
|
467
|
+
onSubmit={noop}
|
|
468
|
+
error={new Error("gate already resolved")}
|
|
469
|
+
/>,
|
|
470
|
+
);
|
|
471
|
+
|
|
472
|
+
const alert = container.querySelector(
|
|
473
|
+
'[data-cursor-target="approval-error"]',
|
|
474
|
+
);
|
|
475
|
+
expect(alert).toBeTruthy();
|
|
476
|
+
expect(alert!.textContent).toContain("gate already resolved");
|
|
477
|
+
// The shared notice announces itself.
|
|
478
|
+
expect(alert!.getAttribute("role")).toBe("alert");
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
it("shows no in-card error when healthy", () => {
|
|
482
|
+
const { container } = render(
|
|
483
|
+
<ApprovalCard pendingApproval={makeApproval()} onSubmit={noop} />,
|
|
484
|
+
);
|
|
485
|
+
expect(
|
|
486
|
+
container.querySelector('[data-cursor-target="approval-error"]'),
|
|
487
|
+
).toBeNull();
|
|
488
|
+
});
|
|
489
|
+
});
|
|
@@ -15,7 +15,6 @@ const binaryArtifact = create(ExecutionArtifactSchema, {
|
|
|
15
15
|
kind: ExecutionArtifactKind.FILE,
|
|
16
16
|
sizeBytes: 128n,
|
|
17
17
|
storageKey: "artifacts/aex_1/report.bin",
|
|
18
|
-
downloadUrl: "https://example.test/report.bin",
|
|
19
18
|
});
|
|
20
19
|
|
|
21
20
|
function withStigmer(children: ReactNode) {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, it, expect, afterEach } from "vitest";
|
|
2
|
+
import { render, screen, cleanup } from "@testing-library/react";
|
|
3
|
+
import { EmptyChangeNotice } from "../EmptyChangeNotice";
|
|
4
|
+
|
|
5
|
+
afterEach(cleanup);
|
|
6
|
+
|
|
7
|
+
// The notice is the single owner of both empty-state messages so the approval
|
|
8
|
+
// gate and the post-execution detail can never drift apart in wording.
|
|
9
|
+
describe("EmptyChangeNotice", () => {
|
|
10
|
+
it("renders the truthful 'new empty file' message for a proven-empty create", () => {
|
|
11
|
+
render(<EmptyChangeNotice kind="empty-create" />);
|
|
12
|
+
expect(screen.getByText("New empty file")).toBeTruthy();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("renders the non-committal 'no preview' message when content is unavailable", () => {
|
|
16
|
+
render(<EmptyChangeNotice kind="no-preview" />);
|
|
17
|
+
expect(screen.getByText("No preview available for this change")).toBeTruthy();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("renders a 'new file' message for a create whose content could not be captured", () => {
|
|
21
|
+
render(<EmptyChangeNotice kind="create" />);
|
|
22
|
+
expect(screen.getByText("New file — preview unavailable")).toBeTruthy();
|
|
23
|
+
});
|
|
24
|
+
});
|