@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
@@ -0,0 +1,193 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState, } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ import { FileChangeType } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
6
+ import { ArtifactContentRenderer } from "../execution/ArtifactContentRenderer.js";
7
+ import { FileChangeDiff } from "../execution/FileChangesView.js";
8
+ import { useWorkspaceFileContent } from "./useWorkspaceFileContent.js";
9
+ /** Line-skeleton widths, mirroring `FileContentStateView` in `ArtifactPreviewModal`. */
10
+ const SKELETON_LINE_WIDTHS = [85, 72, 90, 65, 78, 88, 70, 82];
11
+ /**
12
+ * Read-only viewer for a single workspace file.
13
+ *
14
+ * A thin shell (no new rendering): it resolves the open file, drives
15
+ * {@link useWorkspaceFileContent}, and — for displayable text — delegates to
16
+ * the shared {@link ArtifactContentRenderer} (markdown / YAML / JSON /
17
+ * line-numbered text). Its state body deliberately mirrors
18
+ * `FileContentStateView` in `ArtifactPreviewModal` (same skeleton, error, and
19
+ * delegation), extended with the three states an execution artifact never
20
+ * has — binary, too-large, and unsupported-substrate. The two are **not**
21
+ * merged into one shared component: their surrounding chrome (an artifact's
22
+ * copy/download/apply bar vs. this viewer's header) differs enough that a
23
+ * shared shell would need context-flag props. Keep them as sibling shells that
24
+ * share the one renderer.
25
+ *
26
+ * Framework-agnostic and themed via `--stgm-*` tokens (DD-004/DD-005): a
27
+ * platform builder can mount it directly given a `reader` and a selection.
28
+ *
29
+ * @example
30
+ * ```tsx
31
+ * <FileViewer
32
+ * selectedFile={{ entryId: entry.id, path: "src/index.ts" }}
33
+ * entries={workspace.entries}
34
+ * reader={workspaceFileReader}
35
+ * onClose={() => setSelected(null)}
36
+ * />
37
+ * ```
38
+ */
39
+ export const FileViewer = forwardRef(function FileViewer({ selectedFile, entries, reader, change, reveal, onClose, showHeader = true, className }, ref) {
40
+ const entry = entries.find((e) => e.id === selectedFile.entryId) ?? null;
41
+ const path = selectedFile.path;
42
+ // The hook is called unconditionally — a missing entry passes `null` and the
43
+ // hook stays idle, so hook order is stable across the not-found branch.
44
+ const { content, isLoading, error, isUnsupported, refetch } = useWorkspaceFileContent({ entry, path, reader });
45
+ useImperativeHandle(ref, () => ({ refresh: refetch }), [refetch]);
46
+ // View mode is meaningful only for a changed file. A deleted file has no live
47
+ // bytes to browse, and browsing needs a reader, so the live "File" view is
48
+ // gated on both; otherwise a changed file shows the diff alone (no lone
49
+ // control). The default is the authoritative diff (DD-06). The mount site
50
+ // remounts the viewer per file (`key`), so this initializes correctly for
51
+ // each opened file without deriving during render.
52
+ const canBrowseLive = reader !== undefined && change?.changeType !== FileChangeType.DELETE;
53
+ const showViewToggle = change !== undefined && canBrowseLive;
54
+ // A reveal (jump-to-line) opens in File view even for a changed file — the
55
+ // line number refers to current source, not the diff (DR-1). Absent a reveal,
56
+ // a changed file still defaults to the authoritative diff (DD-06).
57
+ const [viewMode, setViewMode] = useState(reveal ? "file" : change !== undefined ? "diff" : "file");
58
+ // A new reveal on an already-mounted viewer (a second search hit in the same
59
+ // file, so no remount) must return to File view to honor the line.
60
+ useEffect(() => {
61
+ if (reveal)
62
+ setViewMode("file");
63
+ // Keyed on the reveal nonce: only a fresh jump-to-line request re-forces
64
+ // File view, so a manual switch to Diff afterward sticks.
65
+ }, [reveal?.nonce]);
66
+ const effectiveView = change
67
+ ? canBrowseLive
68
+ ? viewMode
69
+ : "diff"
70
+ : "file";
71
+ const handleKeyDown = useCallback((e) => {
72
+ if (e.key === "Escape" && onClose) {
73
+ e.stopPropagation();
74
+ onClose();
75
+ }
76
+ }, [onClose]);
77
+ const lastSlash = path.lastIndexOf("/");
78
+ const basename = lastSlash >= 0 ? path.slice(lastSlash + 1) : path;
79
+ const dir = lastSlash >= 0 ? path.slice(0, lastSlash) : "";
80
+ // The owning entry is gone (removed while its file was open).
81
+ if (!entry) {
82
+ return (_jsxs("div", { role: "region", "aria-label": "File viewer", className: cn("flex h-full flex-col", className), onKeyDown: handleKeyDown, children: [showHeader && (_jsx(ViewerHeader, { basename: basename, dir: dir, onRefresh: undefined, onClose: onClose })), _jsx("div", { className: "flex flex-1 items-center justify-center p-8 text-center text-xs text-muted-foreground", children: "This file is no longer in the workspace." })] }));
83
+ }
84
+ return (_jsxs("div", { role: "region", "aria-label": "File viewer",
85
+ // Focusable (programmatically / on click) so the Escape-to-close handler
86
+ // fires even when the read-only body holds no natively focusable element.
87
+ tabIndex: -1, className: cn("flex h-full flex-col focus:outline-none", className), onKeyDown: handleKeyDown, children: [showHeader && (_jsx(ViewerHeader, { basename: basename, dir: dir, onRefresh: effectiveView === "file" && !isUnsupported ? refetch : undefined, onClose: onClose })), showViewToggle && (_jsx(ViewerModeToggle, { value: viewMode, onChange: setViewMode })), _jsx("div", { className: "min-h-0 flex-1 overflow-y-auto", children: effectiveView === "diff" && change ? (_jsx("div", { className: "p-3", children: _jsx(FileChangeDiff, { change: change, showFileName: false, showStats: true }) })) : (_jsxs(_Fragment, { children: [change && (_jsx("p", { className: "border-b border-border-muted px-4 py-1.5 text-[0.65rem] text-muted-foreground", children: "Live \u2014 may differ from the reviewed change." })), _jsx(FileViewerBody, { basename: basename, content: content, isLoading: isLoading, isUnsupported: isUnsupported, error: error, onRetry: refetch, reveal: reveal })] })) })] }));
88
+ });
89
+ // ---------------------------------------------------------------------------
90
+ // View toggle — Diff vs live File
91
+ // ---------------------------------------------------------------------------
92
+ /**
93
+ * Segmented control for a changed file's two views: the authoritative reviewed
94
+ * **Diff** and the live **File**. A mutually-exclusive choice, so it follows
95
+ * the platform's radiogroup segmented-control pattern (see `library/ScopeToggle`)
96
+ * rather than a tablist — it must not nest a second tablist inside the
97
+ * inspector's own tabs.
98
+ */
99
+ function ViewerModeToggle({ value, onChange, }) {
100
+ const options = [
101
+ { value: "diff", label: "Diff" },
102
+ { value: "file", label: "File" },
103
+ ];
104
+ // Selection follows focus, matching ActivityRail / SearchModeToggle.
105
+ const buttonRefs = useRef([]);
106
+ const selectValue = useCallback((next) => {
107
+ onChange(next);
108
+ buttonRefs.current[next === "diff" ? 0 : 1]?.focus();
109
+ }, [onChange]);
110
+ const handleKeyDown = useCallback((e) => {
111
+ if (e.key === "ArrowRight" || e.key === "ArrowDown") {
112
+ e.preventDefault();
113
+ selectValue("file");
114
+ }
115
+ else if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
116
+ e.preventDefault();
117
+ selectValue("diff");
118
+ }
119
+ }, [selectValue]);
120
+ return (_jsx("div", { className: "border-b border-border px-3 py-1.5", children: _jsx("div", { role: "radiogroup", "aria-label": "File view", className: "inline-flex rounded-md bg-muted p-0.5", children: options.map((option, index) => {
121
+ const isSelected = value === option.value;
122
+ return (_jsx("button", { ref: (el) => {
123
+ buttonRefs.current[index] = el;
124
+ }, type: "button", role: "radio", "aria-checked": isSelected, tabIndex: isSelected ? 0 : -1, onClick: () => onChange(option.value), onKeyDown: handleKeyDown, className: cn("inline-flex cursor-pointer items-center rounded-sm px-2 py-0.5 text-xs font-medium transition-colors", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", isSelected
125
+ ? "bg-background text-foreground shadow-sm"
126
+ : "text-muted-foreground hover:text-foreground"), children: option.label }, option.value));
127
+ }) }) }));
128
+ }
129
+ // ---------------------------------------------------------------------------
130
+ // Body — exactly one state, mirroring FileContentStateView + workspace extras
131
+ // ---------------------------------------------------------------------------
132
+ function FileViewerBody({ basename, content, isLoading, isUnsupported, error, onRetry, reveal, }) {
133
+ // Unsupported comes first: a missing reader means there is nothing to load.
134
+ if (isUnsupported) {
135
+ return (_jsx(MessageState, { children: "Preview isn\u2019t available for this file here." }));
136
+ }
137
+ if (isLoading) {
138
+ return (_jsx("div", { role: "status", className: "space-y-2 p-4", "aria-busy": "true", "aria-label": "Loading file", children: SKELETON_LINE_WIDTHS.map((width, i) => (_jsx("div", { className: "h-4 animate-pulse rounded bg-muted", style: { width: `${width}%` }, "aria-hidden": "true" }, i))) }));
139
+ }
140
+ if (error) {
141
+ return (_jsxs("div", { className: "flex flex-col items-center justify-center gap-2 p-8 text-center", children: [_jsx(ErrorAlertIcon, {}), _jsx("p", { className: "text-sm text-destructive", children: error.message }), _jsx("button", { type: "button", onClick: onRetry, className: "text-xs font-medium text-foreground underline underline-offset-2 hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:rounded-sm", children: "Retry" })] }));
142
+ }
143
+ if (!content) {
144
+ // Not loading, not unsupported, no error, yet no content — defensive.
145
+ return _jsx(MessageState, { children: "Content not available for preview." });
146
+ }
147
+ if (content.isBinary) {
148
+ return (_jsxs(MessageState, { children: ["Binary file \u2014 not shown", content.size ? ` (${formatBytes(content.size)})` : "", "."] }));
149
+ }
150
+ if (content.text === null && content.truncated) {
151
+ return (_jsxs(MessageState, { children: ["This file is too large to preview", content.size ? ` (${formatBytes(content.size)})` : "", "."] }));
152
+ }
153
+ if (content.text === null) {
154
+ return _jsx(MessageState, { children: "This file can\u2019t be displayed as text." });
155
+ }
156
+ return (_jsx(ArtifactContentRenderer, { content: content.text, fileName: basename, isTruncated: content.truncated, reveal: reveal }));
157
+ }
158
+ // ---------------------------------------------------------------------------
159
+ // Header
160
+ // ---------------------------------------------------------------------------
161
+ function ViewerHeader({ basename, dir, onRefresh, onClose, }) {
162
+ return (_jsxs("div", { className: "flex items-center gap-2 border-b border-border px-3 py-2", children: [_jsx(FileIcon, {}), _jsxs("div", { className: "flex min-w-0 flex-1 items-baseline gap-1.5", children: [_jsx("span", { className: "truncate text-xs font-semibold text-foreground", title: dir ? `${dir}/${basename}` : basename, children: basename }), dir && (_jsx("span", { className: "truncate text-[0.65rem] text-muted-foreground", children: dir }))] }), onRefresh && (_jsx("button", { type: "button", onClick: onRefresh, "aria-label": `Reload ${basename}`, className: "shrink-0 rounded p-0.5 text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", children: _jsx(RefreshIcon, {}) })), onClose && (_jsx("button", { type: "button", onClick: onClose, "aria-label": "Close file viewer", className: "shrink-0 rounded p-0.5 text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", children: _jsx(CloseIcon, {}) }))] }));
163
+ }
164
+ function MessageState({ children }) {
165
+ return (_jsx("div", { className: "flex h-full items-center justify-center p-8 text-center text-xs text-muted-foreground", children: children }));
166
+ }
167
+ // ---------------------------------------------------------------------------
168
+ // Helpers
169
+ // ---------------------------------------------------------------------------
170
+ /** Human-readable byte size for the too-large / binary states. */
171
+ function formatBytes(n) {
172
+ if (n < 1024)
173
+ return `${n} B`;
174
+ if (n < 1024 * 1024)
175
+ return `${(n / 1024).toFixed(1)} KB`;
176
+ return `${(n / (1024 * 1024)).toFixed(1)} MB`;
177
+ }
178
+ // ---------------------------------------------------------------------------
179
+ // Inline SVG icons (SDK independence — no lucide dependency)
180
+ // ---------------------------------------------------------------------------
181
+ function FileIcon() {
182
+ return (_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", className: "shrink-0 text-muted-foreground", "aria-hidden": "true", children: [_jsx("path", { d: "M9.5 1.5H5C4.17 1.5 3.5 2.17 3.5 3V13C3.5 13.83 4.17 14.5 5 14.5H11C11.83 14.5 12.5 13.83 12.5 13V4.5L9.5 1.5Z" }), _jsx("path", { d: "M9.5 1.5V4.5H12.5" })] }));
183
+ }
184
+ function CloseIcon() {
185
+ return (_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("path", { d: "M3 3L11 11" }), _jsx("path", { d: "M11 3L3 11" })] }));
186
+ }
187
+ function RefreshIcon() {
188
+ return (_jsxs("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("path", { d: "M1.5 6a4.5 4.5 0 017.794-3.073M10.5 6a4.5 4.5 0 01-7.794 3.073" }), _jsx("path", { d: "M9.5 1v2.5H7M2.5 11V8.5H5" })] }));
189
+ }
190
+ function ErrorAlertIcon() {
191
+ return (_jsxs("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", className: "text-destructive", "aria-hidden": "true", children: [_jsx("circle", { cx: "8", cy: "8", r: "6.5" }), _jsx("path", { d: "M8 5.5V8.5" }), _jsx("circle", { cx: "8", cy: "11", r: "0.5", fill: "currentColor", stroke: "none" })] }));
192
+ }
193
+ //# sourceMappingURL=FileViewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileViewer.js","sourceRoot":"","sources":["../../src/workspace/FileViewer.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { WorkspaceEntry } from "./useWorkspaceEntries.js";
2
+ import type { WorkspaceContentSearcher } from "./WorkspaceContentSearcher.js";
3
+ import type { OpenFileOptions } from "../internal/store/index.js";
4
+ import type { SelectedWorkspaceFile } from "../internal/store/workspace-file-selection-store.js";
5
+ /** Props for {@link WorkspaceContentSearch}. */
6
+ export interface WorkspaceContentSearchProps {
7
+ /** All workspace entries to search across. */
8
+ readonly entries: readonly WorkspaceEntry[];
9
+ /** Platform-injected content searcher. `undefined` → content search is unavailable. */
10
+ readonly searcher: WorkspaceContentSearcher | undefined;
11
+ /**
12
+ * Opens a result's file in the viewer, jumping to the matched line. The
13
+ * `options.line` carries the hit's 1-based line so the viewer scrolls to and
14
+ * highlights it (DR-1/DR-2).
15
+ */
16
+ readonly onOpenFile: (entryId: string, path: string, options?: OpenFileOptions) => void;
17
+ /** The file currently open in the viewer, highlighted in the results. */
18
+ readonly selectedFile?: SelectedWorkspaceFile | null;
19
+ /** Additional CSS classes for the root element. */
20
+ readonly className?: string;
21
+ }
22
+ /**
23
+ * Workspace-wide content (text) search surface.
24
+ *
25
+ * Greps file contents across every workspace entry (via
26
+ * {@link useWorkspaceContentSearch}) and opens a hit's file in the viewer
27
+ * through `onOpenFile` — the same seam a file-tree click and filename search
28
+ * use. Results are a VS Code-style `file → line` layout: each matched file is a
29
+ * header, each hit a line row with a line-number gutter and a highlighted
30
+ * preview. Filename search lives in the sibling {@link WorkspaceFileSearch}; a
31
+ * `Name | Text` toggle in the surface switches between them (DD-09).
32
+ *
33
+ * Keyboard/a11y mirrors the filename sibling (and `McpServerPicker`): the input
34
+ * is a `role="combobox"` driving `aria-activedescendant`; results are a
35
+ * `role="listbox"` of `role="option"` line rows; ArrowUp/Down move a virtual
36
+ * focus over the flat line-hit index (across files and entries) with Enter to
37
+ * open — focus stays in the input. All visual properties flow through `--stgm-*`
38
+ * tokens (DD-005).
39
+ */
40
+ export declare function WorkspaceContentSearch({ entries, searcher, onOpenFile, selectedFile, className, }: WorkspaceContentSearchProps): import("react/jsx-runtime").JSX.Element;
41
+ //# sourceMappingURL=WorkspaceContentSearch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkspaceContentSearch.d.ts","sourceRoot":"","sources":["../../src/workspace/WorkspaceContentSearch.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAEV,wBAAwB,EACzB,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qDAAqD,CAAC;AAgBjG,gDAAgD;AAChD,MAAM,WAAW,2BAA2B;IAC1C,8CAA8C;IAC9C,QAAQ,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IAC5C,uFAAuF;IACvF,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,GAAG,SAAS,CAAC;IACxD;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,CACnB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,eAAe,KACtB,IAAI,CAAC;IACV,yEAAyE;IACzE,QAAQ,CAAC,YAAY,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACrD,mDAAmD;IACnD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAQD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,OAAO,EACP,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,SAAS,GACV,EAAE,2BAA2B,2CA4K7B"}
@@ -0,0 +1,216 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useCallback, useEffect, useId, useMemo, useRef, useState, } from "react";
4
+ import { cn } from "@stigmer/theme";
5
+ import { useWorkspaceContentSearch, } from "./useWorkspaceContentSearch.js";
6
+ import { findHighlightRanges } from "./matchContentPreview.js";
7
+ /** Cap on rendered line rows — keeps the DOM bounded on huge result sets. */
8
+ const MAX_RESULTS = 200;
9
+ /**
10
+ * Minimum query length before searching. Kept in sync with the hook by being
11
+ * passed in explicitly, and reused for the sub-min-length hint copy.
12
+ */
13
+ const MIN_QUERY_LENGTH = 2;
14
+ /**
15
+ * Workspace-wide content (text) search surface.
16
+ *
17
+ * Greps file contents across every workspace entry (via
18
+ * {@link useWorkspaceContentSearch}) and opens a hit's file in the viewer
19
+ * through `onOpenFile` — the same seam a file-tree click and filename search
20
+ * use. Results are a VS Code-style `file → line` layout: each matched file is a
21
+ * header, each hit a line row with a line-number gutter and a highlighted
22
+ * preview. Filename search lives in the sibling {@link WorkspaceFileSearch}; a
23
+ * `Name | Text` toggle in the surface switches between them (DD-09).
24
+ *
25
+ * Keyboard/a11y mirrors the filename sibling (and `McpServerPicker`): the input
26
+ * is a `role="combobox"` driving `aria-activedescendant`; results are a
27
+ * `role="listbox"` of `role="option"` line rows; ArrowUp/Down move a virtual
28
+ * focus over the flat line-hit index (across files and entries) with Enter to
29
+ * open — focus stays in the input. All visual properties flow through `--stgm-*`
30
+ * tokens (DD-005).
31
+ */
32
+ export function WorkspaceContentSearch({ entries, searcher, onOpenFile, selectedFile, className, }) {
33
+ const [query, setQuery] = useState("");
34
+ const [focusIndex, setFocusIndex] = useState(-1);
35
+ const inputRef = useRef(null);
36
+ const listboxId = useId();
37
+ const optionId = useCallback((index) => `${listboxId}-opt-${index}`, [listboxId]);
38
+ const { groups, totalMatches, isLoading, isRefetching, isUnsupported } = useWorkspaceContentSearch({
39
+ entries,
40
+ searcher,
41
+ query,
42
+ minLength: MIN_QUERY_LENGTH,
43
+ });
44
+ // Flat, capped view of every rendered line hit — the index space the keyboard
45
+ // and `aria-activedescendant` share with the grouped render below.
46
+ const flatResults = useMemo(() => {
47
+ const flat = [];
48
+ for (const group of groups) {
49
+ for (const match of group.matches) {
50
+ if (flat.length >= MAX_RESULTS)
51
+ return flat;
52
+ flat.push({ entryId: group.entry.id, match });
53
+ }
54
+ }
55
+ return flat;
56
+ }, [groups]);
57
+ // A new query invalidates the previous virtual focus.
58
+ useEffect(() => {
59
+ setFocusIndex(-1);
60
+ }, [query]);
61
+ // Autofocus on mount — the user switched into Text search intending to type.
62
+ useEffect(() => {
63
+ inputRef.current?.focus();
64
+ }, []);
65
+ // Keep the virtually-focused option in view (no-op where unsupported, e.g. tests).
66
+ useEffect(() => {
67
+ if (focusIndex < 0)
68
+ return;
69
+ const el = typeof document !== "undefined"
70
+ ? document.getElementById(optionId(focusIndex))
71
+ : null;
72
+ el?.scrollIntoView?.({ block: "nearest" });
73
+ }, [focusIndex, optionId]);
74
+ const handleKeyDown = useCallback((e) => {
75
+ if (e.key === "ArrowDown") {
76
+ e.preventDefault();
77
+ setFocusIndex((prev) => (prev < flatResults.length - 1 ? prev + 1 : prev));
78
+ }
79
+ else if (e.key === "ArrowUp") {
80
+ e.preventDefault();
81
+ setFocusIndex((prev) => (prev > 0 ? prev - 1 : -1));
82
+ }
83
+ else if (e.key === "Enter") {
84
+ e.preventDefault();
85
+ const target = flatResults[focusIndex];
86
+ if (target)
87
+ onOpenFile(target.entryId, target.match.path, {
88
+ line: target.match.line,
89
+ });
90
+ }
91
+ }, [flatResults, focusIndex, onOpenFile]);
92
+ const trimmed = query.trim();
93
+ const belowMinLength = trimmed.length > 0 && trimmed.length < MIN_QUERY_LENGTH;
94
+ const showEntryHeaders = groups.length > 1;
95
+ // Screen-reader-only summary in a persistent polite live region: status swaps
96
+ // (searching → results/none) happen across separate unmounting branches, so a
97
+ // stable region is what actually gets announced. Terse by design.
98
+ const statusMessage = isUnsupported
99
+ ? ""
100
+ : trimmed.length === 0
101
+ ? ""
102
+ : belowMinLength
103
+ ? `Type at least ${MIN_QUERY_LENGTH} characters to search.`
104
+ : isLoading
105
+ ? "Searching file contents…"
106
+ : groups.length === 0
107
+ ? `No files containing ${trimmed}.`
108
+ : totalMatches > flatResults.length
109
+ ? `Showing the first ${flatResults.length} of ${totalMatches} matches.`
110
+ : `${totalMatches} ${totalMatches === 1 ? "match" : "matches"}.`;
111
+ return (_jsxs("div", { className: cn("flex h-full flex-col", className), children: [_jsx("div", { role: "status", "aria-live": "polite", className: "sr-only", children: statusMessage }), _jsxs("div", { className: "flex items-center gap-1.5 border-b border-border px-2 py-1.5", children: [_jsx(SearchIcon, {}), _jsx("input", { ref: inputRef, type: "text", role: "combobox", "aria-expanded": true, "aria-controls": listboxId, "aria-activedescendant": focusIndex >= 0 ? optionId(focusIndex) : undefined, value: query, onChange: (e) => setQuery(e.target.value), onKeyDown: handleKeyDown, placeholder: "Search text in files\u2026", disabled: isUnsupported, className: cn("min-w-0 flex-1 bg-transparent text-xs text-foreground", "placeholder:text-muted-foreground", "focus-visible:outline-none disabled:cursor-not-allowed"), "aria-label": "Search text in workspace files" }), isRefetching && _jsx(Spinner, {}), trimmed.length > 0 && (_jsx("button", { type: "button", onClick: () => {
112
+ setQuery("");
113
+ inputRef.current?.focus();
114
+ }, className: "shrink-0 text-muted-foreground transition-colors hover:text-foreground", "aria-label": "Clear search", children: _jsx(ClearIcon, {}) }))] }), _jsx("div", { className: "min-h-0 flex-1 overflow-y-auto", children: isUnsupported ? (_jsx(MessageState, { children: "Text search isn\u2019t available here." })) : trimmed.length === 0 ? (_jsx(MessageState, { children: "Search file contents across the whole workspace." })) : belowMinLength ? (_jsxs(MessageState, { children: ["Type at least ", MIN_QUERY_LENGTH, " characters to search."] })) : isLoading ? (_jsx(MessageState, { children: "Searching\u2026" })) : groups.length === 0 ? (_jsxs(MessageState, { children: ["No files containing \u201C", trimmed, "\u201D."] })) : (_jsxs(_Fragment, { children: [_jsx("ul", { id: listboxId, role: "listbox", "aria-label": "Search results", className: "py-0.5", children: renderRows({
115
+ groups,
116
+ query: trimmed,
117
+ showEntryHeaders,
118
+ selectedFile: selectedFile ?? null,
119
+ focusIndex,
120
+ optionId,
121
+ onOpenFile,
122
+ }) }), totalMatches > flatResults.length && (_jsxs("p", { className: "border-t border-border px-3 py-1.5 text-[0.65rem] text-muted-foreground", children: ["Showing the first ", flatResults.length, " of ", totalMatches, " matches \u2014 refine your search to narrow the list."] }))] })) })] }));
123
+ }
124
+ // ---------------------------------------------------------------------------
125
+ // Result rows — a single pass that keeps the flat line-hit index aligned with
126
+ // `flatResults` (and thus keyboard focus / aria-activedescendant), rendering a
127
+ // VS Code-style entry → file → line hierarchy. Backend order (path, then line)
128
+ // makes each file's hits contiguous, so file headers fall out of a path change.
129
+ // ---------------------------------------------------------------------------
130
+ function renderRows({ groups, query, showEntryHeaders, selectedFile, focusIndex, optionId, onOpenFile, }) {
131
+ const rows = [];
132
+ let matchIndex = 0;
133
+ for (const group of groups) {
134
+ if (showEntryHeaders) {
135
+ rows.push(_jsx(EntryHeader, { name: group.entry.name }, `entry:${group.entry.id}`));
136
+ }
137
+ let currentPath = null;
138
+ for (const match of group.matches) {
139
+ if (matchIndex >= MAX_RESULTS)
140
+ break;
141
+ if (match.path !== currentPath) {
142
+ currentPath = match.path;
143
+ rows.push(_jsx(FileHeader, { path: match.path }, `file:${group.entry.id}:${match.path}`));
144
+ }
145
+ const index = matchIndex++;
146
+ const isOpen = selectedFile?.entryId === group.entry.id && selectedFile.path === match.path;
147
+ rows.push(_jsx(LineRow, { id: optionId(index), match: match, query: query, isFocused: index === focusIndex, isOpen: isOpen, onOpen: () => onOpenFile(group.entry.id, match.path, { line: match.line }) }, `line:${group.entry.id}:${match.path}:${match.line}`));
148
+ }
149
+ if (group.truncated) {
150
+ rows.push(_jsx(GroupNotice, { children: "Partial results \u2014 more matches exist than shown for this workspace." }, `t:${group.entry.id}`));
151
+ }
152
+ if (group.error) {
153
+ rows.push(_jsxs(GroupNotice, { isError: true, children: ["Couldn\u2019t search: ", group.error.message] }, `e:${group.entry.id}`));
154
+ }
155
+ if (matchIndex >= MAX_RESULTS)
156
+ break;
157
+ }
158
+ return rows;
159
+ }
160
+ function LineRow({ id, match, query, isFocused, isOpen, onOpen, }) {
161
+ // The `role="option"` IS the interactive leaf of the listbox (keyboard
162
+ // activation flows through the combobox input's Enter handler +
163
+ // aria-activedescendant). It must not nest another interactive control — a
164
+ // button inside would violate WCAG 4.1.2 (axe `nested-interactive`). So the
165
+ // click handler and row styling live on the option itself.
166
+ return (_jsxs("li", { id: id, role: "option", "aria-selected": isFocused, "aria-current": isOpen ? "true" : undefined, onClick: onOpen, className: cn("flex cursor-pointer items-baseline gap-2 py-0.5 pl-6 pr-3 text-xs transition-colors", isFocused && "bg-muted", isOpen && "bg-muted", !isFocused && !isOpen && "hover:bg-muted"), children: [_jsx("span", { className: "w-8 shrink-0 text-right font-mono text-[0.65rem] tabular-nums text-muted-foreground-subtle", children: match.line }), _jsx("span", { className: "min-w-0 flex-1 truncate font-mono text-muted-foreground", children: _jsx(HighlightedPreview, { text: match.preview, query: query }) })] }));
167
+ }
168
+ /**
169
+ * Renders a preview line, emphasizing every case-insensitive occurrence of the
170
+ * query. Offsets are re-derived from the text (the backend carries no column),
171
+ * so highlighting is consistent with what the user sees.
172
+ */
173
+ function HighlightedPreview({ text, query, }) {
174
+ const ranges = findHighlightRanges(text, query);
175
+ if (ranges.length === 0)
176
+ return _jsx(_Fragment, { children: text });
177
+ const parts = [];
178
+ let cursor = 0;
179
+ ranges.forEach((range, i) => {
180
+ if (range.start > cursor)
181
+ parts.push(text.slice(cursor, range.start));
182
+ parts.push(_jsx("span", { className: "font-semibold text-foreground", children: text.slice(range.start, range.end) }, i));
183
+ cursor = range.end;
184
+ });
185
+ if (cursor < text.length)
186
+ parts.push(text.slice(cursor));
187
+ return _jsx(_Fragment, { children: parts });
188
+ }
189
+ function EntryHeader({ name }) {
190
+ return (_jsx("li", { role: "presentation", className: "truncate px-3 pb-0.5 pt-2 text-[0.6rem] font-medium uppercase tracking-wide text-muted-foreground", children: name }));
191
+ }
192
+ function FileHeader({ path }) {
193
+ const lastSlash = path.lastIndexOf("/");
194
+ const basename = lastSlash >= 0 ? path.slice(lastSlash + 1) : path;
195
+ const dir = lastSlash >= 0 ? path.slice(0, lastSlash) : "";
196
+ return (_jsxs("li", { role: "presentation", className: "flex items-baseline gap-1.5 px-3 pb-0.5 pt-1.5 text-xs", children: [_jsx("span", { className: "shrink-0 font-medium text-foreground", children: basename }), dir && _jsx("span", { className: "truncate text-[0.65rem] text-muted-foreground", children: dir })] }));
197
+ }
198
+ function GroupNotice({ children, isError, }) {
199
+ return (_jsx("li", { role: "presentation", className: cn("px-3 py-1 text-[0.65rem]", isError ? "text-destructive" : "text-muted-foreground"), children: children }));
200
+ }
201
+ function MessageState({ children }) {
202
+ return (_jsx("div", { className: "flex h-full items-center justify-center p-8 text-center text-xs text-muted-foreground", children: children }));
203
+ }
204
+ // ---------------------------------------------------------------------------
205
+ // Inline SVG icons (SDK independence — no lucide dependency)
206
+ // ---------------------------------------------------------------------------
207
+ function SearchIcon() {
208
+ return (_jsxs("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", className: "shrink-0 text-muted-foreground", "aria-hidden": "true", children: [_jsx("circle", { cx: "5.25", cy: "5.25", r: "3.5" }), _jsx("path", { d: "M7.75 7.75L10.5 10.5" })] }));
209
+ }
210
+ function ClearIcon() {
211
+ return (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "M3 3L9 9M9 3L3 9" }) }));
212
+ }
213
+ function Spinner() {
214
+ return (_jsx("span", { "aria-hidden": "true", className: "h-3 w-3 shrink-0 animate-spin rounded-full border border-muted-foreground border-t-transparent" }));
215
+ }
216
+ //# sourceMappingURL=WorkspaceContentSearch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkspaceContentSearch.js","sourceRoot":"","sources":["../../src/workspace/WorkspaceContentSearch.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import type { WorkspaceEntry } from "./useWorkspaceEntries.js";
2
+ /**
3
+ * A single content-search hit: a line in a workspace file whose text contains
4
+ * the query.
5
+ *
6
+ * Deliberately line-level and column-free. The consumer recomputes the
7
+ * highlight range from `preview` + query (a case-insensitive substring), so a
8
+ * byte/column offset would be an unused field until jump-to-line ships — at
9
+ * which point `line` is the anchor. `preview` is guaranteed to contain the
10
+ * match even for long lines (the backend windows it around the first hit).
11
+ */
12
+ export interface WorkspaceContentMatch {
13
+ /** Repo-relative (git) or root-relative (local) path of the matched file. */
14
+ readonly path: string;
15
+ /** 1-based line number of the match within the file. */
16
+ readonly line: number;
17
+ /** The matched line's text, windowed so the match stays visible. */
18
+ readonly preview: string;
19
+ }
20
+ /**
21
+ * The result of searching one workspace entry: its hits plus whether a cap
22
+ * stopped the search early.
23
+ *
24
+ * A result object (rather than a bare `WorkspaceContentMatch[]`) so the
25
+ * per-root `truncated` signal survives to the UI — mirroring how
26
+ * {@link WorkspaceFileReader} returns a
27
+ * `WorkspaceFileContent` object with its own `truncated` flag rather than raw
28
+ * text. `truncated` means "there are more matches than shown for this entry".
29
+ */
30
+ export interface WorkspaceContentSearchResult {
31
+ /** Ranked hits (backend order: path, then line). */
32
+ readonly matches: readonly WorkspaceContentMatch[];
33
+ /** `true` when a per-file or workspace cap stopped the search early. */
34
+ readonly truncated: boolean;
35
+ }
36
+ /**
37
+ * Platform-injected callback that searches file *contents* within one workspace
38
+ * entry for a case-insensitive substring.
39
+ *
40
+ * The text-grep sibling of {@link WorkspaceFileLister}:
41
+ * the SDK calls it (per entry, debounced) while the user types in the Search
42
+ * pane's Text mode; the platform decides *how* the grep runs.
43
+ *
44
+ * Two distinct outcomes — do not conflate them:
45
+ * - Returns `null` **only** when content search is unsupported for this entry
46
+ * (a git entry on desktop, any entry on web until a backend search exists).
47
+ * This is the honest "unavailable here" state, mirroring the lister's null
48
+ * contract — the whole workspace being `null` disables Text search.
49
+ * - **Throws** on a genuine failure (unreadable root, backend error). Consumers
50
+ * isolate this per entry so one failing root never blanks the rest.
51
+ *
52
+ * Implementations:
53
+ * - **Desktop:** Tauri `search_workspace_content` (ripgrep `ignore` walker +
54
+ * `grep-searcher`, respecting `.gitignore`, skipping binary/oversized files).
55
+ * - **Web:** `undefined`/`null` — GitHub code search is default-branch-only and
56
+ * would disagree with the branch the viewer reads (DD-09).
57
+ */
58
+ export type WorkspaceContentSearcher = (entry: WorkspaceEntry, query: string) => Promise<WorkspaceContentSearchResult | null>;
59
+ //# sourceMappingURL=WorkspaceContentSearcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkspaceContentSearcher.d.ts","sourceRoot":"","sources":["../../src/workspace/WorkspaceContentSearcher.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D;;;;;;;;;GASG;AACH,MAAM,WAAW,qBAAqB;IACpC,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,4BAA4B;IAC3C,oDAAoD;IACpD,QAAQ,CAAC,OAAO,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACnD,wEAAwE;IACxE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,wBAAwB,GAAG,CACrC,KAAK,EAAE,cAAc,EACrB,KAAK,EAAE,MAAM,KACV,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ // Content-search capability — the text-grep sibling of WorkspaceFileLister
2
+ // (which does filename/path search over a cached listing). Injected by the host
3
+ // (DD-004) so the SDK never learns how the grep runs: a native ripgrep-backed
4
+ // walker on desktop; `null` (unsupported) on web/git until a branch-accurate
5
+ // backend search exists (DD-09).
6
+ export {};
7
+ //# sourceMappingURL=WorkspaceContentSearcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkspaceContentSearcher.js","sourceRoot":"","sources":["../../src/workspace/WorkspaceContentSearcher.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,gFAAgF;AAChF,8EAA8E;AAC9E,6EAA6E;AAC7E,iCAAiC"}
@@ -1 +1 @@
1
- {"version":3,"file":"WorkspaceEditor.d.ts","sourceRoot":"","sources":["../../src/workspace/WorkspaceEditor.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAKlF,KAAK,WAAW,GAAG,QAAQ,GAAG,IAAI,CAAC;AAEnC,yCAAyC;AACzC,MAAM,WAAW,oBAAoB;IACnC,wDAAwD;IACxD,QAAQ,CAAC,SAAS,EAAE,yBAAyB,CAAC;IAC9C,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,4CAA4C;IAC5C,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,8EAA8E;IAC9E,QAAQ,CAAC,gBAAgB,CAAC,EAAE,yBAAyB,CAAC;IACtD,yDAAyD;IACzD,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC,yCAAyC;IACzC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5D;;;;;;;OAOG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,WAAW,CAAC;CACrC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,eAAe,CAAC,EAC9B,SAAS,EACT,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,YAAmB,EACnB,WAAmB,EACnB,mBAAmB,EACnB,YAAY,GACb,EAAE,oBAAoB,2CA6KtB"}
1
+ {"version":3,"file":"WorkspaceEditor.d.ts","sourceRoot":"","sources":["../../src/workspace/WorkspaceEditor.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAKlF,KAAK,WAAW,GAAG,QAAQ,GAAG,IAAI,CAAC;AAEnC,yCAAyC;AACzC,MAAM,WAAW,oBAAoB;IACnC,wDAAwD;IACxD,QAAQ,CAAC,SAAS,EAAE,yBAAyB,CAAC;IAC9C,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,4CAA4C;IAC5C,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,8EAA8E;IAC9E,QAAQ,CAAC,gBAAgB,CAAC,EAAE,yBAAyB,CAAC;IACtD,yDAAyD;IACzD,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC,yCAAyC;IACzC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5D;;;;;;;OAOG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,WAAW,CAAC;CACrC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,eAAe,CAAC,EAC9B,SAAS,EACT,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,YAAmB,EACnB,WAAmB,EACnB,mBAAmB,EACnB,YAAY,GACb,EAAE,oBAAoB,2CA6KtB"}