@rho-workspace/rho 0.5.3 → 0.5.5
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/README.md +24 -5
- package/dist/browser-access.js +3 -2
- package/dist/capabilities.d.ts +29 -2
- package/dist/capabilities.js +79 -2
- package/dist/cli.js +237 -99
- package/dist/contract.generated.d.ts +441 -16
- package/dist/contract.generated.js +1 -1
- package/dist/contracts/owners.generated.js +459 -10
- package/dist/conversation-presentation.d.ts +3 -1
- package/dist/conversation-presentation.js +16 -6
- package/dist/conversations.d.ts +10 -6
- package/dist/conversations.js +17 -13
- package/dist/discovery.d.ts +1 -0
- package/dist/discovery.js +3 -3
- package/dist/extension-contract.d.ts +99 -0
- package/dist/extension-contract.js +52 -0
- package/dist/extension-directory.d.ts +9 -0
- package/dist/extension-directory.js +11 -0
- package/dist/extension-worker.d.ts +1 -0
- package/dist/extension-worker.js +36 -0
- package/dist/extensions.d.ts +157 -0
- package/dist/extensions.js +349 -0
- package/dist/installs.d.ts +11 -0
- package/dist/installs.js +179 -0
- package/dist/plugin-cli.d.ts +1 -0
- package/dist/plugin-cli.js +139 -0
- package/dist/plugin-inventory.json +18 -0
- package/dist/plugins.d.ts +3 -3
- package/dist/project-notes.js +2 -0
- package/dist/project-work.d.ts +3 -1
- package/dist/project-work.js +15 -2
- package/dist/protocol.d.ts +7 -0
- package/dist/protocol.js +11 -7
- package/dist/screen-check-skill.d.ts +2 -0
- package/dist/screen-check-skill.js +39 -0
- package/dist/server.d.ts +6 -1
- package/dist/server.js +105 -15
- package/dist/web/.vite/manifest.json +65 -65
- package/dist/web/assets/{canvas-BXhC8RDZ.js → canvas-D8rDdfDz.js} +1 -1
- package/dist/web/assets/choices-b0XhrGQV.js +1 -0
- package/dist/web/assets/{console-e1P5qYQ5.js → console-BSjLGe0T.js} +1 -1
- package/dist/web/assets/{dist-Dd3iAGFy.js → dist-Buk0lwzI.js} +2 -2
- package/dist/web/assets/dist-Cw8hRIlT.js +1 -0
- package/dist/web/assets/dist-Tzoe_zm-.js +3 -0
- package/dist/web/assets/{dist-DEorbOW0.js → dist-foH9IKc6.js} +1 -1
- package/dist/web/assets/explore-in-BVUy3ZW_.js +1 -0
- package/dist/web/assets/graph-1OdIJ9l7.js +2 -0
- package/dist/web/assets/index-CsC3sTRq.css +1 -0
- package/dist/web/assets/{index-BYuKpyoi.js → index-CxmItXqa.js} +220 -121
- package/dist/web/assets/{notes-meaning-B3HFbh84.js → notes-meaning-pVbbQUGP.js} +1 -1
- package/dist/web/assets/overview-B9UtVJ32.js +6 -0
- package/dist/web/assets/preview-CksD_5KS.js +1 -0
- package/dist/web/assets/{review-BVh9jWMB.js → review-CMxQlQ-C.js} +1 -1
- package/dist/web/assets/{skills-DPaEYkln.js → skills-BFNSyrnD.js} +1 -1
- package/dist/web/assets/{skills-work-dvjfy_tu.js → skills-work-BGPSnF_I.js} +1 -1
- package/dist/web/assets/{studio-process-BYm8mjRJ.js → studio-process-CsRoTHOh.js} +2 -2
- package/dist/web/assets/{timeline-events-CDZ7wiJX.js → timeline-events-BbuuFWHV.js} +1 -1
- package/dist/web/assets/{work-turns-BeCt303c.js → work-turns-BvJlIMmA.js} +1 -1
- package/dist/web/assets/workspace-CWlkjLNx.js +5 -0
- package/dist/web/composition.json +80 -80
- package/dist/web/index.html +3 -3
- package/dist/web/renderer.json +1 -1
- package/dist/web-assets.d.ts +2 -1
- package/dist/web-assets.js +3 -2
- package/dist/work-contract.js +2 -2
- package/docs/FRONTEND.md +30 -14
- package/docs/HEADLESS.md +60 -14
- package/docs/PLUGIN-AUTHORING.md +4 -0
- package/docs/THIRD-PARTY-PLUGINS.md +190 -0
- package/example/pa14-qs/.rho/rho/conversations/c-67f77cfebaba2cea.json +1 -1
- package/example/pa14-qs/.rho/rho/conversations/c-91aa2e46b1ac1a6c.json +1 -1
- package/example/pa14-qs/.rho/rho/conversations/c-fa24dfd80dfe4bcb.json +1 -1
- package/node_modules/@hono/node-server/dist/index.js +11 -0
- package/node_modules/@hono/node-server/dist/index.mjs +11 -0
- package/node_modules/@hono/node-server/dist/listener.js +11 -0
- package/node_modules/@hono/node-server/dist/listener.mjs +11 -0
- package/node_modules/@hono/node-server/dist/request.js +11 -0
- package/node_modules/@hono/node-server/dist/request.mjs +11 -0
- package/node_modules/@hono/node-server/dist/server.js +11 -0
- package/node_modules/@hono/node-server/dist/server.mjs +11 -0
- package/node_modules/@hono/node-server/dist/vercel.js +11 -0
- package/node_modules/@hono/node-server/dist/vercel.mjs +11 -0
- package/node_modules/@hono/node-server/package.json +1 -1
- package/node_modules/@rho-workspace/plugin-agent/README.md +42 -1
- package/node_modules/@rho-workspace/plugin-agent/dist/acp-conversation.js +14 -3
- package/node_modules/@rho-workspace/plugin-agent/dist/activity-normalize.d.ts +1 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/activity-normalize.js +2 -2
- package/node_modules/@rho-workspace/plugin-agent/dist/conversation.d.ts +1 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/conversation.js +1 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/dsh-session.d.ts +6 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/dsh-session.js +174 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/external-session-contract.d.ts +82 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/external-session-contract.js +15 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/external-session.d.ts +73 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/external-session.js +190 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/generic-acp.d.ts +11 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/generic-acp.js +7 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/index.d.ts +373 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/index.js +1 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/mcp.js +5 -1
- package/node_modules/@rho-workspace/plugin-agent/dist/operations.d.ts +33 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/operations.js +3 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/presentation.d.ts +14 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/presentation.js +2 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/ui-external-session.d.ts +15 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/ui-external-session.js +37 -0
- package/node_modules/@rho-workspace/plugin-agent/package.json +5 -1
- package/node_modules/@rho-workspace/plugin-annotations/package.json +1 -1
- package/node_modules/@rho-workspace/plugin-documents/README.md +4 -0
- package/node_modules/@rho-workspace/plugin-documents/dist/index.d.ts +3 -0
- package/node_modules/@rho-workspace/plugin-documents/dist/index.js +1 -1
- package/node_modules/@rho-workspace/plugin-documents/package.json +1 -1
- package/node_modules/@rho-workspace/plugin-kernel/README.md +71 -10
- package/node_modules/@rho-workspace/plugin-kernel/dist/code.d.ts +2 -0
- package/node_modules/@rho-workspace/plugin-kernel/dist/code.js +4 -1
- package/node_modules/@rho-workspace/plugin-kernel/dist/contract.js +5 -0
- package/node_modules/@rho-workspace/plugin-kernel/dist/index.d.ts +7 -0
- package/node_modules/@rho-workspace/plugin-kernel/dist/index.js +55 -8
- package/node_modules/@rho-workspace/plugin-kernel/dist/lineage.d.ts +9 -6
- package/node_modules/@rho-workspace/plugin-kernel/dist/lineage.js +18 -41
- package/node_modules/@rho-workspace/plugin-kernel/dist/operations.js +5 -2
- package/node_modules/@rho-workspace/plugin-kernel/dist/script-flow.d.ts +39 -0
- package/node_modules/@rho-workspace/plugin-kernel/dist/script-flow.js +661 -0
- package/node_modules/@rho-workspace/plugin-kernel/dist/ui-base.d.ts +3 -0
- package/node_modules/@rho-workspace/plugin-kernel/dist/ui-base.js +10 -0
- package/node_modules/@rho-workspace/plugin-kernel/dist/ui-flow.d.ts +38 -4
- package/node_modules/@rho-workspace/plugin-kernel/dist/ui-flow.js +194 -97
- package/node_modules/@rho-workspace/plugin-kernel/dist/ui-notebook-work.js +1 -2
- package/node_modules/@rho-workspace/plugin-kernel/dist/ui-notebook.d.ts +10 -2
- package/node_modules/@rho-workspace/plugin-kernel/dist/ui-notebook.js +79 -18
- package/node_modules/@rho-workspace/plugin-kernel/dist/ui-styles.js +115 -45
- package/node_modules/@rho-workspace/plugin-kernel/dist/ui.d.ts +1 -1
- package/node_modules/@rho-workspace/plugin-kernel/dist/ui.js +1 -1
- package/node_modules/@rho-workspace/plugin-kernel/dist/value-graph.d.ts +63 -0
- package/node_modules/@rho-workspace/plugin-kernel/dist/value-graph.js +344 -0
- package/node_modules/@rho-workspace/plugin-kernel/package.json +1 -1
- package/node_modules/@rho-workspace/plugin-kernel/runners/runner.R +6 -3
- package/node_modules/@rho-workspace/plugin-kernel/runners/runner.py +6 -3
- package/node_modules/express-rate-limit/dist/index.cjs +1 -1
- package/node_modules/express-rate-limit/dist/index.mjs +1 -1
- package/node_modules/express-rate-limit/package.json +1 -1
- package/node_modules/ip-address/dist/ipv6.js +1 -1
- package/node_modules/ip-address/package.json +1 -1
- package/node_modules/playwright-core/LICENSE +202 -0
- package/node_modules/playwright-core/NOTICE +5 -0
- package/node_modules/playwright-core/ThirdPartyNotices.txt +13 -0
- package/node_modules/playwright-core/bin/install_media_pack.ps1 +5 -0
- package/node_modules/playwright-core/bin/install_webkit_wsl.ps1 +33 -0
- package/node_modules/playwright-core/bin/reinstall_chrome_beta_linux.sh +42 -0
- package/node_modules/playwright-core/bin/reinstall_chrome_beta_mac.sh +13 -0
- package/node_modules/playwright-core/bin/reinstall_chrome_beta_win.ps1 +24 -0
- package/node_modules/playwright-core/bin/reinstall_chrome_stable_linux.sh +42 -0
- package/node_modules/playwright-core/bin/reinstall_chrome_stable_mac.sh +12 -0
- package/node_modules/playwright-core/bin/reinstall_chrome_stable_win.ps1 +24 -0
- package/node_modules/playwright-core/bin/reinstall_msedge_beta_linux.sh +48 -0
- package/node_modules/playwright-core/bin/reinstall_msedge_beta_mac.sh +11 -0
- package/node_modules/playwright-core/bin/reinstall_msedge_beta_win.ps1 +23 -0
- package/node_modules/playwright-core/bin/reinstall_msedge_dev_linux.sh +48 -0
- package/node_modules/playwright-core/bin/reinstall_msedge_dev_mac.sh +11 -0
- package/node_modules/playwright-core/bin/reinstall_msedge_dev_win.ps1 +23 -0
- package/node_modules/playwright-core/bin/reinstall_msedge_stable_linux.sh +48 -0
- package/node_modules/playwright-core/bin/reinstall_msedge_stable_mac.sh +11 -0
- package/node_modules/playwright-core/bin/reinstall_msedge_stable_win.ps1 +24 -0
- package/node_modules/playwright-core/browsers.json +52 -0
- package/node_modules/playwright-core/cli.js +22 -0
- package/node_modules/playwright-core/index.js +17 -0
- package/node_modules/playwright-core/index.mjs +28 -0
- package/node_modules/playwright-core/lib/bootstrap.js +149 -0
- package/node_modules/playwright-core/lib/coreBundle.js +78041 -0
- package/node_modules/playwright-core/lib/entry/cliDaemon.js +5 -0
- package/node_modules/playwright-core/lib/entry/dashboardApp.js +3 -0
- package/node_modules/playwright-core/lib/entry/mcp.js +10 -0
- package/node_modules/playwright-core/lib/entry/oopBrowserDownload.js +3 -0
- package/node_modules/playwright-core/lib/package.js +50 -0
- package/node_modules/playwright-core/lib/server/chromium/appIcon.png +0 -0
- package/node_modules/playwright-core/lib/server/electron/loader.js +123 -0
- package/node_modules/playwright-core/lib/serverRegistry.js +1939 -0
- package/node_modules/playwright-core/lib/serverRegistry.js.LICENSE +65 -0
- package/node_modules/playwright-core/lib/tools/cli-client/channelSessions.js +141 -0
- package/node_modules/playwright-core/lib/tools/cli-client/cli.js +7 -0
- package/node_modules/playwright-core/lib/tools/cli-client/help.json +808 -0
- package/node_modules/playwright-core/lib/tools/cli-client/minimist.js +128 -0
- package/node_modules/playwright-core/lib/tools/cli-client/output.js +352 -0
- package/node_modules/playwright-core/lib/tools/cli-client/program.js +422 -0
- package/node_modules/playwright-core/lib/tools/cli-client/registry.js +180 -0
- package/node_modules/playwright-core/lib/tools/cli-client/session.js +261 -0
- package/node_modules/playwright-core/lib/tools/dashboard/appIcon.png +0 -0
- package/node_modules/playwright-core/lib/tools/utils/extension.js +112 -0
- package/node_modules/playwright-core/lib/tools/utils/socketConnection.js +108 -0
- package/node_modules/playwright-core/lib/utilsBundle.js +86078 -0
- package/node_modules/playwright-core/lib/utilsBundle.js.LICENSE +1890 -0
- package/node_modules/playwright-core/lib/vite/dashboard/assets/codeMirrorModule--QdMvsKi.css +1 -0
- package/node_modules/playwright-core/lib/vite/dashboard/assets/codeMirrorModule-CQ8RZGBm.js +32 -0
- package/node_modules/playwright-core/lib/vite/dashboard/assets/codicon-DCmgc-ay.ttf +0 -0
- package/node_modules/playwright-core/lib/vite/dashboard/assets/firefox-1bWoP6pv.svg +1 -0
- package/node_modules/playwright-core/lib/vite/dashboard/assets/firefox-beta-k3eOH_eK.svg +1 -0
- package/node_modules/playwright-core/lib/vite/dashboard/assets/firefox-nightly-Cp5nfeDT.svg +1 -0
- package/node_modules/playwright-core/lib/vite/dashboard/assets/index-AwgwcYie.css +1 -0
- package/node_modules/playwright-core/lib/vite/dashboard/assets/index-hRvO4yU2.js +12 -0
- package/node_modules/playwright-core/lib/vite/dashboard/assets/safari-na3_-uQk.svg +1 -0
- package/node_modules/playwright-core/lib/vite/dashboard/index.html +29 -0
- package/node_modules/playwright-core/lib/vite/dashboard/playwright-logo.svg +24 -0
- package/node_modules/playwright-core/lib/vite/htmlReport/index.html +16 -0
- package/node_modules/playwright-core/lib/vite/htmlReport/report.css +2 -0
- package/node_modules/playwright-core/lib/vite/htmlReport/report.js +32 -0
- package/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule--QdMvsKi.css +1 -0
- package/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule-DK72OMRi.js +32 -0
- package/node_modules/playwright-core/lib/vite/recorder/assets/codicon-DCmgc-ay.ttf +0 -0
- package/node_modules/playwright-core/lib/vite/recorder/assets/index-BZpYJZ-P.css +1 -0
- package/node_modules/playwright-core/lib/vite/recorder/assets/index-Cn0mmDuv.js +129 -0
- package/node_modules/playwright-core/lib/vite/recorder/index.html +29 -0
- package/node_modules/playwright-core/lib/vite/recorder/playwright-logo.svg +9 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/assets/codeMirrorModule-BEB2e8M3.js +32 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-D-g2vrvf.js +184 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/assets/urlMatch-L3liM589.js +1 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/assets/xtermModule-B794rD2Z.js +7 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/codeMirrorModule.-QdMvsKi.css +1 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/codicon.DCmgc-ay.ttf +0 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/defaultSettingsView.C8BeHuxd.css +1 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/index.B_TqY17P.css +1 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/index.html +44 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/index.oNry3Hjv.js +1 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/manifest.webmanifest +16 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/playwright-logo.svg +9 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/snapshot.B_Jk1wbt.js +1 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/snapshot.html +10 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/sw.bundle.js +4 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.CYwC_gH1.js +5 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.CyMfwkXJ.css +1 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.html +18 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/xtermModule.kHJ-D0s7.css +1 -0
- package/node_modules/playwright-core/lib/webp_codec.LICENSE +173 -0
- package/node_modules/playwright-core/lib/webp_codec.wasm +0 -0
- package/node_modules/playwright-core/lib/xdg-open +1267 -0
- package/node_modules/playwright-core/package.json +34 -0
- package/package.json +13 -7
- package/protocol/index.json +75 -21
- package/protocol/operations/agent.sessions.list.json +100 -0
- package/protocol/operations/agent.sessions.read.json +266 -0
- package/protocol/operations/conversation.settings.check.json +147 -4
- package/protocol/operations/conversation.settings.read.json +145 -3
- package/protocol/operations/conversation.settings.update.json +166 -4
- package/protocol/operations/conversation.start.json +2 -1
- package/protocol/operations/extension.call.json +132 -0
- package/protocol/operations/extension.content.json +78 -0
- package/protocol/operations/extension.describe.json +195 -0
- package/protocol/operations/extension.install.json +198 -0
- package/protocol/operations/extension.list.json +123 -0
- package/protocol/operations/extension.manage.json +55 -0
- package/protocol/operations/extension.read.json +112 -0
- package/protocol/operations/kernel.interrupt.json +20 -0
- package/protocol/operations/kernel.read.json +30 -0
- package/protocol/operations/kernel.run.json +36 -1
- package/protocol/operations/kernel.stop.json +10 -0
- package/protocol/operations/project.work.read.json +3 -2
- package/protocol/operations/session.grant.json +9 -0
- package/scripts/browser-checks.mjs +53 -0
- package/scripts/screen-check.mjs +193 -0
- package/scripts/third-party-acceptance.mjs +77 -0
- package/vendor/composition.json +111 -111
- package/vendor/rho-workspace-plugin-agent-0.4.29.tgz +0 -0
- package/vendor/rho-workspace-plugin-annotations-0.5.2.tgz +0 -0
- package/vendor/rho-workspace-plugin-documents-0.4.11.tgz +0 -0
- package/vendor/rho-workspace-plugin-kernel-0.5.5.tgz +0 -0
- package/web/theme.css +17 -2
- package/dist/web/assets/choices-B-y2OYvE.js +0 -1
- package/dist/web/assets/dist-CBM2oq6g.js +0 -1
- package/dist/web/assets/dist-CH56yNDn.js +0 -3
- package/dist/web/assets/explore-in-muWXOGOY.js +0 -1
- package/dist/web/assets/graph-CK-df5lh.js +0 -2
- package/dist/web/assets/index-DBd77u4a.css +0 -1
- package/dist/web/assets/overview-D1Ev2OC_.js +0 -6
- package/dist/web/assets/preview-HbmQKUGY.js +0 -1
- package/dist/web/assets/workspace-d5Hw_ClZ.js +0 -5
- package/vendor/rho-workspace-plugin-agent-0.4.27.tgz +0 -0
- package/vendor/rho-workspace-plugin-documents-0.4.10.tgz +0 -0
- package/vendor/rho-workspace-plugin-kernel-0.5.2.tgz +0 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import * as fs from 'node:fs/promises';
|
|
2
|
+
import { watch } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { homedir } from 'node:os';
|
|
5
|
+
import { parseArgs } from 'node:util';
|
|
6
|
+
import { randomUUID } from 'node:crypto';
|
|
7
|
+
import { Extensions } from './extensions.js';
|
|
8
|
+
import { RhoClient } from './client.js';
|
|
9
|
+
const help = `Independent Rho plugins (API 1)
|
|
10
|
+
rho plugin create DIRECTORY [--id my-plugin]
|
|
11
|
+
rho plugin check DIRECTORY
|
|
12
|
+
rho plugin add SOURCE [--connection FILE]
|
|
13
|
+
rho plugin list
|
|
14
|
+
rho plugin update ID [--source SOURCE]
|
|
15
|
+
rho plugin enable|disable|remove ID
|
|
16
|
+
rho plugin dev DIRECTORY
|
|
17
|
+
rho plugin call ID OPERATION --project RELATIVE_FOLDER --input JSON [--change-id ID]
|
|
18
|
+
|
|
19
|
+
SOURCE: npm package, local folder/.tgz, public HTTPS .tgz, or
|
|
20
|
+
git+https://host/repo.git#ref:relative/package
|
|
21
|
+
Management uses the running Rho's private connection file (default ~/Rho/state/connection.json).
|
|
22
|
+
Only install packages you trust: hosts run native code with your OS permissions.
|
|
23
|
+
Install skips lifecycle scripts. Build packages before adding them.
|
|
24
|
+
dev watches source and installs checked snapshots; an invalid edit keeps the previous version.
|
|
25
|
+
Remove preserves project files, live sessions, receipts and retained package revisions.
|
|
26
|
+
`;
|
|
27
|
+
export async function pluginCli(args) {
|
|
28
|
+
const { values, positionals } = parseArgs({ args, allowPositionals: true, options: { connection: { type: 'string' }, id: { type: 'string' }, source: { type: 'string' }, project: { type: 'string' }, input: { type: 'string' }, 'change-id': { type: 'string' }, help: { type: 'boolean' } } });
|
|
29
|
+
const [command, target, operation] = positionals;
|
|
30
|
+
if (values.help || !command) {
|
|
31
|
+
process.stdout.write(help);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (command === 'create') {
|
|
35
|
+
if (!target)
|
|
36
|
+
throw new Error('Name a new plugin directory.');
|
|
37
|
+
const id = values.id ?? path.basename(path.resolve(target));
|
|
38
|
+
if (!/^[a-z0-9][a-z0-9._-]{0,95}$/.test(id))
|
|
39
|
+
throw new Error('Use a lowercase plugin id containing letters, digits, dots, underscores or hyphens.');
|
|
40
|
+
await fs.mkdir(path.resolve(target));
|
|
41
|
+
const manifest = { apiVersion: 1, id, title: id, description: 'An independent Rho plugin.', host: 'host.mjs', operations: [{ id: 'greet', title: 'Greet', description: 'Return a greeting without changing project data.', effect: 'read', methods: [], inputSchema: { type: 'object', properties: { name: { type: 'string', maxLength: 120 } }, required: ['name'], additionalProperties: false } }], skills: [{ id: 'guide', title: 'Use this plugin', file: 'SKILL.md' }], views: [{ id: 'main', title: id, file: 'view.html' }] };
|
|
42
|
+
const files = {
|
|
43
|
+
'package.json': JSON.stringify({ name: 'rho-plugin-' + id, version: '0.1.0', type: 'module', license: 'MIT', rhoPlugin: 'rho-plugin.json', files: ['rho-plugin.json', 'host.mjs', 'view.html', 'SKILL.md'] }, null, 2) + '\n',
|
|
44
|
+
'rho-plugin.json': JSON.stringify(manifest, null, 2) + '\n',
|
|
45
|
+
'host.mjs': `export async function run(operation, input, context) {\n if (operation === 'greet') return { greeting: 'Hello, ' + input.name + '!' };\n throw new Error('Unknown operation');\n}\n`,
|
|
46
|
+
'SKILL.md': `# ${id}\n\nRead extension.describe for the installed digest and operation schemas. Call greet with a name. This operation reads only. Use a stable changeId for native operations; observe extension.read after a lost reply.\n`,
|
|
47
|
+
'view.html': `<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>${id}</title><style>body{font:16px system-ui;margin:24px;color:#24312b}input,button{font:inherit;padding:8px}output{display:block;margin-top:16px}</style><h1>${id}</h1><form><label>Your name <input name="name" value="World" maxlength="120"></label> <button>Greet</button></form><output aria-live="polite"></output><script>document.querySelector('form').onsubmit=async e=>{e.preventDefault();const out=document.querySelector('output');try{const result=await rho.call('greet',{name:e.target.elements.name.value});out.textContent=result.value?.greeting||result.error}catch(error){out.textContent=error.message}};</script></html>\n`,
|
|
48
|
+
'README.md': `# ${id}\n\nDevelop: \`rho plugin dev .\`\nCheck: \`rho plugin check .\`\nDistribute: \`npm pack --ignore-scripts\`, then share the tarball, Git package source or publish to your own npm namespace.\n\nSee Rho's docs/THIRD-PARTY-PLUGINS.md for the host and iframe APIs, permissions and contribution process.\n`,
|
|
49
|
+
};
|
|
50
|
+
for (const [file, text] of Object.entries(files))
|
|
51
|
+
await fs.writeFile(path.join(target, file), text, { flag: 'wx' });
|
|
52
|
+
process.stdout.write(`Created ${path.resolve(target)}. Run rho plugin check, then rho plugin dev.\n`);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (command === 'check') {
|
|
56
|
+
if (!target)
|
|
57
|
+
throw new Error('Name a plugin directory.');
|
|
58
|
+
const checked = await new Extensions('').check(path.resolve(target));
|
|
59
|
+
process.stdout.write(JSON.stringify({ valid: true, ...checked }, null, 2) + '\n');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const client = await RhoClient.fromFile(path.resolve(values.connection ?? path.join(homedir(), 'Rho', 'state', 'connection.json')));
|
|
63
|
+
const list = async () => (await client.call('extension.list', {})).plugins;
|
|
64
|
+
const find = async () => { const p = (await list()).find(p => p.id === target); if (!p)
|
|
65
|
+
throw new Error('Plugin is not installed: ' + target); return p; };
|
|
66
|
+
// npm/Git staging can take longer than the ordinary 30-second observation client.
|
|
67
|
+
// There is no execution retry here; a lost response is reconciled with list.
|
|
68
|
+
const install = async (body) => {
|
|
69
|
+
const local = body.source.startsWith('file:') ? body.source.slice(5) : body.source;
|
|
70
|
+
if (await fs.stat(path.resolve(local)).catch(() => null))
|
|
71
|
+
body = { ...body, source: path.resolve(local) };
|
|
72
|
+
const response = await fetch(new URL('/api/v2/extension.install', client.connection.url), { method: 'POST', headers: { authorization: 'Bearer ' + client.connection.token, 'content-type': 'application/json' }, body: JSON.stringify(body) });
|
|
73
|
+
const result = await response.json();
|
|
74
|
+
if (!result.ok)
|
|
75
|
+
throw new Error(result.error.message);
|
|
76
|
+
return result.value;
|
|
77
|
+
};
|
|
78
|
+
let result;
|
|
79
|
+
if (command === 'list')
|
|
80
|
+
result = await list();
|
|
81
|
+
else if (command === 'add') {
|
|
82
|
+
if (!target)
|
|
83
|
+
throw new Error('Name a package source.');
|
|
84
|
+
result = await install({ source: target });
|
|
85
|
+
}
|
|
86
|
+
else if (command === 'update') {
|
|
87
|
+
const p = await find();
|
|
88
|
+
result = await install({ source: values.source ?? p.source, replace: p.id, expectedDigest: p.digest });
|
|
89
|
+
}
|
|
90
|
+
else if (['enable', 'disable', 'remove'].includes(command)) {
|
|
91
|
+
const p = await find();
|
|
92
|
+
result = await client.call('extension.manage', { pluginId: p.id, expectedDigest: p.digest, action: command });
|
|
93
|
+
}
|
|
94
|
+
else if (command === 'call') {
|
|
95
|
+
if (!operation || !values.project)
|
|
96
|
+
throw new Error('Call needs an operation and --project.');
|
|
97
|
+
const p = await find(), project = await client.call('project.open', { path: values.project });
|
|
98
|
+
const changeId = values['change-id'] ?? randomUUID();
|
|
99
|
+
process.stderr.write('changeId: ' + changeId + '\n');
|
|
100
|
+
result = await client.call('extension.call', { projectId: project.id, pluginId: p.id, expectedDigest: p.digest, operation, input: JSON.parse(values.input ?? '{}'), changeId });
|
|
101
|
+
}
|
|
102
|
+
else if (command === 'dev') {
|
|
103
|
+
if (!target)
|
|
104
|
+
throw new Error('Name a plugin directory.');
|
|
105
|
+
const root = path.resolve(target), checked = await new Extensions('').check(root);
|
|
106
|
+
let busy = false, pending = false;
|
|
107
|
+
const update = async () => {
|
|
108
|
+
if (busy) {
|
|
109
|
+
pending = true;
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
busy = true;
|
|
113
|
+
try {
|
|
114
|
+
const p = (await list()).find(p => p.id === checked.manifest.id);
|
|
115
|
+
const installed = await install({ source: root, ...(p ? { replace: p.id, expectedDigest: p.digest } : {}) });
|
|
116
|
+
process.stdout.write(`Installed ${installed.id} ${installed.version} ${installed.digest}. Reopen its view to load this snapshot.\n`);
|
|
117
|
+
}
|
|
118
|
+
catch (e) {
|
|
119
|
+
process.stderr.write((e instanceof Error ? e.message : String(e)) + '\n');
|
|
120
|
+
}
|
|
121
|
+
finally {
|
|
122
|
+
busy = false;
|
|
123
|
+
if (pending) {
|
|
124
|
+
pending = false;
|
|
125
|
+
void update();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
await update();
|
|
130
|
+
let timer;
|
|
131
|
+
watch(root, { recursive: true }, (_event, filename) => { if (filename?.split(/[\\/]/).some(p => p === 'node_modules' || p === '.git'))
|
|
132
|
+
return; clearTimeout(timer); timer = setTimeout(() => void update(), 400); });
|
|
133
|
+
process.stdout.write('Watching ' + root + '. Stop with Ctrl-C.\n');
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
else
|
|
137
|
+
throw new Error('Unknown plugin command.\n' + help);
|
|
138
|
+
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
139
|
+
}
|
|
@@ -768,6 +768,24 @@
|
|
|
768
768
|
},
|
|
769
769
|
"listing": {
|
|
770
770
|
"actions": [
|
|
771
|
+
{
|
|
772
|
+
"presentation": {
|
|
773
|
+
"order": 58,
|
|
774
|
+
"displayName": "External conversations",
|
|
775
|
+
"description": "Reads retained conversations observed in this project. Input remains in the original client.",
|
|
776
|
+
"readOnly": true,
|
|
777
|
+
"runsCode": false
|
|
778
|
+
}
|
|
779
|
+
},
|
|
780
|
+
{
|
|
781
|
+
"presentation": {
|
|
782
|
+
"order": 59,
|
|
783
|
+
"displayName": "External conversation",
|
|
784
|
+
"description": "Reads native turns, tool outcomes and result receipts without sending or resuming anything.",
|
|
785
|
+
"readOnly": true,
|
|
786
|
+
"runsCode": false
|
|
787
|
+
}
|
|
788
|
+
},
|
|
771
789
|
{
|
|
772
790
|
"presentation": {
|
|
773
791
|
"order": 62,
|
package/dist/plugins.d.ts
CHANGED
|
@@ -74,7 +74,7 @@ export declare class Plugins {
|
|
|
74
74
|
timeoutSeconds?: number;
|
|
75
75
|
}[];
|
|
76
76
|
};
|
|
77
|
-
ids(): ("media" | "r" | "agent" | "files" | "documents" | "requirements" | "tables" | "charts" | "annotations" | "console" | "kernel"
|
|
77
|
+
ids(): ("media" | "r" | "agent" | "files" | "skills" | "documents" | "requirements" | "tables" | "charts" | "annotations" | "console" | "kernel")[];
|
|
78
78
|
isKnown(id: string): id is PluginId;
|
|
79
79
|
availabilityFor(id: PluginId): any;
|
|
80
80
|
need<K extends PluginId>(id: K): Modules[K];
|
|
@@ -161,10 +161,10 @@ export declare class Plugins {
|
|
|
161
161
|
reason?: undefined;
|
|
162
162
|
};
|
|
163
163
|
descriptors(): PluginDescriptor[];
|
|
164
|
-
availableIds(): ("media" | "r" | "agent" | "files" | "documents" | "requirements" | "tables" | "charts" | "annotations" | "console" | "kernel"
|
|
164
|
+
availableIds(): ("media" | "r" | "agent" | "files" | "skills" | "documents" | "requirements" | "tables" | "charts" | "annotations" | "console" | "kernel")[];
|
|
165
165
|
descriptor(id: string): PluginDescriptor | undefined;
|
|
166
166
|
nativeAvailability(rscript: string): Promise<any>;
|
|
167
|
-
operationOwner(method: string): "media" | "r" | "agent" | "files" | "documents" | "requirements" | "tables" | "charts" | "annotations" | "console" | "kernel" |
|
|
167
|
+
operationOwner(method: string): "media" | "r" | "agent" | "files" | "skills" | "documents" | "requirements" | "tables" | "charts" | "annotations" | "console" | "kernel" | undefined;
|
|
168
168
|
operationDeclarations(): {
|
|
169
169
|
owner: string;
|
|
170
170
|
method: string;
|
package/dist/project-notes.js
CHANGED
|
@@ -21,6 +21,7 @@ export function notesInstructions(conversationId, options = {}) {
|
|
|
21
21
|
'- Data & method: one bullet for the data and one for each script, each linked, saying what it is and how it is used.',
|
|
22
22
|
'- Key results: one bullet per finding, each linking the result files it rests on; embed a key figure on its own line as .',
|
|
23
23
|
'- Files: right after you write a result, table, figure or script, and before your next command, add a bullet as - [path](path) — what it holds; correct it when that changes. Do not leave this to the end.',
|
|
24
|
+
'- Scripts and cells: above each top-level statement that first makes a value you report, or writes a file, add a comment `# means: …` with one short sentence saying what it is, in the language the person writes in, under 200 characters. Where one statement makes or writes several things, name the one the comment is for: `# means NAME: …`, with a value name or a file path. Comments inside a function, and changes to a value after it is made, need none. Rho shows these sentences beside the code, so a reader who does not read R or Python can follow the steps.',
|
|
24
25
|
'- Choices: when the analysis takes a choice that has a reasonable alternative (a test, a threshold, an exclusion, a model), go on with your choice and do not ask the person or wait. Where the alternative is cheap, compute it too. Write one bullet saying what you chose and what it gives, linking its results, with a nested bullet starting "Alternative:" that says what the other option gives, linking its results.',
|
|
25
26
|
'- To do: a task list (- [ ] open, - [x] done).',
|
|
26
27
|
'- Leave a subsection empty until you have something for it; do not write placeholders such as "to be filled".',
|
|
@@ -33,6 +34,7 @@ export function notesInstructions(conversationId, options = {}) {
|
|
|
33
34
|
'- What a cell defines stays for your next cells, so load data once and build on it. kernel.read shows the cells, including any the person ran, and the variables.',
|
|
34
35
|
'- To look at a value without adding a cell, call kernel.inspect with its language and name: it gives a page of a table, a model\'s fit and coefficients, or a list\'s parts, with the code that reaches each part.',
|
|
35
36
|
'- Keep the code your results rest on in script files as well, so they can be run again without the session.',
|
|
37
|
+
'- Before a multi-step analysis, read the Skill "rho.analysis-run" with skill.list and skill.read: it holds the practice that keeps a long analysis from losing work when a turn stops, written after five real reproductions ran here.',
|
|
36
38
|
] : []),
|
|
37
39
|
].join('\n');
|
|
38
40
|
}
|
package/dist/project-work.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Conversations } from './conversations.js';
|
|
2
2
|
import type { Project } from './state.js';
|
|
3
|
-
import type { observeSessionFiles, readAgentActivity, readExternalAcp } from '@rho-workspace/plugin-agent';
|
|
3
|
+
import type { observeSessionFiles, readAgentActivity, readExternalAcp, listExternalSessions, readExternalSession } from '@rho-workspace/plugin-agent';
|
|
4
4
|
import type { RhoOutput } from './contract.generated.js';
|
|
5
5
|
export declare function projectWork(input: {
|
|
6
6
|
project: Project;
|
|
@@ -24,4 +24,6 @@ export declare function projectWork(input: {
|
|
|
24
24
|
native: Awaited<ReturnType<typeof readAgentActivity>> | null;
|
|
25
25
|
external?: ReturnType<typeof readExternalAcp>;
|
|
26
26
|
inspect?: typeof observeSessionFiles;
|
|
27
|
+
observed?: ReturnType<typeof listExternalSessions>;
|
|
28
|
+
readObserved?: typeof readExternalSession;
|
|
27
29
|
}): Promise<RhoOutput<'project.work.read'>>;
|
package/dist/project-work.js
CHANGED
|
@@ -20,10 +20,23 @@ export async function projectWork(input) {
|
|
|
20
20
|
lastMessage: s.lastMessage, omittedMessageChars: s.omittedMessageChars, pendingPermissions: s.pendingPermissions,
|
|
21
21
|
operationIds: [], resourceRefs: [] }));
|
|
22
22
|
const refs = [...owned, ...external].flatMap(s => [...(s.observation?.tools ?? [])].reverse().flatMap(t => t.locations.map(l => ({ path: l.path, session: s.id, tool: t.id }))));
|
|
23
|
+
const observed = (input.observed?.sessions ?? []).slice(0, 8).map(s => {
|
|
24
|
+
let turns = [];
|
|
25
|
+
try {
|
|
26
|
+
turns = input.readObserved?.(input.project.root, { session: s.id, limit: 2 }).turns ?? [];
|
|
27
|
+
}
|
|
28
|
+
catch { /* Summary remains available when detail cannot be read. */ }
|
|
29
|
+
for (const turn of turns)
|
|
30
|
+
for (const tool of turn.tools)
|
|
31
|
+
for (const path of tool.paths)
|
|
32
|
+
refs.push({ path, session: s.id, tool: tool.id });
|
|
33
|
+
const resources = turns.flatMap(t => t.results.filter(r => r.id && r.version && r.projectId === input.project.id).map(r => ({ id: r.id, version: r.version })));
|
|
34
|
+
return { id: s.id, source: 'external-session', sessionId: s.sessionId, title: s.title, agent: s.producer, state: s.state, version: s.sourceCursor, observation: null, operationIds: [], resourceRefs: [...new Map(resources.map(r => [r.id + '@' + r.version, r])).values()] };
|
|
35
|
+
});
|
|
23
36
|
const inspected = input.inspect ? await input.inspect(input.project.root, refs) : { files: [], omitted: refs.length };
|
|
24
37
|
return { projectId: input.project.id, cursor: input.cursor, observedAt: new Date().toISOString(),
|
|
25
38
|
notes: { path: notesPath, ...(note ? { documentId: note.id, version: note.version, dirty: note.dirty } : {}) },
|
|
26
|
-
sessions: [...owned, ...external, ...native], files: inspected.files,
|
|
39
|
+
sessions: [...owned, ...observed, ...external, ...native], files: inspected.files,
|
|
27
40
|
native: { state: input.native ? 'available' : 'unavailable', message: input.native ? 'Retained native sources; input stays in their original window.' : 'Native activity is not available from the current Host. Reading this view does not start it.' },
|
|
28
|
-
omitted: { conversations: input.conversations.omitted, fileReferences: inspected.omitted, external: (input.external?.omitted ?? 0) + Math.max(0, externalSessions.length - external.length) } };
|
|
41
|
+
omitted: { conversations: input.conversations.omitted, fileReferences: inspected.omitted, external: (input.external?.omitted ?? 0) + (input.observed?.omitted ?? 0) + Math.max(0, (input.observed?.sessions.length ?? 0) - observed.length) + Math.max(0, externalSessions.length - external.length) } };
|
|
29
42
|
}
|
package/dist/protocol.d.ts
CHANGED
|
@@ -192,6 +192,13 @@ export declare const descriptions: {
|
|
|
192
192
|
'workspace.enhance': string;
|
|
193
193
|
'capability.index': string;
|
|
194
194
|
'capability.resolve': string;
|
|
195
|
+
'extension.list': string;
|
|
196
|
+
'extension.describe': string;
|
|
197
|
+
'extension.content': string;
|
|
198
|
+
'extension.call': string;
|
|
199
|
+
'extension.read': string;
|
|
200
|
+
'extension.install': string;
|
|
201
|
+
'extension.manage': string;
|
|
195
202
|
};
|
|
196
203
|
export declare const errorKinds: string[];
|
|
197
204
|
export declare const errorSchema: {
|
package/dist/protocol.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { extensionOperations, extensionResponses, extensionDescriptions } from './extension-contract.js';
|
|
1
2
|
import { evidenceSchema } from './evidence-capture.js';
|
|
2
3
|
import { ownerContracts } from './contracts/owners.generated.js';
|
|
3
4
|
import { enhancementSchemas } from './enhancement-contracts.js';
|
|
@@ -20,7 +21,9 @@ const array = (items) => ({ type: 'array', items });
|
|
|
20
21
|
const response = (properties, required = Object.keys(properties)) => ({ type: 'object', properties, required, additionalProperties: true });
|
|
21
22
|
const changeId = { type: 'string', pattern: '^[A-Za-z0-9._:@-]{1,128}$' };
|
|
22
23
|
const identity = changeId;
|
|
23
|
-
|
|
24
|
+
// 'acp' is a generic ACP agent: the operator names its command (--acp-command), so Rho
|
|
25
|
+
// supports any ACP v1 implementation without a per-agent adapter.
|
|
26
|
+
const agentBackend = { enum: ['claude-acp', 'codex-acp', 'acp'] };
|
|
24
27
|
const outsideAgent = { enum: ['claude-code', 'codex'] };
|
|
25
28
|
const addedTo = response({ agent: outsideAgent, name: text, scope: { enum: ['folder', 'user'] }, at: text });
|
|
26
29
|
const choiceText = { type: 'string', minLength: 1, maxLength: 512 }, choiceValue = { anyOf: [choiceText, { type: 'boolean' }] };
|
|
@@ -40,7 +43,7 @@ for (const owner of ['documents', 'files', 'r', 'requirements', 'tables', 'media
|
|
|
40
43
|
ownerOperations[method] = contract;
|
|
41
44
|
}
|
|
42
45
|
}
|
|
43
|
-
export const operations = { ...base.operations,
|
|
46
|
+
export const operations = { ...base.operations, ...extensionOperations,
|
|
44
47
|
'protocol.describe': obj({ ...project, method: text, cursor: { type: ['string', 'null'], maxLength: 128 }, limit: { type: 'integer', minimum: 1, maximum: 100 }, maxBytes: { type: 'integer', minimum: 1024, maximum: 65536 } }, []),
|
|
45
48
|
'project.pick': obj({}),
|
|
46
49
|
'project.source.pick': obj({}),
|
|
@@ -81,7 +84,7 @@ export const operations = { ...base.operations,
|
|
|
81
84
|
// The person's Agent and its settings (model, effort, mode…) among those the Agent offers.
|
|
82
85
|
'conversation.configure': obj({ ...project, conversationId: changeId, configId: choiceText, value: choiceValue }),
|
|
83
86
|
'conversation.settings.read': obj(project),
|
|
84
|
-
'conversation.settings.update': obj({ ...project, expectedVersion: integer, backend: { anyOf: [agentBackend, { type: 'null' }] }, choices: obj({ 'claude-acp': choices, 'codex-acp': choices }, []), describe: obj({ enabled: { type: 'boolean' } }, ['enabled']) }, ['projectId', 'expectedVersion']),
|
|
87
|
+
'conversation.settings.update': obj({ ...project, expectedVersion: integer, backend: { anyOf: [agentBackend, { type: 'null' }] }, choices: obj({ 'claude-acp': choices, 'codex-acp': choices, 'acp': choices }, []), describe: obj({ enabled: { type: 'boolean' } }, ['enabled']) }, ['projectId', 'expectedVersion']),
|
|
85
88
|
'conversation.settings.check': obj({ ...project, backend: agentBackend }),
|
|
86
89
|
// Claude Code or Codex running outside Rho, given this project and told how to start Rho's MCP server.
|
|
87
90
|
'session.connect': obj({ ...project, agent: outsideAgent })
|
|
@@ -201,8 +204,8 @@ const conversationSummary = response({ conversationId: text, title: text, client
|
|
|
201
204
|
const sessionObservation = ownerSchema('agent-session', 'sessionObservationSchema');
|
|
202
205
|
// What one Agent offered, from a check or a conversation's first session, and the person's choices.
|
|
203
206
|
const offered = response({ at: text, source: { enum: ['check', 'conversation'] }, adapter: { anyOf: [response({ name: text, version: text }, ['name']), { type: 'null' }] }, options: array(ownerSchema('agent-session', 'configOptionSchema')), omitted: integer });
|
|
204
|
-
const agentSettings = response({ version: integer, updatedAt: { anyOf: [text, { type: 'null' }] }, backend: { anyOf: [agentBackend, { type: 'null' }] }, serviceBackend: { enum: ['claude-acp', 'codex-acp', 'claude-cli'] },
|
|
205
|
-
choices: response({ 'claude-acp': choices, 'codex-acp': choices }, []), offered: response({ 'claude-acp': offered, 'codex-acp': offered }, []), checking: array(agentBackend),
|
|
207
|
+
const agentSettings = response({ version: integer, updatedAt: { anyOf: [text, { type: 'null' }] }, backend: { anyOf: [agentBackend, { type: 'null' }] }, serviceBackend: { enum: ['claude-acp', 'codex-acp', 'claude-cli', 'acp'] },
|
|
208
|
+
choices: response({ 'claude-acp': choices, 'codex-acp': choices, 'acp': choices }, []), offered: response({ 'claude-acp': offered, 'codex-acp': offered, 'acp': offered }, []), checking: array(agentBackend),
|
|
206
209
|
// Whether a model describes the files a message writes; the facts are read either way.
|
|
207
210
|
describe: response({ enabled: { type: 'boolean' } }) }, ['version', 'updatedAt', 'backend', 'serviceBackend', 'choices', 'offered', 'checking']);
|
|
208
211
|
// A tool step keeps its original identity, the Agent's bounded human title, its ACP
|
|
@@ -272,7 +275,7 @@ observationSnapshot.required = observationSnapshot.required.filter(key => key !=
|
|
|
272
275
|
const structuredComposition = contract.structuredCompositionSchema;
|
|
273
276
|
const composition = { anyOf: [contract.legacyCompositionSchema, structuredComposition] };
|
|
274
277
|
const taskMap = { ...contract.taskMapStateSchema, properties: { ...contract.taskMapStateSchema.properties, receipt: obj({ changeId: identity, requestDigest: digest, kind: { enum: ['declare', 'present', 'respond'] }, author: text, version: positive, at: { type: 'string', format: 'date-time' }, outcome: contract.taskMapReceiptField }, ['changeId', 'kind', 'author', 'version', 'at']) } };
|
|
275
|
-
export const responses = { ...base.responses, ...ownerResponses,
|
|
278
|
+
export const responses = { ...base.responses, ...ownerResponses, ...extensionResponses,
|
|
276
279
|
'project.work.read': projectWorkSchema(sessionObservation),
|
|
277
280
|
'project.open': { ...contract.projectRecordSchema, properties: { ...contract.projectRecordSchema.properties, host: contract.cliSchema }, required: [...contract.projectRecordSchema.required, 'host'] },
|
|
278
281
|
'project.pick': response({ cancelled: { type: 'boolean' }, project: { anyOf: [contract.projectSummarySchema, { type: 'null' }] } }),
|
|
@@ -372,6 +375,7 @@ export const responses = { ...base.responses, ...ownerResponses,
|
|
|
372
375
|
};
|
|
373
376
|
responses['session.grant'].properties.profile = operations['session.grant'].properties.profile;
|
|
374
377
|
export const descriptions = {
|
|
378
|
+
...extensionDescriptions,
|
|
375
379
|
'workspace.observe': 'Assigned presenter only: bounded layout/basis/owner summary/visibility projection. No feedback, full documents or native trace. Reading starts no model or renderer.',
|
|
376
380
|
'workspace.enhance': 'Assigned presenter only: conditional display emphasis/title/plain Agent note using exact current generation, witness and observation. Does not modify business resources, feedback or protection.',
|
|
377
381
|
'capability.index': 'Read a small role-narrowed index of currently authorized, enabled operations and immutable Skill/contract references.',
|
|
@@ -405,7 +409,7 @@ export const descriptions = {
|
|
|
405
409
|
'console.events': 'Who ran each Console command and when, newest first, for the timeline: the folder, how it ended and its first line. No output.',
|
|
406
410
|
'console.output': 'One bounded page of what a Console command printed. Output past the kept size is counted in a note, not silently dropped.',
|
|
407
411
|
'console.stop': 'Person at this machine only: ask a running Console command and the processes it started to stop; they are killed after a short grace period.',
|
|
408
|
-
'kernel.run': 'Run a cell of R or Python in the project\'s live session of that language, which the Agent and the person share: what one cell defines stays for the next. Starts the session when none is live, on this machine or at a place on one of the person\'s servers (place, or where kernel.places says that language runs next). The same changeId from the same caller returns the same cell and never runs it twice. waitMs waits for the cell to end.',
|
|
412
|
+
'kernel.run': 'Run a cell of R or Python in the project\'s live session of that language, which the Agent and the person share: what one cell defines stays for the next. Starts the session when none is live, on this machine or at a place on one of the person\'s servers (place, or where kernel.places says that language runs next). interpreter names the program a session on this machine starts with, in a folder of the project such as .venv/bin/python; the project keeps it for that language\'s later sessions, and each cell records the program and version that ran it. The same changeId from the same caller returns the same cell and never runs it twice. waitMs waits for the cell to end.',
|
|
409
413
|
'skills.list': 'The project\'s skills: how work is done here (the methods the person chose, the conventions they keep, the traps its work ran into), each a SKILL.md in .claude/skills that every Agent here reads, with what it is for and its newest change. Read before analysing.',
|
|
410
414
|
'skills.read': 'One project skill\'s text and its changes, newest first: who made each, why, from what (cells, conversations, files) and the lines it added and removed, and what changed outside Rho since.',
|
|
411
415
|
'skills.change': 'Record in a project skill when the person corrects a method or says how they work, or a failure\'s cause and fix are found: a new skill, a new text with a one-sentence reason and evidence, or its removal. Record how to work, never results. Made on the version read; the same changeId never writes twice.',
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { digest } from '@rho-workspace/plugin-contracts';
|
|
2
|
+
// The practice for checking a page's layout in a real browser, served as the Skill rho.screen-check.
|
|
3
|
+
// skills/rho/references/screen-check.md carries this text verbatim, and
|
|
4
|
+
// test/screen-check-skill.test.mjs fails when the two differ, so the text has one source.
|
|
5
|
+
const screenCheckContent = [
|
|
6
|
+
'Check how a page lays out in a real browser before you say it works.',
|
|
7
|
+
'',
|
|
8
|
+
'Run `rho-screen-check <url or page.html>`. It opens the page at each viewport (by default 1440x900, 1024x768, 768x1024 and 390x844), waits for it to settle, writes one screenshot per viewport and prints a JSON report. Options: `--viewport WxH` (repeatable), `--out DIR` (default ./screen-check), `--overlap SELECTOR` (report the visible boxes of that selector that overlap one another), `--full-page`, `--settle MS` (default 800), `--browser auto|chrome|msedge|chromium|PATH` (default auto: Chrome, then Edge, then Playwright\'s Chromium).',
|
|
9
|
+
'',
|
|
10
|
+
'Read the exit status first. 0: the check ran, and its findings are in the report. 1: an argument was wrong. 2: the check did not run; `error.kind`, `error.message` and `error.next` say why and what to do. Do what `next` says, then run it again.',
|
|
11
|
+
'',
|
|
12
|
+
'For each viewport, read: `horizontalOverflow` with `scrollWidth` against `clientWidth` (the page is wider than the window); `elementsPastEdgeUnclipped` (what crosses the right edge and no box keeps in: read this count first), then `elementsPastEdge` (the first 50, unclipped first; `clippedBy` names the box that scrolls or hides what is beyond its own width); `unnamedButtons`; `overlaps` for your selector; `pageErrors` and `consoleErrors`; `httpErrors` (each response that failed, with its status and address); `requestsOutsideTarget` (what the page loads from elsewhere).',
|
|
13
|
+
'',
|
|
14
|
+
'Then open each `screenshot` with the Read tool and say what you see. The report says what the page does, not whether a person can follow it; the screenshot and the flow answer that. Check the states a person reaches as well as the first screen: an empty state, an error, a long name or number, a narrow window, the screen after a step. Run the check again after each change.',
|
|
15
|
+
'',
|
|
16
|
+
'Pitfalls seen in real runs:',
|
|
17
|
+
'- A selector can match hidden elements. The report counts visible boxes only; your own probes must filter by visibility too.',
|
|
18
|
+
'- The same attribute can appear in two views at once, such as a script editor\'s flow and a session\'s Data flow. Open a workspace that shows only the view you check.',
|
|
19
|
+
'- At 390 px the sidebar collapses and project labels are hidden. Reach the label through the page\'s own controls before you look for it.',
|
|
20
|
+
'- Text cut short inside a box of fixed height, such as a label that ends mid-word, is not in the report. Only the screenshot shows it.',
|
|
21
|
+
'- Restarting Rho ends the live R sessions, and the page then shows "Rho closed. Values defined before this are gone." Say so when a check follows a restart.',
|
|
22
|
+
'- Check a copy of the project, not the person\'s own project. A check must not change what the person has.',
|
|
23
|
+
].join('\n');
|
|
24
|
+
export const screenCheckSkill = {
|
|
25
|
+
id: 'rho.screen-check',
|
|
26
|
+
version: '1.0',
|
|
27
|
+
content: screenCheckContent,
|
|
28
|
+
digest: digest(screenCheckContent),
|
|
29
|
+
intent: 'Check how a Rho screen or a local page lays out at phone and desktop widths, in a real browser, and read the result rather than assume it.',
|
|
30
|
+
failureRecipes: [
|
|
31
|
+
{ kind: 'browser_missing', message: 'No browser could be started.', next: 'Install Google Chrome or Microsoft Edge, or pass --browser with the path of an installed Chromium-based browser; then run the check again.' },
|
|
32
|
+
{ kind: 'unreachable', message: 'The page did not load.', next: 'Check the address, that the service is running or the file exists, and that the page opens in a browser; then run the check again.' },
|
|
33
|
+
{ kind: 'usage', message: 'An argument was not understood.', next: 'Run rho-screen-check --help and use one of the listed forms.' },
|
|
34
|
+
],
|
|
35
|
+
verify: {
|
|
36
|
+
command: 'npm run test:screen-check',
|
|
37
|
+
description: 'Runs the screen-check tests: the findings on fixture pages in a real browser, the JSON report and the exit codes, and this Skill text against the shipped reference.',
|
|
38
|
+
},
|
|
39
|
+
};
|
package/dist/server.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Extensions, extensionLimits } from './extensions.js';
|
|
1
2
|
import { evidenceExportLimits } from './evidence-export.js';
|
|
2
3
|
import * as http from 'node:http';
|
|
3
4
|
import { Plugins, type PluginConfig } from './plugins.js';
|
|
@@ -49,6 +50,7 @@ export declare const serviceLimits: {
|
|
|
49
50
|
export interface ServiceConfig extends Partial<typeof serviceLimits>, Partial<typeof requestLimits>, PluginConfig {
|
|
50
51
|
root: string;
|
|
51
52
|
stateDir: string;
|
|
53
|
+
extensions?: Partial<typeof extensionLimits>;
|
|
52
54
|
coreBinary?: string;
|
|
53
55
|
rscript: string;
|
|
54
56
|
python?: string;
|
|
@@ -70,6 +72,7 @@ export interface ServiceConfig extends Partial<typeof serviceLimits>, Partial<ty
|
|
|
70
72
|
claude?: string;
|
|
71
73
|
agentBackend?: ConversationConfig['backend'];
|
|
72
74
|
claudeAcp?: ConversationConfig['claudeAcp'];
|
|
75
|
+
acpCommand?: ConversationConfig['acpCommand'];
|
|
73
76
|
codex?: string;
|
|
74
77
|
codexAcp?: ConversationConfig['codexAcp'];
|
|
75
78
|
conversations?: Partial<typeof conversationLimits>;
|
|
@@ -92,6 +95,7 @@ export declare const layeredGrantLimits: {
|
|
|
92
95
|
};
|
|
93
96
|
export declare class RhoService {
|
|
94
97
|
config: ServiceConfig;
|
|
98
|
+
extensions: Extensions;
|
|
95
99
|
plugins: Plugins;
|
|
96
100
|
state: State;
|
|
97
101
|
bridge: CoreBridge;
|
|
@@ -160,12 +164,13 @@ export declare class RhoService {
|
|
|
160
164
|
private catalog;
|
|
161
165
|
private modelFacts;
|
|
162
166
|
start(): Promise<this>;
|
|
167
|
+
private followAddress;
|
|
163
168
|
agentConnection(projectId: string, externalSessionId: string, file: string, methods?: string[], pluginFilter?: string[], profile?: 'layered-business' | 'layered-presentation', who?: {
|
|
164
169
|
label?: string;
|
|
165
170
|
conversationId?: string;
|
|
166
171
|
}): Promise<{
|
|
167
172
|
apiVersion: "2.0";
|
|
168
|
-
pluginFilter?: ("media" | "r" | "agent" | "files" | "documents" | "requirements" | "tables" | "charts" | "annotations" | "console" | "kernel"
|
|
173
|
+
pluginFilter?: ("media" | "r" | "agent" | "files" | "skills" | "documents" | "requirements" | "tables" | "charts" | "annotations" | "console" | "kernel")[] | undefined;
|
|
169
174
|
profile?: "layered-business" | "layered-presentation" | undefined;
|
|
170
175
|
url: string;
|
|
171
176
|
token: string;
|