@agimon-ai/doompi-workflow 0.0.1-alpha.49 → 0.0.1-alpha.50
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 +3 -2
- package/package.json +7 -7
- package/src/web/WorkflowsActivitySection.tsx +4 -4
- package/src/web/WorkflowsPanel.tsx +9 -1
- package/src/web/index.ts +6 -14
package/README.md
CHANGED
|
@@ -117,8 +117,9 @@ Maintained by [Agimon](https://agimon.ai/about).
|
|
|
117
117
|
|
|
118
118
|
## Web cockpit plugin
|
|
119
119
|
|
|
120
|
-
The `src/web` directory is this package's DoomPi web cockpit plugin: the workflows
|
|
121
|
-
|
|
120
|
+
The `src/web` directory is this package's DoomPi web cockpit plugin: the workflows panel the dock's
|
|
121
|
+
workflows group opens in a temporary tab, its store, and its `workflow_runs` session channel,
|
|
122
|
+
compiled into the cockpit bundle by `doompi-web`'s build.
|
|
122
123
|
The hub-side data source ships behind the `./web-hub` subpath and reads the workflow registry
|
|
123
124
|
(run.json plus progress.ndjson) exactly as the engine writes it. Both halves are declared by the
|
|
124
125
|
`doompiWeb` block in package.json.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/doompi-workflow",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.50",
|
|
4
4
|
"description": "GitHub Actions-style workflow graphs, artifacts, recovery, and asynchronous runs for DoomPi.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -68,12 +68,12 @@
|
|
|
68
68
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
69
69
|
"hono": "4.13.5",
|
|
70
70
|
"zod": "4.4.3",
|
|
71
|
-
"@agimon-ai/doompi-
|
|
72
|
-
"@agimon-ai/doompi-
|
|
73
|
-
"@agimon-ai/doompi-
|
|
74
|
-
"@agimon-ai/doompi-
|
|
75
|
-
"@agimon-ai/doompi-web-contracts": "0.0.1-alpha.
|
|
76
|
-
"@agimon-ai/doompi-web-security": "0.0.1-alpha.
|
|
71
|
+
"@agimon-ai/doompi-telemetry": "0.0.1-alpha.49",
|
|
72
|
+
"@agimon-ai/doompi-extension-contracts": "0.0.1-alpha.49",
|
|
73
|
+
"@agimon-ai/doompi-web-components": "0.0.1-alpha.10",
|
|
74
|
+
"@agimon-ai/doompi-ui": "0.0.1-alpha.50",
|
|
75
|
+
"@agimon-ai/doompi-web-contracts": "0.0.1-alpha.13",
|
|
76
|
+
"@agimon-ai/doompi-web-security": "0.0.1-alpha.11"
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
79
79
|
"@earendil-works/pi-coding-agent": "0.84.4",
|
|
@@ -10,10 +10,10 @@ import {
|
|
|
10
10
|
workflowActivityRows,
|
|
11
11
|
} from './workflowActivity.ts';
|
|
12
12
|
import { openCatalog } from './catalogStore.ts';
|
|
13
|
+
import { workflowsTab } from './WorkflowsPanel.tsx';
|
|
13
14
|
import { focusRun, workflows } from './workflowsStore.ts';
|
|
14
15
|
|
|
15
16
|
const TICK_MS = 10_000;
|
|
16
|
-
const WORKFLOWS_TAB = 'workflows';
|
|
17
17
|
|
|
18
18
|
const TONE_DOT: Readonly<Record<WorkflowActivityTone, DotTone>> = {
|
|
19
19
|
running: 'yellow',
|
|
@@ -45,7 +45,7 @@ const GROUP_LABEL: Readonly<Record<WorkflowActivityGroupName, string>> = {
|
|
|
45
45
|
* they are the only ones that need an answer, and the rest stay out of the way
|
|
46
46
|
* until somebody asks. Idle offers the catalog instead of saying nothing.
|
|
47
47
|
*/
|
|
48
|
-
export function WorkflowsActivitySection({ sessionId,
|
|
48
|
+
export function WorkflowsActivitySection({ sessionId, openTransientTab }: WebPluginSlotProps) {
|
|
49
49
|
const runs = useStore(workflows.store, (state) => workflows.select(state, sessionId).runs);
|
|
50
50
|
const [now, setNow] = useState(() => Date.now());
|
|
51
51
|
const [folded, setFolded] = useState<Partial<Record<WorkflowActivityGroupName, boolean>>>({});
|
|
@@ -70,7 +70,7 @@ export function WorkflowsActivitySection({ sessionId, openTab }: WebPluginSlotPr
|
|
|
70
70
|
onClick={() => {
|
|
71
71
|
if (sessionId === null) return;
|
|
72
72
|
openCatalog(sessionId);
|
|
73
|
-
|
|
73
|
+
openTransientTab(workflowsTab());
|
|
74
74
|
}}
|
|
75
75
|
>
|
|
76
76
|
launch a workflow
|
|
@@ -89,7 +89,7 @@ export function WorkflowsActivitySection({ sessionId, openTab }: WebPluginSlotPr
|
|
|
89
89
|
onClick={() => {
|
|
90
90
|
if (sessionId === null) return;
|
|
91
91
|
focusRun(sessionId, row.identity);
|
|
92
|
-
|
|
92
|
+
openTransientTab(workflowsTab());
|
|
93
93
|
}}
|
|
94
94
|
className="min-w-0 gap-0.5 rounded-[5px] px-1 py-1 hover:bg-doom-panel"
|
|
95
95
|
>
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
StatusBadge,
|
|
26
26
|
StreamCursor,
|
|
27
27
|
} from '@agimon-ai/doompi-web-components';
|
|
28
|
-
import type { WebPluginSlotProps } from '@agimon-ai/doompi-web-contracts';
|
|
28
|
+
import type { TransientTab, WebPluginSlotProps } from '@agimon-ai/doompi-web-contracts';
|
|
29
29
|
import { useStore } from '@tanstack/react-store';
|
|
30
30
|
import { type ReactNode, useEffect, useMemo, useRef, useState } from 'react';
|
|
31
31
|
import type {
|
|
@@ -45,6 +45,9 @@ import { WorkflowCatalogDrawer } from './WorkflowCatalogDrawer.tsx';
|
|
|
45
45
|
import { workflowRunIdentity } from './workflowActivity.ts';
|
|
46
46
|
import { focusRun, removeRun, workflows } from './workflowsStore.ts';
|
|
47
47
|
|
|
48
|
+
/** One workflows tab per session; the surface is singular, so the id needs nothing else. */
|
|
49
|
+
export const WORKFLOWS_TAB_ID = 'workflows-runs';
|
|
50
|
+
|
|
48
51
|
const TICK_MS = 10_000;
|
|
49
52
|
|
|
50
53
|
const STATE_ICON: Readonly<Record<WorkflowProgressState, { glyph: string; className: string }>> = {
|
|
@@ -727,3 +730,8 @@ export function WorkflowsPanel({ sessionId, openTransientTab, sendSessionFrame }
|
|
|
727
730
|
</div>
|
|
728
731
|
);
|
|
729
732
|
}
|
|
733
|
+
|
|
734
|
+
/** The temporary tab the workflow surface opens in; opening it again only focuses it. */
|
|
735
|
+
export function workflowsTab(): TransientTab {
|
|
736
|
+
return { id: WORKFLOWS_TAB_ID, label: 'workflows', panel: WorkflowsPanel };
|
|
737
|
+
}
|
package/src/web/index.ts
CHANGED
|
@@ -1,19 +1,10 @@
|
|
|
1
1
|
import { defineWebPlugin } from '@agimon-ai/doompi-web-contracts';
|
|
2
|
-
import { useStore } from '@tanstack/react-store';
|
|
3
2
|
import { openCatalog, workflowCatalogChannel } from './catalogStore.ts';
|
|
4
3
|
import { WorkflowsActivitySection } from './WorkflowsActivitySection.tsx';
|
|
5
|
-
import {
|
|
4
|
+
import { workflowsTab } from './WorkflowsPanel.tsx';
|
|
6
5
|
import { WorkflowToolMessage } from './WorkflowToolMessage.tsx';
|
|
7
6
|
import { workflowRunsChannel, workflows } from './workflowsStore.ts';
|
|
8
7
|
|
|
9
|
-
/** The tab badge: only runs still in the running stage. */
|
|
10
|
-
export function useWorkflowsBadge(sessionId: string | null): number {
|
|
11
|
-
return useStore(
|
|
12
|
-
workflows.store,
|
|
13
|
-
(state) => workflows.select(state, sessionId).runs.filter((run) => run.stage === 'running').length,
|
|
14
|
-
);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
8
|
const WORKFLOWS_GROUP = { key: 'w', label: 'workflows', detail: 'multi-step agent runs' };
|
|
18
9
|
|
|
19
10
|
const workflowActivitySource = {
|
|
@@ -29,7 +20,8 @@ const workflowActivitySource = {
|
|
|
29
20
|
/** The named export the generated plugin registry imports. */
|
|
30
21
|
export const webPlugin = defineWebPlugin({
|
|
31
22
|
id: 'workflows',
|
|
32
|
-
|
|
23
|
+
// No declared tab: the runs surface is a panel the reader opens from the
|
|
24
|
+
// dock's workflows group, and closes when they are done with it.
|
|
33
25
|
channels: [workflowRunsChannel, workflowCatalogChannel],
|
|
34
26
|
minorModes: [{ name: 'workflow', keys: 'w e', widgetKey: 'workflow-mcp-progress', order: 50 }],
|
|
35
27
|
activityGroups: [
|
|
@@ -38,7 +30,7 @@ export const webPlugin = defineWebPlugin({
|
|
|
38
30
|
keys: 'w r',
|
|
39
31
|
widgetKeys: ['workflow-mcp-progress', 'workflow-mcp-follow'],
|
|
40
32
|
activeSource: workflowActivitySource,
|
|
41
|
-
|
|
33
|
+
transientTab: workflowsTab,
|
|
42
34
|
order: 30,
|
|
43
35
|
},
|
|
44
36
|
],
|
|
@@ -53,14 +45,14 @@ export const webPlugin = defineWebPlugin({
|
|
|
53
45
|
{
|
|
54
46
|
id: 'doom-workflow.manage',
|
|
55
47
|
path: [WORKFLOWS_GROUP, { key: 'r', label: 'runs', detail: 'runs in this session' }],
|
|
56
|
-
run: (context) => context.
|
|
48
|
+
run: (context) => context.openTransientTab(workflowsTab()),
|
|
57
49
|
},
|
|
58
50
|
{
|
|
59
51
|
id: 'doom-workflow.catalog',
|
|
60
52
|
path: [WORKFLOWS_GROUP, { key: 'l', label: 'launch', detail: 'pick a workflow and launch it' }],
|
|
61
53
|
run: (context) => {
|
|
62
54
|
if (context.sessionId !== null) openCatalog(context.sessionId);
|
|
63
|
-
context.
|
|
55
|
+
context.openTransientTab(workflowsTab());
|
|
64
56
|
},
|
|
65
57
|
},
|
|
66
58
|
{
|