@agimon-ai/doompi-workflow 0.0.1-alpha.73 → 0.0.1-alpha.76
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/LICENSE +4 -2
- package/README.md +8 -5
- package/package.json +19 -18
- package/src/types/webWorkflowTerminal.ts +7 -6
- package/dist/_virtual/_rolldown/runtime.cjs +0 -1
- package/dist/api-contracts.cjs +0 -1
- package/dist/api-contracts.d.cts +0 -2
- package/dist/api-contracts.d.mts +0 -2
- package/dist/api-contracts.mjs +0 -1
- package/dist/extensions/pi.cjs +0 -2
- package/dist/extensions/pi.cjs.map +0 -1
- package/dist/extensions/pi.d.cts +0 -6
- package/dist/extensions/pi.d.cts.map +0 -1
- package/dist/extensions/pi.d.mts +0 -6
- package/dist/extensions/pi.d.mts.map +0 -1
- package/dist/extensions/pi.mjs +0 -2
- package/dist/extensions/pi.mjs.map +0 -1
- package/dist/extensions/server.cjs +0 -2
- package/dist/extensions/server.cjs.map +0 -1
- package/dist/extensions/server.d.cts +0 -5
- package/dist/extensions/server.d.cts.map +0 -1
- package/dist/extensions/server.d.mts +0 -5
- package/dist/extensions/server.d.mts.map +0 -1
- package/dist/extensions/server.mjs +0 -2
- package/dist/extensions/server.mjs.map +0 -1
- package/dist/index.cjs +0 -1
- package/dist/index.d.cts +0 -2
- package/dist/index.d.mts +0 -2
- package/dist/index.mjs +0 -1
- package/dist/src/constants/workflow.cjs +0 -2
- package/dist/src/constants/workflow.cjs.map +0 -1
- package/dist/src/constants/workflow.mjs +0 -2
- package/dist/src/constants/workflow.mjs.map +0 -1
- package/dist/src/controllers/serverRuntime.cjs +0 -2
- package/dist/src/controllers/serverRuntime.cjs.map +0 -1
- package/dist/src/controllers/serverRuntime.mjs +0 -2
- package/dist/src/controllers/serverRuntime.mjs.map +0 -1
- package/dist/src/controllers/workflowCatalogChannel.cjs +0 -2
- package/dist/src/controllers/workflowCatalogChannel.cjs.map +0 -1
- package/dist/src/controllers/workflowCatalogChannel.mjs +0 -2
- package/dist/src/controllers/workflowCatalogChannel.mjs.map +0 -1
- package/dist/src/controllers/workflowHubApi.cjs +0 -2
- package/dist/src/controllers/workflowHubApi.cjs.map +0 -1
- package/dist/src/controllers/workflowHubApi.mjs +0 -2
- package/dist/src/controllers/workflowHubApi.mjs.map +0 -1
- package/dist/src/controllers/workflowsHubChannel.cjs +0 -2
- package/dist/src/controllers/workflowsHubChannel.cjs.map +0 -1
- package/dist/src/controllers/workflowsHubChannel.mjs +0 -2
- package/dist/src/controllers/workflowsHubChannel.mjs.map +0 -1
- package/dist/src/schemas/apiContracts.cjs +0 -2
- package/dist/src/schemas/apiContracts.cjs.map +0 -1
- package/dist/src/schemas/apiContracts.d.cts +0 -53
- package/dist/src/schemas/apiContracts.d.cts.map +0 -1
- package/dist/src/schemas/apiContracts.d.mts +0 -53
- package/dist/src/schemas/apiContracts.d.mts.map +0 -1
- package/dist/src/schemas/apiContracts.mjs +0 -2
- package/dist/src/schemas/apiContracts.mjs.map +0 -1
- package/dist/src/schemas/workflowPi.cjs +0 -2
- package/dist/src/schemas/workflowPi.cjs.map +0 -1
- package/dist/src/schemas/workflowPi.d.cts +0 -1
- package/dist/src/schemas/workflowPi.d.mts +0 -1
- package/dist/src/schemas/workflowPi.mjs +0 -2
- package/dist/src/schemas/workflowPi.mjs.map +0 -1
- package/dist/src/services/backgroundWork/index.cjs +0 -2
- package/dist/src/services/backgroundWork/index.cjs.map +0 -1
- package/dist/src/services/backgroundWork/index.mjs +0 -2
- package/dist/src/services/backgroundWork/index.mjs.map +0 -1
- package/dist/src/services/piToolBridge/index.cjs +0 -11
- package/dist/src/services/piToolBridge/index.cjs.map +0 -1
- package/dist/src/services/piToolBridge/index.mjs +0 -11
- package/dist/src/services/piToolBridge/index.mjs.map +0 -1
- package/dist/src/services/webWorkflowCatalog/index.cjs +0 -2
- package/dist/src/services/webWorkflowCatalog/index.cjs.map +0 -1
- package/dist/src/services/webWorkflowCatalog/index.mjs +0 -2
- package/dist/src/services/webWorkflowCatalog/index.mjs.map +0 -1
- package/dist/src/services/workflowCatalogDeps/index.cjs +0 -2
- package/dist/src/services/workflowCatalogDeps/index.cjs.map +0 -1
- package/dist/src/services/workflowCatalogDeps/index.mjs +0 -2
- package/dist/src/services/workflowCatalogDeps/index.mjs.map +0 -1
- package/dist/src/services/workflowExecution/index.cjs +0 -2
- package/dist/src/services/workflowExecution/index.cjs.map +0 -1
- package/dist/src/services/workflowExecution/index.d.cts +0 -6
- package/dist/src/services/workflowExecution/index.d.mts +0 -6
- package/dist/src/services/workflowExecution/index.mjs +0 -2
- package/dist/src/services/workflowExecution/index.mjs.map +0 -1
- package/dist/src/services/workflowFence/index.cjs +0 -2
- package/dist/src/services/workflowFence/index.cjs.map +0 -1
- package/dist/src/services/workflowFence/index.mjs +0 -2
- package/dist/src/services/workflowFence/index.mjs.map +0 -1
- package/dist/src/services/workflowLaunchCommand/index.cjs +0 -2
- package/dist/src/services/workflowLaunchCommand/index.cjs.map +0 -1
- package/dist/src/services/workflowLaunchCommand/index.d.cts +0 -52
- package/dist/src/services/workflowLaunchCommand/index.d.cts.map +0 -1
- package/dist/src/services/workflowLaunchCommand/index.d.mts +0 -52
- package/dist/src/services/workflowLaunchCommand/index.d.mts.map +0 -1
- package/dist/src/services/workflowLaunchCommand/index.mjs +0 -2
- package/dist/src/services/workflowLaunchCommand/index.mjs.map +0 -1
- package/dist/src/services/workflowLauncher/index.cjs +0 -2
- package/dist/src/services/workflowLauncher/index.cjs.map +0 -1
- package/dist/src/services/workflowLauncher/index.mjs +0 -2
- package/dist/src/services/workflowLauncher/index.mjs.map +0 -1
- package/dist/src/services/workflowNarration/index.cjs +0 -2
- package/dist/src/services/workflowNarration/index.cjs.map +0 -1
- package/dist/src/services/workflowNarration/index.mjs +0 -2
- package/dist/src/services/workflowNarration/index.mjs.map +0 -1
- package/dist/src/services/workflowResource/index.cjs +0 -2
- package/dist/src/services/workflowResource/index.cjs.map +0 -1
- package/dist/src/services/workflowResource/index.mjs +0 -2
- package/dist/src/services/workflowResource/index.mjs.map +0 -1
- package/dist/src/services/workflowRuns/index.cjs +0 -3
- package/dist/src/services/workflowRuns/index.cjs.map +0 -1
- package/dist/src/services/workflowRuns/index.mjs +0 -3
- package/dist/src/services/workflowRuns/index.mjs.map +0 -1
- package/dist/src/services/workflowTerminal/index.cjs +0 -2
- package/dist/src/services/workflowTerminal/index.cjs.map +0 -1
- package/dist/src/services/workflowTerminal/index.mjs +0 -2
- package/dist/src/services/workflowTerminal/index.mjs.map +0 -1
- package/dist/src/services/workflowWatcher/index.cjs +0 -2
- package/dist/src/services/workflowWatcher/index.cjs.map +0 -1
- package/dist/src/services/workflowWatcher/index.mjs +0 -2
- package/dist/src/services/workflowWatcher/index.mjs.map +0 -1
- package/dist/src/tools/workflowTools.cjs +0 -5
- package/dist/src/tools/workflowTools.cjs.map +0 -1
- package/dist/src/tools/workflowTools.mjs +0 -5
- package/dist/src/tools/workflowTools.mjs.map +0 -1
- package/dist/src/tui/leader.cjs +0 -2
- package/dist/src/tui/leader.cjs.map +0 -1
- package/dist/src/tui/leader.mjs +0 -2
- package/dist/src/tui/leader.mjs.map +0 -1
- package/dist/src/tui/workflow/doomOverlay.cjs +0 -2
- package/dist/src/tui/workflow/doomOverlay.cjs.map +0 -1
- package/dist/src/tui/workflow/doomOverlay.mjs +0 -2
- package/dist/src/tui/workflow/doomOverlay.mjs.map +0 -1
- package/dist/src/tui/workflow/overlayText.cjs +0 -2
- package/dist/src/tui/workflow/overlayText.cjs.map +0 -1
- package/dist/src/tui/workflow/overlayText.mjs +0 -2
- package/dist/src/tui/workflow/overlayText.mjs.map +0 -1
- package/dist/src/tui/workflow/rendering.cjs +0 -2
- package/dist/src/tui/workflow/rendering.cjs.map +0 -1
- package/dist/src/tui/workflow/rendering.mjs +0 -2
- package/dist/src/tui/workflow/rendering.mjs.map +0 -1
- package/dist/src/tui/workflow/workflowCatalog.cjs +0 -2
- package/dist/src/tui/workflow/workflowCatalog.cjs.map +0 -1
- package/dist/src/tui/workflow/workflowCatalog.mjs +0 -2
- package/dist/src/tui/workflow/workflowCatalog.mjs.map +0 -1
- package/dist/src/tui/workflow/workflowFinishedMessage.cjs +0 -3
- package/dist/src/tui/workflow/workflowFinishedMessage.cjs.map +0 -1
- package/dist/src/tui/workflow/workflowFinishedMessage.mjs +0 -3
- package/dist/src/tui/workflow/workflowFinishedMessage.mjs.map +0 -1
- package/dist/src/tui/workflow/workflowInspector.cjs +0 -2
- package/dist/src/tui/workflow/workflowInspector.cjs.map +0 -1
- package/dist/src/tui/workflow/workflowInspector.mjs +0 -2
- package/dist/src/tui/workflow/workflowInspector.mjs.map +0 -1
- package/dist/src/tui/workflow/workflowOverlay.cjs +0 -2
- package/dist/src/tui/workflow/workflowOverlay.cjs.map +0 -1
- package/dist/src/tui/workflow/workflowOverlay.mjs +0 -2
- package/dist/src/tui/workflow/workflowOverlay.mjs.map +0 -1
- package/dist/src/tui/workflow/workflowPicker.cjs +0 -2
- package/dist/src/tui/workflow/workflowPicker.cjs.map +0 -1
- package/dist/src/tui/workflow/workflowPicker.mjs +0 -2
- package/dist/src/tui/workflow/workflowPicker.mjs.map +0 -1
- package/dist/src/tui/workflow/workflowProgressOverlay.cjs +0 -2
- package/dist/src/tui/workflow/workflowProgressOverlay.cjs.map +0 -1
- package/dist/src/tui/workflow/workflowProgressOverlay.mjs +0 -2
- package/dist/src/tui/workflow/workflowProgressOverlay.mjs.map +0 -1
- package/dist/src/tui/workflow/workflowPrompt.cjs +0 -2
- package/dist/src/tui/workflow/workflowPrompt.cjs.map +0 -1
- package/dist/src/tui/workflow/workflowPrompt.mjs +0 -2
- package/dist/src/tui/workflow/workflowPrompt.mjs.map +0 -1
- package/dist/src/tui/workflow/workflowRunPanel.cjs +0 -2
- package/dist/src/tui/workflow/workflowRunPanel.cjs.map +0 -1
- package/dist/src/tui/workflow/workflowRunPanel.mjs +0 -2
- package/dist/src/tui/workflow/workflowRunPanel.mjs.map +0 -1
- package/dist/src/tui/workflow/workflowStatusRow.cjs +0 -2
- package/dist/src/tui/workflow/workflowStatusRow.cjs.map +0 -1
- package/dist/src/tui/workflow/workflowStatusRow.mjs +0 -2
- package/dist/src/tui/workflow/workflowStatusRow.mjs.map +0 -1
- package/dist/src/tui/workflow/workflowStepMessage.cjs +0 -2
- package/dist/src/tui/workflow/workflowStepMessage.cjs.map +0 -1
- package/dist/src/tui/workflow/workflowStepMessage.mjs +0 -2
- package/dist/src/tui/workflow/workflowStepMessage.mjs.map +0 -1
- package/dist/src/tui/workflow/workflowToolRender.cjs +0 -7
- package/dist/src/tui/workflow/workflowToolRender.cjs.map +0 -1
- package/dist/src/tui/workflow/workflowToolRender.mjs +0 -7
- package/dist/src/tui/workflow/workflowToolRender.mjs.map +0 -1
- package/dist/src/tui/workflowRuntime.cjs +0 -9
- package/dist/src/tui/workflowRuntime.cjs.map +0 -1
- package/dist/src/tui/workflowRuntime.d.cts +0 -33
- package/dist/src/tui/workflowRuntime.d.cts.map +0 -1
- package/dist/src/tui/workflowRuntime.d.mts +0 -33
- package/dist/src/tui/workflowRuntime.d.mts.map +0 -1
- package/dist/src/tui/workflowRuntime.mjs +0 -9
- package/dist/src/tui/workflowRuntime.mjs.map +0 -1
- package/dist/src/types/webWorkflowTerminal.cjs +0 -2
- package/dist/src/types/webWorkflowTerminal.cjs.map +0 -1
- package/dist/src/types/webWorkflowTerminal.mjs +0 -2
- package/dist/src/types/webWorkflowTerminal.mjs.map +0 -1
- package/dist/src/types/webWorkflows.cjs +0 -2
- package/dist/src/types/webWorkflows.cjs.map +0 -1
- package/dist/src/types/webWorkflows.mjs +0 -2
- package/dist/src/types/webWorkflows.mjs.map +0 -1
- package/src/extensions/web.ts +0 -80
- package/src/web/api/terminalApi.ts +0 -208
- package/src/web/components/ArtifactsPane.tsx +0 -451
- package/src/web/components/LaunchWorkflowDialog.tsx +0 -259
- package/src/web/components/StepTerminalPanel.tsx +0 -243
- package/src/web/components/WorkflowCatalogDrawer.tsx +0 -229
- package/src/web/components/WorkflowToolMessage.tsx +0 -55
- package/src/web/components/WorkflowsActivitySection.tsx +0 -155
- package/src/web/components/WorkflowsPanel.tsx +0 -750
- package/src/web/lib/launchLine.ts +0 -66
- package/src/web/lib/runDuration.ts +0 -15
- package/src/web/lib/workflowActivity.ts +0 -102
- package/src/web/lib/workflowToolRender.ts +0 -585
- package/src/web/stores/catalogStore.ts +0 -123
- package/src/web/stores/workflowsStore.ts +0 -91
- package/src/web/tsconfig.json +0 -22
- /package/{src/web/LICENSE → LICENSE.web} +0 -0
package/src/extensions/web.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { defineWebPlugin } from '@agimon-ai/doompi-core/web';
|
|
2
|
-
|
|
3
|
-
import { WorkflowsActivitySection } from '../web/components/WorkflowsActivitySection';
|
|
4
|
-
import { workflowsTab } from '../web/components/WorkflowsPanel';
|
|
5
|
-
import { WorkflowToolMessage } from '../web/components/WorkflowToolMessage';
|
|
6
|
-
import { openCatalog, openWorkflowCatalogForContext, workflowCatalogChannel } from '../web/stores/catalogStore';
|
|
7
|
-
import { workflowRunsChannel, workflows } from '../web/stores/workflowsStore';
|
|
8
|
-
|
|
9
|
-
const WORKFLOWS_GROUP = { key: 'w', label: 'workflows', detail: 'multi-step agent runs' };
|
|
10
|
-
|
|
11
|
-
const workflowActivitySource = {
|
|
12
|
-
subscribe(listener: () => void) {
|
|
13
|
-
const subscription = workflows.store.subscribe(listener);
|
|
14
|
-
return () => subscription.unsubscribe();
|
|
15
|
-
},
|
|
16
|
-
isActive(sessionId: string | null) {
|
|
17
|
-
return workflows.select(workflows.store.state, sessionId).runs.some((run) => run.stage === 'running');
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
/** The named export the generated plugin registry imports. */
|
|
22
|
-
export const webPlugin = defineWebPlugin({
|
|
23
|
-
id: 'workflows',
|
|
24
|
-
session: {
|
|
25
|
-
// No declared tab: the runs surface is a panel the reader opens from the
|
|
26
|
-
// dock's workflows group, and closes when they are done with it.
|
|
27
|
-
channels: [workflowRunsChannel, workflowCatalogChannel],
|
|
28
|
-
contextActions: [
|
|
29
|
-
{
|
|
30
|
-
id: 'launch-workflow',
|
|
31
|
-
label: 'Launch Workflow',
|
|
32
|
-
detail: 'Choose a workflow, review its inputs, then launch it.',
|
|
33
|
-
kinds: ['work-item'],
|
|
34
|
-
order: 20,
|
|
35
|
-
run: (context) => openWorkflowCatalogForContext(context, workflowsTab),
|
|
36
|
-
},
|
|
37
|
-
],
|
|
38
|
-
minorModes: [{ name: 'workflow', keys: 'w e', widgetKey: 'workflow-mcp-progress', order: 50 }],
|
|
39
|
-
activityGroups: [
|
|
40
|
-
{
|
|
41
|
-
name: 'workflows',
|
|
42
|
-
keys: 'w r',
|
|
43
|
-
widgetKeys: ['workflow-mcp-progress', 'workflow-mcp-follow'],
|
|
44
|
-
activeSource: workflowActivitySource,
|
|
45
|
-
transientTab: workflowsTab,
|
|
46
|
-
order: 30,
|
|
47
|
-
},
|
|
48
|
-
],
|
|
49
|
-
// Same name as the group: the dock renders this inside it, in place of the
|
|
50
|
-
// widget's bare presence signal.
|
|
51
|
-
activitySections: [{ id: 'workflows', component: WorkflowsActivitySection }],
|
|
52
|
-
// The workflow tools' timeline cards, the web half of src/tui/workflow/workflowToolRender.ts.
|
|
53
|
-
toolRenderers: [{ tools: ['list_workflows', 'launch_workflow', 'workflow_run'], message: WorkflowToolMessage }],
|
|
54
|
-
// The TUI's SPC w r, w l and w e; recovery (w c) is a TUI-only overlay, so
|
|
55
|
-
// it has no cockpit key yet.
|
|
56
|
-
leaderBindings: [
|
|
57
|
-
{
|
|
58
|
-
id: 'doom-workflow.manage',
|
|
59
|
-
path: [WORKFLOWS_GROUP, { key: 'r', label: 'runs', detail: 'runs in this session' }],
|
|
60
|
-
run: (context) => context.openTransientTab(workflowsTab()),
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
id: 'doom-workflow.catalog',
|
|
64
|
-
path: [WORKFLOWS_GROUP, { key: 'l', label: 'launch', detail: 'pick a workflow and launch it' }],
|
|
65
|
-
run: (context) => {
|
|
66
|
-
if (context.sessionId !== null) openCatalog(context.sessionId);
|
|
67
|
-
context.openTransientTab(workflowsTab());
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
id: 'doom-workflow.toggle',
|
|
72
|
-
path: [
|
|
73
|
-
WORKFLOWS_GROUP,
|
|
74
|
-
{ key: 'e', label: 'toggle', detail: 'give the agent workflow tools or take them back' },
|
|
75
|
-
],
|
|
76
|
-
command: 'minor workflow',
|
|
77
|
-
},
|
|
78
|
-
],
|
|
79
|
-
},
|
|
80
|
-
});
|
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
import { sessionApiPath } from '@agimon-ai/doompi-core/web';
|
|
2
|
-
import { sealedTransport } from '@agimon-ai/doompi-web-security/browser';
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
WORKFLOW_SCREEN_EVENT,
|
|
6
|
-
workflowRunPath,
|
|
7
|
-
type WorkflowArtifactContentResponse,
|
|
8
|
-
type WorkflowArtifactsResponse,
|
|
9
|
-
type WorkflowControlResponse,
|
|
10
|
-
type WorkflowDeleteResponse,
|
|
11
|
-
type WorkflowScreenEvent,
|
|
12
|
-
} from '../../types/webWorkflowTerminal';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* The page's half of this package's hub API: one run's terminal and the files
|
|
16
|
-
* its run directory holds. The only place the cockpit talks HTTP for a
|
|
17
|
-
* workflow, so if the transport changes, it changes here alone.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
const UNREACHABLE = 'The cockpit hub is unreachable.';
|
|
21
|
-
const JSON_HEADERS = { 'content-type': 'application/json' };
|
|
22
|
-
|
|
23
|
-
function sessionUrl(path: string, sessionId?: string | null): string {
|
|
24
|
-
if (sessionId === undefined || sessionId === null) return path;
|
|
25
|
-
return path.replace('/api/plugins/', `${sessionApiPath(sessionId)}/plugins/`);
|
|
26
|
-
}
|
|
27
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
28
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/** The error a route reported, or a generic one; never an empty message. */
|
|
32
|
-
function errorOf(body: unknown, fallback: string): string {
|
|
33
|
-
return isRecord(body) && typeof body.error === 'string' && body.error !== '' ? body.error : fallback;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async function post(
|
|
37
|
-
path: string,
|
|
38
|
-
body: unknown,
|
|
39
|
-
sessionId?: string | null,
|
|
40
|
-
): Promise<{ status: number; body: unknown }> {
|
|
41
|
-
try {
|
|
42
|
-
const response = await sealedTransport.fetch(sessionUrl(path, sessionId), {
|
|
43
|
-
method: 'POST',
|
|
44
|
-
headers: JSON_HEADERS,
|
|
45
|
-
body: JSON.stringify(body),
|
|
46
|
-
});
|
|
47
|
-
const text = await response.text();
|
|
48
|
-
return { status: response.status, body: text === '' ? undefined : (JSON.parse(text) as unknown) };
|
|
49
|
-
} catch {
|
|
50
|
-
return { status: 0, body: undefined };
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Follows one run's screen until the run settles or the caller stops.
|
|
56
|
-
*
|
|
57
|
-
* Returns the stop function. The stream is server-sent events, so a hub that
|
|
58
|
-
* restarts reconnects on its own and the page keeps painting.
|
|
59
|
-
*/
|
|
60
|
-
export function followScreen(
|
|
61
|
-
workspace: string,
|
|
62
|
-
runKey: string,
|
|
63
|
-
onEvent: (event: WorkflowScreenEvent) => void,
|
|
64
|
-
sessionId?: string | null,
|
|
65
|
-
): () => void {
|
|
66
|
-
const source = new EventSource(sessionUrl(`${workflowRunPath(workspace, runKey)}/screen/stream`, sessionId));
|
|
67
|
-
const handler = (message: MessageEvent<string>): void => {
|
|
68
|
-
let parsed: unknown;
|
|
69
|
-
try {
|
|
70
|
-
parsed = JSON.parse(message.data);
|
|
71
|
-
} catch {
|
|
72
|
-
return; // A torn frame; the next one repaints the whole screen anyway.
|
|
73
|
-
}
|
|
74
|
-
if (!isRecord(parsed) || !Array.isArray(parsed.lines)) return;
|
|
75
|
-
onEvent(parsed as unknown as WorkflowScreenEvent);
|
|
76
|
-
};
|
|
77
|
-
source.addEventListener(WORKFLOW_SCREEN_EVENT, handler as EventListener);
|
|
78
|
-
return () => {
|
|
79
|
-
source.removeEventListener(WORKFLOW_SCREEN_EVENT, handler as EventListener);
|
|
80
|
-
source.close();
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/** Takes the keyboard for one run, renewing when this page already holds it. */
|
|
85
|
-
export async function takeControl(
|
|
86
|
-
workspace: string,
|
|
87
|
-
runKey: string,
|
|
88
|
-
token?: string,
|
|
89
|
-
sessionId?: string | null,
|
|
90
|
-
): Promise<WorkflowControlResponse> {
|
|
91
|
-
const { status, body } = await post(`${workflowRunPath(workspace, runKey)}/control`, { token }, sessionId);
|
|
92
|
-
if (status === 0) return { held: false, reason: UNREACHABLE };
|
|
93
|
-
if (isRecord(body) && typeof body.held === 'boolean') return body as unknown as WorkflowControlResponse;
|
|
94
|
-
return { held: false, reason: errorOf(body, 'The run refused the keyboard.') };
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export async function releaseControl(
|
|
98
|
-
workspace: string,
|
|
99
|
-
runKey: string,
|
|
100
|
-
token: string,
|
|
101
|
-
sessionId?: string | null,
|
|
102
|
-
): Promise<void> {
|
|
103
|
-
await post(`${workflowRunPath(workspace, runKey)}/control`, { token, release: true }, sessionId);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/** Sends literal keystrokes; the reason comes back when the lease has moved on. */
|
|
107
|
-
export async function sendKeys(
|
|
108
|
-
workspace: string,
|
|
109
|
-
runKey: string,
|
|
110
|
-
token: string,
|
|
111
|
-
data: string,
|
|
112
|
-
sessionId?: string | null,
|
|
113
|
-
): Promise<{ error?: string }> {
|
|
114
|
-
const { status, body } = await post(`${workflowRunPath(workspace, runKey)}/keys`, { token, data }, sessionId);
|
|
115
|
-
if (status === 0) return { error: UNREACHABLE };
|
|
116
|
-
if (status === 204) return {};
|
|
117
|
-
return { error: errorOf(body, 'The run would not take those keys.') };
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/** Matches the run's terminal to the viewport of whoever holds the keyboard. */
|
|
121
|
-
export async function resizeRun(
|
|
122
|
-
workspace: string,
|
|
123
|
-
runKey: string,
|
|
124
|
-
token: string,
|
|
125
|
-
columns: number,
|
|
126
|
-
rows: number,
|
|
127
|
-
sessionId?: string | null,
|
|
128
|
-
): Promise<void> {
|
|
129
|
-
await post(`${workflowRunPath(workspace, runKey)}/resize`, { token, columns, rows }, sessionId);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
export type DeleteWorkflowResult = { result: WorkflowDeleteResponse } | { error: string };
|
|
133
|
-
|
|
134
|
-
/** Permanently removes one settled run and its run directory. */
|
|
135
|
-
export async function deleteWorkflowRun(
|
|
136
|
-
workspace: string,
|
|
137
|
-
runKey: string,
|
|
138
|
-
sessionId?: string | null,
|
|
139
|
-
): Promise<DeleteWorkflowResult> {
|
|
140
|
-
try {
|
|
141
|
-
const response = await sealedTransport.fetch(sessionUrl(workflowRunPath(workspace, runKey), sessionId), {
|
|
142
|
-
method: 'DELETE',
|
|
143
|
-
});
|
|
144
|
-
const body = (await response.json()) as unknown;
|
|
145
|
-
if (!response.ok) return { error: errorOf(body, 'The workflow could not be deleted.') };
|
|
146
|
-
if (isRecord(body) && body.deleted === true) return { result: { deleted: true } };
|
|
147
|
-
return { error: 'The workflow hub returned an invalid deletion response.' };
|
|
148
|
-
} catch {
|
|
149
|
-
return { error: UNREACHABLE };
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
export type ArtifactsResult = { artifacts: WorkflowArtifactsResponse } | { error: string };
|
|
154
|
-
|
|
155
|
-
export async function fetchArtifacts(
|
|
156
|
-
workspace: string,
|
|
157
|
-
runKey: string,
|
|
158
|
-
sessionId?: string | null,
|
|
159
|
-
): Promise<ArtifactsResult> {
|
|
160
|
-
try {
|
|
161
|
-
const response = await sealedTransport.fetch(
|
|
162
|
-
sessionUrl(`${workflowRunPath(workspace, runKey)}/artifacts`, sessionId),
|
|
163
|
-
);
|
|
164
|
-
const body = (await response.json()) as unknown;
|
|
165
|
-
if (!response.ok) return { error: errorOf(body, 'This run has no directory to read.') };
|
|
166
|
-
return { artifacts: body as WorkflowArtifactsResponse };
|
|
167
|
-
} catch {
|
|
168
|
-
return { error: UNREACHABLE };
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
export type ArtifactResult = { artifact: WorkflowArtifactContentResponse } | { error: string };
|
|
173
|
-
|
|
174
|
-
/** Trusted same-origin URL for browser-native media previews and downloads. */
|
|
175
|
-
export function artifactContentUrl(
|
|
176
|
-
workspace: string,
|
|
177
|
-
runKey: string,
|
|
178
|
-
path: string,
|
|
179
|
-
download = false,
|
|
180
|
-
sessionId?: string | null,
|
|
181
|
-
): string {
|
|
182
|
-
const encodedPath = path.split('/').map(encodeURIComponent).join('/');
|
|
183
|
-
return sessionUrl(
|
|
184
|
-
`${workflowRunPath(workspace, runKey)}/artifacts/${encodedPath}?raw=1${download ? '&download=1' : ''}`,
|
|
185
|
-
sessionId,
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export async function fetchArtifact(
|
|
190
|
-
workspace: string,
|
|
191
|
-
runKey: string,
|
|
192
|
-
path: string,
|
|
193
|
-
sessionId?: string | null,
|
|
194
|
-
): Promise<ArtifactResult> {
|
|
195
|
-
try {
|
|
196
|
-
const response = await sealedTransport.fetch(
|
|
197
|
-
sessionUrl(
|
|
198
|
-
`${workflowRunPath(workspace, runKey)}/artifacts/${path.split('/').map(encodeURIComponent).join('/')}`,
|
|
199
|
-
sessionId,
|
|
200
|
-
),
|
|
201
|
-
);
|
|
202
|
-
const body = (await response.json()) as unknown;
|
|
203
|
-
if (!response.ok) return { error: errorOf(body, 'That file has not been written.') };
|
|
204
|
-
return { artifact: body as WorkflowArtifactContentResponse };
|
|
205
|
-
} catch {
|
|
206
|
-
return { error: UNREACHABLE };
|
|
207
|
-
}
|
|
208
|
-
}
|