@stigmer/react 3.1.1 → 3.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (483) hide show
  1. package/composer/SessionComposer.d.ts +25 -1
  2. package/composer/SessionComposer.d.ts.map +1 -1
  3. package/composer/SessionComposer.js +19 -8
  4. package/composer/SessionComposer.js.map +1 -1
  5. package/execution/ArtifactContentRenderer.d.ts +11 -1
  6. package/execution/ArtifactContentRenderer.d.ts.map +1 -1
  7. package/execution/ArtifactContentRenderer.js +39 -15
  8. package/execution/ArtifactContentRenderer.js.map +1 -1
  9. package/execution/ArtifactPreviewModal.d.ts +5 -5
  10. package/execution/ArtifactPreviewModal.js +4 -4
  11. package/execution/ArtifactPreviewModal.js.map +1 -1
  12. package/execution/FileChangeProgressBar.d.ts +47 -0
  13. package/execution/FileChangeProgressBar.d.ts.map +1 -0
  14. package/execution/FileChangeProgressBar.js +49 -0
  15. package/execution/FileChangeProgressBar.js.map +1 -0
  16. package/execution/FileChangesView.d.ts.map +1 -1
  17. package/execution/FileChangesView.js +19 -4
  18. package/execution/FileChangesView.js.map +1 -1
  19. package/execution/FilePathContext.d.ts +8 -1
  20. package/execution/FilePathContext.d.ts.map +1 -1
  21. package/execution/FilePathContext.js.map +1 -1
  22. package/execution/FilePathLink.d.ts.map +1 -1
  23. package/execution/FilePathLink.js +21 -6
  24. package/execution/FilePathLink.js.map +1 -1
  25. package/execution/FileReviewAtoms.d.ts +27 -0
  26. package/execution/FileReviewAtoms.d.ts.map +1 -0
  27. package/execution/FileReviewAtoms.js +64 -0
  28. package/execution/FileReviewAtoms.js.map +1 -0
  29. package/execution/FileReviewCard.d.ts +2 -2
  30. package/execution/FileReviewCard.d.ts.map +1 -1
  31. package/execution/FileReviewCard.js +32 -62
  32. package/execution/FileReviewCard.js.map +1 -1
  33. package/execution/MessageEntry.d.ts +20 -0
  34. package/execution/MessageEntry.d.ts.map +1 -1
  35. package/execution/MessageEntry.js +19 -5
  36. package/execution/MessageEntry.js.map +1 -1
  37. package/execution/MessageThread.d.ts +75 -13
  38. package/execution/MessageThread.d.ts.map +1 -1
  39. package/execution/MessageThread.js +195 -27
  40. package/execution/MessageThread.js.map +1 -1
  41. package/execution/PlanArtifactCard.d.ts +36 -21
  42. package/execution/PlanArtifactCard.d.ts.map +1 -1
  43. package/execution/PlanArtifactCard.js +39 -25
  44. package/execution/PlanArtifactCard.js.map +1 -1
  45. package/execution/PlanCompletionCard.d.ts +4 -4
  46. package/execution/PlanCompletionCard.d.ts.map +1 -1
  47. package/execution/PlanCompletionCard.js +4 -4
  48. package/execution/PlanCompletionCard.js.map +1 -1
  49. package/execution/PlanDocumentMessage.d.ts +32 -0
  50. package/execution/PlanDocumentMessage.d.ts.map +1 -0
  51. package/execution/PlanDocumentMessage.js +37 -0
  52. package/execution/PlanDocumentMessage.js.map +1 -0
  53. package/execution/PlanStreamingCard.d.ts +50 -0
  54. package/execution/PlanStreamingCard.d.ts.map +1 -0
  55. package/execution/PlanStreamingCard.js +40 -0
  56. package/execution/PlanStreamingCard.js.map +1 -0
  57. package/execution/index.d.ts +9 -1
  58. package/execution/index.d.ts.map +1 -1
  59. package/execution/index.js +4 -0
  60. package/execution/index.js.map +1 -1
  61. package/execution/use-build-from-plan-hotkey.d.ts +1 -1
  62. package/execution/use-build-from-plan-hotkey.js +1 -1
  63. package/execution/useArtifactCopy.d.ts +51 -0
  64. package/execution/useArtifactCopy.d.ts.map +1 -0
  65. package/execution/useArtifactCopy.js +75 -0
  66. package/execution/useArtifactCopy.js.map +1 -0
  67. package/execution/useArtifactDownload.d.ts.map +1 -1
  68. package/execution/useArtifactDownload.js +17 -5
  69. package/execution/useArtifactDownload.js.map +1 -1
  70. package/execution/useCreateAgentExecution.d.ts +12 -0
  71. package/execution/useCreateAgentExecution.d.ts.map +1 -1
  72. package/execution/useCreateAgentExecution.js +5 -1
  73. package/execution/useCreateAgentExecution.js.map +1 -1
  74. package/github/decodeGitHubContent.d.ts +29 -0
  75. package/github/decodeGitHubContent.d.ts.map +1 -0
  76. package/github/decodeGitHubContent.js +72 -0
  77. package/github/decodeGitHubContent.js.map +1 -0
  78. package/github/index.d.ts +1 -0
  79. package/github/index.d.ts.map +1 -1
  80. package/github/index.js +1 -0
  81. package/github/index.js.map +1 -1
  82. package/github/useGitHubFileReader.d.ts +26 -0
  83. package/github/useGitHubFileReader.d.ts.map +1 -0
  84. package/github/useGitHubFileReader.js +106 -0
  85. package/github/useGitHubFileReader.js.map +1 -0
  86. package/github/useGitHubTreeLister.d.ts.map +1 -1
  87. package/github/useGitHubTreeLister.js +6 -2
  88. package/github/useGitHubTreeLister.js.map +1 -1
  89. package/index.d.ts +9 -9
  90. package/index.d.ts.map +1 -1
  91. package/index.js +5 -5
  92. package/index.js.map +1 -1
  93. package/internal/ResizableSplit.d.ts +72 -22
  94. package/internal/ResizableSplit.d.ts.map +1 -1
  95. package/internal/ResizableSplit.js +96 -38
  96. package/internal/ResizableSplit.js.map +1 -1
  97. package/internal/VirtualizedThread.d.ts +5 -3
  98. package/internal/VirtualizedThread.d.ts.map +1 -1
  99. package/internal/VirtualizedThread.js +6 -4
  100. package/internal/VirtualizedThread.js.map +1 -1
  101. package/internal/file-icons/index.d.ts +17 -0
  102. package/internal/file-icons/index.d.ts.map +1 -0
  103. package/internal/file-icons/index.js +60 -0
  104. package/internal/file-icons/index.js.map +1 -0
  105. package/internal/file-tree/FileTreeNode.d.ts +18 -1
  106. package/internal/file-tree/FileTreeNode.d.ts.map +1 -1
  107. package/internal/file-tree/FileTreeNode.js +11 -2
  108. package/internal/file-tree/FileTreeNode.js.map +1 -1
  109. package/internal/markdown-components.d.ts +38 -1
  110. package/internal/markdown-components.d.ts.map +1 -1
  111. package/internal/markdown-components.js +86 -11
  112. package/internal/markdown-components.js.map +1 -1
  113. package/{workflow → internal}/motion-preference.d.ts +7 -4
  114. package/internal/motion-preference.d.ts.map +1 -0
  115. package/{workflow → internal}/motion-preference.js +7 -4
  116. package/internal/motion-preference.js.map +1 -0
  117. package/internal/store/index.d.ts +33 -0
  118. package/internal/store/index.d.ts.map +1 -1
  119. package/internal/store/index.js +59 -0
  120. package/internal/store/index.js.map +1 -1
  121. package/internal/store/workspace-editors-store.d.ts +145 -0
  122. package/internal/store/workspace-editors-store.d.ts.map +1 -0
  123. package/internal/store/workspace-editors-store.js +208 -0
  124. package/internal/store/workspace-editors-store.js.map +1 -0
  125. package/internal/store/workspace-file-selection-store.d.ts +38 -0
  126. package/internal/store/workspace-file-selection-store.d.ts.map +1 -0
  127. package/internal/store/workspace-file-selection-store.js +62 -0
  128. package/internal/store/workspace-file-selection-store.js.map +1 -0
  129. package/internal/useRevealLine.d.ts +49 -0
  130. package/internal/useRevealLine.d.ts.map +1 -0
  131. package/internal/useRevealLine.js +43 -0
  132. package/internal/useRevealLine.js.map +1 -0
  133. package/library/detect-plan-artifact.d.ts +43 -4
  134. package/library/detect-plan-artifact.d.ts.map +1 -1
  135. package/library/detect-plan-artifact.js +45 -5
  136. package/library/detect-plan-artifact.js.map +1 -1
  137. package/library/detect-streaming-plan.d.ts +45 -0
  138. package/library/detect-streaming-plan.d.ts.map +1 -0
  139. package/library/detect-streaming-plan.js +83 -0
  140. package/library/detect-streaming-plan.js.map +1 -0
  141. package/library/index.d.ts +4 -1
  142. package/library/index.d.ts.map +1 -1
  143. package/library/index.js +2 -1
  144. package/library/index.js.map +1 -1
  145. package/package.json +4 -4
  146. package/session/NewSessionViewer.d.ts +19 -4
  147. package/session/NewSessionViewer.d.ts.map +1 -1
  148. package/session/NewSessionViewer.js +52 -25
  149. package/session/NewSessionViewer.js.map +1 -1
  150. package/session/PlanEditor.d.ts +55 -0
  151. package/session/PlanEditor.d.ts.map +1 -0
  152. package/session/PlanEditor.js +88 -0
  153. package/session/PlanEditor.js.map +1 -0
  154. package/session/PlanStreamingDocument.d.ts +30 -0
  155. package/session/PlanStreamingDocument.d.ts.map +1 -0
  156. package/session/PlanStreamingDocument.js +37 -0
  157. package/session/PlanStreamingDocument.js.map +1 -0
  158. package/session/SessionPanelChip.d.ts +26 -0
  159. package/session/SessionPanelChip.d.ts.map +1 -0
  160. package/session/SessionPanelChip.js +40 -0
  161. package/session/SessionPanelChip.js.map +1 -0
  162. package/session/SessionViewer.d.ts +34 -7
  163. package/session/SessionViewer.d.ts.map +1 -1
  164. package/session/SessionViewer.js +334 -33
  165. package/session/SessionViewer.js.map +1 -1
  166. package/session/{inspector → facets}/ArtifactsTab.d.ts +10 -2
  167. package/session/facets/ArtifactsTab.d.ts.map +1 -0
  168. package/session/{inspector → facets}/ArtifactsTab.js +8 -3
  169. package/session/facets/ArtifactsTab.js.map +1 -0
  170. package/session/{inspector → facets}/ChangesTab.d.ts +3 -3
  171. package/session/facets/ChangesTab.d.ts.map +1 -0
  172. package/session/{inspector → facets}/ChangesTab.js +3 -3
  173. package/session/facets/ChangesTab.js.map +1 -0
  174. package/session/facets/InspectTab.d.ts.map +1 -0
  175. package/session/facets/InspectTab.js.map +1 -0
  176. package/session/{inspector → facets}/SetupTab.d.ts +11 -2
  177. package/session/facets/SetupTab.d.ts.map +1 -0
  178. package/session/{inspector → facets}/SetupTab.js +4 -3
  179. package/session/facets/SetupTab.js.map +1 -0
  180. package/session/{inspector → facets}/UsageTab.d.ts +1 -1
  181. package/session/facets/UsageTab.d.ts.map +1 -0
  182. package/session/{inspector → facets}/UsageTab.js +1 -1
  183. package/session/facets/UsageTab.js.map +1 -0
  184. package/session/{inspector → facets}/index.d.ts +0 -6
  185. package/session/facets/index.d.ts.map +1 -0
  186. package/session/{inspector → facets}/index.js +0 -3
  187. package/session/facets/index.js.map +1 -0
  188. package/session/index.d.ts +11 -2
  189. package/session/index.d.ts.map +1 -1
  190. package/session/index.js +15 -2
  191. package/session/index.js.map +1 -1
  192. package/session/plan-document.d.ts +21 -0
  193. package/session/plan-document.d.ts.map +1 -0
  194. package/session/plan-document.js +28 -0
  195. package/session/plan-document.js.map +1 -0
  196. package/session/useOpenFileChange.d.ts +20 -0
  197. package/session/useOpenFileChange.d.ts.map +1 -0
  198. package/session/useOpenFileChange.js +31 -0
  199. package/session/useOpenFileChange.js.map +1 -0
  200. package/session/usePlanDraft.d.ts +52 -0
  201. package/session/usePlanDraft.d.ts.map +1 -0
  202. package/session/usePlanDraft.js +63 -0
  203. package/session/usePlanDraft.js.map +1 -0
  204. package/session/useSessionConversation.d.ts +14 -1
  205. package/session/useSessionConversation.d.ts.map +1 -1
  206. package/session/useSessionConversation.js +20 -2
  207. package/session/useSessionConversation.js.map +1 -1
  208. package/session/useSessionPageFlow.d.ts.map +1 -1
  209. package/session/useSessionPageFlow.js +1 -0
  210. package/session/useSessionPageFlow.js.map +1 -1
  211. package/session/useSessionPanel.d.ts +120 -0
  212. package/session/useSessionPanel.d.ts.map +1 -0
  213. package/session/useSessionPanel.js +130 -0
  214. package/session/useSessionPanel.js.map +1 -0
  215. package/session/useSessionRailViews.d.ts +45 -0
  216. package/session/useSessionRailViews.d.ts.map +1 -0
  217. package/session/useSessionRailViews.js +105 -0
  218. package/session/useSessionRailViews.js.map +1 -0
  219. package/src/composer/SessionComposer.tsx +53 -10
  220. package/src/composer/__tests__/SessionComposer-contract.test.tsx +58 -4
  221. package/src/execution/ArtifactContentRenderer.tsx +101 -24
  222. package/src/execution/ArtifactPreviewModal.tsx +9 -9
  223. package/src/execution/FileChangeProgressBar.tsx +121 -0
  224. package/src/execution/FileChangesView.tsx +18 -4
  225. package/src/execution/FilePathContext.tsx +8 -1
  226. package/src/execution/FilePathLink.tsx +22 -6
  227. package/src/execution/FileReviewAtoms.tsx +89 -0
  228. package/src/execution/FileReviewCard.tsx +57 -90
  229. package/src/execution/MessageEntry.tsx +49 -1
  230. package/src/execution/MessageThread.tsx +308 -39
  231. package/src/execution/PlanArtifactCard.tsx +174 -64
  232. package/src/execution/PlanCompletionCard.tsx +5 -5
  233. package/src/execution/PlanDocumentMessage.tsx +96 -0
  234. package/src/execution/PlanStreamingCard.tsx +141 -0
  235. package/src/execution/__tests__/ArtifactContentRenderer.test.tsx +80 -1
  236. package/src/execution/__tests__/ArtifactPreviewModal.test.tsx +6 -6
  237. package/src/execution/__tests__/FileChangeProgressBar.test.tsx +125 -0
  238. package/src/execution/__tests__/FilePathLink.test.tsx +87 -0
  239. package/src/execution/__tests__/FileReviewCard.test.tsx +66 -7
  240. package/src/execution/__tests__/MessageThread.test.tsx +102 -1
  241. package/src/execution/__tests__/PlanArtifactCard.test.tsx +114 -26
  242. package/src/execution/__tests__/PlanCompletionCard.test.tsx +2 -2
  243. package/src/execution/__tests__/PlanDocumentMessage.test.tsx +55 -0
  244. package/src/execution/__tests__/PlanStreamingCard.test.tsx +56 -0
  245. package/src/execution/__tests__/buildThreadItems-plan-completion.test.ts +600 -22
  246. package/src/execution/__tests__/message-entry.test.tsx +17 -0
  247. package/src/execution/__tests__/useArtifactCopy.test.tsx +90 -0
  248. package/src/execution/__tests__/useArtifactDownload.test.tsx +2 -0
  249. package/src/execution/__tests__/useCreateAgentExecution.test.tsx +85 -0
  250. package/src/execution/index.ts +13 -1
  251. package/src/execution/use-build-from-plan-hotkey.ts +1 -1
  252. package/src/execution/useArtifactCopy.ts +109 -0
  253. package/src/execution/useArtifactDownload.ts +17 -5
  254. package/src/execution/useCreateAgentExecution.ts +18 -1
  255. package/src/github/__tests__/decodeGitHubContent.test.ts +102 -0
  256. package/src/github/__tests__/useGitHubFileReader.test.ts +183 -0
  257. package/src/github/decodeGitHubContent.ts +83 -0
  258. package/src/github/index.ts +1 -0
  259. package/src/github/useGitHubFileReader.ts +152 -0
  260. package/src/github/useGitHubTreeLister.ts +6 -2
  261. package/src/index.ts +69 -9
  262. package/src/internal/ResizableSplit.tsx +184 -51
  263. package/src/internal/VirtualizedThread.tsx +12 -4
  264. package/src/internal/__tests__/ResizableSplit.test.tsx +125 -3
  265. package/src/internal/__tests__/markdown-components.test.tsx +68 -0
  266. package/src/internal/__tests__/useRevealLine.test.tsx +97 -0
  267. package/src/internal/file-icons/__tests__/file-icons.test.tsx +35 -0
  268. package/src/internal/file-icons/index.tsx +137 -0
  269. package/src/internal/file-tree/FileTreeNode.tsx +56 -5
  270. package/src/internal/file-tree/__tests__/FileTreeNode-explorer.test.tsx +86 -0
  271. package/src/internal/markdown-components.tsx +116 -11
  272. package/src/{workflow → internal}/motion-preference.ts +7 -4
  273. package/src/internal/store/__tests__/workspace-editors-store.test.ts +216 -0
  274. package/src/internal/store/__tests__/workspace-file-selection-store.test.ts +118 -0
  275. package/src/internal/store/index.ts +94 -0
  276. package/src/internal/store/workspace-editors-store.ts +315 -0
  277. package/src/internal/store/workspace-file-selection-store.ts +88 -0
  278. package/src/internal/useRevealLine.ts +81 -0
  279. package/src/library/__tests__/detect-plan-artifact.test.ts +69 -0
  280. package/src/library/__tests__/detect-streaming-plan.test.ts +234 -0
  281. package/src/library/detect-plan-artifact.ts +62 -5
  282. package/src/library/detect-streaming-plan.ts +108 -0
  283. package/src/library/index.ts +7 -0
  284. package/src/session/NewSessionViewer.tsx +123 -55
  285. package/src/session/PlanEditor.tsx +361 -0
  286. package/src/session/PlanStreamingDocument.tsx +97 -0
  287. package/src/session/SessionPanelChip.tsx +103 -0
  288. package/src/session/SessionViewer.tsx +655 -96
  289. package/src/session/__tests__/NewSessionViewer.test.tsx +148 -0
  290. package/src/session/__tests__/PlanEditor.test.tsx +217 -0
  291. package/src/session/__tests__/PlanStreamingDocument.test.tsx +50 -0
  292. package/src/session/__tests__/SessionPanelChip.test.tsx +42 -0
  293. package/src/session/__tests__/SessionViewer-fileReviewDock.test.tsx +66 -4
  294. package/src/session/__tests__/SessionViewer-transcriptFileOpen.test.tsx +205 -0
  295. package/src/session/__tests__/audienceWiring.test.tsx +55 -19
  296. package/src/session/__tests__/useOpenFileChange.test.tsx +82 -0
  297. package/src/session/__tests__/usePlanDraft.test.ts +102 -0
  298. package/src/session/__tests__/useSessionConversation.test.tsx +44 -0
  299. package/src/session/__tests__/useSessionPanel.test.ts +298 -0
  300. package/src/session/__tests__/useSessionRailViews.test.tsx +124 -0
  301. package/src/session/{inspector → facets}/ArtifactsTab.tsx +27 -5
  302. package/src/session/{inspector → facets}/ChangesTab.tsx +3 -3
  303. package/src/session/{inspector → facets}/SetupTab.tsx +13 -1
  304. package/src/session/{inspector → facets}/UsageTab.tsx +1 -1
  305. package/src/session/{inspector → facets}/__tests__/ArtifactsTab.test.tsx +42 -8
  306. package/src/session/facets/__tests__/SetupTab.test.tsx +44 -0
  307. package/src/session/{inspector → facets}/index.ts +0 -16
  308. package/src/session/index.ts +30 -13
  309. package/src/session/plan-document.ts +30 -0
  310. package/src/session/useOpenFileChange.ts +53 -0
  311. package/src/session/usePlanDraft.ts +109 -0
  312. package/src/session/useSessionConversation.ts +38 -3
  313. package/src/session/useSessionPageFlow.ts +1 -0
  314. package/src/session/useSessionPanel.ts +288 -0
  315. package/src/session/useSessionRailViews.tsx +200 -0
  316. package/src/workflow/WorkflowExecutionGraph.tsx +1 -1
  317. package/src/workflow/index.ts +1 -1
  318. package/src/workflow/useFollowExecution.ts +1 -1
  319. package/src/workspace/EditorTabs.tsx +174 -0
  320. package/src/workspace/ExplorerTree.tsx +253 -0
  321. package/src/workspace/FileViewer.tsx +537 -0
  322. package/src/workspace/WorkspaceContentSearch.tsx +502 -0
  323. package/src/workspace/WorkspaceContentSearcher.ts +70 -0
  324. package/src/workspace/WorkspaceEditor.tsx +19 -16
  325. package/src/workspace/WorkspaceFileLister.ts +11 -0
  326. package/src/workspace/WorkspaceFileReader.ts +57 -0
  327. package/src/workspace/WorkspaceFileSearch.tsx +452 -0
  328. package/src/workspace/WorkspaceSurface.tsx +839 -0
  329. package/src/workspace/__tests__/EditorTabs.test.tsx +102 -0
  330. package/src/workspace/__tests__/ExplorerTree.test.tsx +204 -0
  331. package/src/workspace/__tests__/FileViewer.test.tsx +439 -0
  332. package/src/workspace/__tests__/WorkspaceContentSearch.test.tsx +229 -0
  333. package/src/workspace/__tests__/WorkspaceEditor-initialPanel.test.tsx +19 -0
  334. package/src/workspace/__tests__/WorkspaceFileSearch.test.tsx +227 -0
  335. package/src/workspace/__tests__/WorkspaceSurface.test.tsx +418 -0
  336. package/src/workspace/__tests__/a11y/harness.tsx +140 -0
  337. package/src/workspace/__tests__/a11y/mock-capabilities.ts +138 -0
  338. package/src/workspace/__tests__/a11y/workspace-editor.a11y.test.tsx +65 -0
  339. package/src/workspace/__tests__/a11y/workspace-explorer-search.a11y.test.tsx +112 -0
  340. package/src/workspace/__tests__/a11y/workspace-viewer-tabs.a11y.test.tsx +69 -0
  341. package/src/workspace/__tests__/findChangeForSelection.test.ts +132 -0
  342. package/src/workspace/__tests__/matchContentPreview.test.ts +55 -0
  343. package/src/workspace/__tests__/matchWorkspaceFiles.test.ts +104 -0
  344. package/src/workspace/__tests__/resolveWorkspaceFileSelection.test.ts +135 -0
  345. package/src/workspace/__tests__/useWorkspaceContentSearch.test.tsx +196 -0
  346. package/src/workspace/__tests__/useWorkspaceFileContent.test.tsx +190 -0
  347. package/src/workspace/__tests__/useWorkspaceFileSearch.test.tsx +162 -0
  348. package/src/workspace/findChangeForSelection.ts +61 -0
  349. package/src/workspace/index.ts +56 -2
  350. package/src/workspace/matchContentPreview.ts +51 -0
  351. package/src/workspace/matchWorkspaceFiles.ts +86 -0
  352. package/src/workspace/resolveWorkspaceFileSelection.ts +119 -0
  353. package/src/workspace/useWorkspaceContentSearch.ts +228 -0
  354. package/src/workspace/useWorkspaceFileContent.ts +129 -0
  355. package/src/workspace/useWorkspaceFileSearch.ts +184 -0
  356. package/src/workspace/useWorkspaceFiles.ts +27 -27
  357. package/src/workspace/workspaceListingCache.ts +93 -0
  358. package/styles.css +1 -1
  359. package/workflow/WorkflowExecutionGraph.js +1 -1
  360. package/workflow/WorkflowExecutionGraph.js.map +1 -1
  361. package/workflow/index.d.ts +1 -1
  362. package/workflow/index.d.ts.map +1 -1
  363. package/workflow/index.js +1 -1
  364. package/workflow/index.js.map +1 -1
  365. package/workflow/useFollowExecution.js +1 -1
  366. package/workflow/useFollowExecution.js.map +1 -1
  367. package/workspace/EditorTabs.d.ts +47 -0
  368. package/workspace/EditorTabs.d.ts.map +1 -0
  369. package/workspace/EditorTabs.js +78 -0
  370. package/workspace/EditorTabs.js.map +1 -0
  371. package/workspace/ExplorerTree.d.ts +32 -0
  372. package/workspace/ExplorerTree.d.ts.map +1 -0
  373. package/workspace/ExplorerTree.js +49 -0
  374. package/workspace/ExplorerTree.js.map +1 -0
  375. package/workspace/FileViewer.d.ts +93 -0
  376. package/workspace/FileViewer.d.ts.map +1 -0
  377. package/workspace/FileViewer.js +193 -0
  378. package/workspace/FileViewer.js.map +1 -0
  379. package/workspace/WorkspaceContentSearch.d.ts +41 -0
  380. package/workspace/WorkspaceContentSearch.d.ts.map +1 -0
  381. package/workspace/WorkspaceContentSearch.js +216 -0
  382. package/workspace/WorkspaceContentSearch.js.map +1 -0
  383. package/workspace/WorkspaceContentSearcher.d.ts +59 -0
  384. package/workspace/WorkspaceContentSearcher.d.ts.map +1 -0
  385. package/workspace/WorkspaceContentSearcher.js +7 -0
  386. package/workspace/WorkspaceContentSearcher.js.map +1 -0
  387. package/workspace/WorkspaceEditor.d.ts.map +1 -1
  388. package/workspace/WorkspaceEditor.js +8 -10
  389. package/workspace/WorkspaceEditor.js.map +1 -1
  390. package/workspace/WorkspaceFileLister.d.ts +11 -0
  391. package/workspace/WorkspaceFileLister.d.ts.map +1 -1
  392. package/workspace/WorkspaceFileReader.d.ts +48 -0
  393. package/workspace/WorkspaceFileReader.d.ts.map +1 -0
  394. package/workspace/WorkspaceFileReader.js +11 -0
  395. package/workspace/WorkspaceFileReader.js.map +1 -0
  396. package/workspace/WorkspaceFileSearch.d.ts +32 -0
  397. package/workspace/WorkspaceFileSearch.d.ts.map +1 -0
  398. package/workspace/WorkspaceFileSearch.js +175 -0
  399. package/workspace/WorkspaceFileSearch.js.map +1 -0
  400. package/workspace/WorkspaceSurface.d.ts +151 -0
  401. package/workspace/WorkspaceSurface.d.ts.map +1 -0
  402. package/workspace/WorkspaceSurface.js +220 -0
  403. package/workspace/WorkspaceSurface.js.map +1 -0
  404. package/workspace/findChangeForSelection.d.ts +19 -0
  405. package/workspace/findChangeForSelection.d.ts.map +1 -0
  406. package/workspace/findChangeForSelection.js +46 -0
  407. package/workspace/findChangeForSelection.js.map +1 -0
  408. package/workspace/index.d.ts +24 -2
  409. package/workspace/index.d.ts.map +1 -1
  410. package/workspace/index.js +13 -1
  411. package/workspace/index.js.map +1 -1
  412. package/workspace/matchContentPreview.d.ts +21 -0
  413. package/workspace/matchContentPreview.d.ts.map +1 -0
  414. package/workspace/matchContentPreview.js +36 -0
  415. package/workspace/matchContentPreview.js.map +1 -0
  416. package/workspace/matchWorkspaceFiles.d.ts +30 -0
  417. package/workspace/matchWorkspaceFiles.d.ts.map +1 -0
  418. package/workspace/matchWorkspaceFiles.js +58 -0
  419. package/workspace/matchWorkspaceFiles.js.map +1 -0
  420. package/workspace/resolveWorkspaceFileSelection.d.ts +19 -0
  421. package/workspace/resolveWorkspaceFileSelection.d.ts.map +1 -0
  422. package/workspace/resolveWorkspaceFileSelection.js +115 -0
  423. package/workspace/resolveWorkspaceFileSelection.js.map +1 -0
  424. package/workspace/useWorkspaceContentSearch.d.ts +69 -0
  425. package/workspace/useWorkspaceContentSearch.d.ts.map +1 -0
  426. package/workspace/useWorkspaceContentSearch.js +154 -0
  427. package/workspace/useWorkspaceContentSearch.js.map +1 -0
  428. package/workspace/useWorkspaceFileContent.d.ts +73 -0
  429. package/workspace/useWorkspaceFileContent.d.ts.map +1 -0
  430. package/workspace/useWorkspaceFileContent.js +57 -0
  431. package/workspace/useWorkspaceFileContent.js.map +1 -0
  432. package/workspace/useWorkspaceFileSearch.d.ts +61 -0
  433. package/workspace/useWorkspaceFileSearch.d.ts.map +1 -0
  434. package/workspace/useWorkspaceFileSearch.js +119 -0
  435. package/workspace/useWorkspaceFileSearch.js.map +1 -0
  436. package/workspace/useWorkspaceFiles.d.ts +13 -5
  437. package/workspace/useWorkspaceFiles.d.ts.map +1 -1
  438. package/workspace/useWorkspaceFiles.js +18 -19
  439. package/workspace/useWorkspaceFiles.js.map +1 -1
  440. package/workspace/workspaceListingCache.d.ts +47 -0
  441. package/workspace/workspaceListingCache.d.ts.map +1 -0
  442. package/workspace/workspaceListingCache.js +55 -0
  443. package/workspace/workspaceListingCache.js.map +1 -0
  444. package/session/inspector/ArtifactsTab.d.ts.map +0 -1
  445. package/session/inspector/ArtifactsTab.js.map +0 -1
  446. package/session/inspector/ChangesTab.d.ts.map +0 -1
  447. package/session/inspector/ChangesTab.js.map +0 -1
  448. package/session/inspector/InspectTab.d.ts.map +0 -1
  449. package/session/inspector/InspectTab.js.map +0 -1
  450. package/session/inspector/SessionInspector.d.ts +0 -64
  451. package/session/inspector/SessionInspector.d.ts.map +0 -1
  452. package/session/inspector/SessionInspector.js +0 -53
  453. package/session/inspector/SessionInspector.js.map +0 -1
  454. package/session/inspector/SetupTab.d.ts.map +0 -1
  455. package/session/inspector/SetupTab.js.map +0 -1
  456. package/session/inspector/UsageTab.d.ts.map +0 -1
  457. package/session/inspector/UsageTab.js.map +0 -1
  458. package/session/inspector/WorkspaceTab.d.ts +0 -35
  459. package/session/inspector/WorkspaceTab.d.ts.map +0 -1
  460. package/session/inspector/WorkspaceTab.js +0 -75
  461. package/session/inspector/WorkspaceTab.js.map +0 -1
  462. package/session/inspector/index.d.ts.map +0 -1
  463. package/session/inspector/index.js.map +0 -1
  464. package/session/inspector/useSessionInspector.d.ts +0 -49
  465. package/session/inspector/useSessionInspector.d.ts.map +0 -1
  466. package/session/inspector/useSessionInspector.js +0 -122
  467. package/session/inspector/useSessionInspector.js.map +0 -1
  468. package/src/session/inspector/SessionInspector.tsx +0 -162
  469. package/src/session/inspector/WorkspaceTab.tsx +0 -245
  470. package/src/session/inspector/__tests__/useSessionInspector.test.ts +0 -251
  471. package/src/session/inspector/useSessionInspector.ts +0 -178
  472. package/src/workspace/WorkspaceEntryFiles.tsx +0 -196
  473. package/workflow/motion-preference.d.ts.map +0 -1
  474. package/workflow/motion-preference.js.map +0 -1
  475. package/workspace/WorkspaceEntryFiles.d.ts +0 -22
  476. package/workspace/WorkspaceEntryFiles.d.ts.map +0 -1
  477. package/workspace/WorkspaceEntryFiles.js +0 -58
  478. package/workspace/WorkspaceEntryFiles.js.map +0 -1
  479. /package/session/{inspector → facets}/InspectTab.d.ts +0 -0
  480. /package/session/{inspector → facets}/InspectTab.js +0 -0
  481. /package/src/{workflow → internal}/__tests__/motion-preference.test.ts +0 -0
  482. /package/src/session/{inspector → facets}/InspectTab.tsx +0 -0
  483. /package/src/session/{inspector → facets}/__tests__/ChangesTab.test.tsx +0 -0
@@ -1,10 +1,11 @@
1
1
  "use client";
2
2
 
3
- import { memo, useState } from "react";
3
+ import { memo, useState, type ReactNode } from "react";
4
4
  import { cn } from "@stigmer/theme";
5
5
  import type { ExecutionArtifact } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/artifact_pb";
6
6
  import { ArtifactPreviewModal } from "./ArtifactPreviewModal.js";
7
7
  import { formatArtifactSize } from "./artifact-utils.js";
8
+ import { useArtifactCopy } from "./useArtifactCopy.js";
8
9
  import { useArtifactDownload } from "./useArtifactDownload.js";
9
10
  import { useBuildFromPlanHotkey } from "./use-build-from-plan-hotkey.js";
10
11
 
@@ -15,41 +16,56 @@ export interface PlanArtifactCardProps {
15
16
  /** The published `plan.md` artifact (from `findPlanArtifact`). */
16
17
  readonly artifact: ExecutionArtifact;
17
18
  /**
18
- * Organization slug. Required for the "Open full" modal (the shared
19
+ * The plan's title (its leading `# H1`). The card is the plan's compact
20
+ * stand-in in the thread, so the title is what makes it recognizable.
21
+ * Falls back to "Plan" when omitted.
22
+ */
23
+ readonly title?: string;
24
+ /**
25
+ * Organization slug. Required for the open-in-modal fallback (the shared
19
26
  * {@link ArtifactPreviewModal} uses it for its detection/apply pipeline and
20
- * to fetch the content). When omitted, "Open full" is hidden — the prominent
21
- * "Build from plan" action and "Download" remain.
27
+ * to fetch the content). When omitted, that fallback is hidden — the
28
+ * prominent "Build" action and the download icon remain.
22
29
  */
23
30
  readonly org?: string;
24
- /** Called when the user clicks "Build from plan". Hidden when omitted. */
31
+ /** Called when the user clicks "Build". Hidden when omitted. */
25
32
  readonly onImplement?: () => void;
33
+ /**
34
+ * Opens the plan in the session panel's plan document tab — the
35
+ * side-by-side review/refine surface. When provided it REPLACES the
36
+ * modal-based open fallback (one review affordance, not two). When
37
+ * omitted (hosts without a session panel) the same "Open plan" icon
38
+ * opens the preview modal instead.
39
+ */
40
+ readonly onOpenPlan?: () => void;
26
41
  /** Disables the primary CTA (e.g., while an execution is active). */
27
42
  readonly disabled?: boolean;
43
+ /** When true, the primary button reads "Starting build…" (upload in flight). */
44
+ readonly buildPending?: boolean;
28
45
  /** Additional CSS classes for the root element. */
29
46
  readonly className?: string;
30
47
  }
31
48
 
32
49
  /**
33
- * Action surface for a plan that a completed Plan-mode execution published as a
34
- * `plan.md` artifact.
50
+ * The compact plan card a completed Plan turn's sole representation in the
51
+ * thread. The plan document itself lives in the session panel's plan tab
52
+ * (`PlanEditor`), Cursor-style: chat carries a recognizable, actionable card;
53
+ * the panel carries the document.
35
54
  *
36
- * It is rendered immediately below the plan message in the thread (which already
37
- * shows the plan as rich markdown the message renderer unwraps a model's
38
- * enclosing markdown fence), so this card deliberately holds **no** plan
39
- * content: the message is the document and this is its action bar. Rendering
40
- * the plan a second time here would duplicate the same text the message and the
41
- * "Open full" modal already show.
55
+ * Anatomy: a document-style identity block (plan icon, the plan's title, a
56
+ * `<name> · size` meta line) with the actions trailing open, copy, and
57
+ * download as icon-only secondaries (labelled via `aria-label`/`title`) and
58
+ * one prominent, themeable primary, **Build** so the next step is
59
+ * unmistakable.
42
60
  *
43
- * The hierarchy is the point: one prominent, themeable primary action —
44
- * **Build from plan** with **Open full** and **Download** as subdued
45
- * secondaries, so the next step is unmistakable. A small negative top margin
46
- * pulls the bar against the plan message so the two read as a single
47
- * first-class plan block.
61
+ * Action-label rule (shared with `PlanStreamingCard`, which keeps its
62
+ * labelled "Open plan"): a lone secondary keeps its text label; a row of
63
+ * secondaries competing with a primary collapses to icons, so the primary
64
+ * carries the card's one visible verb.
48
65
  *
49
- * Kept as its own thread item (not merged into the message) on purpose: merging
50
- * would change the streamed message item's identity at completion and remount
51
- * the just-streamed plan. Adjacent-and-attached gets the unified look with no
52
- * remount.
66
+ * Only the LATEST plan's card carries `onImplement`; a superseded plan's card
67
+ * is review-only (its `onOpenPlan` opens the document read-only), so a stale
68
+ * plan can never be implemented by accident.
53
69
  *
54
70
  * All visual properties flow through `--stgm-*` tokens; the component is
55
71
  * self-contained and embeddable.
@@ -57,67 +73,79 @@ export interface PlanArtifactCardProps {
57
73
  export const PlanArtifactCard = memo(function PlanArtifactCard({
58
74
  executionId,
59
75
  artifact,
76
+ title,
60
77
  org,
61
78
  onImplement,
79
+ onOpenPlan,
62
80
  disabled,
81
+ buildPending,
63
82
  className,
64
83
  }: PlanArtifactCardProps) {
65
84
  const [previewOpen, setPreviewOpen] = useState(false);
66
85
  const handleKeyDown = useBuildFromPlanHotkey(onImplement, disabled);
86
+ const { copy, isCopying, copied } = useArtifactCopy(executionId);
67
87
  const { download, isDownloading } = useArtifactDownload(executionId);
68
88
 
69
89
  return (
70
90
  <div
71
91
  role="region"
72
- aria-label="Plan actions"
92
+ aria-label="Plan"
73
93
  onKeyDown={handleKeyDown}
74
94
  className={cn(
75
- // `-mt-2` tightens the thread's `gap-4` so the bar attaches to the
76
- // plan message above it, reading as one first-class plan block.
77
- "mx-4 -mt-2 flex flex-wrap items-center gap-x-3 gap-y-2 rounded-md",
78
- "border border-border-muted bg-muted-faint px-3 py-2",
95
+ "mx-4 flex flex-wrap items-center gap-x-3 gap-y-2 rounded-lg",
96
+ "border border-border-muted bg-card px-3 py-2.5",
79
97
  className,
80
98
  )}
81
99
  >
82
100
  <PlanIcon />
83
- <span className="text-xs font-medium text-foreground">Plan</span>
84
- <span className="text-xs tabular-nums text-muted-foreground-faint">
85
- {formatArtifactSize(artifact.sizeBytes)}
86
- </span>
101
+ <div className="min-w-0 flex-1 basis-48">
102
+ <div className="truncate text-sm font-medium text-foreground">
103
+ {title ?? "Plan"}
104
+ </div>
105
+ <div className="text-[0.65rem] text-muted-foreground-faint">
106
+ {artifact.name}
107
+ <span aria-hidden="true"> · </span>
108
+ <span className="tabular-nums">
109
+ {formatArtifactSize(artifact.sizeBytes)}
110
+ </span>
111
+ </div>
112
+ </div>
87
113
 
88
- <div className="ml-auto flex flex-wrap items-center gap-x-3 gap-y-1.5">
89
- {org && (
90
- <button
91
- type="button"
92
- onClick={() => setPreviewOpen(true)}
93
- className={cn(
94
- "inline-flex items-center gap-1 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground",
95
- FOCUS_RING,
96
- )}
97
- >
98
- <ExpandIcon />
99
- Open full
100
- </button>
114
+ <div className="ml-auto flex flex-wrap items-center gap-x-1.5 gap-y-1.5">
115
+ {onOpenPlan ? (
116
+ <IconAction
117
+ label="Open plan"
118
+ onClick={onOpenPlan}
119
+ icon={<EyeIcon />}
120
+ />
121
+ ) : (
122
+ org && (
123
+ <IconAction
124
+ label="Open plan"
125
+ onClick={() => setPreviewOpen(true)}
126
+ icon={<EyeIcon />}
127
+ />
128
+ )
101
129
  )}
102
- <button
103
- type="button"
130
+ <IconAction
131
+ label={copied ? "Copied" : isCopying ? "Copying…" : "Copy plan"}
132
+ onClick={() => copy(artifact.storageKey)}
133
+ disabled={isCopying}
134
+ icon={copied ? <CheckIcon /> : <CopyIcon />}
135
+ />
136
+ <IconAction
137
+ label={isDownloading ? "Preparing…" : `Download ${artifact.name}`}
104
138
  onClick={() => download(artifact.storageKey, artifact.name)}
105
139
  disabled={isDownloading}
106
- className={cn(
107
- "inline-flex items-center gap-1 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground disabled:opacity-50",
108
- FOCUS_RING,
109
- )}
110
- >
111
- <DownloadIcon />
112
- {isDownloading ? "Preparing…" : "Download"}
113
- </button>
140
+ icon={<DownloadIcon />}
141
+ />
114
142
  {onImplement && (
115
143
  <button
116
144
  type="button"
117
145
  disabled={disabled}
118
146
  onClick={onImplement}
119
147
  className={cn(
120
- "inline-flex items-center gap-1.5 rounded-md px-3 py-1.5",
148
+ "ml-1.5 inline-flex items-center gap-1.5 rounded-md px-3 py-1.5",
121
149
  "text-xs font-medium transition-colors",
122
150
  "bg-primary text-primary-foreground hover:bg-primary-hover",
123
151
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
@@ -125,13 +153,18 @@ export const PlanArtifactCard = memo(function PlanArtifactCard({
125
153
  )}
126
154
  >
127
155
  <ImplementIcon />
128
- Build from plan
156
+ {buildPending ? "Starting build…" : "Build"}
129
157
  </button>
130
158
  )}
131
159
  </div>
132
160
 
133
- {/* "Open full" reuses the shared artifact preview popup — the single place
134
- that fetches/renders plan content (with Copy + Source/Rendered). */}
161
+ <div role="status" aria-live="polite" aria-atomic="true" className="sr-only">
162
+ {copied && "Plan copied to clipboard"}
163
+ </div>
164
+
165
+ {/* The modal open fallback reuses the shared artifact preview popup —
166
+ the single place that fetches/renders plan content (with Copy +
167
+ Source/Rendered). */}
135
168
  {org && previewOpen && (
136
169
  <ArtifactPreviewModal
137
170
  artifact={artifact}
@@ -150,6 +183,41 @@ export const PlanArtifactCard = memo(function PlanArtifactCard({
150
183
  const FOCUS_RING =
151
184
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:rounded-sm";
152
185
 
186
+ /**
187
+ * An icon-only secondary action. The accessible name doubles as the hover
188
+ * tooltip (native `title` — the codebase's tooltip pattern), and the padded
189
+ * hit area keeps the target comfortable despite the compact glyph.
190
+ */
191
+ function IconAction({
192
+ label,
193
+ onClick,
194
+ icon,
195
+ disabled,
196
+ }: {
197
+ readonly label: string;
198
+ readonly onClick: () => void;
199
+ readonly icon: ReactNode;
200
+ readonly disabled?: boolean;
201
+ }) {
202
+ return (
203
+ <button
204
+ type="button"
205
+ aria-label={label}
206
+ title={label}
207
+ onClick={onClick}
208
+ disabled={disabled}
209
+ className={cn(
210
+ "inline-flex items-center rounded-md p-1.5 text-muted-foreground",
211
+ "transition-colors hover:bg-muted hover:text-foreground",
212
+ "disabled:pointer-events-none disabled:opacity-50",
213
+ FOCUS_RING,
214
+ )}
215
+ >
216
+ {icon}
217
+ </button>
218
+ );
219
+ }
220
+
153
221
  function PlanIcon() {
154
222
  return (
155
223
  <svg
@@ -191,8 +259,8 @@ function ImplementIcon() {
191
259
  function DownloadIcon() {
192
260
  return (
193
261
  <svg
194
- width="10"
195
- height="10"
262
+ width="13"
263
+ height="13"
196
264
  viewBox="0 0 12 12"
197
265
  fill="none"
198
266
  stroke="currentColor"
@@ -209,21 +277,63 @@ function DownloadIcon() {
209
277
  );
210
278
  }
211
279
 
212
- function ExpandIcon() {
280
+ function CopyIcon() {
281
+ return (
282
+ <svg
283
+ width="13"
284
+ height="13"
285
+ viewBox="0 0 12 12"
286
+ fill="none"
287
+ stroke="currentColor"
288
+ strokeWidth="1.2"
289
+ strokeLinecap="round"
290
+ strokeLinejoin="round"
291
+ className="shrink-0"
292
+ aria-hidden="true"
293
+ >
294
+ <rect x="4" y="4" width="6.5" height="6.5" rx="1" />
295
+ <path d="M8 4V2.5C8 1.95 7.55 1.5 7 1.5H2.5C1.95 1.5 1.5 1.95 1.5 2.5V7C1.5 7.55 1.95 8 2.5 8H4" />
296
+ </svg>
297
+ );
298
+ }
299
+
300
+ /** A check glyph — transient confirmation that the copy succeeded. */
301
+ function CheckIcon() {
213
302
  return (
214
303
  <svg
215
- width="10"
216
- height="10"
304
+ width="13"
305
+ height="13"
217
306
  viewBox="0 0 12 12"
218
307
  fill="none"
219
308
  stroke="currentColor"
220
309
  strokeWidth="1.5"
221
310
  strokeLinecap="round"
222
311
  strokeLinejoin="round"
312
+ className="shrink-0 text-success"
313
+ aria-hidden="true"
314
+ >
315
+ <path d="M2 6.5L4.5 9L10 3" />
316
+ </svg>
317
+ );
318
+ }
319
+
320
+ /** An eye glyph — "view/open the plan to read it". */
321
+ function EyeIcon() {
322
+ return (
323
+ <svg
324
+ width="13"
325
+ height="13"
326
+ viewBox="0 0 16 16"
327
+ fill="none"
328
+ stroke="currentColor"
329
+ strokeWidth="1.5"
330
+ strokeLinecap="round"
331
+ strokeLinejoin="round"
223
332
  className="shrink-0"
224
333
  aria-hidden="true"
225
334
  >
226
- <path d="M7 1.5h3.5V5M10.5 1.5L6.5 5.5M5 10.5H1.5V7M1.5 10.5l4-4" />
335
+ <path d="M1.5 8S4 3.5 8 3.5s6.5 4.5 6.5 4.5-2.5 4.5-6.5 4.5S1.5 8 1.5 8Z" />
336
+ <circle cx="8" cy="8" r="1.75" />
227
337
  </svg>
228
338
  );
229
339
  }
@@ -6,7 +6,7 @@ import { useBuildFromPlanHotkey } from "./use-build-from-plan-hotkey.js";
6
6
 
7
7
  /** Props for {@link PlanCompletionCard}. */
8
8
  export interface PlanCompletionCardProps {
9
- /** Called when the user clicks the "Build from plan" button. */
9
+ /** Called when the user clicks the "Build" button. */
10
10
  readonly onImplement?: () => void;
11
11
  /** Disables the CTA button (e.g., while an execution is active). */
12
12
  readonly disabled?: boolean;
@@ -20,9 +20,9 @@ export interface PlanCompletionCardProps {
20
20
  * a plan whose upload failed). When a plan artifact exists, the richer
21
21
  * `PlanArtifactCard` is shown instead.
22
22
  *
23
- * Mirrors `PlanArtifactCard`'s hierarchy — one prominent, themeable "Build from
24
- * plan" primary action with the same card-scoped `Cmd/Ctrl+Enter` accelerator —
25
- * so the two cards feel like the same affordance. The consumer wires the action
23
+ * Mirrors `PlanArtifactCard`'s hierarchy — one prominent, themeable "Build"
24
+ * primary action with the same card-scoped `Cmd/Ctrl+Enter` accelerator — so
25
+ * the two cards feel like the same affordance. The consumer wires the action
26
26
  * to switch the interaction mode to Agent and submit the implement turn.
27
27
  *
28
28
  * Renders nothing when `onImplement` is not provided, so the card is fully
@@ -67,7 +67,7 @@ export const PlanCompletionCard = memo(function PlanCompletionCard({
67
67
  )}
68
68
  >
69
69
  <ImplementIcon />
70
- Build from plan
70
+ Build
71
71
  </button>
72
72
  </div>
73
73
  );
@@ -0,0 +1,96 @@
1
+ "use client";
2
+
3
+ import { memo, useMemo } from "react";
4
+ import { Streamdown } from "streamdown";
5
+ import { cn } from "@stigmer/theme";
6
+ import {
7
+ PLAN_DOCUMENT_MARKDOWN_COMPONENTS,
8
+ extractLeadingH1,
9
+ unwrapEnclosingMarkdownFence,
10
+ } from "../internal/markdown-components.js";
11
+
12
+ /** Props for {@link PlanDocumentMessage}. */
13
+ export interface PlanDocumentMessageProps {
14
+ /** The plan message's markdown content (the agent's final Plan-mode reply). */
15
+ readonly content: string;
16
+ /** Additional CSS class names for the root container. */
17
+ readonly className?: string;
18
+ }
19
+
20
+ /**
21
+ * Renders a Plan-mode turn's plan as a first-class document instead of a chat
22
+ * bubble: a bordered card with a title header (the plan's leading `# H1`,
23
+ * lifted out of the prose) and document-grade typography
24
+ * ({@link PLAN_DOCUMENT_MARKDOWN_COMPONENTS}).
25
+ *
26
+ * This is the thread's NO-ARTIFACT fallback: a completed Plan turn that never
27
+ * published `plan.md` (older executions, a failed upload) keeps its plan
28
+ * inline via this component — the message is the only copy of the plan, so it
29
+ * must stay readable in place. A turn that DID publish the artifact collapses
30
+ * its plan message into the compact `PlanArtifactCard` instead, and the
31
+ * document renders in the session panel's plan tab (`PlanEditor`) with the
32
+ * same typography.
33
+ *
34
+ * Fence handling is plan-scoped: a plan wrapped in a whole-body fence is
35
+ * unwrapped even when the fence carries no language tag (`allowBareFence`) —
36
+ * a Plan turn's output is a markdown document by contract, so an enclosing
37
+ * bare fence is wrapping, not code. Render-time only; the transcript and the
38
+ * published artifact stay byte-faithful.
39
+ *
40
+ * Purely presentational — no data fetching, no state.
41
+ * All visual properties flow through `--stgm-*` tokens.
42
+ */
43
+ export const PlanDocumentMessage = memo(function PlanDocumentMessage({
44
+ content,
45
+ className,
46
+ }: PlanDocumentMessageProps) {
47
+ const { title, body } = useMemo(
48
+ () => extractLeadingH1(unwrapEnclosingMarkdownFence(content, true)),
49
+ [content],
50
+ );
51
+
52
+ return (
53
+ <div
54
+ role="article"
55
+ aria-label="Plan document"
56
+ className={cn("mx-4", className)}
57
+ >
58
+ <div className="overflow-hidden rounded-lg border border-border-muted bg-card">
59
+ <header className="flex items-center gap-2 border-b border-border-muted bg-muted-faint px-4 py-2.5">
60
+ <PlanDocIcon />
61
+ <span className="min-w-0 flex-1 truncate text-sm font-semibold text-foreground">
62
+ {title ?? "Plan"}
63
+ </span>
64
+ </header>
65
+ <div className="stgm-prose px-4 py-4">
66
+ <Streamdown
67
+ components={PLAN_DOCUMENT_MARKDOWN_COMPONENTS}
68
+ isAnimating={false}
69
+ >
70
+ {body}
71
+ </Streamdown>
72
+ </div>
73
+ </div>
74
+ </div>
75
+ );
76
+ });
77
+
78
+ function PlanDocIcon() {
79
+ return (
80
+ <svg
81
+ width="14"
82
+ height="14"
83
+ viewBox="0 0 16 16"
84
+ fill="none"
85
+ stroke="currentColor"
86
+ strokeWidth="1.5"
87
+ strokeLinecap="round"
88
+ strokeLinejoin="round"
89
+ className="shrink-0 text-muted-foreground"
90
+ aria-hidden="true"
91
+ >
92
+ <path d="M3 4h10M3 8h7M3 12h8" />
93
+ <path d="M12.5 10.5l1.5 1.5-1.5 1.5" />
94
+ </svg>
95
+ );
96
+ }
@@ -0,0 +1,141 @@
1
+ "use client";
2
+
3
+ import { memo } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ import { formatArtifactSize } from "./artifact-utils.js";
6
+
7
+ /** Props for {@link PlanStreamingCard}. */
8
+ export interface PlanStreamingCardProps {
9
+ /**
10
+ * The plan's title (its leading `# H1`), streaming in live. Falls back to
11
+ * "Writing plan…" until the title has arrived.
12
+ */
13
+ readonly title?: string;
14
+ /**
15
+ * Live size of the plan text streamed so far. An approximation (UTF-16
16
+ * length, not encoded bytes) — it exists to show growth while the agent
17
+ * writes, not to state the artifact's final size.
18
+ */
19
+ readonly sizeBytes: number;
20
+ /**
21
+ * Opens the panel's plan document tab, where the plan is rendering live.
22
+ * Always provided in practice: the thread only collapses a streaming plan
23
+ * behind this card when the host wired `onOpenPlan` (see `MessageThread`'s
24
+ * `collapseStreamingPlan` gate) — without a document surface there is
25
+ * nothing for the card to open, and the plan streams inline instead.
26
+ */
27
+ readonly onOpenPlan?: () => void;
28
+ /** Additional CSS classes for the root element. */
29
+ readonly className?: string;
30
+ }
31
+
32
+ /**
33
+ * The live counterpart of {@link PlanArtifactCard} — a streaming Plan turn's
34
+ * compact stand-in in the thread while the plan document renders live in the
35
+ * session panel's plan tab. Same anatomy as the completed card (icon, title,
36
+ * a `Writing… · size` meta, trailing actions) so the completion handoff reads
37
+ * as the same card settling, not a new element appearing.
38
+ *
39
+ * The meta line deliberately omits a filename: the artifact's name is derived
40
+ * from the plan's title, which is still streaming in, so a name shown here
41
+ * would change under the user when the plan settles. The completed card
42
+ * introduces the final `<slug>_<id>.plan.md` name once it exists.
43
+ *
44
+ * Deliberately action-light: "Open plan" is the only affordance. Download and
45
+ * Build require the published artifact, which does not exist until the turn
46
+ * completes — at which point `buildThreadItems` swaps this item for the
47
+ * `plan-completion` item under the same list key.
48
+ *
49
+ * The pulsing icon is the progress affordance: a CSS animation inside `.stgm`,
50
+ * covered by the stylesheet's global `prefers-reduced-motion` rule (DD-015),
51
+ * and safe under virtualization (no `@starting-style`).
52
+ *
53
+ * All visual properties flow through `--stgm-*` tokens; the component is
54
+ * self-contained and embeddable.
55
+ */
56
+ export const PlanStreamingCard = memo(function PlanStreamingCard({
57
+ title,
58
+ sizeBytes,
59
+ onOpenPlan,
60
+ className,
61
+ }: PlanStreamingCardProps) {
62
+ return (
63
+ <div
64
+ role="region"
65
+ aria-label="Plan being written"
66
+ aria-busy="true"
67
+ className={cn(
68
+ "mx-4 flex flex-wrap items-center gap-x-3 gap-y-2 rounded-lg",
69
+ "border border-border-muted bg-card px-3 py-2.5",
70
+ className,
71
+ )}
72
+ >
73
+ <PlanIcon className="animate-pulse" />
74
+ <div className="min-w-0 flex-1 basis-48">
75
+ <div className="truncate text-sm font-medium text-foreground">
76
+ {title ?? "Writing plan…"}
77
+ </div>
78
+ <div className="text-[0.65rem] text-muted-foreground-faint">
79
+ <span role="status">Writing…</span>
80
+ <span aria-hidden="true"> · </span>
81
+ <span className="tabular-nums">{formatArtifactSize(sizeBytes)}</span>
82
+ </div>
83
+ </div>
84
+
85
+ {onOpenPlan && (
86
+ <button
87
+ type="button"
88
+ onClick={onOpenPlan}
89
+ className={cn(
90
+ "ml-auto inline-flex items-center gap-1 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground",
91
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:rounded-sm",
92
+ )}
93
+ >
94
+ <EyeIcon />
95
+ Open plan
96
+ </button>
97
+ )}
98
+ </div>
99
+ );
100
+ });
101
+
102
+ function PlanIcon({ className }: { readonly className?: string }) {
103
+ return (
104
+ <svg
105
+ width="16"
106
+ height="16"
107
+ viewBox="0 0 16 16"
108
+ fill="none"
109
+ stroke="currentColor"
110
+ strokeWidth="1.5"
111
+ strokeLinecap="round"
112
+ strokeLinejoin="round"
113
+ className={cn("shrink-0 text-muted-foreground-faint", className)}
114
+ aria-hidden="true"
115
+ >
116
+ <path d="M3 4h10M3 8h7M3 12h8" />
117
+ <path d="M12.5 10.5l1.5 1.5-1.5 1.5" />
118
+ </svg>
119
+ );
120
+ }
121
+
122
+ /** An eye glyph — "view/open the plan to read it" (matches PlanArtifactCard). */
123
+ function EyeIcon() {
124
+ return (
125
+ <svg
126
+ width="11"
127
+ height="11"
128
+ viewBox="0 0 16 16"
129
+ fill="none"
130
+ stroke="currentColor"
131
+ strokeWidth="1.5"
132
+ strokeLinecap="round"
133
+ strokeLinejoin="round"
134
+ className="shrink-0"
135
+ aria-hidden="true"
136
+ >
137
+ <path d="M1.5 8S4 3.5 8 3.5s6.5 4.5 6.5 4.5-2.5 4.5-6.5 4.5S1.5 8 1.5 8Z" />
138
+ <circle cx="8" cy="8" r="1.75" />
139
+ </svg>
140
+ );
141
+ }