@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.
Files changed (426) hide show
  1. package/execution/ApprovalCard.d.ts +47 -3
  2. package/execution/ApprovalCard.d.ts.map +1 -1
  3. package/execution/ApprovalCard.js +138 -70
  4. package/execution/ApprovalCard.js.map +1 -1
  5. package/execution/ApprovalContext.d.ts +72 -0
  6. package/execution/ApprovalContext.d.ts.map +1 -0
  7. package/execution/ApprovalContext.js +41 -0
  8. package/execution/ApprovalContext.js.map +1 -0
  9. package/execution/ArtifactCard.d.ts.map +1 -1
  10. package/execution/ArtifactCard.js +3 -1
  11. package/execution/ArtifactCard.js.map +1 -1
  12. package/execution/ArtifactPreviewModal.d.ts.map +1 -1
  13. package/execution/ArtifactPreviewModal.js +5 -3
  14. package/execution/ArtifactPreviewModal.js.map +1 -1
  15. package/execution/EmptyChangeNotice.d.ts +38 -0
  16. package/execution/EmptyChangeNotice.d.ts.map +1 -0
  17. package/execution/EmptyChangeNotice.js +27 -0
  18. package/execution/EmptyChangeNotice.js.map +1 -0
  19. package/execution/FileChangesView.d.ts +81 -0
  20. package/execution/FileChangesView.d.ts.map +1 -0
  21. package/execution/FileChangesView.js +164 -0
  22. package/execution/FileChangesView.js.map +1 -0
  23. package/execution/FilePathLink.d.ts +24 -4
  24. package/execution/FilePathLink.d.ts.map +1 -1
  25. package/execution/FilePathLink.js +31 -9
  26. package/execution/FilePathLink.js.map +1 -1
  27. package/execution/FileReviewCard.d.ts +111 -0
  28. package/execution/FileReviewCard.d.ts.map +1 -0
  29. package/execution/FileReviewCard.js +558 -0
  30. package/execution/FileReviewCard.js.map +1 -0
  31. package/execution/FileReviewContext.d.ts +35 -0
  32. package/execution/FileReviewContext.d.ts.map +1 -0
  33. package/execution/FileReviewContext.js +23 -0
  34. package/execution/FileReviewContext.js.map +1 -0
  35. package/execution/FileReviewDock.d.ts +73 -0
  36. package/execution/FileReviewDock.d.ts.map +1 -0
  37. package/execution/FileReviewDock.js +65 -0
  38. package/execution/FileReviewDock.js.map +1 -0
  39. package/execution/McpToolDetail.d.ts.map +1 -1
  40. package/execution/McpToolDetail.js +38 -5
  41. package/execution/McpToolDetail.js.map +1 -1
  42. package/execution/MessageThread.d.ts +42 -3
  43. package/execution/MessageThread.d.ts.map +1 -1
  44. package/execution/MessageThread.js +263 -18
  45. package/execution/MessageThread.js.map +1 -1
  46. package/execution/PlanArtifactCard.d.ts.map +1 -1
  47. package/execution/PlanArtifactCard.js +3 -1
  48. package/execution/PlanArtifactCard.js.map +1 -1
  49. package/execution/PlanCompletionCard.d.ts +1 -1
  50. package/execution/PlanCompletionCard.js +1 -1
  51. package/execution/ResultView.d.ts +19 -1
  52. package/execution/ResultView.d.ts.map +1 -1
  53. package/execution/ResultView.js +141 -40
  54. package/execution/ResultView.js.map +1 -1
  55. package/execution/SubAgentSection.d.ts.map +1 -1
  56. package/execution/SubAgentSection.js +45 -6
  57. package/execution/SubAgentSection.js.map +1 -1
  58. package/execution/TerminalSession.d.ts +34 -0
  59. package/execution/TerminalSession.d.ts.map +1 -0
  60. package/execution/TerminalSession.js +34 -0
  61. package/execution/TerminalSession.js.map +1 -0
  62. package/execution/TodoCard.d.ts +53 -0
  63. package/execution/TodoCard.d.ts.map +1 -0
  64. package/execution/TodoCard.js +77 -0
  65. package/execution/TodoCard.js.map +1 -0
  66. package/execution/ToolArgsView.d.ts +7 -1
  67. package/execution/ToolArgsView.d.ts.map +1 -1
  68. package/execution/ToolArgsView.js +10 -9
  69. package/execution/ToolArgsView.js.map +1 -1
  70. package/execution/ToolCallDetail.d.ts +10 -1
  71. package/execution/ToolCallDetail.d.ts.map +1 -1
  72. package/execution/ToolCallDetail.js +66 -19
  73. package/execution/ToolCallDetail.js.map +1 -1
  74. package/execution/ToolCallGroup.d.ts +28 -18
  75. package/execution/ToolCallGroup.d.ts.map +1 -1
  76. package/execution/ToolCallGroup.js +39 -148
  77. package/execution/ToolCallGroup.js.map +1 -1
  78. package/execution/ToolCallItem.d.ts +36 -8
  79. package/execution/ToolCallItem.d.ts.map +1 -1
  80. package/execution/ToolCallItem.js +140 -21
  81. package/execution/ToolCallItem.js.map +1 -1
  82. package/execution/ToolRunGroup.d.ts +48 -0
  83. package/execution/ToolRunGroup.d.ts.map +1 -0
  84. package/execution/ToolRunGroup.js +168 -0
  85. package/execution/ToolRunGroup.js.map +1 -0
  86. package/execution/approval-provenance.d.ts +2 -0
  87. package/execution/approval-provenance.d.ts.map +1 -0
  88. package/execution/approval-provenance.js +6 -0
  89. package/execution/approval-provenance.js.map +1 -0
  90. package/execution/artifact-utils.d.ts +0 -10
  91. package/execution/artifact-utils.d.ts.map +1 -1
  92. package/execution/artifact-utils.js +0 -17
  93. package/execution/artifact-utils.js.map +1 -1
  94. package/execution/execution-phases.d.ts +1 -6
  95. package/execution/execution-phases.d.ts.map +1 -1
  96. package/execution/execution-phases.js +4 -14
  97. package/execution/execution-phases.js.map +1 -1
  98. package/execution/file-path-resolver.d.ts +28 -0
  99. package/execution/file-path-resolver.d.ts.map +1 -1
  100. package/execution/file-path-resolver.js +24 -0
  101. package/execution/file-path-resolver.js.map +1 -1
  102. package/execution/file-review-status.d.ts +127 -0
  103. package/execution/file-review-status.d.ts.map +1 -0
  104. package/execution/file-review-status.js +135 -0
  105. package/execution/file-review-status.js.map +1 -0
  106. package/execution/index.d.ts +39 -5
  107. package/execution/index.d.ts.map +1 -1
  108. package/execution/index.js +23 -3
  109. package/execution/index.js.map +1 -1
  110. package/execution/segment-tool-calls.d.ts +46 -0
  111. package/execution/segment-tool-calls.d.ts.map +1 -0
  112. package/execution/segment-tool-calls.js +71 -0
  113. package/execution/segment-tool-calls.js.map +1 -0
  114. package/execution/tool-categories.d.ts +62 -1
  115. package/execution/tool-categories.d.ts.map +1 -1
  116. package/execution/tool-categories.js +96 -2
  117. package/execution/tool-categories.js.map +1 -1
  118. package/execution/tool-presenter.d.ts +38 -2
  119. package/execution/tool-presenter.d.ts.map +1 -1
  120. package/execution/tool-presenter.js +23 -1
  121. package/execution/tool-presenter.js.map +1 -1
  122. package/execution/tool-rendering-primitives.d.ts.map +1 -1
  123. package/execution/tool-rendering-primitives.js +3 -2
  124. package/execution/tool-rendering-primitives.js.map +1 -1
  125. package/execution/useArtifactDownload.d.ts +44 -0
  126. package/execution/useArtifactDownload.d.ts.map +1 -0
  127. package/execution/useArtifactDownload.js +80 -0
  128. package/execution/useArtifactDownload.js.map +1 -0
  129. package/execution/useArtifactDownloadUrl.d.ts +67 -0
  130. package/execution/useArtifactDownloadUrl.d.ts.map +1 -0
  131. package/execution/useArtifactDownloadUrl.js +59 -0
  132. package/execution/useArtifactDownloadUrl.js.map +1 -0
  133. package/execution/useFileChangeContent.d.ts +61 -0
  134. package/execution/useFileChangeContent.d.ts.map +1 -0
  135. package/execution/useFileChangeContent.js +89 -0
  136. package/execution/useFileChangeContent.js.map +1 -0
  137. package/execution/useFileReview.d.ts +89 -0
  138. package/execution/useFileReview.d.ts.map +1 -0
  139. package/execution/useFileReview.js +106 -0
  140. package/execution/useFileReview.js.map +1 -0
  141. package/execution/useSubmitApproval.d.ts +17 -2
  142. package/execution/useSubmitApproval.d.ts.map +1 -1
  143. package/execution/useSubmitApproval.js +27 -23
  144. package/execution/useSubmitApproval.js.map +1 -1
  145. package/execution/useToolOutputContent.d.ts +44 -0
  146. package/execution/useToolOutputContent.d.ts.map +1 -0
  147. package/execution/useToolOutputContent.js +31 -0
  148. package/execution/useToolOutputContent.js.map +1 -0
  149. package/index.d.ts +6 -6
  150. package/index.d.ts.map +1 -1
  151. package/index.js +3 -3
  152. package/index.js.map +1 -1
  153. package/internal/ApprovalPeekBar.d.ts +23 -0
  154. package/internal/ApprovalPeekBar.d.ts.map +1 -0
  155. package/internal/ApprovalPeekBar.js +25 -0
  156. package/internal/ApprovalPeekBar.js.map +1 -0
  157. package/internal/BoundedContent.d.ts +49 -0
  158. package/internal/BoundedContent.d.ts.map +1 -0
  159. package/internal/BoundedContent.js +50 -0
  160. package/internal/BoundedContent.js.map +1 -0
  161. package/internal/DecisionButton.d.ts +47 -0
  162. package/internal/DecisionButton.d.ts.map +1 -0
  163. package/internal/DecisionButton.js +42 -0
  164. package/internal/DecisionButton.js.map +1 -0
  165. package/internal/InCardDecisionError.d.ts +31 -0
  166. package/internal/InCardDecisionError.d.ts.map +1 -0
  167. package/internal/InCardDecisionError.js +23 -0
  168. package/internal/InCardDecisionError.js.map +1 -0
  169. package/internal/RevealToggle.d.ts +36 -0
  170. package/internal/RevealToggle.d.ts.map +1 -0
  171. package/internal/RevealToggle.js +32 -0
  172. package/internal/RevealToggle.js.map +1 -0
  173. package/internal/VirtualizedThread.d.ts +7 -1
  174. package/internal/VirtualizedThread.d.ts.map +1 -1
  175. package/internal/VirtualizedThread.js +7 -3
  176. package/internal/VirtualizedThread.js.map +1 -1
  177. package/internal/useAutoDisclosure.d.ts +34 -0
  178. package/internal/useAutoDisclosure.d.ts.map +1 -0
  179. package/internal/useAutoDisclosure.js +53 -0
  180. package/internal/useAutoDisclosure.js.map +1 -0
  181. package/internal/useElapsedSince.d.ts +30 -0
  182. package/internal/useElapsedSince.d.ts.map +1 -0
  183. package/internal/useElapsedSince.js +70 -0
  184. package/internal/useElapsedSince.js.map +1 -0
  185. package/internal/useIsOverflowing.d.ts +30 -0
  186. package/internal/useIsOverflowing.d.ts.map +1 -0
  187. package/internal/useIsOverflowing.js +47 -0
  188. package/internal/useIsOverflowing.js.map +1 -0
  189. package/internal/useIsTextTruncated.d.ts +24 -0
  190. package/internal/useIsTextTruncated.d.ts.map +1 -0
  191. package/internal/useIsTextTruncated.js +41 -0
  192. package/internal/useIsTextTruncated.js.map +1 -0
  193. package/internal/useKeyedSubmission.d.ts +49 -0
  194. package/internal/useKeyedSubmission.d.ts.map +1 -0
  195. package/internal/useKeyedSubmission.js +67 -0
  196. package/internal/useKeyedSubmission.js.map +1 -0
  197. package/package.json +4 -4
  198. package/session/SessionViewer.d.ts +2 -2
  199. package/session/SessionViewer.d.ts.map +1 -1
  200. package/session/SessionViewer.js +10 -4
  201. package/session/SessionViewer.js.map +1 -1
  202. package/session/index.d.ts +2 -0
  203. package/session/index.d.ts.map +1 -1
  204. package/session/index.js +1 -0
  205. package/session/index.js.map +1 -1
  206. package/session/inspector/ChangesTab.d.ts +8 -5
  207. package/session/inspector/ChangesTab.d.ts.map +1 -1
  208. package/session/inspector/ChangesTab.js +11 -8
  209. package/session/inspector/ChangesTab.js.map +1 -1
  210. package/session/inspector/SessionInspector.d.ts +4 -4
  211. package/session/inspector/SessionInspector.d.ts.map +1 -1
  212. package/session/inspector/SessionInspector.js +4 -4
  213. package/session/inspector/SessionInspector.js.map +1 -1
  214. package/session/inspector/index.d.ts +0 -2
  215. package/session/inspector/index.d.ts.map +1 -1
  216. package/session/inspector/index.js +0 -1
  217. package/session/inspector/index.js.map +1 -1
  218. package/session/inspector/useSessionInspector.d.ts +8 -4
  219. package/session/inspector/useSessionInspector.d.ts.map +1 -1
  220. package/session/inspector/useSessionInspector.js +27 -20
  221. package/session/inspector/useSessionInspector.js.map +1 -1
  222. package/session/useSessionConversation.d.ts +37 -3
  223. package/session/useSessionConversation.d.ts.map +1 -1
  224. package/session/useSessionConversation.js +18 -2
  225. package/session/useSessionConversation.js.map +1 -1
  226. package/session/useSessionFileChanges.d.ts +74 -0
  227. package/session/useSessionFileChanges.d.ts.map +1 -0
  228. package/session/useSessionFileChanges.js +178 -0
  229. package/session/useSessionFileChanges.js.map +1 -0
  230. package/src/__tests__/styles-border-layer-invariant.test.ts +105 -0
  231. package/src/execution/ApprovalCard.tsx +368 -230
  232. package/src/execution/ApprovalContext.ts +109 -0
  233. package/src/execution/ArtifactCard.tsx +10 -6
  234. package/src/execution/ArtifactPreviewModal.tsx +12 -6
  235. package/src/execution/EmptyChangeNotice.tsx +62 -0
  236. package/src/execution/FileChangesView.tsx +383 -0
  237. package/src/execution/FilePathLink.tsx +65 -12
  238. package/src/execution/FileReviewCard.tsx +1118 -0
  239. package/src/execution/FileReviewContext.ts +53 -0
  240. package/src/execution/FileReviewDock.tsx +157 -0
  241. package/src/execution/McpToolDetail.tsx +98 -32
  242. package/src/execution/MessageThread.tsx +374 -9
  243. package/src/execution/PlanArtifactCard.tsx +9 -6
  244. package/src/execution/PlanCompletionCard.tsx +1 -1
  245. package/src/execution/ResultView.tsx +333 -162
  246. package/src/execution/SubAgentSection.tsx +58 -11
  247. package/src/execution/TerminalSession.tsx +91 -0
  248. package/src/execution/TodoCard.tsx +186 -0
  249. package/src/execution/ToolArgsView.tsx +28 -17
  250. package/src/execution/ToolCallDetail.tsx +137 -26
  251. package/src/execution/ToolCallGroup.tsx +68 -296
  252. package/src/execution/ToolCallItem.tsx +265 -67
  253. package/src/execution/ToolRunGroup.tsx +302 -0
  254. package/src/execution/__tests__/ApprovalCard.test.tsx +395 -5
  255. package/src/execution/__tests__/ArtifactPreviewModal.test.tsx +0 -1
  256. package/src/execution/__tests__/EmptyChangeNotice.test.tsx +24 -0
  257. package/src/execution/__tests__/FileChangesView.test.tsx +296 -0
  258. package/src/execution/__tests__/FilePathLink.test.tsx +92 -0
  259. package/src/execution/__tests__/FileReviewCard.test.tsx +1044 -0
  260. package/src/execution/__tests__/FileReviewDock.test.tsx +134 -0
  261. package/src/execution/__tests__/McpToolDetail.test.tsx +79 -0
  262. package/src/execution/__tests__/MessageThread.test.tsx +324 -0
  263. package/src/execution/__tests__/PlanArtifactCard.test.tsx +37 -16
  264. package/src/execution/__tests__/ResultView.test.tsx +280 -2
  265. package/src/execution/__tests__/SubAgentSection.test.tsx +180 -0
  266. package/src/execution/__tests__/TerminalSession.test.tsx +72 -0
  267. package/src/execution/__tests__/TodoCard.test.tsx +102 -0
  268. package/src/execution/__tests__/ToolArgsView.test.tsx +48 -0
  269. package/src/execution/__tests__/ToolCallDetail.test.tsx +195 -0
  270. package/src/execution/__tests__/ToolCallGroup.test.tsx +132 -0
  271. package/src/execution/__tests__/ToolCallItem.test.tsx +521 -0
  272. package/src/execution/__tests__/ToolRunGroup.test.tsx +137 -0
  273. package/src/execution/__tests__/blanked-narration.test.tsx +149 -0
  274. package/src/execution/__tests__/buildThreadItems-approvals.test.ts +304 -0
  275. package/src/execution/__tests__/buildThreadItems-file-review.test.ts +331 -0
  276. package/src/execution/__tests__/file-path-resolver.test.ts +44 -0
  277. package/src/execution/__tests__/file-review-status.test.ts +343 -0
  278. package/src/execution/__tests__/segment-tool-calls.test.ts +124 -0
  279. package/src/execution/__tests__/subagent-file-review-badge.test.tsx +273 -0
  280. package/src/execution/__tests__/thread-keys.test.ts +195 -0
  281. package/src/execution/__tests__/tool-presenter.test.tsx +95 -0
  282. package/src/execution/__tests__/useArtifactDownload.test.tsx +67 -0
  283. package/src/execution/__tests__/useArtifactDownloadUrl.test.tsx +51 -0
  284. package/src/execution/__tests__/useFileChangeContent.test.tsx +240 -0
  285. package/src/execution/__tests__/useFileReview.test.tsx +236 -0
  286. package/src/execution/__tests__/useSubmitApproval.test.tsx +165 -0
  287. package/src/execution/__tests__/useToolOutputContent.test.tsx +82 -0
  288. package/src/execution/approval-provenance.ts +8 -0
  289. package/src/execution/artifact-utils.ts +0 -18
  290. package/src/execution/execution-phases.ts +4 -16
  291. package/src/execution/file-path-resolver.ts +38 -0
  292. package/src/execution/file-review-status.ts +219 -0
  293. package/src/execution/index.ts +84 -4
  294. package/src/execution/segment-tool-calls.ts +101 -0
  295. package/src/execution/tool-categories.ts +128 -1
  296. package/src/execution/tool-presenter.ts +58 -3
  297. package/src/execution/tool-rendering-primitives.tsx +11 -14
  298. package/src/execution/useArtifactDownload.ts +109 -0
  299. package/src/execution/useArtifactDownloadUrl.ts +116 -0
  300. package/src/execution/useFileChangeContent.ts +149 -0
  301. package/src/execution/useFileReview.ts +197 -0
  302. package/src/execution/useSubmitApproval.ts +49 -27
  303. package/src/execution/useToolOutputContent.ts +70 -0
  304. package/src/index.ts +60 -1
  305. package/src/internal/ApprovalPeekBar.tsx +73 -0
  306. package/src/internal/BoundedContent.tsx +97 -0
  307. package/src/internal/DecisionButton.tsx +127 -0
  308. package/src/internal/InCardDecisionError.tsx +47 -0
  309. package/src/internal/RevealToggle.tsx +91 -0
  310. package/src/internal/VirtualizedThread.tsx +28 -2
  311. package/src/internal/__tests__/ApprovalPeekBar.test.tsx +34 -0
  312. package/src/internal/__tests__/BoundedContent.test.tsx +92 -0
  313. package/src/internal/__tests__/DecisionButton.test.tsx +107 -0
  314. package/src/internal/__tests__/RevealToggle.test.tsx +61 -0
  315. package/src/internal/__tests__/useAutoDisclosure.test.ts +74 -0
  316. package/src/internal/__tests__/useElapsedSince.test.tsx +68 -0
  317. package/src/internal/__tests__/useIsOverflowing.test.ts +36 -0
  318. package/src/internal/__tests__/useKeyedSubmission.test.tsx +126 -0
  319. package/src/internal/useAutoDisclosure.ts +58 -0
  320. package/src/internal/useElapsedSince.ts +72 -0
  321. package/src/internal/useIsOverflowing.ts +61 -0
  322. package/src/internal/useIsTextTruncated.ts +55 -0
  323. package/src/internal/useKeyedSubmission.ts +101 -0
  324. package/src/session/SessionViewer.tsx +21 -4
  325. package/src/session/__tests__/SessionViewer-fileReviewDock.test.tsx +198 -0
  326. package/src/session/__tests__/audienceWiring.test.tsx +4 -0
  327. package/src/session/__tests__/useSessionFileChanges.test.ts +303 -0
  328. package/src/session/index.ts +3 -0
  329. package/src/session/inspector/ChangesTab.tsx +20 -17
  330. package/src/session/inspector/SessionInspector.tsx +12 -10
  331. package/src/session/inspector/__tests__/ArtifactsTab.test.tsx +0 -1
  332. package/src/session/inspector/__tests__/ChangesTab.test.tsx +38 -0
  333. package/src/session/inspector/__tests__/useSessionInspector.test.ts +46 -61
  334. package/src/session/inspector/index.ts +0 -3
  335. package/src/session/inspector/useSessionInspector.ts +27 -20
  336. package/src/session/useSessionConversation.ts +80 -3
  337. package/src/session/useSessionFileChanges.ts +207 -0
  338. package/src/styles.css +35 -10
  339. package/src/version-history/DiffViewer.tsx +10 -7
  340. package/src/version-history/UnifiedDiffView.tsx +66 -0
  341. package/src/version-history/__tests__/DiffViewer.test.tsx +57 -0
  342. package/src/version-history/__tests__/UnifiedDiffView.test.tsx +50 -0
  343. package/src/version-history/__tests__/computeDiff.test.ts +35 -0
  344. package/src/version-history/__tests__/parseUnifiedDiff.test.ts +82 -0
  345. package/src/version-history/computeDiff.ts +6 -37
  346. package/src/version-history/diff-hunks.ts +63 -0
  347. package/src/version-history/index.ts +1 -0
  348. package/src/version-history/parseUnifiedDiff.ts +34 -0
  349. package/src/workflow/WorkflowExecutionApprovalCard.tsx +49 -24
  350. package/src/workflow/WorkflowExecutionTimeline.tsx +15 -4
  351. package/src/workflow/WorkflowExecutionTimelineEvent.tsx +8 -3
  352. package/src/workflow/WorkflowExecutionViewer.tsx +72 -28
  353. package/src/workflow/WorkflowFileReviewList.tsx +152 -0
  354. package/src/workflow/WorkflowTaskApprovalCard.tsx +37 -85
  355. package/src/workflow/__tests__/ExecutionInspector.test.tsx +30 -2
  356. package/src/workflow/__tests__/WorkflowExecutionApprovalCard.test.tsx +129 -0
  357. package/src/workflow/__tests__/WorkflowFileReviewList.test.tsx +129 -0
  358. package/src/workflow/__tests__/WorkflowTaskApprovalCard.test.tsx +43 -11
  359. package/src/workflow/__tests__/useWorkflowExecutionActions.test.tsx +276 -0
  360. package/src/workflow/execution-inspector/ExecutionInspector.tsx +42 -18
  361. package/src/workflow/index.ts +5 -0
  362. package/src/workflow/useWorkflowExecutionActions.ts +177 -29
  363. package/styles.css +1 -1
  364. package/version-history/DiffViewer.d.ts.map +1 -1
  365. package/version-history/DiffViewer.js +9 -3
  366. package/version-history/DiffViewer.js.map +1 -1
  367. package/version-history/UnifiedDiffView.d.ts +29 -0
  368. package/version-history/UnifiedDiffView.d.ts.map +1 -0
  369. package/version-history/UnifiedDiffView.js +36 -0
  370. package/version-history/UnifiedDiffView.js.map +1 -0
  371. package/version-history/computeDiff.d.ts +3 -1
  372. package/version-history/computeDiff.d.ts.map +1 -1
  373. package/version-history/computeDiff.js +5 -35
  374. package/version-history/computeDiff.js.map +1 -1
  375. package/version-history/diff-hunks.d.ts +21 -0
  376. package/version-history/diff-hunks.d.ts.map +1 -0
  377. package/version-history/diff-hunks.js +58 -0
  378. package/version-history/diff-hunks.js.map +1 -0
  379. package/version-history/index.d.ts +1 -0
  380. package/version-history/index.d.ts.map +1 -1
  381. package/version-history/index.js +1 -0
  382. package/version-history/index.js.map +1 -1
  383. package/version-history/parseUnifiedDiff.d.ts +22 -0
  384. package/version-history/parseUnifiedDiff.d.ts.map +1 -0
  385. package/version-history/parseUnifiedDiff.js +34 -0
  386. package/version-history/parseUnifiedDiff.js.map +1 -0
  387. package/workflow/WorkflowExecutionApprovalCard.d.ts +8 -1
  388. package/workflow/WorkflowExecutionApprovalCard.d.ts.map +1 -1
  389. package/workflow/WorkflowExecutionApprovalCard.js +17 -3
  390. package/workflow/WorkflowExecutionApprovalCard.js.map +1 -1
  391. package/workflow/WorkflowExecutionTimeline.d.ts +11 -2
  392. package/workflow/WorkflowExecutionTimeline.d.ts.map +1 -1
  393. package/workflow/WorkflowExecutionTimeline.js +2 -2
  394. package/workflow/WorkflowExecutionTimeline.js.map +1 -1
  395. package/workflow/WorkflowExecutionTimelineEvent.d.ts +4 -1
  396. package/workflow/WorkflowExecutionTimelineEvent.d.ts.map +1 -1
  397. package/workflow/WorkflowExecutionTimelineEvent.js +2 -2
  398. package/workflow/WorkflowExecutionTimelineEvent.js.map +1 -1
  399. package/workflow/WorkflowExecutionViewer.d.ts.map +1 -1
  400. package/workflow/WorkflowExecutionViewer.js +18 -10
  401. package/workflow/WorkflowExecutionViewer.js.map +1 -1
  402. package/workflow/WorkflowFileReviewList.d.ts +46 -0
  403. package/workflow/WorkflowFileReviewList.d.ts.map +1 -0
  404. package/workflow/WorkflowFileReviewList.js +48 -0
  405. package/workflow/WorkflowFileReviewList.js.map +1 -0
  406. package/workflow/WorkflowTaskApprovalCard.d.ts +8 -1
  407. package/workflow/WorkflowTaskApprovalCard.d.ts.map +1 -1
  408. package/workflow/WorkflowTaskApprovalCard.js +12 -19
  409. package/workflow/WorkflowTaskApprovalCard.js.map +1 -1
  410. package/workflow/execution-inspector/ExecutionInspector.d.ts +21 -4
  411. package/workflow/execution-inspector/ExecutionInspector.d.ts.map +1 -1
  412. package/workflow/execution-inspector/ExecutionInspector.js +6 -3
  413. package/workflow/execution-inspector/ExecutionInspector.js.map +1 -1
  414. package/workflow/index.d.ts +1 -0
  415. package/workflow/index.d.ts.map +1 -1
  416. package/workflow/index.js +1 -0
  417. package/workflow/index.js.map +1 -1
  418. package/workflow/useWorkflowExecutionActions.d.ts +62 -4
  419. package/workflow/useWorkflowExecutionActions.d.ts.map +1 -1
  420. package/workflow/useWorkflowExecutionActions.js +94 -18
  421. package/workflow/useWorkflowExecutionActions.js.map +1 -1
  422. package/session/inspector/PlanTab.d.ts +0 -15
  423. package/session/inspector/PlanTab.d.ts.map +0 -1
  424. package/session/inspector/PlanTab.js +0 -19
  425. package/session/inspector/PlanTab.js.map +0 -1
  426. package/src/session/inspector/PlanTab.tsx +0 -31
@@ -0,0 +1,296 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ import { render, screen, cleanup, fireEvent, within } from "@testing-library/react";
3
+ import { create } from "@bufbuild/protobuf";
4
+ import {
5
+ FileChangeSchema,
6
+ FileContentSchema,
7
+ type FileChange,
8
+ type FileContent,
9
+ } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
10
+ import {
11
+ FileChangeCaptureLevel,
12
+ FileChangeType,
13
+ } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
14
+ import type { UseFileChangeContentReturn } from "../useFileChangeContent";
15
+
16
+ // ---------------------------------------------------------------------------
17
+ // Mock the content resolver so we can drive every render state.
18
+ // ---------------------------------------------------------------------------
19
+
20
+ let mockReturn: UseFileChangeContentReturn;
21
+
22
+ vi.mock("../useFileChangeContent", () => ({
23
+ useFileChangeContent: () => mockReturn,
24
+ }));
25
+
26
+ const { FileChangesView, FileChangeDiff } = await import("../FileChangesView");
27
+
28
+ function setContent(overrides?: Partial<UseFileChangeContentReturn>) {
29
+ mockReturn = {
30
+ beforeText: "",
31
+ afterText: "",
32
+ isBinary: false,
33
+ isLoading: false,
34
+ error: null,
35
+ isTruncated: false,
36
+ downloadUrl: null,
37
+ ...overrides,
38
+ };
39
+ }
40
+
41
+ beforeEach(() => setContent());
42
+ afterEach(() => cleanup());
43
+
44
+ // ---------------------------------------------------------------------------
45
+ // Fixtures
46
+ // ---------------------------------------------------------------------------
47
+
48
+ function inlineSide(value: string): FileContent {
49
+ return create(FileContentSchema, { body: { case: "inline", value } });
50
+ }
51
+
52
+ function wholeFile(path: string, before: string, after: string): FileChange {
53
+ return create(FileChangeSchema, {
54
+ path,
55
+ changeType: FileChangeType.MODIFY,
56
+ captureLevel: FileChangeCaptureLevel.WHOLE_FILE,
57
+ before: inlineSide(before),
58
+ after: inlineSide(after),
59
+ });
60
+ }
61
+
62
+ function hunkChange(path: string): FileChange {
63
+ return create(FileChangeSchema, {
64
+ path,
65
+ changeType: FileChangeType.MODIFY,
66
+ captureLevel: FileChangeCaptureLevel.HUNK_ONLY,
67
+ unifiedDiff: "@@ -1 +1 @@\n-alpha\n+beta",
68
+ linesAdded: 1,
69
+ linesRemoved: 1,
70
+ });
71
+ }
72
+
73
+ /** A whole-file CREATE with no content — a genuinely empty new file. */
74
+ function emptyCreate(path: string): FileChange {
75
+ return create(FileChangeSchema, {
76
+ path,
77
+ changeType: FileChangeType.CREATE,
78
+ captureLevel: FileChangeCaptureLevel.WHOLE_FILE,
79
+ });
80
+ }
81
+
82
+ /** A whole-file MODIFY that resolves to no change — a contentless edit. */
83
+ function emptyModify(path: string): FileChange {
84
+ return create(FileChangeSchema, {
85
+ path,
86
+ changeType: FileChangeType.MODIFY,
87
+ captureLevel: FileChangeCaptureLevel.WHOLE_FILE,
88
+ });
89
+ }
90
+
91
+ /** A hunk-only CREATE whose diff never materialized (no unifiedDiff). */
92
+ function emptyHunkCreate(path: string): FileChange {
93
+ return create(FileChangeSchema, {
94
+ path,
95
+ changeType: FileChangeType.CREATE,
96
+ captureLevel: FileChangeCaptureLevel.HUNK_ONLY,
97
+ });
98
+ }
99
+
100
+ // ---------------------------------------------------------------------------
101
+ // FileChangeDiff
102
+ // ---------------------------------------------------------------------------
103
+
104
+ describe("FileChangeDiff", () => {
105
+ it("renders the diff full (unbounded) by default — the dedicated Changes view", () => {
106
+ setContent({ beforeText: "alpha\n", afterText: "beta\n" });
107
+ const { container } = render(
108
+ <FileChangeDiff change={wholeFile("src/full.ts", "alpha\n", "beta\n")} />,
109
+ );
110
+ // No shared preview clamp: the Changes review surface shows the whole diff.
111
+ expect(container.querySelector(".overflow-hidden.max-h-48")).toBeNull();
112
+ expect(container.querySelector("table")).not.toBeNull();
113
+ });
114
+
115
+ it("bounds the diff to the shared preview budget when `bounded` is set (the approval gate)", () => {
116
+ setContent({ beforeText: "alpha\n", afterText: "beta\n" });
117
+ const { container } = render(
118
+ <FileChangeDiff change={wholeFile("src/bound.ts", "alpha\n", "beta\n")} bounded />,
119
+ );
120
+ // Opt-in clamp wraps the diff body via the shared BoundedContent primitive.
121
+ const clamp = container.querySelector(".overflow-hidden.max-h-48");
122
+ expect(clamp).not.toBeNull();
123
+ expect(clamp!.querySelector("table")).not.toBeNull();
124
+ });
125
+
126
+ it("renders a whole-file diff from resolved before/after text", () => {
127
+ setContent({ beforeText: "alpha\n", afterText: "beta\n" });
128
+ render(<FileChangeDiff change={wholeFile("src/a.ts", "alpha\n", "beta\n")} />);
129
+ // Filename-first: the base name is its own node; the dimmed dir is separate.
130
+ expect(screen.getByText("a.ts")).toBeTruthy();
131
+ expect(screen.getByText("src/")).toBeTruthy();
132
+ // computeDiff over the resolved text drives the +/- header stats.
133
+ expect(screen.getByText("+1")).toBeTruthy();
134
+ expect(screen.getByText("-1")).toBeTruthy();
135
+ });
136
+
137
+ it("renders a hunk-only unified diff through the DiffViewer table (no raw preamble)", () => {
138
+ const { container } = render(<FileChangeDiff change={hunkChange("src/h.ts")} />);
139
+ // The hunk-only patch is parsed into the accessible table, not dumped raw:
140
+ // the +/- prefixes live in a gutter cell, so the content cells hold the
141
+ // bare line text.
142
+ expect(container.querySelector("table")).not.toBeNull();
143
+ expect(screen.getByText("beta")).toBeTruthy();
144
+ expect(screen.getByText("alpha")).toBeTruthy();
145
+ // No raw unified-diff preamble or marker leaks into the content.
146
+ expect(container.textContent).not.toContain("@@");
147
+ // The authoritative counts still render in the header stats.
148
+ expect(screen.getByText("+1")).toBeTruthy();
149
+ expect(screen.getByText("-1")).toBeTruthy();
150
+ });
151
+
152
+ it("shows a binary notice when a side is binary", () => {
153
+ setContent({ isBinary: true });
154
+ render(<FileChangeDiff change={wholeFile("src/img.png", "", "")} />);
155
+ expect(screen.getByText(/binary file changed/i)).toBeTruthy();
156
+ });
157
+
158
+ it("shows a loading state while an offloaded side is fetched", () => {
159
+ setContent({ beforeText: null, afterText: null, isLoading: true });
160
+ render(<FileChangeDiff change={wholeFile("src/big.ts", "", "")} />);
161
+ expect(screen.getByText(/loading diff/i)).toBeTruthy();
162
+ });
163
+
164
+ it("shows an error state when content fails to load", () => {
165
+ setContent({ beforeText: null, afterText: null, error: new Error("nope") });
166
+ render(<FileChangeDiff change={wholeFile("src/x.ts", "", "")} />);
167
+ expect(screen.getByText(/could not load/i)).toBeTruthy();
168
+ });
169
+
170
+ it("offers a download link when an offloaded side is truncated", () => {
171
+ setContent({
172
+ beforeText: null,
173
+ afterText: null,
174
+ isTruncated: true,
175
+ downloadUrl: "https://dl/full",
176
+ });
177
+ render(<FileChangeDiff change={wholeFile("src/huge.ts", "", "")} />);
178
+ const link = screen.getByRole("link", { name: /download the full file/i });
179
+ expect(link.getAttribute("href")).toBe("https://dl/full");
180
+ });
181
+
182
+ it("suppresses the filename header when showFileName is false but keeps the stats", () => {
183
+ setContent({ beforeText: "alpha\n", afterText: "beta\n" });
184
+ render(
185
+ <FileChangeDiff
186
+ change={wholeFile("src/a.ts", "alpha\n", "beta\n")}
187
+ showFileName={false}
188
+ />,
189
+ );
190
+ // Neither the base name nor the dimmed directory renders.
191
+ expect(screen.queryByText("a.ts")).toBeNull();
192
+ expect(screen.queryByText("src/")).toBeNull();
193
+ // The +/- stats still render.
194
+ expect(screen.getByText("+1")).toBeTruthy();
195
+ expect(screen.getByText("-1")).toBeTruthy();
196
+ });
197
+
198
+ it("suppresses the +/- stats when showStats is false (owning row shows them)", () => {
199
+ setContent({ beforeText: "alpha\n", afterText: "beta\n" });
200
+ render(
201
+ <FileChangeDiff
202
+ change={wholeFile("src/a.ts", "alpha\n", "beta\n")}
203
+ showFileName={false}
204
+ showStats={false}
205
+ />,
206
+ );
207
+ // Neither the name nor the duplicate counts render; the diff body remains.
208
+ expect(screen.queryByText("a.ts")).toBeNull();
209
+ expect(screen.queryByText("+1")).toBeNull();
210
+ expect(screen.queryByText("-1")).toBeNull();
211
+ });
212
+
213
+ it("shows 'New empty file' for an empty whole-file CREATE", () => {
214
+ setContent({ beforeText: "", afterText: "" });
215
+ render(<FileChangeDiff change={emptyCreate("src/new.md")} />);
216
+ expect(screen.getByText("New empty file")).toBeTruthy();
217
+ });
218
+
219
+ it("shows 'New empty file' for an empty hunk-only CREATE (no diff yet)", () => {
220
+ render(<FileChangeDiff change={emptyHunkCreate("src/e.ts")} />);
221
+ expect(screen.getByText("New empty file")).toBeTruthy();
222
+ });
223
+
224
+ it("shows a neutral 'no preview' notice for a contentless MODIFY", () => {
225
+ setContent({ beforeText: "", afterText: "" });
226
+ render(<FileChangeDiff change={emptyModify("src/x.ts")} />);
227
+ expect(screen.getByText("No preview available for this change")).toBeTruthy();
228
+ });
229
+ });
230
+
231
+ // ---------------------------------------------------------------------------
232
+ // FileChangesView
233
+ // ---------------------------------------------------------------------------
234
+
235
+ describe("FileChangesView", () => {
236
+ it("renders nothing when there are no changes", () => {
237
+ const { container } = render(<FileChangesView changes={[]} />);
238
+ expect(container.firstChild).toBeNull();
239
+ });
240
+
241
+ it("renders a summary and the sole file's diff for a single change", () => {
242
+ setContent({ beforeText: "a\n", afterText: "b\n" });
243
+ render(<FileChangesView changes={[wholeFile("src/only.ts", "a\n", "b\n")]} />);
244
+ // Single change: no file list, just the diff header (filename-first).
245
+ expect(screen.getByText("only.ts")).toBeTruthy();
246
+ });
247
+
248
+ it("renders a file list when multiple files changed", () => {
249
+ setContent({ beforeText: "a\n", afterText: "b\n" });
250
+ render(
251
+ <FileChangesView
252
+ changes={[
253
+ wholeFile("src/one.ts", "a\n", "b\n"),
254
+ wholeFile("src/two.ts", "a\n", "b\n"),
255
+ ]}
256
+ />,
257
+ );
258
+ // The selected file appears in both the list and the diff header.
259
+ expect(screen.getAllByText("src/one.ts").length).toBeGreaterThanOrEqual(1);
260
+ expect(screen.getByText("src/two.ts")).toBeTruthy();
261
+ });
262
+
263
+ it("swaps the active diff when another file in the list is selected", () => {
264
+ setContent({ beforeText: "a\n", afterText: "b\n" });
265
+ render(
266
+ <FileChangesView
267
+ changes={[
268
+ wholeFile("src/one.ts", "a\n", "b\n"),
269
+ wholeFile("src/two.ts", "a\n", "b\n"),
270
+ ]}
271
+ />,
272
+ );
273
+
274
+ // The file selector (DiffFileList) keeps full paths; scope the button
275
+ // queries to its nav so they don't collide with the diff header's
276
+ // filename-first FilePathLink (a button whose aria-label includes the path).
277
+ const list = within(
278
+ screen.getByRole("navigation", { name: "Changed files" }),
279
+ );
280
+ const oneButton = list.getByRole("button", { name: /src\/one\.ts/ });
281
+ const twoButton = list.getByRole("button", { name: /src\/two\.ts/ });
282
+
283
+ // The first file is selected by default: aria-current marks the list entry,
284
+ // and the diff header shows that file's name (filename-first).
285
+ expect(oneButton.getAttribute("aria-current")).toBe("true");
286
+ expect(twoButton.getAttribute("aria-current")).toBeNull();
287
+ expect(screen.getByText("one.ts")).toBeTruthy();
288
+
289
+ fireEvent.click(twoButton);
290
+
291
+ // Selection moves to the second file; the header now shows it instead.
292
+ expect(twoButton.getAttribute("aria-current")).toBe("true");
293
+ expect(oneButton.getAttribute("aria-current")).toBeNull();
294
+ expect(screen.getByText("two.ts")).toBeTruthy();
295
+ });
296
+ });
@@ -0,0 +1,92 @@
1
+ import { describe, it, expect, afterEach, vi } from "vitest";
2
+ import { render, screen, cleanup, fireEvent } from "@testing-library/react";
3
+ import { create } from "@bufbuild/protobuf";
4
+ import {
5
+ WorkspaceEntrySchema,
6
+ WorkspaceSourceSchema,
7
+ LocalPathSourceSchema,
8
+ } from "@stigmer/protos/ai/stigmer/agentic/session/v1/workspace_pb";
9
+ import type { WorkspaceEntry } from "@stigmer/protos/ai/stigmer/agentic/session/v1/workspace_pb";
10
+ import { FilePathLink } from "../FilePathLink";
11
+ import { FilePathContext } from "../FilePathContext";
12
+
13
+ afterEach(cleanup);
14
+
15
+ function localEntry(name: string, path: string): WorkspaceEntry {
16
+ return create(WorkspaceEntrySchema, {
17
+ name,
18
+ source: create(WorkspaceSourceSchema, {
19
+ source: { case: "localPath", value: create(LocalPathSourceSchema, { path }) },
20
+ }),
21
+ });
22
+ }
23
+
24
+ describe("FilePathLink filename-first display", () => {
25
+ it("shows only the base name by default, hiding the directory", () => {
26
+ render(<FilePathLink path="src/app/main.ts" />);
27
+ expect(screen.getByText("main.ts")).toBeTruthy();
28
+ expect(screen.queryByText("src/app/")).toBeNull();
29
+ });
30
+
31
+ it("shows a dimmed directory alongside the base when dirDisplay='dim'", () => {
32
+ render(<FilePathLink path="src/app/main.ts" dirDisplay="dim" />);
33
+ expect(screen.getByText("main.ts")).toBeTruthy();
34
+ expect(screen.getByText("src/app/")).toBeTruthy();
35
+ });
36
+
37
+ it("never clips the file name even for a long absolute path", () => {
38
+ // The base lives in its own non-shrinking node; only the dir is allowed to
39
+ // truncate. The defect this fixes was a single `truncate` over the whole
40
+ // path that hid the file name.
41
+ render(<FilePathLink path="/Users/me/scm/very/deep/notes.md" dirDisplay="dim" />);
42
+ const base = screen.getByText("notes.md");
43
+ expect(base.className).toContain("shrink-0");
44
+ expect(base.className).not.toContain("truncate");
45
+ });
46
+ });
47
+
48
+ describe("FilePathLink full path on hover", () => {
49
+ it("puts the absolute local path in the title (not the action verb)", () => {
50
+ const entries = [localEntry("my-app", "/Users/dev/my-app")];
51
+ render(
52
+ <FilePathContext.Provider value={{ workspaceEntries: entries }}>
53
+ <FilePathLink path="src/main.go" />
54
+ </FilePathContext.Provider>,
55
+ );
56
+ const el = screen.getByRole("button");
57
+ expect(el.getAttribute("title")).toBe("/Users/dev/my-app/src/main.go");
58
+ // The action verb moves into the accessible name, with the path.
59
+ expect(el.getAttribute("aria-label")).toBe("Copy path: /Users/dev/my-app/src/main.go");
60
+ });
61
+
62
+ it("falls back to the logical path in the title when unresolved", () => {
63
+ render(<FilePathLink path="src/main.go" />);
64
+ expect(screen.getByRole("button").getAttribute("title")).toBe("src/main.go");
65
+ });
66
+ });
67
+
68
+ describe("FilePathLink interaction", () => {
69
+ it("stops click propagation so it never toggles an enclosing row", () => {
70
+ const onRowClick = vi.fn();
71
+ render(
72
+ <div onClick={onRowClick}>
73
+ <FilePathLink path="src/main.go" />
74
+ </div>,
75
+ );
76
+ fireEvent.click(screen.getByRole("button"));
77
+ expect(onRowClick).not.toHaveBeenCalled();
78
+ });
79
+
80
+ it("invokes the context onFilePathClick override with the resolved action", () => {
81
+ const onFilePathClick = vi.fn();
82
+ render(
83
+ <FilePathContext.Provider value={{ workspaceEntries: [], onFilePathClick }}>
84
+ <FilePathLink path="src/main.go" />
85
+ </FilePathContext.Provider>,
86
+ );
87
+ fireEvent.click(screen.getByRole("button"));
88
+ expect(onFilePathClick).toHaveBeenCalledTimes(1);
89
+ expect(onFilePathClick.mock.calls[0][0]).toBe("src/main.go");
90
+ expect(onFilePathClick.mock.calls[0][1].action).toBe("copy");
91
+ });
92
+ });