@rho-workspace/rho 0.5.3 → 0.5.4
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/capabilities.d.ts +27 -0
- package/dist/capabilities.js +73 -1
- package/dist/cli.js +150 -25
- package/dist/contract.generated.d.ts +112 -12
- package/dist/contracts/owners.generated.js +103 -8
- 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/installs.d.ts +11 -0
- package/dist/installs.js +179 -0
- package/dist/project-notes.js +2 -0
- package/dist/protocol.js +7 -5
- package/dist/screen-check-skill.d.ts +2 -0
- package/dist/screen-check-skill.js +39 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +50 -7
- package/dist/web/.vite/manifest.json +51 -51
- package/dist/web/assets/{choices-B-y2OYvE.js → choices-DU9kHlyQ.js} +1 -1
- package/dist/web/assets/{console-e1P5qYQ5.js → console-Dbdo-5oO.js} +1 -1
- package/dist/web/assets/{dist-Dd3iAGFy.js → dist-B2V0VDO0.js} +1 -1
- package/dist/web/assets/{dist-CH56yNDn.js → dist-BV3hWfn_.js} +1 -1
- package/dist/web/assets/{dist-CBM2oq6g.js → dist-CLNF2g-E.js} +1 -1
- package/dist/web/assets/{dist-DEorbOW0.js → dist-D25Vn17i.js} +1 -1
- package/dist/web/assets/{explore-in-muWXOGOY.js → explore-in-8Q5ftt-E.js} +1 -1
- package/dist/web/assets/{graph-CK-df5lh.js → graph-hS2kvHTI.js} +1 -1
- package/dist/web/assets/{index-BYuKpyoi.js → index-BHQIaDsx.js} +220 -121
- package/dist/web/assets/index-Cj1_iqyK.css +1 -0
- package/dist/web/assets/{notes-meaning-B3HFbh84.js → notes-meaning-DdPbtNzJ.js} +1 -1
- package/dist/web/assets/{overview-D1Ev2OC_.js → overview-BV6ZO5TO.js} +3 -3
- package/dist/web/assets/{preview-HbmQKUGY.js → preview-n5lOOdjN.js} +1 -1
- package/dist/web/assets/{review-BVh9jWMB.js → review-CmWou4Iv.js} +1 -1
- package/dist/web/assets/{skills-DPaEYkln.js → skills-Dy7n3L9d.js} +1 -1
- package/dist/web/assets/{skills-work-dvjfy_tu.js → skills-work-Cj0W6b-I.js} +1 -1
- package/dist/web/assets/{studio-process-BYm8mjRJ.js → studio-process-QOY_n2_8.js} +1 -1
- package/dist/web/assets/{timeline-events-CDZ7wiJX.js → timeline-events-DmX1BCh3.js} +1 -1
- package/dist/web/assets/{work-turns-BeCt303c.js → work-turns-Co0C71rJ.js} +1 -1
- package/dist/web/assets/{workspace-d5Hw_ClZ.js → workspace-BKFefRfJ.js} +2 -2
- package/dist/web/composition.json +73 -73
- package/dist/web/index.html +2 -2
- package/dist/web/renderer.json +1 -1
- package/docs/FRONTEND.md +30 -14
- package/docs/HEADLESS.md +59 -13
- 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 +3 -1
- package/node_modules/@rho-workspace/plugin-agent/dist/acp-conversation.js +14 -3
- 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/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/mcp.js +5 -1
- package/node_modules/@rho-workspace/plugin-agent/package.json +1 -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 +10 -6
- package/protocol/index.json +17 -17
- 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/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/scripts/browser-checks.mjs +53 -0
- package/scripts/screen-check.mjs +193 -0
- package/vendor/composition.json +102 -102
- package/vendor/rho-workspace-plugin-agent-0.4.28.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/index-DBd77u4a.css +0 -1
- 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
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { statements, unfinished } from './statements.js';
|
|
4
|
+
import { cellRelations } from './lineage.js';
|
|
5
|
+
import { CellScriptFlow } from './ui-flow.js';
|
|
4
6
|
import { Icon } from './ui-icons.js';
|
|
5
7
|
import { PlaceChip, usePlaces, whereOf } from './ui-servers.js';
|
|
6
8
|
import { takeCell } from './ui-notebook-target.js';
|
|
7
|
-
import { call, refused, agentName, clock, durationText, useShell, withShell } from './ui-base.js';
|
|
9
|
+
import { call, refused, agentName, clock, durationText, useShell, withShell, versionOf } from './ui-base.js';
|
|
10
|
+
export { versionOf };
|
|
8
11
|
export const languages = ['r', 'python'];
|
|
9
12
|
export const languageName = { r: 'R', python: 'Python' };
|
|
10
13
|
// A Notebook view at least this wide shows the sessions beside the cells.
|
|
11
14
|
export const notebookViewLimits = { cells: 300, codeLines: 14, outputLines: 12, railPlots: 12, cachedPlots: 64, wideViewPx: 840 };
|
|
12
15
|
const me = 'browser:local';
|
|
13
16
|
const failure = (error) => error instanceof Error ? error.message : 'The live session could not be reached.';
|
|
14
|
-
export const versionOf = (session) => session.version?.replace(/^R version (\S+).*$/, 'R $1') ?? languageName[session.language];
|
|
15
17
|
export const at = (iso) => clock(Date.parse(iso));
|
|
16
18
|
export function useAuthors(snapshot) {
|
|
17
19
|
return useMemo(() => {
|
|
@@ -122,14 +124,49 @@ function Ending({ cell, now }) {
|
|
|
122
124
|
return _jsx("span", { className: "nb-ending", children: "Not run" });
|
|
123
125
|
return _jsx("span", { className: "nb-ending failed", children: "Outcome unknown" });
|
|
124
126
|
}
|
|
125
|
-
|
|
127
|
+
// A cell named where another reads from it or is read by it; it goes to that cell where the page
|
|
128
|
+
// shows it. A cell lists at most `cells` of the later cells that read a value; the rest are counted.
|
|
129
|
+
export const relationLimits = { cells: 3 };
|
|
130
|
+
function CellLink({ cell, language, onCell, what }) {
|
|
131
|
+
const name = `${languageName[language]} ${cell.number}`;
|
|
132
|
+
return onCell ? _jsx("button", { className: "nb-cell-link", title: `Go to ${name}, which ${what}`, onClick: () => onCell(cell.cellId), children: name }) : _jsx("span", { className: "nb-cell-link", children: name });
|
|
133
|
+
}
|
|
134
|
+
// The later cells that read a value, at most `cells` of them; the rest are counted.
|
|
135
|
+
function CellLinks({ cells, language, onCell }) {
|
|
136
|
+
const shown = cells.slice(0, relationLimits.cells);
|
|
137
|
+
return _jsxs(_Fragment, { children: [shown.map((c, i) => _jsxs("span", { className: "nb-cell-links", children: [_jsx(CellLink, { cell: c, language: language, onCell: onCell, what: "read it" }), i < shown.length - 1 && ','] }, c.cellId)), cells.length > shown.length && _jsxs("span", { children: ["and ", cells.length - shown.length, " more"] })] });
|
|
138
|
+
}
|
|
139
|
+
// What each session's cells read from each other, by session.
|
|
140
|
+
export function useRelations(cells) {
|
|
141
|
+
return useMemo(() => {
|
|
142
|
+
const bySession = new Map();
|
|
143
|
+
for (const c of cells)
|
|
144
|
+
bySession.set(c.sessionId, [...bySession.get(c.sessionId) ?? [], c]);
|
|
145
|
+
const out = new Map(), all = { reads: new Map(), readers: new Map(), maker: new Map() };
|
|
146
|
+
for (const [id, list] of bySession) {
|
|
147
|
+
const r = cellRelations(list.map(c => ({ ...c, plots: 0 })));
|
|
148
|
+
out.set(id, r);
|
|
149
|
+
for (const [k, v] of r.reads)
|
|
150
|
+
all.reads.set(k, v);
|
|
151
|
+
for (const [k, v] of r.readers)
|
|
152
|
+
all.readers.set(k, v);
|
|
153
|
+
}
|
|
154
|
+
return { bySession: out, all };
|
|
155
|
+
}, [cells]);
|
|
156
|
+
}
|
|
157
|
+
function CellView({ cell, author, who, client, projectId, now, onEdit, onRunAgain, onConversation, onObject, relations, onCell }) {
|
|
126
158
|
const settled = !['queued', 'running'].includes(cell.state);
|
|
159
|
+
const reads = relations?.reads.get(cell.cellId) ?? [], readers = relations?.readers.get(cell.cellId);
|
|
160
|
+
const value = (name) => onObject
|
|
161
|
+
? _jsx("button", { className: "nb-value", title: 'Look at ' + name, onClick: () => onObject(cell.language, name), children: name })
|
|
162
|
+
: _jsx("code", { className: "nb-value", children: name });
|
|
127
163
|
const interrupted = cell.interrupt ? `Interrupted by ${who(cell.interrupt.by).name === 'You' ? 'you' : who(cell.interrupt.by).name} at ${at(cell.interrupt.at)}.` : null;
|
|
128
164
|
return _jsxs("li", { className: 'nb-cell ' + cell.state + (cell.by === me ? ' mine' : ''), id: 'cell-' + cell.cellId, children: [_jsxs("div", { className: "nb-gutter", "aria-hidden": "true", children: [_jsx("span", { className: 'nb-lang ' + cell.language, children: languageName[cell.language] }), _jsx("span", { className: "nb-number", children: cell.number })] }), _jsxs("div", { className: "nb-body", children: [_jsxs("header", { className: "nb-head", children: [_jsx("span", { className: "nb-who", children: author.conversationId
|
|
129
165
|
? _jsx("button", { className: "text-button", title: author.title ? 'Open ' + author.title : undefined, onClick: () => onConversation(author.conversationId), children: author.name })
|
|
130
|
-
: author.name }), _jsx("span", { className: "nb-purpose", children: cell.purpose ?? _jsxs("span", { className: "nb-unnamed", children: [languageName[cell.language], " cell ", cell.number] }) }), _jsxs("span", { className: "nb-when", children: [_jsx("time", { dateTime: cell.queuedAt, children: at(cell.queuedAt) }), _jsx(Ending, { cell: cell, now: now })] })] }), _jsx(Code, { code: cell.code, language: cell.language }), _jsx(Outputs, { cell: cell, client: client, projectId: projectId }), settled && ((cell.defined?.length ?? 0) > 0 || (cell.removed?.length ?? 0) > 0) && _jsxs("p", { className: "nb-values", children: [(cell.defined?.length ?? 0) > 0 && _jsxs(_Fragment, { children: [_jsx("span", { children: "Made or changed" }), cell.defined.map(name =>
|
|
131
|
-
|
|
132
|
-
|
|
166
|
+
: author.name }), _jsx("span", { className: "nb-purpose", children: cell.purpose ?? _jsxs("span", { className: "nb-unnamed", children: [languageName[cell.language], " cell ", cell.number] }) }), _jsxs("span", { className: "nb-when", children: [_jsx("time", { dateTime: cell.queuedAt, children: at(cell.queuedAt) }), _jsx(Ending, { cell: cell, now: now })] })] }), _jsx(Code, { code: cell.code, language: cell.language }), _jsx(Outputs, { cell: cell, client: client, projectId: projectId }), settled && (reads.length > 0 || (cell.defined?.length ?? 0) > 0 || (cell.removed?.length ?? 0) > 0) && _jsxs("p", { className: "nb-values", children: [reads.length > 0 && _jsxs(_Fragment, { children: [_jsx("span", { children: "Read" }), reads.map(({ name, from }) => _jsxs("span", { className: "nb-rel", children: [value(name), from && _jsxs(_Fragment, { children: ["from ", _jsx(CellLink, { cell: from, language: cell.language, onCell: onCell, what: "made it" })] })] }, name))] }), (cell.defined?.length ?? 0) > 0 && _jsxs(_Fragment, { children: [_jsx("span", { children: "Made or changed" }), cell.defined.map(name => {
|
|
167
|
+
const by = readers?.get(name) ?? [];
|
|
168
|
+
return _jsxs("span", { className: "nb-rel", children: [value(name), by.length > 0 && _jsxs(_Fragment, { children: ["read in ", _jsx(CellLinks, { cells: by, language: cell.language, onCell: onCell })] })] }, name);
|
|
169
|
+
})] }), (cell.removed?.length ?? 0) > 0 && _jsxs(_Fragment, { children: [_jsx("span", { children: "Removed" }), cell.removed.map(name => _jsx("code", { className: "nb-value gone", children: name }, name))] })] }), settled && _jsx(CellScriptFlow, { code: cell.code, language: cell.language }), (interrupted || (cell.problem && cell.state !== 'interrupted')) && _jsx("p", { className: "nb-problem", children: interrupted ?? cell.problem }), settled && _jsxs("div", { className: "nb-actions", children: [_jsxs("button", { className: "text-button", onClick: () => onEdit(cell), children: [_jsx(Icon, { name: "pencil", size: 13 }), "Edit and run"] }), _jsxs("button", { className: "text-button", onClick: () => onRunAgain(cell), children: [_jsx(Icon, { name: "run", size: 13 }), "Run again"] })] })] })] });
|
|
133
170
|
}
|
|
134
171
|
// Where a session started and where it ended, among the cells.
|
|
135
172
|
function Mark({ session, edge, who }) {
|
|
@@ -156,7 +193,7 @@ function SessionRow({ language, session, onInterrupt, onStop, asking }) {
|
|
|
156
193
|
return _jsxs("div", { className: 'nb-session ' + session.state, children: [_jsx("span", { className: "nb-dot", "aria-hidden": "true" }), _jsxs("div", { children: [_jsx("strong", { children: session.version ? versionOf(session) : name }), _jsx("small", { children: [whereOf(session), session.state === 'starting' ? (session.place ? 'Connecting…' : 'Starting…') : busy ? 'Running a cell' : 'Idle', `${session.cells} ${session.cells === 1 ? 'cell' : 'cells'}`].filter(Boolean).join(' · ') })] }), _jsxs("div", { className: "nb-session-actions", children: [busy && _jsx("button", { className: "secondary", disabled: asking.startsWith('interrupt:'), onClick: onInterrupt, children: "Interrupt" }), _jsx("button", { className: "text-button", disabled: asking === 'stop:' + session.sessionId, title: `End the ${name} session; its values are gone`, onClick: () => onStop(session), children: "Stop" })] })] });
|
|
157
194
|
}
|
|
158
195
|
// The session shown is the person's choice, else the one the newest cell ran in.
|
|
159
|
-
function Variables({ sessions, onObject, pane = false, recent }) {
|
|
196
|
+
function Variables({ sessions, onObject, pane = false, recent, relations, onCell }) {
|
|
160
197
|
const live = languages.filter(l => sessions[l] && sessions[l].state !== 'ended');
|
|
161
198
|
const [chosen, setChosen] = useState(null);
|
|
162
199
|
useEffect(() => setChosen(null), [recent]);
|
|
@@ -167,7 +204,16 @@ function Variables({ sessions, onObject, pane = false, recent }) {
|
|
|
167
204
|
? _jsx("h2", { id: id, className: "nb-pane-state", children: session ? _jsxs(_Fragment, { children: [_jsx("span", { className: 'nb-dot ' + session.state, "aria-hidden": "true" }), [versionOf(session), whereOf(session), session.state === 'busy' ? 'running a cell' : session.state === 'starting' ? 'starting' : 'idle', `${session.variables.length + session.variablesOmitted} ${session.variables.length + session.variablesOmitted === 1 ? 'value' : 'values'}`].filter(Boolean).join(' · ')] }) : 'Variables' })
|
|
168
205
|
: _jsx("h2", { id: id, children: "Variables" }), live.length > 1 && _jsx("div", { className: "nb-tabs", role: "group", "aria-label": "Session", children: live.map(l => _jsx("button", { "aria-pressed": l === shown, onClick: () => setChosen(l), children: languageName[l] }, l)) })] }), !session ? _jsx("p", { className: "nb-empty-line", children: pane ? 'No live session. Values show here once a cell runs in R or Python, from the Notebook or a script\'s line.' : 'No live session.' })
|
|
169
206
|
: !session.variables.length ? _jsxs("p", { className: "nb-empty-line", children: ["Nothing defined in ", languageName[session.language], " yet."] })
|
|
170
|
-
: _jsx("ul", { className: "nb-vars", children: session.variables.map(v => _jsxs("li", { title: v.summary, children: [onObject ? _jsx("button", { className: "nb-var-name", title: 'Look at ' + v.name, onClick: () => onObject(session.language, v.name), children: v.name }) : _jsx("span", { className: "nb-var-name", children: v.name }), _jsxs("span", { className: "nb-var-type", children: [v.type, v.size ? ' · ' + v.size : ''] }), v.summary && _jsx("span", { className: "nb-var-summary", children: v.summary })] }, v.name)) }), session && session.variablesOmitted > 0 && _jsxs("p", { className: "nb-note", children: [session.variablesOmitted, " more not listed."] })] });
|
|
207
|
+
: _jsx("ul", { className: "nb-vars", children: session.variables.map(v => _jsxs("li", { title: v.summary, children: [onObject ? _jsx("button", { className: "nb-var-name", title: 'Look at ' + v.name, onClick: () => onObject(session.language, v.name), children: v.name }) : _jsx("span", { className: "nb-var-name", children: v.name }), _jsxs("span", { className: "nb-var-type", children: [v.type, v.size ? ' · ' + v.size : ''] }), v.summary && _jsx("span", { className: "nb-var-summary", children: v.summary }), _jsx(Made, { name: v.name, session: session, relations: relations?.get(session.sessionId), onCell: onCell })] }, v.name)) }), session && session.variablesOmitted > 0 && _jsxs("p", { className: "nb-note", children: [session.variablesOmitted, " more not listed."] })] });
|
|
208
|
+
}
|
|
209
|
+
// Where a value came from and where it went: the cell that made it as it is now, and the later
|
|
210
|
+
// cells that read that version.
|
|
211
|
+
function Made({ name, session, relations, onCell }) {
|
|
212
|
+
const maker = relations?.maker.get(name);
|
|
213
|
+
if (!maker)
|
|
214
|
+
return null;
|
|
215
|
+
const by = relations.readers.get(maker.cellId)?.get(name) ?? [];
|
|
216
|
+
return _jsxs("span", { className: "nb-var-made", children: ["Made in ", _jsx(CellLink, { cell: maker, language: session.language, onCell: onCell, what: "made it" }), by.length > 0 && _jsxs(_Fragment, { children: [" \u00B7 read in ", _jsx(CellLinks, { cells: by, language: session.language, onCell: onCell })] })] });
|
|
171
217
|
}
|
|
172
218
|
function RailPlot({ client, projectId, cell, output, onShow }) {
|
|
173
219
|
const { src } = usePlot(client, projectId, cell.cellId, output.plot);
|
|
@@ -431,18 +477,21 @@ function NotebookBody({ client, snapshot, onConversation, onObject, scope, compa
|
|
|
431
477
|
const [now, setNow] = useState(Date.now());
|
|
432
478
|
useEffect(() => { if (!running)
|
|
433
479
|
return; const t = setInterval(() => setNow(Date.now()), 1000); return () => clearInterval(t); }, [running]);
|
|
434
|
-
// The list in time: each cell, and where a session started or ended among them.
|
|
480
|
+
// The list in time: each cell, and where a session started or ended among them. At one instant
|
|
481
|
+
// a session that ended comes first and the one that started next (an Agent starting its own
|
|
482
|
+
// session again with another program does both at once); one that started and ended then shows
|
|
483
|
+
// its start before its end.
|
|
435
484
|
const rows = useMemo(() => {
|
|
436
|
-
const out = cells.map(cell => ({ at: Date.parse(cell.queuedAt), order:
|
|
485
|
+
const out = cells.map(cell => ({ at: Date.parse(cell.queuedAt), order: 2, key: cell.cellId, cell }));
|
|
437
486
|
const first = out[0]?.at ?? Infinity, until = scope?.at ?? Infinity;
|
|
438
487
|
for (const session of read?.sessions ?? []) {
|
|
439
488
|
const has = cells.some(c => c.sessionId === session.sessionId);
|
|
440
489
|
if (scope && !has)
|
|
441
490
|
continue;
|
|
442
491
|
if (has || Date.parse(session.startedAt) >= first)
|
|
443
|
-
out.push({ at: Date.parse(session.startedAt), order:
|
|
492
|
+
out.push({ at: Date.parse(session.startedAt), order: 1, key: session.sessionId + ':start', session, edge: 'start' });
|
|
444
493
|
if (session.endedAt && Date.parse(session.endedAt) <= until && (has || Date.parse(session.endedAt) >= first))
|
|
445
|
-
out.push({ at: Date.parse(session.endedAt), order:
|
|
494
|
+
out.push({ at: Date.parse(session.endedAt), order: session.endedAt === session.startedAt ? 3 : 0, key: session.sessionId + ':end', session, edge: 'end' });
|
|
446
495
|
}
|
|
447
496
|
return out.sort((a, b) => a.at - b.at || a.order - b.order);
|
|
448
497
|
}, [cells, read?.sessions, scope?.at]);
|
|
@@ -553,7 +602,17 @@ function NotebookBody({ client, snapshot, onConversation, onObject, scope, compa
|
|
|
553
602
|
}
|
|
554
603
|
const edit = (cell) => { setLanguage(cell.language); setDraft(cell.code); requestAnimationFrame(() => { input.current?.focus(); input.current?.scrollIntoView({ block: 'nearest' }); }); };
|
|
555
604
|
const plots = useMemo(() => cells.flatMap(cell => cell.outputs.filter(o => o.kind === 'plot').map(output => ({ cell, output }))).slice(-notebookViewLimits.railPlots).reverse(), [cells]);
|
|
556
|
-
|
|
605
|
+
// A cell gone to is brought into view and marked for a moment.
|
|
606
|
+
const show = (cellId) => {
|
|
607
|
+
const element = document.getElementById('cell-' + cellId);
|
|
608
|
+
if (!element)
|
|
609
|
+
return;
|
|
610
|
+
element.scrollIntoView({ block: 'start', behavior: 'smooth' });
|
|
611
|
+
element.classList.remove('flash');
|
|
612
|
+
void element.offsetWidth;
|
|
613
|
+
element.classList.add('flash');
|
|
614
|
+
};
|
|
615
|
+
const relations = useRelations(cells);
|
|
557
616
|
if (off)
|
|
558
617
|
return _jsx("p", { className: "nb-empty-line", children: problem });
|
|
559
618
|
// The line to run waits for now during a replay.
|
|
@@ -586,16 +645,16 @@ function NotebookBody({ client, snapshot, onConversation, onObject, scope, compa
|
|
|
586
645
|
setNote(''); }, note: note, problem: runProblem, busy: busy, input: input, history: history, running: latest[shownLanguage]?.state === 'busy', onRun: code => void run(code, shownLanguage), onInterrupt: () => void interrupt(shownLanguage), onClear: () => setCleared(rows.at(-1)?.at ?? Date.now()) })] });
|
|
587
646
|
}
|
|
588
647
|
if (compact)
|
|
589
|
-
return _jsx("div", { className: "nb-page compact", ref: page, children: _jsxs("div", { className: "nb-main", children: [problem && _jsx("p", { className: "inline-error", role: "alert", children: problem }), live.length > 0 && !beside.variables && _jsxs("details", { className: "nb-strip", children: [_jsx("summary", { children: live.map(l => _jsxs("span", { className: 'nb-strip-session ' + latest[l].state, children: [_jsx("span", { className: "nb-dot", "aria-hidden": "true" }), versionOf(latest[l]), " \u00B7 ", latest[l].state === 'busy' ? 'running' : latest[l].state, " \u00B7 ", latest[l].variables.length, " ", latest[l].variables.length === 1 ? 'value' : 'values'] }, l)) }), _jsx(Variables, { sessions: Object.fromEntries(live.map(l => [l, latest[l]])), onObject: onObject })] }), !read ? _jsx("p", { className: "nb-empty-line", children: "Reading the live sessions\u2026" })
|
|
648
|
+
return _jsx("div", { className: "nb-page compact", ref: page, children: _jsxs("div", { className: "nb-main", children: [problem && _jsx("p", { className: "inline-error", role: "alert", children: problem }), live.length > 0 && !beside.variables && _jsxs("details", { className: "nb-strip", children: [_jsx("summary", { children: live.map(l => _jsxs("span", { className: 'nb-strip-session ' + latest[l].state, children: [_jsx("span", { className: "nb-dot", "aria-hidden": "true" }), versionOf(latest[l]), " \u00B7 ", latest[l].state === 'busy' ? 'running' : latest[l].state, " \u00B7 ", latest[l].variables.length, " ", latest[l].variables.length === 1 ? 'value' : 'values'] }, l)) }), _jsx(Variables, { sessions: Object.fromEntries(live.map(l => [l, latest[l]])), onObject: onObject, relations: relations.bySession, onCell: show })] }), !read ? _jsx("p", { className: "nb-empty-line", children: "Reading the live sessions\u2026" })
|
|
590
649
|
: !cells.length ? _jsx("p", { className: "nb-empty-line", children: nothing })
|
|
591
650
|
: _jsx("ol", { className: "nb-cells", ref: list, children: rows.map(row => 'cell' in row
|
|
592
|
-
? _jsx(CellView, { cell: row.cell, author: who(row.cell.by), who: who, client: client, projectId: projectId, now: now, onEdit: edit, onRunAgain: cell => void run(cell.code, cell.language), onConversation: onConversation, onObject: current.has(row.cell.sessionId) ? onObject : undefined }, row.key)
|
|
651
|
+
? _jsx(CellView, { cell: row.cell, author: who(row.cell.by), who: who, client: client, projectId: projectId, now: now, onEdit: edit, onRunAgain: cell => void run(cell.code, cell.language), onConversation: onConversation, onObject: current.has(row.cell.sessionId) ? onObject : undefined, relations: relations.bySession.get(row.cell.sessionId), onCell: show }, row.key)
|
|
593
652
|
: _jsx(Mark, { session: row.session, edge: row.edge, who: who }, row.key)) }), composer(true)] }) });
|
|
594
653
|
return _jsxs("div", { className: 'nb-page' + (inView ? ' in-view' : ''), ref: page, children: [_jsxs("div", { className: "nb-main", children: [problem && _jsx("p", { className: "inline-error", role: "alert", children: problem }), !read ? _jsx("p", { className: "nb-empty-line", children: "Reading the live sessions\u2026" })
|
|
595
654
|
: !cells.length ? inView ? _jsx("p", { className: "nb-empty-line", children: nothing }) : _jsxs("div", { className: "nb-empty", children: [_jsx("h2", { children: "Nothing has run here yet" }), _jsx("p", { children: "When the Agent runs R or Python in this project's live sessions, each cell shows here with its purpose, its code, what it printed, its plots and the values it left. Your own cells run in the same sessions, so you can look at what the Agent made." })] })
|
|
596
655
|
: _jsx("ol", { className: "nb-cells", ref: list, children: rows.map(row => 'cell' in row
|
|
597
|
-
? _jsx(CellView, { cell: row.cell, author: who(row.cell.by), who: who, client: client, projectId: projectId, now: now, onEdit: edit, onRunAgain: cell => void run(cell.code, cell.language), onConversation: onConversation, onObject: current.has(row.cell.sessionId) ? onObject : undefined }, row.key)
|
|
598
|
-
: _jsx(Mark, { session: row.session, edge: row.edge, who: who }, row.key)) }), read && read.omitted > 0 && _jsxs("p", { className: "nb-note", children: [read.omitted, " earlier ", read.omitted === 1 ? 'cell is' : 'cells are', " kept but not shown."] }), composer(false)] }), _jsxs("aside", { className: "nb-rail", "aria-label": "Live sessions", children: [_jsxs("section", { className: "nb-rail-section", "aria-labelledby": "nb-sessions", children: [_jsx("header", { children: _jsx("h2", { id: "nb-sessions", children: "Sessions" }) }), languages.map(l => _jsx(SessionRow, { language: l, session: latest[l], asking: asking, onInterrupt: () => void interrupt(l), onStop: session => void stop(session) }, l)), askProblem && _jsx("p", { className: "inline-error", role: "alert", children: askProblem })] }), !beside.variables && _jsx(Variables, { sessions: latest, onObject: onObject }), plots.length > 0 && !beside.plots && _jsxs("section", { className: "nb-rail-section", "aria-labelledby": "nb-plots", children: [_jsx("header", { children: _jsx("h2", { id: "nb-plots", children: "Plots" }) }), _jsx("div", { className: "nb-thumbs", children: plots.map(({ cell, output }) => _jsx(RailPlot, { client: client, projectId: projectId, cell: cell, output: output, onShow: () => show(cell.cellId) }, cell.cellId + ':' + output.plot)) })] })] })] });
|
|
656
|
+
? _jsx(CellView, { cell: row.cell, author: who(row.cell.by), who: who, client: client, projectId: projectId, now: now, onEdit: edit, onRunAgain: cell => void run(cell.code, cell.language), onConversation: onConversation, onObject: current.has(row.cell.sessionId) ? onObject : undefined, relations: relations.bySession.get(row.cell.sessionId), onCell: show }, row.key)
|
|
657
|
+
: _jsx(Mark, { session: row.session, edge: row.edge, who: who }, row.key)) }), read && read.omitted > 0 && _jsxs("p", { className: "nb-note", children: [read.omitted, " earlier ", read.omitted === 1 ? 'cell is' : 'cells are', " kept but not shown."] }), composer(false)] }), _jsxs("aside", { className: "nb-rail", "aria-label": "Live sessions", children: [_jsxs("section", { className: "nb-rail-section", "aria-labelledby": "nb-sessions", children: [_jsx("header", { children: _jsx("h2", { id: "nb-sessions", children: "Sessions" }) }), languages.map(l => _jsx(SessionRow, { language: l, session: latest[l], asking: asking, onInterrupt: () => void interrupt(l), onStop: session => void stop(session) }, l)), askProblem && _jsx("p", { className: "inline-error", role: "alert", children: askProblem })] }), !beside.variables && _jsx(Variables, { sessions: latest, onObject: onObject, relations: relations.bySession, onCell: show }), plots.length > 0 && !beside.plots && _jsxs("section", { className: "nb-rail-section", "aria-labelledby": "nb-plots", children: [_jsx("header", { children: _jsx("h2", { id: "nb-plots", children: "Plots" }) }), _jsx("div", { className: "nb-thumbs", children: plots.map(({ cell, output }) => _jsx(RailPlot, { client: client, projectId: projectId, cell: cell, output: output, onShow: () => show(cell.cellId) }, cell.cellId + ':' + output.plot)) })] })] })] });
|
|
599
658
|
}
|
|
600
659
|
// The newest session of each language.
|
|
601
660
|
export function latestSessions(read) {
|
|
@@ -607,12 +666,14 @@ export function latestSessions(read) {
|
|
|
607
666
|
}
|
|
608
667
|
// The live sessions' variables as a view of their own, beside a script and the Notebook: each
|
|
609
668
|
// with its type, size and summary, read again after every cell. A name opens the value.
|
|
669
|
+
const none = [];
|
|
610
670
|
export function VariablesPane({ client, snapshot, onObject }) {
|
|
611
671
|
const { read, off, problem } = useKernel(client, snapshot.project.id, snapshot.cursor);
|
|
612
672
|
const latest = useMemo(() => latestSessions(read), [read]);
|
|
673
|
+
const relations = useRelations(read?.cells ?? none);
|
|
613
674
|
return _jsx("div", { className: "nb-pane", children: off || (problem && !read) ? _jsx("p", { className: "nb-empty-line", children: problem })
|
|
614
675
|
: !read ? _jsx("p", { className: "nb-empty-line", children: "Reading the live sessions\u2026" })
|
|
615
|
-
: _jsx(Variables, { pane: true, sessions: latest, onObject: onObject, recent: read.cells.at(-1)?.language }) });
|
|
676
|
+
: _jsx(Variables, { pane: true, sessions: latest, onObject: onObject, recent: read.cells.at(-1)?.language, relations: relations.bySession }) });
|
|
616
677
|
}
|
|
617
678
|
// The plots the live sessions drew, as a view of their own: the newest at the size of the view,
|
|
618
679
|
// the ones before it to step back through. A new plot comes forward as it is drawn. Plots of an
|
|
@@ -107,6 +107,18 @@ button.nb-var-name:hover { text-decoration: underline; background: none; }
|
|
|
107
107
|
button.nb-value:hover { border-color: var(--color-accent); background: var(--color-hover); }
|
|
108
108
|
code.nb-value { border-color: transparent; background: var(--color-well); color: var(--color-ink); font-weight: 500; }
|
|
109
109
|
.nb-value.gone { color: var(--color-meta); text-decoration: line-through; }
|
|
110
|
+
/* What a cell read and from which cell, and which later cells read what it made. */
|
|
111
|
+
.nb-values > .nb-rel + span { margin-left: 8px; }
|
|
112
|
+
.nb-rel { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 2px 4px; }
|
|
113
|
+
.nb-rel + .nb-rel { margin-left: 4px; }
|
|
114
|
+
.nb-cell-link { min-height: 0; padding: 0 2px; border: 0; border-radius: 4px; background: none; box-shadow: none; color: var(--color-meta); font: 500 11.5px var(--font-mono); white-space: nowrap; }
|
|
115
|
+
button.nb-cell-link { color: var(--color-accent-strong); }
|
|
116
|
+
button.nb-cell-link:hover { background: var(--color-hover); text-decoration: underline; }
|
|
117
|
+
.nb-var-made { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 0 3px; color: var(--color-meta); font-size: 11.5px; }
|
|
118
|
+
.nb-var-made .nb-cell-link { font-size: 11px; }
|
|
119
|
+
.nb-cell-links { display: inline-flex; align-items: baseline; }
|
|
120
|
+
@keyframes nb-flash { from { background: var(--color-accent-soft); } to { background: transparent; } }
|
|
121
|
+
.nb-cell.flash { animation: nb-flash 1.6s ease-out; }
|
|
110
122
|
.nb-var-type { overflow: hidden; color: var(--color-meta); font-size: 12px; text-align: right; text-overflow: ellipsis; white-space: nowrap; }
|
|
111
123
|
.nb-var-summary { grid-column: 1 / -1; overflow: hidden; color: var(--color-muted); font: 11.5px/1.4 var(--font-mono); text-overflow: ellipsis; white-space: nowrap; }
|
|
112
124
|
.nb-thumbs { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
|
|
@@ -340,54 +352,112 @@ code.nb-value { border-color: transparent; background: var(--color-well); color:
|
|
|
340
352
|
.sv-reader-body { min-width: 0; font-size: 12.5px; overflow-wrap: anywhere; }
|
|
341
353
|
.sv-reader-body pre { white-space: pre-wrap; }
|
|
342
354
|
.sv-reader .nb-note code { overflow-wrap: anywhere; }
|
|
343
|
-
/*
|
|
344
|
-
|
|
355
|
+
/* Data flow: a graph of values from the data read at the top to the results at the bottom, with
|
|
356
|
+
the results to trace above it and the value chosen beside it (below it when narrow). Its path
|
|
357
|
+
shows in the colors a script's editor marks lines in: what it comes from, and what comes of it. */
|
|
345
358
|
.flow-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
|
|
346
|
-
.flow-lede { margin: -4px 0 0; color: var(--color-meta); font-size: 12px; }
|
|
347
|
-
.
|
|
348
|
-
.
|
|
349
|
-
.
|
|
350
|
-
.
|
|
351
|
-
.
|
|
352
|
-
.
|
|
353
|
-
.
|
|
354
|
-
.
|
|
355
|
-
.
|
|
356
|
-
.
|
|
357
|
-
.
|
|
358
|
-
.
|
|
359
|
-
|
|
360
|
-
.
|
|
361
|
-
|
|
362
|
-
.
|
|
363
|
-
.
|
|
364
|
-
.
|
|
365
|
-
.
|
|
366
|
-
.
|
|
367
|
-
.
|
|
368
|
-
|
|
369
|
-
.
|
|
370
|
-
|
|
371
|
-
.
|
|
372
|
-
.
|
|
373
|
-
.
|
|
374
|
-
.
|
|
375
|
-
.
|
|
376
|
-
.
|
|
377
|
-
.
|
|
378
|
-
.
|
|
379
|
-
.
|
|
380
|
-
.
|
|
381
|
-
.
|
|
382
|
-
.
|
|
383
|
-
.
|
|
384
|
-
.
|
|
385
|
-
.flow-cell
|
|
386
|
-
.
|
|
387
|
-
.
|
|
388
|
-
.
|
|
359
|
+
.flow-lede { margin: -4px 0 0; color: var(--color-meta); font-size: 12px; line-height: 1.45; }
|
|
360
|
+
.lin { display: flex; flex-direction: column; gap: 10px; min-width: 0; container-type: inline-size; }
|
|
361
|
+
.lin-results { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
|
|
362
|
+
.lin-results > span { margin-right: 4px; color: var(--color-meta); font-size: 11.5px; font-weight: 650; }
|
|
363
|
+
.lin-results > button:not(.text-button) { display: inline-flex; align-items: center; justify-content: flex-start; gap: 4px; max-width: 16rem; min-height: 0; padding: 2px 8px; border: 1px solid var(--color-hairline); border-radius: 999px; background: var(--color-surface); box-shadow: none; color: var(--color-muted); font-size: 11.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
364
|
+
.lin-results > button:not(.text-button) > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
|
365
|
+
.lin-results > button:not(.text-button):hover { border-color: var(--color-hairline-strong); color: var(--color-ink); }
|
|
366
|
+
.lin-results > button[aria-pressed="true"] { border-color: var(--color-accent); background: var(--color-accent-soft); color: var(--color-accent-strong); }
|
|
367
|
+
.lin-results > button > svg { flex: none; }
|
|
368
|
+
.lin-results > .text-button { min-height: 0; padding: 2px 4px; font-size: 11.5px; }
|
|
369
|
+
.lin-main { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; align-items: start; }
|
|
370
|
+
.lin-canvas { position: relative; display: flex; flex-direction: column; gap: 30px; min-width: 0; padding: 4px 0 10px; }
|
|
371
|
+
.lin-edges { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
|
|
372
|
+
.lin-edges path { fill: none; stroke: var(--color-hairline-strong); stroke-width: 1.3; transition: stroke .12s, opacity .12s; }
|
|
373
|
+
.lin-edges path.from { stroke: var(--color-hue-sky-ink); stroke-width: 1.8; }
|
|
374
|
+
.lin-edges path.into { stroke: var(--color-hue-clay-ink); stroke-width: 1.8; }
|
|
375
|
+
.lin-edges path.off { opacity: .18; }
|
|
376
|
+
.lin-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 12px; }
|
|
377
|
+
.lin-node { position: relative; display: flex; align-items: flex-start; gap: 6px; max-width: min(100%, 14rem); min-width: 0; min-height: 0; padding: 6px 10px 7px; border: 1px solid var(--color-hairline-strong); border-radius: 8px; background: var(--color-surface); box-shadow: none; color: var(--color-ink); text-align: left; cursor: pointer; transition: opacity .12s, border-color .12s, background .12s; }
|
|
378
|
+
.lin-node:hover { border-color: var(--color-accent); }
|
|
379
|
+
.lin-node > svg { flex: none; margin-top: 2px; color: var(--color-meta); }
|
|
380
|
+
.lin-text { display: grid; gap: 2px; min-width: 0; }
|
|
381
|
+
.lin-title { display: -webkit-box; min-width: 0; overflow: hidden; overflow-wrap: anywhere; font-size: 12.5px; font-weight: 500; line-height: 1.35; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
|
|
382
|
+
.lin-name { min-width: 0; overflow: hidden; font: 600 12px var(--font-mono); text-overflow: ellipsis; white-space: nowrap; }
|
|
383
|
+
.lin-name.lin-sub { font: 500 10.5px/1.3 var(--font-mono); color: var(--color-meta); }
|
|
384
|
+
.lin-node.input { border-style: dashed; background: var(--color-canvas); }
|
|
385
|
+
.lin-node.output { border-color: transparent; background: var(--color-hue-moss); color: var(--color-hue-moss-ink); }
|
|
386
|
+
.lin-node.plot { border-color: transparent; background: var(--color-hue-iris); color: var(--color-hue-iris-ink); }
|
|
387
|
+
.lin-node.output > svg, .lin-node.plot > svg, .lin-node.output .lin-sub, .lin-node.plot .lin-sub { color: inherit; opacity: .8; }
|
|
388
|
+
.lin-node.from { border-color: var(--color-hue-sky-ink); }
|
|
389
|
+
.lin-node.into { border-color: var(--color-hue-clay-ink); }
|
|
390
|
+
.lin-node.value.from, .lin-node.input.from { background: var(--color-hue-sky); }
|
|
391
|
+
.lin-node.value.into { background: var(--color-hue-clay); }
|
|
392
|
+
.lin-node.here { border-color: var(--color-accent); box-shadow: 0 0 0 2px var(--color-accent-soft); }
|
|
393
|
+
.lin-node.chosen { border-color: var(--color-accent); border-style: solid; box-shadow: 0 0 0 3px var(--color-accent-soft); }
|
|
394
|
+
.lin-node.dim { border-color: var(--color-hairline); background: var(--color-canvas); color: var(--color-meta); }
|
|
395
|
+
.lin-node.dim > * { opacity: .55; }
|
|
396
|
+
.lin-detail { display: flex; flex-direction: column; gap: 8px; min-width: 0; padding: 10px 12px 11px; border: 1px solid var(--color-hairline); border-radius: 10px; background: var(--color-surface); font-size: 12px; }
|
|
397
|
+
.lin-detail > * { flex: none; }
|
|
398
|
+
.lin-detail .flow-cell-plots img { max-height: 9rem; width: auto; }
|
|
399
|
+
.lin-detail.empty { color: var(--color-muted); }
|
|
400
|
+
.lin-detail p { margin: 0; }
|
|
401
|
+
.lin-sum { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 6px; color: var(--color-muted); font-size: 12px; }
|
|
402
|
+
.lin-sum b { color: var(--color-ink); font-size: 15px; font-variant-numeric: tabular-nums; }
|
|
403
|
+
.lin-sum > span { color: var(--color-meta); }
|
|
404
|
+
.lin-detail > header { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 7px; min-width: 0; }
|
|
405
|
+
.lin-detail > header > svg { flex: none; color: var(--color-meta); }
|
|
406
|
+
.lin-detail h3 { min-width: 0; margin: 0; overflow-wrap: anywhere; font-size: 14px; font-weight: 650; line-height: 1.35; }
|
|
407
|
+
.lin-detail h3.lin-bare { font: 650 13px var(--font-mono); }
|
|
408
|
+
.lin-kind { color: var(--color-meta); font-size: 11.5px; }
|
|
409
|
+
.lin-detail > header > .text-button { min-height: 0; padding: 1px 4px; font-size: 12px; }
|
|
410
|
+
.lin-detail > header > .text-button:first-of-type { margin-left: auto; }
|
|
411
|
+
.lin-path { color: var(--color-meta); font: 11px var(--font-mono); overflow-wrap: anywhere; }
|
|
412
|
+
.lin-said { color: var(--color-meta); font-size: 11.5px; overflow-wrap: anywhere; }
|
|
413
|
+
.lin-ident { font: 11px var(--font-mono); color: var(--color-muted); }
|
|
414
|
+
.lin-made-line { display: flex; flex-wrap: wrap; gap: 2px 8px; color: var(--color-muted); }
|
|
415
|
+
.lin-made .text-button { min-height: 0; padding: 0 2px; font-size: 12px; font-weight: 650; }
|
|
416
|
+
.lin-made b { font-weight: 650; color: var(--color-ink); }
|
|
417
|
+
.lin-purpose { color: var(--color-ink); }
|
|
418
|
+
.lin-purpose > span { color: var(--color-meta); }
|
|
419
|
+
.lin-detail dl { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 6px 10px; margin: 0; }
|
|
420
|
+
.lin-detail dt { padding-top: 2px; color: var(--color-meta); font-weight: 600; }
|
|
421
|
+
.lin-detail dd { display: flex; flex-wrap: wrap; align-items: center; gap: 3px 4px; min-width: 0; margin: 0; color: var(--color-muted); }
|
|
422
|
+
.lin-detail dd.lin-uses { display: grid; gap: 4px; color: var(--color-ink); font-size: 12px; line-height: 1.45; overflow-wrap: anywhere; }
|
|
423
|
+
.lin-use { display: block; }
|
|
424
|
+
.lin-use code { color: var(--color-muted); font: 11.5px var(--font-mono); }
|
|
425
|
+
.lin-use-means { color: var(--color-ink); }
|
|
426
|
+
.lin-chip { max-width: 100%; min-width: 0; min-height: 0; padding: 1px 7px; text-align: left; overflow: hidden; border: 1px solid var(--color-hairline); border-radius: 999px; background: var(--color-well); box-shadow: none; color: var(--color-ink); font-size: 11.5px; text-overflow: ellipsis; white-space: nowrap; }
|
|
427
|
+
.lin-chip:hover { border-color: var(--color-accent); }
|
|
428
|
+
.lin-chip > span { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
429
|
+
.lin-chip.from { border-color: transparent; background: var(--color-hue-sky); color: var(--color-hue-sky-ink); }
|
|
430
|
+
.lin-chip.into { border-color: transparent; background: var(--color-hue-clay); color: var(--color-hue-clay-ink); }
|
|
431
|
+
.lin-chip.chosen { border-color: var(--color-accent); }
|
|
432
|
+
.lin-code > summary { width: fit-content; color: var(--color-accent-strong); font-weight: 600; cursor: pointer; }
|
|
433
|
+
.lin-code[open] > summary { margin-bottom: 6px; }
|
|
434
|
+
.lin-code > .nb-code-block, .lin-code > pre { margin-top: 4px; }
|
|
435
|
+
.lin-who { color: var(--color-meta); }
|
|
436
|
+
.lin-stale { color: var(--color-amber-text); }
|
|
437
|
+
.lin-others { display: flex; flex-wrap: wrap; align-items: center; gap: 3px 4px; }
|
|
438
|
+
/* Narrow, the chosen value is above the graph, and stays in view in a view of its own; the graph
|
|
439
|
+
names its values without how each is made. Wide, the chosen value sits beside the graph. */
|
|
440
|
+
@container (max-width: 639px) {
|
|
441
|
+
.lin-main.pinned > .lin-detail { position: sticky; top: 0; z-index: 2; max-height: 12rem; overflow-y: auto; box-shadow: 0 6px 14px -10px rgb(0 0 0 / 30%); }
|
|
442
|
+
.lin-detail { gap: 6px; padding: 8px 10px; }
|
|
443
|
+
.lin-main.pinned > .lin-detail.empty, .lin-detail.empty { position: static; flex-direction: row; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; padding: 0; border: 0; background: none; box-shadow: none; }
|
|
444
|
+
.lin-detail.empty > * { flex: 0 1 auto; }
|
|
445
|
+
.lin-detail.empty > p:last-child { font-size: 11.5px; }
|
|
446
|
+
.lin-node { max-width: 100%; }
|
|
447
|
+
.lin-title { -webkit-line-clamp: 3; }
|
|
448
|
+
}
|
|
449
|
+
@container (min-width: 640px) {
|
|
450
|
+
.lin-main { grid-template-columns: minmax(0, 1fr) minmax(240px, 34%); }
|
|
451
|
+
.lin-main > .lin-detail { grid-column: 2; grid-row: 1; }
|
|
452
|
+
.lin-main > .lin-canvas { grid-column: 1; grid-row: 1; }
|
|
453
|
+
.lin-main.pinned > .lin-detail { position: sticky; top: 8px; }
|
|
454
|
+
}
|
|
389
455
|
.flow-cell-plots { display: flex; flex-wrap: wrap; gap: 8px; }
|
|
390
456
|
.flow-cell-plots img { max-width: min(100%, 320px); height: auto; border: 1px solid var(--color-hairline); border-radius: 6px; background: #fff; }
|
|
457
|
+
.flow-inner { display: flex; flex-direction: column; gap: 8px; }
|
|
458
|
+
.flow-inner > summary { width: fit-content; color: var(--color-accent-strong); font-size: 12px; font-weight: 600; cursor: pointer; }
|
|
459
|
+
.flow-inner[open] > summary { margin-bottom: 6px; }
|
|
460
|
+
.nb-body > .flow-inner { padding-left: 12px; }
|
|
391
461
|
/* A value of a live session: where in it, what it is and when it was read, then its facts and a page of it. */
|
|
392
462
|
.ov { display: flex; flex-direction: column; gap: 12px; flex: 1; min-height: 0; overflow-y: auto; padding: 12px 14px 16px; container-type: inline-size; }
|
|
393
463
|
.ov.stale .ov-section, .ov.stale .ov-facts, .ov.stale .ov-value { opacity: .62; }
|
|
@@ -3,7 +3,7 @@ export { SessionPane, NotebookPage, VariablesPane, PlotsPane, Code, FormSwitch,
|
|
|
3
3
|
export { savedForm, saveForm } from './ui-notebook-form.js';
|
|
4
4
|
export { askCell } from './ui-notebook-target.js';
|
|
5
5
|
export { ServersPane, showOnServer } from './ui-servers.js';
|
|
6
|
-
export { FlowPane,
|
|
6
|
+
export { FlowPane, ScriptFlowView, lineageViewLimits, innerFlowLimits } from './ui-flow.js';
|
|
7
7
|
export { ObjectView, objectViewLimits } from './ui-object.js';
|
|
8
8
|
export { NotebookWorkSection, useNotebookWork, notebookWorkLimits, type NotebookWork } from './ui-notebook-work.js';
|
|
9
9
|
export { useLiveValues, liveValueLimits, type LiveSession, type LiveValues, type ValueLanguage } from './ui-values.js';
|
|
@@ -8,7 +8,7 @@ export { SessionPane, NotebookPage, VariablesPane, PlotsPane, Code, FormSwitch,
|
|
|
8
8
|
export { savedForm, saveForm } from './ui-notebook-form.js';
|
|
9
9
|
export { askCell } from './ui-notebook-target.js';
|
|
10
10
|
export { ServersPane, showOnServer } from './ui-servers.js';
|
|
11
|
-
export { FlowPane,
|
|
11
|
+
export { FlowPane, ScriptFlowView, lineageViewLimits, innerFlowLimits } from './ui-flow.js';
|
|
12
12
|
export { ObjectView, objectViewLimits } from './ui-object.js';
|
|
13
13
|
export { NotebookWorkSection, useNotebookWork, notebookWorkLimits } from './ui-notebook-work.js';
|
|
14
14
|
export { useLiveValues, liveValueLimits } from './ui-values.js';
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Language } from './explore-code.js';
|
|
2
|
+
import { type LineageCell } from './lineage.js';
|
|
3
|
+
import { type ScriptFlow } from './script-flow.js';
|
|
4
|
+
export type GraphKind = 'input' | 'value' | 'output' | 'plot';
|
|
5
|
+
export interface Making {
|
|
6
|
+
from: number;
|
|
7
|
+
to: number;
|
|
8
|
+
code: string;
|
|
9
|
+
cell?: {
|
|
10
|
+
cellId: string;
|
|
11
|
+
number: number;
|
|
12
|
+
label: string;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export interface GraphNode {
|
|
16
|
+
id: string;
|
|
17
|
+
kind: GraphKind;
|
|
18
|
+
name: string;
|
|
19
|
+
means?: string;
|
|
20
|
+
how: string;
|
|
21
|
+
made: Making[];
|
|
22
|
+
uses: string[];
|
|
23
|
+
parents: string[];
|
|
24
|
+
children: string[];
|
|
25
|
+
stale?: string[];
|
|
26
|
+
}
|
|
27
|
+
export interface ValueGraph {
|
|
28
|
+
nodes: Map<string, GraphNode>;
|
|
29
|
+
results: string[];
|
|
30
|
+
inputs: string[];
|
|
31
|
+
others: string[];
|
|
32
|
+
folded: Map<string, {
|
|
33
|
+
made: Making[];
|
|
34
|
+
means?: string;
|
|
35
|
+
}>;
|
|
36
|
+
quiet: number;
|
|
37
|
+
cut: number;
|
|
38
|
+
tooLong: boolean;
|
|
39
|
+
}
|
|
40
|
+
export declare function scriptGraph(flow: ScriptFlow, language: Language): ValueGraph;
|
|
41
|
+
export interface SessionCell extends LineageCell {
|
|
42
|
+
language: Language;
|
|
43
|
+
}
|
|
44
|
+
export declare function sessionGraph(cells: SessionCell[], values: Array<{
|
|
45
|
+
name: string;
|
|
46
|
+
type?: string;
|
|
47
|
+
}>, language: Language): ValueGraph & {
|
|
48
|
+
omitted: {
|
|
49
|
+
values: number;
|
|
50
|
+
plots: number;
|
|
51
|
+
files: number;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
export declare function graphPath(graph: ValueGraph, id: string): {
|
|
55
|
+
up: Set<string>;
|
|
56
|
+
down: Set<string>;
|
|
57
|
+
};
|
|
58
|
+
export declare function graphRows(graph: ValueGraph, shown: Set<string>): string[][];
|
|
59
|
+
export type MarkKind = 'here' | 'from' | 'into';
|
|
60
|
+
export declare function graphMarks(graph: ValueGraph, id: string): Array<Making & {
|
|
61
|
+
kind: MarkKind;
|
|
62
|
+
}>;
|
|
63
|
+
export declare function graphNodeAt(graph: ValueGraph, line: number, cellId?: string): GraphNode | null;
|