@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.
- package/dist/agent-connect.d.ts +42 -0
- package/dist/agent-connect.js +68 -0
- package/dist/answer-board.js +3 -3
- package/dist/bridge.js +6 -1
- package/dist/browser-access.d.ts +1 -0
- package/dist/browser-access.js +5 -3
- package/dist/capabilities.d.ts +21 -5
- package/dist/capabilities.js +6 -4
- package/dist/cli.js +113 -18
- package/dist/composition.d.ts +1 -1
- package/dist/composition.js +13 -3
- package/dist/connect-cli.d.ts +50 -0
- package/dist/connect-cli.js +128 -0
- package/dist/contract.generated.d.ts +1437 -381
- package/dist/contract.generated.js +1 -1
- package/dist/contracts/owners.generated.js +1160 -267
- package/dist/conversation-presentation.d.ts +9 -2
- package/dist/conversation-presentation.js +3 -1
- package/dist/conversations.d.ts +306 -7
- package/dist/conversations.js +208 -22
- package/dist/discovery.js +3 -3
- package/dist/extension-contract.d.ts +19 -0
- package/dist/extension-contract.js +15 -6
- package/dist/extension-markets.d.ts +74 -0
- package/dist/extension-markets.js +166 -0
- package/dist/extensions.d.ts +29 -1
- package/dist/extensions.js +13 -4
- package/dist/external-work.d.ts +22 -0
- package/dist/external-work.js +91 -0
- package/dist/plugin-cli.js +75 -3
- package/dist/plugin-inventory.d.ts +56 -0
- package/dist/plugin-inventory.js +41 -0
- package/dist/plugin-inventory.json +1581 -102
- package/dist/plugin-presentation.d.ts +105 -2
- package/dist/plugin-presentation.js +59 -5
- package/dist/plugins.d.ts +14 -3
- package/dist/plugins.js +12 -6
- package/dist/project-notes.js +1 -1
- package/dist/protocol.d.ts +7 -0
- package/dist/protocol.js +40 -15
- package/dist/replay.js +4 -0
- package/dist/response-contracts.js +26 -11
- package/dist/running.d.ts +10 -0
- package/dist/running.js +45 -0
- package/dist/server.d.ts +4 -10
- package/dist/server.js +140 -14
- package/dist/state.d.ts +8 -0
- package/dist/state.js +8 -0
- package/dist/studio-layout.js +3 -3
- package/dist/task-frame.d.ts +1 -1
- package/dist/timeline-events.d.ts +1 -0
- package/dist/timeline-events.js +8 -1
- package/dist/ui-context.d.ts +73 -0
- package/dist/ui-context.js +98 -0
- package/dist/ui-contract.d.ts +23 -0
- package/dist/web/.vite/manifest.json +135 -76
- package/dist/web/assets/answer-board-CeYS8k8y.js +1 -0
- package/dist/web/assets/choices-D8vGwsl2.js +1 -0
- package/dist/web/assets/{console-BSjLGe0T.js → console-Dyuo1q4N.js} +4 -4
- package/dist/web/assets/{dist-Tzoe_zm-.js → dist-CSiCyBml.js} +1 -1
- package/dist/web/assets/{dist-Cw8hRIlT.js → dist-D9FLb9Hm.js} +1 -1
- package/dist/web/assets/{dist-foH9IKc6.js → dist-FXbTBwML.js} +1 -1
- package/dist/web/assets/{dist-Buk0lwzI.js → dist-l3DUhbw5.js} +1 -1
- package/dist/web/assets/{explore-in-BVUy3ZW_.js → explore-in-BfSFGRh2.js} +1 -1
- package/dist/web/assets/graph-BU2_o5uA.js +2 -0
- package/dist/web/assets/index-C16mXVvk.css +1 -0
- package/dist/web/assets/index-CWg9XYXx.js +952 -0
- package/dist/web/assets/markdown.reader-Ct2-e2Zt.png +0 -0
- package/dist/web/assets/{notes-meaning-pVbbQUGP.js → notes-meaning-T2m5zQfv.js} +1 -1
- package/dist/web/assets/overview-PzfLJCo-.js +6 -0
- package/dist/web/assets/preview-BguEdsza.js +1 -0
- package/dist/web/assets/previews-pWNik-2g.js +3 -0
- package/dist/web/assets/{review-CMxQlQ-C.js → review-Dy_85lcH.js} +1 -1
- package/dist/web/assets/rho.editor-CCJeyHma.png +0 -0
- package/dist/web/assets/rho.flow-WkMj6fRS.png +0 -0
- package/dist/web/assets/rho.media-Cc6amodO.png +0 -0
- package/dist/web/assets/rho.notebook-6vsZKGDq.png +0 -0
- package/dist/web/assets/rho.object-BGoeXjte.png +0 -0
- package/dist/web/assets/rho.plots-yIiISCkb.png +0 -0
- package/dist/web/assets/rho.scatter-DwHxesCs.png +0 -0
- package/dist/web/assets/rho.servers-DKf_mnNq.png +0 -0
- package/dist/web/assets/rho.table-DWOGaWDa.png +0 -0
- package/dist/web/assets/rho.variables-CKcWczhQ.png +0 -0
- package/dist/web/assets/{skills-BFNSyrnD.js → skills-Dyz7mBlc.js} +1 -1
- package/dist/web/assets/{skills-work-BGPSnF_I.js → skills-work-BEGqlCkx.js} +1 -1
- package/dist/web/assets/studio-process-D-ykbC4D.js +2 -0
- package/dist/web/assets/timeline-events-DKTho9fU.js +1 -0
- package/dist/web/assets/work-turns-DSabCogR.js +1 -0
- package/dist/web/assets/{workspace-CWlkjLNx.js → workspace-DfjBL--r.js} +2 -2
- package/dist/web/composition.json +135 -80
- package/dist/web/index.html +3 -3
- package/dist/web/renderer.json +1 -1
- package/dist/web-assets.js +2 -2
- package/dist/work-graph.d.ts +11 -1
- package/dist/work-graph.js +16 -5
- package/dist/workspace.d.ts +2 -2
- package/dist/workspace.js +8 -7
- package/docs/FRONTEND.md +71 -21
- package/docs/HEADLESS.md +127 -24
- package/docs/THIRD-PARTY-PLUGINS.md +75 -3
- package/node_modules/@rho-workspace/plugin-agent/README.md +34 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/acp-command.d.ts +32 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/acp-command.js +54 -11
- package/node_modules/@rho-workspace/plugin-agent/dist/acp-conversation.d.ts +1 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/acp-conversation.js +29 -3
- package/node_modules/@rho-workspace/plugin-agent/dist/external-session-contract.js +11 -5
- package/node_modules/@rho-workspace/plugin-agent/dist/external-session.d.ts +12 -1
- package/node_modules/@rho-workspace/plugin-agent/dist/index.d.ts +8 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/index.js +3 -2
- package/node_modules/@rho-workspace/plugin-agent/dist/mcp-entry.d.ts +13 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/mcp-entry.js +13 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/mcp.js +16 -8
- package/node_modules/@rho-workspace/plugin-agent/dist/native-sessions.d.ts +70 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/native-sessions.js +538 -0
- package/node_modules/@rho-workspace/plugin-agent/package.json +2 -1
- package/node_modules/@rho-workspace/plugin-figures/LICENSE +661 -0
- package/node_modules/@rho-workspace/plugin-figures/README.md +191 -0
- package/node_modules/@rho-workspace/plugin-figures/dist/index.d.ts +236 -0
- package/node_modules/@rho-workspace/plugin-figures/dist/index.js +165 -0
- package/node_modules/@rho-workspace/plugin-figures/dist/operations.d.ts +44 -0
- package/node_modules/@rho-workspace/plugin-figures/dist/operations.js +39 -0
- package/node_modules/@rho-workspace/plugin-figures/dist/presentation.d.ts +19 -0
- package/node_modules/@rho-workspace/plugin-figures/dist/presentation.js +26 -0
- package/node_modules/@rho-workspace/plugin-figures/dist/record.d.ts +188 -0
- package/node_modules/@rho-workspace/plugin-figures/dist/record.js +143 -0
- package/node_modules/@rho-workspace/plugin-figures/dist/ui-styles.d.ts +1 -0
- package/node_modules/@rho-workspace/plugin-figures/dist/ui-styles.js +68 -0
- package/node_modules/@rho-workspace/plugin-figures/dist/ui.d.ts +56 -0
- package/node_modules/@rho-workspace/plugin-figures/dist/ui.js +363 -0
- package/node_modules/@rho-workspace/plugin-figures/package.json +41 -0
- package/node_modules/@rho-workspace/plugin-figures/py/figures.py +856 -0
- package/node_modules/@rho-workspace/plugin-figures/r/figures.R +775 -0
- package/node_modules/@rho-workspace/plugin-kernel/README.md +27 -3
- package/node_modules/@rho-workspace/plugin-kernel/dist/contract.d.ts +12 -0
- package/node_modules/@rho-workspace/plugin-kernel/dist/contract.js +8 -1
- package/node_modules/@rho-workspace/plugin-kernel/dist/index.d.ts +61 -0
- package/node_modules/@rho-workspace/plugin-kernel/dist/index.js +125 -9
- package/node_modules/@rho-workspace/plugin-kernel/dist/session-scope.d.ts +14 -0
- package/node_modules/@rho-workspace/plugin-kernel/dist/session-scope.js +9 -0
- package/node_modules/@rho-workspace/plugin-kernel/dist/ui-base.d.ts +23 -5
- package/node_modules/@rho-workspace/plugin-kernel/dist/ui-notebook-work.js +1 -1
- package/node_modules/@rho-workspace/plugin-kernel/dist/ui-notebook.d.ts +6 -4
- package/node_modules/@rho-workspace/plugin-kernel/dist/ui-notebook.js +44 -17
- package/node_modules/@rho-workspace/plugin-kernel/dist/ui-styles.js +6 -0
- package/node_modules/@rho-workspace/plugin-kernel/package.json +1 -1
- package/node_modules/@rho-workspace/plugin-kernel/runners/runner.R +144 -4
- package/node_modules/@rho-workspace/plugin-kernel/runners/runner.py +106 -1
- package/node_modules/@rho-workspace/plugin-tables/README.md +5 -0
- package/node_modules/@rho-workspace/plugin-tables/dist/index.d.ts +1 -0
- package/node_modules/@rho-workspace/plugin-tables/dist/index.js +19 -3
- package/node_modules/@rho-workspace/plugin-tables/dist/ui.js +1 -1
- package/node_modules/@rho-workspace/plugin-tables/package.json +1 -1
- package/node_modules/hono/dist/adapter/aws-lambda/handler.js +1 -1
- package/node_modules/hono/dist/cjs/adapter/aws-lambda/handler.js +1 -1
- package/node_modules/hono/dist/cjs/adapter/bun/serve-static.js +1 -1
- package/node_modules/hono/dist/cjs/adapter/bun/websocket.js +1 -1
- package/node_modules/hono/dist/cjs/client/fetch-result-please.js +1 -1
- package/node_modules/hono/dist/cjs/helper/accepts/accepts.js +2 -1
- package/node_modules/hono/dist/cjs/helper/ssg/ssg.js +5 -3
- package/node_modules/hono/dist/cjs/jsx/base.js +49 -30
- package/node_modules/hono/dist/cjs/jsx/components.js +2 -2
- package/node_modules/hono/dist/cjs/jsx/constants.js +2 -0
- package/node_modules/hono/dist/cjs/jsx/jsx-runtime.js +13 -17
- package/node_modules/hono/dist/cjs/middleware/etag/index.js +3 -1
- package/node_modules/hono/dist/cjs/middleware/pretty-json/index.js +1 -0
- package/node_modules/hono/dist/cjs/middleware/timing/timing.js +4 -3
- package/node_modules/hono/dist/cjs/utils/cookie.js +2 -2
- package/node_modules/hono/dist/cjs/utils/mime.js +1 -1
- package/node_modules/hono/dist/cjs/utils/url.js +1 -1
- package/node_modules/hono/dist/client/fetch-result-please.js +1 -1
- package/node_modules/hono/dist/helper/accepts/accepts.js +2 -1
- package/node_modules/hono/dist/helper/ssg/ssg.js +5 -3
- package/node_modules/hono/dist/jsx/base.js +49 -32
- package/node_modules/hono/dist/jsx/components.js +2 -2
- package/node_modules/hono/dist/jsx/constants.js +2 -1
- package/node_modules/hono/dist/jsx/jsx-runtime.js +15 -19
- package/node_modules/hono/dist/middleware/etag/index.js +3 -1
- package/node_modules/hono/dist/middleware/language/language.js +1 -1
- package/node_modules/hono/dist/middleware/pretty-json/index.js +1 -0
- package/node_modules/hono/dist/middleware/timing/timing.js +4 -3
- package/node_modules/hono/dist/utils/cookie.js +2 -2
- package/node_modules/hono/dist/utils/mime.js +1 -1
- package/node_modules/hono/dist/utils/url.js +1 -1
- package/node_modules/hono/package.json +1 -1
- package/node_modules/jose/dist/webapi/jwe/general/decrypt.js +3 -2
- package/node_modules/jose/dist/webapi/jwks/remote.js +1 -1
- package/node_modules/jose/dist/webapi/jws/general/verify.js +2 -8
- package/node_modules/jose/dist/webapi/lib/jwe_decrypt.js +11 -8
- package/node_modules/jose/dist/webapi/lib/key_management.js +0 -1
- package/node_modules/jose/package.json +1 -1
- package/package.json +6 -4
- package/protocol/index.json +106 -64
- package/protocol/operations/agent.sessions.list.json +57 -3
- package/protocol/operations/agent.sessions.read.json +61 -4
- package/protocol/operations/capability.list.json +382 -6
- package/protocol/operations/composition.apply.json +10 -2
- package/protocol/operations/composition.delete.json +845 -0
- package/protocol/operations/composition.read.json +10 -2
- package/protocol/operations/composition.undo.json +10 -2
- package/protocol/operations/conversation.agents.add.json +346 -0
- package/protocol/operations/conversation.agents.remove.json +340 -0
- package/protocol/operations/conversation.configure.json +29 -0
- package/protocol/operations/conversation.decide.json +225 -0
- package/protocol/operations/conversation.list.json +29 -0
- package/protocol/operations/conversation.permission.json +225 -0
- package/protocol/operations/conversation.read.json +225 -0
- package/protocol/operations/conversation.restore.json +29 -0
- package/protocol/operations/conversation.send.json +294 -0
- package/protocol/operations/conversation.settings.check.json +226 -416
- package/protocol/operations/conversation.settings.read.json +224 -411
- package/protocol/operations/conversation.settings.update.json +248 -475
- package/protocol/operations/conversation.start.json +313 -6
- package/protocol/operations/conversation.stop.json +225 -0
- package/protocol/operations/conversation.trash.json +29 -0
- package/protocol/operations/extension.describe.json +39 -0
- package/protocol/operations/extension.install.json +62 -0
- package/protocol/operations/extension.list.json +164 -1
- package/protocol/operations/extension.market.change.json +210 -0
- package/protocol/operations/figure.read.json +265 -0
- package/protocol/operations/figure.select.json +157 -0
- package/protocol/operations/kernel.interrupt.json +119 -0
- package/protocol/operations/kernel.read.json +119 -0
- package/protocol/operations/kernel.run.json +119 -0
- package/protocol/operations/observation.snapshot.json +445 -8
- package/protocol/operations/project.openFile.json +10 -2
- package/protocol/operations/session.grant.json +4 -0
- package/protocol/operations/session.instructions.json +43 -0
- package/protocol/operations/shared.json +1 -0
- package/protocol/operations/view.close.json +10 -2
- package/protocol/operations/view.protection.set.json +10 -2
- package/vendor/composition.json +174 -109
- package/vendor/rho-workspace-plugin-agent-0.4.33.tgz +0 -0
- package/vendor/rho-workspace-plugin-figures-0.5.1.tgz +0 -0
- package/vendor/rho-workspace-plugin-kernel-0.5.13.tgz +0 -0
- package/vendor/rho-workspace-plugin-tables-0.5.2.tgz +0 -0
- package/web/theme.css +17 -0
- package/dist/web/assets/answer-board-CBkGbSLD.js +0 -1
- package/dist/web/assets/canvas-D8rDdfDz.js +0 -1
- package/dist/web/assets/choices-b0XhrGQV.js +0 -1
- package/dist/web/assets/graph-1OdIJ9l7.js +0 -2
- package/dist/web/assets/index-CsC3sTRq.css +0 -1
- package/dist/web/assets/index-CxmItXqa.js +0 -891
- package/dist/web/assets/overview-B9UtVJ32.js +0 -6
- package/dist/web/assets/preview-CksD_5KS.js +0 -1
- package/dist/web/assets/studio-process-CsRoTHOh.js +0 -2
- package/dist/web/assets/timeline-events-BbuuFWHV.js +0 -1
- package/dist/web/assets/work-turns-BvJlIMmA.js +0 -1
- package/vendor/rho-workspace-plugin-agent-0.4.29.tgz +0 -0
- package/vendor/rho-workspace-plugin-kernel-0.5.5.tgz +0 -0
- 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-
|
|
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
|
|
253
|
-
by day, searchable and by Agent:
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
one
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
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
|
|
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
|
|
576
|
-
|
|
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
|
|
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
|
|
146
|
+
### Connect your own Agent
|
|
136
147
|
|
|
137
|
-
The
|
|
138
|
-
|
|
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
|
|
153
|
+
rho connect "/absolute/project folder" --as NAME
|
|
142
154
|
```
|
|
143
155
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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
|
-
|
|
152
|
-
|
|
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
|
|
197
|
+
rho --grant /absolute/service-state/connection.json \
|
|
198
|
+
--project-id EXISTING_PROJECT_ID --session my-agent
|
|
156
199
|
```
|
|
157
200
|
|
|
158
|
-
`--project`
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
`
|
|
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;
|