@flanksource/clicky-ui 0.3.40 → 0.3.41

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 (342) hide show
  1. package/README.md +24 -0
  2. package/dist/ai.cjs +10 -0
  3. package/dist/ai.cjs.map +1 -1
  4. package/dist/ai.js +10 -0
  5. package/dist/ai.js.map +1 -1
  6. package/dist/components/AccordionList.cjs +5 -1
  7. package/dist/components/AccordionList.cjs.map +1 -1
  8. package/dist/components/AccordionList.d.ts +3 -1
  9. package/dist/components/AccordionList.d.ts.map +1 -1
  10. package/dist/components/AccordionList.js +5 -1
  11. package/dist/components/AccordionList.js.map +1 -1
  12. package/dist/components/JsonSchemaForm.cjs +9 -4
  13. package/dist/components/JsonSchemaForm.cjs.map +1 -1
  14. package/dist/components/JsonSchemaForm.d.ts +1 -1
  15. package/dist/components/JsonSchemaForm.d.ts.map +1 -1
  16. package/dist/components/JsonSchemaForm.js +8 -3
  17. package/dist/components/JsonSchemaForm.js.map +1 -1
  18. package/dist/components/json-schema-form-accordion-array.cjs +3 -1
  19. package/dist/components/json-schema-form-accordion-array.cjs.map +1 -1
  20. package/dist/components/json-schema-form-accordion-array.d.ts +4 -1
  21. package/dist/components/json-schema-form-accordion-array.d.ts.map +1 -1
  22. package/dist/components/json-schema-form-accordion-array.js +3 -1
  23. package/dist/components/json-schema-form-accordion-array.js.map +1 -1
  24. package/dist/components/json-schema-form-array-view.cjs +63 -0
  25. package/dist/components/json-schema-form-array-view.cjs.map +1 -0
  26. package/dist/components/json-schema-form-array-view.d.ts +21 -0
  27. package/dist/components/json-schema-form-array-view.d.ts.map +1 -0
  28. package/dist/components/json-schema-form-array-view.js +63 -0
  29. package/dist/components/json-schema-form-array-view.js.map +1 -0
  30. package/dist/components/json-schema-form-array.cjs +3 -7
  31. package/dist/components/json-schema-form-array.cjs.map +1 -1
  32. package/dist/components/json-schema-form-array.d.ts.map +1 -1
  33. package/dist/components/json-schema-form-array.js +3 -7
  34. package/dist/components/json-schema-form-array.js.map +1 -1
  35. package/dist/components/json-schema-form-conditionals.cjs +67 -0
  36. package/dist/components/json-schema-form-conditionals.cjs.map +1 -0
  37. package/dist/components/json-schema-form-conditionals.d.ts +9 -0
  38. package/dist/components/json-schema-form-conditionals.d.ts.map +1 -0
  39. package/dist/components/json-schema-form-conditionals.js +67 -0
  40. package/dist/components/json-schema-form-conditionals.js.map +1 -0
  41. package/dist/components/json-schema-form-defaults.cjs +68 -0
  42. package/dist/components/json-schema-form-defaults.cjs.map +1 -0
  43. package/dist/components/json-schema-form-defaults.d.ts +4 -0
  44. package/dist/components/json-schema-form-defaults.d.ts.map +1 -0
  45. package/dist/components/json-schema-form-defaults.js +68 -0
  46. package/dist/components/json-schema-form-defaults.js.map +1 -0
  47. package/dist/components/json-schema-form-errors.cjs +49 -31
  48. package/dist/components/json-schema-form-errors.cjs.map +1 -1
  49. package/dist/components/json-schema-form-errors.d.ts +4 -2
  50. package/dist/components/json-schema-form-errors.d.ts.map +1 -1
  51. package/dist/components/json-schema-form-errors.js +51 -33
  52. package/dist/components/json-schema-form-errors.js.map +1 -1
  53. package/dist/components/json-schema-form-filter.cjs +2 -1
  54. package/dist/components/json-schema-form-filter.cjs.map +1 -1
  55. package/dist/components/json-schema-form-filter.js +2 -1
  56. package/dist/components/json-schema-form-filter.js.map +1 -1
  57. package/dist/components/json-schema-form-item-summary.cjs +6 -2
  58. package/dist/components/json-schema-form-item-summary.cjs.map +1 -1
  59. package/dist/components/json-schema-form-item-summary.d.ts.map +1 -1
  60. package/dist/components/json-schema-form-item-summary.js +6 -2
  61. package/dist/components/json-schema-form-item-summary.js.map +1 -1
  62. package/dist/components/json-schema-form-layout.cjs +28 -19
  63. package/dist/components/json-schema-form-layout.cjs.map +1 -1
  64. package/dist/components/json-schema-form-layout.d.ts +8 -6
  65. package/dist/components/json-schema-form-layout.d.ts.map +1 -1
  66. package/dist/components/json-schema-form-layout.js +29 -20
  67. package/dist/components/json-schema-form-layout.js.map +1 -1
  68. package/dist/components/json-schema-form-listener-paths.cjs +52 -0
  69. package/dist/components/json-schema-form-listener-paths.cjs.map +1 -0
  70. package/dist/components/json-schema-form-listener-paths.d.ts +10 -0
  71. package/dist/components/json-schema-form-listener-paths.d.ts.map +1 -0
  72. package/dist/components/json-schema-form-listener-paths.js +52 -0
  73. package/dist/components/json-schema-form-listener-paths.js.map +1 -0
  74. package/dist/components/json-schema-form-listener-types.d.ts +22 -0
  75. package/dist/components/json-schema-form-listener-types.d.ts.map +1 -0
  76. package/dist/components/json-schema-form-listeners.cjs +250 -0
  77. package/dist/components/json-schema-form-listeners.cjs.map +1 -0
  78. package/dist/components/json-schema-form-listeners.d.ts +13 -0
  79. package/dist/components/json-schema-form-listeners.d.ts.map +1 -0
  80. package/dist/components/json-schema-form-listeners.js +250 -0
  81. package/dist/components/json-schema-form-listeners.js.map +1 -0
  82. package/dist/components/json-schema-form-object-array-view.cjs +62 -0
  83. package/dist/components/json-schema-form-object-array-view.cjs.map +1 -0
  84. package/dist/components/json-schema-form-object-array-view.d.ts +14 -0
  85. package/dist/components/json-schema-form-object-array-view.d.ts.map +1 -0
  86. package/dist/components/json-schema-form-object-array-view.js +62 -0
  87. package/dist/components/json-schema-form-object-array-view.js.map +1 -0
  88. package/dist/components/json-schema-form-object.cjs +3 -0
  89. package/dist/components/json-schema-form-object.cjs.map +1 -1
  90. package/dist/components/json-schema-form-object.d.ts.map +1 -1
  91. package/dist/components/json-schema-form-object.js +3 -0
  92. package/dist/components/json-schema-form-object.js.map +1 -1
  93. package/dist/components/json-schema-form-render.cjs +17 -9
  94. package/dist/components/json-schema-form-render.cjs.map +1 -1
  95. package/dist/components/json-schema-form-render.d.ts.map +1 -1
  96. package/dist/components/json-schema-form-render.js +19 -11
  97. package/dist/components/json-schema-form-render.js.map +1 -1
  98. package/dist/components/json-schema-form-resolve.cjs +6 -99
  99. package/dist/components/json-schema-form-resolve.cjs.map +1 -1
  100. package/dist/components/json-schema-form-resolve.d.ts +1 -8
  101. package/dist/components/json-schema-form-resolve.d.ts.map +1 -1
  102. package/dist/components/json-schema-form-resolve.js +5 -98
  103. package/dist/components/json-schema-form-resolve.js.map +1 -1
  104. package/dist/components/json-schema-form-runtime-types.d.ts +15 -0
  105. package/dist/components/json-schema-form-runtime-types.d.ts.map +1 -1
  106. package/dist/components/json-schema-form-table-array.cjs +67 -16
  107. package/dist/components/json-schema-form-table-array.cjs.map +1 -1
  108. package/dist/components/json-schema-form-table-array.d.ts +4 -1
  109. package/dist/components/json-schema-form-table-array.d.ts.map +1 -1
  110. package/dist/components/json-schema-form-table-array.js +70 -19
  111. package/dist/components/json-schema-form-table-array.js.map +1 -1
  112. package/dist/components/json-schema-form-types.d.ts +16 -0
  113. package/dist/components/json-schema-form-types.d.ts.map +1 -1
  114. package/dist/components/json-schema-form-utils.cjs +7 -1
  115. package/dist/components/json-schema-form-utils.cjs.map +1 -1
  116. package/dist/components/json-schema-form-utils.d.ts +2 -1
  117. package/dist/components/json-schema-form-utils.d.ts.map +1 -1
  118. package/dist/components/json-schema-form-utils.js +7 -1
  119. package/dist/components/json-schema-form-utils.js.map +1 -1
  120. package/dist/components.cjs +3 -2
  121. package/dist/components.cjs.map +1 -1
  122. package/dist/components.d.ts +3 -2
  123. package/dist/components.d.ts.map +1 -1
  124. package/dist/components.js +2 -1
  125. package/dist/components.js.map +1 -1
  126. package/dist/data/DataTable.cjs +9 -3
  127. package/dist/data/DataTable.cjs.map +1 -1
  128. package/dist/data/DataTable.d.ts +6 -0
  129. package/dist/data/DataTable.d.ts.map +1 -1
  130. package/dist/data/DataTable.js +9 -3
  131. package/dist/data/DataTable.js.map +1 -1
  132. package/dist/data/FixtureEditor/FixtureEditor.cjs +43 -24
  133. package/dist/data/FixtureEditor/FixtureEditor.cjs.map +1 -1
  134. package/dist/data/FixtureEditor/FixtureEditor.d.ts.map +1 -1
  135. package/dist/data/FixtureEditor/FixtureEditor.js +43 -24
  136. package/dist/data/FixtureEditor/FixtureEditor.js.map +1 -1
  137. package/dist/data/Tree.cjs +10 -2
  138. package/dist/data/Tree.cjs.map +1 -1
  139. package/dist/data/Tree.d.ts +6 -1
  140. package/dist/data/Tree.d.ts.map +1 -1
  141. package/dist/data/Tree.js +10 -2
  142. package/dist/data/Tree.js.map +1 -1
  143. package/dist/data/ai/SessionInspector.cjs +143 -167
  144. package/dist/data/ai/SessionInspector.cjs.map +1 -1
  145. package/dist/data/ai/SessionInspector.collection-types.d.ts +5 -0
  146. package/dist/data/ai/SessionInspector.collection-types.d.ts.map +1 -1
  147. package/dist/data/ai/SessionInspector.collection.cjs +18 -5
  148. package/dist/data/ai/SessionInspector.collection.cjs.map +1 -1
  149. package/dist/data/ai/SessionInspector.collection.d.ts +2 -0
  150. package/dist/data/ai/SessionInspector.collection.d.ts.map +1 -1
  151. package/dist/data/ai/SessionInspector.collection.fixtures.d.ts +6 -0
  152. package/dist/data/ai/SessionInspector.collection.fixtures.d.ts.map +1 -0
  153. package/dist/data/ai/SessionInspector.collection.js +18 -5
  154. package/dist/data/ai/SessionInspector.collection.js.map +1 -1
  155. package/dist/data/ai/SessionInspector.d.ts +24 -2
  156. package/dist/data/ai/SessionInspector.d.ts.map +1 -1
  157. package/dist/data/ai/SessionInspector.hierarchy-state.cjs +105 -7
  158. package/dist/data/ai/SessionInspector.hierarchy-state.cjs.map +1 -1
  159. package/dist/data/ai/SessionInspector.hierarchy-state.d.ts +12 -1
  160. package/dist/data/ai/SessionInspector.hierarchy-state.d.ts.map +1 -1
  161. package/dist/data/ai/SessionInspector.hierarchy-state.js +107 -9
  162. package/dist/data/ai/SessionInspector.hierarchy-state.js.map +1 -1
  163. package/dist/data/ai/SessionInspector.hierarchy.cjs +1 -1
  164. package/dist/data/ai/SessionInspector.hierarchy.cjs.map +1 -1
  165. package/dist/data/ai/SessionInspector.hierarchy.js +1 -1
  166. package/dist/data/ai/SessionInspector.hierarchy.js.map +1 -1
  167. package/dist/data/ai/SessionInspector.js +144 -168
  168. package/dist/data/ai/SessionInspector.js.map +1 -1
  169. package/dist/data/ai/SessionInspector.legacy.cjs +116 -0
  170. package/dist/data/ai/SessionInspector.legacy.cjs.map +1 -0
  171. package/dist/data/ai/SessionInspector.legacy.d.ts +19 -0
  172. package/dist/data/ai/SessionInspector.legacy.d.ts.map +1 -0
  173. package/dist/data/ai/SessionInspector.legacy.js +116 -0
  174. package/dist/data/ai/SessionInspector.legacy.js.map +1 -0
  175. package/dist/data/ai/SessionInspector.panels.cjs +3 -0
  176. package/dist/data/ai/SessionInspector.panels.cjs.map +1 -1
  177. package/dist/data/ai/SessionInspector.panels.d.ts.map +1 -1
  178. package/dist/data/ai/SessionInspector.panels.js +3 -0
  179. package/dist/data/ai/SessionInspector.panels.js.map +1 -1
  180. package/dist/data/ai/SessionInspector.plan.cjs +29 -12
  181. package/dist/data/ai/SessionInspector.plan.cjs.map +1 -1
  182. package/dist/data/ai/SessionInspector.plan.d.ts.map +1 -1
  183. package/dist/data/ai/SessionInspector.plan.js +30 -13
  184. package/dist/data/ai/SessionInspector.plan.js.map +1 -1
  185. package/dist/data/ai/SessionInspector.remote-view.cjs +44 -0
  186. package/dist/data/ai/SessionInspector.remote-view.cjs.map +1 -0
  187. package/dist/data/ai/SessionInspector.remote-view.d.ts +11 -0
  188. package/dist/data/ai/SessionInspector.remote-view.d.ts.map +1 -0
  189. package/dist/data/ai/SessionInspector.remote-view.js +44 -0
  190. package/dist/data/ai/SessionInspector.remote-view.js.map +1 -0
  191. package/dist/data/ai/SessionInspector.remote.cjs +275 -0
  192. package/dist/data/ai/SessionInspector.remote.cjs.map +1 -0
  193. package/dist/data/ai/SessionInspector.remote.d.ts +57 -0
  194. package/dist/data/ai/SessionInspector.remote.d.ts.map +1 -0
  195. package/dist/data/ai/SessionInspector.remote.js +275 -0
  196. package/dist/data/ai/SessionInspector.remote.js.map +1 -0
  197. package/dist/data/ai/SessionInspector.summary.cjs +0 -156
  198. package/dist/data/ai/SessionInspector.summary.cjs.map +1 -1
  199. package/dist/data/ai/SessionInspector.summary.d.ts +0 -3
  200. package/dist/data/ai/SessionInspector.summary.d.ts.map +1 -1
  201. package/dist/data/ai/SessionInspector.summary.js +2 -158
  202. package/dist/data/ai/SessionInspector.summary.js.map +1 -1
  203. package/dist/data/ai/SessionInspector.tab-state.cjs +15 -0
  204. package/dist/data/ai/SessionInspector.tab-state.cjs.map +1 -0
  205. package/dist/data/ai/SessionInspector.tab-state.d.ts +3 -0
  206. package/dist/data/ai/SessionInspector.tab-state.d.ts.map +1 -0
  207. package/dist/data/ai/SessionInspector.tab-state.js +15 -0
  208. package/dist/data/ai/SessionInspector.tab-state.js.map +1 -0
  209. package/dist/data/ai/SessionInspector.tabs.model.cjs +31 -18
  210. package/dist/data/ai/SessionInspector.tabs.model.cjs.map +1 -1
  211. package/dist/data/ai/SessionInspector.tabs.model.d.ts +3 -1
  212. package/dist/data/ai/SessionInspector.tabs.model.d.ts.map +1 -1
  213. package/dist/data/ai/SessionInspector.tabs.model.js +32 -19
  214. package/dist/data/ai/SessionInspector.tabs.model.js.map +1 -1
  215. package/dist/data/ai/SessionInspector.verification.cjs +53 -0
  216. package/dist/data/ai/SessionInspector.verification.cjs.map +1 -0
  217. package/dist/data/ai/SessionInspector.verification.d.ts +7 -0
  218. package/dist/data/ai/SessionInspector.verification.d.ts.map +1 -0
  219. package/dist/data/ai/SessionInspector.verification.js +53 -0
  220. package/dist/data/ai/SessionInspector.verification.js.map +1 -0
  221. package/dist/data/ai/SessionViewer.model.cjs +7 -1
  222. package/dist/data/ai/SessionViewer.model.cjs.map +1 -1
  223. package/dist/data/ai/SessionViewer.model.d.ts +21 -3
  224. package/dist/data/ai/SessionViewer.model.d.ts.map +1 -1
  225. package/dist/data/ai/SessionViewer.model.js +7 -1
  226. package/dist/data/ai/SessionViewer.model.js.map +1 -1
  227. package/dist/data/ai/SessionViewer.unified.d.ts +13 -0
  228. package/dist/data/ai/SessionViewer.unified.d.ts.map +1 -1
  229. package/dist/data/ai/index.d.ts +3 -1
  230. package/dist/data/ai/index.d.ts.map +1 -1
  231. package/dist/data/version-info.cjs +3 -3
  232. package/dist/data/version-info.js +3 -3
  233. package/dist/devtools/useDebugStream.cjs +5 -1
  234. package/dist/devtools/useDebugStream.cjs.map +1 -1
  235. package/dist/devtools/useDebugStream.d.ts.map +1 -1
  236. package/dist/devtools/useDebugStream.js +6 -2
  237. package/dist/devtools/useDebugStream.js.map +1 -1
  238. package/dist/hooks/event-source-provider.cjs +9 -0
  239. package/dist/hooks/event-source-provider.cjs.map +1 -0
  240. package/dist/hooks/event-source-provider.d.ts +15 -0
  241. package/dist/hooks/event-source-provider.d.ts.map +1 -0
  242. package/dist/hooks/event-source-provider.js +9 -0
  243. package/dist/hooks/event-source-provider.js.map +1 -0
  244. package/dist/hooks/event-source.cjs +11 -0
  245. package/dist/hooks/event-source.cjs.map +1 -0
  246. package/dist/hooks/event-source.d.ts +22 -0
  247. package/dist/hooks/event-source.d.ts.map +1 -0
  248. package/dist/hooks/event-source.js +11 -0
  249. package/dist/hooks/event-source.js.map +1 -0
  250. package/dist/hooks/use-log-tail.cjs +5 -1
  251. package/dist/hooks/use-log-tail.cjs.map +1 -1
  252. package/dist/hooks/use-log-tail.d.ts.map +1 -1
  253. package/dist/hooks/use-log-tail.js +5 -1
  254. package/dist/hooks/use-log-tail.js.map +1 -1
  255. package/dist/hooks/use-prompts.cjs +5 -1
  256. package/dist/hooks/use-prompts.cjs.map +1 -1
  257. package/dist/hooks/use-prompts.d.ts.map +1 -1
  258. package/dist/hooks/use-prompts.js +6 -2
  259. package/dist/hooks/use-prompts.js.map +1 -1
  260. package/dist/hooks/use-task-run.cjs +9 -2
  261. package/dist/hooks/use-task-run.cjs.map +1 -1
  262. package/dist/hooks/use-task-run.d.ts.map +1 -1
  263. package/dist/hooks/use-task-run.js +10 -3
  264. package/dist/hooks/use-task-run.js.map +1 -1
  265. package/dist/hooks.cjs +4 -0
  266. package/dist/hooks.cjs.map +1 -1
  267. package/dist/hooks.d.ts +2 -0
  268. package/dist/hooks.d.ts.map +1 -1
  269. package/dist/hooks.js +4 -0
  270. package/dist/hooks.js.map +1 -1
  271. package/dist/icons/programmingCatalog.cjs +34 -34
  272. package/dist/icons/programmingCatalog.cjs.map +1 -1
  273. package/dist/icons/programmingCatalog.js +34 -34
  274. package/dist/icons/programmingCatalog.js.map +1 -1
  275. package/dist/index.cjs +9 -2
  276. package/dist/index.cjs.map +1 -1
  277. package/dist/index.js +8 -1
  278. package/dist/index.js.map +1 -1
  279. package/dist/monaco/MonacoEditor.cjs +4 -1
  280. package/dist/monaco/MonacoEditor.cjs.map +1 -1
  281. package/dist/monaco/MonacoEditor.d.ts +1 -1
  282. package/dist/monaco/MonacoEditor.d.ts.map +1 -1
  283. package/dist/monaco/MonacoEditor.js +4 -1
  284. package/dist/monaco/MonacoEditor.js.map +1 -1
  285. package/dist/monaco/types.d.ts +2 -1
  286. package/dist/monaco/types.d.ts.map +1 -1
  287. package/dist/overlay/CommandPalette.cjs +14 -4
  288. package/dist/overlay/CommandPalette.cjs.map +1 -1
  289. package/dist/overlay/CommandPalette.d.ts +5 -1
  290. package/dist/overlay/CommandPalette.d.ts.map +1 -1
  291. package/dist/overlay/CommandPalette.js +14 -4
  292. package/dist/overlay/CommandPalette.js.map +1 -1
  293. package/dist/overlay/CommandPaletteList.cjs +5 -0
  294. package/dist/overlay/CommandPaletteList.cjs.map +1 -1
  295. package/dist/overlay/CommandPaletteList.d.ts +4 -2
  296. package/dist/overlay/CommandPaletteList.d.ts.map +1 -1
  297. package/dist/overlay/CommandPaletteList.js +5 -0
  298. package/dist/overlay/CommandPaletteList.js.map +1 -1
  299. package/dist/overlay/DropdownMenu.cjs +1 -0
  300. package/dist/overlay/DropdownMenu.cjs.map +1 -1
  301. package/dist/overlay/DropdownMenu.js +1 -0
  302. package/dist/overlay/DropdownMenu.js.map +1 -1
  303. package/dist/rpc/OperationCatalog.cjs +29 -26
  304. package/dist/rpc/OperationCatalog.cjs.map +1 -1
  305. package/dist/rpc/OperationCatalog.d.ts +9 -1
  306. package/dist/rpc/OperationCatalog.d.ts.map +1 -1
  307. package/dist/rpc/OperationCatalog.js +29 -26
  308. package/dist/rpc/OperationCatalog.js.map +1 -1
  309. package/dist/rpc/OperationEntityContextPicker.cjs +62 -256
  310. package/dist/rpc/OperationEntityContextPicker.cjs.map +1 -1
  311. package/dist/rpc/OperationEntityContextPicker.d.ts.map +1 -1
  312. package/dist/rpc/OperationEntityContextPicker.js +64 -258
  313. package/dist/rpc/OperationEntityContextPicker.js.map +1 -1
  314. package/dist/rpc/OperationEntityPicker.cjs +185 -0
  315. package/dist/rpc/OperationEntityPicker.cjs.map +1 -0
  316. package/dist/rpc/OperationEntityPicker.d.ts +51 -0
  317. package/dist/rpc/OperationEntityPicker.d.ts.map +1 -0
  318. package/dist/rpc/OperationEntityPicker.js +185 -0
  319. package/dist/rpc/OperationEntityPicker.js.map +1 -0
  320. package/dist/rpc/OperationEntityPicker.model.cjs +39 -0
  321. package/dist/rpc/OperationEntityPicker.model.cjs.map +1 -0
  322. package/dist/rpc/OperationEntityPicker.model.d.ts +27 -0
  323. package/dist/rpc/OperationEntityPicker.model.d.ts.map +1 -0
  324. package/dist/rpc/OperationEntityPicker.model.js +39 -0
  325. package/dist/rpc/OperationEntityPicker.model.js.map +1 -0
  326. package/dist/rpc/operationCatalogRowSelection.cjs +85 -0
  327. package/dist/rpc/operationCatalogRowSelection.cjs.map +1 -0
  328. package/dist/rpc/operationCatalogRowSelection.d.ts +57 -0
  329. package/dist/rpc/operationCatalogRowSelection.d.ts.map +1 -0
  330. package/dist/rpc/operationCatalogRowSelection.js +85 -0
  331. package/dist/rpc/operationCatalogRowSelection.js.map +1 -0
  332. package/dist/rpc/operationEntityPicker.fixtures.d.ts +13 -0
  333. package/dist/rpc/operationEntityPicker.fixtures.d.ts.map +1 -0
  334. package/dist/rpc.cjs +2 -0
  335. package/dist/rpc.cjs.map +1 -1
  336. package/dist/rpc.d.ts +2 -0
  337. package/dist/rpc.d.ts.map +1 -1
  338. package/dist/rpc.js +2 -0
  339. package/dist/rpc.js.map +1 -1
  340. package/dist/styles.css +1 -1
  341. package/package.json +4 -1
  342. package/schemas/json-schema-form.schema.json +566 -0
@@ -1 +1 @@
1
- {"version":3,"file":"Tree.js","sources":["../../src/data/Tree.tsx"],"sourcesContent":["import { useMemo, useState, type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"./Icon\";\nimport { UiClose, UiCollapseAll, UiExpandAll, UiSearch } from \"../icons\";\nimport { TreeNode, type TreeNodeProps } from \"./TreeNode\";\n\nexport type TreeProps<T> = Omit<\n TreeNodeProps<T>,\n \"node\" | \"depth\" | \"expandAll\" | \"forcedOpenKeys\"\n> & {\n /** Root nodes to render. */\n roots: T[];\n /** Empty-state content when no roots are provided. */\n empty?: ReactNode;\n /** Classes applied to the tree root. */\n className?: string;\n /** Accessible name applied to the tree root. */\n ariaLabel?: string;\n /**\n * Render the Expand all / Collapse all toolbar above the tree. Enabled by\n * default. Set to false to suppress when the tree is tiny or the controls\n * are owned externally.\n */\n showControls?: boolean;\n /**\n * Externally controlled expand-all state. When provided together with\n * `onExpandAllChange`, the tree is controlled; otherwise it manages the\n * toolbar state internally.\n */\n expandAll?: boolean | null;\n /** Called when the toolbar expand-all state changes. */\n onExpandAllChange?: (next: boolean | null) => void;\n /** Classes applied to the search/control toolbar. */\n toolbarClassName?: string;\n /**\n * Extra controls rendered in the toolbar's right-hand group, before Expand\n * all / Collapse all. Providing actions shows the toolbar even when the tree\n * is too small for the filter and `showControls` is off.\n */\n actions?: ReactNode;\n /**\n * Override the text the filter matches against for a given node.\n * Defaults to a recursive walk of the node's own fields (excluding\n * its `children` and any secondary children), which works for\n * plain-shape trees but leaks text from nested domain objects —\n * e.g. a SQL Table's Field rows are marked secondary, yet the\n * parent record still carries `record.fields[].field` strings that\n * the default walker would collect. Callers that need precise\n * control over search behaviour should return only the text they\n * want surfaced (the node's own display label / id / type).\n */\n getSearchText?: (node: T) => string;\n /**\n * Force-open the ancestors of the `selected` node so it is always revealed,\n * even when its branch was collapsed (a deep-link, a programmatic selection\n * from outside the tree, or simply a folder the user never opened). While a\n * node is selected its ancestors cannot be collapsed. Off by default; other\n * nodes keep their normal expand state. Requires `selected` to be set.\n */\n revealSelected?: boolean;\n};\n\n// ancestorPathKeys returns the keys of every ancestor on the path from a root\n// down to `target` (excluding target itself — opening the ancestors is what\n// makes target render). Matches by getKey so it is robust to object identity\n// across roots rebuilds. Returns null when target is not found.\nfunction ancestorPathKeys<T>(\n roots: T[],\n getChildren: TreeProps<T>[\"getChildren\"],\n getKey: TreeProps<T>[\"getKey\"],\n target: T,\n): Set<string | number> | null {\n const targetKey = getKey(target);\n const path: (string | number)[] = [];\n const visit = (node: T): boolean => {\n if (getKey(node) === targetKey) return true;\n for (const child of getChildren(node) ?? []) {\n if (visit(child)) {\n path.push(getKey(node));\n return true;\n }\n }\n return false;\n };\n for (const root of roots) {\n if (visit(root)) return path.length ? new Set(path) : null;\n }\n return null;\n}\n\n// mergeKeySets unions two optional key sets, preserving the null fast-path when\n// both are empty so consumers without a filter or reveal pass null downstream.\nfunction mergeKeySets(\n a: Set<string | number> | null,\n b: Set<string | number> | null,\n): Set<string | number> | null {\n if (!a) return b;\n if (!b) return a;\n return new Set([...a, ...b]);\n}\n\n// Edge counting, search-text collection and filtering all walk the tree through\n// the synchronous `getChildren` only. A lazy node (one declared via\n// `hasMoreChildren` whose children have not been fetched yet) therefore\n// contributes no edges and no search text until the operator expands it — so it\n// is invisible to \"expand all\" and to the filter while still collapsed. This is\n// intentional: we never trigger network loads from bulk/search operations.\nfunction countTreeEdges<T>(roots: T[], getChildren: TreeProps<T>[\"getChildren\"]) {\n let total = 0;\n const stack = [...roots];\n\n while (stack.length > 0) {\n const node = stack.pop()!;\n const children = getChildren(node) ?? [];\n total += children.length;\n stack.push(...children);\n }\n\n return total;\n}\n\nfunction collectTreeSearchText(\n value: unknown,\n excluded = new Set<unknown>(),\n seen = new Set<unknown>(),\n): string {\n if (value == null || excluded.has(value)) return \"\";\n\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\" ||\n typeof value === \"bigint\"\n ) {\n return String(value);\n }\n\n if (typeof value !== \"object\") return \"\";\n if (seen.has(value)) return \"\";\n seen.add(value);\n\n if (Array.isArray(value)) {\n return value\n .map((entry) => collectTreeSearchText(entry, excluded, seen))\n .filter(Boolean)\n .join(\" \");\n }\n\n const preferredKeys = [\"label\", \"name\", \"title\", \"text\", \"plain\", \"id\", \"content\"];\n const record = value as Record<string, unknown>;\n const chunks: string[] = [];\n\n for (const key of preferredKeys) {\n if (!(key in record)) continue;\n const text = collectTreeSearchText(record[key], excluded, seen);\n if (text) chunks.push(text);\n }\n\n for (const [key, entry] of Object.entries(record)) {\n if (key === \"children\" || preferredKeys.includes(key)) continue;\n const text = collectTreeSearchText(entry, excluded, seen);\n if (text) chunks.push(text);\n }\n\n return chunks.join(\" \");\n}\n\nfunction nodeSearchText<T>(node: T, children: ReturnType<TreeProps<T>[\"getChildren\"]>) {\n const excluded = new Set<unknown>();\n if (children) excluded.add(children);\n return collectTreeSearchText(node, excluded).trim().toLowerCase();\n}\n\nfunction filterTreeRoots<T>(\n roots: T[],\n getChildren: TreeProps<T>[\"getChildren\"],\n getKey: TreeProps<T>[\"getKey\"],\n query: string,\n isSecondary?: (node: T) => boolean,\n getSearchText?: (node: T) => string,\n) {\n const normalizedQuery = query.trim().toLowerCase();\n if (!normalizedQuery) {\n return {\n roots,\n filteredChildren: null as Map<string | number, T[]> | null,\n forcedOpenKeys: null as Set<string | number> | null,\n };\n }\n\n const filteredChildren = new Map<string | number, T[]>();\n const forcedOpenKeys = new Set<string | number>();\n\n function matchText(node: T, children: T[]): string {\n // Honour the caller-supplied text extractor first — it's the\n // only way to get precise control over what the filter sees when\n // the node carries domain data whose fields would otherwise leak\n // into the default walker.\n if (getSearchText) return getSearchText(node).trim().toLowerCase();\n // Match-text skips secondary children so e.g. a Table's search\n // text only draws from the Table itself, not from its Field\n // rows. The Table is primary, so its own text still counts.\n const searchChildren = children.filter((c) => !isSecondary?.(c));\n return nodeSearchText(node, searchChildren);\n }\n\n function visit(node: T): boolean {\n // A secondary node never drives a filter match — it's\n // effectively invisible to search. Still rendered when the\n // caller opens the parent manually. This is what lets a 28k-row\n // field tree stay searchable at the record level without \"field\n // name contains 'x'\" matches spamming the results.\n if (isSecondary?.(node)) return false;\n\n const key = getKey(node);\n const children = getChildren(node) ?? [];\n const childrenAllSecondary =\n children.length > 0 && children.every((child) => isSecondary?.(child));\n const matches = matchText(node, children).includes(normalizedQuery);\n const visibleChildren: T[] = [];\n\n for (const child of children) {\n if (visit(child)) visibleChildren.push(child);\n }\n\n if (matches) {\n if (children.length > 0) {\n filteredChildren.set(key, children);\n if (!childrenAllSecondary) forcedOpenKeys.add(key);\n }\n return true;\n }\n\n if (visibleChildren.length > 0) {\n filteredChildren.set(key, visibleChildren);\n forcedOpenKeys.add(key);\n return true;\n }\n\n return false;\n }\n\n return {\n roots: roots.filter((root) => visit(root)),\n filteredChildren,\n forcedOpenKeys,\n };\n}\n\nexport function Tree<T>({\n roots,\n empty,\n className,\n ariaLabel,\n showControls = true,\n expandAll: controlledExpandAll,\n onExpandAllChange,\n toolbarClassName,\n actions,\n getSearchText,\n revealSelected = false,\n ...nodeProps\n}: TreeProps<T>) {\n const [internalExpandAll, setInternalExpandAll] = useState<boolean | null>(null);\n const [filterQuery, setFilterQuery] = useState(\"\");\n const basePaddingPx = nodeProps.basePaddingPx ?? 8;\n const isControlled = onExpandAllChange !== undefined;\n const expandAll = isControlled ? (controlledExpandAll ?? null) : internalExpandAll;\n const totalEdges = useMemo(\n () => countTreeEdges(roots, nodeProps.getChildren),\n [roots, nodeProps.getChildren],\n );\n const showFilter = totalEdges > 20;\n const activeFilter = showFilter ? filterQuery : \"\";\n const filteredTree = useMemo(\n () =>\n filterTreeRoots(\n roots,\n nodeProps.getChildren,\n nodeProps.getKey,\n activeFilter,\n nodeProps.isSecondary,\n getSearchText,\n ),\n [\n roots,\n nodeProps.getChildren,\n nodeProps.getKey,\n activeFilter,\n nodeProps.isSecondary,\n getSearchText,\n ],\n );\n const treeRoots = filteredTree.roots;\n const filteredChildren = filteredTree.filteredChildren;\n // Force-open the selected node's ancestors when revealSelected is set, unioned\n // with the filter's own forced-open keys. Recomputed when the selection moves\n // so the tree follows it without a remount.\n const revealKeys = useMemo(\n () =>\n revealSelected && nodeProps.selected\n ? ancestorPathKeys(roots, nodeProps.getChildren, nodeProps.getKey, nodeProps.selected)\n : null,\n [revealSelected, roots, nodeProps.getChildren, nodeProps.getKey, nodeProps.selected],\n );\n const forcedOpenKeys = useMemo(\n () => mergeKeySets(filteredTree.forcedOpenKeys, revealKeys),\n [filteredTree.forcedOpenKeys, revealKeys],\n );\n const effectiveGetChildren = filteredChildren\n ? (node: T) => filteredChildren.get(nodeProps.getKey(node)) ?? []\n : nodeProps.getChildren;\n const effectiveExpandAll = expandAll;\n const effectiveEmpty = activeFilter.trim() ? (\n <div className=\"px-3 py-4 text-sm text-muted-foreground\">No matching tree nodes.</div>\n ) : (\n empty\n );\n const showControlButtons = showControls && roots.length > 0;\n const showVirtualRow = showFilter || showControlButtons || actions != null;\n const setExpandAll = (next: boolean | null) => {\n if (isControlled) onExpandAllChange?.(next);\n else setInternalExpandAll(next);\n };\n\n if (treeRoots.length === 0 && !showVirtualRow) return <>{effectiveEmpty ?? null}</>;\n\n return (\n <div className={cn(\"flex flex-col min-h-0\", className)}>\n <div\n role=\"tree\"\n aria-label={ariaLabel}\n className=\"min-h-0 flex-1 overflow-auto\"\n >\n {showVirtualRow && (\n <div\n role=\"presentation\"\n className={cn(\n \"sticky top-0 z-10 flex items-center gap-1.5 border-b border-border/70 bg-background/95 py-1 pr-2 text-sm backdrop-blur supports-[backdrop-filter]:bg-background/80\",\n toolbarClassName,\n )}\n style={{ paddingLeft: `${basePaddingPx}px` }}\n >\n {showFilter ? (\n <Icon icon={UiSearch} className=\"w-3 shrink-0 text-xs text-muted-foreground\" />\n ) : (\n <span className=\"w-3 shrink-0\" aria-hidden />\n )}\n\n {showFilter ? (\n <label className=\"flex min-w-0 flex-1 items-center gap-2 rounded-md border border-border bg-background px-2 py-1 text-xs text-foreground shadow-sm\">\n <input\n type=\"search\"\n value={filterQuery}\n onChange={(event) => setFilterQuery(event.target.value)}\n placeholder=\"Filter tree\"\n className=\"h-5 w-full min-w-0 border-0 bg-transparent p-0 text-xs outline-none placeholder:text-placeholder\"\n aria-label=\"Filter tree nodes\"\n />\n {filterQuery && (\n <button\n type=\"button\"\n onClick={() => setFilterQuery(\"\")}\n className=\"inline-flex items-center rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-accent-foreground\"\n aria-label=\"Clear tree filter\"\n title=\"Clear tree filter\"\n >\n <Icon icon={UiClose} className=\"text-xs\" />\n </button>\n )}\n </label>\n ) : (\n <span className=\"flex-1\" />\n )}\n\n {(showControlButtons || actions != null) && (\n <div className=\"ml-auto flex items-center gap-1\">\n {actions}\n {showControlButtons && (\n <>\n <button\n type=\"button\"\n onClick={() => setExpandAll(true)}\n aria-pressed={effectiveExpandAll === true}\n aria-label=\"Expand all\"\n title=\"Expand all\"\n disabled={activeFilter.trim().length > 0}\n className={cn(\n \"inline-flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50\",\n effectiveExpandAll === true && \"bg-accent text-accent-foreground\",\n )}\n >\n <Icon icon={UiExpandAll} className=\"text-sm\" />\n </button>\n <button\n type=\"button\"\n onClick={() => setExpandAll(false)}\n aria-pressed={effectiveExpandAll === false}\n aria-label=\"Collapse all\"\n title=\"Collapse all\"\n disabled={activeFilter.trim().length > 0}\n className={cn(\n \"inline-flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50\",\n effectiveExpandAll === false && \"bg-accent text-accent-foreground\",\n )}\n >\n <Icon icon={UiCollapseAll} className=\"text-sm\" />\n </button>\n </>\n )}\n </div>\n )}\n </div>\n )}\n\n {treeRoots.length === 0 ? (\n (effectiveEmpty ?? null)\n ) : (\n <>\n {treeRoots.map((root) => (\n <TreeNode<T>\n {...nodeProps}\n key={nodeProps.getKey(root)}\n node={root}\n expandAll={effectiveExpandAll}\n forcedOpenKeys={forcedOpenKeys}\n getChildren={effectiveGetChildren}\n />\n ))}\n </>\n )}\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Tree.js","sources":["../../src/data/Tree.tsx"],"sourcesContent":["import { useMemo, useState, type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"./Icon\";\nimport { UiClose, UiCollapseAll, UiExpandAll, UiSearch } from \"../icons\";\nimport { TreeNode, type TreeNodeProps } from \"./TreeNode\";\n\nexport type TreeProps<T> = Omit<\n TreeNodeProps<T>,\n \"node\" | \"depth\" | \"expandAll\" | \"forcedOpenKeys\"\n> & {\n /** Root nodes to render. */\n roots: T[];\n /** Empty-state content when no roots are provided. */\n empty?: ReactNode;\n /** Classes applied to the tree root. */\n className?: string;\n /** Accessible name applied to the tree root. */\n ariaLabel?: string;\n /**\n * Render the Expand all / Collapse all toolbar above the tree. Enabled by\n * default. Set to false to suppress when the tree is tiny or the controls\n * are owned externally.\n */\n showControls?: boolean;\n /** Keep search visible for small or empty trees. */\n showSearch?: boolean;\n /** URL or parent-controlled search query. */\n searchQuery?: string;\n onSearchQueryChange?: (query: string) => void;\n /**\n * Externally controlled expand-all state. When provided together with\n * `onExpandAllChange`, the tree is controlled; otherwise it manages the\n * toolbar state internally.\n */\n expandAll?: boolean | null;\n /** Called when the toolbar expand-all state changes. */\n onExpandAllChange?: (next: boolean | null) => void;\n /** Classes applied to the search/control toolbar. */\n toolbarClassName?: string;\n /**\n * Extra controls rendered in the toolbar's right-hand group, before Expand\n * all / Collapse all. Providing actions shows the toolbar even when the tree\n * is too small for the filter and `showControls` is off.\n */\n actions?: ReactNode;\n /**\n * Override the text the filter matches against for a given node.\n * Defaults to a recursive walk of the node's own fields (excluding\n * its `children` and any secondary children), which works for\n * plain-shape trees but leaks text from nested domain objects —\n * e.g. a SQL Table's Field rows are marked secondary, yet the\n * parent record still carries `record.fields[].field` strings that\n * the default walker would collect. Callers that need precise\n * control over search behaviour should return only the text they\n * want surfaced (the node's own display label / id / type).\n */\n getSearchText?: (node: T) => string;\n /**\n * Force-open the ancestors of the `selected` node so it is always revealed,\n * even when its branch was collapsed (a deep-link, a programmatic selection\n * from outside the tree, or simply a folder the user never opened). While a\n * node is selected its ancestors cannot be collapsed. Off by default; other\n * nodes keep their normal expand state. Requires `selected` to be set.\n */\n revealSelected?: boolean;\n};\n\n// ancestorPathKeys returns the keys of every ancestor on the path from a root\n// down to `target` (excluding target itself — opening the ancestors is what\n// makes target render). Matches by getKey so it is robust to object identity\n// across roots rebuilds. Returns null when target is not found.\nfunction ancestorPathKeys<T>(\n roots: T[],\n getChildren: TreeProps<T>[\"getChildren\"],\n getKey: TreeProps<T>[\"getKey\"],\n target: T,\n): Set<string | number> | null {\n const targetKey = getKey(target);\n const path: (string | number)[] = [];\n const visit = (node: T): boolean => {\n if (getKey(node) === targetKey) return true;\n for (const child of getChildren(node) ?? []) {\n if (visit(child)) {\n path.push(getKey(node));\n return true;\n }\n }\n return false;\n };\n for (const root of roots) {\n if (visit(root)) return path.length ? new Set(path) : null;\n }\n return null;\n}\n\n// mergeKeySets unions two optional key sets, preserving the null fast-path when\n// both are empty so consumers without a filter or reveal pass null downstream.\nfunction mergeKeySets(\n a: Set<string | number> | null,\n b: Set<string | number> | null,\n): Set<string | number> | null {\n if (!a) return b;\n if (!b) return a;\n return new Set([...a, ...b]);\n}\n\n// Edge counting, search-text collection and filtering all walk the tree through\n// the synchronous `getChildren` only. A lazy node (one declared via\n// `hasMoreChildren` whose children have not been fetched yet) therefore\n// contributes no edges and no search text until the operator expands it — so it\n// is invisible to \"expand all\" and to the filter while still collapsed. This is\n// intentional: we never trigger network loads from bulk/search operations.\nfunction countTreeEdges<T>(roots: T[], getChildren: TreeProps<T>[\"getChildren\"]) {\n let total = 0;\n const stack = [...roots];\n\n while (stack.length > 0) {\n const node = stack.pop()!;\n const children = getChildren(node) ?? [];\n total += children.length;\n stack.push(...children);\n }\n\n return total;\n}\n\nfunction collectTreeSearchText(\n value: unknown,\n excluded = new Set<unknown>(),\n seen = new Set<unknown>(),\n): string {\n if (value == null || excluded.has(value)) return \"\";\n\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\" ||\n typeof value === \"bigint\"\n ) {\n return String(value);\n }\n\n if (typeof value !== \"object\") return \"\";\n if (seen.has(value)) return \"\";\n seen.add(value);\n\n if (Array.isArray(value)) {\n return value\n .map((entry) => collectTreeSearchText(entry, excluded, seen))\n .filter(Boolean)\n .join(\" \");\n }\n\n const preferredKeys = [\"label\", \"name\", \"title\", \"text\", \"plain\", \"id\", \"content\"];\n const record = value as Record<string, unknown>;\n const chunks: string[] = [];\n\n for (const key of preferredKeys) {\n if (!(key in record)) continue;\n const text = collectTreeSearchText(record[key], excluded, seen);\n if (text) chunks.push(text);\n }\n\n for (const [key, entry] of Object.entries(record)) {\n if (key === \"children\" || preferredKeys.includes(key)) continue;\n const text = collectTreeSearchText(entry, excluded, seen);\n if (text) chunks.push(text);\n }\n\n return chunks.join(\" \");\n}\n\nfunction nodeSearchText<T>(node: T, children: ReturnType<TreeProps<T>[\"getChildren\"]>) {\n const excluded = new Set<unknown>();\n if (children) excluded.add(children);\n return collectTreeSearchText(node, excluded).trim().toLowerCase();\n}\n\nfunction filterTreeRoots<T>(\n roots: T[],\n getChildren: TreeProps<T>[\"getChildren\"],\n getKey: TreeProps<T>[\"getKey\"],\n query: string,\n isSecondary?: (node: T) => boolean,\n getSearchText?: (node: T) => string,\n) {\n const normalizedQuery = query.trim().toLowerCase();\n if (!normalizedQuery) {\n return {\n roots,\n filteredChildren: null as Map<string | number, T[]> | null,\n forcedOpenKeys: null as Set<string | number> | null,\n };\n }\n\n const filteredChildren = new Map<string | number, T[]>();\n const forcedOpenKeys = new Set<string | number>();\n\n function matchText(node: T, children: T[]): string {\n // Honour the caller-supplied text extractor first — it's the\n // only way to get precise control over what the filter sees when\n // the node carries domain data whose fields would otherwise leak\n // into the default walker.\n if (getSearchText) return getSearchText(node).trim().toLowerCase();\n // Match-text skips secondary children so e.g. a Table's search\n // text only draws from the Table itself, not from its Field\n // rows. The Table is primary, so its own text still counts.\n const searchChildren = children.filter((c) => !isSecondary?.(c));\n return nodeSearchText(node, searchChildren);\n }\n\n function visit(node: T): boolean {\n // A secondary node never drives a filter match — it's\n // effectively invisible to search. Still rendered when the\n // caller opens the parent manually. This is what lets a 28k-row\n // field tree stay searchable at the record level without \"field\n // name contains 'x'\" matches spamming the results.\n if (isSecondary?.(node)) return false;\n\n const key = getKey(node);\n const children = getChildren(node) ?? [];\n const childrenAllSecondary =\n children.length > 0 && children.every((child) => isSecondary?.(child));\n const matches = matchText(node, children).includes(normalizedQuery);\n const visibleChildren: T[] = [];\n\n for (const child of children) {\n if (visit(child)) visibleChildren.push(child);\n }\n\n if (matches) {\n if (children.length > 0) {\n filteredChildren.set(key, children);\n if (!childrenAllSecondary) forcedOpenKeys.add(key);\n }\n return true;\n }\n\n if (visibleChildren.length > 0) {\n filteredChildren.set(key, visibleChildren);\n forcedOpenKeys.add(key);\n return true;\n }\n\n return false;\n }\n\n return {\n roots: roots.filter((root) => visit(root)),\n filteredChildren,\n forcedOpenKeys,\n };\n}\n\nexport function Tree<T>({\n roots,\n empty,\n className,\n ariaLabel,\n showControls = true,\n showSearch = false,\n searchQuery,\n onSearchQueryChange,\n expandAll: controlledExpandAll,\n onExpandAllChange,\n toolbarClassName,\n actions,\n getSearchText,\n revealSelected = false,\n ...nodeProps\n}: TreeProps<T>) {\n const [internalExpandAll, setInternalExpandAll] = useState<boolean | null>(null);\n const [internalFilterQuery, setInternalFilterQuery] = useState(\"\");\n const filterQuery = searchQuery ?? internalFilterQuery;\n const setFilterQuery = (next: string) => {\n if (searchQuery !== undefined) onSearchQueryChange?.(next);\n else setInternalFilterQuery(next);\n };\n const basePaddingPx = nodeProps.basePaddingPx ?? 8;\n const isControlled = onExpandAllChange !== undefined;\n const expandAll = isControlled ? (controlledExpandAll ?? null) : internalExpandAll;\n const totalEdges = useMemo(\n () => countTreeEdges(roots, nodeProps.getChildren),\n [roots, nodeProps.getChildren],\n );\n const showFilter = showSearch || totalEdges > 20 || Boolean(searchQuery);\n const activeFilter = showFilter ? filterQuery : \"\";\n const filteredTree = useMemo(\n () =>\n filterTreeRoots(\n roots,\n nodeProps.getChildren,\n nodeProps.getKey,\n activeFilter,\n nodeProps.isSecondary,\n getSearchText,\n ),\n [\n roots,\n nodeProps.getChildren,\n nodeProps.getKey,\n activeFilter,\n nodeProps.isSecondary,\n getSearchText,\n ],\n );\n const treeRoots = filteredTree.roots;\n const filteredChildren = filteredTree.filteredChildren;\n // Force-open the selected node's ancestors when revealSelected is set, unioned\n // with the filter's own forced-open keys. Recomputed when the selection moves\n // so the tree follows it without a remount.\n const revealKeys = useMemo(\n () =>\n revealSelected && nodeProps.selected\n ? ancestorPathKeys(roots, nodeProps.getChildren, nodeProps.getKey, nodeProps.selected)\n : null,\n [revealSelected, roots, nodeProps.getChildren, nodeProps.getKey, nodeProps.selected],\n );\n const forcedOpenKeys = useMemo(\n () => mergeKeySets(filteredTree.forcedOpenKeys, revealKeys),\n [filteredTree.forcedOpenKeys, revealKeys],\n );\n const effectiveGetChildren = filteredChildren\n ? (node: T) => filteredChildren.get(nodeProps.getKey(node)) ?? []\n : nodeProps.getChildren;\n const effectiveExpandAll = expandAll;\n const effectiveEmpty = activeFilter.trim() ? (\n <div className=\"px-3 py-4 text-sm text-muted-foreground\">No matching tree nodes.</div>\n ) : (\n empty\n );\n const showControlButtons = showControls && roots.length > 0;\n const showVirtualRow = showFilter || showControlButtons || actions != null;\n const setExpandAll = (next: boolean | null) => {\n if (isControlled) onExpandAllChange?.(next);\n else setInternalExpandAll(next);\n };\n\n if (treeRoots.length === 0 && !showVirtualRow) return <>{effectiveEmpty ?? null}</>;\n\n return (\n <div className={cn(\"flex flex-col min-h-0\", className)}>\n <div\n role=\"tree\"\n aria-label={ariaLabel}\n className=\"min-h-0 flex-1 overflow-auto\"\n >\n {showVirtualRow && (\n <div\n role=\"presentation\"\n className={cn(\n \"sticky top-0 z-10 flex items-center gap-1.5 border-b border-border/70 bg-background/95 py-1 pr-2 text-sm backdrop-blur supports-[backdrop-filter]:bg-background/80\",\n toolbarClassName,\n )}\n style={{ paddingLeft: `${basePaddingPx}px` }}\n >\n {showFilter ? (\n <Icon icon={UiSearch} className=\"w-3 shrink-0 text-xs text-muted-foreground\" />\n ) : (\n <span className=\"w-3 shrink-0\" aria-hidden />\n )}\n\n {showFilter ? (\n <label className=\"flex min-w-0 flex-1 items-center gap-2 rounded-md border border-border bg-background px-2 py-1 text-xs text-foreground shadow-sm\">\n <input\n type=\"search\"\n value={filterQuery}\n onChange={(event) => setFilterQuery(event.target.value)}\n placeholder=\"Filter tree\"\n className=\"h-5 w-full min-w-0 border-0 bg-transparent p-0 text-xs outline-none placeholder:text-placeholder\"\n aria-label=\"Filter tree nodes\"\n />\n {filterQuery && (\n <button\n type=\"button\"\n onClick={() => setFilterQuery(\"\")}\n className=\"inline-flex items-center rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-accent-foreground\"\n aria-label=\"Clear tree filter\"\n title=\"Clear tree filter\"\n >\n <Icon icon={UiClose} className=\"text-xs\" />\n </button>\n )}\n </label>\n ) : (\n <span className=\"flex-1\" />\n )}\n\n {(showControlButtons || actions != null) && (\n <div className=\"ml-auto flex items-center gap-1\">\n {actions}\n {showControlButtons && (\n <>\n <button\n type=\"button\"\n onClick={() => setExpandAll(true)}\n aria-pressed={effectiveExpandAll === true}\n aria-label=\"Expand all\"\n title=\"Expand all\"\n disabled={activeFilter.trim().length > 0}\n className={cn(\n \"inline-flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50\",\n effectiveExpandAll === true && \"bg-accent text-accent-foreground\",\n )}\n >\n <Icon icon={UiExpandAll} className=\"text-sm\" />\n </button>\n <button\n type=\"button\"\n onClick={() => setExpandAll(false)}\n aria-pressed={effectiveExpandAll === false}\n aria-label=\"Collapse all\"\n title=\"Collapse all\"\n disabled={activeFilter.trim().length > 0}\n className={cn(\n \"inline-flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50\",\n effectiveExpandAll === false && \"bg-accent text-accent-foreground\",\n )}\n >\n <Icon icon={UiCollapseAll} className=\"text-sm\" />\n </button>\n </>\n )}\n </div>\n )}\n </div>\n )}\n\n {treeRoots.length === 0 ? (\n (effectiveEmpty ?? null)\n ) : (\n <>\n {treeRoots.map((root) => (\n <TreeNode<T>\n {...nodeProps}\n key={nodeProps.getKey(root)}\n node={root}\n expandAll={effectiveExpandAll}\n forcedOpenKeys={forcedOpenKeys}\n getChildren={effectiveGetChildren}\n />\n ))}\n </>\n )}\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -12,12 +12,70 @@ const SessionInspector_transcript = require("./SessionInspector.transcript.cjs")
12
12
  const SessionInspector_collection = require("./SessionInspector.collection.cjs");
13
13
  const SessionInspector_hierarchy = require("./SessionInspector.hierarchy.cjs");
14
14
  const SessionInspector_hierarchyState = require("./SessionInspector.hierarchy-state.cjs");
15
- const SessionViewer = require("./SessionViewer.cjs");
15
+ const SessionInspector_legacy = require("./SessionInspector.legacy.cjs");
16
+ const SessionInspector_tabState = require("./SessionInspector.tab-state.cjs");
17
+ const SessionInspector_remote = require("./SessionInspector.remote.cjs");
18
+ const SessionInspector_remoteView = require("./SessionInspector.remote-view.cjs");
16
19
  const SessionViewer_model = require("./SessionViewer.model.cjs");
17
20
  function SessionInspector({
18
21
  session,
22
+ src,
23
+ follow,
24
+ className,
25
+ ...options
26
+ }) {
27
+ if (session !== void 0 && src !== void 0) {
28
+ throw new Error(
29
+ "SessionInspector takes either `session` or `src`, not both"
30
+ );
31
+ }
32
+ if (session === void 0 && src === void 0) {
33
+ throw new Error("SessionInspector requires a `session` or a `src`");
34
+ }
35
+ const followOptions = follow === void 0 ? {} : { follow };
36
+ const remote = SessionInspector_remote.useRemoteSession(src, followOptions);
37
+ const collection = session !== void 0 && SessionInspector_collection.isSessionCollectionInput(session) ? session : void 0;
38
+ const remoteCollection = SessionInspector_remote.useRemoteCollection(collection, followOptions);
39
+ const status = src !== void 0 ? remote : remoteCollection;
40
+ const resolved = src !== void 0 ? remote.session : collection ? remoteCollection.collection : session;
41
+ const remoteBacked = src !== void 0 || collection !== void 0 && remoteCollection.collection !== collection;
42
+ if (resolved && !remoteBacked) {
43
+ return /* @__PURE__ */ jsxRuntime.jsx(
44
+ SessionInspectorView,
45
+ {
46
+ session: resolved,
47
+ ...followOptions,
48
+ ...options,
49
+ ...className ? { className } : {}
50
+ }
51
+ );
52
+ }
53
+ return /* @__PURE__ */ jsxRuntime.jsx(
54
+ SessionInspector_remoteView.RemoteSessionStatus,
55
+ {
56
+ loading: status.loading,
57
+ ...status.error ? { error: status.error } : {},
58
+ ...className ? { className } : {},
59
+ children: resolved ? /* @__PURE__ */ jsxRuntime.jsx(
60
+ SessionInspectorView,
61
+ {
62
+ session: resolved,
63
+ ...followOptions,
64
+ ...options
65
+ }
66
+ ) : null
67
+ }
68
+ );
69
+ }
70
+ function SessionInspectorView({
71
+ session,
72
+ follow,
19
73
  className,
20
74
  defaultTab = "transcript",
75
+ tab,
76
+ onTabChange,
77
+ selectedSessionIds,
78
+ onSelectedSessionIdsChange,
21
79
  transcriptProps,
22
80
  renderSessionActions,
23
81
  onPlanChange,
@@ -35,8 +93,16 @@ function SessionInspector({
35
93
  () => SessionInspector_collection.isSessionCollectionInput(session) ? session : detail ? singleSessionCollection(detail) : void 0,
36
94
  [detail, session]
37
95
  );
96
+ const tabProps = {
97
+ ...tab ? { tab } : {},
98
+ ...onTabChange ? { onTabChange } : {}
99
+ };
38
100
  if (collection) {
39
101
  const optionalProps = {
102
+ ...tabProps,
103
+ ...follow === void 0 ? {} : { follow },
104
+ ...selectedSessionIds ? { selectedSessionIds } : {},
105
+ ...onSelectedSessionIdsChange ? { onSelectedSessionIdsChange } : {},
40
106
  ...className ? { className } : {},
41
107
  ...transcriptProps ? { transcriptProps } : {},
42
108
  ...renderSessionActions ? { renderSessionActions } : {},
@@ -57,10 +123,11 @@ function SessionInspector({
57
123
  );
58
124
  }
59
125
  return /* @__PURE__ */ jsxRuntime.jsx(
60
- LegacySessionInspector,
126
+ SessionInspector_legacy.LegacySessionInspector,
61
127
  {
62
128
  session,
63
129
  defaultTab,
130
+ ...tabProps,
64
131
  ...className ? { className } : {},
65
132
  ...transcriptProps ? { transcriptProps } : {},
66
133
  ...composer ? { composer } : {},
@@ -72,8 +139,13 @@ function SessionInspector({
72
139
  }
73
140
  function CollectionSessionInspector({
74
141
  collection,
142
+ follow,
75
143
  className,
76
144
  defaultTab = "transcript",
145
+ tab: controlledTab,
146
+ onTabChange,
147
+ selectedSessionIds,
148
+ onSelectedSessionIdsChange,
77
149
  transcriptProps,
78
150
  renderSessionActions,
79
151
  onPlanChange,
@@ -83,15 +155,22 @@ function CollectionSessionInspector({
83
155
  metadata,
84
156
  toolbarActions
85
157
  }) {
86
- const hierarchy = SessionInspector_hierarchyState.useSessionHierarchy(collection);
158
+ const hierarchy = SessionInspector_hierarchyState.useSessionHierarchy(collection, {
159
+ ...selectedSessionIds ? { selectedSessionIds } : {},
160
+ ...onSelectedSessionIdsChange ? { onSelectedSessionIdsChange } : {},
161
+ ...follow === void 0 ? {} : { follow }
162
+ });
87
163
  const compact = layout === "compact";
88
164
  const [menuHost, setMenuHost] = react.useState(null);
89
165
  const outputVisible = SessionInspector_tabs_model.hasStructuredOutput(hierarchy.current);
90
- const [tab, setTab] = react.useState(
91
- defaultTab === "output" && !outputVisible ? "transcript" : defaultTab
166
+ const [tab, setTab] = SessionInspector_tabState.useInspectorTab(
167
+ defaultTab,
168
+ outputVisible,
169
+ controlledTab,
170
+ onTabChange
92
171
  );
93
172
  const transcriptClassName = utils.cn("h-full", transcriptProps == null ? void 0 : transcriptProps.className);
94
- const panelDetail = tab === "costs" ? hierarchy.filtered : hierarchy.current;
173
+ const panelDetail = tab === "costs" || tab === "verification" ? hierarchy.filtered : hierarchy.current;
95
174
  const compactMetadata = metadata ?? SessionViewer_model.getSessionMetadata(hierarchy.current);
96
175
  const compactTabs = SessionInspector_tabs_model.inspectorTabs(
97
176
  outputVisible,
@@ -117,9 +196,6 @@ function CollectionSessionInspector({
117
196
  menuHeader: compactMenuHeader,
118
197
  showMenu: menuHost !== null && (transcriptProps == null ? void 0 : transcriptProps.showMenu) !== false
119
198
  } : transcriptProps;
120
- react.useEffect(() => {
121
- if (tab === "output" && !outputVisible) setTab("transcript");
122
- }, [outputVisible, tab]);
123
199
  return /* @__PURE__ */ jsxRuntime.jsxs(
124
200
  "div",
125
201
  {
@@ -159,189 +235,89 @@ function CollectionSessionInspector({
159
235
  ),
160
236
  /* @__PURE__ */ jsxRuntime.jsx(SessionInspector_tabs.InspectorTabs, { tab, tabs: compactTabs, onSelect: setTab })
161
237
  ] }),
162
- /* @__PURE__ */ jsxRuntime.jsxs(
238
+ /* @__PURE__ */ jsxRuntime.jsx(
163
239
  "div",
164
240
  {
165
241
  className: utils.cn(
166
242
  "min-h-0 flex-1 overflow-y-auto",
167
- !compact && "grid lg:grid-cols-[minmax(0,1fr)_18rem] lg:overflow-hidden"
243
+ !compact && "flex flex-col lg:overflow-hidden"
168
244
  ),
169
- children: [
170
- /* @__PURE__ */ jsxRuntime.jsxs(
171
- "main",
172
- {
173
- className: utils.cn(
174
- "flex min-w-0 flex-col",
175
- compact ? "min-h-0" : "min-h-[28rem] lg:min-h-0"
176
- ),
177
- children: [
178
- compact ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
179
- /* @__PURE__ */ jsxRuntime.jsx(
180
- "div",
181
- {
182
- className: utils.cn(
183
- "min-h-0 flex-1 overflow-hidden",
184
- tab !== "transcript" && "hidden"
185
- ),
186
- children: /* @__PURE__ */ jsxRuntime.jsx(
187
- SessionInspector_transcript.SessionTranscript,
188
- {
189
- session: hierarchy.filtered,
190
- viewerProps: {
191
- ...compactTranscriptProps,
192
- className: transcriptClassName
193
- }
194
- }
195
- )
196
- }
197
- ),
198
- tab !== "transcript" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1 overflow-auto p-density-4", children: /* @__PURE__ */ jsxRuntime.jsx(
199
- SessionInspector_panels.SessionInspectorPanel,
200
- {
201
- tab,
202
- detail: panelDetail,
203
- session: hierarchy.current,
204
- ...onPlanChange ? { onPlanChange } : {},
205
- ...onResolveApproval ? { onResolveApproval } : {}
206
- }
207
- ) }) : null
208
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(
245
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
246
+ "main",
247
+ {
248
+ className: utils.cn(
249
+ "flex min-w-0 flex-col",
250
+ compact ? "min-h-0" : "min-h-[28rem] flex-1 lg:min-h-0"
251
+ ),
252
+ children: [
253
+ compact ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
254
+ /* @__PURE__ */ jsxRuntime.jsx(
209
255
  "div",
210
256
  {
211
257
  className: utils.cn(
212
- "min-h-0 flex-1",
213
- tab === "transcript" ? "overflow-hidden" : "overflow-auto p-density-4"
258
+ "min-h-0 flex-1 overflow-hidden",
259
+ tab !== "transcript" && "hidden"
214
260
  ),
215
- children: tab === "transcript" ? /* @__PURE__ */ jsxRuntime.jsx(
261
+ children: /* @__PURE__ */ jsxRuntime.jsx(
216
262
  SessionInspector_transcript.SessionTranscript,
217
263
  {
218
264
  session: hierarchy.filtered,
219
265
  viewerProps: {
220
- ...transcriptProps,
266
+ ...compactTranscriptProps,
221
267
  className: transcriptClassName
222
268
  }
223
269
  }
224
- ) : /* @__PURE__ */ jsxRuntime.jsx(
225
- SessionInspector_panels.SessionInspectorPanel,
226
- {
227
- tab,
228
- detail: panelDetail,
229
- session: hierarchy.current,
230
- ...onPlanChange ? { onPlanChange } : {},
231
- ...onResolveApproval ? { onResolveApproval } : {}
232
- }
233
270
  )
234
271
  }
235
272
  ),
236
- composer ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 border-t border-border p-density-3", children: composer }) : null
237
- ]
238
- }
239
- ),
240
- !compact ? /* @__PURE__ */ jsxRuntime.jsx(SessionInspector_summary.SessionInspectorSidebar, { session: hierarchy.current }) : null
241
- ]
273
+ tab !== "transcript" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1 overflow-auto p-density-4", children: /* @__PURE__ */ jsxRuntime.jsx(
274
+ SessionInspector_panels.SessionInspectorPanel,
275
+ {
276
+ tab,
277
+ detail: panelDetail,
278
+ session: hierarchy.current,
279
+ ...onPlanChange ? { onPlanChange } : {},
280
+ ...onResolveApproval ? { onResolveApproval } : {}
281
+ }
282
+ ) }) : null
283
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(
284
+ "div",
285
+ {
286
+ className: utils.cn(
287
+ "min-h-0 flex-1",
288
+ tab === "transcript" ? "overflow-hidden" : "overflow-auto p-density-4"
289
+ ),
290
+ children: tab === "transcript" ? /* @__PURE__ */ jsxRuntime.jsx(
291
+ SessionInspector_transcript.SessionTranscript,
292
+ {
293
+ session: hierarchy.filtered,
294
+ viewerProps: {
295
+ ...transcriptProps,
296
+ className: transcriptClassName
297
+ }
298
+ }
299
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
300
+ SessionInspector_panels.SessionInspectorPanel,
301
+ {
302
+ tab,
303
+ detail: panelDetail,
304
+ session: hierarchy.current,
305
+ ...onPlanChange ? { onPlanChange } : {},
306
+ ...onResolveApproval ? { onResolveApproval } : {}
307
+ }
308
+ )
309
+ }
310
+ ),
311
+ composer ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 border-t border-border p-density-3", children: composer }) : null
312
+ ]
313
+ }
314
+ )
242
315
  }
243
316
  )
244
317
  ]
245
318
  }
246
319
  );
247
320
  }
248
- function LegacySessionInspector({
249
- session,
250
- className,
251
- defaultTab = "transcript",
252
- transcriptProps,
253
- composer,
254
- layout = "default",
255
- metadata,
256
- toolbarActions
257
- }) {
258
- const compact = layout === "compact";
259
- const [menuHost, setMenuHost] = react.useState(null);
260
- const [tab, setTab] = react.useState(
261
- defaultTab === "output" ? "transcript" : defaultTab
262
- );
263
- const transcriptClassName = utils.cn("h-full", transcriptProps == null ? void 0 : transcriptProps.className);
264
- const compactTabs = SessionInspector_tabs_model.inspectorTabs(false);
265
- const compactMetadata = metadata ?? SessionViewer_model.getSessionMetadata(session);
266
- const viewerProps = compact ? {
267
- ...transcriptProps,
268
- menuContainer: menuHost,
269
- showMenu: menuHost !== null && (transcriptProps == null ? void 0 : transcriptProps.showMenu) !== false
270
- } : transcriptProps;
271
- return /* @__PURE__ */ jsxRuntime.jsxs(
272
- "div",
273
- {
274
- className: utils.cn(
275
- "flex h-full min-h-0 w-full max-w-full flex-col overflow-hidden bg-background text-sm",
276
- compact ? "@container rounded-none border-0 shadow-none" : "rounded-xl border border-border shadow-sm",
277
- className
278
- ),
279
- children: [
280
- compact ? /* @__PURE__ */ jsxRuntime.jsx(
281
- SessionInspector_compact.CompactSessionInspectorToolbar,
282
- {
283
- tabs: compactTabs,
284
- activeTab: tab,
285
- onSelect: (next) => setTab(next),
286
- onMenuHost: setMenuHost,
287
- ...compactMetadata ? { metadata: compactMetadata } : {},
288
- ...toolbarActions ? { toolbarActions } : {}
289
- }
290
- ) : /* @__PURE__ */ jsxRuntime.jsx(SessionInspector_tabs.InspectorTabs, { tab, tabs: compactTabs, onSelect: setTab }),
291
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1 flex-col overflow-hidden", children: [
292
- compact ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
293
- /* @__PURE__ */ jsxRuntime.jsx(
294
- "div",
295
- {
296
- className: utils.cn(
297
- "min-h-0 flex-1 overflow-hidden",
298
- tab !== "transcript" && "hidden"
299
- ),
300
- children: /* @__PURE__ */ jsxRuntime.jsx(
301
- SessionViewer.SessionViewer,
302
- {
303
- session,
304
- scrollable: true,
305
- showRowMetadata: true,
306
- ...viewerProps,
307
- className: transcriptClassName,
308
- showHeader: false,
309
- showContextMeter: false
310
- }
311
- )
312
- }
313
- ),
314
- tab !== "transcript" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1 overflow-auto p-density-4", children: /* @__PURE__ */ jsxRuntime.jsx(
315
- SessionInspector_panels.SessionInspectorPanel,
316
- {
317
- tab,
318
- detail: void 0,
319
- session
320
- }
321
- ) }) : null
322
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1 overflow-hidden", children: tab === "transcript" ? /* @__PURE__ */ jsxRuntime.jsx(
323
- SessionViewer.SessionViewer,
324
- {
325
- session,
326
- scrollable: true,
327
- showRowMetadata: true,
328
- ...transcriptProps,
329
- className: transcriptClassName
330
- }
331
- ) : /* @__PURE__ */ jsxRuntime.jsx(
332
- SessionInspector_panels.SessionInspectorPanel,
333
- {
334
- tab,
335
- detail: void 0,
336
- session
337
- }
338
- ) }),
339
- composer ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 border-t border-border p-density-3", children: composer }) : null
340
- ] })
341
- ]
342
- }
343
- );
344
- }
345
321
  function singleSessionCollection(session) {
346
322
  const id = session.id || "session";
347
323
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"SessionInspector.cjs","sources":["../../../src/data/ai/SessionInspector.tsx"],"sourcesContent":["import { useEffect, useMemo, useState, type ReactNode } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { SessionInspectorPanel } from \"./SessionInspector.panels\";\nimport {\n SessionInspectorHeader,\n SessionInspectorSidebar,\n} from \"./SessionInspector.summary\";\nimport { CompactSessionInspectorToolbar } from \"./SessionInspector.compact\";\nimport { InspectorTabs } from \"./SessionInspector.tabs\";\nimport {\n hasStructuredOutput,\n inspectorTabs,\n type SessionInspectorTab,\n} from \"./SessionInspector.tabs.model\";\nimport { SessionTranscript } from \"./SessionInspector.transcript\";\nimport {\n isSessionCollectionInput,\n type SessionCollectionInput,\n type SessionCollectionItem,\n type SessionInspectorInput,\n} from \"./SessionInspector.collection\";\nimport {\n SessionHierarchyPicker,\n SessionHierarchyTree,\n} from \"./SessionInspector.hierarchy\";\nimport { useSessionHierarchy } from \"./SessionInspector.hierarchy-state\";\nimport { type ApprovalResolveHandler } from \"./SessionInspector.approvals-model\";\nimport { SessionViewer, type SessionViewerProps } from \"./SessionViewer\";\nimport {\n getSessionMetadata,\n type SessionInput,\n type SessionMetadataSummary,\n} from \"./SessionViewer.model\";\nimport type { UnifiedSessionInput } from \"./SessionViewer.unified\";\n\nexport type { SessionInspectorTab } from \"./SessionInspector.tabs.model\";\n\nexport interface SessionInspectorProps {\n session: SessionInspectorInput;\n className?: string;\n /** Compact keeps tabs, runtime context, host actions, and session options on one line. */\n layout?: \"default\" | \"compact\";\n /** Runtime metadata to display in the compact context bar. Defaults to session metadata. */\n metadata?: SessionMetadataSummary;\n /** Host controls rendered before Session options in the compact toolbar. */\n toolbarActions?: ReactNode;\n defaultTab?: SessionInspectorTab;\n transcriptProps?: Omit<SessionViewerProps, \"session\">;\n renderSessionActions?: (item: SessionCollectionItem) => ReactNode;\n /** Receives edits made in the Plan tab. The inspector also keeps the draft visible locally. */\n onPlanChange?: (content: string) => void;\n /** Resolves one pending tool approval from the Approvals tab. Omitted, the\n * tab still lists pending requests but renders no Approve/Deny controls. */\n onResolveApproval?: ApprovalResolveHandler;\n composer?: ReactNode;\n}\n\nexport function SessionInspector({\n session,\n className,\n defaultTab = \"transcript\",\n transcriptProps,\n renderSessionActions,\n onPlanChange,\n onResolveApproval,\n composer,\n layout = \"default\",\n metadata,\n toolbarActions,\n}: SessionInspectorProps) {\n const detail = useMemo(\n () =>\n isSessionCollectionInput(session) ? undefined : asUnifiedSession(session),\n [session],\n );\n const collection = useMemo(\n () =>\n isSessionCollectionInput(session)\n ? session\n : detail\n ? singleSessionCollection(detail)\n : undefined,\n [detail, session],\n );\n\n if (collection) {\n const optionalProps = {\n ...(className ? { className } : {}),\n ...(transcriptProps ? { transcriptProps } : {}),\n ...(renderSessionActions ? { renderSessionActions } : {}),\n ...(onPlanChange ? { onPlanChange } : {}),\n ...(onResolveApproval ? { onResolveApproval } : {}),\n ...(composer ? { composer } : {}),\n ...(layout === \"compact\" ? { layout } : {}),\n ...(metadata ? { metadata } : {}),\n ...(toolbarActions ? { toolbarActions } : {}),\n };\n return (\n <CollectionSessionInspector\n collection={collection}\n defaultTab={defaultTab}\n {...optionalProps}\n />\n );\n }\n\n return (\n <LegacySessionInspector\n session={session as SessionInput}\n defaultTab={defaultTab}\n {...(className ? { className } : {})}\n {...(transcriptProps ? { transcriptProps } : {})}\n {...(composer ? { composer } : {})}\n {...(layout === \"compact\" ? { layout } : {})}\n {...(metadata ? { metadata } : {})}\n {...(toolbarActions ? { toolbarActions } : {})}\n />\n );\n}\n\nfunction CollectionSessionInspector({\n collection,\n className,\n defaultTab = \"transcript\",\n transcriptProps,\n renderSessionActions,\n onPlanChange,\n onResolveApproval,\n composer,\n layout = \"default\",\n metadata,\n toolbarActions,\n}: Omit<SessionInspectorProps, \"session\"> & {\n collection: SessionCollectionInput;\n}) {\n const hierarchy = useSessionHierarchy(collection);\n const compact = layout === \"compact\";\n const [menuHost, setMenuHost] = useState<HTMLSpanElement | null>(null);\n const outputVisible = hasStructuredOutput(hierarchy.current);\n const [tab, setTab] = useState<SessionInspectorTab>(\n defaultTab === \"output\" && !outputVisible ? \"transcript\" : defaultTab,\n );\n const transcriptClassName = cn(\"h-full\", transcriptProps?.className);\n const panelDetail = tab === \"costs\" ? hierarchy.filtered : hierarchy.current;\n const compactMetadata = metadata ?? getSessionMetadata(hierarchy.current);\n const compactTabs = inspectorTabs(\n outputVisible,\n hierarchy.current,\n hierarchy.filtered,\n );\n const compactMenuHeader = (\n <div className=\"w-[min(38rem,calc(100vw-4rem))]\">\n <p className=\"px-1 pb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground\">\n Session content\n </p>\n <SessionHierarchyTree\n collection={collection}\n state={hierarchy}\n {...(renderSessionActions ? { renderSessionActions } : {})}\n className=\"h-[min(32rem,52vh)]\"\n />\n {transcriptProps?.menuHeader ? (\n <div className=\"mt-1 border-t border-border pt-1\">\n {transcriptProps.menuHeader}\n </div>\n ) : null}\n </div>\n );\n const compactTranscriptProps = compact\n ? {\n ...transcriptProps,\n menuContainer: menuHost,\n menuHeader: compactMenuHeader,\n showMenu: menuHost !== null && transcriptProps?.showMenu !== false,\n }\n : transcriptProps;\n\n useEffect(() => {\n if (tab === \"output\" && !outputVisible) setTab(\"transcript\");\n }, [outputVisible, tab]);\n\n return (\n <div\n className={cn(\n \"flex h-full min-h-0 w-full max-w-full flex-col overflow-hidden bg-background text-sm\",\n compact\n ? \"@container rounded-none border-0 shadow-none\"\n : \"rounded-xl border border-border shadow-sm\",\n className,\n )}\n >\n {compact ? (\n <CompactSessionInspectorToolbar\n tabs={compactTabs}\n activeTab={tab}\n onSelect={(next) => setTab(next as SessionInspectorTab)}\n onMenuHost={setMenuHost}\n {...(compactMetadata ? { metadata: compactMetadata } : {})}\n {...(toolbarActions ? { toolbarActions } : {})}\n />\n ) : (\n <>\n <SessionInspectorHeader session={hierarchy.current} />\n <div\n role=\"toolbar\"\n aria-label=\"Session content controls\"\n className=\"flex shrink-0 justify-start border-b border-border px-density-2 py-density-2\"\n >\n <SessionHierarchyPicker\n collection={collection}\n state={hierarchy}\n {...(renderSessionActions ? { renderSessionActions } : {})}\n />\n </div>\n <InspectorTabs tab={tab} tabs={compactTabs} onSelect={setTab} />\n </>\n )}\n <div\n className={cn(\n \"min-h-0 flex-1 overflow-y-auto\",\n !compact &&\n \"grid lg:grid-cols-[minmax(0,1fr)_18rem] lg:overflow-hidden\",\n )}\n >\n <main\n className={cn(\n \"flex min-w-0 flex-col\",\n compact ? \"min-h-0\" : \"min-h-[28rem] lg:min-h-0\",\n )}\n >\n {compact ? (\n <>\n <div\n className={cn(\n \"min-h-0 flex-1 overflow-hidden\",\n tab !== \"transcript\" && \"hidden\",\n )}\n >\n <SessionTranscript\n session={hierarchy.filtered}\n viewerProps={{\n ...compactTranscriptProps,\n className: transcriptClassName,\n }}\n />\n </div>\n {tab !== \"transcript\" ? (\n <div className=\"min-h-0 flex-1 overflow-auto p-density-4\">\n <SessionInspectorPanel\n tab={tab}\n detail={panelDetail}\n session={hierarchy.current}\n {...(onPlanChange ? { onPlanChange } : {})}\n {...(onResolveApproval ? { onResolveApproval } : {})}\n />\n </div>\n ) : null}\n </>\n ) : (\n <div\n className={cn(\n \"min-h-0 flex-1\",\n tab === \"transcript\"\n ? \"overflow-hidden\"\n : \"overflow-auto p-density-4\",\n )}\n >\n {tab === \"transcript\" ? (\n <SessionTranscript\n session={hierarchy.filtered}\n viewerProps={{\n ...transcriptProps,\n className: transcriptClassName,\n }}\n />\n ) : (\n <SessionInspectorPanel\n tab={tab}\n detail={panelDetail}\n session={hierarchy.current}\n {...(onPlanChange ? { onPlanChange } : {})}\n {...(onResolveApproval ? { onResolveApproval } : {})}\n />\n )}\n </div>\n )}\n {composer ? (\n <div className=\"shrink-0 border-t border-border p-density-3\">\n {composer}\n </div>\n ) : null}\n </main>\n {!compact ? (\n <SessionInspectorSidebar session={hierarchy.current} />\n ) : null}\n </div>\n </div>\n );\n}\n\nfunction LegacySessionInspector({\n session,\n className,\n defaultTab = \"transcript\",\n transcriptProps,\n composer,\n layout = \"default\",\n metadata,\n toolbarActions,\n}: Pick<\n SessionInspectorProps,\n | \"className\"\n | \"defaultTab\"\n | \"transcriptProps\"\n | \"composer\"\n | \"layout\"\n | \"metadata\"\n | \"toolbarActions\"\n> & {\n session: SessionInput;\n}) {\n const compact = layout === \"compact\";\n const [menuHost, setMenuHost] = useState<HTMLSpanElement | null>(null);\n const [tab, setTab] = useState<SessionInspectorTab>(\n defaultTab === \"output\" ? \"transcript\" : defaultTab,\n );\n const transcriptClassName = cn(\"h-full\", transcriptProps?.className);\n const compactTabs = inspectorTabs(false);\n const compactMetadata = metadata ?? getSessionMetadata(session);\n const viewerProps = compact\n ? {\n ...transcriptProps,\n menuContainer: menuHost,\n showMenu: menuHost !== null && transcriptProps?.showMenu !== false,\n }\n : transcriptProps;\n return (\n <div\n className={cn(\n \"flex h-full min-h-0 w-full max-w-full flex-col overflow-hidden bg-background text-sm\",\n compact\n ? \"@container rounded-none border-0 shadow-none\"\n : \"rounded-xl border border-border shadow-sm\",\n className,\n )}\n >\n {compact ? (\n <CompactSessionInspectorToolbar\n tabs={compactTabs}\n activeTab={tab}\n onSelect={(next) => setTab(next as SessionInspectorTab)}\n onMenuHost={setMenuHost}\n {...(compactMetadata ? { metadata: compactMetadata } : {})}\n {...(toolbarActions ? { toolbarActions } : {})}\n />\n ) : (\n <InspectorTabs tab={tab} tabs={compactTabs} onSelect={setTab} />\n )}\n <div className=\"flex min-h-0 flex-1 flex-col overflow-hidden\">\n {compact ? (\n <>\n <div\n className={cn(\n \"min-h-0 flex-1 overflow-hidden\",\n tab !== \"transcript\" && \"hidden\",\n )}\n >\n <SessionViewer\n session={session}\n scrollable\n showRowMetadata\n {...viewerProps}\n className={transcriptClassName}\n showHeader={false}\n showContextMeter={false}\n />\n </div>\n {tab !== \"transcript\" ? (\n <div className=\"min-h-0 flex-1 overflow-auto p-density-4\">\n <SessionInspectorPanel\n tab={tab}\n detail={undefined}\n session={session}\n />\n </div>\n ) : null}\n </>\n ) : (\n <div className=\"min-h-0 flex-1 overflow-hidden\">\n {tab === \"transcript\" ? (\n <SessionViewer\n session={session}\n scrollable\n showRowMetadata\n {...transcriptProps}\n className={transcriptClassName}\n />\n ) : (\n <SessionInspectorPanel\n tab={tab}\n detail={undefined}\n session={session}\n />\n )}\n </div>\n )}\n {composer ? (\n <div className=\"shrink-0 border-t border-border p-density-3\">\n {composer}\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n\nfunction singleSessionCollection(\n session: UnifiedSessionInput,\n): SessionCollectionInput {\n const id = session.id || \"session\";\n return {\n kind: \"session-collection\",\n id,\n currentSessionId: id,\n sessions: [{ id, session }],\n };\n}\n\nfunction asUnifiedSession(\n session: SessionInput,\n): UnifiedSessionInput | undefined {\n if (typeof session !== \"object\" || session === null || Array.isArray(session))\n return undefined;\n return session as UnifiedSessionInput;\n}\n"],"names":["useMemo","isSessionCollectionInput","jsx","useSessionHierarchy","useState","hasStructuredOutput","cn","getSessionMetadata","inspectorTabs","jsxs","SessionHierarchyTree","useEffect","CompactSessionInspectorToolbar","Fragment","SessionInspectorHeader","SessionHierarchyPicker","InspectorTabs","SessionTranscript","SessionInspectorPanel","SessionInspectorSidebar","SessionViewer"],"mappings":"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"}
1
+ {"version":3,"file":"SessionInspector.cjs","sources":["../../../src/data/ai/SessionInspector.tsx"],"sourcesContent":["import { useMemo, useState, type ReactNode } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { SessionInspectorPanel } from \"./SessionInspector.panels\";\nimport { SessionInspectorHeader } from \"./SessionInspector.summary\";\nimport { CompactSessionInspectorToolbar } from \"./SessionInspector.compact\";\nimport { InspectorTabs } from \"./SessionInspector.tabs\";\nimport {\n hasStructuredOutput,\n inspectorTabs,\n type SessionInspectorTab,\n} from \"./SessionInspector.tabs.model\";\nimport { SessionTranscript } from \"./SessionInspector.transcript\";\nimport {\n isSessionCollectionInput,\n type SessionCollectionInput,\n type SessionCollectionItem,\n type SessionInspectorInput,\n} from \"./SessionInspector.collection\";\nimport {\n SessionHierarchyPicker,\n SessionHierarchyTree,\n} from \"./SessionInspector.hierarchy\";\nimport { useSessionHierarchy } from \"./SessionInspector.hierarchy-state\";\nimport { type ApprovalResolveHandler } from \"./SessionInspector.approvals-model\";\nimport { LegacySessionInspector } from \"./SessionInspector.legacy\";\nimport { useInspectorTab } from \"./SessionInspector.tab-state\";\nimport {\n useRemoteCollection,\n useRemoteSession,\n} from \"./SessionInspector.remote\";\nimport { RemoteSessionStatus } from \"./SessionInspector.remote-view\";\nimport type { SessionViewerProps } from \"./SessionViewer\";\nimport {\n getSessionMetadata,\n type SessionInput,\n type SessionMetadataSummary,\n} from \"./SessionViewer.model\";\nimport type { UnifiedSessionInput } from \"./SessionViewer.unified\";\n\nexport type { SessionInspectorTab } from \"./SessionInspector.tabs.model\";\n\n/**\n * Either an in-memory `session` or a session URL `src` (never both — the\n * types forbid it and the component throws). With `src` the inspector fetches\n * the session and follows it while it is live; see `SessionInput` for the URL\n * contract. `follow` forces (`true`) or suppresses (`false`) the live stream\n * for `src` and for collection items that carry `src`.\n */\nexport type SessionInspectorProps = SessionInspectorOptions &\n (\n | { session: SessionInspectorInput; src?: never; follow?: boolean }\n | { src: string; session?: never; follow?: boolean }\n );\n\nexport interface SessionInspectorOptions {\n className?: string;\n /** Compact keeps tabs, runtime context, host actions, and session options on one line. */\n layout?: \"default\" | \"compact\";\n /** Runtime metadata to display in the compact context bar. Defaults to session metadata. */\n metadata?: SessionMetadataSummary;\n /** Host controls rendered before Session options in the compact toolbar. */\n toolbarActions?: ReactNode;\n defaultTab?: SessionInspectorTab;\n /** Controlled active tab (e.g. from the URL); pair with `onTabChange`. */\n tab?: SessionInspectorTab;\n onTabChange?: (tab: SessionInspectorTab) => void;\n /** Controlled session-level selection of a session collection; `[]` selects\n * nothing. Omit to start from the collection's defaults. */\n selectedSessionIds?: readonly string[];\n onSelectedSessionIdsChange?: (ids: string[]) => void;\n transcriptProps?: Omit<SessionViewerProps, \"session\">;\n renderSessionActions?: (item: SessionCollectionItem) => ReactNode;\n /** Receives edits made in the Plan tab. The inspector also keeps the draft visible locally. */\n onPlanChange?: (content: string) => void;\n /** Resolves one pending tool approval from the Approvals tab. Omitted, the\n * tab still lists pending requests but renders no Approve/Deny controls. */\n onResolveApproval?: ApprovalResolveHandler;\n composer?: ReactNode;\n}\n\nexport function SessionInspector({\n session,\n src,\n follow,\n className,\n ...options\n}: SessionInspectorProps) {\n if (session !== undefined && src !== undefined) {\n throw new Error(\n \"SessionInspector takes either `session` or `src`, not both\",\n );\n }\n if (session === undefined && src === undefined) {\n throw new Error(\"SessionInspector requires a `session` or a `src`\");\n }\n const followOptions = follow === undefined ? {} : { follow };\n const remote = useRemoteSession(src, followOptions);\n const collection =\n session !== undefined && isSessionCollectionInput(session)\n ? session\n : undefined;\n const remoteCollection = useRemoteCollection(collection, followOptions);\n const status = src !== undefined ? remote : remoteCollection;\n const resolved: SessionInspectorInput | undefined =\n src !== undefined\n ? remote.session\n : collection\n ? remoteCollection.collection\n : session;\n\n // A URL-backed inspector always renders inside the status wrapper, so an\n // error arriving mid-follow adds the alert without remounting the view.\n const remoteBacked =\n src !== undefined ||\n (collection !== undefined && remoteCollection.collection !== collection);\n if (resolved && !remoteBacked) {\n return (\n <SessionInspectorView\n session={resolved}\n {...followOptions}\n {...options}\n {...(className ? { className } : {})}\n />\n );\n }\n return (\n <RemoteSessionStatus\n loading={status.loading}\n {...(status.error ? { error: status.error } : {})}\n {...(className ? { className } : {})}\n >\n {resolved ? (\n <SessionInspectorView\n session={resolved}\n {...followOptions}\n {...options}\n />\n ) : null}\n </RemoteSessionStatus>\n );\n}\n\nfunction SessionInspectorView({\n session,\n follow,\n className,\n defaultTab = \"transcript\",\n tab,\n onTabChange,\n selectedSessionIds,\n onSelectedSessionIdsChange,\n transcriptProps,\n renderSessionActions,\n onPlanChange,\n onResolveApproval,\n composer,\n layout = \"default\",\n metadata,\n toolbarActions,\n}: SessionInspectorOptions & {\n session: SessionInspectorInput;\n follow?: boolean;\n}) {\n const detail = useMemo(\n () =>\n isSessionCollectionInput(session) ? undefined : asUnifiedSession(session),\n [session],\n );\n const collection = useMemo(\n () =>\n isSessionCollectionInput(session)\n ? session\n : detail\n ? singleSessionCollection(detail)\n : undefined,\n [detail, session],\n );\n\n const tabProps = {\n ...(tab ? { tab } : {}),\n ...(onTabChange ? { onTabChange } : {}),\n };\n\n if (collection) {\n const optionalProps = {\n ...tabProps,\n ...(follow === undefined ? {} : { follow }),\n ...(selectedSessionIds ? { selectedSessionIds } : {}),\n ...(onSelectedSessionIdsChange ? { onSelectedSessionIdsChange } : {}),\n ...(className ? { className } : {}),\n ...(transcriptProps ? { transcriptProps } : {}),\n ...(renderSessionActions ? { renderSessionActions } : {}),\n ...(onPlanChange ? { onPlanChange } : {}),\n ...(onResolveApproval ? { onResolveApproval } : {}),\n ...(composer ? { composer } : {}),\n ...(layout === \"compact\" ? { layout } : {}),\n ...(metadata ? { metadata } : {}),\n ...(toolbarActions ? { toolbarActions } : {}),\n };\n return (\n <CollectionSessionInspector\n collection={collection}\n defaultTab={defaultTab}\n {...optionalProps}\n />\n );\n }\n\n return (\n <LegacySessionInspector\n session={session as SessionInput}\n defaultTab={defaultTab}\n {...tabProps}\n {...(className ? { className } : {})}\n {...(transcriptProps ? { transcriptProps } : {})}\n {...(composer ? { composer } : {})}\n {...(layout === \"compact\" ? { layout } : {})}\n {...(metadata ? { metadata } : {})}\n {...(toolbarActions ? { toolbarActions } : {})}\n />\n );\n}\n\nfunction CollectionSessionInspector({\n collection,\n follow,\n className,\n defaultTab = \"transcript\",\n tab: controlledTab,\n onTabChange,\n selectedSessionIds,\n onSelectedSessionIdsChange,\n transcriptProps,\n renderSessionActions,\n onPlanChange,\n onResolveApproval,\n composer,\n layout = \"default\",\n metadata,\n toolbarActions,\n}: SessionInspectorOptions & {\n collection: SessionCollectionInput;\n follow?: boolean;\n}) {\n const hierarchy = useSessionHierarchy(collection, {\n ...(selectedSessionIds ? { selectedSessionIds } : {}),\n ...(onSelectedSessionIdsChange ? { onSelectedSessionIdsChange } : {}),\n ...(follow === undefined ? {} : { follow }),\n });\n const compact = layout === \"compact\";\n const [menuHost, setMenuHost] = useState<HTMLSpanElement | null>(null);\n const outputVisible = hasStructuredOutput(hierarchy.current);\n const [tab, setTab] = useInspectorTab(\n defaultTab,\n outputVisible,\n controlledTab,\n onTabChange,\n );\n const transcriptClassName = cn(\"h-full\", transcriptProps?.className);\n const panelDetail =\n tab === \"costs\" || tab === \"verification\"\n ? hierarchy.filtered\n : hierarchy.current;\n const compactMetadata = metadata ?? getSessionMetadata(hierarchy.current);\n const compactTabs = inspectorTabs(\n outputVisible,\n hierarchy.current,\n hierarchy.filtered,\n );\n const compactMenuHeader = (\n <div className=\"w-[min(38rem,calc(100vw-4rem))]\">\n <p className=\"px-1 pb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground\">\n Session content\n </p>\n <SessionHierarchyTree\n collection={collection}\n state={hierarchy}\n {...(renderSessionActions ? { renderSessionActions } : {})}\n className=\"h-[min(32rem,52vh)]\"\n />\n {transcriptProps?.menuHeader ? (\n <div className=\"mt-1 border-t border-border pt-1\">\n {transcriptProps.menuHeader}\n </div>\n ) : null}\n </div>\n );\n const compactTranscriptProps = compact\n ? {\n ...transcriptProps,\n menuContainer: menuHost,\n menuHeader: compactMenuHeader,\n showMenu: menuHost !== null && transcriptProps?.showMenu !== false,\n }\n : transcriptProps;\n\n return (\n <div\n className={cn(\n \"flex h-full min-h-0 w-full max-w-full flex-col overflow-hidden bg-background text-sm\",\n compact\n ? \"@container rounded-none border-0 shadow-none\"\n : \"rounded-xl border border-border shadow-sm\",\n className,\n )}\n >\n {compact ? (\n <CompactSessionInspectorToolbar\n tabs={compactTabs}\n activeTab={tab}\n onSelect={(next) => setTab(next as SessionInspectorTab)}\n onMenuHost={setMenuHost}\n {...(compactMetadata ? { metadata: compactMetadata } : {})}\n {...(toolbarActions ? { toolbarActions } : {})}\n />\n ) : (\n <>\n <SessionInspectorHeader session={hierarchy.current} />\n <div\n role=\"toolbar\"\n aria-label=\"Session content controls\"\n className=\"flex shrink-0 justify-start border-b border-border px-density-2 py-density-2\"\n >\n <SessionHierarchyPicker\n collection={collection}\n state={hierarchy}\n {...(renderSessionActions ? { renderSessionActions } : {})}\n />\n </div>\n <InspectorTabs tab={tab} tabs={compactTabs} onSelect={setTab} />\n </>\n )}\n <div\n className={cn(\n \"min-h-0 flex-1 overflow-y-auto\",\n !compact && \"flex flex-col lg:overflow-hidden\",\n )}\n >\n <main\n className={cn(\n \"flex min-w-0 flex-col\",\n compact ? \"min-h-0\" : \"min-h-[28rem] flex-1 lg:min-h-0\",\n )}\n >\n {compact ? (\n <>\n <div\n className={cn(\n \"min-h-0 flex-1 overflow-hidden\",\n tab !== \"transcript\" && \"hidden\",\n )}\n >\n <SessionTranscript\n session={hierarchy.filtered}\n viewerProps={{\n ...compactTranscriptProps,\n className: transcriptClassName,\n }}\n />\n </div>\n {tab !== \"transcript\" ? (\n <div className=\"min-h-0 flex-1 overflow-auto p-density-4\">\n <SessionInspectorPanel\n tab={tab}\n detail={panelDetail}\n session={hierarchy.current}\n {...(onPlanChange ? { onPlanChange } : {})}\n {...(onResolveApproval ? { onResolveApproval } : {})}\n />\n </div>\n ) : null}\n </>\n ) : (\n <div\n className={cn(\n \"min-h-0 flex-1\",\n tab === \"transcript\"\n ? \"overflow-hidden\"\n : \"overflow-auto p-density-4\",\n )}\n >\n {tab === \"transcript\" ? (\n <SessionTranscript\n session={hierarchy.filtered}\n viewerProps={{\n ...transcriptProps,\n className: transcriptClassName,\n }}\n />\n ) : (\n <SessionInspectorPanel\n tab={tab}\n detail={panelDetail}\n session={hierarchy.current}\n {...(onPlanChange ? { onPlanChange } : {})}\n {...(onResolveApproval ? { onResolveApproval } : {})}\n />\n )}\n </div>\n )}\n {composer ? (\n <div className=\"shrink-0 border-t border-border p-density-3\">\n {composer}\n </div>\n ) : null}\n </main>\n </div>\n </div>\n );\n}\n\nfunction singleSessionCollection(\n session: UnifiedSessionInput,\n): SessionCollectionInput {\n const id = session.id || \"session\";\n return {\n kind: \"session-collection\",\n id,\n currentSessionId: id,\n sessions: [{ id, session }],\n };\n}\n\nfunction asUnifiedSession(\n session: SessionInput,\n): UnifiedSessionInput | undefined {\n if (typeof session !== \"object\" || session === null || Array.isArray(session))\n return undefined;\n return session as UnifiedSessionInput;\n}\n"],"names":["useRemoteSession","isSessionCollectionInput","useRemoteCollection","jsx","RemoteSessionStatus","useMemo","LegacySessionInspector","useSessionHierarchy","useState","hasStructuredOutput","useInspectorTab","cn","getSessionMetadata","inspectorTabs","jsxs","SessionHierarchyTree","CompactSessionInspectorToolbar","Fragment","SessionInspectorHeader","SessionHierarchyPicker","InspectorTabs","SessionTranscript","SessionInspectorPanel"],"mappings":"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"}
@@ -20,6 +20,11 @@ export interface SessionCollectionItem {
20
20
  status?: string;
21
21
  summary?: SessionCollectionSummary;
22
22
  session?: UnifiedSessionInput;
23
+ /** Session URL (see `SessionInput`'s src contract) loaded — and followed
24
+ * while live — when the item is current or selected. Ignored when
25
+ * `session` is present; takes precedence over the collection's
26
+ * `loadSession`. */
27
+ src?: string;
23
28
  }
24
29
  export interface SessionCollectionInput {
25
30
  kind: "session-collection";