@agimon-ai/doompi-workflow 0.0.1-alpha.7 → 0.0.1-alpha.71
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 +6 -0
- package/README.md +122 -26
- package/dist/_virtual/_rolldown/runtime.cjs +1 -0
- package/dist/api-contracts.cjs +1 -0
- package/dist/api-contracts.d.cts +2 -0
- package/dist/api-contracts.d.mts +2 -0
- package/dist/api-contracts.mjs +1 -0
- package/dist/extensions/pi.cjs +1 -1
- package/dist/extensions/pi.cjs.map +1 -1
- package/dist/extensions/pi.d.cts +6 -2
- package/dist/extensions/pi.d.cts.map +1 -0
- package/dist/extensions/pi.d.mts +6 -2
- package/dist/extensions/pi.d.mts.map +1 -0
- package/dist/extensions/pi.mjs +1 -1
- package/dist/extensions/pi.mjs.map +1 -1
- package/dist/extensions/server.cjs +2 -0
- package/dist/extensions/server.cjs.map +1 -0
- package/dist/extensions/server.d.cts +5 -0
- package/dist/extensions/server.d.cts.map +1 -0
- package/dist/extensions/server.d.mts +5 -0
- package/dist/extensions/server.d.mts.map +1 -0
- package/dist/extensions/server.mjs +2 -0
- package/dist/extensions/server.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2 -3
- package/dist/index.d.mts +2 -3
- package/dist/index.mjs +1 -1
- package/dist/src/constants/workflow.cjs +2 -0
- package/dist/src/constants/workflow.cjs.map +1 -0
- package/dist/src/constants/workflow.mjs +2 -0
- package/dist/src/constants/workflow.mjs.map +1 -0
- package/dist/src/controllers/serverRuntime.cjs +2 -0
- package/dist/src/controllers/serverRuntime.cjs.map +1 -0
- package/dist/src/controllers/serverRuntime.mjs +2 -0
- package/dist/src/controllers/serverRuntime.mjs.map +1 -0
- package/dist/src/controllers/workflowCatalogChannel.cjs +2 -0
- package/dist/src/controllers/workflowCatalogChannel.cjs.map +1 -0
- package/dist/src/controllers/workflowCatalogChannel.mjs +2 -0
- package/dist/src/controllers/workflowCatalogChannel.mjs.map +1 -0
- package/dist/src/controllers/workflowHubApi.cjs +2 -0
- package/dist/src/controllers/workflowHubApi.cjs.map +1 -0
- package/dist/src/controllers/workflowHubApi.mjs +2 -0
- package/dist/src/controllers/workflowHubApi.mjs.map +1 -0
- package/dist/src/controllers/workflowsHubChannel.cjs +2 -0
- package/dist/src/controllers/workflowsHubChannel.cjs.map +1 -0
- package/dist/src/controllers/workflowsHubChannel.mjs +2 -0
- package/dist/src/controllers/workflowsHubChannel.mjs.map +1 -0
- package/dist/src/schemas/apiContracts.cjs +2 -0
- package/dist/src/schemas/apiContracts.cjs.map +1 -0
- package/dist/src/schemas/apiContracts.d.cts +53 -0
- package/dist/src/schemas/apiContracts.d.cts.map +1 -0
- package/dist/src/schemas/apiContracts.d.mts +53 -0
- package/dist/src/schemas/apiContracts.d.mts.map +1 -0
- package/dist/src/schemas/apiContracts.mjs +2 -0
- package/dist/src/schemas/apiContracts.mjs.map +1 -0
- package/dist/src/schemas/workflowPi.cjs +2 -0
- package/dist/src/schemas/workflowPi.cjs.map +1 -0
- package/dist/src/schemas/workflowPi.d.cts +1 -0
- package/dist/src/schemas/workflowPi.d.mts +1 -0
- package/dist/src/schemas/workflowPi.mjs +2 -0
- package/dist/src/schemas/workflowPi.mjs.map +1 -0
- package/dist/src/services/backgroundWork/index.cjs +2 -0
- package/dist/src/services/backgroundWork/index.cjs.map +1 -0
- package/dist/src/services/backgroundWork/index.mjs +2 -0
- package/dist/src/services/backgroundWork/index.mjs.map +1 -0
- package/dist/{workflow/piToolBridge.cjs → src/services/piToolBridge/index.cjs} +2 -2
- package/dist/src/services/piToolBridge/index.cjs.map +1 -0
- package/dist/{workflow/piToolBridge.mjs → src/services/piToolBridge/index.mjs} +2 -2
- package/dist/src/services/piToolBridge/index.mjs.map +1 -0
- package/dist/src/services/webWorkflowCatalog/index.cjs +2 -0
- package/dist/src/services/webWorkflowCatalog/index.cjs.map +1 -0
- package/dist/src/services/webWorkflowCatalog/index.mjs +2 -0
- package/dist/src/services/webWorkflowCatalog/index.mjs.map +1 -0
- package/dist/src/services/workflowCatalogDeps/index.cjs +2 -0
- package/dist/src/services/workflowCatalogDeps/index.cjs.map +1 -0
- package/dist/src/services/workflowCatalogDeps/index.mjs +2 -0
- package/dist/src/services/workflowCatalogDeps/index.mjs.map +1 -0
- package/dist/src/services/workflowExecution/index.cjs +2 -0
- package/dist/src/services/workflowExecution/index.cjs.map +1 -0
- package/dist/src/services/workflowExecution/index.d.cts +6 -0
- package/dist/src/services/workflowExecution/index.d.mts +6 -0
- package/dist/src/services/workflowExecution/index.mjs +2 -0
- package/dist/src/services/workflowExecution/index.mjs.map +1 -0
- package/dist/src/services/workflowFence/index.cjs +2 -0
- package/dist/src/services/workflowFence/index.cjs.map +1 -0
- package/dist/src/services/workflowFence/index.mjs +2 -0
- package/dist/src/services/workflowFence/index.mjs.map +1 -0
- package/dist/src/services/workflowLaunchCommand/index.cjs +2 -0
- package/dist/src/services/workflowLaunchCommand/index.cjs.map +1 -0
- package/dist/src/services/workflowLaunchCommand/index.d.cts +52 -0
- package/dist/src/services/workflowLaunchCommand/index.d.cts.map +1 -0
- package/dist/src/services/workflowLaunchCommand/index.d.mts +52 -0
- package/dist/src/services/workflowLaunchCommand/index.d.mts.map +1 -0
- package/dist/src/services/workflowLaunchCommand/index.mjs +2 -0
- package/dist/src/services/workflowLaunchCommand/index.mjs.map +1 -0
- package/dist/src/services/workflowLauncher/index.cjs +2 -0
- package/dist/src/services/workflowLauncher/index.cjs.map +1 -0
- package/dist/src/services/workflowLauncher/index.mjs +2 -0
- package/dist/src/services/workflowLauncher/index.mjs.map +1 -0
- package/dist/src/services/workflowNarration/index.cjs +2 -0
- package/dist/src/services/workflowNarration/index.cjs.map +1 -0
- package/dist/src/services/workflowNarration/index.mjs +2 -0
- package/dist/src/services/workflowNarration/index.mjs.map +1 -0
- package/dist/src/services/workflowResource/index.cjs +2 -0
- package/dist/src/services/workflowResource/index.cjs.map +1 -0
- package/dist/src/services/workflowResource/index.mjs +2 -0
- package/dist/src/services/workflowResource/index.mjs.map +1 -0
- package/dist/src/services/workflowRuns/index.cjs +3 -0
- package/dist/src/services/workflowRuns/index.cjs.map +1 -0
- package/dist/src/services/workflowRuns/index.mjs +3 -0
- package/dist/src/services/workflowRuns/index.mjs.map +1 -0
- package/dist/src/services/workflowTerminal/index.cjs +2 -0
- package/dist/src/services/workflowTerminal/index.cjs.map +1 -0
- package/dist/src/services/workflowTerminal/index.mjs +2 -0
- package/dist/src/services/workflowTerminal/index.mjs.map +1 -0
- package/dist/src/services/workflowWatcher/index.cjs +2 -0
- package/dist/src/services/workflowWatcher/index.cjs.map +1 -0
- package/dist/src/services/workflowWatcher/index.mjs +2 -0
- package/dist/src/services/workflowWatcher/index.mjs.map +1 -0
- package/dist/src/tools/workflowTools.cjs +5 -0
- package/dist/src/tools/workflowTools.cjs.map +1 -0
- package/dist/src/tools/workflowTools.mjs +5 -0
- package/dist/src/tools/workflowTools.mjs.map +1 -0
- package/dist/src/tui/leader.cjs +2 -0
- package/dist/src/tui/leader.cjs.map +1 -0
- package/dist/src/tui/leader.mjs +2 -0
- package/dist/src/tui/leader.mjs.map +1 -0
- package/dist/src/tui/workflow/doomOverlay.cjs.map +1 -0
- package/dist/src/tui/workflow/doomOverlay.mjs.map +1 -0
- package/dist/src/tui/workflow/overlayText.cjs +2 -0
- package/dist/src/tui/workflow/overlayText.cjs.map +1 -0
- package/dist/src/tui/workflow/overlayText.mjs +2 -0
- package/dist/src/tui/workflow/overlayText.mjs.map +1 -0
- package/dist/src/tui/workflow/rendering.cjs.map +1 -0
- package/dist/src/tui/workflow/rendering.mjs.map +1 -0
- package/dist/src/tui/workflow/workflowCatalog.cjs +2 -0
- package/dist/src/tui/workflow/workflowCatalog.cjs.map +1 -0
- package/dist/src/tui/workflow/workflowCatalog.mjs +2 -0
- package/dist/src/tui/workflow/workflowCatalog.mjs.map +1 -0
- package/dist/src/tui/workflow/workflowFinishedMessage.cjs +3 -0
- package/dist/src/tui/workflow/workflowFinishedMessage.cjs.map +1 -0
- package/dist/src/tui/workflow/workflowFinishedMessage.mjs +3 -0
- package/dist/src/tui/workflow/workflowFinishedMessage.mjs.map +1 -0
- package/dist/src/tui/workflow/workflowInspector.cjs +2 -0
- package/dist/src/tui/workflow/workflowInspector.cjs.map +1 -0
- package/dist/src/tui/workflow/workflowInspector.mjs +2 -0
- package/dist/src/tui/workflow/workflowInspector.mjs.map +1 -0
- package/dist/{workflow → src/tui/workflow}/workflowOverlay.cjs +1 -1
- package/dist/src/tui/workflow/workflowOverlay.cjs.map +1 -0
- package/dist/{workflow → src/tui/workflow}/workflowOverlay.mjs +1 -1
- package/dist/src/tui/workflow/workflowOverlay.mjs.map +1 -0
- package/dist/src/tui/workflow/workflowPicker.cjs.map +1 -0
- package/dist/src/tui/workflow/workflowPicker.mjs.map +1 -0
- package/dist/src/tui/workflow/workflowProgressOverlay.cjs +2 -0
- package/dist/src/tui/workflow/workflowProgressOverlay.cjs.map +1 -0
- package/dist/src/tui/workflow/workflowProgressOverlay.mjs +2 -0
- package/dist/src/tui/workflow/workflowProgressOverlay.mjs.map +1 -0
- package/dist/src/tui/workflow/workflowPrompt.cjs.map +1 -0
- package/dist/src/tui/workflow/workflowPrompt.mjs.map +1 -0
- package/dist/src/tui/workflow/workflowRunPanel.cjs +2 -0
- package/dist/src/tui/workflow/workflowRunPanel.cjs.map +1 -0
- package/dist/src/tui/workflow/workflowRunPanel.mjs +2 -0
- package/dist/src/tui/workflow/workflowRunPanel.mjs.map +1 -0
- package/dist/src/tui/workflow/workflowStatusRow.cjs +2 -0
- package/dist/src/tui/workflow/workflowStatusRow.cjs.map +1 -0
- package/dist/src/tui/workflow/workflowStatusRow.mjs +2 -0
- package/dist/src/tui/workflow/workflowStatusRow.mjs.map +1 -0
- package/dist/src/tui/workflow/workflowStepMessage.cjs +2 -0
- package/dist/src/tui/workflow/workflowStepMessage.cjs.map +1 -0
- package/dist/src/tui/workflow/workflowStepMessage.mjs +2 -0
- package/dist/src/tui/workflow/workflowStepMessage.mjs.map +1 -0
- package/dist/src/tui/workflow/workflowToolRender.cjs +7 -0
- package/dist/src/tui/workflow/workflowToolRender.cjs.map +1 -0
- package/dist/src/tui/workflow/workflowToolRender.mjs +7 -0
- package/dist/src/tui/workflow/workflowToolRender.mjs.map +1 -0
- package/dist/src/tui/workflowRuntime.cjs +9 -0
- package/dist/src/tui/workflowRuntime.cjs.map +1 -0
- package/dist/src/tui/workflowRuntime.d.cts +33 -0
- package/dist/src/tui/workflowRuntime.d.cts.map +1 -0
- package/dist/src/tui/workflowRuntime.d.mts +33 -0
- package/dist/src/tui/workflowRuntime.d.mts.map +1 -0
- package/dist/src/tui/workflowRuntime.mjs +9 -0
- package/dist/src/tui/workflowRuntime.mjs.map +1 -0
- package/dist/src/types/webWorkflowTerminal.cjs +2 -0
- package/dist/src/types/webWorkflowTerminal.cjs.map +1 -0
- package/dist/src/types/webWorkflowTerminal.mjs +2 -0
- package/dist/src/types/webWorkflowTerminal.mjs.map +1 -0
- package/dist/src/types/webWorkflows.cjs +2 -0
- package/dist/src/types/webWorkflows.cjs.map +1 -0
- package/dist/src/types/webWorkflows.mjs +2 -0
- package/dist/src/types/webWorkflows.mjs.map +1 -0
- package/llms.txt +16 -0
- package/package.json +88 -24
- package/src/extensions/web.ts +80 -0
- package/src/prompts/doompi-author-workflow/SKILL.md +30 -0
- package/src/prompts/doompi-use-workflow/SKILL.md +21 -0
- package/src/types/webWorkflowTerminal.ts +96 -0
- package/src/types/webWorkflows.ts +150 -0
- package/src/web/LICENSE +29 -0
- package/src/web/api/terminalApi.ts +207 -0
- package/src/web/components/ArtifactsPane.tsx +451 -0
- package/src/web/components/LaunchWorkflowDialog.tsx +259 -0
- package/src/web/components/StepTerminalPanel.tsx +243 -0
- package/src/web/components/WorkflowCatalogDrawer.tsx +229 -0
- package/src/web/components/WorkflowToolMessage.tsx +55 -0
- package/src/web/components/WorkflowsActivitySection.tsx +155 -0
- package/src/web/components/WorkflowsPanel.tsx +750 -0
- package/src/web/lib/launchLine.ts +66 -0
- package/src/web/lib/runDuration.ts +15 -0
- package/src/web/lib/workflowActivity.ts +102 -0
- package/src/web/lib/workflowToolRender.ts +585 -0
- package/src/web/stores/catalogStore.ts +123 -0
- package/src/web/stores/workflowsStore.ts +91 -0
- package/src/web/tsconfig.json +22 -0
- package/dist/dispatcher.cjs +0 -2
- package/dist/dispatcher.cjs.map +0 -1
- package/dist/dispatcher.d.cts +0 -6
- package/dist/dispatcher.d.cts.map +0 -1
- package/dist/dispatcher.d.mts +0 -6
- package/dist/dispatcher.d.mts.map +0 -1
- package/dist/dispatcher.mjs +0 -2
- package/dist/dispatcher.mjs.map +0 -1
- package/dist/extension.cjs +0 -2
- package/dist/extension.cjs.map +0 -1
- package/dist/extension.d.cts +0 -6
- package/dist/extension.d.cts.map +0 -1
- package/dist/extension.d.mts +0 -6
- package/dist/extension.d.mts.map +0 -1
- package/dist/extension.mjs +0 -2
- package/dist/extension.mjs.map +0 -1
- package/dist/extensions/dispatcher.cjs +0 -2
- package/dist/extensions/dispatcher.cjs.map +0 -1
- package/dist/extensions/dispatcher.d.cts +0 -2
- package/dist/extensions/dispatcher.d.mts +0 -2
- package/dist/extensions/dispatcher.mjs +0 -2
- package/dist/extensions/dispatcher.mjs.map +0 -1
- package/dist/leader.cjs +0 -2
- package/dist/leader.cjs.map +0 -1
- package/dist/leader.mjs +0 -2
- package/dist/leader.mjs.map +0 -1
- package/dist/types.cjs +0 -2
- package/dist/types.cjs.map +0 -1
- package/dist/types.mjs +0 -2
- package/dist/types.mjs.map +0 -1
- package/dist/workflow/backgroundWork.cjs +0 -2
- package/dist/workflow/backgroundWork.cjs.map +0 -1
- package/dist/workflow/backgroundWork.mjs +0 -2
- package/dist/workflow/backgroundWork.mjs.map +0 -1
- package/dist/workflow/doomOverlay.cjs.map +0 -1
- package/dist/workflow/doomOverlay.mjs.map +0 -1
- package/dist/workflow/overlayText.cjs +0 -2
- package/dist/workflow/overlayText.cjs.map +0 -1
- package/dist/workflow/overlayText.mjs +0 -2
- package/dist/workflow/overlayText.mjs.map +0 -1
- package/dist/workflow/piExtension.cjs +0 -11
- package/dist/workflow/piExtension.cjs.map +0 -1
- package/dist/workflow/piExtension.mjs +0 -11
- package/dist/workflow/piExtension.mjs.map +0 -1
- package/dist/workflow/piToolBridge.cjs.map +0 -1
- package/dist/workflow/piToolBridge.mjs.map +0 -1
- package/dist/workflow/piTools.cjs +0 -4
- package/dist/workflow/piTools.cjs.map +0 -1
- package/dist/workflow/piTools.mjs +0 -4
- package/dist/workflow/piTools.mjs.map +0 -1
- package/dist/workflow/rendering.cjs.map +0 -1
- package/dist/workflow/rendering.mjs.map +0 -1
- package/dist/workflow/workflowFooterStatus.cjs +0 -2
- package/dist/workflow/workflowFooterStatus.cjs.map +0 -1
- package/dist/workflow/workflowFooterStatus.mjs +0 -2
- package/dist/workflow/workflowFooterStatus.mjs.map +0 -1
- package/dist/workflow/workflowInspector.cjs +0 -2
- package/dist/workflow/workflowInspector.cjs.map +0 -1
- package/dist/workflow/workflowInspector.mjs +0 -2
- package/dist/workflow/workflowInspector.mjs.map +0 -1
- package/dist/workflow/workflowLauncher.cjs +0 -2
- package/dist/workflow/workflowLauncher.cjs.map +0 -1
- package/dist/workflow/workflowLauncher.mjs +0 -2
- package/dist/workflow/workflowLauncher.mjs.map +0 -1
- package/dist/workflow/workflowOverlay.cjs.map +0 -1
- package/dist/workflow/workflowOverlay.mjs.map +0 -1
- package/dist/workflow/workflowPicker.cjs.map +0 -1
- package/dist/workflow/workflowPicker.mjs.map +0 -1
- package/dist/workflow/workflowPrompt.cjs.map +0 -1
- package/dist/workflow/workflowPrompt.mjs.map +0 -1
- package/dist/workflow/workflowRunPanel.cjs +0 -2
- package/dist/workflow/workflowRunPanel.cjs.map +0 -1
- package/dist/workflow/workflowRunPanel.mjs +0 -2
- package/dist/workflow/workflowRunPanel.mjs.map +0 -1
- package/dist/workflow/workflowStatusRow.cjs +0 -2
- package/dist/workflow/workflowStatusRow.cjs.map +0 -1
- package/dist/workflow/workflowStatusRow.mjs +0 -2
- package/dist/workflow/workflowStatusRow.mjs.map +0 -1
- package/dist/workflow/workflowStepMessage.cjs +0 -2
- package/dist/workflow/workflowStepMessage.cjs.map +0 -1
- package/dist/workflow/workflowStepMessage.mjs +0 -2
- package/dist/workflow/workflowStepMessage.mjs.map +0 -1
- /package/dist/{workflow → src/tui/workflow}/doomOverlay.cjs +0 -0
- /package/dist/{workflow → src/tui/workflow}/doomOverlay.mjs +0 -0
- /package/dist/{workflow → src/tui/workflow}/rendering.cjs +0 -0
- /package/dist/{workflow → src/tui/workflow}/rendering.mjs +0 -0
- /package/dist/{workflow → src/tui/workflow}/workflowPicker.cjs +0 -0
- /package/dist/{workflow → src/tui/workflow}/workflowPicker.mjs +0 -0
- /package/dist/{workflow → src/tui/workflow}/workflowPrompt.cjs +0 -0
- /package/dist/{workflow → src/tui/workflow}/workflowPrompt.mjs +0 -0
package/LICENSE
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
Portions of this software are licensed as follows:
|
|
2
|
+
|
|
3
|
+
* All content under the "web/" directory is licensed under the DoomPi Web
|
|
4
|
+
License defined in "web/LICENSE": free to use, not to redistribute.
|
|
5
|
+
* All other content is licensed under the MIT license below.
|
|
6
|
+
|
|
1
7
|
MIT License
|
|
2
8
|
|
|
3
9
|
Copyright (c) 2026 Vuong Ngo
|
package/README.md
CHANGED
|
@@ -1,47 +1,143 @@
|
|
|
1
1
|
# @agimon-ai/doompi-workflow
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Discover, launch, monitor, control, and recover asynchronous DoomPi workflows.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
`needs:`, `steps:`, timeouts, and declared artifacts. Every step names the session it wants,
|
|
7
|
-
so one run can hand each job exactly the context that job needs.
|
|
5
|
+
Part of the [DoomPi distribution](https://www.npmjs.com/package/@agimon-ai/doompi).
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
The integration embeds `@agimon-ai/workflow-mcp`. Workflow files describe job dependencies and
|
|
8
|
+
host-executed steps, while DoomPi provides session-scoped tools and TUI surfaces.
|
|
9
|
+
|
|
10
|
+
> **Alpha:** workflow and recovery contracts may change between releases.
|
|
11
|
+
|
|
12
|
+
## Requirements
|
|
13
|
+
|
|
14
|
+
- Node.js 22.19.0 or newer
|
|
15
|
+
- Pi 0.85.0 and Pi TUI 0.85.0
|
|
12
16
|
|
|
13
17
|
## Install
|
|
14
18
|
|
|
19
|
+
The seeded `modes.yaml` selects Workflow in `default.packages`. Keep it there or select it through
|
|
20
|
+
a layer; its tools remain inactive until Workflow mode is enabled. For standalone Pi:
|
|
21
|
+
|
|
15
22
|
```bash
|
|
16
|
-
|
|
23
|
+
pi install npm:@agimon-ai/doompi-workflow
|
|
17
24
|
```
|
|
18
25
|
|
|
19
|
-
|
|
26
|
+
Enable tools with `SPC w e`, or set `WORKFLOW_MCP_MODE=on` for a non-interactive harness that cannot
|
|
27
|
+
toggle the minor mode.
|
|
28
|
+
|
|
29
|
+
## Define a workflow
|
|
30
|
+
|
|
31
|
+
Create a `*.workflow.yml` file:
|
|
32
|
+
|
|
33
|
+
```yaml
|
|
34
|
+
name: verify
|
|
35
|
+
|
|
36
|
+
jobs:
|
|
37
|
+
test:
|
|
38
|
+
steps:
|
|
39
|
+
- name: Run tests
|
|
40
|
+
run: pnpm test
|
|
41
|
+
|
|
42
|
+
summarize:
|
|
43
|
+
needs: test
|
|
44
|
+
steps:
|
|
45
|
+
- name: Record result
|
|
46
|
+
run: node scripts/write-verification-summary.mjs
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`run` commands execute on the host with the workflow process's environment and privileges. There is
|
|
50
|
+
no VM, container, or sandbox. Review workflow files as executable code. Runner-specific
|
|
51
|
+
`interactiveRun` mappings are available for commands that require a TTY.
|
|
52
|
+
|
|
53
|
+
## Launch and monitor
|
|
54
|
+
|
|
55
|
+
Core tools are:
|
|
20
56
|
|
|
21
|
-
|
|
22
|
-
|
|
57
|
+
- `list_workflows`: discover workflows.
|
|
58
|
+
- `launch_workflow`: register and start an asynchronous run.
|
|
59
|
+
- `workflow_run`: inspect or control a run through supported actions.
|
|
23
60
|
|
|
24
|
-
|
|
61
|
+
Launch returns after the run is registered, not after all jobs complete. Use status and follow
|
|
62
|
+
controls for progress, and wait for a terminal notification.
|
|
25
63
|
|
|
26
|
-
|
|
64
|
+
In the TUI, `SPC w l` lists the repository's workflows and launches the one under the cursor with
|
|
65
|
+
`r`, `SPC w r` inspects this session's runs, `SPC w c` opens recovery, and `SPC w e`
|
|
66
|
+
toggles model-visible tools. The root session can launch; child sessions can inspect the catalog but
|
|
67
|
+
do not receive an unrestricted workflow factory.
|
|
27
68
|
|
|
28
|
-
|
|
29
|
-
The recovery picker includes terminal failed runs from earlier Pi sessions. `workflow_run` action `recovery-evidence` reads only terminal registry evidence; generic status/tail and all live controls remain session-scoped. Replay claims the failed record atomically, transfers only `PI_SESSION_ID`, and binds controls to the exact run generation the session authorized.
|
|
69
|
+
## Storage, concurrency, and lifecycle
|
|
30
70
|
|
|
31
|
-
|
|
71
|
+
Registry data defaults to `$HOME/.workflow-mcp`; set `WORKFLOW_MCP_HOME` to relocate it. Persisted
|
|
72
|
+
records contain workflow and run identity, job and step state, ownership, output locations, and
|
|
73
|
+
recovery evidence. The default concurrency ceiling is five runs.
|
|
74
|
+
|
|
75
|
+
Runs embedded directly in the Pi process end with that process. Runs launched through a terminal
|
|
76
|
+
host such as tmux or cmux can have a different lifetime and remain manageable from the CLI. When
|
|
77
|
+
Team is loaded, Workflow contributes active session runs through Team's `doom/background-work`
|
|
78
|
+
service. That contribution reconnects after Team is replaced and is removed when Workflow unloads.
|
|
79
|
+
Reconciliation distinguishes stale registry records from live processes; do not assume every run
|
|
80
|
+
outlives its parent session.
|
|
81
|
+
|
|
82
|
+
Each workflow or repair step can launch commands and model-backed agents, consuming provider quota
|
|
83
|
+
and repeating external side effects.
|
|
84
|
+
|
|
85
|
+
## Recovery
|
|
86
|
+
|
|
87
|
+
Recovery is available only for records in a terminal failure state. A recovery claim atomically
|
|
88
|
+
adopts the eligible failure, validates the evidence, and transfers ownership to the replay session.
|
|
89
|
+
Live controls remain scoped to the owning session. Recovery does not launch a second copy beside a
|
|
90
|
+
still-running job and does not guarantee that parent-session work survives shutdown.
|
|
91
|
+
|
|
92
|
+
The package publishes `workflow-recovery` for active Workflow mode. While parent Help mode is
|
|
93
|
+
active, it also contributes `doompi-author-workflow` for writing workflow definitions and
|
|
94
|
+
`doompi-use-workflow` for launching, monitoring, and recovering runs. Deactivating Help hides both
|
|
95
|
+
descriptors; cached files may remain.
|
|
96
|
+
|
|
97
|
+
Each Pi extension instance uses the runner's shared Doom lifecycle. Reload or shutdown stops retained
|
|
98
|
+
callbacks, interrupts bounded inline work, removes UI and service registrations, and releases
|
|
99
|
+
package resources. Detached children load the same extension entry in their own process.
|
|
100
|
+
|
|
101
|
+
## Pi extension
|
|
102
|
+
|
|
103
|
+
The Pi extension is published at `@agimon-ai/doompi-workflow/extensions/pi` and declared in
|
|
104
|
+
`package.json.pi.extensions`. Installing the package loads it automatically; there is no secondary
|
|
105
|
+
registration or dispatcher export.
|
|
106
|
+
|
|
107
|
+
## Development
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
pnpm build
|
|
111
|
+
pnpm typecheck
|
|
112
|
+
pnpm test
|
|
113
|
+
pnpm lint
|
|
114
|
+
```
|
|
32
115
|
|
|
33
|
-
|
|
34
|
-
root session, so a subagent can look but not spawn.
|
|
116
|
+
Maintained by [Agimon](https://agimon.ai/about).
|
|
35
117
|
|
|
36
|
-
##
|
|
118
|
+
## Web cockpit plugin
|
|
37
119
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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.
|
|
123
|
+
The hub-side data source ships behind the `./web-hub` subpath and reads the workflow registry
|
|
124
|
+
(run.json plus progress.ndjson) exactly as the engine writes it. Both halves are declared by the
|
|
125
|
+
`doompiWeb` block in package.json.
|
|
44
126
|
|
|
45
127
|
## License
|
|
46
128
|
|
|
47
|
-
MIT
|
|
129
|
+
MIT, except the `src/web` directory, which is source available under the DoomPi Web License (see
|
|
130
|
+
`src/web/LICENSE`): free to use, including commercially, but not to redistribute.
|
|
131
|
+
|
|
132
|
+
Workflow's host entries live in `src/extensions/pi.ts`, `server.ts`, and `web.ts`.
|
|
133
|
+
`src/exports` exposes reusable package APIs. Controllers declare server APIs and
|
|
134
|
+
contributions, tools declare native tools, and each service has its own folder.
|
|
135
|
+
Terminal presentation and its session coordinator live in `src/tui`.
|
|
136
|
+
|
|
137
|
+
The Pi helper owns registrations and service fibers. The Workflow runtime returns
|
|
138
|
+
commands, events, mode ownership, and tool dependencies. Session startup begins
|
|
139
|
+
readiness discovery; dependent calls await that session's readiness. On shutdown,
|
|
140
|
+
`onStop` interrupts inline runs and clears session resources, while `onDispose`
|
|
141
|
+
also handles startup failure. Both use the same idempotent cleanup. A generation
|
|
142
|
+
fence prevents retired callbacks from sending messages or updating the UI; only
|
|
143
|
+
explicit resource teardown may use a retired UI context.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,s)=>(s=n==null?{}:e(i(n)),o(r||!n||!n.__esModule||!a.call(n,`default`)?t(s,`default`,{value:n,enumerable:!0}):s,n));exports.__toESM=s;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("./src/schemas/apiContracts.cjs");exports.apiContracts=e.apiContracts,exports.default=e.apiContracts;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{apiContracts as e}from"./src/schemas/apiContracts.mjs";export{e as apiContracts,e as default};
|
package/dist/extensions/pi.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../src/constants/workflow.cjs"),t=require("../src/services/workflowFence/index.cjs"),n=require("../src/services/workflowResource/index.cjs"),r=require("../src/tools/workflowTools.cjs"),i=require("../src/tui/leader.cjs"),a=require("../src/tui/workflow/workflowToolRender.cjs"),o=require("../src/tui/workflowRuntime.cjs");let s=require("@agimon-ai/doompi-core/pi-extension"),c=require("@agimon-ai/doompi-core/skills"),l=require("@agimon-ai/doompi-core/ui-hub");const u=(0,s.definePiExtension)(e.PACKAGE_SOURCE,({pi:u,context:d,options:f,signal:p})=>{let m=f?.environment??Object.freeze({...process.env}),h=t.isWorkflowDispatcherProcess(m),g=t.createWorkflowFence(u,p),_=!1,v,y=o.createWorkflowPiRuntime(g.pi,{...f,environment:m,cordis:d,initialMode:h||f?.initialMode,isActive:g.isCurrentInvocation,runCleanup:g.runCleanup,onModeChange(e){_=e,v?.setMode(e),f?.onModeChange?.(e)}}),b=r.createWorkflowTools(y.toolDependencies,e=>({renderCall:(t,n)=>a.renderWorkflowToolCall(e,t,n),renderResult:(t,n,r,i)=>a.renderWorkflowToolResult(e,i.args,t,{...n,isError:i.isError},r)})),x=h?t.dispatcherTools(b,t.resolveDispatcherParentSession(m),m):b;return{services:[...y.services??[],t=>{t.inject([c.DOOM_SKILL_SOURCES_SERVICE],t=>{let r=n.workflowSkillDirectory(),i=(0,c.requireDoomSkillSourcesService)(t).register({source:e.PACKAGE_SOURCE,directories:[r]});return()=>i.dispose()}),h||t.inject([l.DOOM_UI_HUB_SERVICE],e=>{let t=i.registerLeaderContribution((0,l.requireDoomUiHub)(e),_);return v=t,()=>{t.dispose(),v===t&&(v=void 0)}})}],tools:x.map(e=>(0,s.definePiTool)(g.tool({...e,async execute(...t){return await y.waitForReadiness(t[2]),e.execute(...t)}}))),commands:y.commands.map(([e,t])=>g.command(e,t)),shortcuts:y.shortcuts?.map(([e,t])=>g.shortcut(e,t)),events:g.events(y.events??{}),messageRenderers:y.messageRenderers,toolRestrictions:[...y.toolRestrictions??[],...h?[{source:`${e.PACKAGE_SOURCE}/dispatcher`,restrict:t.dispatcherToolRestriction()}]:[]],resources:h?[]:[{source:e.PACKAGE_SOURCE,moduleUrl:require("url").pathToFileURL(__filename).href,skills:[{name:`doompi-author-workflow`,description:`Author DoomPi workflow definitions, job dependencies and host-executed steps.`},{name:`doompi-use-workflow`,description:`Discover, launch, monitor, control and recover DoomPi workflow runs.`}]}],async onStop(){g.beginDisposal(),await g.runCleanup(()=>y.dispose())},async onDispose(){g.beginDisposal();try{await g.runCleanup(()=>y.dispose())}finally{g.finishDisposal()}}}});exports.default=u,exports.workflowExtension=u;
|
|
2
2
|
//# sourceMappingURL=pi.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pi.cjs","names":["
|
|
1
|
+
{"version":3,"file":"pi.cjs","names":["definePiExtension","PACKAGE_SOURCE","isWorkflowDispatcherProcess","createWorkflowFence","createWorkflowPiRuntime","createWorkflowTools","renderWorkflowToolCall","renderWorkflowToolResult","dispatcherTools","resolveDispatcherParentSession","DOOM_SKILL_SOURCES_SERVICE","workflowSkillDirectory","requireDoomSkillSourcesService","DOOM_UI_HUB_SERVICE","registerLeaderContribution","requireDoomUiHub","definePiTool","dispatcherToolRestriction"],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import { definePiExtension, definePiTool } from '@agimon-ai/doompi-core/pi-extension';\nimport { DOOM_SKILL_SOURCES_SERVICE, requireDoomSkillSourcesService } from '@agimon-ai/doompi-core/skills';\nimport { DOOM_UI_HUB_SERVICE, requireDoomUiHub } from '@agimon-ai/doompi-core/ui-hub';\nimport type { Context } from '@deepseek-ai/cordis';\n\nimport { PACKAGE_SOURCE } from '../constants/workflow';\nimport {\n createWorkflowFence,\n dispatcherTools,\n dispatcherToolRestriction,\n isWorkflowDispatcherProcess,\n resolveDispatcherParentSession,\n} from '../services/workflowFence';\nimport { workflowSkillDirectory } from '../services/workflowResource';\nimport { createWorkflowTools } from '../tools/workflowTools';\nimport { registerLeaderContribution } from '../tui/leader';\nimport { renderWorkflowToolCall, renderWorkflowToolResult } from '../tui/workflow/workflowToolRender';\nimport { createWorkflowPiRuntime, type WorkflowPiExtensionOptions } from '../tui/workflowRuntime';\n\nexport const workflowExtension = definePiExtension<Partial<WorkflowPiExtensionOptions>>(\n PACKAGE_SOURCE,\n ({ pi, context, options, signal }) => {\n const environment = options?.environment ?? Object.freeze({ ...process.env });\n const dispatcher = isWorkflowDispatcherProcess(environment);\n const fence = createWorkflowFence(pi, signal);\n let workflowMode = false;\n let leader: ReturnType<typeof registerLeaderContribution> | undefined;\n const runtime = createWorkflowPiRuntime(fence.pi, {\n ...options,\n environment,\n cordis: context,\n initialMode: dispatcher || options?.initialMode,\n isActive: fence.isCurrentInvocation,\n runCleanup: fence.runCleanup,\n onModeChange(enabled) {\n workflowMode = enabled;\n leader?.setMode(enabled);\n options?.onModeChange?.(enabled);\n },\n });\n const nativeTools = createWorkflowTools(runtime.toolDependencies, (name) => ({\n renderCall: (args, theme) => renderWorkflowToolCall(name, args as Record<string, unknown>, theme),\n renderResult: (result, renderOptions, theme, renderContext) =>\n renderWorkflowToolResult(\n name,\n renderContext.args as Record<string, unknown>,\n result,\n { ...renderOptions, isError: renderContext.isError },\n theme,\n ),\n }));\n const selectedTools = dispatcher\n ? dispatcherTools(nativeTools, resolveDispatcherParentSession(environment), environment)\n : nativeTools;\n return {\n services: [\n ...(runtime.services ?? []),\n (cordis: Context) => {\n cordis.inject([DOOM_SKILL_SOURCES_SERVICE], (skillContext) => {\n const directory = workflowSkillDirectory();\n const contribution = requireDoomSkillSourcesService(skillContext).register({\n source: PACKAGE_SOURCE,\n directories: [directory],\n });\n return () => contribution.dispose();\n });\n if (!dispatcher)\n cordis.inject([DOOM_UI_HUB_SERVICE], (uiContext) => {\n const contribution = registerLeaderContribution(requireDoomUiHub(uiContext), workflowMode);\n leader = contribution;\n return () => {\n contribution.dispose();\n if (leader === contribution) leader = undefined;\n };\n });\n },\n ],\n tools: selectedTools.map((tool) =>\n definePiTool(\n fence.tool({\n ...tool,\n async execute(...args) {\n await runtime.waitForReadiness(args[2]);\n return tool.execute(...args);\n },\n }),\n ),\n ),\n commands: runtime.commands.map(([name, command]) => fence.command(name, command)),\n shortcuts: runtime.shortcuts?.map(([key, shortcut]) => fence.shortcut(key, shortcut)),\n events: fence.events(runtime.events ?? {}),\n messageRenderers: runtime.messageRenderers,\n\n toolRestrictions: [\n ...(runtime.toolRestrictions ?? []),\n ...(dispatcher ? [{ source: `${PACKAGE_SOURCE}/dispatcher`, restrict: dispatcherToolRestriction() }] : []),\n ],\n resources: dispatcher\n ? []\n : [\n {\n source: PACKAGE_SOURCE,\n moduleUrl: import.meta.url,\n skills: [\n {\n name: 'doompi-author-workflow',\n description: 'Author DoomPi workflow definitions, job dependencies and host-executed steps.',\n },\n {\n name: 'doompi-use-workflow',\n description: 'Discover, launch, monitor, control and recover DoomPi workflow runs.',\n },\n ],\n },\n ],\n async onStop() {\n fence.beginDisposal();\n await fence.runCleanup(() => runtime.dispose());\n },\n async onDispose() {\n fence.beginDisposal();\n try {\n await fence.runCleanup(() => runtime.dispose());\n } finally {\n fence.finishDisposal();\n }\n },\n };\n },\n);\nexport default workflowExtension;\n"],"mappings":"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"}
|
package/dist/extensions/pi.d.cts
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { WorkflowPiExtensionOptions } from "../src/tui/workflowRuntime.cjs";
|
|
2
|
+
//#region src/extensions/pi.d.ts
|
|
3
|
+
export declare const workflowExtension: import("@agimon-ai/doompi-core/runtime-pi-extension").DefinedPiExtension<Partial<WorkflowPiExtensionOptions>>;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { workflowExtension as default };
|
|
6
|
+
//# sourceMappingURL=pi.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi.d.cts","names":[],"sources":["../../src/extensions/pi.ts"],"mappings":";;qBAmBa,yEAAiB,mBAAA,QAAA"}
|
package/dist/extensions/pi.d.mts
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { WorkflowPiExtensionOptions } from "../src/tui/workflowRuntime.mjs";
|
|
2
|
+
//#region src/extensions/pi.d.ts
|
|
3
|
+
export declare const workflowExtension: import("@agimon-ai/doompi-core/runtime-pi-extension").DefinedPiExtension<Partial<WorkflowPiExtensionOptions>>;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { workflowExtension as default };
|
|
6
|
+
//# sourceMappingURL=pi.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi.d.mts","names":[],"sources":["../../src/extensions/pi.ts"],"mappings":";;qBAmBa,yEAAiB,mBAAA,QAAA"}
|
package/dist/extensions/pi.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{PACKAGE_SOURCE as e}from"../src/constants/workflow.mjs";import{createWorkflowFence as t,dispatcherToolRestriction as n,dispatcherTools as r,isWorkflowDispatcherProcess as i,resolveDispatcherParentSession as a}from"../src/services/workflowFence/index.mjs";import{workflowSkillDirectory as o}from"../src/services/workflowResource/index.mjs";import{createWorkflowTools as s}from"../src/tools/workflowTools.mjs";import{registerLeaderContribution as c}from"../src/tui/leader.mjs";import{renderWorkflowToolCall as l,renderWorkflowToolResult as u}from"../src/tui/workflow/workflowToolRender.mjs";import{createWorkflowPiRuntime as d}from"../src/tui/workflowRuntime.mjs";import{definePiExtension as f,definePiTool as p}from"@agimon-ai/doompi-core/pi-extension";import{DOOM_SKILL_SOURCES_SERVICE as m,requireDoomSkillSourcesService as h}from"@agimon-ai/doompi-core/skills";import{DOOM_UI_HUB_SERVICE as g,requireDoomUiHub as _}from"@agimon-ai/doompi-core/ui-hub";const v=f(e,({pi:f,context:v,options:y,signal:b})=>{let x=y?.environment??Object.freeze({...process.env}),S=i(x),C=t(f,b),w=!1,T,E=d(C.pi,{...y,environment:x,cordis:v,initialMode:S||y?.initialMode,isActive:C.isCurrentInvocation,runCleanup:C.runCleanup,onModeChange(e){w=e,T?.setMode(e),y?.onModeChange?.(e)}}),D=s(E.toolDependencies,e=>({renderCall:(t,n)=>l(e,t,n),renderResult:(t,n,r,i)=>u(e,i.args,t,{...n,isError:i.isError},r)})),O=S?r(D,a(x),x):D;return{services:[...E.services??[],t=>{t.inject([m],t=>{let n=o(),r=h(t).register({source:e,directories:[n]});return()=>r.dispose()}),S||t.inject([g],e=>{let t=c(_(e),w);return T=t,()=>{t.dispose(),T===t&&(T=void 0)}})}],tools:O.map(e=>p(C.tool({...e,async execute(...t){return await E.waitForReadiness(t[2]),e.execute(...t)}}))),commands:E.commands.map(([e,t])=>C.command(e,t)),shortcuts:E.shortcuts?.map(([e,t])=>C.shortcut(e,t)),events:C.events(E.events??{}),messageRenderers:E.messageRenderers,toolRestrictions:[...E.toolRestrictions??[],...S?[{source:`${e}/dispatcher`,restrict:n()}]:[]],resources:S?[]:[{source:e,moduleUrl:import.meta.url,skills:[{name:`doompi-author-workflow`,description:`Author DoomPi workflow definitions, job dependencies and host-executed steps.`},{name:`doompi-use-workflow`,description:`Discover, launch, monitor, control and recover DoomPi workflow runs.`}]}],async onStop(){C.beginDisposal(),await C.runCleanup(()=>E.dispose())},async onDispose(){C.beginDisposal();try{await C.runCleanup(()=>E.dispose())}finally{C.finishDisposal()}}}});export{v as default,v as workflowExtension};
|
|
2
2
|
//# sourceMappingURL=pi.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pi.mjs","names":[],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"pi.mjs","names":[],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import { definePiExtension, definePiTool } from '@agimon-ai/doompi-core/pi-extension';\nimport { DOOM_SKILL_SOURCES_SERVICE, requireDoomSkillSourcesService } from '@agimon-ai/doompi-core/skills';\nimport { DOOM_UI_HUB_SERVICE, requireDoomUiHub } from '@agimon-ai/doompi-core/ui-hub';\nimport type { Context } from '@deepseek-ai/cordis';\n\nimport { PACKAGE_SOURCE } from '../constants/workflow';\nimport {\n createWorkflowFence,\n dispatcherTools,\n dispatcherToolRestriction,\n isWorkflowDispatcherProcess,\n resolveDispatcherParentSession,\n} from '../services/workflowFence';\nimport { workflowSkillDirectory } from '../services/workflowResource';\nimport { createWorkflowTools } from '../tools/workflowTools';\nimport { registerLeaderContribution } from '../tui/leader';\nimport { renderWorkflowToolCall, renderWorkflowToolResult } from '../tui/workflow/workflowToolRender';\nimport { createWorkflowPiRuntime, type WorkflowPiExtensionOptions } from '../tui/workflowRuntime';\n\nexport const workflowExtension = definePiExtension<Partial<WorkflowPiExtensionOptions>>(\n PACKAGE_SOURCE,\n ({ pi, context, options, signal }) => {\n const environment = options?.environment ?? Object.freeze({ ...process.env });\n const dispatcher = isWorkflowDispatcherProcess(environment);\n const fence = createWorkflowFence(pi, signal);\n let workflowMode = false;\n let leader: ReturnType<typeof registerLeaderContribution> | undefined;\n const runtime = createWorkflowPiRuntime(fence.pi, {\n ...options,\n environment,\n cordis: context,\n initialMode: dispatcher || options?.initialMode,\n isActive: fence.isCurrentInvocation,\n runCleanup: fence.runCleanup,\n onModeChange(enabled) {\n workflowMode = enabled;\n leader?.setMode(enabled);\n options?.onModeChange?.(enabled);\n },\n });\n const nativeTools = createWorkflowTools(runtime.toolDependencies, (name) => ({\n renderCall: (args, theme) => renderWorkflowToolCall(name, args as Record<string, unknown>, theme),\n renderResult: (result, renderOptions, theme, renderContext) =>\n renderWorkflowToolResult(\n name,\n renderContext.args as Record<string, unknown>,\n result,\n { ...renderOptions, isError: renderContext.isError },\n theme,\n ),\n }));\n const selectedTools = dispatcher\n ? dispatcherTools(nativeTools, resolveDispatcherParentSession(environment), environment)\n : nativeTools;\n return {\n services: [\n ...(runtime.services ?? []),\n (cordis: Context) => {\n cordis.inject([DOOM_SKILL_SOURCES_SERVICE], (skillContext) => {\n const directory = workflowSkillDirectory();\n const contribution = requireDoomSkillSourcesService(skillContext).register({\n source: PACKAGE_SOURCE,\n directories: [directory],\n });\n return () => contribution.dispose();\n });\n if (!dispatcher)\n cordis.inject([DOOM_UI_HUB_SERVICE], (uiContext) => {\n const contribution = registerLeaderContribution(requireDoomUiHub(uiContext), workflowMode);\n leader = contribution;\n return () => {\n contribution.dispose();\n if (leader === contribution) leader = undefined;\n };\n });\n },\n ],\n tools: selectedTools.map((tool) =>\n definePiTool(\n fence.tool({\n ...tool,\n async execute(...args) {\n await runtime.waitForReadiness(args[2]);\n return tool.execute(...args);\n },\n }),\n ),\n ),\n commands: runtime.commands.map(([name, command]) => fence.command(name, command)),\n shortcuts: runtime.shortcuts?.map(([key, shortcut]) => fence.shortcut(key, shortcut)),\n events: fence.events(runtime.events ?? {}),\n messageRenderers: runtime.messageRenderers,\n\n toolRestrictions: [\n ...(runtime.toolRestrictions ?? []),\n ...(dispatcher ? [{ source: `${PACKAGE_SOURCE}/dispatcher`, restrict: dispatcherToolRestriction() }] : []),\n ],\n resources: dispatcher\n ? []\n : [\n {\n source: PACKAGE_SOURCE,\n moduleUrl: import.meta.url,\n skills: [\n {\n name: 'doompi-author-workflow',\n description: 'Author DoomPi workflow definitions, job dependencies and host-executed steps.',\n },\n {\n name: 'doompi-use-workflow',\n description: 'Discover, launch, monitor, control and recover DoomPi workflow runs.',\n },\n ],\n },\n ],\n async onStop() {\n fence.beginDisposal();\n await fence.runCleanup(() => runtime.dispose());\n },\n async onDispose() {\n fence.beginDisposal();\n try {\n await fence.runCleanup(() => runtime.dispose());\n } finally {\n fence.finishDisposal();\n }\n },\n };\n },\n);\nexport default workflowExtension;\n"],"mappings":"g8BAmBA,MAAa,EAAoB,EAC/B,GACC,CAAE,KAAI,UAAS,UAAS,YAAa,CACpC,IAAM,EAAc,GAAS,aAAe,OAAO,OAAO,CAAE,GAAG,QAAQ,GAAI,CAAC,EACtE,EAAa,EAA4B,CAAW,EACpD,EAAQ,EAAoB,EAAI,CAAM,EACxC,EAAe,GACf,EACE,EAAU,EAAwB,EAAM,GAAI,CAChD,GAAG,EACH,cACA,OAAQ,EACR,YAAa,GAAc,GAAS,YACpC,SAAU,EAAM,oBAChB,WAAY,EAAM,WAClB,aAAa,EAAS,CACpB,EAAe,EACf,GAAQ,QAAQ,CAAO,EACvB,GAAS,eAAe,CAAO,CACjC,CACF,CAAC,EACK,EAAc,EAAoB,EAAQ,iBAAmB,IAAU,CAC3E,YAAa,EAAM,IAAU,EAAuB,EAAM,EAAiC,CAAK,EAChG,cAAe,EAAQ,EAAe,EAAO,IAC3C,EACE,EACA,EAAc,KACd,EACA,CAAE,GAAG,EAAe,QAAS,EAAc,OAAQ,EACnD,CACF,CACJ,EAAE,EACI,EAAgB,EAClB,EAAgB,EAAa,EAA+B,CAAW,EAAG,CAAW,EACrF,EACJ,MAAO,CACL,SAAU,CACR,GAAI,EAAQ,UAAY,CAAC,EACxB,GAAoB,CACnB,EAAO,OAAO,CAAC,CAA0B,EAAI,GAAiB,CAC5D,IAAM,EAAY,EAAuB,EACnC,EAAe,EAA+B,CAAY,CAAC,CAAC,SAAS,CACzE,OAAQ,EACR,YAAa,CAAC,CAAS,CACzB,CAAC,EACD,UAAa,EAAa,QAAQ,CACpC,CAAC,EACI,GACH,EAAO,OAAO,CAAC,CAAmB,EAAI,GAAc,CAClD,IAAM,EAAe,EAA2B,EAAiB,CAAS,EAAG,CAAY,EAEzF,MADA,GAAS,MACI,CACX,EAAa,QAAQ,EACjB,IAAW,IAAc,EAAS,IAAA,GACxC,CACF,CAAC,CACL,CACF,EACA,MAAO,EAAc,IAAK,GACxB,EACE,EAAM,KAAK,CACT,GAAG,EACH,MAAM,QAAQ,GAAG,EAAM,CAErB,OADA,MAAM,EAAQ,iBAAiB,EAAK,EAAE,EAC/B,EAAK,QAAQ,GAAG,CAAI,CAC7B,CACF,CAAC,CACH,CACF,EACA,SAAU,EAAQ,SAAS,KAAK,CAAC,EAAM,KAAa,EAAM,QAAQ,EAAM,CAAO,CAAC,EAChF,UAAW,EAAQ,WAAW,KAAK,CAAC,EAAK,KAAc,EAAM,SAAS,EAAK,CAAQ,CAAC,EACpF,OAAQ,EAAM,OAAO,EAAQ,QAAU,CAAC,CAAC,EACzC,iBAAkB,EAAQ,iBAE1B,iBAAkB,CAChB,GAAI,EAAQ,kBAAoB,CAAC,EACjC,GAAI,EAAa,CAAC,CAAE,OAAQ,GAAG,EAAe,aAAc,SAAU,EAA0B,CAAE,CAAC,EAAI,CAAC,CAC1G,EACA,UAAW,EACP,CAAC,EACD,CACE,CACE,OAAQ,EACR,UAAW,YAAY,IACvB,OAAQ,CACN,CACE,KAAM,yBACN,YAAa,+EACf,EACA,CACE,KAAM,sBACN,YAAa,sEACf,CACF,CACF,CACF,EACJ,MAAM,QAAS,CACb,EAAM,cAAc,EACpB,MAAM,EAAM,eAAiB,EAAQ,QAAQ,CAAC,CAChD,EACA,MAAM,WAAY,CAChB,EAAM,cAAc,EACpB,GAAI,CACF,MAAM,EAAM,eAAiB,EAAQ,QAAQ,CAAC,CAChD,QAAU,CACR,EAAM,eAAe,CACvB,CACF,CACF,CACF,CACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../src/constants/workflow.cjs"),t=require("../src/controllers/serverRuntime.cjs"),n=require("../src/controllers/workflowCatalogChannel.cjs"),r=require("../src/controllers/workflowHubApi.cjs"),i=require("../src/controllers/workflowsHubChannel.cjs"),a=(0,require("@agimon-ai/doompi-core/server-facet").defineServerPlugin)({name:e.PACKAGE_SOURCE,global:{channels:[i.createWorkflowsChannel,n.createWorkflowCatalogChannel],api:[r.api]},workspace:{channels:[i.createWorkflowsChannel,n.createWorkflowCatalogChannel],api:[r.api]},session:({agent:e,host:n})=>({api:[r.api],...e?t.createWorkflowServerRuntime(e,n):{}})});exports.default=a,exports.workflowServerFacet=a;
|
|
2
|
+
//# sourceMappingURL=server.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.cjs","names":["defineServerPlugin","PACKAGE_SOURCE","createWorkflowsChannel","createWorkflowCatalogChannel","api","createWorkflowServerRuntime"],"sources":["../../src/extensions/server.ts"],"sourcesContent":["import { defineServerPlugin } from '@agimon-ai/doompi-core/server-facet';\n\nimport { PACKAGE_SOURCE } from '../constants/workflow';\nimport { createWorkflowServerRuntime } from '../controllers/serverRuntime';\nimport { createWorkflowCatalogChannel } from '../controllers/workflowCatalogChannel';\nimport { api } from '../controllers/workflowHubApi';\nimport { createWorkflowsChannel } from '../controllers/workflowsHubChannel';\nexport const workflowServerFacet = defineServerPlugin({\n name: PACKAGE_SOURCE,\n global: { channels: [createWorkflowsChannel, createWorkflowCatalogChannel], api: [api] },\n workspace: { channels: [createWorkflowsChannel, createWorkflowCatalogChannel], api: [api] },\n session: ({ agent, host }) => ({ api: [api], ...(agent ? createWorkflowServerRuntime(agent, host) : {}) }),\n});\nexport default workflowServerFacet;\n"],"mappings":"wWAOa,GAAA,+CAAsBA,CAAAA,CAAAA,mBAAAA,CAAmB,CACpD,KAAMC,EAAAA,eACN,OAAQ,CAAE,SAAU,CAACC,EAAAA,uBAAwBC,EAAAA,4BAA4B,EAAG,IAAK,CAACC,EAAAA,GAAG,CAAE,EACvF,UAAW,CAAE,SAAU,CAACF,EAAAA,uBAAwBC,EAAAA,4BAA4B,EAAG,IAAK,CAACC,EAAAA,GAAG,CAAE,EAC1F,SAAU,CAAE,QAAO,WAAY,CAAE,IAAK,CAACA,EAAAA,GAAG,EAAG,GAAI,EAAQC,EAAAA,4BAA4B,EAAO,CAAI,EAAI,CAAC,CAAG,EAC1G,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.cts","names":[],"sources":["../../src/extensions/server.ts"],"mappings":";qBAOa,mEAAmB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.mts","names":[],"sources":["../../src/extensions/server.ts"],"mappings":";qBAOa,mEAAmB"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{PACKAGE_SOURCE as e}from"../src/constants/workflow.mjs";import{createWorkflowServerRuntime as t}from"../src/controllers/serverRuntime.mjs";import{createWorkflowCatalogChannel as n}from"../src/controllers/workflowCatalogChannel.mjs";import{api as r}from"../src/controllers/workflowHubApi.mjs";import{createWorkflowsChannel as i}from"../src/controllers/workflowsHubChannel.mjs";import{defineServerPlugin as a}from"@agimon-ai/doompi-core/server-facet";const o=a({name:e,global:{channels:[i,n],api:[r]},workspace:{channels:[i,n],api:[r]},session:({agent:e,host:n})=>({api:[r],...e?t(e,n):{}})});export{o as default,o as workflowServerFacet};
|
|
2
|
+
//# sourceMappingURL=server.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.mjs","names":[],"sources":["../../src/extensions/server.ts"],"sourcesContent":["import { defineServerPlugin } from '@agimon-ai/doompi-core/server-facet';\n\nimport { PACKAGE_SOURCE } from '../constants/workflow';\nimport { createWorkflowServerRuntime } from '../controllers/serverRuntime';\nimport { createWorkflowCatalogChannel } from '../controllers/workflowCatalogChannel';\nimport { api } from '../controllers/workflowHubApi';\nimport { createWorkflowsChannel } from '../controllers/workflowsHubChannel';\nexport const workflowServerFacet = defineServerPlugin({\n name: PACKAGE_SOURCE,\n global: { channels: [createWorkflowsChannel, createWorkflowCatalogChannel], api: [api] },\n workspace: { channels: [createWorkflowsChannel, createWorkflowCatalogChannel], api: [api] },\n session: ({ agent, host }) => ({ api: [api], ...(agent ? createWorkflowServerRuntime(agent, host) : {}) }),\n});\nexport default workflowServerFacet;\n"],"mappings":"wcAOA,MAAa,EAAsB,EAAmB,CACpD,KAAM,EACN,OAAQ,CAAE,SAAU,CAAC,EAAwB,CAA4B,EAAG,IAAK,CAAC,CAAG,CAAE,EACvF,UAAW,CAAE,SAAU,CAAC,EAAwB,CAA4B,EAAG,IAAK,CAAC,CAAG,CAAE,EAC1F,SAAU,CAAE,QAAO,WAAY,CAAE,IAAK,CAAC,CAAG,EAAG,GAAI,EAAQ,EAA4B,EAAO,CAAI,EAAI,CAAC,CAAG,EAC1G,CAAC"}
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./src/services/workflowLaunchCommand/index.cjs");exports.parseWorkflowLaunchCommand=e.parseWorkflowLaunchCommand,exports.validateWorkflowLaunch=e.validateWorkflowLaunch;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
export { registerWorkflowDispatcherExtension, registerWorkflowExtension };
|
|
1
|
+
import { parseWorkflowLaunchCommand, validateWorkflowLaunch } from "./src/services/workflowLaunchCommand/index.cjs";
|
|
2
|
+
export { parseWorkflowLaunchCommand, validateWorkflowLaunch };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
export { registerWorkflowDispatcherExtension, registerWorkflowExtension };
|
|
1
|
+
import { parseWorkflowLaunchCommand, validateWorkflowLaunch } from "./src/services/workflowLaunchCommand/index.mjs";
|
|
2
|
+
export { parseWorkflowLaunchCommand, validateWorkflowLaunch };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{parseWorkflowLaunchCommand as e,validateWorkflowLaunch as t}from"./src/services/workflowLaunchCommand/index.mjs";export{e as parseWorkflowLaunchCommand,t as validateWorkflowLaunch};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=`list_workflows`,t=`launch_workflow`,n=`workflow_run`,r=[e,t,n];exports.LAUNCH_WORKFLOW_TOOL_NAME=t,exports.LEADER_CATALOG_ACTION=`workflow.catalog`,exports.LEADER_DETAIL=`multi-step agent runs`,exports.LEADER_DISABLE_ACTION=`workflow.disable`,exports.LEADER_ENABLE_ACTION=`workflow.enable`,exports.LEADER_LABEL=`workflows`,exports.LEADER_MANAGE_ACTION=`workflow.manage`,exports.LEADER_RECOVER_ACTION=`workflow.recover`,exports.LIST_WORKFLOWS_TOOL_NAME=e,exports.PACKAGE_SOURCE=`@agimon-ai/doompi-workflow`,exports.WORKFLOW_PI_TOOL_NAMES=r,exports.WORKFLOW_RUN_TOOL_NAME=n;
|
|
2
|
+
//# sourceMappingURL=workflow.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.cjs","names":[],"sources":["../../../src/constants/workflow.ts"],"sourcesContent":["export const COMMAND_DESCRIPTION = 'Doom Pi workflow execution and monitoring integration';\nexport const PACKAGE_SOURCE = '@agimon-ai/doompi-workflow';\n\nexport const LEADER_KEY = 'w';\nexport const LEADER_LABEL = 'workflows';\nexport const LEADER_ORDER = 50;\nexport const LEADER_ENABLE_ACTION = 'workflow.enable';\nexport const LEADER_DISABLE_ACTION = 'workflow.disable';\nexport const LEADER_MANAGE_ACTION = 'workflow.manage';\nexport const LEADER_RECOVER_ACTION = 'workflow.recover';\nexport const LEADER_CATALOG_ACTION = 'workflow.catalog';\nexport const LEADER_DETAIL = 'multi-step agent runs';\n\nexport const LIST_WORKFLOWS_TOOL_NAME = 'list_workflows';\nexport const LAUNCH_WORKFLOW_TOOL_NAME = 'launch_workflow';\nexport const WORKFLOW_RUN_TOOL_NAME = 'workflow_run';\nexport const WORKFLOW_PI_TOOL_NAMES = [\n LIST_WORKFLOWS_TOOL_NAME,\n LAUNCH_WORKFLOW_TOOL_NAME,\n WORKFLOW_RUN_TOOL_NAME,\n] as const;\n"],"mappings":"AACA,MAYa,EAA2B,iBAC3B,EAA4B,kBAC5B,EAAyB,eACzB,EAAyB,CACpC,EACA,EACA,CACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=`@agimon-ai/doompi-workflow`,t=`workflows`,n=`workflow.enable`,r=`workflow.disable`,i=`workflow.manage`,a=`workflow.recover`,o=`workflow.catalog`,s=`multi-step agent runs`,c=`list_workflows`,l=`launch_workflow`,u=`workflow_run`,d=[c,l,u];export{l as LAUNCH_WORKFLOW_TOOL_NAME,o as LEADER_CATALOG_ACTION,s as LEADER_DETAIL,r as LEADER_DISABLE_ACTION,n as LEADER_ENABLE_ACTION,t as LEADER_LABEL,i as LEADER_MANAGE_ACTION,a as LEADER_RECOVER_ACTION,c as LIST_WORKFLOWS_TOOL_NAME,e as PACKAGE_SOURCE,d as WORKFLOW_PI_TOOL_NAMES,u as WORKFLOW_RUN_TOOL_NAME};
|
|
2
|
+
//# sourceMappingURL=workflow.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.mjs","names":[],"sources":["../../../src/constants/workflow.ts"],"sourcesContent":["export const COMMAND_DESCRIPTION = 'Doom Pi workflow execution and monitoring integration';\nexport const PACKAGE_SOURCE = '@agimon-ai/doompi-workflow';\n\nexport const LEADER_KEY = 'w';\nexport const LEADER_LABEL = 'workflows';\nexport const LEADER_ORDER = 50;\nexport const LEADER_ENABLE_ACTION = 'workflow.enable';\nexport const LEADER_DISABLE_ACTION = 'workflow.disable';\nexport const LEADER_MANAGE_ACTION = 'workflow.manage';\nexport const LEADER_RECOVER_ACTION = 'workflow.recover';\nexport const LEADER_CATALOG_ACTION = 'workflow.catalog';\nexport const LEADER_DETAIL = 'multi-step agent runs';\n\nexport const LIST_WORKFLOWS_TOOL_NAME = 'list_workflows';\nexport const LAUNCH_WORKFLOW_TOOL_NAME = 'launch_workflow';\nexport const WORKFLOW_RUN_TOOL_NAME = 'workflow_run';\nexport const WORKFLOW_PI_TOOL_NAMES = [\n LIST_WORKFLOWS_TOOL_NAME,\n LAUNCH_WORKFLOW_TOOL_NAME,\n WORKFLOW_RUN_TOOL_NAME,\n] as const;\n"],"mappings":"AACA,MAAa,EAAiB,6BAGjB,EAAe,YAEf,EAAuB,kBACvB,EAAwB,mBACxB,EAAuB,kBACvB,EAAwB,mBACxB,EAAwB,mBACxB,EAAgB,wBAEhB,EAA2B,iBAC3B,EAA4B,kBAC5B,EAAyB,eACzB,EAAyB,CACpC,EACA,EACA,CACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("../services/workflowLaunchCommand/index.cjs"),t=require("../services/workflowResource/index.cjs"),n=require("../services/webWorkflowCatalog/index.cjs"),r=require("../services/workflowCatalogDeps/index.cjs"),i=require("../services/workflowRuns/index.cjs"),a=require("../services/workflowWatcher/index.cjs"),o=require("../types/webWorkflows.cjs");let s=require("@agimon-ai/workflow-mcp"),c=require("zod"),l=require("@agimon-ai/doompi-minor-mode");const u=`@agimon-ai/doompi-workflow`,d=`workflow`,f=`list_workflows`,p=`launch_workflow`,m=`workflow_run`;function h(e){let t=[];if(typeof e==`object`&&e&&`content`in e&&Array.isArray(e.content))for(let n of e.content){if(typeof n!=`object`||!n||!(`type`in n))continue;let e=n;e.type===`text`&&typeof e.text==`string`?t.push({type:`text`,text:e.text}):e.type===`image`&&typeof e.data==`string`&&typeof e.mimeType==`string`&&t.push({type:`image`,data:e.data,mimeType:e.mimeType})}return t.length===0&&t.push({type:`text`,text:JSON.stringify(e,null,2)}),{content:t,details:e}}function g(g,_){if(_.context.directEvents===void 0)throw Error(`Workflow headless facet requires the session direct event bus.`);let v=_.context.directEvents,y=n.createWorkflowCatalogReader(r.defaultCatalogDeps()),b=async e=>{let t=i.presentWorkflowRuns(a.readWorkflowRuns({environment:e.environment}).filter(t=>i.runBelongsToSession(t,e.sessionId)).map(e=>e.view),Date.now());v.publish(o.WORKFLOW_RUNS_TYPE,e.sessionId,{runs:t});try{v.publish(o.WORKFLOW_CATALOG_TYPE,e.sessionId,{cwd:e.cwd,workflows:n.presentWorkflowCatalog(await y.read(e.cwd))})}catch(t){let n=t instanceof Error?t.message:String(t);v.publish(o.WORKFLOW_CATALOG_TYPE,e.sessionId,{cwd:e.cwd,workflows:[],warning:n})}},x=(0,s.createEmbeddedWorkflowFeature)(),S=x.createListStatusesTool({recordFilter:e=>{let t=g.context.sessionId;return e.env?.PI_SESSION_ID===void 0||e.env.PI_SESSION_ID===t}}),C,w,T=()=>(g.context.selection.state?.[`minor-mode`]??[]).includes(d),E=()=>{let e=T();return{activation:e?`active`:`inactive`,condition:`ready`,...e?{detail:`workflow tools available`}:{},actions:[{id:`activate`,enabled:!e,...e?{disabledReason:`Workflow mode is active.`}:{}},{id:`deactivate`,enabled:e,...e?{}:{disabledReason:`Workflow mode is inactive.`}}]}},D=async e=>{let t=(g.context.selection.state?.[`minor-mode`]??[]).filter(e=>e!==d);await g.changeSelection({axis:`state`,key:`minor-mode`,values:e?[...t,d]:t}),w?.publish()};return w=(0,l.defineMinorMode)({descriptor:{source:u,id:d,label:`Workflow`,description:`Workflow discovery, launch, inspection, control, and recovery tools.`,order:20,actions:[{id:`activate`,label:`Activate`,description:`Enable workflow tools for this session.`,contexts:[`headless`],parameters:[]},{id:`deactivate`,label:`Deactivate`,description:`Disable workflow tools without stopping active runs.`,contexts:[`headless`],parameters:[]}]},state:E,async handleAction(e,t,n,r){if(r.signal.throwIfAborted(),t===`activate`)return await D(!0),{message:`Workflow mode activated.`};if(t===`deactivate`)return await D(!1),{message:`Workflow mode deactivated.`};throw Error(`Unknown workflow mode action: ${t}`)}}).createOwner(void 0),{services:[(0,l.serverMinorModes)([w])],toolRestrictions:[{when:{state:{"minor-mode":d}},allowedTools:[f,p,m]}],hooks:[{event:`tool_execution_end`,handle:async(e,t)=>{await b(t)}},{when:{state:{"minor-mode":d},attribution:{kind:`minor`,mode:d}},event:`session_shutdown`,handle:()=>{C?.dispose(),C=void 0}}],resources:[{when:{state:{"minor-mode":d},attribution:{kind:`minor`,mode:d}},name:`doompi-author-workflow`,kind:`skill`,read:()=>t.readWorkflowSkill(`doompi-author-workflow`)},{when:{state:{"minor-mode":d},attribution:{kind:`minor`,mode:d}},name:`doompi-use-workflow`,kind:`skill`,read:()=>t.readWorkflowSkill(`doompi-use-workflow`)},{when:{state:{"minor-mode":d},attribution:{kind:`minor`,mode:d}},name:`workflow-recovery`,kind:`skill`,read:()=>t.readWorkflowSkill(`workflow-recovery`)}],activities:[{when:{state:{"minor-mode":d},attribution:{kind:`minor`,mode:d}},name:u,async start(e){return C=x.createRunControl({}),await C.start(),await b(e),()=>{C?.dispose(),C=void 0}}}],tools:[{when:{state:{"minor-mode":d},attribution:{kind:`minor`,mode:d}},name:f,label:`List Workflows`,description:`List workflow definitions available in this repository.`,parameters:c.z.toJSONSchema(x.listWorkflowsTool.getInputSchema()),executionMode:`serial`,async execute(e,t,n){return n?.throwIfAborted(),h(await x.listWorkflowsTool.execute(t))}},{when:{state:{"minor-mode":d},attribution:{kind:`minor`,mode:d}},name:p,label:`Launch Workflow`,description:`Start a workflow run and return its recorded launch result.`,parameters:c.z.toJSONSchema(x.runTool.getInputSchema()),executionMode:`serial`,async execute(e,t,n){return n?.throwIfAborted(),h(await x.runTool.execute(t))}},{when:{state:{"minor-mode":d},attribution:{kind:`minor`,mode:d}},name:m,label:`Workflow Run`,description:`Inspect the status of a workflow run or request cooperative control.`,parameters:{type:`object`,properties:{action:{type:`string`,enum:[`status`,`pause`,`resume`,`stop`]},runKey:{type:`string`,minLength:1},workspace:{type:`string`},reason:{type:`string`},expectedRunId:{type:`string`}},required:[`action`,`runKey`],additionalProperties:!1},executionMode:`serial`,async execute(e,t,n){n?.throwIfAborted();let r=t;return r.action===`status`?h(await S.execute({workspace:r.workspace,pageSize:100})):C?typeof r.expectedRunId!=`string`||r.expectedRunId.length===0?h({error:`expectedRunId is required for workflow control.`}):h(r.action===`pause`?await C.pause(r.runKey,r.expectedRunId,r.workspace,r.reason):r.action===`resume`?await C.resume(r.runKey,r.expectedRunId,r.workspace):await C.stop(r.runKey,r.expectedRunId,r.workspace,r.reason)):h({error:`Workflow activity is not active.`})}}],commands:[{when:{state:{"minor-mode":d},attribution:{kind:`minor`,mode:d}},name:`workflow-launch`,description:`Launch a workflow from a slash command.`,async execute(t,n){let r=e.parseWorkflowLaunchCommand(t);if(`error`in r){await n.client.notify({body:r.error,level:`error`});return}let i=h(await x.runTool.execute({workflowPath:r.workflow,...r.runner===void 0?{}:{runner:r.runner},...Object.keys(r.inputs).length===0?{}:{inputs:r.inputs},...r.prompt===void 0?{}:{prompt:r.prompt}})).content.find(e=>e.type===`text`);await n.client.notify({body:i?.type===`text`?i.text:`Workflow launch requested.`,level:`info`})}}],onDispose(){C?.dispose(),C=void 0}}}exports.createWorkflowServerRuntime=g;
|
|
2
|
+
//# sourceMappingURL=serverRuntime.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverRuntime.cjs","names":["createWorkflowCatalogReader","defaultCatalogDeps","presentWorkflowRuns","readWorkflowRuns","runBelongsToSession","WORKFLOW_RUNS_TYPE","WORKFLOW_CATALOG_TYPE","presentWorkflowCatalog","createEmbeddedWorkflowFeature","defineMinorMode","serverMinorModes","skill","z","parseWorkflowLaunchCommand"],"sources":["../../../src/controllers/serverRuntime.ts"],"sourcesContent":["import {\n type DoomHeadlessExecutionContext,\n type DoomHeadlessContent,\n type DoomHeadlessToolResult,\n} from '@agimon-ai/doompi-core/headless';\nimport { serverMinorModes } from '@agimon-ai/doompi-minor-mode';\nimport { defineMinorMode, type MinorModeOwner, type MinorModeState } from '@agimon-ai/doompi-minor-mode';\nimport { createEmbeddedWorkflowFeature } from '@agimon-ai/workflow-mcp';\nimport { z } from 'zod';\n\nimport { createWorkflowCatalogReader, presentWorkflowCatalog } from '../services/webWorkflowCatalog';\nimport { defaultCatalogDeps } from '../services/workflowCatalogDeps';\nimport { parseWorkflowLaunchCommand } from '../services/workflowLaunchCommand';\nimport { readWorkflowSkill as skill } from '../services/workflowResource';\nimport { presentWorkflowRuns, runBelongsToSession } from '../services/workflowRuns';\nimport { readWorkflowRuns } from '../services/workflowWatcher';\nimport { WORKFLOW_CATALOG_TYPE, WORKFLOW_RUNS_TYPE } from '../types/webWorkflows';\n\nconst SOURCE = '@agimon-ai/doompi-workflow';\nconst WORKFLOW_MODE_ID = 'workflow';\nconst LIST_TOOL = 'list_workflows';\nconst LAUNCH_TOOL = 'launch_workflow';\nconst RUN_TOOL = 'workflow_run';\n\nfunction callResult(value: unknown): DoomHeadlessToolResult {\n const content: DoomHeadlessContent[] = [];\n if (typeof value === 'object' && value !== null && 'content' in value && Array.isArray(value.content)) {\n for (const item of value.content) {\n if (typeof item !== 'object' || item === null || !('type' in item)) continue;\n const record = item as Record<string, unknown>;\n if (record.type === 'text' && typeof record.text === 'string') content.push({ type: 'text', text: record.text });\n else if (record.type === 'image' && typeof record.data === 'string' && typeof record.mimeType === 'string') {\n content.push({ type: 'image', data: record.data, mimeType: record.mimeType });\n }\n }\n }\n if (content.length === 0) content.push({ type: 'text', text: JSON.stringify(value, null, 2) });\n return { content, details: value };\n}\n\nimport { type DoomHeadlessHostService } from '@agimon-ai/doompi-core/headless';\nimport { type DoomServerHostService, type DoomServerSessionPlugin } from '@agimon-ai/doompi-core/server-facet';\nexport function createWorkflowServerRuntime(\n host: DoomHeadlessHostService,\n serverHost: DoomServerHostService,\n): DoomServerSessionPlugin {\n if (serverHost.context.directEvents === undefined)\n throw new Error('Workflow headless facet requires the session direct event bus.');\n const directEvents = serverHost.context.directEvents;\n const catalogReader = createWorkflowCatalogReader(defaultCatalogDeps());\n const publishLifecycle = async (executionContext: typeof host.context): Promise<void> => {\n const runs = presentWorkflowRuns(\n readWorkflowRuns({ environment: executionContext.environment })\n .filter((run) => runBelongsToSession(run, executionContext.sessionId))\n .map((run) => run.view),\n Date.now(),\n );\n directEvents.publish(WORKFLOW_RUNS_TYPE, executionContext.sessionId, { runs });\n try {\n directEvents.publish(WORKFLOW_CATALOG_TYPE, executionContext.sessionId, {\n cwd: executionContext.cwd,\n workflows: presentWorkflowCatalog(await catalogReader.read(executionContext.cwd)),\n });\n } catch (error) {\n const warning = error instanceof Error ? error.message : String(error);\n directEvents.publish(WORKFLOW_CATALOG_TYPE, executionContext.sessionId, {\n cwd: executionContext.cwd,\n workflows: [],\n warning,\n });\n }\n };\n const feature = createEmbeddedWorkflowFeature();\n const statuses = feature.createListStatusesTool({\n recordFilter: (record) => {\n const sessionId = host.context.sessionId;\n return record.env?.PI_SESSION_ID === undefined || record.env.PI_SESSION_ID === sessionId;\n },\n });\n let control: ReturnType<typeof feature.createRunControl> | undefined;\n let modeOwner: MinorModeOwner | undefined;\n const modeSelected = (): boolean => (host.context.selection.state?.['minor-mode'] ?? []).includes(WORKFLOW_MODE_ID);\n const modeState = (): MinorModeState => {\n const active = modeSelected();\n return {\n activation: active ? 'active' : 'inactive',\n condition: 'ready',\n ...(active ? { detail: 'workflow tools available' } : {}),\n actions: [\n { id: 'activate', enabled: !active, ...(!active ? {} : { disabledReason: 'Workflow mode is active.' }) },\n { id: 'deactivate', enabled: active, ...(active ? {} : { disabledReason: 'Workflow mode is inactive.' }) },\n ],\n };\n };\n const selectMode = async (enabled: boolean): Promise<void> => {\n const modes = (host.context.selection.state?.['minor-mode'] ?? []).filter((mode) => mode !== WORKFLOW_MODE_ID);\n await host.changeSelection({\n axis: 'state',\n key: 'minor-mode',\n values: enabled ? [...modes, WORKFLOW_MODE_ID] : modes,\n });\n modeOwner?.publish();\n };\n modeOwner = defineMinorMode({\n descriptor: {\n source: SOURCE,\n id: WORKFLOW_MODE_ID,\n label: 'Workflow',\n description: 'Workflow discovery, launch, inspection, control, and recovery tools.',\n order: 20,\n actions: [\n {\n id: 'activate',\n label: 'Activate',\n description: 'Enable workflow tools for this session.',\n contexts: ['headless'],\n parameters: [],\n },\n {\n id: 'deactivate',\n label: 'Deactivate',\n description: 'Disable workflow tools without stopping active runs.',\n contexts: ['headless'],\n parameters: [],\n },\n ],\n },\n state: modeState,\n async handleAction(_runtime, actionId, _argumentsValue, execution) {\n execution.signal.throwIfAborted();\n if (actionId === 'activate') {\n await selectMode(true);\n return { message: 'Workflow mode activated.' };\n }\n if (actionId === 'deactivate') {\n await selectMode(false);\n return { message: 'Workflow mode deactivated.' };\n }\n throw new Error(`Unknown workflow mode action: ${actionId}`);\n },\n }).createOwner(undefined);\n return {\n services: [serverMinorModes([modeOwner])],\n toolRestrictions: [\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID } },\n allowedTools: [LIST_TOOL, LAUNCH_TOOL, RUN_TOOL],\n },\n ],\n hooks: [\n {\n event: 'tool_execution_end',\n handle: async (_event, executionContext) => {\n await publishLifecycle(executionContext);\n },\n },\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n event: 'session_shutdown',\n handle: () => {\n control?.dispose();\n control = undefined;\n },\n },\n ],\n resources: [\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: 'doompi-author-workflow',\n kind: 'skill',\n read: () => skill('doompi-author-workflow'),\n },\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: 'doompi-use-workflow',\n kind: 'skill',\n read: () => skill('doompi-use-workflow'),\n },\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: 'workflow-recovery',\n kind: 'skill',\n read: () => skill('workflow-recovery'),\n },\n ],\n activities: [\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: SOURCE,\n async start(executionContext) {\n control = feature.createRunControl({});\n await control.start();\n await publishLifecycle(executionContext);\n return () => {\n control?.dispose();\n control = undefined;\n };\n },\n },\n ],\n tools: [\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: LIST_TOOL,\n label: 'List Workflows',\n description: 'List workflow definitions available in this repository.',\n parameters: z.toJSONSchema(feature.listWorkflowsTool.getInputSchema()),\n executionMode: 'serial',\n async execute(_toolCallId, parameters, signal) {\n signal?.throwIfAborted();\n return callResult(\n await feature.listWorkflowsTool.execute(\n parameters as Parameters<typeof feature.listWorkflowsTool.execute>[0],\n ),\n );\n },\n },\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: LAUNCH_TOOL,\n label: 'Launch Workflow',\n description: 'Start a workflow run and return its recorded launch result.',\n parameters: z.toJSONSchema(feature.runTool.getInputSchema()),\n executionMode: 'serial',\n async execute(_toolCallId, parameters, signal) {\n signal?.throwIfAborted();\n return callResult(await feature.runTool.execute(parameters as Parameters<typeof feature.runTool.execute>[0]));\n },\n },\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: RUN_TOOL,\n label: 'Workflow Run',\n description: 'Inspect the status of a workflow run or request cooperative control.',\n parameters: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['status', 'pause', 'resume', 'stop'] },\n runKey: { type: 'string', minLength: 1 },\n workspace: { type: 'string' },\n reason: { type: 'string' },\n expectedRunId: { type: 'string' },\n },\n required: ['action', 'runKey'],\n additionalProperties: false,\n },\n executionMode: 'serial',\n async execute(_toolCallId, parameters, signal) {\n signal?.throwIfAborted();\n const input = parameters as unknown as {\n action: 'status' | 'pause' | 'resume' | 'stop';\n runKey: string;\n workspace?: string;\n reason?: string;\n expectedRunId?: string;\n };\n if (input.action === 'status')\n return callResult(await statuses.execute({ workspace: input.workspace, pageSize: 100 }));\n if (!control) return callResult({ error: 'Workflow activity is not active.' });\n if (typeof input.expectedRunId !== 'string' || input.expectedRunId.length === 0) {\n return callResult({ error: 'expectedRunId is required for workflow control.' });\n }\n const request =\n input.action === 'pause'\n ? await control.pause(input.runKey, input.expectedRunId, input.workspace, input.reason)\n : input.action === 'resume'\n ? await control.resume(input.runKey, input.expectedRunId, input.workspace)\n : await control.stop(input.runKey, input.expectedRunId, input.workspace, input.reason);\n return callResult(request);\n },\n },\n ],\n commands: [\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: 'workflow-launch',\n description: 'Launch a workflow from a slash command.',\n async execute(args: string, execution: DoomHeadlessExecutionContext) {\n const parsed = parseWorkflowLaunchCommand(args);\n if ('error' in parsed) {\n await execution.client.notify({ body: parsed.error, level: 'error' });\n return;\n }\n const result = await feature.runTool.execute({\n workflowPath: parsed.workflow,\n ...(parsed.runner === undefined ? {} : { runner: parsed.runner }),\n ...(Object.keys(parsed.inputs).length === 0 ? {} : { inputs: parsed.inputs }),\n ...(parsed.prompt === undefined ? {} : { prompt: parsed.prompt }),\n });\n const rendered = callResult(result).content.find((entry) => entry.type === 'text');\n await execution.client.notify({\n body: rendered?.type === 'text' ? rendered.text : 'Workflow launch requested.',\n level: 'info',\n });\n },\n },\n ],\n onDispose() {\n control?.dispose();\n control = undefined;\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{parseWorkflowLaunchCommand as e}from"../services/workflowLaunchCommand/index.mjs";import{readWorkflowSkill as t}from"../services/workflowResource/index.mjs";import{createWorkflowCatalogReader as n,presentWorkflowCatalog as r}from"../services/webWorkflowCatalog/index.mjs";import{defaultCatalogDeps as i}from"../services/workflowCatalogDeps/index.mjs";import{presentWorkflowRuns as a,runBelongsToSession as o}from"../services/workflowRuns/index.mjs";import{readWorkflowRuns as s}from"../services/workflowWatcher/index.mjs";import{WORKFLOW_CATALOG_TYPE as c,WORKFLOW_RUNS_TYPE as l}from"../types/webWorkflows.mjs";import{createEmbeddedWorkflowFeature as u}from"@agimon-ai/workflow-mcp";import{z as d}from"zod";import{defineMinorMode as f,serverMinorModes as p}from"@agimon-ai/doompi-minor-mode";const m=`@agimon-ai/doompi-workflow`,h=`workflow`,g=`list_workflows`,_=`launch_workflow`,v=`workflow_run`;function y(e){let t=[];if(typeof e==`object`&&e&&`content`in e&&Array.isArray(e.content))for(let n of e.content){if(typeof n!=`object`||!n||!(`type`in n))continue;let e=n;e.type===`text`&&typeof e.text==`string`?t.push({type:`text`,text:e.text}):e.type===`image`&&typeof e.data==`string`&&typeof e.mimeType==`string`&&t.push({type:`image`,data:e.data,mimeType:e.mimeType})}return t.length===0&&t.push({type:`text`,text:JSON.stringify(e,null,2)}),{content:t,details:e}}function b(b,x){if(x.context.directEvents===void 0)throw Error(`Workflow headless facet requires the session direct event bus.`);let S=x.context.directEvents,C=n(i()),w=async e=>{let t=a(s({environment:e.environment}).filter(t=>o(t,e.sessionId)).map(e=>e.view),Date.now());S.publish(l,e.sessionId,{runs:t});try{S.publish(c,e.sessionId,{cwd:e.cwd,workflows:r(await C.read(e.cwd))})}catch(t){let n=t instanceof Error?t.message:String(t);S.publish(c,e.sessionId,{cwd:e.cwd,workflows:[],warning:n})}},T=u(),E=T.createListStatusesTool({recordFilter:e=>{let t=b.context.sessionId;return e.env?.PI_SESSION_ID===void 0||e.env.PI_SESSION_ID===t}}),D,O,k=()=>(b.context.selection.state?.[`minor-mode`]??[]).includes(h),A=()=>{let e=k();return{activation:e?`active`:`inactive`,condition:`ready`,...e?{detail:`workflow tools available`}:{},actions:[{id:`activate`,enabled:!e,...e?{disabledReason:`Workflow mode is active.`}:{}},{id:`deactivate`,enabled:e,...e?{}:{disabledReason:`Workflow mode is inactive.`}}]}},j=async e=>{let t=(b.context.selection.state?.[`minor-mode`]??[]).filter(e=>e!==h);await b.changeSelection({axis:`state`,key:`minor-mode`,values:e?[...t,h]:t}),O?.publish()};return O=f({descriptor:{source:m,id:h,label:`Workflow`,description:`Workflow discovery, launch, inspection, control, and recovery tools.`,order:20,actions:[{id:`activate`,label:`Activate`,description:`Enable workflow tools for this session.`,contexts:[`headless`],parameters:[]},{id:`deactivate`,label:`Deactivate`,description:`Disable workflow tools without stopping active runs.`,contexts:[`headless`],parameters:[]}]},state:A,async handleAction(e,t,n,r){if(r.signal.throwIfAborted(),t===`activate`)return await j(!0),{message:`Workflow mode activated.`};if(t===`deactivate`)return await j(!1),{message:`Workflow mode deactivated.`};throw Error(`Unknown workflow mode action: ${t}`)}}).createOwner(void 0),{services:[p([O])],toolRestrictions:[{when:{state:{"minor-mode":h}},allowedTools:[g,_,v]}],hooks:[{event:`tool_execution_end`,handle:async(e,t)=>{await w(t)}},{when:{state:{"minor-mode":h},attribution:{kind:`minor`,mode:h}},event:`session_shutdown`,handle:()=>{D?.dispose(),D=void 0}}],resources:[{when:{state:{"minor-mode":h},attribution:{kind:`minor`,mode:h}},name:`doompi-author-workflow`,kind:`skill`,read:()=>t(`doompi-author-workflow`)},{when:{state:{"minor-mode":h},attribution:{kind:`minor`,mode:h}},name:`doompi-use-workflow`,kind:`skill`,read:()=>t(`doompi-use-workflow`)},{when:{state:{"minor-mode":h},attribution:{kind:`minor`,mode:h}},name:`workflow-recovery`,kind:`skill`,read:()=>t(`workflow-recovery`)}],activities:[{when:{state:{"minor-mode":h},attribution:{kind:`minor`,mode:h}},name:m,async start(e){return D=T.createRunControl({}),await D.start(),await w(e),()=>{D?.dispose(),D=void 0}}}],tools:[{when:{state:{"minor-mode":h},attribution:{kind:`minor`,mode:h}},name:g,label:`List Workflows`,description:`List workflow definitions available in this repository.`,parameters:d.toJSONSchema(T.listWorkflowsTool.getInputSchema()),executionMode:`serial`,async execute(e,t,n){return n?.throwIfAborted(),y(await T.listWorkflowsTool.execute(t))}},{when:{state:{"minor-mode":h},attribution:{kind:`minor`,mode:h}},name:_,label:`Launch Workflow`,description:`Start a workflow run and return its recorded launch result.`,parameters:d.toJSONSchema(T.runTool.getInputSchema()),executionMode:`serial`,async execute(e,t,n){return n?.throwIfAborted(),y(await T.runTool.execute(t))}},{when:{state:{"minor-mode":h},attribution:{kind:`minor`,mode:h}},name:v,label:`Workflow Run`,description:`Inspect the status of a workflow run or request cooperative control.`,parameters:{type:`object`,properties:{action:{type:`string`,enum:[`status`,`pause`,`resume`,`stop`]},runKey:{type:`string`,minLength:1},workspace:{type:`string`},reason:{type:`string`},expectedRunId:{type:`string`}},required:[`action`,`runKey`],additionalProperties:!1},executionMode:`serial`,async execute(e,t,n){n?.throwIfAborted();let r=t;return r.action===`status`?y(await E.execute({workspace:r.workspace,pageSize:100})):D?typeof r.expectedRunId!=`string`||r.expectedRunId.length===0?y({error:`expectedRunId is required for workflow control.`}):y(r.action===`pause`?await D.pause(r.runKey,r.expectedRunId,r.workspace,r.reason):r.action===`resume`?await D.resume(r.runKey,r.expectedRunId,r.workspace):await D.stop(r.runKey,r.expectedRunId,r.workspace,r.reason)):y({error:`Workflow activity is not active.`})}}],commands:[{when:{state:{"minor-mode":h},attribution:{kind:`minor`,mode:h}},name:`workflow-launch`,description:`Launch a workflow from a slash command.`,async execute(t,n){let r=e(t);if(`error`in r){await n.client.notify({body:r.error,level:`error`});return}let i=y(await T.runTool.execute({workflowPath:r.workflow,...r.runner===void 0?{}:{runner:r.runner},...Object.keys(r.inputs).length===0?{}:{inputs:r.inputs},...r.prompt===void 0?{}:{prompt:r.prompt}})).content.find(e=>e.type===`text`);await n.client.notify({body:i?.type===`text`?i.text:`Workflow launch requested.`,level:`info`})}}],onDispose(){D?.dispose(),D=void 0}}}export{b as createWorkflowServerRuntime};
|
|
2
|
+
//# sourceMappingURL=serverRuntime.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverRuntime.mjs","names":["skill"],"sources":["../../../src/controllers/serverRuntime.ts"],"sourcesContent":["import {\n type DoomHeadlessExecutionContext,\n type DoomHeadlessContent,\n type DoomHeadlessToolResult,\n} from '@agimon-ai/doompi-core/headless';\nimport { serverMinorModes } from '@agimon-ai/doompi-minor-mode';\nimport { defineMinorMode, type MinorModeOwner, type MinorModeState } from '@agimon-ai/doompi-minor-mode';\nimport { createEmbeddedWorkflowFeature } from '@agimon-ai/workflow-mcp';\nimport { z } from 'zod';\n\nimport { createWorkflowCatalogReader, presentWorkflowCatalog } from '../services/webWorkflowCatalog';\nimport { defaultCatalogDeps } from '../services/workflowCatalogDeps';\nimport { parseWorkflowLaunchCommand } from '../services/workflowLaunchCommand';\nimport { readWorkflowSkill as skill } from '../services/workflowResource';\nimport { presentWorkflowRuns, runBelongsToSession } from '../services/workflowRuns';\nimport { readWorkflowRuns } from '../services/workflowWatcher';\nimport { WORKFLOW_CATALOG_TYPE, WORKFLOW_RUNS_TYPE } from '../types/webWorkflows';\n\nconst SOURCE = '@agimon-ai/doompi-workflow';\nconst WORKFLOW_MODE_ID = 'workflow';\nconst LIST_TOOL = 'list_workflows';\nconst LAUNCH_TOOL = 'launch_workflow';\nconst RUN_TOOL = 'workflow_run';\n\nfunction callResult(value: unknown): DoomHeadlessToolResult {\n const content: DoomHeadlessContent[] = [];\n if (typeof value === 'object' && value !== null && 'content' in value && Array.isArray(value.content)) {\n for (const item of value.content) {\n if (typeof item !== 'object' || item === null || !('type' in item)) continue;\n const record = item as Record<string, unknown>;\n if (record.type === 'text' && typeof record.text === 'string') content.push({ type: 'text', text: record.text });\n else if (record.type === 'image' && typeof record.data === 'string' && typeof record.mimeType === 'string') {\n content.push({ type: 'image', data: record.data, mimeType: record.mimeType });\n }\n }\n }\n if (content.length === 0) content.push({ type: 'text', text: JSON.stringify(value, null, 2) });\n return { content, details: value };\n}\n\nimport { type DoomHeadlessHostService } from '@agimon-ai/doompi-core/headless';\nimport { type DoomServerHostService, type DoomServerSessionPlugin } from '@agimon-ai/doompi-core/server-facet';\nexport function createWorkflowServerRuntime(\n host: DoomHeadlessHostService,\n serverHost: DoomServerHostService,\n): DoomServerSessionPlugin {\n if (serverHost.context.directEvents === undefined)\n throw new Error('Workflow headless facet requires the session direct event bus.');\n const directEvents = serverHost.context.directEvents;\n const catalogReader = createWorkflowCatalogReader(defaultCatalogDeps());\n const publishLifecycle = async (executionContext: typeof host.context): Promise<void> => {\n const runs = presentWorkflowRuns(\n readWorkflowRuns({ environment: executionContext.environment })\n .filter((run) => runBelongsToSession(run, executionContext.sessionId))\n .map((run) => run.view),\n Date.now(),\n );\n directEvents.publish(WORKFLOW_RUNS_TYPE, executionContext.sessionId, { runs });\n try {\n directEvents.publish(WORKFLOW_CATALOG_TYPE, executionContext.sessionId, {\n cwd: executionContext.cwd,\n workflows: presentWorkflowCatalog(await catalogReader.read(executionContext.cwd)),\n });\n } catch (error) {\n const warning = error instanceof Error ? error.message : String(error);\n directEvents.publish(WORKFLOW_CATALOG_TYPE, executionContext.sessionId, {\n cwd: executionContext.cwd,\n workflows: [],\n warning,\n });\n }\n };\n const feature = createEmbeddedWorkflowFeature();\n const statuses = feature.createListStatusesTool({\n recordFilter: (record) => {\n const sessionId = host.context.sessionId;\n return record.env?.PI_SESSION_ID === undefined || record.env.PI_SESSION_ID === sessionId;\n },\n });\n let control: ReturnType<typeof feature.createRunControl> | undefined;\n let modeOwner: MinorModeOwner | undefined;\n const modeSelected = (): boolean => (host.context.selection.state?.['minor-mode'] ?? []).includes(WORKFLOW_MODE_ID);\n const modeState = (): MinorModeState => {\n const active = modeSelected();\n return {\n activation: active ? 'active' : 'inactive',\n condition: 'ready',\n ...(active ? { detail: 'workflow tools available' } : {}),\n actions: [\n { id: 'activate', enabled: !active, ...(!active ? {} : { disabledReason: 'Workflow mode is active.' }) },\n { id: 'deactivate', enabled: active, ...(active ? {} : { disabledReason: 'Workflow mode is inactive.' }) },\n ],\n };\n };\n const selectMode = async (enabled: boolean): Promise<void> => {\n const modes = (host.context.selection.state?.['minor-mode'] ?? []).filter((mode) => mode !== WORKFLOW_MODE_ID);\n await host.changeSelection({\n axis: 'state',\n key: 'minor-mode',\n values: enabled ? [...modes, WORKFLOW_MODE_ID] : modes,\n });\n modeOwner?.publish();\n };\n modeOwner = defineMinorMode({\n descriptor: {\n source: SOURCE,\n id: WORKFLOW_MODE_ID,\n label: 'Workflow',\n description: 'Workflow discovery, launch, inspection, control, and recovery tools.',\n order: 20,\n actions: [\n {\n id: 'activate',\n label: 'Activate',\n description: 'Enable workflow tools for this session.',\n contexts: ['headless'],\n parameters: [],\n },\n {\n id: 'deactivate',\n label: 'Deactivate',\n description: 'Disable workflow tools without stopping active runs.',\n contexts: ['headless'],\n parameters: [],\n },\n ],\n },\n state: modeState,\n async handleAction(_runtime, actionId, _argumentsValue, execution) {\n execution.signal.throwIfAborted();\n if (actionId === 'activate') {\n await selectMode(true);\n return { message: 'Workflow mode activated.' };\n }\n if (actionId === 'deactivate') {\n await selectMode(false);\n return { message: 'Workflow mode deactivated.' };\n }\n throw new Error(`Unknown workflow mode action: ${actionId}`);\n },\n }).createOwner(undefined);\n return {\n services: [serverMinorModes([modeOwner])],\n toolRestrictions: [\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID } },\n allowedTools: [LIST_TOOL, LAUNCH_TOOL, RUN_TOOL],\n },\n ],\n hooks: [\n {\n event: 'tool_execution_end',\n handle: async (_event, executionContext) => {\n await publishLifecycle(executionContext);\n },\n },\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n event: 'session_shutdown',\n handle: () => {\n control?.dispose();\n control = undefined;\n },\n },\n ],\n resources: [\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: 'doompi-author-workflow',\n kind: 'skill',\n read: () => skill('doompi-author-workflow'),\n },\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: 'doompi-use-workflow',\n kind: 'skill',\n read: () => skill('doompi-use-workflow'),\n },\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: 'workflow-recovery',\n kind: 'skill',\n read: () => skill('workflow-recovery'),\n },\n ],\n activities: [\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: SOURCE,\n async start(executionContext) {\n control = feature.createRunControl({});\n await control.start();\n await publishLifecycle(executionContext);\n return () => {\n control?.dispose();\n control = undefined;\n };\n },\n },\n ],\n tools: [\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: LIST_TOOL,\n label: 'List Workflows',\n description: 'List workflow definitions available in this repository.',\n parameters: z.toJSONSchema(feature.listWorkflowsTool.getInputSchema()),\n executionMode: 'serial',\n async execute(_toolCallId, parameters, signal) {\n signal?.throwIfAborted();\n return callResult(\n await feature.listWorkflowsTool.execute(\n parameters as Parameters<typeof feature.listWorkflowsTool.execute>[0],\n ),\n );\n },\n },\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: LAUNCH_TOOL,\n label: 'Launch Workflow',\n description: 'Start a workflow run and return its recorded launch result.',\n parameters: z.toJSONSchema(feature.runTool.getInputSchema()),\n executionMode: 'serial',\n async execute(_toolCallId, parameters, signal) {\n signal?.throwIfAborted();\n return callResult(await feature.runTool.execute(parameters as Parameters<typeof feature.runTool.execute>[0]));\n },\n },\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: RUN_TOOL,\n label: 'Workflow Run',\n description: 'Inspect the status of a workflow run or request cooperative control.',\n parameters: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['status', 'pause', 'resume', 'stop'] },\n runKey: { type: 'string', minLength: 1 },\n workspace: { type: 'string' },\n reason: { type: 'string' },\n expectedRunId: { type: 'string' },\n },\n required: ['action', 'runKey'],\n additionalProperties: false,\n },\n executionMode: 'serial',\n async execute(_toolCallId, parameters, signal) {\n signal?.throwIfAborted();\n const input = parameters as unknown as {\n action: 'status' | 'pause' | 'resume' | 'stop';\n runKey: string;\n workspace?: string;\n reason?: string;\n expectedRunId?: string;\n };\n if (input.action === 'status')\n return callResult(await statuses.execute({ workspace: input.workspace, pageSize: 100 }));\n if (!control) return callResult({ error: 'Workflow activity is not active.' });\n if (typeof input.expectedRunId !== 'string' || input.expectedRunId.length === 0) {\n return callResult({ error: 'expectedRunId is required for workflow control.' });\n }\n const request =\n input.action === 'pause'\n ? await control.pause(input.runKey, input.expectedRunId, input.workspace, input.reason)\n : input.action === 'resume'\n ? await control.resume(input.runKey, input.expectedRunId, input.workspace)\n : await control.stop(input.runKey, input.expectedRunId, input.workspace, input.reason);\n return callResult(request);\n },\n },\n ],\n commands: [\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: 'workflow-launch',\n description: 'Launch a workflow from a slash command.',\n async execute(args: string, execution: DoomHeadlessExecutionContext) {\n const parsed = parseWorkflowLaunchCommand(args);\n if ('error' in parsed) {\n await execution.client.notify({ body: parsed.error, level: 'error' });\n return;\n }\n const result = await feature.runTool.execute({\n workflowPath: parsed.workflow,\n ...(parsed.runner === undefined ? {} : { runner: parsed.runner }),\n ...(Object.keys(parsed.inputs).length === 0 ? {} : { inputs: parsed.inputs }),\n ...(parsed.prompt === undefined ? {} : { prompt: parsed.prompt }),\n });\n const rendered = callResult(result).content.find((entry) => entry.type === 'text');\n await execution.client.notify({\n body: rendered?.type === 'text' ? rendered.text : 'Workflow launch requested.',\n level: 'info',\n });\n },\n },\n ],\n onDispose() {\n control?.dispose();\n control = undefined;\n },\n };\n}\n"],"mappings":"gyBAkBA,MAAM,EAAS,6BACT,EAAmB,WACnB,EAAY,iBACZ,EAAc,kBACd,EAAW,eAEjB,SAAS,EAAW,EAAwC,CAC1D,IAAM,EAAiC,CAAC,EACxC,GAAI,OAAO,GAAU,UAAY,GAAkB,YAAa,GAAS,MAAM,QAAQ,EAAM,OAAO,EAClG,IAAK,IAAM,KAAQ,EAAM,QAAS,CAChC,GAAI,OAAO,GAAS,WAAY,GAAiB,EAAE,SAAU,GAAO,SACpE,IAAM,EAAS,EACX,EAAO,OAAS,QAAU,OAAO,EAAO,MAAS,SAAU,EAAQ,KAAK,CAAE,KAAM,OAAQ,KAAM,EAAO,IAAK,CAAC,EACtG,EAAO,OAAS,SAAW,OAAO,EAAO,MAAS,UAAY,OAAO,EAAO,UAAa,UAChG,EAAQ,KAAK,CAAE,KAAM,QAAS,KAAM,EAAO,KAAM,SAAU,EAAO,QAAS,CAAC,CAEhF,CAGF,OADI,EAAQ,SAAW,GAAG,EAAQ,KAAK,CAAE,KAAM,OAAQ,KAAM,KAAK,UAAU,EAAO,KAAM,CAAC,CAAE,CAAC,EACtF,CAAE,UAAS,QAAS,CAAM,CACnC,CAIA,SAAgB,EACd,EACA,EACyB,CACzB,GAAI,EAAW,QAAQ,eAAiB,IAAA,GACtC,MAAU,MAAM,gEAAgE,EAClF,IAAM,EAAe,EAAW,QAAQ,aAClC,EAAgB,EAA4B,EAAmB,CAAC,EAChE,EAAmB,KAAO,IAAyD,CACvF,IAAM,EAAO,EACX,EAAiB,CAAE,YAAa,EAAiB,WAAY,CAAC,CAAC,CAC5D,OAAQ,GAAQ,EAAoB,EAAK,EAAiB,SAAS,CAAC,CAAC,CACrE,IAAK,GAAQ,EAAI,IAAI,EACxB,KAAK,IAAI,CACX,EACA,EAAa,QAAQ,EAAoB,EAAiB,UAAW,CAAE,MAAK,CAAC,EAC7E,GAAI,CACF,EAAa,QAAQ,EAAuB,EAAiB,UAAW,CACtE,IAAK,EAAiB,IACtB,UAAW,EAAuB,MAAM,EAAc,KAAK,EAAiB,GAAG,CAAC,CAClF,CAAC,CACH,OAAS,EAAO,CACd,IAAM,EAAU,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EACrE,EAAa,QAAQ,EAAuB,EAAiB,UAAW,CACtE,IAAK,EAAiB,IACtB,UAAW,CAAC,EACZ,SACF,CAAC,CACH,CACF,EACM,EAAU,EAA8B,EACxC,EAAW,EAAQ,uBAAuB,CAC9C,aAAe,GAAW,CACxB,IAAM,EAAY,EAAK,QAAQ,UAC/B,OAAO,EAAO,KAAK,gBAAkB,IAAA,IAAa,EAAO,IAAI,gBAAkB,CACjF,CACF,CAAC,EACG,EACA,EACE,OAA+B,EAAK,QAAQ,UAAU,QAAQ,eAAiB,CAAC,EAAA,CAAG,SAAS,CAAgB,EAC5G,MAAkC,CACtC,IAAM,EAAS,EAAa,EAC5B,MAAO,CACL,WAAY,EAAS,SAAW,WAChC,UAAW,QACX,GAAI,EAAS,CAAE,OAAQ,0BAA2B,EAAI,CAAC,EACvD,QAAS,CACP,CAAE,GAAI,WAAY,QAAS,CAAC,EAAQ,GAAK,EAAc,CAAE,eAAgB,0BAA2B,EAAlD,CAAC,CAAoD,EACvG,CAAE,GAAI,aAAc,QAAS,EAAQ,GAAI,EAAS,CAAC,EAAI,CAAE,eAAgB,4BAA6B,CAAG,CAC3G,CACF,CACF,EACM,EAAa,KAAO,IAAoC,CAC5D,IAAM,GAAS,EAAK,QAAQ,UAAU,QAAQ,eAAiB,CAAC,EAAA,CAAG,OAAQ,GAAS,IAAS,CAAgB,EAC7G,MAAM,EAAK,gBAAgB,CACzB,KAAM,QACN,IAAK,aACL,OAAQ,EAAU,CAAC,GAAG,EAAO,CAAgB,EAAI,CACnD,CAAC,EACD,GAAW,QAAQ,CACrB,EAuCA,MAtCA,GAAY,EAAgB,CAC1B,WAAY,CACV,OAAQ,EACR,GAAI,EACJ,MAAO,WACP,YAAa,uEACb,MAAO,GACP,QAAS,CACP,CACE,GAAI,WACJ,MAAO,WACP,YAAa,0CACb,SAAU,CAAC,UAAU,EACrB,WAAY,CAAC,CACf,EACA,CACE,GAAI,aACJ,MAAO,aACP,YAAa,uDACb,SAAU,CAAC,UAAU,EACrB,WAAY,CAAC,CACf,CACF,CACF,EACA,MAAO,EACP,MAAM,aAAa,EAAU,EAAU,EAAiB,EAAW,CAEjE,GADA,EAAU,OAAO,eAAe,EAC5B,IAAa,WAEf,OADA,MAAM,EAAW,EAAI,EACd,CAAE,QAAS,0BAA2B,EAE/C,GAAI,IAAa,aAEf,OADA,MAAM,EAAW,EAAK,EACf,CAAE,QAAS,4BAA6B,EAEjD,MAAU,MAAM,iCAAiC,GAAU,CAC7D,CACF,CAAC,CAAC,CAAC,YAAY,IAAA,EAAS,EACjB,CACL,SAAU,CAAC,EAAiB,CAAC,CAAS,CAAC,CAAC,EACxC,iBAAkB,CAChB,CACE,KAAM,CAAE,MAAO,CAAE,aAAc,CAAiB,CAAE,EAClD,aAAc,CAAC,EAAW,EAAa,CAAQ,CACjD,CACF,EACA,MAAO,CACL,CACE,MAAO,qBACP,OAAQ,MAAO,EAAQ,IAAqB,CAC1C,MAAM,EAAiB,CAAgB,CACzC,CACF,EACA,CACE,KAAM,CAAE,MAAO,CAAE,aAAc,CAAiB,EAAG,YAAa,CAAE,KAAM,QAAS,KAAM,CAAiB,CAAE,EAC1G,MAAO,mBACP,WAAc,CACZ,GAAS,QAAQ,EACjB,EAAU,IAAA,EACZ,CACF,CACF,EACA,UAAW,CACT,CACE,KAAM,CAAE,MAAO,CAAE,aAAc,CAAiB,EAAG,YAAa,CAAE,KAAM,QAAS,KAAM,CAAiB,CAAE,EAC1G,KAAM,yBACN,KAAM,QACN,SAAYA,EAAM,wBAAwB,CAC5C,EACA,CACE,KAAM,CAAE,MAAO,CAAE,aAAc,CAAiB,EAAG,YAAa,CAAE,KAAM,QAAS,KAAM,CAAiB,CAAE,EAC1G,KAAM,sBACN,KAAM,QACN,SAAYA,EAAM,qBAAqB,CACzC,EACA,CACE,KAAM,CAAE,MAAO,CAAE,aAAc,CAAiB,EAAG,YAAa,CAAE,KAAM,QAAS,KAAM,CAAiB,CAAE,EAC1G,KAAM,oBACN,KAAM,QACN,SAAYA,EAAM,mBAAmB,CACvC,CACF,EACA,WAAY,CACV,CACE,KAAM,CAAE,MAAO,CAAE,aAAc,CAAiB,EAAG,YAAa,CAAE,KAAM,QAAS,KAAM,CAAiB,CAAE,EAC1G,KAAM,EACN,MAAM,MAAM,EAAkB,CAI5B,MAHA,GAAU,EAAQ,iBAAiB,CAAC,CAAC,EACrC,MAAM,EAAQ,MAAM,EACpB,MAAM,EAAiB,CAAgB,MAC1B,CACX,GAAS,QAAQ,EACjB,EAAU,IAAA,EACZ,CACF,CACF,CACF,EACA,MAAO,CACL,CACE,KAAM,CAAE,MAAO,CAAE,aAAc,CAAiB,EAAG,YAAa,CAAE,KAAM,QAAS,KAAM,CAAiB,CAAE,EAC1G,KAAM,EACN,MAAO,iBACP,YAAa,0DACb,WAAY,EAAE,aAAa,EAAQ,kBAAkB,eAAe,CAAC,EACrE,cAAe,SACf,MAAM,QAAQ,EAAa,EAAY,EAAQ,CAE7C,OADA,GAAQ,eAAe,EAChB,EACL,MAAM,EAAQ,kBAAkB,QAC9B,CACF,CACF,CACF,CACF,EACA,CACE,KAAM,CAAE,MAAO,CAAE,aAAc,CAAiB,EAAG,YAAa,CAAE,KAAM,QAAS,KAAM,CAAiB,CAAE,EAC1G,KAAM,EACN,MAAO,kBACP,YAAa,8DACb,WAAY,EAAE,aAAa,EAAQ,QAAQ,eAAe,CAAC,EAC3D,cAAe,SACf,MAAM,QAAQ,EAAa,EAAY,EAAQ,CAE7C,OADA,GAAQ,eAAe,EAChB,EAAW,MAAM,EAAQ,QAAQ,QAAQ,CAA2D,CAAC,CAC9G,CACF,EACA,CACE,KAAM,CAAE,MAAO,CAAE,aAAc,CAAiB,EAAG,YAAa,CAAE,KAAM,QAAS,KAAM,CAAiB,CAAE,EAC1G,KAAM,EACN,MAAO,eACP,YAAa,uEACb,WAAY,CACV,KAAM,SACN,WAAY,CACV,OAAQ,CAAE,KAAM,SAAU,KAAM,CAAC,SAAU,QAAS,SAAU,MAAM,CAAE,EACtE,OAAQ,CAAE,KAAM,SAAU,UAAW,CAAE,EACvC,UAAW,CAAE,KAAM,QAAS,EAC5B,OAAQ,CAAE,KAAM,QAAS,EACzB,cAAe,CAAE,KAAM,QAAS,CAClC,EACA,SAAU,CAAC,SAAU,QAAQ,EAC7B,qBAAsB,EACxB,EACA,cAAe,SACf,MAAM,QAAQ,EAAa,EAAY,EAAQ,CAC7C,GAAQ,eAAe,EACvB,IAAM,EAAQ,EAmBd,OAZI,EAAM,SAAW,SACZ,EAAW,MAAM,EAAS,QAAQ,CAAE,UAAW,EAAM,UAAW,SAAU,GAAI,CAAC,CAAC,EACpF,EACD,OAAO,EAAM,eAAkB,UAAY,EAAM,cAAc,SAAW,EACrE,EAAW,CAAE,MAAO,iDAAkD,CAAC,EAQzE,EALL,EAAM,SAAW,QACb,MAAM,EAAQ,MAAM,EAAM,OAAQ,EAAM,cAAe,EAAM,UAAW,EAAM,MAAM,EACpF,EAAM,SAAW,SACf,MAAM,EAAQ,OAAO,EAAM,OAAQ,EAAM,cAAe,EAAM,SAAS,EACvE,MAAM,EAAQ,KAAK,EAAM,OAAQ,EAAM,cAAe,EAAM,UAAW,EAAM,MAAM,CAClE,EAVJ,EAAW,CAAE,MAAO,kCAAmC,CAAC,CAW/E,CACF,CACF,EACA,SAAU,CACR,CACE,KAAM,CAAE,MAAO,CAAE,aAAc,CAAiB,EAAG,YAAa,CAAE,KAAM,QAAS,KAAM,CAAiB,CAAE,EAC1G,KAAM,kBACN,YAAa,0CACb,MAAM,QAAQ,EAAc,EAAyC,CACnE,IAAM,EAAS,EAA2B,CAAI,EAC9C,GAAI,UAAW,EAAQ,CACrB,MAAM,EAAU,OAAO,OAAO,CAAE,KAAM,EAAO,MAAO,MAAO,OAAQ,CAAC,EACpE,MACF,CAOA,IAAM,EAAW,EAAW,MANP,EAAQ,QAAQ,QAAQ,CAC3C,aAAc,EAAO,SACrB,GAAI,EAAO,SAAW,IAAA,GAAY,CAAC,EAAI,CAAE,OAAQ,EAAO,MAAO,EAC/D,GAAI,OAAO,KAAK,EAAO,MAAM,CAAC,CAAC,SAAW,EAAI,CAAC,EAAI,CAAE,OAAQ,EAAO,MAAO,EAC3E,GAAI,EAAO,SAAW,IAAA,GAAY,CAAC,EAAI,CAAE,OAAQ,EAAO,MAAO,CACjE,CAAC,CACiC,CAAC,CAAC,QAAQ,KAAM,GAAU,EAAM,OAAS,MAAM,EACjF,MAAM,EAAU,OAAO,OAAO,CAC5B,KAAM,GAAU,OAAS,OAAS,EAAS,KAAO,6BAClD,MAAO,MACT,CAAC,CACH,CACF,CACF,EACA,WAAY,CACV,GAAS,QAAQ,EACjB,EAAU,IAAA,EACZ,CACF,CACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("../services/webWorkflowCatalog/index.cjs"),t=require("../services/workflowCatalogDeps/index.cjs"),n=require("../types/webWorkflows.cjs");function r(r={}){let a=e.createWorkflowCatalogReader(r.deps??t.defaultCatalogDeps());return{frameType:n.WORKFLOW_CATALOG_TYPE,start(t){let r=new Map,o=new Map,s=new Map,c=(e,n)=>{o.set(e.sessionId,n),t.publish(e.sessionId,n)},l=async n=>{let i;try{i={cwd:n.cwd,workflows:e.presentWorkflowCatalog(await a.read(n.cwd))}}catch(e){let r=e instanceof Error?e.message:String(e);i={cwd:n.cwd,workflows:[],warning:r},t.onNotice(`workflow catalog for ${n.cwd} is unavailable (${r})`)}r.get(n.sessionId)===n&&c(n,i)};return{payloadFor(e){return r.has(e.sessionId)?o.get(e.sessionId):void 0},sessionAdded(e){r.set(e.sessionId,e),s.get(e.sessionId)?.();let a=t.directEvents.subscribe(n.WORKFLOW_CATALOG_TYPE,e.sessionId,t=>{i(t)&&c(e,t)},{replayLatest:!0});s.set(e.sessionId,a),l(e)},sessionRemoved(e){s.get(e)?.(),s.delete(e),r.delete(e),o.delete(e)},close(){for(let e of s.values())e();s.clear(),r.clear(),o.clear()}}}}}function i(e){return typeof e==`object`&&!!e&&typeof e.cwd==`string`&&Array.isArray(e.workflows)}exports.createWorkflowCatalogChannel=r;
|
|
2
|
+
//# sourceMappingURL=workflowCatalogChannel.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflowCatalogChannel.cjs","names":["createWorkflowCatalogReader","defaultCatalogDeps","WORKFLOW_CATALOG_TYPE","presentWorkflowCatalog"],"sources":["../../../src/controllers/workflowCatalogChannel.ts"],"sourcesContent":["import type { DoomHubChannelSource, DoomHubSessionScope, DoomHubChannel } from '@agimon-ai/doompi-core/hub-channel';\n\nimport {\n createWorkflowCatalogReader,\n presentWorkflowCatalog,\n type WorkflowCatalogReaderDeps,\n} from '../services/webWorkflowCatalog';\nimport { defaultCatalogDeps } from '../services/workflowCatalogDeps';\nimport { WORKFLOW_CATALOG_TYPE, type WorkflowCatalogPayload } from '../types/webWorkflows';\n\nexport interface WorkflowCatalogChannelOptions {\n deps?: WorkflowCatalogReaderDeps;\n}\n\n/**\n * The workflow catalog channel. Durable state seeds a session once, then\n * session lifecycle events deliver updates over the direct event bus.\n */\nexport function createWorkflowCatalogChannel(options: WorkflowCatalogChannelOptions = {}): DoomHubChannel {\n const reader = createWorkflowCatalogReader(options.deps ?? defaultCatalogDeps());\n return {\n frameType: WORKFLOW_CATALOG_TYPE,\n start(host) {\n const scopes = new Map<string, DoomHubSessionScope>();\n const latest = new Map<string, WorkflowCatalogPayload>();\n const subscriptions = new Map<string, () => void>();\n const publish = (scope: DoomHubSessionScope, payload: WorkflowCatalogPayload): void => {\n latest.set(scope.sessionId, payload);\n host.publish(scope.sessionId, payload);\n };\n const readInitial = async (scope: DoomHubSessionScope): Promise<void> => {\n let payload: WorkflowCatalogPayload;\n try {\n payload = {\n cwd: scope.cwd,\n workflows: presentWorkflowCatalog(await reader.read(scope.cwd)),\n };\n } catch (error) {\n const warning = error instanceof Error ? error.message : String(error);\n payload = { cwd: scope.cwd, workflows: [], warning };\n host.onNotice(`workflow catalog for ${scope.cwd} is unavailable (${warning})`);\n }\n if (scopes.get(scope.sessionId) === scope) publish(scope, payload);\n };\n const source: DoomHubChannelSource = {\n payloadFor(scope) {\n return scopes.has(scope.sessionId) ? latest.get(scope.sessionId) : undefined;\n },\n sessionAdded(scope) {\n scopes.set(scope.sessionId, scope);\n subscriptions.get(scope.sessionId)?.();\n const unsubscribe = host.directEvents.subscribe(\n WORKFLOW_CATALOG_TYPE,\n scope.sessionId,\n (value) => {\n if (isWorkflowCatalogPayload(value)) publish(scope, value);\n },\n { replayLatest: true },\n );\n subscriptions.set(scope.sessionId, unsubscribe);\n void readInitial(scope);\n },\n sessionRemoved(sessionId) {\n subscriptions.get(sessionId)?.();\n subscriptions.delete(sessionId);\n scopes.delete(sessionId);\n latest.delete(sessionId);\n },\n close() {\n for (const unsubscribe of subscriptions.values()) unsubscribe();\n subscriptions.clear();\n scopes.clear();\n latest.clear();\n },\n };\n return source;\n },\n };\n}\n\nfunction isWorkflowCatalogPayload(value: unknown): value is WorkflowCatalogPayload {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as { cwd?: unknown }).cwd === 'string' &&\n Array.isArray((value as { workflows?: unknown }).workflows)\n );\n}\n"],"mappings":"0JAkBA,SAAgB,EAA6B,EAAyC,CAAC,EAAmB,CACxG,IAAM,EAASA,EAAAA,4BAA4B,EAAQ,MAAQC,EAAAA,mBAAmB,CAAC,EAC/E,MAAO,CACL,UAAWC,EAAAA,sBACX,MAAM,EAAM,CACV,IAAM,EAAS,IAAI,IACb,EAAS,IAAI,IACb,EAAgB,IAAI,IACpB,GAAW,EAA4B,IAA0C,CACrF,EAAO,IAAI,EAAM,UAAW,CAAO,EACnC,EAAK,QAAQ,EAAM,UAAW,CAAO,CACvC,EACM,EAAc,KAAO,IAA8C,CACvE,IAAI,EACJ,GAAI,CACF,EAAU,CACR,IAAK,EAAM,IACX,UAAWC,EAAAA,uBAAuB,MAAM,EAAO,KAAK,EAAM,GAAG,CAAC,CAChE,CACF,OAAS,EAAO,CACd,IAAM,EAAU,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EACrE,EAAU,CAAE,IAAK,EAAM,IAAK,UAAW,CAAC,EAAG,SAAQ,EACnD,EAAK,SAAS,wBAAwB,EAAM,IAAI,mBAAmB,EAAQ,EAAE,CAC/E,CACI,EAAO,IAAI,EAAM,SAAS,IAAM,GAAO,EAAQ,EAAO,CAAO,CACnE,EAgCA,MAAO,CA9BL,WAAW,EAAO,CAChB,OAAO,EAAO,IAAI,EAAM,SAAS,EAAI,EAAO,IAAI,EAAM,SAAS,EAAI,IAAA,EACrE,EACA,aAAa,EAAO,CAClB,EAAO,IAAI,EAAM,UAAW,CAAK,EACjC,EAAc,IAAI,EAAM,SAAS,CAAC,GAAG,EACrC,IAAM,EAAc,EAAK,aAAa,UACpCD,EAAAA,sBACA,EAAM,UACL,GAAU,CACL,EAAyB,CAAK,GAAG,EAAQ,EAAO,CAAK,CAC3D,EACA,CAAE,aAAc,EAAK,CACvB,EACA,EAAc,IAAI,EAAM,UAAW,CAAW,EAC9C,EAAiB,CAAK,CACxB,EACA,eAAe,EAAW,CACxB,EAAc,IAAI,CAAS,CAAC,GAAG,EAC/B,EAAc,OAAO,CAAS,EAC9B,EAAO,OAAO,CAAS,EACvB,EAAO,OAAO,CAAS,CACzB,EACA,OAAQ,CACN,IAAK,IAAM,KAAe,EAAc,OAAO,EAAG,EAAY,EAC9D,EAAc,MAAM,EACpB,EAAO,MAAM,EACb,EAAO,MAAM,CACf,CAEU,CACd,CACF,CACF,CAEA,SAAS,EAAyB,EAAiD,CACjF,OACE,OAAO,GAAU,YACjB,GACA,OAAQ,EAA4B,KAAQ,UAC5C,MAAM,QAAS,EAAkC,SAAS,CAE9D"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createWorkflowCatalogReader as e,presentWorkflowCatalog as t}from"../services/webWorkflowCatalog/index.mjs";import{defaultCatalogDeps as n}from"../services/workflowCatalogDeps/index.mjs";import{WORKFLOW_CATALOG_TYPE as r}from"../types/webWorkflows.mjs";function i(i={}){let o=e(i.deps??n());return{frameType:r,start(e){let n=new Map,i=new Map,s=new Map,c=(t,n)=>{i.set(t.sessionId,n),e.publish(t.sessionId,n)},l=async r=>{let i;try{i={cwd:r.cwd,workflows:t(await o.read(r.cwd))}}catch(t){let n=t instanceof Error?t.message:String(t);i={cwd:r.cwd,workflows:[],warning:n},e.onNotice(`workflow catalog for ${r.cwd} is unavailable (${n})`)}n.get(r.sessionId)===r&&c(r,i)};return{payloadFor(e){return n.has(e.sessionId)?i.get(e.sessionId):void 0},sessionAdded(t){n.set(t.sessionId,t),s.get(t.sessionId)?.();let i=e.directEvents.subscribe(r,t.sessionId,e=>{a(e)&&c(t,e)},{replayLatest:!0});s.set(t.sessionId,i),l(t)},sessionRemoved(e){s.get(e)?.(),s.delete(e),n.delete(e),i.delete(e)},close(){for(let e of s.values())e();s.clear(),n.clear(),i.clear()}}}}}function a(e){return typeof e==`object`&&!!e&&typeof e.cwd==`string`&&Array.isArray(e.workflows)}export{i as createWorkflowCatalogChannel};
|
|
2
|
+
//# sourceMappingURL=workflowCatalogChannel.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflowCatalogChannel.mjs","names":[],"sources":["../../../src/controllers/workflowCatalogChannel.ts"],"sourcesContent":["import type { DoomHubChannelSource, DoomHubSessionScope, DoomHubChannel } from '@agimon-ai/doompi-core/hub-channel';\n\nimport {\n createWorkflowCatalogReader,\n presentWorkflowCatalog,\n type WorkflowCatalogReaderDeps,\n} from '../services/webWorkflowCatalog';\nimport { defaultCatalogDeps } from '../services/workflowCatalogDeps';\nimport { WORKFLOW_CATALOG_TYPE, type WorkflowCatalogPayload } from '../types/webWorkflows';\n\nexport interface WorkflowCatalogChannelOptions {\n deps?: WorkflowCatalogReaderDeps;\n}\n\n/**\n * The workflow catalog channel. Durable state seeds a session once, then\n * session lifecycle events deliver updates over the direct event bus.\n */\nexport function createWorkflowCatalogChannel(options: WorkflowCatalogChannelOptions = {}): DoomHubChannel {\n const reader = createWorkflowCatalogReader(options.deps ?? defaultCatalogDeps());\n return {\n frameType: WORKFLOW_CATALOG_TYPE,\n start(host) {\n const scopes = new Map<string, DoomHubSessionScope>();\n const latest = new Map<string, WorkflowCatalogPayload>();\n const subscriptions = new Map<string, () => void>();\n const publish = (scope: DoomHubSessionScope, payload: WorkflowCatalogPayload): void => {\n latest.set(scope.sessionId, payload);\n host.publish(scope.sessionId, payload);\n };\n const readInitial = async (scope: DoomHubSessionScope): Promise<void> => {\n let payload: WorkflowCatalogPayload;\n try {\n payload = {\n cwd: scope.cwd,\n workflows: presentWorkflowCatalog(await reader.read(scope.cwd)),\n };\n } catch (error) {\n const warning = error instanceof Error ? error.message : String(error);\n payload = { cwd: scope.cwd, workflows: [], warning };\n host.onNotice(`workflow catalog for ${scope.cwd} is unavailable (${warning})`);\n }\n if (scopes.get(scope.sessionId) === scope) publish(scope, payload);\n };\n const source: DoomHubChannelSource = {\n payloadFor(scope) {\n return scopes.has(scope.sessionId) ? latest.get(scope.sessionId) : undefined;\n },\n sessionAdded(scope) {\n scopes.set(scope.sessionId, scope);\n subscriptions.get(scope.sessionId)?.();\n const unsubscribe = host.directEvents.subscribe(\n WORKFLOW_CATALOG_TYPE,\n scope.sessionId,\n (value) => {\n if (isWorkflowCatalogPayload(value)) publish(scope, value);\n },\n { replayLatest: true },\n );\n subscriptions.set(scope.sessionId, unsubscribe);\n void readInitial(scope);\n },\n sessionRemoved(sessionId) {\n subscriptions.get(sessionId)?.();\n subscriptions.delete(sessionId);\n scopes.delete(sessionId);\n latest.delete(sessionId);\n },\n close() {\n for (const unsubscribe of subscriptions.values()) unsubscribe();\n subscriptions.clear();\n scopes.clear();\n latest.clear();\n },\n };\n return source;\n },\n };\n}\n\nfunction isWorkflowCatalogPayload(value: unknown): value is WorkflowCatalogPayload {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as { cwd?: unknown }).cwd === 'string' &&\n Array.isArray((value as { workflows?: unknown }).workflows)\n );\n}\n"],"mappings":"oQAkBA,SAAgB,EAA6B,EAAyC,CAAC,EAAmB,CACxG,IAAM,EAAS,EAA4B,EAAQ,MAAQ,EAAmB,CAAC,EAC/E,MAAO,CACL,UAAW,EACX,MAAM,EAAM,CACV,IAAM,EAAS,IAAI,IACb,EAAS,IAAI,IACb,EAAgB,IAAI,IACpB,GAAW,EAA4B,IAA0C,CACrF,EAAO,IAAI,EAAM,UAAW,CAAO,EACnC,EAAK,QAAQ,EAAM,UAAW,CAAO,CACvC,EACM,EAAc,KAAO,IAA8C,CACvE,IAAI,EACJ,GAAI,CACF,EAAU,CACR,IAAK,EAAM,IACX,UAAW,EAAuB,MAAM,EAAO,KAAK,EAAM,GAAG,CAAC,CAChE,CACF,OAAS,EAAO,CACd,IAAM,EAAU,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EACrE,EAAU,CAAE,IAAK,EAAM,IAAK,UAAW,CAAC,EAAG,SAAQ,EACnD,EAAK,SAAS,wBAAwB,EAAM,IAAI,mBAAmB,EAAQ,EAAE,CAC/E,CACI,EAAO,IAAI,EAAM,SAAS,IAAM,GAAO,EAAQ,EAAO,CAAO,CACnE,EAgCA,MAAO,CA9BL,WAAW,EAAO,CAChB,OAAO,EAAO,IAAI,EAAM,SAAS,EAAI,EAAO,IAAI,EAAM,SAAS,EAAI,IAAA,EACrE,EACA,aAAa,EAAO,CAClB,EAAO,IAAI,EAAM,UAAW,CAAK,EACjC,EAAc,IAAI,EAAM,SAAS,CAAC,GAAG,EACrC,IAAM,EAAc,EAAK,aAAa,UACpC,EACA,EAAM,UACL,GAAU,CACL,EAAyB,CAAK,GAAG,EAAQ,EAAO,CAAK,CAC3D,EACA,CAAE,aAAc,EAAK,CACvB,EACA,EAAc,IAAI,EAAM,UAAW,CAAW,EAC9C,EAAiB,CAAK,CACxB,EACA,eAAe,EAAW,CACxB,EAAc,IAAI,CAAS,CAAC,GAAG,EAC/B,EAAc,OAAO,CAAS,EAC9B,EAAO,OAAO,CAAS,EACvB,EAAO,OAAO,CAAS,CACzB,EACA,OAAQ,CACN,IAAK,IAAM,KAAe,EAAc,OAAO,EAAG,EAAY,EAC9D,EAAc,MAAM,EACpB,EAAO,MAAM,EACb,EAAO,MAAM,CACf,CAEU,CACd,CACF,CACF,CAEA,SAAS,EAAyB,EAAiD,CACjF,OACE,OAAO,GAAU,YACjB,GACA,OAAQ,EAA4B,KAAQ,UAC5C,MAAM,QAAS,EAAkC,SAAS,CAE9D"}
|