@rho-workspace/rho 0.5.6 → 0.5.7

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 (211) hide show
  1. package/dist/agent-connect.d.ts +36 -2
  2. package/dist/agent-connect.js +64 -11
  3. package/dist/answer-board.js +3 -3
  4. package/dist/bridge.js +6 -1
  5. package/dist/browser-access.d.ts +1 -0
  6. package/dist/browser-access.js +5 -3
  7. package/dist/capabilities.d.ts +21 -5
  8. package/dist/capabilities.js +6 -4
  9. package/dist/cli.js +76 -11
  10. package/dist/composition.d.ts +1 -1
  11. package/dist/composition.js +13 -3
  12. package/dist/connect-cli.d.ts +50 -0
  13. package/dist/connect-cli.js +128 -0
  14. package/dist/contract.generated.d.ts +1191 -278
  15. package/dist/contract.generated.js +1 -1
  16. package/dist/contracts/owners.generated.js +845 -47
  17. package/dist/conversation-presentation.d.ts +9 -2
  18. package/dist/conversation-presentation.js +3 -1
  19. package/dist/conversations.d.ts +154 -8
  20. package/dist/conversations.js +147 -24
  21. package/dist/discovery.js +2 -2
  22. package/dist/extension-contract.d.ts +19 -0
  23. package/dist/extension-contract.js +15 -6
  24. package/dist/extension-markets.d.ts +74 -0
  25. package/dist/extension-markets.js +166 -0
  26. package/dist/extensions.d.ts +29 -1
  27. package/dist/extensions.js +13 -4
  28. package/dist/external-work.d.ts +22 -0
  29. package/dist/external-work.js +91 -0
  30. package/dist/plugin-cli.js +75 -3
  31. package/dist/plugin-inventory.d.ts +56 -0
  32. package/dist/plugin-inventory.js +41 -0
  33. package/dist/plugin-inventory.json +1581 -102
  34. package/dist/plugin-presentation.d.ts +105 -2
  35. package/dist/plugin-presentation.js +59 -5
  36. package/dist/plugins.d.ts +14 -3
  37. package/dist/plugins.js +12 -6
  38. package/dist/project-notes.js +1 -1
  39. package/dist/protocol.d.ts +6 -0
  40. package/dist/protocol.js +30 -12
  41. package/dist/replay.js +4 -0
  42. package/dist/response-contracts.js +26 -11
  43. package/dist/running.d.ts +10 -0
  44. package/dist/running.js +45 -0
  45. package/dist/server.d.ts +2 -0
  46. package/dist/server.js +71 -8
  47. package/dist/state.d.ts +8 -0
  48. package/dist/state.js +8 -0
  49. package/dist/studio-layout.js +3 -3
  50. package/dist/task-frame.d.ts +1 -1
  51. package/dist/timeline-events.d.ts +1 -0
  52. package/dist/timeline-events.js +8 -1
  53. package/dist/ui-context.d.ts +73 -0
  54. package/dist/ui-context.js +98 -0
  55. package/dist/ui-contract.d.ts +23 -0
  56. package/dist/web/.vite/manifest.json +133 -74
  57. package/dist/web/assets/answer-board-CeYS8k8y.js +1 -0
  58. package/dist/web/assets/choices-D8vGwsl2.js +1 -0
  59. package/dist/web/assets/{console-Trqc0swD.js → console-Dyuo1q4N.js} +4 -4
  60. package/dist/web/assets/{dist-pF902jHA.js → dist-CSiCyBml.js} +1 -1
  61. package/dist/web/assets/{dist-DpIHRk3B.js → dist-D9FLb9Hm.js} +1 -1
  62. package/dist/web/assets/{dist-eMx6b8N1.js → dist-FXbTBwML.js} +1 -1
  63. package/dist/web/assets/{dist-DZmszrjG.js → dist-l3DUhbw5.js} +1 -1
  64. package/dist/web/assets/{explore-in-BCHqjJ7B.js → explore-in-BfSFGRh2.js} +1 -1
  65. package/dist/web/assets/graph-BU2_o5uA.js +2 -0
  66. package/dist/web/assets/index-C16mXVvk.css +1 -0
  67. package/dist/web/assets/index-CWg9XYXx.js +952 -0
  68. package/dist/web/assets/markdown.reader-Ct2-e2Zt.png +0 -0
  69. package/dist/web/assets/{notes-meaning-DcVGUBBY.js → notes-meaning-T2m5zQfv.js} +1 -1
  70. package/dist/web/assets/overview-PzfLJCo-.js +6 -0
  71. package/dist/web/assets/preview-BguEdsza.js +1 -0
  72. package/dist/web/assets/previews-pWNik-2g.js +3 -0
  73. package/dist/web/assets/{review-DYP0aCXb.js → review-Dy_85lcH.js} +1 -1
  74. package/dist/web/assets/rho.editor-CCJeyHma.png +0 -0
  75. package/dist/web/assets/rho.flow-WkMj6fRS.png +0 -0
  76. package/dist/web/assets/rho.media-Cc6amodO.png +0 -0
  77. package/dist/web/assets/rho.notebook-6vsZKGDq.png +0 -0
  78. package/dist/web/assets/rho.object-BGoeXjte.png +0 -0
  79. package/dist/web/assets/rho.plots-yIiISCkb.png +0 -0
  80. package/dist/web/assets/rho.scatter-DwHxesCs.png +0 -0
  81. package/dist/web/assets/rho.servers-DKf_mnNq.png +0 -0
  82. package/dist/web/assets/rho.table-DWOGaWDa.png +0 -0
  83. package/dist/web/assets/rho.variables-CKcWczhQ.png +0 -0
  84. package/dist/web/assets/{skills-1ec0Z-jx.js → skills-Dyz7mBlc.js} +1 -1
  85. package/dist/web/assets/{skills-work-DNexV4OJ.js → skills-work-BEGqlCkx.js} +1 -1
  86. package/dist/web/assets/studio-process-D-ykbC4D.js +2 -0
  87. package/dist/web/assets/timeline-events-DKTho9fU.js +1 -0
  88. package/dist/web/assets/work-turns-DSabCogR.js +1 -0
  89. package/dist/web/assets/{workspace-COmCbGV3.js → workspace-DfjBL--r.js} +2 -2
  90. package/dist/web/composition.json +138 -83
  91. package/dist/web/index.html +3 -3
  92. package/dist/web/renderer.json +1 -1
  93. package/dist/web-assets.js +2 -2
  94. package/dist/work-graph.d.ts +11 -1
  95. package/dist/work-graph.js +16 -5
  96. package/dist/workspace.d.ts +2 -2
  97. package/dist/workspace.js +8 -7
  98. package/docs/FRONTEND.md +53 -11
  99. package/docs/HEADLESS.md +104 -11
  100. package/docs/THIRD-PARTY-PLUGINS.md +75 -3
  101. package/node_modules/@rho-workspace/plugin-agent/README.md +5 -0
  102. package/node_modules/@rho-workspace/plugin-agent/dist/acp-command.d.ts +31 -0
  103. package/node_modules/@rho-workspace/plugin-agent/dist/acp-command.js +45 -10
  104. package/node_modules/@rho-workspace/plugin-agent/dist/acp-conversation.js +19 -3
  105. package/node_modules/@rho-workspace/plugin-agent/dist/external-session-contract.js +3 -2
  106. package/node_modules/@rho-workspace/plugin-agent/dist/external-session.d.ts +1 -1
  107. package/node_modules/@rho-workspace/plugin-agent/dist/index.d.ts +8 -0
  108. package/node_modules/@rho-workspace/plugin-agent/dist/index.js +3 -2
  109. package/node_modules/@rho-workspace/plugin-agent/dist/mcp-entry.d.ts +13 -0
  110. package/node_modules/@rho-workspace/plugin-agent/dist/mcp-entry.js +13 -0
  111. package/node_modules/@rho-workspace/plugin-agent/dist/mcp.js +16 -8
  112. package/node_modules/@rho-workspace/plugin-agent/dist/native-sessions.d.ts +1 -1
  113. package/node_modules/@rho-workspace/plugin-agent/package.json +1 -1
  114. package/node_modules/@rho-workspace/plugin-figures/LICENSE +661 -0
  115. package/node_modules/@rho-workspace/plugin-figures/README.md +191 -0
  116. package/node_modules/@rho-workspace/plugin-figures/dist/index.d.ts +236 -0
  117. package/node_modules/@rho-workspace/plugin-figures/dist/index.js +165 -0
  118. package/node_modules/@rho-workspace/plugin-figures/dist/operations.d.ts +44 -0
  119. package/node_modules/@rho-workspace/plugin-figures/dist/operations.js +39 -0
  120. package/node_modules/@rho-workspace/plugin-figures/dist/presentation.d.ts +19 -0
  121. package/node_modules/@rho-workspace/plugin-figures/dist/presentation.js +26 -0
  122. package/node_modules/@rho-workspace/plugin-figures/dist/record.d.ts +188 -0
  123. package/node_modules/@rho-workspace/plugin-figures/dist/record.js +143 -0
  124. package/node_modules/@rho-workspace/plugin-figures/dist/ui-styles.d.ts +1 -0
  125. package/node_modules/@rho-workspace/plugin-figures/dist/ui-styles.js +68 -0
  126. package/node_modules/@rho-workspace/plugin-figures/dist/ui.d.ts +56 -0
  127. package/node_modules/@rho-workspace/plugin-figures/dist/ui.js +363 -0
  128. package/node_modules/@rho-workspace/plugin-figures/package.json +41 -0
  129. package/node_modules/@rho-workspace/plugin-figures/py/figures.py +856 -0
  130. package/node_modules/@rho-workspace/plugin-figures/r/figures.R +775 -0
  131. package/node_modules/@rho-workspace/plugin-kernel/README.md +27 -3
  132. package/node_modules/@rho-workspace/plugin-kernel/dist/contract.d.ts +12 -0
  133. package/node_modules/@rho-workspace/plugin-kernel/dist/contract.js +8 -1
  134. package/node_modules/@rho-workspace/plugin-kernel/dist/index.d.ts +61 -0
  135. package/node_modules/@rho-workspace/plugin-kernel/dist/index.js +125 -9
  136. package/node_modules/@rho-workspace/plugin-kernel/dist/session-scope.d.ts +14 -0
  137. package/node_modules/@rho-workspace/plugin-kernel/dist/session-scope.js +9 -0
  138. package/node_modules/@rho-workspace/plugin-kernel/dist/ui-base.d.ts +23 -5
  139. package/node_modules/@rho-workspace/plugin-kernel/dist/ui-notebook-work.js +1 -1
  140. package/node_modules/@rho-workspace/plugin-kernel/dist/ui-notebook.d.ts +6 -4
  141. package/node_modules/@rho-workspace/plugin-kernel/dist/ui-notebook.js +44 -17
  142. package/node_modules/@rho-workspace/plugin-kernel/dist/ui-styles.js +6 -0
  143. package/node_modules/@rho-workspace/plugin-kernel/package.json +1 -1
  144. package/node_modules/@rho-workspace/plugin-kernel/runners/runner.R +144 -4
  145. package/node_modules/@rho-workspace/plugin-kernel/runners/runner.py +106 -1
  146. package/node_modules/@rho-workspace/plugin-tables/README.md +5 -0
  147. package/node_modules/@rho-workspace/plugin-tables/dist/index.d.ts +1 -0
  148. package/node_modules/@rho-workspace/plugin-tables/dist/index.js +19 -3
  149. package/node_modules/@rho-workspace/plugin-tables/dist/ui.js +1 -1
  150. package/node_modules/@rho-workspace/plugin-tables/package.json +1 -1
  151. package/node_modules/jose/dist/webapi/jwe/general/decrypt.js +3 -2
  152. package/node_modules/jose/dist/webapi/jwks/remote.js +1 -1
  153. package/node_modules/jose/dist/webapi/jws/general/verify.js +2 -8
  154. package/node_modules/jose/dist/webapi/lib/jwe_decrypt.js +11 -8
  155. package/node_modules/jose/dist/webapi/lib/key_management.js +0 -1
  156. package/node_modules/jose/package.json +1 -1
  157. package/package.json +6 -4
  158. package/protocol/index.json +91 -55
  159. package/protocol/operations/agent.sessions.list.json +13 -5
  160. package/protocol/operations/agent.sessions.read.json +13 -5
  161. package/protocol/operations/capability.list.json +382 -6
  162. package/protocol/operations/composition.apply.json +10 -2
  163. package/protocol/operations/composition.delete.json +845 -0
  164. package/protocol/operations/composition.read.json +10 -2
  165. package/protocol/operations/composition.undo.json +10 -2
  166. package/protocol/operations/conversation.agents.add.json +346 -0
  167. package/protocol/operations/conversation.agents.remove.json +340 -0
  168. package/protocol/operations/conversation.decide.json +196 -0
  169. package/protocol/operations/conversation.permission.json +196 -0
  170. package/protocol/operations/conversation.read.json +196 -0
  171. package/protocol/operations/conversation.send.json +265 -0
  172. package/protocol/operations/conversation.settings.check.json +213 -495
  173. package/protocol/operations/conversation.settings.read.json +211 -490
  174. package/protocol/operations/conversation.settings.update.json +235 -554
  175. package/protocol/operations/conversation.start.json +267 -5
  176. package/protocol/operations/conversation.stop.json +196 -0
  177. package/protocol/operations/extension.describe.json +39 -0
  178. package/protocol/operations/extension.install.json +62 -0
  179. package/protocol/operations/extension.list.json +164 -1
  180. package/protocol/operations/extension.market.change.json +210 -0
  181. package/protocol/operations/figure.read.json +265 -0
  182. package/protocol/operations/figure.select.json +157 -0
  183. package/protocol/operations/kernel.interrupt.json +119 -0
  184. package/protocol/operations/kernel.read.json +119 -0
  185. package/protocol/operations/kernel.run.json +119 -0
  186. package/protocol/operations/observation.snapshot.json +416 -8
  187. package/protocol/operations/project.openFile.json +10 -2
  188. package/protocol/operations/session.grant.json +4 -0
  189. package/protocol/operations/shared.json +1 -0
  190. package/protocol/operations/view.close.json +10 -2
  191. package/protocol/operations/view.protection.set.json +10 -2
  192. package/vendor/composition.json +177 -112
  193. package/vendor/rho-workspace-plugin-agent-0.4.33.tgz +0 -0
  194. package/vendor/rho-workspace-plugin-figures-0.5.1.tgz +0 -0
  195. package/vendor/rho-workspace-plugin-kernel-0.5.13.tgz +0 -0
  196. package/vendor/rho-workspace-plugin-tables-0.5.2.tgz +0 -0
  197. package/web/theme.css +5 -0
  198. package/dist/web/assets/answer-board-CBkGbSLD.js +0 -1
  199. package/dist/web/assets/canvas-D8rDdfDz.js +0 -1
  200. package/dist/web/assets/choices-D-YfnFP6.js +0 -1
  201. package/dist/web/assets/graph-lENgfQNH.js +0 -2
  202. package/dist/web/assets/index-B3_OVy91.css +0 -1
  203. package/dist/web/assets/index-BpL_Kl_s.js +0 -892
  204. package/dist/web/assets/overview-CDnVKlOt.js +0 -6
  205. package/dist/web/assets/preview-BEC1E9MK.js +0 -1
  206. package/dist/web/assets/studio-process-EYQgikxq.js +0 -2
  207. package/dist/web/assets/timeline-events-Chj2Gbx7.js +0 -1
  208. package/dist/web/assets/work-turns-CT9RVcWY.js +0 -1
  209. package/vendor/rho-workspace-plugin-agent-0.4.30.tgz +0 -0
  210. package/vendor/rho-workspace-plugin-kernel-0.5.5.tgz +0 -0
  211. package/vendor/rho-workspace-plugin-tables-0.5.0.tgz +0 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "format": "rho.web-build/1",
3
3
  "uiProtocol": "0.1-draft",
4
- "rendererBuild": "094bee327d7964c2c6ea9fe3db6d35899545d090074c964d0cdb056f556471f1",
4
+ "rendererBuild": "c91ca90733547979438dc656e21b4881d5df05f971152e686d48b89585294a48",
5
5
  "ownerEntries": [
6
6
  {
7
7
  "plugin": "documents",
@@ -20,8 +20,8 @@
20
20
  "component": "rho.table",
21
21
  "version": "0.2.0",
22
22
  "source": "web/entries/tables.tsx",
23
- "packageVersion": "0.5.0",
24
- "entrySha256": "e11c5f8259554ce91abf00c84558ad7b97ea09577379825407ccab0561363730"
23
+ "packageVersion": "0.5.2",
24
+ "entrySha256": "3d550c002d3b3462a7869afeb12f60cfbe77b476ae26a576054c1c34b449cf33"
25
25
  },
26
26
  {
27
27
  "plugin": "charts",
@@ -60,7 +60,7 @@
60
60
  "component": "rho.agent-note",
61
61
  "version": "0.2.0",
62
62
  "source": "web/entries/agent.tsx",
63
- "packageVersion": "0.4.30",
63
+ "packageVersion": "0.4.33",
64
64
  "entrySha256": "0e18d175dfc25fd8e237ec0341422e0d1311d2d8882e487962e8c7c25794d69e"
65
65
  },
66
66
  {
@@ -71,7 +71,7 @@
71
71
  "version": "1",
72
72
  "source": "web/entries/kernel.tsx",
73
73
  "export": "notebook",
74
- "packageVersion": "0.5.5",
74
+ "packageVersion": "0.5.13",
75
75
  "entrySha256": "b5a012c8cd766e04cafb550e62eeec1c3b85eae07ac2fa69175f472268ddfbb2"
76
76
  },
77
77
  {
@@ -82,7 +82,7 @@
82
82
  "version": "1",
83
83
  "source": "web/entries/kernel.tsx",
84
84
  "export": "variables",
85
- "packageVersion": "0.5.5",
85
+ "packageVersion": "0.5.13",
86
86
  "entrySha256": "b5a012c8cd766e04cafb550e62eeec1c3b85eae07ac2fa69175f472268ddfbb2"
87
87
  },
88
88
  {
@@ -93,7 +93,7 @@
93
93
  "version": "1",
94
94
  "source": "web/entries/kernel.tsx",
95
95
  "export": "plots",
96
- "packageVersion": "0.5.5",
96
+ "packageVersion": "0.5.13",
97
97
  "entrySha256": "b5a012c8cd766e04cafb550e62eeec1c3b85eae07ac2fa69175f472268ddfbb2"
98
98
  },
99
99
  {
@@ -104,7 +104,7 @@
104
104
  "version": "1",
105
105
  "source": "web/entries/kernel.tsx",
106
106
  "export": "flow",
107
- "packageVersion": "0.5.5",
107
+ "packageVersion": "0.5.13",
108
108
  "entrySha256": "b5a012c8cd766e04cafb550e62eeec1c3b85eae07ac2fa69175f472268ddfbb2"
109
109
  },
110
110
  {
@@ -115,7 +115,7 @@
115
115
  "version": "1",
116
116
  "source": "web/entries/kernel.tsx",
117
117
  "export": "servers",
118
- "packageVersion": "0.5.5",
118
+ "packageVersion": "0.5.13",
119
119
  "entrySha256": "b5a012c8cd766e04cafb550e62eeec1c3b85eae07ac2fa69175f472268ddfbb2"
120
120
  },
121
121
  {
@@ -126,7 +126,7 @@
126
126
  "version": "1",
127
127
  "source": "web/entries/kernel.tsx",
128
128
  "export": "object",
129
- "packageVersion": "0.5.5",
129
+ "packageVersion": "0.5.13",
130
130
  "entrySha256": "b5a012c8cd766e04cafb550e62eeec1c3b85eae07ac2fa69175f472268ddfbb2"
131
131
  },
132
132
  {
@@ -254,23 +254,18 @@
254
254
  "assets": [
255
255
  {
256
256
  "path": ".vite/manifest.json",
257
- "bytes": 23614,
258
- "sha256": "2dc60f63158b05c257607125515a2cdd1c31059f96cf596a31c88bb20dbf6576"
259
- },
260
- {
261
- "path": "assets/answer-board-CBkGbSLD.js",
262
- "bytes": 4040,
263
- "sha256": "2d1a41d6ce8a1ad1e06c6eb26bf33520b467b1fcb3a158d6c585c6b9140a0bc6"
257
+ "bytes": 25499,
258
+ "sha256": "9eba9a613f0ffb1372bf3b8637a297c2225674699d5d77c69da6ecf36c2b01df"
264
259
  },
265
260
  {
266
- "path": "assets/canvas-D8rDdfDz.js",
267
- "bytes": 20318,
268
- "sha256": "cd9dfbef068bacb28e1327cd137b26fff32004288a0827152ec532abc24f7558"
261
+ "path": "assets/answer-board-CeYS8k8y.js",
262
+ "bytes": 4206,
263
+ "sha256": "1084e56f250fba2f5e0ccdf79ef244e978a98967d5fe41fcfc0176737f006b0c"
269
264
  },
270
265
  {
271
- "path": "assets/choices-D-YfnFP6.js",
272
- "bytes": 11096,
273
- "sha256": "29d0563c9bf57492a6aee0c373d1da152594435c35708b5d2b6a7c79f18f6a33"
266
+ "path": "assets/choices-D8vGwsl2.js",
267
+ "bytes": 11097,
268
+ "sha256": "987f7ea23f75c4214e3e688cd5778b86012f78f324b204bf1c51f5ad66e00f22"
274
269
  },
275
270
  {
276
271
  "path": "assets/choices-DLah50GC.css",
@@ -283,39 +278,39 @@
283
278
  "sha256": "38fdefe20f181e6a050793f715a13bcbde2e9c167f80f554a775e3578dcd78bc"
284
279
  },
285
280
  {
286
- "path": "assets/console-Trqc0swD.js",
287
- "bytes": 21020,
288
- "sha256": "c0e7821902b6e19724d259aec4aa115ed7462402eec0a3f6452df10f3152a10c"
281
+ "path": "assets/console-Dyuo1q4N.js",
282
+ "bytes": 21041,
283
+ "sha256": "f7d34b3ec6ab42de0aa46a26feff2ec5f491021fc9590edc425e5dd1a4187d22"
289
284
  },
290
285
  {
291
- "path": "assets/dist-DCtcCJPs.js",
292
- "bytes": 34901,
293
- "sha256": "9deb65f8b227a08473b422b448735f045aa2251acf498f169640f7d38d96173e"
286
+ "path": "assets/dist-CSiCyBml.js",
287
+ "bytes": 37492,
288
+ "sha256": "fd45cc66c4d5b6e964a4d2575ae51dc15c495fad627953f50e32ad889f11eee3"
294
289
  },
295
290
  {
296
- "path": "assets/dist-DpIHRk3B.js",
291
+ "path": "assets/dist-D9FLb9Hm.js",
297
292
  "bytes": 35411,
298
- "sha256": "22bf26faa31efb7f46296f6fc4f3b831bcf9303056c1b9bf9bb1b0fc0c58cdd3"
293
+ "sha256": "cd0ca4611168eb267b73edd28d791d9995ec5513bfd60ce8c0c2e15c3b8edb32"
299
294
  },
300
295
  {
301
- "path": "assets/dist-DZmszrjG.js",
302
- "bytes": 183314,
303
- "sha256": "0879df241ab3ba4064054d6c5f44a70ee10ad2f32b7d249107c143578dd891de"
296
+ "path": "assets/dist-DCtcCJPs.js",
297
+ "bytes": 34901,
298
+ "sha256": "9deb65f8b227a08473b422b448735f045aa2251acf498f169640f7d38d96173e"
304
299
  },
305
300
  {
306
- "path": "assets/dist-eMx6b8N1.js",
301
+ "path": "assets/dist-FXbTBwML.js",
307
302
  "bytes": 44651,
308
- "sha256": "f0e536da7c98837e3b7841fbaf1e6eef294bb1d6fb5a939e923ec6d605ef56cd"
303
+ "sha256": "47295c25afc3c0036532edc113e830ae5c28b48ad96855247a0d5884aa3e8a43"
309
304
  },
310
305
  {
311
- "path": "assets/dist-pF902jHA.js",
312
- "bytes": 37492,
313
- "sha256": "d2af94b048491a451eb7225abd3c581843d8e4370708c7a5f2dd4d984b7fc2f5"
306
+ "path": "assets/dist-l3DUhbw5.js",
307
+ "bytes": 183314,
308
+ "sha256": "053fca9b4463b89ed40d6d96ca76c814f4248b94486af0f273918bb1948b317c"
314
309
  },
315
310
  {
316
- "path": "assets/explore-in-BCHqjJ7B.js",
311
+ "path": "assets/explore-in-BfSFGRh2.js",
317
312
  "bytes": 782,
318
- "sha256": "75cea34047fd256982cea015a63bc82a39e3819c6bd8bcabe684893852ec7127"
313
+ "sha256": "a906f7553bb455f0e4153036cdba5dc8b4f03603b8d6d71c41f9e9eb3eea6a22"
319
314
  },
320
315
  {
321
316
  "path": "assets/facts-BMO6V3-3.js",
@@ -327,30 +322,30 @@
327
322
  "bytes": 18546,
328
323
  "sha256": "413304efcb99472948f1c20b997d0a0f9a4a6c84f2255338fef001ddfe8408b4"
329
324
  },
325
+ {
326
+ "path": "assets/graph-BU2_o5uA.js",
327
+ "bytes": 49087,
328
+ "sha256": "597806d9e16f80b85ed0cdfc1c681712c7876a71364230d6ea2f22d108af5771"
329
+ },
330
330
  {
331
331
  "path": "assets/graph-BYKN84J3.css",
332
332
  "bytes": 24857,
333
333
  "sha256": "e84aa51d7376fc0a6104c0b140821c54bc25a2b55be32be6005e08b85dd7e0df"
334
334
  },
335
- {
336
- "path": "assets/graph-lENgfQNH.js",
337
- "bytes": 48768,
338
- "sha256": "39361c04da7930383cb5b0fd9753b1cbdb28d186c514da92cc13a4524ef3ef97"
339
- },
340
335
  {
341
336
  "path": "assets/home-CCbP6kS-.js",
342
337
  "bytes": 12617,
343
338
  "sha256": "6bbbe67af01bd03b2777abcc02e63dda1bad1fa7aaf9296b07cda04ac481e7cb"
344
339
  },
345
340
  {
346
- "path": "assets/index-B3_OVy91.css",
347
- "bytes": 114009,
348
- "sha256": "15692810923cc0bcc8e4eb08df8a9ec0ca8ebaf8a05c754b6589052603869201"
341
+ "path": "assets/index-C16mXVvk.css",
342
+ "bytes": 124839,
343
+ "sha256": "8e9f0a42c426a758d96b3ef003188b32f12e61c0f2dc1b82ecba9ea22d9a5600"
349
344
  },
350
345
  {
351
- "path": "assets/index-BpL_Kl_s.js",
352
- "bytes": 1779367,
353
- "sha256": "0944ee8e42207a963f7be95c817b58648651f8cd2ccae0f475c265a105234038"
346
+ "path": "assets/index-CWg9XYXx.js",
347
+ "bytes": 1981755,
348
+ "sha256": "0225571b6eacda05ac6fb82786adf56bd3bbb042f431f3dc102461e96a07768e"
354
349
  },
355
350
  {
356
351
  "path": "assets/KaTeX_AMS-Regular-BQhdFMY1.woff2",
@@ -663,14 +658,14 @@
663
658
  "sha256": "717274e2c02c05db67e7f1bf6fec4dfae799f3a2780ea7a95c4fdf0d160dfab8"
664
659
  },
665
660
  {
666
- "path": "assets/notes-meaning-DcVGUBBY.js",
667
- "bytes": 5850,
668
- "sha256": "4af65e597d04917ac151c30f91f0811139350b3758132686729f8d49f63f849b"
661
+ "path": "assets/markdown.reader-Ct2-e2Zt.png",
662
+ "bytes": 52645,
663
+ "sha256": "9bac86bfc38e6e8b0865b211f9a81c9eb4f9110df0679a3e12b1683eef74f200"
669
664
  },
670
665
  {
671
- "path": "assets/overview-CDnVKlOt.js",
672
- "bytes": 48647,
673
- "sha256": "a4e4bf4b0bfbbd3a73fbb216dcee730e46e83bb260fab25f836406db93840b14"
666
+ "path": "assets/notes-meaning-T2m5zQfv.js",
667
+ "bytes": 5850,
668
+ "sha256": "28f221435cd3358aeaea779241d3dc29733c66b7fd7b3e59572ced52d05efb74"
674
669
  },
675
670
  {
676
671
  "path": "assets/overview-CmC7mah4.css",
@@ -678,9 +673,19 @@
678
673
  "sha256": "f6b19e1fbbb7cc884faff634b6f7b016f806313b946600b11bbf76dc59caf1a9"
679
674
  },
680
675
  {
681
- "path": "assets/preview-BEC1E9MK.js",
682
- "bytes": 4703,
683
- "sha256": "9888dc22cea50e3757542e144c09fc85bf53fc3abc212955a8af6ae059d155fa"
676
+ "path": "assets/overview-PzfLJCo-.js",
677
+ "bytes": 49192,
678
+ "sha256": "5d40d9695add4257ed9453dd45612032d751e3c803fa9a06fa4720005e83a981"
679
+ },
680
+ {
681
+ "path": "assets/preview-BguEdsza.js",
682
+ "bytes": 4708,
683
+ "sha256": "d48695976adfd13f6fd8562c9005ad4b2bd452820f1bc9e78df33fadc479ebf3"
684
+ },
685
+ {
686
+ "path": "assets/previews-pWNik-2g.js",
687
+ "bytes": 35016,
688
+ "sha256": "c63b364c80a0d44dd31266fd7bedba359712eaa0e16abea42888c2b058146499"
684
689
  },
685
690
  {
686
691
  "path": "assets/r-CxDmU1I4.js",
@@ -698,9 +703,59 @@
698
703
  "sha256": "364a909acd2231cafe737e8f9b19ad58ba16d3b6cbb90b0de78015dd437bd56b"
699
704
  },
700
705
  {
701
- "path": "assets/review-DYP0aCXb.js",
706
+ "path": "assets/review-Dy_85lcH.js",
702
707
  "bytes": 4860,
703
- "sha256": "6059e4b493405b191cae348f63ce7ae32ae97e8165710adeee0d26672405576e"
708
+ "sha256": "e741343e502faaf78a0820a1f5beaf0dab96a7050daf8b6e1a164e4e09e0897f"
709
+ },
710
+ {
711
+ "path": "assets/rho.editor-CCJeyHma.png",
712
+ "bytes": 126375,
713
+ "sha256": "6c661a5b40d79053c4a40e66315d484bdbb922b049c611db9c4d8c6ca02a5e50"
714
+ },
715
+ {
716
+ "path": "assets/rho.flow-WkMj6fRS.png",
717
+ "bytes": 25961,
718
+ "sha256": "d6f7c4481a696aee3b1d99593aaad990dfaccff49761029806efb15753096441"
719
+ },
720
+ {
721
+ "path": "assets/rho.media-Cc6amodO.png",
722
+ "bytes": 60791,
723
+ "sha256": "deff16dc63e2a320020b5cc407a7c5408c572938d408a2d1f5d65a6ef5251e4a"
724
+ },
725
+ {
726
+ "path": "assets/rho.notebook-6vsZKGDq.png",
727
+ "bytes": 94387,
728
+ "sha256": "c5cf66d52ca8c09e6fd6bf47b5975ca76a5df47501f23f8c51a71e89dc4da035"
729
+ },
730
+ {
731
+ "path": "assets/rho.object-BGoeXjte.png",
732
+ "bytes": 59331,
733
+ "sha256": "baca57704dc107c92ec12a37334b89855728c6ae86bc1dae36d866f09898b655"
734
+ },
735
+ {
736
+ "path": "assets/rho.plots-yIiISCkb.png",
737
+ "bytes": 21130,
738
+ "sha256": "0ade92610bbe753ebf541fee66178d8969f6b819b4ca83ca7d64493c5953c729"
739
+ },
740
+ {
741
+ "path": "assets/rho.scatter-DwHxesCs.png",
742
+ "bytes": 10078,
743
+ "sha256": "7316ea10fa6a3476b91ac53a4a1add3c472e3c05a9db138824317b7f828f6128"
744
+ },
745
+ {
746
+ "path": "assets/rho.servers-DKf_mnNq.png",
747
+ "bytes": 24827,
748
+ "sha256": "a9591775e625d203d1136a7f4b066eb5d5cbadb771eb9b05cc76d93da372452e"
749
+ },
750
+ {
751
+ "path": "assets/rho.table-DWOGaWDa.png",
752
+ "bytes": 52197,
753
+ "sha256": "0c381aa96a5a1422b119998288a0404bfcc51ec619a58a57c5a437c1c9e88cd8"
754
+ },
755
+ {
756
+ "path": "assets/rho.variables-CKcWczhQ.png",
757
+ "bytes": 13632,
758
+ "sha256": "6a928563a6088748b7565a4a11a0e5bb8286c18b6658ca1210d2a96caf38f3c9"
704
759
  },
705
760
  {
706
761
  "path": "assets/rolldown-runtime-XKyaHtl9.js",
@@ -708,9 +763,9 @@
708
763
  "sha256": "548d1dbf321e7d2ae804fcc158b588706a7c52f8ca175de1490c6ccb4dbe55b7"
709
764
  },
710
765
  {
711
- "path": "assets/skills-1ec0Z-jx.js",
766
+ "path": "assets/skills-Dyz7mBlc.js",
712
767
  "bytes": 12538,
713
- "sha256": "aeaf67104b99a56d368f41e6f2ddceb82c179f5309281258a8cecf50c8cc264b"
768
+ "sha256": "4513c2e0e8f5ef3142512556d40e8703e74bc494a441a6f78812709dfa1ba662"
714
769
  },
715
770
  {
716
771
  "path": "assets/skills-WkE0KCzn.css",
@@ -718,9 +773,9 @@
718
773
  "sha256": "162823ce43fd1e1f2bd92a330516c171280b59a0b5460752f0d7aba5f194f3eb"
719
774
  },
720
775
  {
721
- "path": "assets/skills-work-DNexV4OJ.js",
776
+ "path": "assets/skills-work-BEGqlCkx.js",
722
777
  "bytes": 2528,
723
- "sha256": "3f30614690b9199ece7838ab8076bb902f6f2fb619ff03dd568806b562ac1fa9"
778
+ "sha256": "c4f950967358e17ac51e382752924e5f3a4918d82ee42e5403129b944936b9a0"
724
779
  },
725
780
  {
726
781
  "path": "assets/snapshot-CAxBYPvV.js",
@@ -733,29 +788,29 @@
733
788
  "sha256": "7acddf1303643a15a8df990808a42e218033edf56b8c03b0fcc8271683b0195f"
734
789
  },
735
790
  {
736
- "path": "assets/studio-process-EYQgikxq.js",
737
- "bytes": 22888,
738
- "sha256": "055ece65b0ba5c0b6787daaa834bdd4e09aeb66a0fb062735114a5fa40c0fa3e"
791
+ "path": "assets/studio-process-D-ykbC4D.js",
792
+ "bytes": 22343,
793
+ "sha256": "755d181d71dd5103f325316c3a9016c47fe1c995f8139b4d5c8ff377270da875"
739
794
  },
740
795
  {
741
- "path": "assets/timeline-events-Chj2Gbx7.js",
742
- "bytes": 2227,
743
- "sha256": "be716e87f5a47e4e602a0d326e84cfb8e5e701abe10ae484e3f23fdb3587c3ff"
796
+ "path": "assets/timeline-events-DKTho9fU.js",
797
+ "bytes": 2595,
798
+ "sha256": "a37e782a8a51fb53a9afa2c70786bc930e6381293d465ed9a243e8cb9b0a41ec"
744
799
  },
745
800
  {
746
- "path": "assets/work-turns-CT9RVcWY.js",
747
- "bytes": 1460,
748
- "sha256": "2270b5c2510a3b04a642621a345ead825c44bc7896b7231a3fbfb24903f62e3f"
801
+ "path": "assets/work-turns-DSabCogR.js",
802
+ "bytes": 2006,
803
+ "sha256": "9272b191093b468ce8c478771ac166fa37c1868ffe3fcafad5024776846e6034"
749
804
  },
750
805
  {
751
- "path": "assets/workspace-COmCbGV3.js",
752
- "bytes": 81815,
753
- "sha256": "d55693dd507204b35dd28f7e8723e9e15a425d05f8b727c55d73e7866b1f7562"
806
+ "path": "assets/workspace-DfjBL--r.js",
807
+ "bytes": 81849,
808
+ "sha256": "dd5e612127d0b1e04aa54d4b2bef8e7f8a1693c6e4ab566dc752df6d5e005f20"
754
809
  },
755
810
  {
756
811
  "path": "index.html",
757
- "bytes": 1142,
758
- "sha256": "d304ba22383bd32eba1e0ab88319c127fe05a0d255fc178253a79a0b6ce22425"
812
+ "bytes": 1144,
813
+ "sha256": "b0cb41cac3d2c798a21e2f1fa25f29c83f754ab941f5b1c5f4eae348838ef397"
759
814
  },
760
815
  {
761
816
  "path": "licenses.md",
@@ -765,10 +820,10 @@
765
820
  {
766
821
  "path": "renderer.json",
767
822
  "bytes": 85,
768
- "sha256": "05327600965d5e945f3f6b239255194b3a90324408889b7dc2508a98cf4c1440"
823
+ "sha256": "11a3ad4426ea4f0c04bafd72d627172175fdfaafb5c2c53050c9b156658f4c41"
769
824
  }
770
825
  ],
771
- "assetsSha256": "75bcc4b9c1aee998d3112cc11bae15e86356104151ecea4f81826d5c3d13ec5a",
826
+ "assetsSha256": "a0b475ab534694292c4ace8539f714212187d99cbbe9d58c4ad82aaeb9a111f0",
772
827
  "licenses": "licenses.md",
773
828
  "node": "v22.23.4"
774
829
  }
@@ -6,13 +6,13 @@
6
6
  <meta name="color-scheme" content="light" />
7
7
  <title>Rho Workspace</title>
8
8
  <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='8' fill='%231e6b52'/%3E%3Ctext x='16' y='23' font-family='Georgia,serif' font-size='22' text-anchor='middle' fill='white'%3E%CF%81%3C/text%3E%3C/svg%3E" />
9
- <script type="module" crossorigin src="/assets/index-BpL_Kl_s.js"></script>
9
+ <script type="module" crossorigin src="/assets/index-CWg9XYXx.js"></script>
10
10
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-XKyaHtl9.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/react-Dss-ouuy.js">
12
12
  <link rel="modulepreload" crossorigin href="/assets/markdown-0ngRuTpW.js">
13
13
  <link rel="modulepreload" crossorigin href="/assets/home-CCbP6kS-.js">
14
- <link rel="modulepreload" crossorigin href="/assets/canvas-D8rDdfDz.js">
15
- <link rel="stylesheet" crossorigin href="/assets/index-B3_OVy91.css">
14
+ <link rel="modulepreload" crossorigin href="/assets/previews-pWNik-2g.js">
15
+ <link rel="stylesheet" crossorigin href="/assets/index-C16mXVvk.css">
16
16
  </head>
17
17
  <body>
18
18
  <div id="root"></div>
@@ -1 +1 @@
1
- {"rendererBuild":"094bee327d7964c2c6ea9fe3db6d35899545d090074c964d0cdb056f556471f1"}
1
+ {"rendererBuild":"c91ca90733547979438dc656e21b4881d5df05f971152e686d48b89585294a48"}
@@ -49,9 +49,9 @@ export function servePageFrame(response, head = false, allowForms = false) {
49
49
  response.writeHead(200, { 'content-type': 'text/html; charset=utf-8', 'content-length': bytes.length, 'content-security-policy': allowForms ? pageFramePolicy.replace('sandbox allow-scripts;', 'sandbox allow-scripts allow-forms;') : pageFramePolicy });
50
50
  response.end(head ? undefined : bytes);
51
51
  }
52
- const types = { '.html': 'text/html; charset=utf-8', '.js': 'text/javascript; charset=utf-8', '.css': 'text/css; charset=utf-8', '.woff2': 'font/woff2', '.svg': 'image/svg+xml' };
52
+ const types = { '.html': 'text/html; charset=utf-8', '.js': 'text/javascript; charset=utf-8', '.css': 'text/css; charset=utf-8', '.woff2': 'font/woff2', '.svg': 'image/svg+xml', '.png': 'image/png' };
53
53
  export async function serveWeb(pathname, response, root = webRoot, head = false) {
54
- requireThat(pathname === '/' || pathname === '/index.html' || /^\/assets\/[A-Za-z0-9_-][A-Za-z0-9._-]*\.(js|css|woff2|svg)$/.test(pathname), 'not_found', 'Static asset is not in the browser build.');
54
+ requireThat(pathname === '/' || pathname === '/index.html' || /^\/assets\/[A-Za-z0-9_-][A-Za-z0-9._-]*\.(js|css|woff2|svg|png)$/.test(pathname), 'not_found', 'Static asset is not in the browser build.');
55
55
  const relative = pathname === '/' ? 'index.html' : pathname.slice(1);
56
56
  let file;
57
57
  try {
@@ -23,6 +23,16 @@ export interface GraphTurn {
23
23
  agent: string;
24
24
  turn: ConversationTurn;
25
25
  observation?: SessionObservation | null;
26
+ external?: boolean;
27
+ kernelCells?: string[];
28
+ reportedResults?: Array<{
29
+ path: string;
30
+ at: string;
31
+ resource?: {
32
+ id: string;
33
+ version: string;
34
+ };
35
+ }>;
26
36
  }
27
37
  export interface GraphInput {
28
38
  turns: GraphTurn[];
@@ -32,7 +42,7 @@ export interface GraphInput {
32
42
  now: number;
33
43
  }
34
44
  export type NodeKind = 'question' | 'file' | 'run' | 'finding' | 'choice';
35
- export type EventAction = 'ask' | 'read' | 'edit' | 'write' | 'run' | 'changed' | 'capture' | 'answer';
45
+ export type EventAction = 'ask' | 'read' | 'edit' | 'write' | 'run' | 'changed' | 'capture' | 'answer' | 'report';
36
46
  export type Basis = 'reported' | 'named' | 'observed' | 'declared';
37
47
  export interface GraphEvent {
38
48
  key: string;
@@ -62,14 +62,14 @@ export function buildWorkGraph(input) {
62
62
  const files = new Map(input.files.map(f => [f.path, f]));
63
63
  let live = null, inTurn = '';
64
64
  let evidence;
65
- const fileNode = (path, at, exact) => {
65
+ const fileNode = (path, at, exact, reported) => {
66
66
  const observed = evidence?.records.filter(r => r.path === path).flatMap(r => r.snapshots).filter(s => s.source.kind !== 'buffer').sort((a, b) => a.observedAt.localeCompare(b.observedAt)) ?? [];
67
67
  const selected = exact ?? [...observed].reverse().find(s => (time(s.observedAt) ?? Infinity) <= at);
68
- const id = 'f:' + path + (selected ? '@' + selected.resource.id : evidence ? '@' + inTurn + ':unrecorded' : '');
68
+ const id = 'f:' + path + (selected ? '@' + selected.resource.id : reported ? '@' + reported.id + ':' + reported.version : evidence ? '@' + inTurn + ':unrecorded' : '');
69
69
  let node = nodes.get(id);
70
70
  if (!node) {
71
71
  const seen = files.get(path);
72
- node = { id, kind: 'file', title: path.split('/').at(-1) ?? path, at, path, category: seen?.category ?? input.kindOf(path), exists: !!seen, bytes: selected?.bytes ?? seen?.bytes, modifiedAt: seen?.modifiedAt, events: [], ...(selected ? { resource: selected.resource, capturedAt: time(selected.observedAt) ?? at, captureSource: String(selected.source.kind) } : { gap: evidence ? evidence.records.find(r => r.path === path)?.reason ?? 'No historical snapshot was captured.' : 'This older record has no captured version.' }) };
72
+ node = { id, kind: 'file', title: path.split('/').at(-1) ?? path, at, path, category: seen?.category ?? input.kindOf(path), exists: !!seen, bytes: selected?.bytes ?? seen?.bytes, modifiedAt: seen?.modifiedAt, events: [], ...(selected ? { resource: selected.resource, capturedAt: time(selected.observedAt) ?? at, captureSource: String(selected.source.kind) } : reported ? { resource: reported, captureSource: 'tool reply' } : { gap: evidence ? evidence.records.find(r => r.path === path)?.reason ?? 'No historical snapshot was captured.' : 'No historical version was kept in this record.' }) };
73
73
  nodes.set(id, node);
74
74
  }
75
75
  return node;
@@ -80,7 +80,7 @@ export function buildWorkGraph(input) {
80
80
  edges.set(id, { id, from, to, label, basis, at, turn: inTurn });
81
81
  };
82
82
  const note = (node, event) => { const full = { ...event, node: node.id }; node.events.push(full); events.push(full); node.at = Math.min(node.at, event.at); };
83
- ordered.forEach(({ conversationId, conversationTitle, agent, turn: message, observation }, position) => {
83
+ ordered.forEach(({ conversationId, conversationTitle, agent, turn: message, observation, external, reportedResults }, position) => {
84
84
  // Message identities are per conversation; the graph names each by both.
85
85
  const turn = { ...message, id: conversationId + '/' + message.id };
86
86
  inTurn = turn.id;
@@ -103,7 +103,7 @@ export function buildWorkGraph(input) {
103
103
  // once it has. A finished step ran from the step before it until then.
104
104
  const at = time(activity.step.at) ?? start;
105
105
  const before = index ? time(activities[index - 1].step.at) ?? start : start;
106
- const window = activity.outcome === 'requested' ? { from: at, to: end } : { from: Math.min(before, at), to: at };
106
+ const window = external ? { from: at, to: at } : activity.outcome === 'requested' ? { from: at, to: end } : { from: Math.min(before, at), to: at };
107
107
  // A refused step did nothing; a command that ran and failed did, and stays.
108
108
  if (activity.outcome === 'rejected')
109
109
  return;
@@ -196,6 +196,17 @@ export function buildWorkGraph(input) {
196
196
  const answer = [...blocks].reverse().find(block => block.kind === 'text');
197
197
  if (answer?.kind === 'text' && answer.step.text)
198
198
  q.answer = answer.step.text;
199
+ for (const result of reportedResults ?? []) {
200
+ const path = projectPath(result.path, input.project);
201
+ if (!path)
202
+ continue;
203
+ const at = time(result.at);
204
+ if (at === null || at > input.now)
205
+ continue;
206
+ const node = fileNode(path, at, undefined, result.resource);
207
+ note(node, { key: turn.id + ':result:' + path, at, turn: turn.id, action: 'report', label: 'Reported result' });
208
+ edge(q.id, node.id, 'reported result', 'reported', at);
209
+ }
199
210
  if (!running && time(turn.endedAt) !== null)
200
211
  note(q, { key: turn.id + ':answer', at: end, turn: turn.id, action: 'answer', label: turn.state === 'completed' ? 'Answered' : turn.state === 'failed' ? 'Failed' : turn.state === 'stopped' ? 'Stopped' : 'Ended' });
201
212
  if (running && !live)
@@ -22,13 +22,13 @@ export declare class Workspace {
22
22
  constructor(project: Project, owners: ProjectPlugins, limits?: Partial<typeof workspaceLimits>, interactions?: Partial<typeof interactionLimits>);
23
23
  private directory;
24
24
  private file;
25
- compositions(): Promise<any[]>;
25
+ compositions(includeDeleted?: boolean): Promise<any[]>;
26
26
  read(id: string): Promise<any>;
27
27
  structured(trustedPresentation?: {
28
28
  authorBindingId: string;
29
29
  basisWitnessId: string;
30
30
  }, retainedNotes?: any[]): Compositions;
31
- apply(body: any, author: string, kind?: 'apply' | 'undo' | 'protect', trustedPresentation?: {
31
+ apply(body: any, author: string, kind?: 'apply' | 'undo' | 'protect' | 'delete', trustedPresentation?: {
32
32
  authorBindingId: string;
33
33
  basisWitnessId: string;
34
34
  }): Promise<any>;
package/dist/workspace.js CHANGED
@@ -41,16 +41,17 @@ export class Workspace {
41
41
  }
42
42
  async directory() { return stateDirectory(this.project.root, '.rho/rho/compositions'); }
43
43
  async file(id) { return path.join(await this.directory(), digest(id) + '.json'); }
44
- async compositions() {
44
+ async compositions(includeDeleted = false) {
45
45
  const d = await this.directory();
46
- return Promise.all((await fs.readdir(d)).filter(f => /^[a-f0-9]{64}\.json$/.test(f)).map(f => readJson(path.join(d, f))));
46
+ const retained = await Promise.all((await fs.readdir(d)).filter(f => /^[a-f0-9]{64}\.json$/.test(f)).map(f => readJson(path.join(d, f))));
47
+ return includeDeleted ? retained : retained.filter(c => !c.deleted);
47
48
  }
48
49
  async read(id) { return readJson(await this.file(id)); }
49
50
  structured(trustedPresentation, retainedNotes = []) { return new Compositions(this.project, (views, retained) => this.validateViews(views, retained, trustedPresentation, retainedNotes), this.limits); }
50
51
  async apply(body, author, kind = 'apply', trustedPresentation) {
51
52
  // Existing receipt must remain readable even at the composition count limit.
52
53
  const current = await readJson(await this.file(body.compositionId), null);
53
- requireThat(current || (await this.compositions()).length < this.limits.maxCompositions, 'limit', 'Composition retention limit reached.');
54
+ requireThat(current || (await this.compositions(true)).length < this.limits.maxCompositions, 'limit', 'Composition retention limit reached. Reuse a retained layout identity to keep its history.');
54
55
  const retainedNotes = kind === 'undo' ? (current?.history ?? []).flatMap((h) => h.snapshot.nodes.filter((n) => n.kind === 'view' && n.component === 'rho.agent-note')) : [];
55
56
  return this.structured(trustedPresentation, retainedNotes).transact(body, author, kind);
56
57
  }
@@ -109,7 +110,7 @@ export class Workspace {
109
110
  const current = await readJson(file, null);
110
111
  requireThat((current?.version ?? 0) === body.expectedVersion, 'stale', 'Composition version changed.', { actualVersion: current?.version ?? 0 });
111
112
  requireThat(new Set(body.views.map((v) => v.id)).size === body.views.length, 'invalid', 'View identities must be unique in a composition.');
112
- requireThat(current || (await this.compositions()).length < this.limits.maxCompositions, 'limit', 'Composition retention limit reached.', { limit: 'maxCompositions', maximum: this.limits.maxCompositions });
113
+ requireThat(current || (await this.compositions(true)).length < this.limits.maxCompositions, 'limit', 'Composition retention limit reached.', { limit: 'maxCompositions', maximum: this.limits.maxCompositions });
113
114
  requireThat(current?.format !== 'rho.composition/1', 'condition', 'Structured compositions require composition.apply; legacy put cannot bypass protection.');
114
115
  const availability = await this.validateViews(body.views, current?.views ?? []);
115
116
  const result = { compositionId: body.compositionId, version: (current?.version ?? 0) + 1, views: body.views, layout: body.layout, availability, acknowledgedAt: now() };
@@ -148,9 +149,9 @@ export class Workspace {
148
149
  async save(format = 2) {
149
150
  requireThat([1, 2, 3].includes(format), 'invalid', 'Select archive format 1, 2 or 3.');
150
151
  const collaboration = await this.collaborationState();
151
- const compositions = await this.compositions();
152
+ const compositions = await this.compositions(true);
152
153
  requireThat(format === 3 || !(collaboration.configured || collaboration.interactions.length || collaboration.annotations.length || collaboration.contexts.length || compositions.some(c => c.format)), 'condition', 'Archive format 3 is required to preserve collaboration state; older formats would be lossy.');
153
- const workspace = { ...(format === 3 ? { capabilities: collaboration.capabilities, interactions: collaboration.interactions, annotations: collaboration.annotations, contexts: collaboration.contexts } : {}), schemaVersion: format, sourceProjectId: this.project.id, acknowledgedAt: now(), documents: await this.owners.retainedDocuments(), resources: (await this.owners.retainedResources()).map(({ storage, ...r }) => r), compositions: await this.compositions(), selection: await readJson(path.join(await stateDirectory(this.project.root, '.rho/rho'), 'selection.json'), null) };
154
+ const workspace = { ...(format === 3 ? { capabilities: collaboration.capabilities, interactions: collaboration.interactions, annotations: collaboration.annotations, contexts: collaboration.contexts } : {}), schemaVersion: format, sourceProjectId: this.project.id, acknowledgedAt: now(), documents: await this.owners.retainedDocuments(), resources: (await this.owners.retainedResources()).map(({ storage, ...r }) => r), compositions, selection: await readJson(path.join(await stateDirectory(this.project.root, '.rho/rho'), 'selection.json'), null) };
154
155
  requireThat(Buffer.byteLength(JSON.stringify(workspace)) <= this.limits.maxMetadataBytes, 'limit', 'Workspace metadata exceeds the export byte budget; acknowledged owner state is retained.', { limit: 'maxMetadataBytes', maximum: this.limits.maxMetadataBytes });
155
156
  await atomicJson(path.join(await stateDirectory(this.project.root, '.rho/rho'), 'workspace.json'), workspace);
156
157
  return workspace;
@@ -245,7 +246,7 @@ export class Workspace {
245
246
  report.compositions.push({ compositionId: composition.compositionId, state: 'conflict' });
246
247
  continue;
247
248
  }
248
- requireThat(current || (await this.compositions()).length < this.limits.maxCompositions, 'limit', 'Composition retention limit reached during restore.', { limit: 'maxCompositions' });
249
+ requireThat(current || (await this.compositions(true)).length < this.limits.maxCompositions, 'limit', 'Composition retention limit reached during restore.', { limit: 'maxCompositions' });
249
250
  // Restore references even if a UI entry is missing. Reading or restoring
250
251
  // this intent never submits scientific work.
251
252
  const availability = Object.fromEntries(composition.views.map((v) => [v.id, v.component === actionFormComponent.id ? { state: 'entry-installed', visibility: 'unobserved' } : this.owners.assembly.viewAvailability(v.component, v.version)]));