@agimon-ai/doompi-workflow 0.0.1-alpha.77 → 0.0.1-alpha.79

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.
@@ -1,9 +1,10 @@
1
1
  const require_index = require("../workflowLaunchCommand/index.cjs");
2
2
  const require_index$1 = require("../workflowResource/index.cjs");
3
- const require_index$2 = require("../webWorkflowCatalog/index.cjs");
4
- const require_index$3 = require("../workflowCatalogDeps/index.cjs");
5
- const require_index$4 = require("../workflowRuns/index.cjs");
6
- const require_index$5 = require("../workflowWatcher/index.cjs");
3
+ const require_index$2 = require("../backgroundWork/index.cjs");
4
+ const require_index$3 = require("../webWorkflowCatalog/index.cjs");
5
+ const require_index$4 = require("../workflowCatalogDeps/index.cjs");
6
+ const require_index$5 = require("../workflowRuns/index.cjs");
7
+ const require_index$6 = require("../workflowWatcher/index.cjs");
7
8
  const require_webWorkflows = require("../../types/webWorkflows.cjs");
8
9
  let _agimon_ai_workflow_mcp = require("@agimon-ai/workflow-mcp");
9
10
  let zod = require("zod");
@@ -41,14 +42,21 @@ function callResult(value) {
41
42
  function createWorkflowServerRuntime(host, serverHost) {
42
43
  if (serverHost.context.directEvents === void 0) throw new Error("Workflow headless facet requires the session direct event bus.");
43
44
  const directEvents = serverHost.context.directEvents;
44
- const catalogReader = require_index$2.createWorkflowCatalogReader(require_index$3.defaultCatalogDeps());
45
+ let runProvider;
46
+ const catalogReader = require_index$3.createWorkflowCatalogReader(require_index$4.defaultCatalogDeps());
45
47
  const publishLifecycle = async (executionContext) => {
46
- const runs = require_index$4.presentWorkflowRuns(require_index$5.readWorkflowRuns({ environment: executionContext.environment }).filter((run) => require_index$4.runBelongsToSession(run, executionContext.sessionId)).map((run) => run.view), Date.now());
48
+ const records = require_index$6.readWorkflowRuns({ environment: executionContext.environment }).filter((run) => require_index$5.runBelongsToSession(run, executionContext.sessionId));
49
+ const activeItems = records.filter((run) => run.view.stage === "running" && run.view.stale !== true).map((run) => ({
50
+ id: `${run.view.workspace}/${run.view.runKey}`,
51
+ sessionId: executionContext.sessionId
52
+ }));
53
+ runProvider?.update(activeItems);
54
+ const runs = require_index$5.presentWorkflowRuns(records.map((run) => run.view), Date.now());
47
55
  directEvents.publish(require_webWorkflows.WORKFLOW_RUNS_TYPE, executionContext.sessionId, { runs });
48
56
  try {
49
57
  directEvents.publish(require_webWorkflows.WORKFLOW_CATALOG_TYPE, executionContext.sessionId, {
50
58
  cwd: executionContext.cwd,
51
- workflows: require_index$2.presentWorkflowCatalog(await catalogReader.read(executionContext.cwd))
59
+ workflows: require_index$3.presentWorkflowCatalog(await catalogReader.read(executionContext.cwd))
52
60
  });
53
61
  } catch (error) {
54
62
  const warning = error instanceof Error ? error.message : String(error);
@@ -58,9 +66,16 @@ function createWorkflowServerRuntime(host, serverHost) {
58
66
  warning
59
67
  });
60
68
  }
69
+ return activeItems.length > 0;
61
70
  };
62
71
  const feature = (0, _agimon_ai_workflow_mcp.createEmbeddedWorkflowFeature)();
63
72
  let control;
73
+ let controlDisposers = [];
74
+ const disposeControl = () => {
75
+ for (const dispose of controlDisposers.splice(0)) dispose();
76
+ control?.dispose();
77
+ control = void 0;
78
+ };
64
79
  let modeOwner;
65
80
  const modeSelected = () => (host.context.selection.state?.["minor-mode"] ?? []).includes(WORKFLOW_MODE_ID);
66
81
  const modeState = () => {
@@ -125,7 +140,14 @@ function createWorkflowServerRuntime(host, serverHost) {
125
140
  }
126
141
  }).createOwner(void 0);
127
142
  return {
128
- services: [(0, _agimon_ai_doompi_minor_mode.serverMinorModes)([modeOwner])],
143
+ services: [(0, _agimon_ai_doompi_minor_mode.serverMinorModes)([modeOwner]), (context) => {
144
+ const provider = require_index$2.registerRunProvider(context);
145
+ runProvider = provider;
146
+ return () => {
147
+ provider.dispose();
148
+ if (runProvider === provider) runProvider = void 0;
149
+ };
150
+ }],
129
151
  toolRestrictions: [{
130
152
  when: { state: { "minor-mode": WORKFLOW_MODE_ID } },
131
153
  allowedTools: [
@@ -148,10 +170,7 @@ function createWorkflowServerRuntime(host, serverHost) {
148
170
  }
149
171
  },
150
172
  event: "session_shutdown",
151
- handle: () => {
152
- control?.dispose();
153
- control = void 0;
154
- }
173
+ handle: disposeControl
155
174
  }],
156
175
  resources: [
157
176
  {
@@ -201,13 +220,39 @@ function createWorkflowServerRuntime(host, serverHost) {
201
220
  },
202
221
  name: SOURCE,
203
222
  async start(executionContext) {
223
+ const reportFailure = (error) => {
224
+ process.emitWarning(`Could not publish headless workflow state: ${String(error)}`);
225
+ };
226
+ const stopFor = (ownedControl) => () => {
227
+ publishLifecycle(executionContext).then((active) => {
228
+ if (!active && !modeSelected() && control === ownedControl) disposeControl();
229
+ }).catch(reportFailure);
230
+ };
231
+ if (control !== void 0) {
232
+ const ownedControl = control;
233
+ await publishLifecycle(executionContext);
234
+ return stopFor(ownedControl);
235
+ }
204
236
  control = feature.createRunControl({});
205
- await control.start();
206
- await publishLifecycle(executionContext);
207
- return () => {
208
- control?.dispose();
209
- control = void 0;
237
+ const ownedControl = control;
238
+ const refresh = () => {
239
+ publishLifecycle(executionContext).then((active) => {
240
+ if (!active && !modeSelected() && control === ownedControl) disposeControl();
241
+ }).catch(reportFailure);
210
242
  };
243
+ controlDisposers = [
244
+ ownedControl.on("runStarted", refresh),
245
+ ownedControl.on("runUpdated", refresh),
246
+ ownedControl.on("runFinished", refresh)
247
+ ];
248
+ try {
249
+ await ownedControl.start();
250
+ await publishLifecycle(executionContext);
251
+ return stopFor(ownedControl);
252
+ } catch (error) {
253
+ if (control === ownedControl) disposeControl();
254
+ throw error;
255
+ }
211
256
  }
212
257
  }],
213
258
  tools: [
@@ -285,7 +330,7 @@ function createWorkflowServerRuntime(host, serverHost) {
285
330
  async execute(_toolCallId, parameters, signal) {
286
331
  signal?.throwIfAborted();
287
332
  const input = parameters;
288
- const runs = require_index$5.readWorkflowRuns({ environment: host.context.environment }).filter((run) => require_index$4.runBelongsToSession(run, host.context.sessionId) && run.view.runKey === input.runKey && (input.workspace === void 0 || run.view.workspace === input.workspace));
333
+ const runs = require_index$6.readWorkflowRuns({ environment: host.context.environment }).filter((run) => require_index$5.runBelongsToSession(run, host.context.sessionId) && run.view.runKey === input.runKey && (input.workspace === void 0 || run.view.workspace === input.workspace));
289
334
  if (runs.length !== 1) return {
290
335
  ...callResult({ error: runs.length === 0 ? "Workflow run was not found in this session." : "Specify the workspace for this run key." }),
291
336
  isError: true
@@ -330,8 +375,9 @@ function createWorkflowServerRuntime(host, serverHost) {
330
375
  }
331
376
  }],
332
377
  onDispose() {
333
- control?.dispose();
334
- control = void 0;
378
+ disposeControl();
379
+ runProvider?.dispose();
380
+ runProvider = void 0;
335
381
  }
336
382
  };
337
383
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["createWorkflowCatalogReader","defaultCatalogDeps","presentWorkflowRuns","readWorkflowRuns","runBelongsToSession","WORKFLOW_RUNS_TYPE","WORKFLOW_CATALOG_TYPE","presentWorkflowCatalog","createEmbeddedWorkflowFeature","defineMinorMode","serverMinorModes","skill","z","parseWorkflowLaunchCommand"],"sources":["../../../../src/services/serverRuntime/index.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 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 const runs = readWorkflowRuns({ environment: host.context.environment }).filter(\n (run) =>\n runBelongsToSession(run, host.context.sessionId) &&\n run.view.runKey === input.runKey &&\n (input.workspace === undefined || run.view.workspace === input.workspace),\n );\n if (runs.length !== 1)\n return {\n ...callResult({\n error:\n runs.length === 0\n ? 'Workflow run was not found in this session.'\n : 'Specify the workspace for this run key.',\n }),\n isError: true,\n };\n const run = runs[0]!.view;\n if (input.action === 'status') return callResult(run);\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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"}
1
+ {"version":3,"file":"index.cjs","names":["createWorkflowCatalogReader","defaultCatalogDeps","readWorkflowRuns","runBelongsToSession","presentWorkflowRuns","WORKFLOW_RUNS_TYPE","WORKFLOW_CATALOG_TYPE","presentWorkflowCatalog","createEmbeddedWorkflowFeature","defineMinorMode","serverMinorModes","registerRunProvider","skill","z","parseWorkflowLaunchCommand"],"sources":["../../../../src/services/serverRuntime/index.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 { registerRunProvider, type RunProviderHandle } from '../../services/backgroundWork';\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 let runProvider: RunProviderHandle | undefined;\n const catalogReader = createWorkflowCatalogReader(defaultCatalogDeps());\n const publishLifecycle = async (executionContext: typeof host.context): Promise<boolean> => {\n const records = readWorkflowRuns({ environment: executionContext.environment }).filter((run) =>\n runBelongsToSession(run, executionContext.sessionId),\n );\n const activeItems = records\n .filter((run) => run.view.stage === 'running' && run.view.stale !== true)\n .map((run) => ({ id: `${run.view.workspace}/${run.view.runKey}`, sessionId: executionContext.sessionId }));\n runProvider?.update(activeItems);\n const runs = presentWorkflowRuns(\n records.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 return activeItems.length > 0;\n };\n const feature = createEmbeddedWorkflowFeature();\n let control: ReturnType<typeof feature.createRunControl> | undefined;\n let controlDisposers: (() => void)[] = [];\n const disposeControl = (): void => {\n for (const dispose of controlDisposers.splice(0)) dispose();\n control?.dispose();\n control = undefined;\n };\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: [\n serverMinorModes([modeOwner]),\n (context) => {\n const provider = registerRunProvider(context);\n runProvider = provider;\n return () => {\n provider.dispose();\n if (runProvider === provider) runProvider = undefined;\n };\n },\n ],\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: disposeControl,\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 const reportFailure = (error: unknown): void => {\n process.emitWarning(`Could not publish headless workflow state: ${String(error)}`);\n };\n const stopFor =\n (ownedControl: NonNullable<typeof control>): (() => void) =>\n () => {\n void publishLifecycle(executionContext)\n .then((active) => {\n if (!active && !modeSelected() && control === ownedControl) disposeControl();\n })\n .catch(reportFailure);\n };\n if (control !== undefined) {\n const ownedControl = control;\n await publishLifecycle(executionContext);\n return stopFor(ownedControl);\n }\n control = feature.createRunControl({});\n const ownedControl = control;\n const refresh = (): void => {\n void publishLifecycle(executionContext)\n .then((active) => {\n if (!active && !modeSelected() && control === ownedControl) disposeControl();\n })\n .catch(reportFailure);\n };\n controlDisposers = [\n ownedControl.on('runStarted', refresh),\n ownedControl.on('runUpdated', refresh),\n ownedControl.on('runFinished', refresh),\n ];\n try {\n await ownedControl.start();\n await publishLifecycle(executionContext);\n return stopFor(ownedControl);\n } catch (error) {\n if (control === ownedControl) disposeControl();\n throw error;\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 const runs = readWorkflowRuns({ environment: host.context.environment }).filter(\n (run) =>\n runBelongsToSession(run, host.context.sessionId) &&\n run.view.runKey === input.runKey &&\n (input.workspace === undefined || run.view.workspace === input.workspace),\n );\n if (runs.length !== 1)\n return {\n ...callResult({\n error:\n runs.length === 0\n ? 'Workflow run was not found in this session.'\n : 'Specify the workspace for this run key.',\n }),\n isError: true,\n };\n const run = runs[0]!.view;\n if (input.action === 'status') return callResult(run);\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 disposeControl();\n runProvider?.dispose();\n runProvider = undefined;\n },\n };\n}\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { parseWorkflowLaunchCommand } from "../workflowLaunchCommand/index.mjs";
2
2
  import { readWorkflowSkill } from "../workflowResource/index.mjs";
3
+ import { registerRunProvider } from "../backgroundWork/index.mjs";
3
4
  import { createWorkflowCatalogReader, presentWorkflowCatalog } from "../webWorkflowCatalog/index.mjs";
4
5
  import { defaultCatalogDeps } from "../workflowCatalogDeps/index.mjs";
5
6
  import { presentWorkflowRuns, runBelongsToSession } from "../workflowRuns/index.mjs";
@@ -41,9 +42,16 @@ function callResult(value) {
41
42
  function createWorkflowServerRuntime(host, serverHost) {
42
43
  if (serverHost.context.directEvents === void 0) throw new Error("Workflow headless facet requires the session direct event bus.");
43
44
  const directEvents = serverHost.context.directEvents;
45
+ let runProvider;
44
46
  const catalogReader = createWorkflowCatalogReader(defaultCatalogDeps());
45
47
  const publishLifecycle = async (executionContext) => {
46
- const runs = presentWorkflowRuns(readWorkflowRuns({ environment: executionContext.environment }).filter((run) => runBelongsToSession(run, executionContext.sessionId)).map((run) => run.view), Date.now());
48
+ const records = readWorkflowRuns({ environment: executionContext.environment }).filter((run) => runBelongsToSession(run, executionContext.sessionId));
49
+ const activeItems = records.filter((run) => run.view.stage === "running" && run.view.stale !== true).map((run) => ({
50
+ id: `${run.view.workspace}/${run.view.runKey}`,
51
+ sessionId: executionContext.sessionId
52
+ }));
53
+ runProvider?.update(activeItems);
54
+ const runs = presentWorkflowRuns(records.map((run) => run.view), Date.now());
47
55
  directEvents.publish(WORKFLOW_RUNS_TYPE, executionContext.sessionId, { runs });
48
56
  try {
49
57
  directEvents.publish(WORKFLOW_CATALOG_TYPE, executionContext.sessionId, {
@@ -58,9 +66,16 @@ function createWorkflowServerRuntime(host, serverHost) {
58
66
  warning
59
67
  });
60
68
  }
69
+ return activeItems.length > 0;
61
70
  };
62
71
  const feature = createEmbeddedWorkflowFeature();
63
72
  let control;
73
+ let controlDisposers = [];
74
+ const disposeControl = () => {
75
+ for (const dispose of controlDisposers.splice(0)) dispose();
76
+ control?.dispose();
77
+ control = void 0;
78
+ };
64
79
  let modeOwner;
65
80
  const modeSelected = () => (host.context.selection.state?.["minor-mode"] ?? []).includes(WORKFLOW_MODE_ID);
66
81
  const modeState = () => {
@@ -125,7 +140,14 @@ function createWorkflowServerRuntime(host, serverHost) {
125
140
  }
126
141
  }).createOwner(void 0);
127
142
  return {
128
- services: [serverMinorModes([modeOwner])],
143
+ services: [serverMinorModes([modeOwner]), (context) => {
144
+ const provider = registerRunProvider(context);
145
+ runProvider = provider;
146
+ return () => {
147
+ provider.dispose();
148
+ if (runProvider === provider) runProvider = void 0;
149
+ };
150
+ }],
129
151
  toolRestrictions: [{
130
152
  when: { state: { "minor-mode": WORKFLOW_MODE_ID } },
131
153
  allowedTools: [
@@ -148,10 +170,7 @@ function createWorkflowServerRuntime(host, serverHost) {
148
170
  }
149
171
  },
150
172
  event: "session_shutdown",
151
- handle: () => {
152
- control?.dispose();
153
- control = void 0;
154
- }
173
+ handle: disposeControl
155
174
  }],
156
175
  resources: [
157
176
  {
@@ -201,13 +220,39 @@ function createWorkflowServerRuntime(host, serverHost) {
201
220
  },
202
221
  name: SOURCE,
203
222
  async start(executionContext) {
223
+ const reportFailure = (error) => {
224
+ process.emitWarning(`Could not publish headless workflow state: ${String(error)}`);
225
+ };
226
+ const stopFor = (ownedControl) => () => {
227
+ publishLifecycle(executionContext).then((active) => {
228
+ if (!active && !modeSelected() && control === ownedControl) disposeControl();
229
+ }).catch(reportFailure);
230
+ };
231
+ if (control !== void 0) {
232
+ const ownedControl = control;
233
+ await publishLifecycle(executionContext);
234
+ return stopFor(ownedControl);
235
+ }
204
236
  control = feature.createRunControl({});
205
- await control.start();
206
- await publishLifecycle(executionContext);
207
- return () => {
208
- control?.dispose();
209
- control = void 0;
237
+ const ownedControl = control;
238
+ const refresh = () => {
239
+ publishLifecycle(executionContext).then((active) => {
240
+ if (!active && !modeSelected() && control === ownedControl) disposeControl();
241
+ }).catch(reportFailure);
210
242
  };
243
+ controlDisposers = [
244
+ ownedControl.on("runStarted", refresh),
245
+ ownedControl.on("runUpdated", refresh),
246
+ ownedControl.on("runFinished", refresh)
247
+ ];
248
+ try {
249
+ await ownedControl.start();
250
+ await publishLifecycle(executionContext);
251
+ return stopFor(ownedControl);
252
+ } catch (error) {
253
+ if (control === ownedControl) disposeControl();
254
+ throw error;
255
+ }
211
256
  }
212
257
  }],
213
258
  tools: [
@@ -330,8 +375,9 @@ function createWorkflowServerRuntime(host, serverHost) {
330
375
  }
331
376
  }],
332
377
  onDispose() {
333
- control?.dispose();
334
- control = void 0;
378
+ disposeControl();
379
+ runProvider?.dispose();
380
+ runProvider = void 0;
335
381
  }
336
382
  };
337
383
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["skill"],"sources":["../../../../src/services/serverRuntime/index.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 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 const runs = readWorkflowRuns({ environment: host.context.environment }).filter(\n (run) =>\n runBelongsToSession(run, host.context.sessionId) &&\n run.view.runKey === input.runKey &&\n (input.workspace === undefined || run.view.workspace === input.workspace),\n );\n if (runs.length !== 1)\n return {\n ...callResult({\n error:\n runs.length === 0\n ? 'Workflow run was not found in this session.'\n : 'Specify the workspace for this run key.',\n }),\n isError: true,\n };\n const run = runs[0]!.view;\n if (input.action === 'status') return callResult(run);\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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"}
1
+ {"version":3,"file":"index.mjs","names":["skill"],"sources":["../../../../src/services/serverRuntime/index.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 { registerRunProvider, type RunProviderHandle } from '../../services/backgroundWork';\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 let runProvider: RunProviderHandle | undefined;\n const catalogReader = createWorkflowCatalogReader(defaultCatalogDeps());\n const publishLifecycle = async (executionContext: typeof host.context): Promise<boolean> => {\n const records = readWorkflowRuns({ environment: executionContext.environment }).filter((run) =>\n runBelongsToSession(run, executionContext.sessionId),\n );\n const activeItems = records\n .filter((run) => run.view.stage === 'running' && run.view.stale !== true)\n .map((run) => ({ id: `${run.view.workspace}/${run.view.runKey}`, sessionId: executionContext.sessionId }));\n runProvider?.update(activeItems);\n const runs = presentWorkflowRuns(\n records.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 return activeItems.length > 0;\n };\n const feature = createEmbeddedWorkflowFeature();\n let control: ReturnType<typeof feature.createRunControl> | undefined;\n let controlDisposers: (() => void)[] = [];\n const disposeControl = (): void => {\n for (const dispose of controlDisposers.splice(0)) dispose();\n control?.dispose();\n control = undefined;\n };\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: [\n serverMinorModes([modeOwner]),\n (context) => {\n const provider = registerRunProvider(context);\n runProvider = provider;\n return () => {\n provider.dispose();\n if (runProvider === provider) runProvider = undefined;\n };\n },\n ],\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: disposeControl,\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 const reportFailure = (error: unknown): void => {\n process.emitWarning(`Could not publish headless workflow state: ${String(error)}`);\n };\n const stopFor =\n (ownedControl: NonNullable<typeof control>): (() => void) =>\n () => {\n void publishLifecycle(executionContext)\n .then((active) => {\n if (!active && !modeSelected() && control === ownedControl) disposeControl();\n })\n .catch(reportFailure);\n };\n if (control !== undefined) {\n const ownedControl = control;\n await publishLifecycle(executionContext);\n return stopFor(ownedControl);\n }\n control = feature.createRunControl({});\n const ownedControl = control;\n const refresh = (): void => {\n void publishLifecycle(executionContext)\n .then((active) => {\n if (!active && !modeSelected() && control === ownedControl) disposeControl();\n })\n .catch(reportFailure);\n };\n controlDisposers = [\n ownedControl.on('runStarted', refresh),\n ownedControl.on('runUpdated', refresh),\n ownedControl.on('runFinished', refresh),\n ];\n try {\n await ownedControl.start();\n await publishLifecycle(executionContext);\n return stopFor(ownedControl);\n } catch (error) {\n if (control === ownedControl) disposeControl();\n throw error;\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 const runs = readWorkflowRuns({ environment: host.context.environment }).filter(\n (run) =>\n runBelongsToSession(run, host.context.sessionId) &&\n run.view.runKey === input.runKey &&\n (input.workspace === undefined || run.view.workspace === input.workspace),\n );\n if (runs.length !== 1)\n return {\n ...callResult({\n error:\n runs.length === 0\n ? 'Workflow run was not found in this session.'\n : 'Specify the workspace for this run key.',\n }),\n isError: true,\n };\n const run = runs[0]!.view;\n if (input.action === 'status') return callResult(run);\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 disposeControl();\n runProvider?.dispose();\n runProvider = undefined;\n },\n };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agimon-ai/doompi-workflow",
3
- "version": "0.0.1-alpha.77",
3
+ "version": "0.0.1-alpha.79",
4
4
  "description": "GitHub Actions-style workflow graphs, artifacts, recovery, and asynchronous runs for DoomPi.",
5
5
  "keywords": [
6
6
  "ai",
@@ -64,12 +64,12 @@
64
64
  "access": "public"
65
65
  },
66
66
  "dependencies": {
67
- "@agimon-ai/doompi-core": "0.0.1-alpha.76",
68
- "@agimon-ai/doompi-minor-mode": "0.0.1-alpha.76",
69
- "@agimon-ai/doompi-telemetry": "0.0.1-alpha.73",
70
- "@agimon-ai/doompi-ui": "0.0.1-alpha.76",
71
- "@agimon-ai/doompi-web-components": "0.0.1-alpha.34",
72
- "@agimon-ai/doompi-web-security": "0.0.1-alpha.36",
67
+ "@agimon-ai/doompi-core": "0.0.1-alpha.78",
68
+ "@agimon-ai/doompi-minor-mode": "0.0.1-alpha.78",
69
+ "@agimon-ai/doompi-telemetry": "0.0.1-alpha.75",
70
+ "@agimon-ai/doompi-ui": "0.0.1-alpha.78",
71
+ "@agimon-ai/doompi-web-components": "0.0.1-alpha.36",
72
+ "@agimon-ai/doompi-web-security": "0.0.1-alpha.38",
73
73
  "@agimon-ai/workflow-mcp": "0.23.26",
74
74
  "@deepseek-ai/cordis": "4.0.2",
75
75
  "@modelcontextprotocol/sdk": "1.30.0",
@@ -78,9 +78,9 @@
78
78
  "zod": "4.6.2"
79
79
  },
80
80
  "devDependencies": {
81
- "@agimon-ai/doompi-build": "0.0.1-alpha.5",
82
- "@earendil-works/pi-coding-agent": "0.85.1",
83
- "@earendil-works/pi-tui": "0.85.1",
81
+ "@agimon-ai/doompi-build": "0.0.1-alpha.7",
82
+ "@earendil-works/pi-coding-agent": "0.86.0",
83
+ "@earendil-works/pi-tui": "0.86.0",
84
84
  "@tanstack/react-store": "0.11.1",
85
85
  "@tanstack/store": "0.11.1",
86
86
  "@types/node": "26.5.1",
@@ -94,8 +94,8 @@
94
94
  "vitest": "5.0.0"
95
95
  },
96
96
  "peerDependencies": {
97
- "@earendil-works/pi-coding-agent": "0.85.1",
98
- "@earendil-works/pi-tui": "0.85.1"
97
+ "@earendil-works/pi-coding-agent": "0.86.0",
98
+ "@earendil-works/pi-tui": "0.86.0"
99
99
  },
100
100
  "peerDependenciesMeta": {
101
101
  "@earendil-works/pi-coding-agent": {