@go-go-golems/os-scripting 0.1.0
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 +147 -0
- package/app/createAppStore.d.ts +89 -0
- package/app/createAppStore.js +90 -0
- package/app/index.d.ts +2 -0
- package/app/index.js +2 -0
- package/app/runtimeSessionLifecycleMiddleware.d.ts +6 -0
- package/app/runtimeSessionLifecycleMiddleware.js +42 -0
- package/features/runtimeSessions/capabilityPolicy.d.ts +12 -0
- package/features/runtimeSessions/capabilityPolicy.js +36 -0
- package/features/runtimeSessions/index.d.ts +3 -0
- package/features/runtimeSessions/index.js +3 -0
- package/features/runtimeSessions/runtimeSessionsSlice.d.ts +90 -0
- package/features/runtimeSessions/runtimeSessionsSlice.js +210 -0
- package/features/runtimeSessions/selectors.d.ts +16 -0
- package/features/runtimeSessions/selectors.js +40 -0
- package/hypercard/artifacts/artifactProjectionMiddleware.d.ts +1 -0
- package/hypercard/artifacts/artifactProjectionMiddleware.js +66 -0
- package/hypercard/artifacts/artifactRuntime.d.ts +22 -0
- package/hypercard/artifacts/artifactRuntime.js +137 -0
- package/hypercard/artifacts/artifactsSelectors.d.ts +10 -0
- package/hypercard/artifacts/artifactsSelectors.js +2 -0
- package/hypercard/artifacts/artifactsSlice.d.ts +38 -0
- package/hypercard/artifacts/artifactsSlice.js +94 -0
- package/hypercard/debug/RuntimeSurfaceDebugWindow.d.ts +7 -0
- package/hypercard/debug/RuntimeSurfaceDebugWindow.js +181 -0
- package/hypercard/debug/jsSessionDebugRegistry.d.ts +11 -0
- package/hypercard/debug/jsSessionDebugRegistry.js +43 -0
- package/hypercard/debug/runtimeDebugApp.d.ts +19 -0
- package/hypercard/debug/runtimeDebugApp.js +25 -0
- package/hypercard/debug/runtimeDebugRegistry.d.ts +6 -0
- package/hypercard/debug/runtimeDebugRegistry.js +49 -0
- package/hypercard/editor/CodeEditorWindow.d.ts +7 -0
- package/hypercard/editor/CodeEditorWindow.js +128 -0
- package/hypercard/editor/editorLaunch.d.ts +16 -0
- package/hypercard/editor/editorLaunch.js +58 -0
- package/hypercard/editor/runtimeSurfaceRef.d.ts +8 -0
- package/hypercard/editor/runtimeSurfaceRef.js +60 -0
- package/hypercard/index.d.ts +12 -0
- package/hypercard/index.js +12 -0
- package/hypercard/task-manager/TaskManagerWindow.d.ts +1 -0
- package/hypercard/task-manager/TaskManagerWindow.js +102 -0
- package/hypercard/task-manager/index.d.ts +6 -0
- package/hypercard/task-manager/index.js +6 -0
- package/hypercard/task-manager/jsSessionSource.d.ts +10 -0
- package/hypercard/task-manager/jsSessionSource.js +49 -0
- package/hypercard/task-manager/runtimeSessionSource.d.ts +26 -0
- package/hypercard/task-manager/runtimeSessionSource.js +123 -0
- package/hypercard/task-manager/taskManagerApp.d.ts +16 -0
- package/hypercard/task-manager/taskManagerApp.js +25 -0
- package/hypercard/task-manager/taskManagerRegistry.d.ts +10 -0
- package/hypercard/task-manager/taskManagerRegistry.js +75 -0
- package/hypercard/task-manager/types.d.ts +25 -0
- package/hypercard/task-manager/types.js +1 -0
- package/hypercard/timeline/hypercardCard.d.ts +5 -0
- package/hypercard/timeline/hypercardCard.js +104 -0
- package/index.d.ts +18 -0
- package/index.js +18 -0
- package/package.json +72 -0
- package/plugin-runtime/contracts.d.ts +116 -0
- package/plugin-runtime/contracts.js +32 -0
- package/plugin-runtime/fixtures/column-stack.vm.js +19 -0
- package/plugin-runtime/fixtures/dynamic-card.vm.js +13 -0
- package/plugin-runtime/fixtures/inventory-stack.vm.js +29 -0
- package/plugin-runtime/fixtures/kanban-card.vm.js +55 -0
- package/plugin-runtime/fixtures/loop-stack.vm.js +16 -0
- package/plugin-runtime/fixtures/patched-low-stock-handler.vm.js +3 -0
- package/plugin-runtime/fixtures/patched-low-stock-render.vm.js +5 -0
- package/plugin-runtime/index.d.ts +6 -0
- package/plugin-runtime/index.js +6 -0
- package/plugin-runtime/intentSchema.d.ts +3 -0
- package/plugin-runtime/intentSchema.js +25 -0
- package/plugin-runtime/jsEvalSupport.d.ts +6 -0
- package/plugin-runtime/jsEvalSupport.js +93 -0
- package/plugin-runtime/jsSessionService.d.ts +55 -0
- package/plugin-runtime/jsSessionService.js +136 -0
- package/plugin-runtime/quickJsSessionCore.d.ts +24 -0
- package/plugin-runtime/quickJsSessionCore.js +92 -0
- package/plugin-runtime/runtimeService.d.ts +34 -0
- package/plugin-runtime/runtimeService.js +248 -0
- package/plugin-runtime/runtimeSurfaceRegistry.d.ts +45 -0
- package/plugin-runtime/runtimeSurfaceRegistry.js +73 -0
- package/plugin-runtime/stack-bootstrap.vm.js +236 -0
- package/repl/attachedJsSessionRegistry.d.ts +25 -0
- package/repl/attachedJsSessionRegistry.js +81 -0
- package/repl/attachedRuntimeSessionRegistry.d.ts +11 -0
- package/repl/attachedRuntimeSessionRegistry.js +107 -0
- package/repl/hypercardReplDriver.d.ts +54 -0
- package/repl/hypercardReplDriver.js +600 -0
- package/repl/jsReplDriver.d.ts +8 -0
- package/repl/jsReplDriver.js +348 -0
- package/repl/jsSessionBroker.d.ts +21 -0
- package/repl/jsSessionBroker.js +75 -0
- package/repl/runtimeBroker.d.ts +43 -0
- package/repl/runtimeBroker.js +117 -0
- package/runtime-host/RuntimeSurfaceSessionHost.d.ts +8 -0
- package/runtime-host/RuntimeSurfaceSessionHost.js +384 -0
- package/runtime-host/fixtures/CardSessionHost.chat.vm.js +61 -0
- package/runtime-host/fixtures/CardSessionHost.list.vm.js +29 -0
- package/runtime-host/fixtures/CardSessionHost.nav.vm.js +101 -0
- package/runtime-host/fixtures/CardSessionHost.report.vm.js +34 -0
- package/runtime-host/pluginIntentRouting.d.ts +13 -0
- package/runtime-host/pluginIntentRouting.js +83 -0
- package/runtime-packages/index.d.ts +1 -0
- package/runtime-packages/index.js +1 -0
- package/runtime-packages/runtimePackageRegistry.d.ts +14 -0
- package/runtime-packages/runtimePackageRegistry.js +42 -0
- package/runtime-packages/ui.package.vm.js +84 -0
- package/runtime-packs/index.d.ts +1 -0
- package/runtime-packs/index.js +1 -0
- package/runtime-packs/runtimeSurfaceTypeRegistry.d.ts +20 -0
- package/runtime-packs/runtimeSurfaceTypeRegistry.js +37 -0
- package/runtime-session-manager/index.d.ts +2 -0
- package/runtime-session-manager/index.js +2 -0
- package/runtime-session-manager/runtimeOwnership.d.ts +10 -0
- package/runtime-session-manager/runtimeOwnership.js +19 -0
- package/runtime-session-manager/runtimeSessionManager.d.ts +47 -0
- package/runtime-session-manager/runtimeSessionManager.js +214 -0
- package/testRuntimeUi.d.ts +4 -0
- package/testRuntimeUi.js +39 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from './artifacts/artifactRuntime';
|
|
2
|
+
export * from './artifacts/artifactsSelectors';
|
|
3
|
+
export * from './artifacts/artifactsSlice';
|
|
4
|
+
export * from './debug/RuntimeSurfaceDebugWindow';
|
|
5
|
+
export * from './debug/runtimeDebugApp';
|
|
6
|
+
export * from './debug/runtimeDebugRegistry';
|
|
7
|
+
export * from './debug/jsSessionDebugRegistry';
|
|
8
|
+
export * from './editor/CodeEditorWindow';
|
|
9
|
+
export * from './editor/editorLaunch';
|
|
10
|
+
export * from './editor/runtimeSurfaceRef';
|
|
11
|
+
export * from './task-manager';
|
|
12
|
+
export * from './timeline/hypercardCard';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function TaskManagerWindow(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useState } from 'react';
|
|
3
|
+
import { invokeTaskManagerAction, useRegisteredTaskManagerSources, useTaskManagerRows, } from './taskManagerRegistry';
|
|
4
|
+
function normalize(text) {
|
|
5
|
+
return typeof text === 'string' ? text.trim().toLowerCase() : '';
|
|
6
|
+
}
|
|
7
|
+
function matchesText(value, query) {
|
|
8
|
+
if (!query) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
return normalize(value).includes(query);
|
|
12
|
+
}
|
|
13
|
+
function detailSummary(details) {
|
|
14
|
+
if (!details) {
|
|
15
|
+
return '—';
|
|
16
|
+
}
|
|
17
|
+
const entries = Object.entries(details).filter(([, value]) => value && value !== '—');
|
|
18
|
+
if (entries.length === 0) {
|
|
19
|
+
return '—';
|
|
20
|
+
}
|
|
21
|
+
return entries.map(([key, value]) => `${key}: ${value}`).join(' · ');
|
|
22
|
+
}
|
|
23
|
+
export function TaskManagerWindow() {
|
|
24
|
+
const sources = useRegisteredTaskManagerSources();
|
|
25
|
+
const rows = useTaskManagerRows();
|
|
26
|
+
const [query, setQuery] = useState('');
|
|
27
|
+
const [kindFilter, setKindFilter] = useState('all');
|
|
28
|
+
const [statusFilter, setStatusFilter] = useState('all');
|
|
29
|
+
const [busyAction, setBusyAction] = useState(null);
|
|
30
|
+
const [error, setError] = useState(null);
|
|
31
|
+
const normalizedQuery = normalize(query);
|
|
32
|
+
const availableKinds = useMemo(() => Array.from(new Set(rows.map((row) => row.kind))).sort(), [rows]);
|
|
33
|
+
const availableStatuses = useMemo(() => Array.from(new Set(rows.map((row) => row.status))).sort(), [rows]);
|
|
34
|
+
const filteredRows = useMemo(() => rows.filter((row) => {
|
|
35
|
+
if (kindFilter !== 'all' && row.kind !== kindFilter) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
if (statusFilter !== 'all' && row.status !== statusFilter) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
if (!normalizedQuery) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
return (matchesText(row.title, normalizedQuery) ||
|
|
45
|
+
matchesText(row.kind, normalizedQuery) ||
|
|
46
|
+
matchesText(row.status, normalizedQuery) ||
|
|
47
|
+
matchesText(row.sourceTitle, normalizedQuery) ||
|
|
48
|
+
Object.values(row.details ?? {}).some((value) => matchesText(value, normalizedQuery)));
|
|
49
|
+
}), [rows, kindFilter, statusFilter, normalizedQuery]);
|
|
50
|
+
const summary = useMemo(() => {
|
|
51
|
+
const byKind = rows.reduce((acc, row) => {
|
|
52
|
+
acc[row.kind] = (acc[row.kind] ?? 0) + 1;
|
|
53
|
+
return acc;
|
|
54
|
+
}, {});
|
|
55
|
+
return Object.entries(byKind)
|
|
56
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
57
|
+
.map(([kind, count]) => `${kind}: ${count}`)
|
|
58
|
+
.join(' · ');
|
|
59
|
+
}, [rows]);
|
|
60
|
+
const td = {
|
|
61
|
+
padding: '4px 8px',
|
|
62
|
+
fontSize: 11,
|
|
63
|
+
borderBottom: '1px solid #ccc',
|
|
64
|
+
verticalAlign: 'top',
|
|
65
|
+
color: '#111',
|
|
66
|
+
};
|
|
67
|
+
const th = {
|
|
68
|
+
...td,
|
|
69
|
+
fontWeight: 700,
|
|
70
|
+
background: '#e8e8f0',
|
|
71
|
+
position: 'sticky',
|
|
72
|
+
top: 0,
|
|
73
|
+
};
|
|
74
|
+
async function handleAction(sourceId, rowId, actionId) {
|
|
75
|
+
const token = `${sourceId}:${rowId}:${actionId}`;
|
|
76
|
+
setBusyAction(token);
|
|
77
|
+
setError(null);
|
|
78
|
+
try {
|
|
79
|
+
await invokeTaskManagerAction(sourceId, rowId, actionId);
|
|
80
|
+
}
|
|
81
|
+
catch (cause) {
|
|
82
|
+
setError(cause instanceof Error ? cause.message : String(cause));
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
setBusyAction((current) => (current === token ? null : current));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return (_jsxs("div", { style: { padding: 12, fontFamily: 'monospace', fontSize: 12, color: '#111', overflow: 'auto', height: '100%' }, children: [_jsxs("div", { style: { display: 'grid', gap: 10, marginBottom: 12 }, children: [_jsxs("div", { style: { display: 'flex', justifyContent: 'space-between', gap: 12, alignItems: 'baseline', flexWrap: 'wrap' }, children: [_jsxs("div", { children: [_jsx("div", { style: { fontWeight: 700, fontSize: 14 }, children: "Task Manager" }), _jsxs("div", { style: { fontSize: 11, color: '#555' }, children: [sources.length, " sources \u00B7 ", rows.length, " rows", summary ? ` · ${summary}` : ''] })] }), _jsx("div", { style: { fontSize: 11, color: '#555' }, children: "Operator view for runtime sessions and broker-owned JS sessions" })] }), _jsxs("div", { style: { display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'end' }, children: [_jsxs("label", { style: { display: 'grid', gap: 4 }, children: [_jsx("span", { style: { fontSize: 11, color: '#555' }, children: "Search" }), _jsx("input", { value: query, onChange: (event) => setQuery(event.target.value), placeholder: "Search title, source, details...", style: { width: 260, padding: '4px 6px', fontFamily: 'inherit', fontSize: 12 } })] }), _jsxs("label", { style: { display: 'grid', gap: 4 }, children: [_jsx("span", { style: { fontSize: 11, color: '#555' }, children: "Kind" }), _jsxs("select", { value: kindFilter, onChange: (event) => setKindFilter(event.target.value), style: { minWidth: 150, padding: '4px 6px', fontFamily: 'inherit', fontSize: 12 }, children: [_jsx("option", { value: "all", children: "All kinds" }), availableKinds.map((kind) => (_jsx("option", { value: kind, children: kind }, kind)))] })] }), _jsxs("label", { style: { display: 'grid', gap: 4 }, children: [_jsx("span", { style: { fontSize: 11, color: '#555' }, children: "Status" }), _jsxs("select", { value: statusFilter, onChange: (event) => setStatusFilter(event.target.value), style: { minWidth: 140, padding: '4px 6px', fontFamily: 'inherit', fontSize: 12 }, children: [_jsx("option", { value: "all", children: "All statuses" }), availableStatuses.map((status) => (_jsx("option", { value: status, children: status }, status)))] })] })] }), error ? (_jsx("div", { style: { padding: '6px 8px', border: '1px solid #c88', background: '#fff2f2', color: '#822' }, children: error })) : null] }), _jsxs("table", { style: { width: '100%', borderCollapse: 'collapse' }, children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { style: th, children: "Source" }), _jsx("th", { style: th, children: "Kind" }), _jsx("th", { style: th, children: "Title" }), _jsx("th", { style: th, children: "Status" }), _jsx("th", { style: th, children: "Started" }), _jsx("th", { style: th, children: "Details" }), _jsx("th", { style: th, children: "Actions" })] }) }), _jsxs("tbody", { children: [filteredRows.map((row) => (_jsxs("tr", { children: [_jsx("td", { style: td, children: row.sourceTitle }), _jsx("td", { style: td, children: _jsx("code", { children: row.kind }) }), _jsxs("td", { style: td, children: [_jsx("div", { children: row.title }), _jsx("div", { style: { fontSize: 10, color: '#666' }, children: _jsx("code", { children: row.id }) })] }), _jsx("td", { style: td, children: row.status }), _jsx("td", { style: td, children: row.startedAt ?? '—' }), _jsx("td", { style: td, children: detailSummary(row.details) }), _jsx("td", { style: td, children: _jsx("div", { style: { display: 'flex', gap: 6, flexWrap: 'wrap' }, children: row.actions.map((action) => {
|
|
89
|
+
const token = `${row.sourceId}:${row.id}:${action.id}`;
|
|
90
|
+
const busy = busyAction === token;
|
|
91
|
+
return (_jsx("button", { onClick: () => void handleAction(row.sourceId, row.id, action.id), disabled: busy, style: {
|
|
92
|
+
fontSize: 10,
|
|
93
|
+
padding: '1px 6px',
|
|
94
|
+
borderRadius: 3,
|
|
95
|
+
border: '1px solid #999',
|
|
96
|
+
background: busy ? '#ddd' : '#f0f0f0',
|
|
97
|
+
cursor: busy ? 'progress' : 'pointer',
|
|
98
|
+
}, children: busy ? '…' : action.label }, action.id));
|
|
99
|
+
}) }) })] }, `${row.sourceId}:${row.id}`))), filteredRows.length === 0 ? (_jsx("tr", { children: _jsx("td", { style: td, colSpan: 7, children: rows.length === 0
|
|
100
|
+
? 'No task-manager sources are registered yet.'
|
|
101
|
+
: 'No rows match the current search and filter settings.' }) })) : null] })] })] }));
|
|
102
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { JsSessionBroker } from '../../repl/jsSessionBroker';
|
|
2
|
+
import type { TaskManagerSource } from './types';
|
|
3
|
+
interface JsSessionTaskManagerSourceOptions {
|
|
4
|
+
sourceId: string;
|
|
5
|
+
sourceTitle: string;
|
|
6
|
+
broker: JsSessionBroker;
|
|
7
|
+
focusSession?: (sessionId: string) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function createJsSessionTaskManagerSource(options: JsSessionTaskManagerSourceOptions): TaskManagerSource;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export function createJsSessionTaskManagerSource(options) {
|
|
2
|
+
return {
|
|
3
|
+
sourceId() {
|
|
4
|
+
return options.sourceId;
|
|
5
|
+
},
|
|
6
|
+
title() {
|
|
7
|
+
return options.sourceTitle;
|
|
8
|
+
},
|
|
9
|
+
listRows() {
|
|
10
|
+
return options.broker.listSessions().map((session) => ({
|
|
11
|
+
id: session.sessionId,
|
|
12
|
+
kind: 'js-session',
|
|
13
|
+
sourceId: options.sourceId,
|
|
14
|
+
sourceTitle: options.sourceTitle,
|
|
15
|
+
title: session.title,
|
|
16
|
+
status: 'ready',
|
|
17
|
+
startedAt: session.createdAt,
|
|
18
|
+
details: {
|
|
19
|
+
ownership: 'broker-owned',
|
|
20
|
+
globals: String(session.globalNames.length),
|
|
21
|
+
globalsPreview: session.globalNames.slice(0, 6).join(', ') || '—',
|
|
22
|
+
},
|
|
23
|
+
actions: [
|
|
24
|
+
{ id: 'focus', label: 'Focus', intent: 'focus' },
|
|
25
|
+
{ id: 'reset', label: 'Reset', intent: 'reset' },
|
|
26
|
+
{ id: 'dispose', label: 'Dispose', intent: 'dispose' },
|
|
27
|
+
],
|
|
28
|
+
}));
|
|
29
|
+
},
|
|
30
|
+
async invoke(actionId, rowId) {
|
|
31
|
+
if (actionId === 'focus') {
|
|
32
|
+
options.focusSession?.(rowId);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (actionId === 'reset') {
|
|
36
|
+
await options.broker.resetSession(rowId);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (actionId === 'dispose') {
|
|
40
|
+
options.broker.disposeSession(rowId);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
throw new Error(`Unsupported JS session action: ${actionId}`);
|
|
44
|
+
},
|
|
45
|
+
subscribe(listener) {
|
|
46
|
+
return options.broker.subscribe(listener);
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { RuntimeBundleDefinition } from '@go-go-golems/os-core';
|
|
2
|
+
import type { TaskManagerSource } from './types';
|
|
3
|
+
import { type RuntimeSessionManager } from '../../runtime-session-manager';
|
|
4
|
+
interface RuntimeSessionTaskManagerState {
|
|
5
|
+
windowing?: {
|
|
6
|
+
sessions: Record<string, {
|
|
7
|
+
nav?: Array<{
|
|
8
|
+
surface?: string;
|
|
9
|
+
param?: string;
|
|
10
|
+
}>;
|
|
11
|
+
}>;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
interface RuntimeSessionTaskManagerSourceOptions {
|
|
15
|
+
sourceId?: string;
|
|
16
|
+
sourceTitle?: string;
|
|
17
|
+
getState: () => RuntimeSessionTaskManagerState;
|
|
18
|
+
dispatch: (action: unknown) => void;
|
|
19
|
+
bundles: RuntimeBundleDefinition[];
|
|
20
|
+
ownerAppId: string;
|
|
21
|
+
focusJsConsole?: (sessionId: string) => void;
|
|
22
|
+
subscribe: (listener: () => void) => () => void;
|
|
23
|
+
manager?: RuntimeSessionManager;
|
|
24
|
+
}
|
|
25
|
+
export declare function createRuntimeSessionTaskManagerSource(options: RuntimeSessionTaskManagerSourceOptions): TaskManagerSource;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { openWindow } from '@go-go-golems/os-core/desktop-core';
|
|
2
|
+
import { buildRuntimeDebugWindowPayload } from '../debug/runtimeDebugApp';
|
|
3
|
+
import { DEFAULT_RUNTIME_SESSION_MANAGER, } from '../../runtime-session-manager';
|
|
4
|
+
function buildBundleSurfaceWindowPayload(bundle, surfaceId, param) {
|
|
5
|
+
const surface = bundle.surfaces[surfaceId];
|
|
6
|
+
if (!surface) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
const sessionId = typeof globalThis.crypto?.randomUUID === 'function'
|
|
10
|
+
? `task-manager:${bundle.id}:${surfaceId}:${globalThis.crypto.randomUUID()}`
|
|
11
|
+
: `task-manager:${bundle.id}:${surfaceId}:${Date.now()}`;
|
|
12
|
+
return {
|
|
13
|
+
id: `window:task-manager:${bundle.id}:${surfaceId}:${sessionId}`,
|
|
14
|
+
title: surface.title ?? surfaceId,
|
|
15
|
+
icon: surface.icon ?? '📄',
|
|
16
|
+
bounds: { x: 180, y: 56, w: 960, h: 700 },
|
|
17
|
+
content: {
|
|
18
|
+
kind: 'surface',
|
|
19
|
+
surface: {
|
|
20
|
+
bundleId: bundle.id,
|
|
21
|
+
surfaceId,
|
|
22
|
+
surfaceSessionId: sessionId,
|
|
23
|
+
param,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
dedupeKey: `task-surface:${bundle.id}:${surfaceId}:${param ?? ''}`,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function currentSurfaceForSession(session, navSessions) {
|
|
30
|
+
const nav = navSessions?.sessions?.[session.sessionId]?.nav;
|
|
31
|
+
if (Array.isArray(nav) && nav.length > 0) {
|
|
32
|
+
const current = nav[nav.length - 1];
|
|
33
|
+
if (typeof current?.surface === 'string') {
|
|
34
|
+
return { surfaceId: current.surface, param: current.param };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return { surfaceId: session.surfaces[0] ?? null };
|
|
38
|
+
}
|
|
39
|
+
export function createRuntimeSessionTaskManagerSource(options) {
|
|
40
|
+
const bundlesById = new Map(options.bundles.map((bundle) => [bundle.id, bundle]));
|
|
41
|
+
const sourceId = options.sourceId ?? 'runtime-sessions';
|
|
42
|
+
const sourceTitle = options.sourceTitle ?? 'Runtime Sessions';
|
|
43
|
+
const manager = options.manager ?? DEFAULT_RUNTIME_SESSION_MANAGER;
|
|
44
|
+
return {
|
|
45
|
+
sourceId() {
|
|
46
|
+
return sourceId;
|
|
47
|
+
},
|
|
48
|
+
title() {
|
|
49
|
+
return sourceTitle;
|
|
50
|
+
},
|
|
51
|
+
listRows() {
|
|
52
|
+
const state = options.getState();
|
|
53
|
+
const windowing = state.windowing;
|
|
54
|
+
return manager.listSessions().map((session) => {
|
|
55
|
+
const bundle = bundlesById.get(session.bundleId);
|
|
56
|
+
const currentSurface = currentSurfaceForSession(session, windowing);
|
|
57
|
+
return {
|
|
58
|
+
id: session.sessionId,
|
|
59
|
+
kind: 'runtime-session',
|
|
60
|
+
sourceId,
|
|
61
|
+
sourceTitle,
|
|
62
|
+
title: `${bundle?.name ?? session.bundleId}${currentSurface.surfaceId ? ` · ${currentSurface.surfaceId}` : ''}`,
|
|
63
|
+
status: session.status,
|
|
64
|
+
details: {
|
|
65
|
+
bundleId: session.bundleId,
|
|
66
|
+
bundleName: bundle?.name ?? session.bundleId,
|
|
67
|
+
ownership: session.ownership.kind,
|
|
68
|
+
currentSurface: currentSurface.surfaceId ?? '—',
|
|
69
|
+
surfaceCount: String(session.surfaces.length),
|
|
70
|
+
attachedViews: String(session.attachedViewIds.length),
|
|
71
|
+
},
|
|
72
|
+
actions: [
|
|
73
|
+
{ id: 'open', label: 'Open', intent: 'open' },
|
|
74
|
+
{ id: 'js-console', label: 'JS Console', intent: 'custom' },
|
|
75
|
+
{ id: 'inspect', label: 'Inspect', intent: 'inspect' },
|
|
76
|
+
],
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
},
|
|
80
|
+
invoke(actionId, rowId) {
|
|
81
|
+
const state = options.getState();
|
|
82
|
+
const session = manager.listSessions().find((entry) => entry.sessionId === rowId);
|
|
83
|
+
if (!session) {
|
|
84
|
+
throw new Error(`Unknown runtime session: ${rowId}`);
|
|
85
|
+
}
|
|
86
|
+
if (actionId === 'inspect') {
|
|
87
|
+
options.dispatch(openWindow(buildRuntimeDebugWindowPayload({
|
|
88
|
+
appId: options.ownerAppId,
|
|
89
|
+
})));
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (actionId === 'js-console') {
|
|
93
|
+
options.focusJsConsole?.(rowId);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (actionId === 'open') {
|
|
97
|
+
const bundle = bundlesById.get(session.bundleId);
|
|
98
|
+
if (!bundle) {
|
|
99
|
+
throw new Error(`Unknown runtime bundle: ${session.bundleId}`);
|
|
100
|
+
}
|
|
101
|
+
const currentSurface = currentSurfaceForSession(session, state.windowing);
|
|
102
|
+
if (!currentSurface.surfaceId) {
|
|
103
|
+
throw new Error(`Runtime session has no active surface: ${rowId}`);
|
|
104
|
+
}
|
|
105
|
+
const payload = buildBundleSurfaceWindowPayload(bundle, currentSurface.surfaceId, currentSurface.param);
|
|
106
|
+
if (!payload) {
|
|
107
|
+
throw new Error(`Unknown runtime surface: ${session.bundleId}:${currentSurface.surfaceId}`);
|
|
108
|
+
}
|
|
109
|
+
options.dispatch(openWindow(payload));
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
throw new Error(`Unsupported runtime session action: ${actionId}`);
|
|
113
|
+
},
|
|
114
|
+
subscribe(listener) {
|
|
115
|
+
const unregisterStore = options.subscribe(listener);
|
|
116
|
+
const unregisterManager = manager.subscribe(listener);
|
|
117
|
+
return () => {
|
|
118
|
+
unregisterManager();
|
|
119
|
+
unregisterStore();
|
|
120
|
+
};
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { OpenWindowPayload } from '@go-go-golems/os-core/desktop-core';
|
|
2
|
+
export declare const HYPERCARD_TASK_MANAGER_APP_ID = "hypercard-task-manager";
|
|
3
|
+
export declare const HYPERCARD_TASK_MANAGER_INSTANCE_ID = "tasks";
|
|
4
|
+
export interface BuildTaskManagerWindowPayloadOptions {
|
|
5
|
+
appId?: string;
|
|
6
|
+
instanceId?: string;
|
|
7
|
+
title?: string;
|
|
8
|
+
icon?: string;
|
|
9
|
+
bounds?: OpenWindowPayload['bounds'];
|
|
10
|
+
dedupeKey?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface TaskManagerAppWindowProps {
|
|
13
|
+
instanceId: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function buildTaskManagerWindowPayload(options?: BuildTaskManagerWindowPayloadOptions): OpenWindowPayload;
|
|
16
|
+
export declare function TaskManagerAppWindow({ instanceId }: TaskManagerAppWindowProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { TaskManagerWindow } from './TaskManagerWindow';
|
|
3
|
+
export const HYPERCARD_TASK_MANAGER_APP_ID = 'hypercard-task-manager';
|
|
4
|
+
export const HYPERCARD_TASK_MANAGER_INSTANCE_ID = 'tasks';
|
|
5
|
+
export function buildTaskManagerWindowPayload(options = {}) {
|
|
6
|
+
const appId = options.appId ?? HYPERCARD_TASK_MANAGER_APP_ID;
|
|
7
|
+
const instanceId = options.instanceId ?? HYPERCARD_TASK_MANAGER_INSTANCE_ID;
|
|
8
|
+
return {
|
|
9
|
+
id: `window:${appId}:${instanceId}`,
|
|
10
|
+
title: options.title ?? 'Task Manager',
|
|
11
|
+
icon: options.icon ?? '🗂️',
|
|
12
|
+
bounds: options.bounds ?? { x: 120, y: 52, w: 860, h: 520 },
|
|
13
|
+
content: {
|
|
14
|
+
kind: 'app',
|
|
15
|
+
appKey: `${appId}:${instanceId}`,
|
|
16
|
+
},
|
|
17
|
+
dedupeKey: options.dedupeKey ?? `${appId}:${instanceId}`,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function TaskManagerAppWindow({ instanceId }) {
|
|
21
|
+
if (instanceId !== HYPERCARD_TASK_MANAGER_INSTANCE_ID) {
|
|
22
|
+
return (_jsxs("section", { style: { padding: 12, display: 'grid', gap: 8 }, children: [_jsx("strong", { children: "Task Manager" }), _jsxs("span", { children: ["Unknown task manager window instance: ", instanceId] })] }));
|
|
23
|
+
}
|
|
24
|
+
return _jsx(TaskManagerWindow, {});
|
|
25
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TaskManagerRow, TaskManagerSource } from './types';
|
|
2
|
+
export declare function registerTaskManagerSource(source: TaskManagerSource): void;
|
|
3
|
+
export declare function unregisterTaskManagerSource(sourceId: string): void;
|
|
4
|
+
export declare function clearTaskManagerSources(): void;
|
|
5
|
+
export declare function listTaskManagerSources(): TaskManagerSource[];
|
|
6
|
+
export declare function listTaskManagerRows(): TaskManagerRow[];
|
|
7
|
+
export declare function invokeTaskManagerAction(sourceId: string, rowId: string, actionId: string): Promise<void>;
|
|
8
|
+
export declare function subscribeTaskManagerSources(listener: () => void): () => void;
|
|
9
|
+
export declare function useRegisteredTaskManagerSources(): TaskManagerSource[];
|
|
10
|
+
export declare function useTaskManagerRows(): TaskManagerRow[];
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { useSyncExternalStore } from 'react';
|
|
2
|
+
const registeredSources = new Map();
|
|
3
|
+
const listeners = new Set();
|
|
4
|
+
let registeredSourcesSnapshot = [];
|
|
5
|
+
let registeredRowsSnapshot = [];
|
|
6
|
+
const sourceUnsubscribes = new Map();
|
|
7
|
+
function refreshSnapshots() {
|
|
8
|
+
registeredSourcesSnapshot = Array.from(registeredSources.values());
|
|
9
|
+
registeredRowsSnapshot = registeredSourcesSnapshot.flatMap((source) => source.listRows());
|
|
10
|
+
}
|
|
11
|
+
function emitChange() {
|
|
12
|
+
for (const listener of listeners) {
|
|
13
|
+
listener();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function refreshAndEmit() {
|
|
17
|
+
refreshSnapshots();
|
|
18
|
+
emitChange();
|
|
19
|
+
}
|
|
20
|
+
export function registerTaskManagerSource(source) {
|
|
21
|
+
const sourceId = source?.sourceId?.();
|
|
22
|
+
if (!sourceId) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (registeredSources.get(sourceId) === source) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
sourceUnsubscribes.get(sourceId)?.();
|
|
29
|
+
registeredSources.set(sourceId, source);
|
|
30
|
+
sourceUnsubscribes.set(sourceId, source.subscribe(refreshAndEmit));
|
|
31
|
+
refreshAndEmit();
|
|
32
|
+
}
|
|
33
|
+
export function unregisterTaskManagerSource(sourceId) {
|
|
34
|
+
if (!registeredSources.has(sourceId)) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
sourceUnsubscribes.get(sourceId)?.();
|
|
38
|
+
sourceUnsubscribes.delete(sourceId);
|
|
39
|
+
registeredSources.delete(sourceId);
|
|
40
|
+
refreshAndEmit();
|
|
41
|
+
}
|
|
42
|
+
export function clearTaskManagerSources() {
|
|
43
|
+
if (registeredSources.size === 0) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
sourceUnsubscribes.forEach((unsubscribe) => unsubscribe());
|
|
47
|
+
sourceUnsubscribes.clear();
|
|
48
|
+
registeredSources.clear();
|
|
49
|
+
refreshAndEmit();
|
|
50
|
+
}
|
|
51
|
+
export function listTaskManagerSources() {
|
|
52
|
+
return registeredSourcesSnapshot;
|
|
53
|
+
}
|
|
54
|
+
export function listTaskManagerRows() {
|
|
55
|
+
return registeredRowsSnapshot;
|
|
56
|
+
}
|
|
57
|
+
export async function invokeTaskManagerAction(sourceId, rowId, actionId) {
|
|
58
|
+
const source = registeredSources.get(sourceId);
|
|
59
|
+
if (!source) {
|
|
60
|
+
throw new Error(`Unknown task manager source: ${sourceId}`);
|
|
61
|
+
}
|
|
62
|
+
await source.invoke(actionId, rowId);
|
|
63
|
+
}
|
|
64
|
+
export function subscribeTaskManagerSources(listener) {
|
|
65
|
+
listeners.add(listener);
|
|
66
|
+
return () => {
|
|
67
|
+
listeners.delete(listener);
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export function useRegisteredTaskManagerSources() {
|
|
71
|
+
return useSyncExternalStore(subscribeTaskManagerSources, listTaskManagerSources, listTaskManagerSources);
|
|
72
|
+
}
|
|
73
|
+
export function useTaskManagerRows() {
|
|
74
|
+
return useSyncExternalStore(subscribeTaskManagerSources, listTaskManagerRows, listTaskManagerRows);
|
|
75
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface TaskManagerAction {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
intent: 'open' | 'focus' | 'inspect' | 'reset' | 'dispose' | 'terminate' | 'custom';
|
|
5
|
+
}
|
|
6
|
+
export interface TaskManagerRow {
|
|
7
|
+
id: string;
|
|
8
|
+
kind: string;
|
|
9
|
+
sourceId: string;
|
|
10
|
+
sourceTitle: string;
|
|
11
|
+
title: string;
|
|
12
|
+
status: string;
|
|
13
|
+
startedAt?: string;
|
|
14
|
+
updatedAt?: string;
|
|
15
|
+
tags?: string[];
|
|
16
|
+
details?: Record<string, string>;
|
|
17
|
+
actions: TaskManagerAction[];
|
|
18
|
+
}
|
|
19
|
+
export interface TaskManagerSource {
|
|
20
|
+
sourceId(): string;
|
|
21
|
+
title(): string;
|
|
22
|
+
listRows(): TaskManagerRow[];
|
|
23
|
+
invoke(actionId: string, rowId: string): Promise<void> | void;
|
|
24
|
+
subscribe(listener: () => void): () => void;
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useDispatch } from 'react-redux';
|
|
3
|
+
import { SyntaxHighlight, recordField, stringField } from '@go-go-golems/os-chat';
|
|
4
|
+
import { openWindow } from '@go-go-golems/os-core/desktop-core';
|
|
5
|
+
import { buildArtifactOpenWindowPayload, normalizeArtifactId } from '../artifacts/artifactRuntime';
|
|
6
|
+
import { openCodeEditor } from '../editor/editorLaunch';
|
|
7
|
+
function artifactPayload(props) {
|
|
8
|
+
return recordField(props, 'result') ?? props;
|
|
9
|
+
}
|
|
10
|
+
function artifactData(props) {
|
|
11
|
+
return recordField(artifactPayload(props) ?? {}, 'data');
|
|
12
|
+
}
|
|
13
|
+
function artifactIdFromCardArtifact(props) {
|
|
14
|
+
const payload = artifactPayload(props);
|
|
15
|
+
const payloadData = artifactData(props);
|
|
16
|
+
const artifact = recordField(payload ?? {}, 'artifact') ??
|
|
17
|
+
recordField(payloadData ?? {}, 'artifact');
|
|
18
|
+
return stringField(props, 'artifactId') ?? stringField(artifact ?? {}, 'id') ?? '';
|
|
19
|
+
}
|
|
20
|
+
function runtimeSurfaceId(props) {
|
|
21
|
+
const payload = artifactPayload(props);
|
|
22
|
+
const payloadData = artifactData(props);
|
|
23
|
+
const card = recordField(payload ?? {}, 'card') ??
|
|
24
|
+
recordField(payloadData ?? {}, 'card');
|
|
25
|
+
return stringField(props, 'runtimeSurfaceId') ?? stringField(card ?? {}, 'id') ?? '';
|
|
26
|
+
}
|
|
27
|
+
function runtimeSurfaceCode(props) {
|
|
28
|
+
const payload = artifactPayload(props);
|
|
29
|
+
const payloadData = artifactData(props);
|
|
30
|
+
const card = recordField(payload ?? {}, 'card') ??
|
|
31
|
+
recordField(payloadData ?? {}, 'card');
|
|
32
|
+
return stringField(props, 'runtimeSurfaceCode') ?? stringField(card ?? {}, 'code') ?? '';
|
|
33
|
+
}
|
|
34
|
+
function runtimeSurfacePackId(props) {
|
|
35
|
+
const payload = artifactPayload(props);
|
|
36
|
+
const payloadData = artifactData(props);
|
|
37
|
+
const runtime = recordField(payload ?? {}, 'runtime') ??
|
|
38
|
+
recordField(payloadData ?? {}, 'runtime');
|
|
39
|
+
return stringField(props, 'packId') ?? stringField(runtime ?? {}, 'pack') ?? '';
|
|
40
|
+
}
|
|
41
|
+
function titleFromArtifactCard(props) {
|
|
42
|
+
const payload = artifactPayload(props);
|
|
43
|
+
return (stringField(props, 'title') ??
|
|
44
|
+
stringField(props, 'name') ??
|
|
45
|
+
stringField(payload ?? {}, 'title') ??
|
|
46
|
+
stringField(payload ?? {}, 'name') ??
|
|
47
|
+
'Card') ??
|
|
48
|
+
'Card';
|
|
49
|
+
}
|
|
50
|
+
function detailFromArtifactCard(props) {
|
|
51
|
+
const payload = artifactPayload(props);
|
|
52
|
+
const error = stringField(props, 'error') ?? stringField(payload ?? {}, 'error') ?? '';
|
|
53
|
+
if (error) {
|
|
54
|
+
return { status: 'error', detail: error };
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
status: stringField(props, 'status') ?? 'success',
|
|
58
|
+
detail: stringField(props, 'detail') ?? 'ready',
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export function HypercardCardRenderer({ e, ctx }) {
|
|
62
|
+
const dispatch = useDispatch();
|
|
63
|
+
const props = e.props;
|
|
64
|
+
const title = titleFromArtifactCard(props);
|
|
65
|
+
const { status, detail } = detailFromArtifactCard(props);
|
|
66
|
+
const artifactId = artifactIdFromCardArtifact(props);
|
|
67
|
+
const surfaceId = runtimeSurfaceId(props);
|
|
68
|
+
const surfaceCode = runtimeSurfaceCode(props);
|
|
69
|
+
const surfacePackId = runtimeSurfacePackId(props);
|
|
70
|
+
const bundleId = props.stackId ? String(props.stackId) : undefined;
|
|
71
|
+
const hasRuntimeSurface = surfaceId.trim().length > 0;
|
|
72
|
+
const hasSurfaceCode = surfaceCode.trim().length > 0;
|
|
73
|
+
const hasSurfacePackId = surfacePackId.trim().length > 0;
|
|
74
|
+
const canOpenArtifact = Boolean(normalizeArtifactId(artifactId) &&
|
|
75
|
+
hasRuntimeSurface &&
|
|
76
|
+
hasSurfacePackId &&
|
|
77
|
+
status !== 'streaming' &&
|
|
78
|
+
status !== 'pending');
|
|
79
|
+
const canEditCode = hasRuntimeSurface && hasSurfaceCode && status !== 'streaming' && status !== 'pending';
|
|
80
|
+
const openArtifact = () => {
|
|
81
|
+
const payload = buildArtifactOpenWindowPayload({
|
|
82
|
+
artifactId,
|
|
83
|
+
title,
|
|
84
|
+
runtimeSurfaceId: surfaceId,
|
|
85
|
+
bundleId,
|
|
86
|
+
});
|
|
87
|
+
if (!payload) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
dispatch(openWindow(payload));
|
|
91
|
+
};
|
|
92
|
+
const editArtifact = () => {
|
|
93
|
+
if (!hasRuntimeSurface || !hasSurfaceCode) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
openCodeEditor(dispatch, { ownerAppId: 'inventory', surfaceId }, surfaceCode, surfacePackId);
|
|
97
|
+
};
|
|
98
|
+
return (_jsxs("div", { "data-part": "chat-message", "data-role": "system", children: [_jsx("div", { "data-part": "chat-role", children: "Card:" }), _jsxs("div", { style: { fontSize: 11, whiteSpace: 'pre-wrap' }, children: [_jsx("strong", { children: title }), surfaceId ? ` · runtime=${surfaceId}` : '', detail ? ` — ${detail}` : ''] }), _jsxs("div", { style: { fontSize: 11, whiteSpace: 'pre-wrap', opacity: 0.8 }, children: ["status: ", status] }), hasSurfaceCode && (_jsx(SyntaxHighlight, { code: surfaceCode, language: "javascript", maxLines: 18, style: { marginTop: 6 } })), ctx?.mode === 'debug' && (_jsx("pre", { style: {
|
|
99
|
+
margin: '6px 0 0',
|
|
100
|
+
fontSize: 10,
|
|
101
|
+
whiteSpace: 'pre-wrap',
|
|
102
|
+
opacity: 0.9,
|
|
103
|
+
}, children: JSON.stringify(e.props, null, 2) })), (canOpenArtifact || canEditCode) && (_jsxs("div", { style: { marginTop: 4, display: 'flex', gap: 6 }, children: [canOpenArtifact && (_jsx("button", { type: "button", "data-part": "btn", onClick: openArtifact, children: "Open" })), canEditCode && (_jsx("button", { type: "button", "data-part": "btn", onClick: editArtifact, children: "Edit" }))] }))] }));
|
|
104
|
+
}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export * from './app';
|
|
2
|
+
export * from './plugin-runtime';
|
|
3
|
+
export * from './repl/hypercardReplDriver';
|
|
4
|
+
export * from './repl/attachedJsSessionRegistry';
|
|
5
|
+
export * from './repl/attachedRuntimeSessionRegistry';
|
|
6
|
+
export * from './repl/jsReplDriver';
|
|
7
|
+
export * from './repl/jsSessionBroker';
|
|
8
|
+
export * from './repl/runtimeBroker';
|
|
9
|
+
export * from './runtime-session-manager';
|
|
10
|
+
export * from './features/runtimeSessions';
|
|
11
|
+
export * from './hypercard';
|
|
12
|
+
export * from './hypercard/debug/runtimeDebugApp';
|
|
13
|
+
export * from './hypercard/debug/runtimeDebugRegistry';
|
|
14
|
+
export * from './hypercard/task-manager';
|
|
15
|
+
export * from './runtime-packs';
|
|
16
|
+
export * from './runtime-packages';
|
|
17
|
+
export { RuntimeSurfaceSessionHost, type RuntimeSurfaceSessionHostProps } from './runtime-host/RuntimeSurfaceSessionHost';
|
|
18
|
+
export { dispatchRuntimeAction } from './runtime-host/pluginIntentRouting';
|