@rho-workspace/rho 0.5.5 → 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 (250) hide show
  1. package/dist/agent-connect.d.ts +42 -0
  2. package/dist/agent-connect.js +68 -0
  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 +113 -18
  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 +1437 -381
  15. package/dist/contract.generated.js +1 -1
  16. package/dist/contracts/owners.generated.js +1160 -267
  17. package/dist/conversation-presentation.d.ts +9 -2
  18. package/dist/conversation-presentation.js +3 -1
  19. package/dist/conversations.d.ts +306 -7
  20. package/dist/conversations.js +208 -22
  21. package/dist/discovery.js +3 -3
  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 +7 -0
  40. package/dist/protocol.js +40 -15
  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 +4 -10
  46. package/dist/server.js +140 -14
  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 +135 -76
  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-BSjLGe0T.js → console-Dyuo1q4N.js} +4 -4
  60. package/dist/web/assets/{dist-Tzoe_zm-.js → dist-CSiCyBml.js} +1 -1
  61. package/dist/web/assets/{dist-Cw8hRIlT.js → dist-D9FLb9Hm.js} +1 -1
  62. package/dist/web/assets/{dist-foH9IKc6.js → dist-FXbTBwML.js} +1 -1
  63. package/dist/web/assets/{dist-Buk0lwzI.js → dist-l3DUhbw5.js} +1 -1
  64. package/dist/web/assets/{explore-in-BVUy3ZW_.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-pVbbQUGP.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-CMxQlQ-C.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-BFNSyrnD.js → skills-Dyz7mBlc.js} +1 -1
  85. package/dist/web/assets/{skills-work-BGPSnF_I.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-CWlkjLNx.js → workspace-DfjBL--r.js} +2 -2
  90. package/dist/web/composition.json +135 -80
  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 +71 -21
  99. package/docs/HEADLESS.md +127 -24
  100. package/docs/THIRD-PARTY-PLUGINS.md +75 -3
  101. package/node_modules/@rho-workspace/plugin-agent/README.md +34 -0
  102. package/node_modules/@rho-workspace/plugin-agent/dist/acp-command.d.ts +32 -0
  103. package/node_modules/@rho-workspace/plugin-agent/dist/acp-command.js +54 -11
  104. package/node_modules/@rho-workspace/plugin-agent/dist/acp-conversation.d.ts +1 -0
  105. package/node_modules/@rho-workspace/plugin-agent/dist/acp-conversation.js +29 -3
  106. package/node_modules/@rho-workspace/plugin-agent/dist/external-session-contract.js +11 -5
  107. package/node_modules/@rho-workspace/plugin-agent/dist/external-session.d.ts +12 -1
  108. package/node_modules/@rho-workspace/plugin-agent/dist/index.d.ts +8 -0
  109. package/node_modules/@rho-workspace/plugin-agent/dist/index.js +3 -2
  110. package/node_modules/@rho-workspace/plugin-agent/dist/mcp-entry.d.ts +13 -0
  111. package/node_modules/@rho-workspace/plugin-agent/dist/mcp-entry.js +13 -0
  112. package/node_modules/@rho-workspace/plugin-agent/dist/mcp.js +16 -8
  113. package/node_modules/@rho-workspace/plugin-agent/dist/native-sessions.d.ts +70 -0
  114. package/node_modules/@rho-workspace/plugin-agent/dist/native-sessions.js +538 -0
  115. package/node_modules/@rho-workspace/plugin-agent/package.json +2 -1
  116. package/node_modules/@rho-workspace/plugin-figures/LICENSE +661 -0
  117. package/node_modules/@rho-workspace/plugin-figures/README.md +191 -0
  118. package/node_modules/@rho-workspace/plugin-figures/dist/index.d.ts +236 -0
  119. package/node_modules/@rho-workspace/plugin-figures/dist/index.js +165 -0
  120. package/node_modules/@rho-workspace/plugin-figures/dist/operations.d.ts +44 -0
  121. package/node_modules/@rho-workspace/plugin-figures/dist/operations.js +39 -0
  122. package/node_modules/@rho-workspace/plugin-figures/dist/presentation.d.ts +19 -0
  123. package/node_modules/@rho-workspace/plugin-figures/dist/presentation.js +26 -0
  124. package/node_modules/@rho-workspace/plugin-figures/dist/record.d.ts +188 -0
  125. package/node_modules/@rho-workspace/plugin-figures/dist/record.js +143 -0
  126. package/node_modules/@rho-workspace/plugin-figures/dist/ui-styles.d.ts +1 -0
  127. package/node_modules/@rho-workspace/plugin-figures/dist/ui-styles.js +68 -0
  128. package/node_modules/@rho-workspace/plugin-figures/dist/ui.d.ts +56 -0
  129. package/node_modules/@rho-workspace/plugin-figures/dist/ui.js +363 -0
  130. package/node_modules/@rho-workspace/plugin-figures/package.json +41 -0
  131. package/node_modules/@rho-workspace/plugin-figures/py/figures.py +856 -0
  132. package/node_modules/@rho-workspace/plugin-figures/r/figures.R +775 -0
  133. package/node_modules/@rho-workspace/plugin-kernel/README.md +27 -3
  134. package/node_modules/@rho-workspace/plugin-kernel/dist/contract.d.ts +12 -0
  135. package/node_modules/@rho-workspace/plugin-kernel/dist/contract.js +8 -1
  136. package/node_modules/@rho-workspace/plugin-kernel/dist/index.d.ts +61 -0
  137. package/node_modules/@rho-workspace/plugin-kernel/dist/index.js +125 -9
  138. package/node_modules/@rho-workspace/plugin-kernel/dist/session-scope.d.ts +14 -0
  139. package/node_modules/@rho-workspace/plugin-kernel/dist/session-scope.js +9 -0
  140. package/node_modules/@rho-workspace/plugin-kernel/dist/ui-base.d.ts +23 -5
  141. package/node_modules/@rho-workspace/plugin-kernel/dist/ui-notebook-work.js +1 -1
  142. package/node_modules/@rho-workspace/plugin-kernel/dist/ui-notebook.d.ts +6 -4
  143. package/node_modules/@rho-workspace/plugin-kernel/dist/ui-notebook.js +44 -17
  144. package/node_modules/@rho-workspace/plugin-kernel/dist/ui-styles.js +6 -0
  145. package/node_modules/@rho-workspace/plugin-kernel/package.json +1 -1
  146. package/node_modules/@rho-workspace/plugin-kernel/runners/runner.R +144 -4
  147. package/node_modules/@rho-workspace/plugin-kernel/runners/runner.py +106 -1
  148. package/node_modules/@rho-workspace/plugin-tables/README.md +5 -0
  149. package/node_modules/@rho-workspace/plugin-tables/dist/index.d.ts +1 -0
  150. package/node_modules/@rho-workspace/plugin-tables/dist/index.js +19 -3
  151. package/node_modules/@rho-workspace/plugin-tables/dist/ui.js +1 -1
  152. package/node_modules/@rho-workspace/plugin-tables/package.json +1 -1
  153. package/node_modules/hono/dist/adapter/aws-lambda/handler.js +1 -1
  154. package/node_modules/hono/dist/cjs/adapter/aws-lambda/handler.js +1 -1
  155. package/node_modules/hono/dist/cjs/adapter/bun/serve-static.js +1 -1
  156. package/node_modules/hono/dist/cjs/adapter/bun/websocket.js +1 -1
  157. package/node_modules/hono/dist/cjs/client/fetch-result-please.js +1 -1
  158. package/node_modules/hono/dist/cjs/helper/accepts/accepts.js +2 -1
  159. package/node_modules/hono/dist/cjs/helper/ssg/ssg.js +5 -3
  160. package/node_modules/hono/dist/cjs/jsx/base.js +49 -30
  161. package/node_modules/hono/dist/cjs/jsx/components.js +2 -2
  162. package/node_modules/hono/dist/cjs/jsx/constants.js +2 -0
  163. package/node_modules/hono/dist/cjs/jsx/jsx-runtime.js +13 -17
  164. package/node_modules/hono/dist/cjs/middleware/etag/index.js +3 -1
  165. package/node_modules/hono/dist/cjs/middleware/pretty-json/index.js +1 -0
  166. package/node_modules/hono/dist/cjs/middleware/timing/timing.js +4 -3
  167. package/node_modules/hono/dist/cjs/utils/cookie.js +2 -2
  168. package/node_modules/hono/dist/cjs/utils/mime.js +1 -1
  169. package/node_modules/hono/dist/cjs/utils/url.js +1 -1
  170. package/node_modules/hono/dist/client/fetch-result-please.js +1 -1
  171. package/node_modules/hono/dist/helper/accepts/accepts.js +2 -1
  172. package/node_modules/hono/dist/helper/ssg/ssg.js +5 -3
  173. package/node_modules/hono/dist/jsx/base.js +49 -32
  174. package/node_modules/hono/dist/jsx/components.js +2 -2
  175. package/node_modules/hono/dist/jsx/constants.js +2 -1
  176. package/node_modules/hono/dist/jsx/jsx-runtime.js +15 -19
  177. package/node_modules/hono/dist/middleware/etag/index.js +3 -1
  178. package/node_modules/hono/dist/middleware/language/language.js +1 -1
  179. package/node_modules/hono/dist/middleware/pretty-json/index.js +1 -0
  180. package/node_modules/hono/dist/middleware/timing/timing.js +4 -3
  181. package/node_modules/hono/dist/utils/cookie.js +2 -2
  182. package/node_modules/hono/dist/utils/mime.js +1 -1
  183. package/node_modules/hono/dist/utils/url.js +1 -1
  184. package/node_modules/hono/package.json +1 -1
  185. package/node_modules/jose/dist/webapi/jwe/general/decrypt.js +3 -2
  186. package/node_modules/jose/dist/webapi/jwks/remote.js +1 -1
  187. package/node_modules/jose/dist/webapi/jws/general/verify.js +2 -8
  188. package/node_modules/jose/dist/webapi/lib/jwe_decrypt.js +11 -8
  189. package/node_modules/jose/dist/webapi/lib/key_management.js +0 -1
  190. package/node_modules/jose/package.json +1 -1
  191. package/package.json +6 -4
  192. package/protocol/index.json +106 -64
  193. package/protocol/operations/agent.sessions.list.json +57 -3
  194. package/protocol/operations/agent.sessions.read.json +61 -4
  195. package/protocol/operations/capability.list.json +382 -6
  196. package/protocol/operations/composition.apply.json +10 -2
  197. package/protocol/operations/composition.delete.json +845 -0
  198. package/protocol/operations/composition.read.json +10 -2
  199. package/protocol/operations/composition.undo.json +10 -2
  200. package/protocol/operations/conversation.agents.add.json +346 -0
  201. package/protocol/operations/conversation.agents.remove.json +340 -0
  202. package/protocol/operations/conversation.configure.json +29 -0
  203. package/protocol/operations/conversation.decide.json +225 -0
  204. package/protocol/operations/conversation.list.json +29 -0
  205. package/protocol/operations/conversation.permission.json +225 -0
  206. package/protocol/operations/conversation.read.json +225 -0
  207. package/protocol/operations/conversation.restore.json +29 -0
  208. package/protocol/operations/conversation.send.json +294 -0
  209. package/protocol/operations/conversation.settings.check.json +226 -416
  210. package/protocol/operations/conversation.settings.read.json +224 -411
  211. package/protocol/operations/conversation.settings.update.json +248 -475
  212. package/protocol/operations/conversation.start.json +313 -6
  213. package/protocol/operations/conversation.stop.json +225 -0
  214. package/protocol/operations/conversation.trash.json +29 -0
  215. package/protocol/operations/extension.describe.json +39 -0
  216. package/protocol/operations/extension.install.json +62 -0
  217. package/protocol/operations/extension.list.json +164 -1
  218. package/protocol/operations/extension.market.change.json +210 -0
  219. package/protocol/operations/figure.read.json +265 -0
  220. package/protocol/operations/figure.select.json +157 -0
  221. package/protocol/operations/kernel.interrupt.json +119 -0
  222. package/protocol/operations/kernel.read.json +119 -0
  223. package/protocol/operations/kernel.run.json +119 -0
  224. package/protocol/operations/observation.snapshot.json +445 -8
  225. package/protocol/operations/project.openFile.json +10 -2
  226. package/protocol/operations/session.grant.json +4 -0
  227. package/protocol/operations/session.instructions.json +43 -0
  228. package/protocol/operations/shared.json +1 -0
  229. package/protocol/operations/view.close.json +10 -2
  230. package/protocol/operations/view.protection.set.json +10 -2
  231. package/vendor/composition.json +174 -109
  232. package/vendor/rho-workspace-plugin-agent-0.4.33.tgz +0 -0
  233. package/vendor/rho-workspace-plugin-figures-0.5.1.tgz +0 -0
  234. package/vendor/rho-workspace-plugin-kernel-0.5.13.tgz +0 -0
  235. package/vendor/rho-workspace-plugin-tables-0.5.2.tgz +0 -0
  236. package/web/theme.css +17 -0
  237. package/dist/web/assets/answer-board-CBkGbSLD.js +0 -1
  238. package/dist/web/assets/canvas-D8rDdfDz.js +0 -1
  239. package/dist/web/assets/choices-b0XhrGQV.js +0 -1
  240. package/dist/web/assets/graph-1OdIJ9l7.js +0 -2
  241. package/dist/web/assets/index-CsC3sTRq.css +0 -1
  242. package/dist/web/assets/index-CxmItXqa.js +0 -891
  243. package/dist/web/assets/overview-B9UtVJ32.js +0 -6
  244. package/dist/web/assets/preview-CksD_5KS.js +0 -1
  245. package/dist/web/assets/studio-process-CsRoTHOh.js +0 -2
  246. package/dist/web/assets/timeline-events-BbuuFWHV.js +0 -1
  247. package/dist/web/assets/work-turns-BvJlIMmA.js +0 -1
  248. package/vendor/rho-workspace-plugin-agent-0.4.29.tgz +0 -0
  249. package/vendor/rho-workspace-plugin-kernel-0.5.5.tgz +0 -0
  250. package/vendor/rho-workspace-plugin-tables-0.5.0.tgz +0 -0
package/docs/FRONTEND.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Browser application
2
2
 
3
- Updated 2026-11-01. The frontend was reset at the user's request. Previous frontend
3
+ Updated 2026-11-07. The frontend was reset at the user's request. Previous frontend
4
4
  plans, visual specifications, Paper references and appearance rulers have been
5
5
  removed from the working repository. Git retains their history; they do not govern
6
6
  this implementation. This document describes the current application, not another
@@ -10,6 +10,19 @@ prescriptive design system. How it changes next is decided by reviewing real run
10
10
  screens do not yet show. Avoid unnecessary secondary labels and descriptions: let the
11
11
  layout do the explaining.
12
12
 
13
+ ## The Agent's view of the sending tab
14
+
15
+ Each message sent from the Agent panel carries that tab's page and, in Studio,
16
+ its workspace ID, observed layout version and replay position. The service freezes
17
+ a bounded view summary with the message; a retry keeps that original context.
18
+ Under a Studio message, the workspace name records where it was sent from.
19
+ An empty workspace has no views, even when the project contains files. An Agent can
20
+ delete that empty layout through `composition.delete` and restore it through
21
+ `composition.undo`. Deletion removes the sidebar entry and moves an observing tab
22
+ to another workspace, or Overview if none remains. Project files and sessions are
23
+ separate. The [Studio context episode](STUDIO-CONTEXT-EPISODE.md) records the original
24
+ misunderstanding, the real OpenCode run and the limits of this summary.
25
+
13
26
  ## Starting from the work
14
27
 
15
28
  A person needs to find a project, work on its contents, ask an Agent for help and
@@ -111,6 +124,20 @@ inspect what happened. The application gives those actions direct places:
111
124
  the reader is there, also when it is shown again or resized. Only the reader's own
112
125
  wheel, touch, keys or scroll bar take it off the end
113
126
  ([episode](SIMULATED-PROJECT-EPISODE.md#the-notebook)).
127
+ - **Figures.** An R plot built with ggplot2 (directly or by a package on it) is drawn in the
128
+ cell and in the Plots view from its figure record. Pointing at a mark shows its row;
129
+ click, Shift/⌘-click or drag selects, Esc clears, and the rows behind the selection are
130
+ listed by layer. **Ask the Agent** keeps the selection and opens the Agent panel with it
131
+ attached to the next message; the chip's × detaches it. Marks the Agent pointed at appear
132
+ as an amber chip above the plot with its note, shown on the plot when the person has
133
+ nothing selected. A plot nothing described stays a picture; one that failed says why
134
+ under it ([episode](FIGURES-EPISODE.md)). A ggplot a cell saved with `ggsave` is drawn the
135
+ same way wherever its file is shown with the bytes the cell saved: on the answer board, in
136
+ the Results & figures file view and Studio's media view, and under the cell, which names
137
+ the file ([episode](SAVED-FIGURES-EPISODE.md)). Layers that draw the same rows count the
138
+ selection once. Pages drawn with base graphics and ComplexHeatmaps are drawn and selected
139
+ the same way; heatmap cells keep their colour while others are selected, and a selection
140
+ outlines them ([episode](DRAWN-FIGURES-EPISODE.md)).
114
141
  - **Two forms.** Notebook | Console switches how the same sessions read: as a notebook (above)
115
142
  or as a console, one transcript as R or Python print it at a terminal. Each cell is its code
116
143
  after the prompt (`>`/`+` in R, `>>>`/`...` in Python, a new statement at the prompt) and what
@@ -249,24 +276,39 @@ inspect what happened. The application gives those actions direct places:
249
276
  - **Files** opens documents, browses the project's folder and the source folders it
250
277
  works in, and filters the current folder. A source folder is named as the person
251
278
  named it and opens one level at a time, the same way any other folder does.
252
- - **Agent** (the sidebar row) has three tabs. Conversations lists those started in Rho
253
- by day, searchable and by Agent: each row its title, model, effort, messages, state,
254
- context use and cost, with Continue, export as Markdown and the trash; opened, its
255
- facts beside what its latest messages did (the files changed and looked at, each
256
- shown in place when chosen, the commands and the answer). The trash restores or
257
- deletes. Runs follow when there are any, with their execution records, output,
258
- repair context and exports. Agents shows Claude Code and Codex: version, whether
259
- asked, the default, model, settings, Claude Code's own model names and the providers
260
- with their models. Outside Rho adds Rho to the person's own Claude Code or Codex with
261
- one button (`session.connect`) and shows three steps in the state Rho observes:
262
- access to this project, Rho in that Agent, its first call; Other ACP clients gives
263
- the `rho --acp` commands. Core-backed Claude Code/dsh activity streams, native errors
264
- and observed output files sit below in a section read only while it is open
265
- ([activity episode](AGENT-ACTIVITY.md), [Agents and conversations](AGENT-PAGE-EPISODE.md),
266
- [Agents outside Rho](AGENT-PANEL-EPISODE.md#agents-outside-rho)).
279
+ - **Agent** (the sidebar row) has two tabs. Conversations lists every session in
280
+ the project folder by day, searchable and by Agent: Rho's conversations, Claude
281
+ Code and Codex sessions read from the Agents' own records, and observed Harness
282
+ conversations. Each row names where the session started (Terminal, VS Code, Codex
283
+ app, Script…) and whether another window has it open now, and offers Continue,
284
+ the terminal resume command, Markdown export and the trash
285
+ ([session continuity](SESSION-CONTINUITY-EPISODE.md)). Agents is one list of
286
+ the project's Agents in one row design, whatever way each works here: the Agents
287
+ this service can start (a radio for new conversations, the model and folded
288
+ settings; one not found on this computer is greyed out), and the Agents connected
289
+ from their own windows. A window sits under the Agent it belongs to, named by its
290
+ MCP client's own name (`clientInfo`) or else by the session name the Agent chose;
291
+ each window shows its name, a waiting, verified, refused or ended state, what its
292
+ grant allows and its last call. Marks and Agent names come from the Agent icons
293
+ plugin, by the words of the name an Agent gave; a name it does not know shows
294
+ its initial. Below the list, one setup prompt is for the person's own local
295
+ MCP client. The prompt names the project and gives one `rho connect` command,
296
+ whose reply tells the Agent how to configure its own client. Reading or copying grants no
297
+ access. Copy failure leaves selectable text; request failure
298
+ offers retry. ACP observations and Host activity remain under a disclosure
299
+ ([connection episode](AGENT-CONNECT-EPISODE.md)). Conversation rows retain title,
300
+ model, effort, messages, state, usage, cost and their files, commands and answers;
301
+ the trash restores or deletes. Runs follow when present
302
+ ([Agents and conversations](AGENT-PAGE-EPISODE.md)).
267
303
  - **Project settings** manages source folders and explicitly checks available tools.
304
+ - **Work from other windows** feeds the same Graph, Console, answer board
305
+ and session Studio through `agent.sessions.read`. File links in a native answer are
306
+ reported results; current bytes are not labelled historical. A continued native session
307
+ is listed once. Notebook cells join its timeline by exact cell IDs in their receipts,
308
+ not by assuming every call on one connection belongs to that conversation. The
309
+ [external work episode](EXTERNAL-WORK-EPISODE.md) records the actual Harness check.
268
310
  - **Studio** shows how a conversation's work was done. The sidebar lists under Studio
269
- each session started in Rho, newest first (eight, then All sessions), and then the
311
+ each recorded Agent session, newest first (eight, then All sessions), and then the
270
312
  person's own workspaces; the Studio bar names the one shown. A session is titled by its
271
313
  section of the project notes, else by the Agent's title, else by its first message.
272
314
  The **project notes** (`project-notes.md` at the project root) are one Markdown file
@@ -567,13 +609,18 @@ four messages through `web/agent-work.tsx`, the same step model as the panel.
567
609
  `web/agent-settings.tsx` keeps one copy of `conversation.settings.read` per tab for
568
610
  the Agents tab and the panel's settings menu (`web/settings-menu.tsx`);
569
611
  asking an Agent what it offers (`conversation.settings.check`) is always the
570
- person's click.
612
+ person's click. The Agents tab adds an ACP Agent (`conversation.agents.add`) when the
613
+ person clicks Add on one found installed, types its command, or clicks Use in Rho on an
614
+ Agent connected from its own window whose command Rho knows; an added Agent's settings
615
+ show its command and Remove from Rho. An Agent that offers no settings says so in the
616
+ message box rather than offering to ask.
571
617
  Shared notes opens `project-notes.md` in the existing Documents owner. A failed work read keeps the previous
572
618
  view and offers Refresh. The cursor invalidates the read model; individual sources
573
619
  and resources retain their own versions. See the [observed loop](ACP-EPISODE.md#shared-workspace-loop).
574
620
  External ACP sessions use the same work surface with their own source identity,
575
- plans, usage and read-only latest reply. Their input and permission choices stay
576
- in the original client. The visible Overview rereads external projections every
621
+ plans, usage and read-only latest reply there. Their permission choices stay in the
622
+ original client; the Agent panel continues such a session in the folder once no
623
+ other window holds it. The visible Overview rereads external projections every
577
624
  1.5 seconds; it does not start a collector, Agent or Host. Turn cancellation keeps
578
625
  unfinished tool outcomes unknown and does not claim all native processes exited.
579
626
 
@@ -607,7 +654,10 @@ A conversation's messages, steps and endings belong to the service's record, not
607
654
  the tab. The tab keeps only an unsent message per conversation and the identity of
608
655
  a message being sent. When the reply to a send is lost, Retry sends that same message
609
656
  once; when the service refuses it, the words go back into the box. A session started
610
- elsewhere has no message box in Rho: its input stays in its own window.
657
+ elsewhere opens in the same panel with its history, its turns marked with where they
658
+ were sent, and its next message continues that session. While another window holds
659
+ it, the box is disabled with where it is open and a link to continue a copy; Rho
660
+ reloads a session whose record changed after its own last message.
611
661
 
612
662
  The palette and responsive dialogs use native dialog focus containment and Escape.
613
663
  Typography, color and layout are implemented in the three CSS files under `web/`.
package/docs/HEADLESS.md CHANGED
@@ -40,7 +40,7 @@ The selected baseline is macOS arm64, Node 22.22.3 (engine range
40
40
  `>=22.22.0 <27`; the suite and the installed check also passed on Node 24.22.2 and
41
41
  26.13.0), npm 10.9.8, Python 3 with `fcntl`, and Rscript 4.5.2. Windows x64
42
42
  was checked with Node 22.23.4 and Rscript 4.5.1; its writer lock needs no Python, and
43
- there `rho.cmd` starts Rho and Ctrl+Break on its console stops it in order.
43
+ there `rho.cmd` starts Rho, and Ctrl+Break on its console or `rho --stop` stops it in order.
44
44
  The unsigned npm package `@rho-workspace/rho` contains Plugins and one digest-checked Core
45
45
  binary for each of macOS arm64, Linux x64 and arm64 and Windows x64; CI installs it on each.
46
46
  R and any project-selected packages are external prerequisites, and so are the Agent
@@ -89,6 +89,17 @@ the state that named the old address is rewritten to the new one, keeping its to
89
89
  port named, never replaced. A second start on a state that is already running is
90
90
  refused with the running service's address.
91
91
 
92
+ `rho --stop [--state-dir DIR]` (`~/Rho/state` without the flag) stops the service that
93
+ holds that state as Ctrl+C does, from any program. On Windows no signal reaches a
94
+ console program from another process, so an Agent that started Rho in the background
95
+ had no orderly way to stop it ([episode](WINDOWS-SETUP-EPISODE.md)). The command leaves
96
+ `service.stop` in the state folder, which the running launcher takes within half a
97
+ second, then waits until the state's writer lock is free and the process that served
98
+ it, named in `connection.json`, has ended. It prints `{"stopped":{"state":…}}`, and the
99
+ service's own output ends with its `{"shutdown":…}` line. It exits 1 when nothing holds
100
+ that state, or when the service there is an earlier version that never takes the
101
+ request (after 10 s, removing it). A start removes a request no service took.
102
+
92
103
  `--port`, `--rscript`, `--core`, `--plugins` and `--limits` are explicit
93
104
  operator selections; `RHO_RSCRIPT`, `RHO_CORE_BINARY` and `RHO_PYTHON` select
94
105
  equivalent runtimes. A Core override is outside bundled digest verification.
@@ -132,38 +143,89 @@ Exact Host and supplied Origin are checked. The bearer credential is project
132
143
  scoped for external callers. CLI shutdown stops only Hosts started by this
133
144
  service and reports confirmation separately. Existing Hosts keep their owner.
134
145
 
135
- ### Connect Claude Code or Codex
146
+ ### Connect your own Agent
136
147
 
137
- The running service's operator connection adds Rho to the person's own Claude Code
138
- or Codex for one project, as the project page's "Add to …" button does:
148
+ The project's **Agent → Agents** tab offers one prompt for any Agent
149
+ that can configure and run a local stdio MCP server. The prompt names the project
150
+ and gives one command:
139
151
 
140
152
  ```sh
141
- rho --grant /absolute/service-state/connection.json --project PROJECT_FOLDER --agent claude-code|codex
153
+ rho connect "/absolute/project folder" --as NAME
142
154
  ```
143
155
 
144
- It gives that Agent its own grant to the project (kept when it still reaches the
145
- service), runs that Agent's `mcp remove` and `mcp add` on this machine — Claude Code's
146
- with `-s local` in the project folder, Codex's for every folder — and records it, so the
147
- page shows it under that Agent. The JSON reply names the project, its root, the number
148
- of granted methods, whether a new grant was made, and what was added (`name`, `scope`,
149
- `at`). A session that was already open does not have the tools; a new one does.
156
+ The Agent puts a short, stable name for itself in place of `NAME`.
157
+
158
+ Each Rho started from the command line writes a note in `~/Rho/running/`: its state
159
+ folder, address and process ID, with no credential. It removes the note when it
160
+ stops, and a note whose process is gone is ignored. `RHO_RUNNING_DIR` moves that
161
+ folder.
162
+
163
+ Without `--state-dir`, `rho connect` asks each running Rho with a note, and the Rho
164
+ on `~/Rho/state`, which of them holds the folder. It refuses when more than one does.
165
+ The prompt adds `--state-dir` only for a Rho that has no note and does not use
166
+ `~/Rho/state`, such as one started by a program rather than the CLI.
167
+
168
+ When the first `rho` on the service's PATH is not this installation, or cannot run,
169
+ the prompt starts the command with this Node and `cli.js` instead. The build marks
170
+ `dist/cli.js` executable, so a source checkout linked onto PATH keeps working.
171
+
172
+ `rho connect` finds the innermost project holding the folder, grants it to the named
173
+ Agent and tells the Agent the rest in its reply:
174
+
175
+ - the MCP server to add, and the ready entries below;
176
+ - to keep the entry private and out of version control;
177
+ - to call `rho_index` and check the project ID.
178
+
179
+ `--json` prints the `--grant` reply instead. The command refuses, without a grant:
150
180
 
151
- Without `--agent`, the same connection grants one project to one Agent session and
152
- prints how Claude Code starts that session's MCP server:
181
+ - a missing or placeholder name (exit 2);
182
+ - a folder that is not a project, or a state folder no Rho has used (exit 1);
183
+ - a folder that more than one running Rho holds (exit 1);
184
+ - no running Rho, naming the last address it knows (exit 1).
185
+
186
+ `session.instructions` is a read-only operation for the local browser or operator.
187
+ It returns the prompt and the command, without credential contents. Reading or
188
+ copying starts no Agent, grants no access and edits no client configuration. The
189
+ Agent uses its own supported configuration mechanism and writes its own entry; the
190
+ ready entries only spare it the search. The [connection episode](AGENT-CONNECT-EPISODE.md)
191
+ records the actual clients checked and the limits.
192
+
193
+ The running service's operator connection also grants one project to a named Agent
194
+ directly, which setup prompts gave before `rho connect`:
153
195
 
154
196
  ```sh
155
- rho --grant /absolute/service-state/connection.json --project PROJECT_FOLDER [--session NAME]
197
+ rho --grant /absolute/service-state/connection.json \
198
+ --project-id EXISTING_PROJECT_ID --session my-agent
156
199
  ```
157
200
 
158
- `--project` is the folder relative to `--root`; `--session` defaults to
159
- `claude-code`, the session `--agent claude-code` uses, and `--session codex` is the one
160
- `--agent codex` uses. When the service is not running, both forms say so and exit 1. The JSON reply names the project, the private session connection
161
- file, the number of granted methods (the server default), an `mcp` entry
162
- (`name`, `command`, `args`) for an MCP configuration file, and the equivalent
163
- `claude mcp add rho-<folder> -- … --mcp <file>` command. `rho --mcp FILE` serves
164
- that grant on stdio with the four tools `rho_index`, `rho_resolve`, `rho_call` and
165
- `rho_read`; nothing else writes to stdout in that mode. Every connection file is a
166
- credential. `rho --help` prints the usage; an unknown option exits 2 with it.
201
+ `--project-id` selects an already registered project, including one chosen outside
202
+ the service's projects folder. The older `--project PROJECT_FOLDER` form remains
203
+ available for a folder relative to `--root`; select exactly one form. Choose a
204
+ stable session name for each Agent and reuse it on retry. Without `--session`, the
205
+ legacy default is `claude-code`.
206
+
207
+ The JSON reply supplies `mcp.name`, `mcp.command` and `mcp.args` for the Agent to
208
+ register in its own client. `rho --mcp FILE` serves that project grant on stdio with
209
+ `rho_index`, `rho_resolve`, `rho_call` and `rho_read`. Connection files are credentials;
210
+ keep their contents out of prompts and projects. The reply also holds ready entries
211
+ for the clients whose own mechanism has been used with Rho: `claude` and `codex`
212
+ (their `mcp add` commands), `opencode` (the project's `.opencode/opencode.json` and
213
+ the entry to merge) and `dsh` (the DeepSeek Harness profile patch and the entry to
214
+ append). The bridge sends its MCP client's `clientInfo` name and version as
215
+ `x-rho-client`; Rho keeps it with the grant and shows it as `client` in the
216
+ snapshot's `agents`, ignoring anything that is not short printable text.
217
+
218
+ Repeating the same grant keeps a valid credential with the same project, methods
219
+ and profile; changing scope, expired access or stale connection data requires a
220
+ fresh one. A client may need to reload its tools or open a new session. A saved
221
+ entry alone does not verify a connection: call `rho_index` in that client and check
222
+ its project scope. The page observes grants and actual calls separately and does
223
+ not claim that an old successful call means the Agent is online now.
224
+
225
+ The existing `--agent claude-code|codex` shortcut and `session.connect` remain
226
+ available. They use those clients' own `mcp add` commands (Claude Code in the project
227
+ folder, Codex in user configuration). They are no longer the page's setup workflow.
228
+ A stopped service is reported with exit 1; an unknown CLI option exits 2 with usage.
167
229
 
168
230
  Agent 0.4.11 provides persistent Claude and Codex ACP entries and retains each
169
231
  tool step's human title, ACP category and one identifying input (command, file path,
@@ -204,6 +266,26 @@ settings name one; a model without Auto runs in Accept edits with the adapter's
204
266
  Codex's adapter already opens in its own auto-review mode. ACP cancellation confirms the
205
267
  turn, not every native job.
206
268
 
269
+ Any other Agent that speaks ACP v1 runs through the generic driver, with no adapter of its
270
+ own. `conversation.agents.add` adds one for new conversations in every project, given its
271
+ program (on `PATH` or a path) and arguments, such as `["hermes", "acp"]`. Rho starts it
272
+ once in the project, as `conversation.settings.check` does: a session is opened, what the
273
+ Agent offers is read and the session is removed; no message is sent. The Agent is kept as
274
+ `acp:<name>` only when it answered; otherwise the reply is the Agent's error, or the last
275
+ line it printed when it exited first. `conversation.settings.read` lists the added Agents
276
+ (`added`) and, from `PATH`, the Agents with a known ACP command that are installed and not
277
+ added (`installed`; Agent's `knownAcpAgents`). `conversation.agents.remove` takes one out
278
+ of new conversations. Each conversation records the command it started with, so it
279
+ continues with the same Agent. `--acp-command '<argv JSON>'` / `RHO_ACP_COMMAND` still
280
+ names one ACP Agent at start (`acp`); without it, `dsh acp` is used when Harness's `acp`
281
+ profile is installed. A Harness session in the folder continues only through Harness's own
282
+ ACP command, named at start or added. See the [episode](AGENTS-IN-RHO-EPISODE.md).
283
+
284
+ | Protected resource | Configuration and default | Exhaustion |
285
+ | --- | --- | --- |
286
+ | Added Agents, kept in the service's Agent settings | `conversations.maxAddedAgents` 16 | Adding another is refused until one is removed. |
287
+ | Starting an Agent to add it | `conversations.connectTimeoutMs` 60 s; one start per command at a time | The start ends; nothing is added and the reason is returned. |
288
+
207
289
  For an external ACP client, select this command as that client's Agent executable:
208
290
 
209
291
  ```sh
@@ -279,7 +361,8 @@ const check = await rho.call('requirements.check', {
279
361
  | `context.create/read` | Exact buffer/version/range, declared selected entities, a media rectangle with page and pixels/points, or one run (`run: {operationId}`): its state, exit, stop, the last 8 KiB of retained stderr with its byte offset and Core's truncation flag, the script reference, args and declared files. |
280
362
  | `session.grant`, `binding.open/close/list/activity` | Operator-selected method grant, external binding metadata and bounded tool receipts. Agent grants include the read-only `project.entries` and no other `project.*` method. |
281
363
  | `session.connect` | The person at this machine only: grants Claude Code or Codex access to one project and runs that Agent's own `mcp add` (`claude mcp add -s local` in the project folder, `codex mcp add`) with the project-scoped connection. A grant that still reaches this service is kept; a new one the Agent refuses is removed. Each CLI call: 20 s and 8 KiB of output, then stopped with what it printed. |
282
- | `conversation.start/send/stop/read/permission` | Only the browser on this machine. Original message identities, retained text/tool steps and one selected Agent session. New conversations use the selected Claude or Codex ACP connection. Cancel is confirmed by the original prompt response; lost transport keeps an unknown outcome. Reads and reconnect never replay a prompt. Native permission choices are scoped to the original pending request. Limits are in `conversationLimits` and `--limits`. |
364
+ | `conversation.start/send/stop/read/permission` | Only the browser on this machine. Original message identities, retained text/tool steps and one selected Agent session. New conversations use the selected Claude or Codex ACP connection; `continue: {session, copy}` instead loads a session listed by `agent.sessions.list` under its own native ID, or forks it, and is refused while another process holds that session. Cancel is confirmed by the original prompt response; lost transport keeps an unknown outcome. Reads and reconnect never replay a prompt. Native permission choices are scoped to the original pending request. Limits are in `conversationLimits` and `--limits`. |
365
+ | `agent.sessions.list/read` | Only the browser on this machine; excluded from Agent grants. Claude Code and Codex sessions in the project folder read from their own records, and observed Harness conversations, each with where it started, whether another window holds it now and its resume command. Reading starts no Agent and is bounded (`nativeSessionLimits` in the Agent plugin). |
283
366
  | `composition.put/read/apply/undo`, `view.close` | Registered entry/version, props and binding checks; `apply`/`undo` are conditional tree transactions with receipts ([Collaboration](COLLABORATION.md#composition-and-selection)). Uninstalled UI is explicitly unavailable. `rho.action` (version `1`, no bindings) is Rho's own form for one proposed action: props `{title, action, actionVersion, operationId, input, repairOf?}`, and the action must be registered at that version. |
284
367
  | `workspace.save/export/restore` | Drafts/undo, bytes/provenance, selections and composition intent; native execution is not replayed. |
285
368
  | `action.export` | One run as ordinary files in a new project folder (default `exports/<operationId>`): `script/` holds the code that ran, from the run's own record; `outputs/` holds each declared file as the run left it; `provenance.json` and `PROVENANCE.md` give the run, script digest, arguments, inputs, each file's SHA-256 and whether it matches the inventory the run wrote. A declared file that was not written, or no longer matches that inventory, is named and left out, and the export says `partial`. When the script has unsaved changes the call must say `unsaved: "include"` (written as `<name>.unsaved.<ext>`, marked as never run) or `"leave"`. Runs nothing; never writes into an existing folder. |
@@ -425,6 +508,7 @@ RHO_CORE_BINARY=/absolute/rho-core npm run recovery
425
508
  RHO_CORE_BINARY=/absolute/rho-core npm run agent
426
509
  npm run pack:local -- --core darwin-arm64=/absolute/mac/rho-core \
427
510
  --core linux-x64=/absolute/linux-x64/rho-core --core linux-arm64=/absolute/linux-arm64/rho-core \
511
+ --core win32-x64=/absolute/win32-x64/rho-core.exe \
428
512
  --core-source /absolute/Rho-core --plugins /absolute/Rho-plugins
429
513
  node scripts/install-acceptance.mjs /absolute/rho-workspace-rho-0.5.2.tgz \
430
514
  /absolute/ordinary-project /absolute/paired-project
@@ -460,6 +544,25 @@ records source commits/trees, build-input and lock hashes, binary/package digest
460
544
  and platform, plus each selected plugin tarball identity. It does not build Core, sign or publish to a registry. Direct
461
545
  packing of the development source-linked root is rejected.
462
546
 
547
+ Each Core is built as CI's `core` job in [`ci.yml`](../.github/workflows/ci.yml) builds it.
548
+ Check out the Core commit that `components.json` selects with LF line endings
549
+ (`git config --global core.autocrlf false` before cloning). Core compiles
550
+ `docs/ACTIVITY.md` and `docs/MANAGED-RUN.md` in byte for byte, and under Git for
551
+ Windows' default a fresh clone gave a Core whose contract text ended its lines in CRLF
552
+ where CI's has LF. Core keeps those two files LF itself from `8ef933a`, and the packer
553
+ records them among Core's build inputs. Then run
554
+ `CARGO_PROFILE_DEV_DEBUG=0 cargo build --locked --target TARGET`: on Windows, TARGET is
555
+ `x86_64-pc-windows-msvc` (MSVC Build Tools) and the binary is
556
+ `target/x86_64-pc-windows-msvc/debug/rho-core.exe`. A Core built on another machine is
557
+ not CI's: it names that machine's Cargo registry folder, under the builder's user
558
+ folder, 78 times. To carry the accepted Cores instead, take CI's `core-PLATFORM`
559
+ artifacts or the published package's `vendor/core/PLATFORM/` binaries, and add
560
+ `--core-composition` with the composition that records them (the package's
561
+ `vendor/composition.json`); the packer refuses a binary whose digest it does not record. On Windows, `npm ci` in Rho-plugins also
562
+ unpacks the Agent adapters' optional platform clients (Codex 462 MiB, the Claude Agent
563
+ SDK 284 MiB), which the package leaves out. In one run that took 14.5 of its 15
564
+ minutes ([#112](https://github.com/YuLab-SMU/Rho/issues/112)).
565
+
463
566
 
464
567
  ## Native artifact intake (phase 1)
465
568
 
@@ -7,9 +7,10 @@ or becoming a base dependency. The first consumer is the optional
7
7
  Its scientific implementation remains in sclet and its objects remain in the
8
8
  project's shared R session. See the [observed episode](THIRD-PARTY-PLUGINS-EPISODE.md).
9
9
 
10
- This is source functionality after Rho 0.5.4, not a new npm release. Build the
11
- current checkout with `npm run build` and use `node dist/cli.js` in place of
12
- `rho` until a distribution containing it is installed.
10
+ Runtime package installation is included in Rho 0.5.5. User-configured remote
11
+ markets are source functionality after 0.5.6. Build the current checkout with
12
+ `npm run build` and use `node dist/cli.js` in place of `rho` for that new path
13
+ until a distribution containing it is installed.
13
14
 
14
15
  ## Install and manage
15
16
 
@@ -55,6 +56,69 @@ selection. Both preserve native tasks, R sessions, project files and receipts.
55
56
  Package revisions are retained in the service's `plugins/versions` directory;
56
57
  remove is not a disk-purge command. Closing a view only releases its renderer.
57
58
 
59
+ ## Remote plugin markets
60
+
61
+ In **Plugins → Third-party plugins → Plugin markets**, add an HTTPS JSON index.
62
+ The plugin search above includes its titles, descriptions, package ids and
63
+ keywords. Rho retains the index locally; opening the page, searching and listing
64
+ do not fetch it again or install its packages. **Refresh** explicitly reads the
65
+ source again. A failed refresh displays its error and keeps the last successful
66
+ index available. **Remove** removes the source, keeping installed plugins and
67
+ their recorded market keywords searchable.
68
+
69
+ The [YuLab Rho index](https://raw.githubusercontent.com/YuLab-SMU/Rho/main/site/market/rho.json)
70
+ includes Semantic figures, discoverable by `ggtree`, `clusterProfiler`, `dotplot`
71
+ and `cnetplot`. It is an optional source; add it explicitly:
72
+
73
+ ```sh
74
+ rho plugin market add https://raw.githubusercontent.com/YuLab-SMU/Rho/main/site/market/rho.json
75
+ rho plugin market list
76
+ rho plugin market install MARKET_ID yulab.semantic-figures
77
+ rho plugin market refresh MARKET_ID
78
+ rho plugin market remove MARKET_ID
79
+ ```
80
+
81
+ Use the id returned by `add` or `list` for `MARKET_ID`. The ordinary
82
+ `--connection FILE` option selects a running service. The browser and CLI use
83
+ the same saved sources. Agents can read cached indexes with `extension.list`;
84
+ adding, refreshing, removing sources and installing packages remain local-person
85
+ operations through `extension.market.change` and `extension.install`.
86
+
87
+ Publishers can host a static file matching the [actual index](../site/market/rho.json):
88
+
89
+ ```json
90
+ {
91
+ "apiVersion": 1,
92
+ "title": "My lab's Rho plugins",
93
+ "plugins": [{
94
+ "id": "lab.my-plugin",
95
+ "title": "My plugin",
96
+ "version": "0.1.0",
97
+ "description": "What this plugin does",
98
+ "source": "@my-lab/rho-plugin@0.1.0",
99
+ "repository": "https://github.com/my-lab/rho-plugin",
100
+ "needs": "Required tools or data",
101
+ "keywords": ["analysis", "visualization"]
102
+ }]
103
+ }
104
+ ```
105
+
106
+ Each index selects one version per plugin id. `keywords` is optional; the other
107
+ fields shown are required. Package sources use an exact npm version matching
108
+ `version`, or `git+https://…#FULL_40_CHARACTER_COMMIT:package/path`. The package's
109
+ actual plugin id and version must match before installation selects it. Install
110
+ binds the source to the index digest the person selected; a changed or removed
111
+ index refuses a stale install. The installed package records its market URL,
112
+ title, index digest and keywords alongside its own source and runtime-tree digest.
113
+
114
+ Index URLs use HTTPS without credentials, queries or fragments. Explicit loopback
115
+ HTTP supports local development. Redirects, authenticated indexes, automatic
116
+ refresh/update and tarball entries in markets are not supported in this pass;
117
+ direct package installation still accepts tarballs. An index is publisher metadata,
118
+ not a signature or proof of package validity. This Rho `apiVersion: 1` index is
119
+ separate from the [Harness index](../site/market/index.json); the formats are not
120
+ interchangeable. See the [observed market episode](PLUGIN-MARKETS-EPISODE.md).
121
+
58
122
  ## Create a package
59
123
 
60
124
  ```sh
@@ -141,6 +205,10 @@ output.textContent = receipt.state === 'completed'
141
205
  ? receipt.value.greeting : receipt.error;
142
206
  ```
143
207
 
208
+ The frame follows the page's own height from 200 to 900 px, so let the page flow
209
+ rather than fill the viewport; a taller page scrolls inside the frame. The page
210
+ `create` generates shows a labelled form, a result and a failure state to start from.
211
+
144
212
  Pass a third argument to `rho.call` to retain an explicit original changeId.
145
213
  The default generates one per deliberate call. A stale digest is refused; reopen
146
214
  the view after an update. Several views may be declared and selected in the plugin
@@ -174,6 +242,8 @@ and obtained receipts, or records an unknown result after an interrupted call.
174
242
 
175
243
  | Protected resource | Default configuration |
176
244
  | --- | --- |
245
+ | Configured market sources / entries in each index | `maxMarkets: 16`, `maxMarketEntries: 128` |
246
+ | Each downloaded index / request duration | `maxMarketBytes: 262144`, `marketTimeoutMs: 10000` |
177
247
  | Installed selections / retained revisions | `maxPlugins: 32`, `maxVersions: 128` |
178
248
  | Admitted runtime tree | `maxFiles: 20000`, `maxPackageBytes: 134217728` |
179
249
  | Skill/view bytes | `maxContentBytes: 524288` |
@@ -181,6 +251,8 @@ and obtained receipts, or records an unknown result after an interrupted call.
181
251
  | Concurrent calls / delegated calls per invocation | `maxRunning: 4`, `maxDelegations: 32` |
182
252
  | Worker / each install subprocess | `timeoutMs: 30000`, `installTimeoutMs: 180000` |
183
253
 
254
+ Market limits refuse an initial add or retain the previous index after a failed
255
+ refresh. The byte limit also checks streamed responses without a Content-Length.
184
256
  The tree-size check applies after npm staging; it is not a disk quota on npm/Git.
185
257
  A timed-out worker does not prove a delegated native task stopped. Observe its
186
258
  original identity. Retention limits refuse rather than silently evict identities;
@@ -347,6 +347,11 @@ observation of the original identity, never replacement work. A refused connecti
347
347
  transport failure whose outcome is known: nothing reached the service, so the call
348
348
  returns `unavailable` naming the address and saying nothing ran (`delivered: false`).
349
349
 
350
+ Since 0.4.31 each call also carries `x-rho-client`: the name and version the MCP
351
+ client gave in its own `initialize` (`clientInfo`), each URL-encoded and at most 128
352
+ characters, joined by `/`. A client that gives no name sends no header. The
353
+ application uses it to say which Agent a connection belongs to; it grants nothing.
354
+
350
355
  The pure `./layered-contract` entry defines the four tool inputs and Agent note
351
356
  props. `./layered` provides the bounded complete-object cache and caller checks;
352
357
  it owns no second registry, native loop or task scheduler. Before execution it
@@ -429,3 +434,32 @@ local storage and observation work; they do not limit the native Agent.
429
434
  `test/external-session.test.mjs` checks identity, prefix conflicts, omissions,
430
435
  missing outcomes, redaction, project containment, retained failure and pagination.
431
436
  The Rho application records its separate real Harness/browser acceptance.
437
+
438
+ ### Native Claude Code and Codex sessions
439
+
440
+ Agent 0.4.30 exports `native-sessions`. `listNativeSessions(root, nativeSources(env))`
441
+ lists the Claude Code and Codex sessions whose recorded working folder is `root`,
442
+ read from the Agents' own records: `CLAUDE_CONFIG_DIR` (or `~/.claude`)
443
+ `/projects/<folder>/<id>.jsonl` and `CODEX_HOME` (or `~/.codex`)
444
+ `/sessions/**/rollout-*.jsonl`. Each summary keeps the native session ID, title,
445
+ times, turn counts, where it started (Claude Code's `entrypoint`, Codex's
446
+ `originator`), whether another process holds it now (Claude Code's live
447
+ `sessions/<pid>.json` with a running PID, Codex's `thread-writer-locks/<id>.lock`)
448
+ and the terminal resume command. `readNativeSession` streams one record into the
449
+ same turn shape as `readExternalSession`, with each turn's tools, results and
450
+ reply. Reading starts no Agent, takes no lock and writes nothing.
451
+ `nativeSessionLimits` names the budgets: 64 sessions per listing, 4,096 files
452
+ scanned per Claude Code folder and across Codex's sessions, 256 KiB read from each end of a file for a summary, at most 256 MiB
453
+ streamed from the end for a read, 200 turns, 256 tools per turn, and the text and
454
+ tool field limits above. Sidechains, injected reminders and local command output
455
+ are excluded. A recorded interruption is stopped. A last turn without an end record
456
+ is running while its file was written in the last minute; after that it is completed
457
+ when it has a reply and no unanswered tool, and unknown otherwise.
458
+
459
+ To continue such a session, the application passes its ID as `sessionId` (ACP
460
+ `session/load`). `forkFrom` instead asks the Agent for a separate copy through
461
+ `session/fork`; the connection is refused before sending when the Agent does not
462
+ advertise fork, or returns the same ID. `acpEnvironment` drops inherited Claude Code
463
+ session markers (`CLAUDECODE`, `CLAUDE_CODE_CHILD_SESSION` and related variables):
464
+ a Claude Code started under them saves no transcript, so its session could not be
465
+ listed or continued anywhere else.
@@ -7,6 +7,38 @@ export declare function acpCommand(agent: AcpAgent): {
7
7
  * optional dependencies that an application need not install, so name the selected
8
8
  * executable, else the one already named in the environment, else the client on PATH. */
9
9
  export declare function acpEnvironment(agent: AcpAgent, env: NodeJS.ProcessEnv, executable?: string): NodeJS.ProcessEnv;
10
+ export declare function withoutSessionMarkers(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
11
+ /** The file a shell runs for `program`: the program itself when it names a path, else the first
12
+ * runnable match on PATH. On Windows a copied environment keeps the variable's own case (Path),
13
+ * and a program is a file with an extension PATHEXT names (claude.exe, an npm codex.cmd). */
14
+ export declare function locate(program: string, env: NodeJS.ProcessEnv): string | null;
10
15
  /** Why the adapter could not start the person's client, or null when its executable is
11
16
  * there. The adapters report a missing client only as a closed connection. */
12
17
  export declare function missingClient(agent: AcpAgent, env: NodeJS.ProcessEnv): string | null;
18
+ /** Agents that serve ACP through a command of their own: the program a person installs and the
19
+ * arguments that make it an ACP Agent, as the ACP registry (github.com/agentclientprotocol/registry,
20
+ * read 2026-11-07) gives them or as Rho has run them. Rho starts any of these as it starts a
21
+ * command the person names; the list only lets it find them. */
22
+ export interface KnownAcpAgent {
23
+ id: string;
24
+ name: string;
25
+ program: string;
26
+ args: string[];
27
+ }
28
+ export declare const knownAcpAgents: KnownAcpAgent[];
29
+ /** The known Agents installed on this computer, each with the file its command starts. Finding
30
+ * them reads PATH (and Harness's profile folder) and starts nothing: whether one answers as an
31
+ * ACP Agent is known only once it is started. */
32
+ export declare function installedAcpAgents(env?: NodeJS.ProcessEnv): {
33
+ id: string;
34
+ name: string;
35
+ command: {
36
+ file: string;
37
+ args: string[];
38
+ };
39
+ }[];
40
+ /** The known Agent a command starts, when it starts one with its ACP arguments. */
41
+ export declare function knownAcpAgent(command: {
42
+ file: string;
43
+ args: string[];
44
+ }): KnownAcpAgent | null;