@rho-workspace/rho 0.5.4 → 0.5.6
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 +8 -0
- package/dist/agent-connect.js +15 -0
- package/dist/browser-access.js +3 -2
- package/dist/capabilities.d.ts +2 -2
- package/dist/capabilities.js +6 -1
- package/dist/cli.js +219 -176
- package/dist/contract.generated.d.ts +472 -4
- package/dist/contract.generated.js +1 -1
- package/dist/contracts/owners.generated.js +455 -6
- package/dist/conversations.d.ts +157 -4
- package/dist/conversations.js +69 -6
- 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/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-work.d.ts +3 -1
- package/dist/project-work.js +15 -2
- package/dist/protocol.d.ts +8 -0
- package/dist/protocol.js +16 -7
- package/dist/server.d.ts +5 -10
- package/dist/server.js +122 -12
- package/dist/web/.vite/manifest.json +67 -67
- package/dist/web/assets/{canvas-BXhC8RDZ.js → canvas-D8rDdfDz.js} +1 -1
- package/dist/web/assets/choices-D-YfnFP6.js +1 -0
- package/dist/web/assets/{console-Dbdo-5oO.js → console-Trqc0swD.js} +1 -1
- package/dist/web/assets/{dist-B2V0VDO0.js → dist-DZmszrjG.js} +2 -2
- package/dist/web/assets/dist-DpIHRk3B.js +1 -0
- package/dist/web/assets/{dist-D25Vn17i.js → dist-eMx6b8N1.js} +1 -1
- package/dist/web/assets/dist-pF902jHA.js +3 -0
- package/dist/web/assets/explore-in-BCHqjJ7B.js +1 -0
- package/dist/web/assets/graph-lENgfQNH.js +2 -0
- package/dist/web/assets/index-B3_OVy91.css +1 -0
- package/dist/web/assets/{index-BHQIaDsx.js → index-BpL_Kl_s.js} +87 -86
- package/dist/web/assets/{notes-meaning-DdPbtNzJ.js → notes-meaning-DcVGUBBY.js} +1 -1
- package/dist/web/assets/overview-CDnVKlOt.js +6 -0
- package/dist/web/assets/preview-BEC1E9MK.js +1 -0
- package/dist/web/assets/{review-CmWou4Iv.js → review-DYP0aCXb.js} +1 -1
- package/dist/web/assets/{skills-Dy7n3L9d.js → skills-1ec0Z-jx.js} +1 -1
- package/dist/web/assets/{skills-work-Cj0W6b-I.js → skills-work-DNexV4OJ.js} +1 -1
- package/dist/web/assets/{studio-process-QOY_n2_8.js → studio-process-EYQgikxq.js} +2 -2
- package/dist/web/assets/{timeline-events-DmX1BCh3.js → timeline-events-Chj2Gbx7.js} +1 -1
- package/dist/web/assets/{work-turns-Co0C71rJ.js → work-turns-CT9RVcWY.js} +1 -1
- package/dist/web/assets/workspace-COmCbGV3.js +5 -0
- package/dist/web/composition.json +65 -65
- 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 +26 -18
- package/docs/HEADLESS.md +38 -28
- package/docs/PLUGIN-AUTHORING.md +4 -0
- package/docs/THIRD-PARTY-PLUGINS.md +190 -0
- package/node_modules/@rho-workspace/plugin-agent/README.md +68 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/acp-command.d.ts +1 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/acp-command.js +9 -1
- 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 +10 -0
- 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/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 +20 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/external-session.d.ts +84 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/external-session.js +190 -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/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/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 +6 -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/package.json +5 -3
- package/protocol/index.json +93 -33
- package/protocol/operations/agent.sessions.list.json +146 -0
- package/protocol/operations/agent.sessions.read.json +315 -0
- package/protocol/operations/conversation.configure.json +29 -0
- package/protocol/operations/conversation.decide.json +29 -0
- package/protocol/operations/conversation.list.json +29 -0
- package/protocol/operations/conversation.permission.json +29 -0
- package/protocol/operations/conversation.read.json +29 -0
- package/protocol/operations/conversation.restore.json +29 -0
- package/protocol/operations/conversation.send.json +29 -0
- package/protocol/operations/conversation.settings.check.json +92 -0
- package/protocol/operations/conversation.settings.read.json +92 -0
- package/protocol/operations/conversation.settings.update.json +92 -0
- package/protocol/operations/conversation.start.json +46 -1
- package/protocol/operations/conversation.stop.json +29 -0
- package/protocol/operations/conversation.trash.json +29 -0
- 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/observation.snapshot.json +29 -0
- package/protocol/operations/project.work.read.json +3 -2
- package/protocol/operations/session.grant.json +9 -0
- package/protocol/operations/session.instructions.json +43 -0
- package/scripts/third-party-acceptance.mjs +77 -0
- package/vendor/composition.json +83 -83
- package/vendor/rho-workspace-plugin-agent-0.4.30.tgz +0 -0
- package/web/theme.css +12 -0
- package/dist/web/assets/choices-DU9kHlyQ.js +0 -1
- package/dist/web/assets/dist-BV3hWfn_.js +0 -3
- package/dist/web/assets/dist-CLNF2g-E.js +0 -1
- package/dist/web/assets/explore-in-8Q5ftt-E.js +0 -1
- package/dist/web/assets/graph-hS2kvHTI.js +0 -2
- package/dist/web/assets/index-Cj1_iqyK.css +0 -1
- package/dist/web/assets/overview-BV6ZO5TO.js +0 -6
- package/dist/web/assets/preview-n5lOOdjN.js +0 -1
- package/dist/web/assets/workspace-BKFefRfJ.js +0 -5
- package/vendor/rho-workspace-plugin-agent-0.4.28.tgz +0 -0
package/dist/server.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { Extensions } from './extensions.js';
|
|
2
|
+
import { extensionManagement } from './extension-contract.js';
|
|
1
3
|
import { EvidenceExporter, evidenceExportLimits } from './evidence-export.js';
|
|
2
|
-
import { Discovery } from './discovery.js';
|
|
4
|
+
import { Discovery, applicationEffects } from './discovery.js';
|
|
3
5
|
import * as http from 'node:http';
|
|
4
6
|
import * as fs from 'node:fs/promises';
|
|
5
7
|
import path from 'node:path';
|
|
@@ -17,10 +19,10 @@ import { Interactions } from './interactions.js';
|
|
|
17
19
|
import { TaskMap } from './task-map.js';
|
|
18
20
|
import { Capabilities } from './capabilities.js';
|
|
19
21
|
import { BrowserAccess, localBrowserId, localBrowserPrincipal } from './browser-access.js';
|
|
20
|
-
import { addToAgent, connectLimits, mcpCommand, mcpName, outsideLabel } from './agent-connect.js';
|
|
22
|
+
import { addToAgent, connectionInstructions, connectLimits, mcpCommand, mcpName, outsideLabel } from './agent-connect.js';
|
|
21
23
|
import { NativeFolderPicker, nativeFolderLimits } from './native-folders.js';
|
|
22
24
|
import { homedir } from 'node:os';
|
|
23
|
-
import { serveWeb, servePageFrame, pageFramePath, webRoot, installedWebEntries } from './web-assets.js';
|
|
25
|
+
import { serveWeb, servePageFrame, pageFramePath, extensionFramePath, webRoot, installedWebEntries } from './web-assets.js';
|
|
24
26
|
import { Presentation } from './presentation.js';
|
|
25
27
|
import { presentationSchemas } from './presentation-contracts.js';
|
|
26
28
|
import { isNativeTime } from './native-time.js';
|
|
@@ -178,6 +180,7 @@ function explainFailure(e) {
|
|
|
178
180
|
}
|
|
179
181
|
export class RhoService {
|
|
180
182
|
config;
|
|
183
|
+
extensions;
|
|
181
184
|
plugins;
|
|
182
185
|
state;
|
|
183
186
|
bridge;
|
|
@@ -377,6 +380,7 @@ export class RhoService {
|
|
|
377
380
|
if (typeof value === 'number')
|
|
378
381
|
requireThat(Number.isSafeInteger(value) && (key === 'port' ? value >= 0 && value <= 65535 : value > 0), 'invalid', 'Invalid service budget.', { field: key });
|
|
379
382
|
}
|
|
383
|
+
this.extensions = new Extensions(path.join(config.stateDir, 'plugins'), config.extensions);
|
|
380
384
|
this.plugins = new Plugins(config);
|
|
381
385
|
this.state = new State(config.root, config.stateDir);
|
|
382
386
|
this.bridge = new CoreBridge(config.coreBinary, config.rscript);
|
|
@@ -448,6 +452,7 @@ export class RhoService {
|
|
|
448
452
|
return [await writeClaudePlugin(path.join(this.state.directory, 'claude-plugins'), { name: 'rho', version: selectedPluginVersions.agent, description: 'Skills and hooks of the plugins selected in Rho.', ...declared })];
|
|
449
453
|
},
|
|
450
454
|
changed: async (project, conversationId) => { void this.serial(project.id, () => this.emit(project, 'conversation.changed', conversationId, localBrowserId)).catch(() => { }); },
|
|
455
|
+
nativeSession: async (project, producer, sessionId) => (await import('@rho-workspace/plugin-agent/native-sessions')).nativeSession(project.root, producer, sessionId),
|
|
451
456
|
// The person's own Claude Code when one is named, with no tools and in an empty folder of
|
|
452
457
|
// Rho's state, so it reads only what it is given and loads no project instructions. What
|
|
453
458
|
// a call cost comes from Claude Code when it knows the model's price, else from models.dev.
|
|
@@ -484,6 +489,7 @@ export class RhoService {
|
|
|
484
489
|
await this.plugins.load();
|
|
485
490
|
this.plugins.installUi(await installedWebEntries(this.config.webRoot), Object.keys(operations));
|
|
486
491
|
await this.state.init();
|
|
492
|
+
await this.extensions.init();
|
|
487
493
|
// A person who starts Rho on a fresh state sees one finished study beside their own work.
|
|
488
494
|
// It is copied into the projects folder once and is otherwise an ordinary project.
|
|
489
495
|
this.example = await seedExampleProject(this.state, { enabled: this.config.example === true }).catch(() => null);
|
|
@@ -558,18 +564,29 @@ export class RhoService {
|
|
|
558
564
|
const capabilities = new Capabilities(this.plugins, project);
|
|
559
565
|
const state = await capabilities.state();
|
|
560
566
|
// The shared project listing remains available alongside an Agent's native tools.
|
|
561
|
-
const available = Object.keys(operations).filter(m => !m.startsWith('agent.activity.') && !m.startsWith('session.') && !m.startsWith('conversation.') && (!m.startsWith('project.') || m === 'project.entries') && !m.startsWith('requirements.prepare') && !m.startsWith('workspace.restore') && !['task.routing.put', 'binding.activity.append', 'feedback.submit', 'view.observe', 'view.observations.read', 'task.map.respond', 'annotation.decide', 'evidence.export', 'evidence.preview', 'console.run', 'console.stop', 'kernel.stop'].includes(m));
|
|
567
|
+
const available = Object.keys(operations).filter(m => !extensionManagement.includes(m) && !m.startsWith('agent.activity.') && !m.startsWith('agent.sessions.') && !m.startsWith('session.') && !m.startsWith('conversation.') && (!m.startsWith('project.') || m === 'project.entries') && !m.startsWith('requirements.prepare') && !m.startsWith('workspace.restore') && !['task.routing.put', 'binding.activity.append', 'feedback.submit', 'view.observe', 'view.observations.read', 'task.map.respond', 'annotation.decide', 'evidence.export', 'evidence.preview', 'console.run', 'console.stop', 'kernel.stop'].includes(m));
|
|
562
568
|
const profileMethods = profile === 'layered-presentation' ? ['binding.open', 'capability.index', 'capability.resolve', 'workspace.observe', 'workspace.enhance'] : available.filter(m => !['workspace.observe', 'workspace.enhance', ...(profile ? ['skill.list', 'skill.read', 'protocol.describe'] : [])].includes(m));
|
|
563
569
|
const selected = methods ?? (profile === 'layered-presentation' ? profileMethods : (await Promise.all(profileMethods.map(async (method) => [method, await capabilities.isAvailable(method, state)]))).filter(([, enabled]) => enabled).map(([method]) => method));
|
|
564
570
|
requireThat(profile !== 'layered-presentation' || selected.every(m => profileMethods.includes(m)), 'scope', 'The selected role cannot receive broader methods.');
|
|
565
|
-
requireThat(selected.every(m => !!operations[m] && !m.startsWith('session.') && !m.startsWith('conversation.') && (!m.startsWith('project.') || m === 'project.entries') && !['task.routing.put', 'console.run', 'console.stop', 'kernel.stop'].includes(m)), 'invalid', 'Unknown or operator-only Agent capability.');
|
|
571
|
+
requireThat(selected.every(m => !extensionManagement.includes(m) && !!operations[m] && !m.startsWith('agent.sessions.') && !m.startsWith('session.') && !m.startsWith('conversation.') && (!m.startsWith('project.') || m === 'project.entries') && !['task.routing.put', 'console.run', 'console.stop', 'kernel.stop'].includes(m)), 'invalid', 'Unknown or operator-only Agent capability.');
|
|
566
572
|
requireThat(await Promise.all(selected.map(method => capabilities.isAvailable(method, state))).then(values => values.every(Boolean)), 'unavailable', 'A requested Agent operation has no selected provider.');
|
|
567
573
|
requireThat(!profile || new Set(['capability.index', 'capability.resolve', ...selected]).size <= layeredGrantLimits.maxMethods, 'limit', `Layered connection methods exceed the ${layeredGrantLimits.maxMethods}-method profile; choose an explicit narrower grant.`, { limit: 'maxMethods', maximum: layeredGrantLimits.maxMethods });
|
|
568
|
-
const token = randomBytes(32).toString('hex');
|
|
569
574
|
const id = 'agent:' + digest(projectId + ':' + externalSessionId).slice(0, 32);
|
|
575
|
+
const grantedMethods = [...new Set([...(profile ? ['capability.index', 'capability.resolve'] : ['protocol.describe', 'capability.list']), ...selected])];
|
|
576
|
+
const existing = this.state.principals.find(p => p.id === id);
|
|
577
|
+
const kept = await fs.readFile(file, 'utf8').then(text => JSON.parse(text), () => null);
|
|
578
|
+
// Repeating the same setup must not disconnect a client already using its grant.
|
|
579
|
+
// Changed scope, expired access or a stale address still requires a fresh credential.
|
|
580
|
+
if (existing && !(existing.expiresAt && Date.parse(existing.expiresAt) <= Date.now())
|
|
581
|
+
&& kept?.url === this.url && kept.projectId === projectId && kept.externalSessionId === externalSessionId
|
|
582
|
+
&& typeof kept.token === 'string' && digest(kept.token) === existing.tokenHash
|
|
583
|
+
&& canonical([...existing.methods].sort()) === canonical([...grantedMethods].sort())
|
|
584
|
+
&& kept.profile === profile && canonical(existing.pluginFilter ?? []) === canonical(pluginFilter ?? []))
|
|
585
|
+
return kept;
|
|
586
|
+
const token = randomBytes(32).toString('hex');
|
|
570
587
|
this.state.principals = this.state.principals.filter(p => p.id !== id);
|
|
571
588
|
requireThat(!pluginFilter || pluginFilter.every(id => this.plugins.isKnown(id)), 'invalid', 'Unknown MCP plugin filter.');
|
|
572
|
-
await this.state.addPrincipal({ id, tokenHash: digest(token), projectId, label: who.label ?? externalSessionId, ...(who.conversationId ? { conversationId: who.conversationId } : {}), methods:
|
|
589
|
+
await this.state.addPrincipal({ id, tokenHash: digest(token), projectId, label: who.label ?? externalSessionId, ...(who.conversationId ? { conversationId: who.conversationId } : {}), methods: grantedMethods, ...(profile ? { profile } : {}), ...(pluginFilter ? { pluginFilter } : {}) });
|
|
573
590
|
const connection = { url: this.url, token, projectId, externalSessionId, methods: [...new Set([...(profile ? ['capability.index', 'capability.resolve'] : []), ...selected])], ...(profile ? { profile } : {}), ...(pluginFilter ? { pluginFilter } : {}), apiVersion: '2.0' };
|
|
574
591
|
await atomicJson(file, connection);
|
|
575
592
|
return connection;
|
|
@@ -656,8 +673,8 @@ export class RhoService {
|
|
|
656
673
|
}
|
|
657
674
|
if (!url.pathname.startsWith('/api/')) {
|
|
658
675
|
requireThat((req.method === 'GET' || req.method === 'HEAD') && !url.search, 'not_found', 'Use the same-origin browser entry without query credentials.');
|
|
659
|
-
if (url.pathname === pageFramePath) {
|
|
660
|
-
servePageFrame(res, req.method === 'HEAD');
|
|
676
|
+
if (url.pathname === pageFramePath || url.pathname === extensionFramePath) {
|
|
677
|
+
servePageFrame(res, req.method === 'HEAD', url.pathname === extensionFramePath);
|
|
661
678
|
return;
|
|
662
679
|
}
|
|
663
680
|
await serveWeb(url.pathname, res, this.config.webRoot, req.method === 'HEAD');
|
|
@@ -688,7 +705,7 @@ export class RhoService {
|
|
|
688
705
|
requireThat(read.ok, read.ok ? 'invalid' : read.kind, read.ok ? '' : (read.problems[0]?.fix ? `Request does not match the versioned schema: ${read.problems[0].fix}` : 'Request does not match the versioned schema.'), read.ok ? {} : { problems: read.problems, remedy: 'Fix the named fields and resend the same request identity.' });
|
|
689
706
|
const request = read.request, contractRef = typeof req.headers['x-rho-contract-ref'] === 'string' ? req.headers['x-rho-contract-ref'] : undefined;
|
|
690
707
|
let value;
|
|
691
|
-
if (body.projectId && method.startsWith('kernel.')) {
|
|
708
|
+
if (body.projectId && (method.startsWith('kernel.') || method === 'extension.call')) {
|
|
692
709
|
// A cell may run for minutes and a run may wait for it. The live sessions keep their own
|
|
693
710
|
// order, so waiting holds no other request of the project, an interrupt among them.
|
|
694
711
|
const projectId = body.projectId;
|
|
@@ -780,6 +797,32 @@ export class RhoService {
|
|
|
780
797
|
// What the project's Agents did, for the person's screen:
|
|
781
798
|
// only principals whose grant names this project, only the fields the activity record
|
|
782
799
|
// keeps. A grant is the scope; an Agent need not have opened a binding.
|
|
800
|
+
// Every Agent session in the project folder, wherever it was started: Harness conversations Rho
|
|
801
|
+
// observes and the sessions Claude Code and Codex keep in their own files. Each names the Agent
|
|
802
|
+
// Rho continues it with and the Rho conversation that already continues it. Reads files only.
|
|
803
|
+
async agentSessions(p) {
|
|
804
|
+
const agent = this.plugins.optional('agent');
|
|
805
|
+
const external = agent ? agent.listExternalSessions(p.root) : { sessions: [], omitted: 0 };
|
|
806
|
+
const native = (await import('@rho-workspace/plugin-agent/native-sessions')).listNativeSessions(p.root);
|
|
807
|
+
const conversations = [...await this.conversations.list(p, {}), ...await this.conversations.list(p, { trashed: true })];
|
|
808
|
+
const bySession = new Map(conversations.filter(c => c.sessionId).map(c => [c.sessionId, c]));
|
|
809
|
+
const sessions = [...external.sessions, ...native.sessions].flatMap(s => {
|
|
810
|
+
const conversation = bySession.get(s.sessionId);
|
|
811
|
+
if (conversation?.trashedAt)
|
|
812
|
+
return [];
|
|
813
|
+
const continueWith = s.producer === 'claude-code' ? 'claude-acp' : s.producer === 'codex' ? 'codex-acp' : s.producer === 'dsh' && this.config.acpCommand ? 'acp' : null;
|
|
814
|
+
// Harness reports a turn in progress, not whether a window holds the session idle; a turn
|
|
815
|
+
// Rho itself is running is Rho's.
|
|
816
|
+
const open = s.producer === 'dsh' && s.state === 'running' && conversation?.state !== 'running' ? { where: 'DeepSeek Harness' } : s.open;
|
|
817
|
+
return [{ ...s, continueWith, ...(open !== undefined ? { open } : {}), ...(conversation ? { conversationId: conversation.conversationId } : {}) }];
|
|
818
|
+
});
|
|
819
|
+
// A session held only by Rho's own connection is not open elsewhere.
|
|
820
|
+
for (const s of sessions)
|
|
821
|
+
if (s.open && s.conversationId && await this.conversations.owns(p, s.conversationId, s.open.pid))
|
|
822
|
+
s.open = null;
|
|
823
|
+
sessions.sort((a, b) => b.lastAt.localeCompare(a.lastAt));
|
|
824
|
+
return { sessions: sessions.slice(0, 128), omitted: external.omitted + native.omitted + Math.max(0, sessions.length - 128) };
|
|
825
|
+
}
|
|
783
826
|
async projectActivity(p) {
|
|
784
827
|
const agent = this.plugins.project(p.root, p.id).agent;
|
|
785
828
|
if (!agent)
|
|
@@ -862,6 +905,14 @@ export class RhoService {
|
|
|
862
905
|
requireThat(this.state.principals.some(current => current.id === principal.id && current.tokenHash === principal.tokenHash && current.methods.includes(method) && (!current.expiresAt || Date.parse(current.expiresAt) > Date.now())), 'unauthorized', 'Session authorization expired or was revoked before this operation.');
|
|
863
906
|
if (method === 'protocol.describe')
|
|
864
907
|
return describeProtocol(protocol, principal.methods, b);
|
|
908
|
+
if (extensionManagement.includes(method)) {
|
|
909
|
+
requireThat(principal.id === 'operator' || principal.id === localBrowserId, 'scope', 'Plugin installation and management belong to the person at this machine.');
|
|
910
|
+
return method === 'extension.install' ? this.extensions.install(b.source, b.replace, b.expectedDigest) : this.extensions.manage(b.pluginId, b.expectedDigest, b.action);
|
|
911
|
+
}
|
|
912
|
+
if (method === 'extension.list' && !b.projectId) {
|
|
913
|
+
requireThat(principal.id === 'operator' || principal.id === localBrowserId, 'scope', 'A project-scoped caller must supply its project.');
|
|
914
|
+
return this.extensions.list();
|
|
915
|
+
}
|
|
865
916
|
// A dry run of any operation body: the same schema the server enforces, with the
|
|
866
917
|
// edit each problem needs. Nothing is executed and no project is touched.
|
|
867
918
|
if (method === 'protocol.validate') {
|
|
@@ -936,6 +987,32 @@ export class RhoService {
|
|
|
936
987
|
const workspace = new Workspace(p, owners, this.config.workspace, this.config.interactions);
|
|
937
988
|
const interactions = new Interactions(p, owners, this.config.interactions);
|
|
938
989
|
const routing = new TaskRouting(p, this.config.capabilityLimits?.maxReceipts, this.config.maxRetainedMetadataBytes);
|
|
990
|
+
if (method.startsWith('extension.')) {
|
|
991
|
+
if (contractRef) {
|
|
992
|
+
const reader = new Discovery(this.plugins, p, principal, await routing.read(), await readJson(path.join(await this.dataDir(p), 'bindings.json'), []));
|
|
993
|
+
await reader.assertContract(method, contractRef);
|
|
994
|
+
}
|
|
995
|
+
if (method === 'extension.list')
|
|
996
|
+
return this.extensions.list();
|
|
997
|
+
if (method === 'extension.describe')
|
|
998
|
+
return this.extensions.describe(b.pluginId);
|
|
999
|
+
if (method === 'extension.content')
|
|
1000
|
+
return this.extensions.content(b.pluginId, b.expectedDigest, b.kind, b.entryId);
|
|
1001
|
+
if (method === 'extension.read')
|
|
1002
|
+
return this.extensions.read(b.invocationId, principal.id, p.id);
|
|
1003
|
+
if (method === 'extension.call')
|
|
1004
|
+
return this.extensions.call(b, principal.id, p.root, async (target, body, effect) => {
|
|
1005
|
+
requireThat(principal.methods.includes(target), 'scope', 'The caller has not been granted this Rho method.');
|
|
1006
|
+
requireThat(!body?.projectId || body.projectId === p.id, 'scope', 'A plugin cannot delegate into another project.');
|
|
1007
|
+
const request = readOperation(target, { ...body, projectId: p.id });
|
|
1008
|
+
requireThat(request.ok, 'invalid', 'Plugin delegated an invalid Rho request.');
|
|
1009
|
+
const capabilities = new Capabilities(this.plugins, p);
|
|
1010
|
+
const status = (await capabilities.operationStatus(principal, await capabilities.state())).find(op => op.method === target);
|
|
1011
|
+
requireThat(effect !== 'read' || (status?.effect ?? applicationEffects[target]) === 'read', 'scope', 'A read operation cannot delegate a mutating Rho method.');
|
|
1012
|
+
const run = () => this.dispatch(request.request, principal);
|
|
1013
|
+
return target.startsWith('kernel.') ? run() : this.serial(p.id, run);
|
|
1014
|
+
});
|
|
1015
|
+
}
|
|
939
1016
|
// A person's own view of the folder they selected. The tab is confined to this one
|
|
940
1017
|
// project, so it may list that folder and open a text file from it; registering
|
|
941
1018
|
// resources and execution stay Agent/operator work.
|
|
@@ -1117,10 +1194,15 @@ export class RhoService {
|
|
|
1117
1194
|
await this.emit(p, 'composition.changed', b.compositionId);
|
|
1118
1195
|
return { document, viewId, composition };
|
|
1119
1196
|
}
|
|
1197
|
+
if (method === 'session.instructions') {
|
|
1198
|
+
requireThat(principal.id === localBrowserId || principal.id === 'operator', 'unauthorized', 'Only the person at this machine can read Agent setup instructions.');
|
|
1199
|
+
return connectionInstructions(p, this.state.directory);
|
|
1200
|
+
}
|
|
1120
1201
|
if (method === 'session.grant') {
|
|
1121
1202
|
requireThat(principal.id === 'operator', 'unauthorized', 'Only the local operator may provision a project-scoped session.');
|
|
1122
1203
|
const file = path.join(this.state.directory, 'agent-' + digest(p.id + ':' + b.externalSessionId) + '.json');
|
|
1123
1204
|
const connection = await this.agentConnection(p.id, b.externalSessionId, file, b.methods, undefined, b.profile);
|
|
1205
|
+
await this.emit(p, 'activity.changed', method);
|
|
1124
1206
|
return { profile: connection.profile, connectionFile: file, projectId: p.id, methods: connection.methods, transport: 'stdio-mcp', externalSessionId: b.externalSessionId };
|
|
1125
1207
|
}
|
|
1126
1208
|
// The person's own Claude Code or Codex, outside Rho: the same grant the operator gives, kept
|
|
@@ -1150,6 +1232,18 @@ export class RhoService {
|
|
|
1150
1232
|
}
|
|
1151
1233
|
// The person at this machine talks to a conversation Rho started; Agents and narrower links
|
|
1152
1234
|
// cannot start one, and an Agent started this way cannot start another.
|
|
1235
|
+
if (method.startsWith('agent.sessions.')) {
|
|
1236
|
+
requireThat(principal.id === localBrowserId, 'unauthorized', 'Agent session history belongs to the person at this machine.');
|
|
1237
|
+
if (method === 'agent.sessions.list')
|
|
1238
|
+
return this.agentSessions(p);
|
|
1239
|
+
const listed = (await this.agentSessions(p)).sessions.find(s => s.id === b.session);
|
|
1240
|
+
requireThat(listed, 'not_found', 'That Agent session is not in this project.');
|
|
1241
|
+
const read = listed.producer === 'claude-code' || listed.producer === 'codex'
|
|
1242
|
+
? await (await import('@rho-workspace/plugin-agent/native-sessions')).readNativeSession(p.root, b)
|
|
1243
|
+
: this.plugins.need('agent').readExternalSession(p.root, b);
|
|
1244
|
+
requireThat(read, 'not_found', 'That Agent session is no longer in this project.');
|
|
1245
|
+
return { ...read, session: { ...read.session, ...listed } };
|
|
1246
|
+
}
|
|
1153
1247
|
if (method === 'project.work.read') {
|
|
1154
1248
|
requireThat(principal.id === localBrowserId, 'scope', 'Project work is available to the person at this machine.');
|
|
1155
1249
|
const agent = (await new Capabilities(this.plugins, p).state()).enabled.includes('agent') ? this.plugins.optional('agent') : null;
|
|
@@ -1166,7 +1260,7 @@ export class RhoService {
|
|
|
1166
1260
|
}
|
|
1167
1261
|
return projectWork({ project: p, cursor: (await this.events(p)).cursor, conversations: await this.conversations.work(p, b.limit),
|
|
1168
1262
|
documents: await owners.documentSummaries(), activity: (await this.projectActivity(p)).entries,
|
|
1169
|
-
native, external: agent?.readExternalAcp(p.root), inspect: agent?.observeSessionFiles });
|
|
1263
|
+
native, external: agent?.readExternalAcp(p.root), observed: agent?.listExternalSessions(p.root), readObserved: agent?.readExternalSession, inspect: agent?.observeSessionFiles });
|
|
1170
1264
|
}
|
|
1171
1265
|
if (method.startsWith('conversation.')) {
|
|
1172
1266
|
requireThat(principal.id === localBrowserId, 'unauthorized', 'Conversations started in Rho belong to the person at this machine. Open Rho in a browser on this machine.');
|
|
@@ -1189,10 +1283,25 @@ export class RhoService {
|
|
|
1189
1283
|
if (method === 'conversation.settings.read')
|
|
1190
1284
|
return this.conversations.settings();
|
|
1191
1285
|
this.plugins.need('agent');
|
|
1286
|
+
if (method === 'conversation.start' && b.continue) {
|
|
1287
|
+
const listed = (await this.agentSessions(p)).sessions.find(s => s.id === b.continue.session);
|
|
1288
|
+
requireThat(listed, 'not_found', 'That Agent session is not in this project. Nothing was sent.');
|
|
1289
|
+
requireThat(listed.continueWith, 'condition', listed.producer === 'dsh'
|
|
1290
|
+
? 'Rho continues DeepSeek Harness sessions through Harness\'s ACP command. Start Rho with --agent-backend acp --acp-command \'["dsh","acp"]\', or continue in Harness. Nothing was sent.'
|
|
1291
|
+
: 'Rho cannot continue this Agent\'s sessions. Nothing was sent.');
|
|
1292
|
+
requireThat(!listed.conversationId, 'conflict', 'This session already continues as a conversation here. Open it to send your message.');
|
|
1293
|
+
requireThat(!b.continue.copy || listed.producer !== 'dsh', 'condition', 'DeepSeek Harness cannot copy a session. Continue it in place once it is not answering. Nothing was sent.');
|
|
1294
|
+
requireThat(!listed.open || listed.producer !== 'dsh', 'condition', 'DeepSeek Harness is answering in this session now. Continue it once that turn ends. Nothing was sent.', { heldBy: 'DeepSeek Harness' });
|
|
1295
|
+
return this.conversations.start(p, principal.id, { ...b, continue: { producer: listed.producer, sessionId: listed.sessionId, title: listed.title, where: listed.where ?? (listed.producer === 'dsh' ? 'DeepSeek Harness' : 'another window'), copy: !!b.continue.copy, backend: listed.continueWith } });
|
|
1296
|
+
}
|
|
1192
1297
|
if (method === 'conversation.start')
|
|
1193
1298
|
return this.conversations.start(p, principal.id, b);
|
|
1194
|
-
if (method === 'conversation.send')
|
|
1299
|
+
if (method === 'conversation.send') {
|
|
1300
|
+
// A Harness session reports its own turns through its adapter; Rho does not write into one it is answering.
|
|
1301
|
+
const listed = (await this.agentSessions(p)).sessions.find(s => s.conversationId === b.conversationId && s.producer === 'dsh');
|
|
1302
|
+
requireThat(!listed?.open, 'condition', 'DeepSeek Harness is answering in this session now. Send once that turn ends. Nothing was sent.', { heldBy: 'DeepSeek Harness' });
|
|
1195
1303
|
return this.conversations.send(p, principal.id, b);
|
|
1304
|
+
}
|
|
1196
1305
|
if (method === 'conversation.configure')
|
|
1197
1306
|
return this.conversations.configure(p, principal.id, b);
|
|
1198
1307
|
if (method === 'conversation.settings.update')
|
|
@@ -1715,6 +1824,7 @@ export class RhoService {
|
|
|
1715
1824
|
return this.state.principals.some(p => p.id === id && p.tokenHash === tokenHash && p.methods.includes('observation.snapshot') && (!p.expiresAt || Date.parse(p.expiresAt) > Date.now()));
|
|
1716
1825
|
}
|
|
1717
1826
|
async close() {
|
|
1827
|
+
this.extensions.close();
|
|
1718
1828
|
this.closing = true;
|
|
1719
1829
|
this.folderPicker.close();
|
|
1720
1830
|
for (const s of this.subscribers)
|
|
@@ -253,7 +253,7 @@
|
|
|
253
253
|
]
|
|
254
254
|
},
|
|
255
255
|
"../node_modules/@codemirror/lang-markdown/dist/index.js": {
|
|
256
|
-
"file": "assets/dist-
|
|
256
|
+
"file": "assets/dist-DZmszrjG.js",
|
|
257
257
|
"name": "dist",
|
|
258
258
|
"src": "../node_modules/@codemirror/lang-markdown/dist/index.js",
|
|
259
259
|
"isDynamicEntry": true,
|
|
@@ -261,22 +261,22 @@
|
|
|
261
261
|
"index.html",
|
|
262
262
|
"_dist-DCtcCJPs.js",
|
|
263
263
|
"../node_modules/@codemirror/language/dist/index.js",
|
|
264
|
-
"_dist-
|
|
264
|
+
"_dist-DpIHRk3B.js"
|
|
265
265
|
]
|
|
266
266
|
},
|
|
267
267
|
"../node_modules/@codemirror/lang-python/dist/index.js": {
|
|
268
|
-
"file": "assets/dist-
|
|
268
|
+
"file": "assets/dist-eMx6b8N1.js",
|
|
269
269
|
"name": "dist",
|
|
270
270
|
"src": "../node_modules/@codemirror/lang-python/dist/index.js",
|
|
271
271
|
"isDynamicEntry": true,
|
|
272
272
|
"imports": [
|
|
273
273
|
"_dist-DCtcCJPs.js",
|
|
274
274
|
"../node_modules/@codemirror/language/dist/index.js",
|
|
275
|
-
"_dist-
|
|
275
|
+
"_dist-DpIHRk3B.js"
|
|
276
276
|
]
|
|
277
277
|
},
|
|
278
278
|
"../node_modules/@codemirror/language/dist/index.js": {
|
|
279
|
-
"file": "assets/dist-
|
|
279
|
+
"file": "assets/dist-pF902jHA.js",
|
|
280
280
|
"name": "dist",
|
|
281
281
|
"src": "../node_modules/@codemirror/language/dist/index.js",
|
|
282
282
|
"isDynamicEntry": true,
|
|
@@ -295,8 +295,8 @@
|
|
|
295
295
|
"file": "assets/answer-board-CBkGbSLD.js",
|
|
296
296
|
"name": "answer-board"
|
|
297
297
|
},
|
|
298
|
-
"_canvas-
|
|
299
|
-
"file": "assets/canvas-
|
|
298
|
+
"_canvas-D8rDdfDz.js": {
|
|
299
|
+
"file": "assets/canvas-D8rDdfDz.js",
|
|
300
300
|
"name": "canvas",
|
|
301
301
|
"imports": [
|
|
302
302
|
"_rolldown-runtime-XKyaHtl9.js",
|
|
@@ -304,64 +304,64 @@
|
|
|
304
304
|
"_home-CCbP6kS-.js"
|
|
305
305
|
]
|
|
306
306
|
},
|
|
307
|
-
"_choices-
|
|
308
|
-
"file": "assets/choices-
|
|
309
|
-
"src": "_choices-DLah50GC.css"
|
|
310
|
-
},
|
|
311
|
-
"_choices-DU9kHlyQ.js": {
|
|
312
|
-
"file": "assets/choices-DU9kHlyQ.js",
|
|
307
|
+
"_choices-D-YfnFP6.js": {
|
|
308
|
+
"file": "assets/choices-D-YfnFP6.js",
|
|
313
309
|
"name": "choices",
|
|
314
310
|
"imports": [
|
|
315
311
|
"_rolldown-runtime-XKyaHtl9.js",
|
|
316
312
|
"_react-Dss-ouuy.js",
|
|
317
313
|
"_markdown-0ngRuTpW.js",
|
|
318
|
-
"_canvas-
|
|
314
|
+
"_canvas-D8rDdfDz.js",
|
|
319
315
|
"index.html",
|
|
320
|
-
"_notes-meaning-
|
|
316
|
+
"_notes-meaning-DcVGUBBY.js"
|
|
321
317
|
],
|
|
322
318
|
"css": [
|
|
323
319
|
"assets/choices-DLah50GC.css"
|
|
324
320
|
]
|
|
325
321
|
},
|
|
322
|
+
"_choices-DLah50GC.css": {
|
|
323
|
+
"file": "assets/choices-DLah50GC.css",
|
|
324
|
+
"src": "_choices-DLah50GC.css"
|
|
325
|
+
},
|
|
326
326
|
"_console-By4Mvn1y.css": {
|
|
327
327
|
"file": "assets/console-By4Mvn1y.css",
|
|
328
328
|
"src": "_console-By4Mvn1y.css"
|
|
329
329
|
},
|
|
330
|
-
"_console-
|
|
331
|
-
"file": "assets/console-
|
|
330
|
+
"_console-Trqc0swD.js": {
|
|
331
|
+
"file": "assets/console-Trqc0swD.js",
|
|
332
332
|
"name": "console",
|
|
333
333
|
"imports": [
|
|
334
334
|
"_rolldown-runtime-XKyaHtl9.js",
|
|
335
335
|
"_react-Dss-ouuy.js",
|
|
336
336
|
"_home-CCbP6kS-.js",
|
|
337
337
|
"_markdown-0ngRuTpW.js",
|
|
338
|
-
"_canvas-
|
|
338
|
+
"_canvas-D8rDdfDz.js",
|
|
339
339
|
"index.html",
|
|
340
340
|
"_facts-BMO6V3-3.js",
|
|
341
|
-
"_work-turns-
|
|
341
|
+
"_work-turns-CT9RVcWY.js"
|
|
342
342
|
],
|
|
343
343
|
"css": [
|
|
344
344
|
"assets/console-By4Mvn1y.css"
|
|
345
345
|
]
|
|
346
346
|
},
|
|
347
|
-
"_dist-
|
|
348
|
-
"file": "assets/dist-
|
|
347
|
+
"_dist-DCtcCJPs.js": {
|
|
348
|
+
"file": "assets/dist-DCtcCJPs.js",
|
|
349
349
|
"name": "dist",
|
|
350
350
|
"imports": [
|
|
351
|
-
"
|
|
352
|
-
"_dist-DCtcCJPs.js",
|
|
353
|
-
"../node_modules/@codemirror/language/dist/index.js"
|
|
351
|
+
"_rolldown-runtime-XKyaHtl9.js"
|
|
354
352
|
]
|
|
355
353
|
},
|
|
356
|
-
"_dist-
|
|
357
|
-
"file": "assets/dist-
|
|
354
|
+
"_dist-DpIHRk3B.js": {
|
|
355
|
+
"file": "assets/dist-DpIHRk3B.js",
|
|
358
356
|
"name": "dist",
|
|
359
357
|
"imports": [
|
|
360
|
-
"
|
|
358
|
+
"index.html",
|
|
359
|
+
"_dist-DCtcCJPs.js",
|
|
360
|
+
"../node_modules/@codemirror/language/dist/index.js"
|
|
361
361
|
]
|
|
362
362
|
},
|
|
363
|
-
"_explore-in-
|
|
364
|
-
"file": "assets/explore-in-
|
|
363
|
+
"_explore-in-BCHqjJ7B.js": {
|
|
364
|
+
"file": "assets/explore-in-BCHqjJ7B.js",
|
|
365
365
|
"name": "explore-in",
|
|
366
366
|
"imports": [
|
|
367
367
|
"_react-Dss-ouuy.js",
|
|
@@ -402,8 +402,8 @@
|
|
|
402
402
|
"_react-Dss-ouuy.js"
|
|
403
403
|
]
|
|
404
404
|
},
|
|
405
|
-
"_notes-meaning-
|
|
406
|
-
"file": "assets/notes-meaning-
|
|
405
|
+
"_notes-meaning-DcVGUBBY.js": {
|
|
406
|
+
"file": "assets/notes-meaning-DcVGUBBY.js",
|
|
407
407
|
"name": "notes-meaning",
|
|
408
408
|
"imports": [
|
|
409
409
|
"index.html"
|
|
@@ -420,8 +420,8 @@
|
|
|
420
420
|
"file": "assets/rolldown-runtime-XKyaHtl9.js",
|
|
421
421
|
"name": "rolldown-runtime"
|
|
422
422
|
},
|
|
423
|
-
"_skills-work-
|
|
424
|
-
"file": "assets/skills-work-
|
|
423
|
+
"_skills-work-DNexV4OJ.js": {
|
|
424
|
+
"file": "assets/skills-work-DNexV4OJ.js",
|
|
425
425
|
"name": "skills-work",
|
|
426
426
|
"imports": [
|
|
427
427
|
"_rolldown-runtime-XKyaHtl9.js",
|
|
@@ -439,8 +439,8 @@
|
|
|
439
439
|
"_react-Dss-ouuy.js"
|
|
440
440
|
]
|
|
441
441
|
},
|
|
442
|
-
"_timeline-events-
|
|
443
|
-
"file": "assets/timeline-events-
|
|
442
|
+
"_timeline-events-Chj2Gbx7.js": {
|
|
443
|
+
"file": "assets/timeline-events-Chj2Gbx7.js",
|
|
444
444
|
"name": "timeline-events",
|
|
445
445
|
"imports": [
|
|
446
446
|
"_rolldown-runtime-XKyaHtl9.js",
|
|
@@ -448,8 +448,8 @@
|
|
|
448
448
|
"index.html"
|
|
449
449
|
]
|
|
450
450
|
},
|
|
451
|
-
"_work-turns-
|
|
452
|
-
"file": "assets/work-turns-
|
|
451
|
+
"_work-turns-CT9RVcWY.js": {
|
|
452
|
+
"file": "assets/work-turns-CT9RVcWY.js",
|
|
453
453
|
"name": "work-turns",
|
|
454
454
|
"imports": [
|
|
455
455
|
"_rolldown-runtime-XKyaHtl9.js",
|
|
@@ -458,7 +458,7 @@
|
|
|
458
458
|
]
|
|
459
459
|
},
|
|
460
460
|
"graph.tsx": {
|
|
461
|
-
"file": "assets/graph-
|
|
461
|
+
"file": "assets/graph-lENgfQNH.js",
|
|
462
462
|
"name": "graph",
|
|
463
463
|
"src": "graph.tsx",
|
|
464
464
|
"isDynamicEntry": true,
|
|
@@ -466,19 +466,19 @@
|
|
|
466
466
|
"_rolldown-runtime-XKyaHtl9.js",
|
|
467
467
|
"_react-Dss-ouuy.js",
|
|
468
468
|
"_markdown-0ngRuTpW.js",
|
|
469
|
-
"_canvas-
|
|
469
|
+
"_canvas-D8rDdfDz.js",
|
|
470
470
|
"index.html",
|
|
471
|
-
"_work-turns-
|
|
471
|
+
"_work-turns-CT9RVcWY.js",
|
|
472
472
|
"_snapshot-CAxBYPvV.js",
|
|
473
|
-
"_timeline-events-
|
|
474
|
-
"_choices-
|
|
473
|
+
"_timeline-events-Chj2Gbx7.js",
|
|
474
|
+
"_choices-D-YfnFP6.js"
|
|
475
475
|
],
|
|
476
476
|
"css": [
|
|
477
477
|
"assets/graph-BYKN84J3.css"
|
|
478
478
|
]
|
|
479
479
|
},
|
|
480
480
|
"index.html": {
|
|
481
|
-
"file": "assets/index-
|
|
481
|
+
"file": "assets/index-BpL_Kl_s.js",
|
|
482
482
|
"name": "index",
|
|
483
483
|
"src": "index.html",
|
|
484
484
|
"isEntry": true,
|
|
@@ -487,7 +487,7 @@
|
|
|
487
487
|
"_react-Dss-ouuy.js",
|
|
488
488
|
"_home-CCbP6kS-.js",
|
|
489
489
|
"_markdown-0ngRuTpW.js",
|
|
490
|
-
"_canvas-
|
|
490
|
+
"_canvas-D8rDdfDz.js"
|
|
491
491
|
],
|
|
492
492
|
"dynamicImports": [
|
|
493
493
|
"_dist-DCtcCJPs.js",
|
|
@@ -501,17 +501,17 @@
|
|
|
501
501
|
"overview.tsx",
|
|
502
502
|
"preview.tsx",
|
|
503
503
|
"graph.tsx",
|
|
504
|
-
"_console-
|
|
504
|
+
"_console-Trqc0swD.js",
|
|
505
505
|
"index.html",
|
|
506
506
|
"skills.tsx",
|
|
507
507
|
"studio-process.tsx"
|
|
508
508
|
],
|
|
509
509
|
"css": [
|
|
510
|
-
"assets/index-
|
|
510
|
+
"assets/index-B3_OVy91.css"
|
|
511
511
|
]
|
|
512
512
|
},
|
|
513
513
|
"overview.tsx": {
|
|
514
|
-
"file": "assets/overview-
|
|
514
|
+
"file": "assets/overview-CDnVKlOt.js",
|
|
515
515
|
"name": "overview",
|
|
516
516
|
"src": "overview.tsx",
|
|
517
517
|
"isDynamicEntry": true,
|
|
@@ -520,13 +520,13 @@
|
|
|
520
520
|
"_react-Dss-ouuy.js",
|
|
521
521
|
"_home-CCbP6kS-.js",
|
|
522
522
|
"_markdown-0ngRuTpW.js",
|
|
523
|
-
"_canvas-
|
|
523
|
+
"_canvas-D8rDdfDz.js",
|
|
524
524
|
"index.html",
|
|
525
525
|
"_facts-BMO6V3-3.js",
|
|
526
|
-
"_work-turns-
|
|
527
|
-
"_choices-
|
|
528
|
-
"_skills-work-
|
|
529
|
-
"_explore-in-
|
|
526
|
+
"_work-turns-CT9RVcWY.js",
|
|
527
|
+
"_choices-D-YfnFP6.js",
|
|
528
|
+
"_skills-work-DNexV4OJ.js",
|
|
529
|
+
"_explore-in-BCHqjJ7B.js",
|
|
530
530
|
"_answer-board-CBkGbSLD.js"
|
|
531
531
|
],
|
|
532
532
|
"dynamicImports": [
|
|
@@ -537,7 +537,7 @@
|
|
|
537
537
|
]
|
|
538
538
|
},
|
|
539
539
|
"preview.tsx": {
|
|
540
|
-
"file": "assets/preview-
|
|
540
|
+
"file": "assets/preview-BEC1E9MK.js",
|
|
541
541
|
"name": "preview",
|
|
542
542
|
"src": "preview.tsx",
|
|
543
543
|
"isDynamicEntry": true,
|
|
@@ -545,13 +545,13 @@
|
|
|
545
545
|
"_rolldown-runtime-XKyaHtl9.js",
|
|
546
546
|
"_react-Dss-ouuy.js",
|
|
547
547
|
"_markdown-0ngRuTpW.js",
|
|
548
|
-
"_canvas-
|
|
548
|
+
"_canvas-D8rDdfDz.js",
|
|
549
549
|
"index.html",
|
|
550
|
-
"_explore-in-
|
|
550
|
+
"_explore-in-BCHqjJ7B.js"
|
|
551
551
|
]
|
|
552
552
|
},
|
|
553
553
|
"review.tsx": {
|
|
554
|
-
"file": "assets/review-
|
|
554
|
+
"file": "assets/review-DYP0aCXb.js",
|
|
555
555
|
"name": "review",
|
|
556
556
|
"src": "review.tsx",
|
|
557
557
|
"isDynamicEntry": true,
|
|
@@ -564,7 +564,7 @@
|
|
|
564
564
|
]
|
|
565
565
|
},
|
|
566
566
|
"shell/workspace.tsx": {
|
|
567
|
-
"file": "assets/workspace-
|
|
567
|
+
"file": "assets/workspace-COmCbGV3.js",
|
|
568
568
|
"name": "workspace",
|
|
569
569
|
"src": "shell/workspace.tsx",
|
|
570
570
|
"isDynamicEntry": true,
|
|
@@ -572,16 +572,16 @@
|
|
|
572
572
|
"_rolldown-runtime-XKyaHtl9.js",
|
|
573
573
|
"_react-Dss-ouuy.js",
|
|
574
574
|
"_markdown-0ngRuTpW.js",
|
|
575
|
-
"_canvas-
|
|
575
|
+
"_canvas-D8rDdfDz.js",
|
|
576
576
|
"index.html",
|
|
577
|
-
"_console-
|
|
577
|
+
"_console-Trqc0swD.js",
|
|
578
578
|
"_facts-BMO6V3-3.js",
|
|
579
579
|
"_snapshot-CAxBYPvV.js",
|
|
580
|
-
"_explore-in-
|
|
580
|
+
"_explore-in-BCHqjJ7B.js"
|
|
581
581
|
]
|
|
582
582
|
},
|
|
583
583
|
"skills.tsx": {
|
|
584
|
-
"file": "assets/skills-
|
|
584
|
+
"file": "assets/skills-1ec0Z-jx.js",
|
|
585
585
|
"name": "skills",
|
|
586
586
|
"src": "skills.tsx",
|
|
587
587
|
"isDynamicEntry": true,
|
|
@@ -591,14 +591,14 @@
|
|
|
591
591
|
"_home-CCbP6kS-.js",
|
|
592
592
|
"_markdown-0ngRuTpW.js",
|
|
593
593
|
"index.html",
|
|
594
|
-
"_skills-work-
|
|
594
|
+
"_skills-work-DNexV4OJ.js"
|
|
595
595
|
],
|
|
596
596
|
"css": [
|
|
597
597
|
"assets/skills-WkE0KCzn.css"
|
|
598
598
|
]
|
|
599
599
|
},
|
|
600
600
|
"studio-process.tsx": {
|
|
601
|
-
"file": "assets/studio-process-
|
|
601
|
+
"file": "assets/studio-process-EYQgikxq.js",
|
|
602
602
|
"name": "studio-process",
|
|
603
603
|
"src": "studio-process.tsx",
|
|
604
604
|
"isDynamicEntry": true,
|
|
@@ -606,11 +606,11 @@
|
|
|
606
606
|
"_rolldown-runtime-XKyaHtl9.js",
|
|
607
607
|
"_react-Dss-ouuy.js",
|
|
608
608
|
"_markdown-0ngRuTpW.js",
|
|
609
|
-
"_canvas-
|
|
609
|
+
"_canvas-D8rDdfDz.js",
|
|
610
610
|
"index.html",
|
|
611
|
-
"_console-
|
|
612
|
-
"_timeline-events-
|
|
613
|
-
"_notes-meaning-
|
|
611
|
+
"_console-Trqc0swD.js",
|
|
612
|
+
"_timeline-events-Chj2Gbx7.js",
|
|
613
|
+
"_notes-meaning-DcVGUBBY.js",
|
|
614
614
|
"_answer-board-CBkGbSLD.js",
|
|
615
615
|
"shell/workspace.tsx"
|
|
616
616
|
],
|