@agimon-ai/po-workflow 0.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.cjs","names":["z","z","DOOM_BACKGROUND_WORK_SERVICE","readDoomBackgroundWorkService","PI_SESSION_ENV","asError","resolveRootSessionId","randomUUID","PI_SESSION_ENV","resolve","RUNNING_STAGE","delay","textResult","fs","plain","path","randomUUID","WORKFLOW_DECISION_STEERING_ENV","WORKFLOW_DECISION_STEERING_HOST","WORKFLOW_STEP_SESSION_PROVENANCE","WORKFLOW_DECISION_FILE_ENV","readStepDecision","holdsSettledSession","BACKGROUND_WORK_HOLDING_PROVIDERS","gateStepDecision","NativeTerminalService","terminalSocketPath","serveNativeTerminal","fs","readWorkflowCatalog","summarizeWorkflow","diagnoseWorkflow","statSync","readChildProcessContext","SUBAGENT_PARENT_SESSION_ENV","fs","connectNativeTerminal","path","defineApiRoutes","apiResponse","WorkflowRegistryService","WorkflowTerminalFacade","Hono","routes","streamSSE","randomUUID","doomApiCallerFrom","path","fs","Readable","path","fileURLToPath","existsSync","readFile","basename","createEmbeddedWorkflowFeature","os","path","fs","randomUUID","createDoomTelemetry","createDoomNotificationEntryData","DOOM_NOTIFICATION_ENTRY_TYPE","createNarrationRequest","readWorkflowProgress","summarizeWorkflowProgress","createEmbeddedWorkflowFeature","resolve","relative","isAbsolute","validateWorkflowLaunch","routes","resolveRootSessionId","defineMinorMode","createDoomReadinessCoordinator","readDoomReadinessCoordinator","DOOM_NARRATION_SERVICE","requireDoomNarrationService","serverMinorModes","WORKFLOW_DECISION_FILE_ENV","WORKFLOW_DECISION_STEERING_ENV","WORKFLOW_DECISION_STEERING_HOST","readDoomBackgroundWorkService","holdsSettledSession","BACKGROUND_WORK_HOLDING_PROVIDERS","gateStepDecision","skill","z","readFile","join","parseWorkflowLaunchCommand","resolveWorkflowEntry","defineRoot","runtime","defineRoutedContribution","legacy","defineChannel","defineChannel","defineRoutedContribution","defineRoutedContribution","defineRoutedContribution","defineRoutedContribution","defineRoutedContribution","defineRoutedContribution","defineRoutedContribution","defineRoutedContribution","defineRoutedContribution","defineRoutedContribution","defineRoutedContribution","defineRoutedContribution","defineRoutedContribution","defineRoutedContribution","defineRoutedContribution","defineRoutedContribution","defineServerPlugin","composeServerProviderOverrides","rootSession","apiRoute","channelWorkflowCatalog","channelWorkflows","composeRootHooks","apiRoute2","commandWorkflowLaunch","hookAgentSettled","hookAgentStart","hookSessionShutdown","hookSessionStart","hookToolExecutionEnd","resourcePoAuthorWorkflow","resourcePoUseWorkflow","resourceWorkflowRecovery","resourceWorkflowSession","toolRestrictionDispatcher","toolLaunchWorkflow","toolListWorkflows","toolWorkflowRun","toolWorkflowTools"],"sources":["../../src/constants/workflow.ts","../../src/schemas/runConfig.ts","../../src/schemas/workflowPi.ts","../../src/services/backgroundWork/index.ts","../../src/services/piToolBridge/index.ts","../../src/services/workflowExecution/index.ts","../../src/services/workflowRuns/index.ts","../../src/services/serverLaunch/index.ts","../../src/types/webWorkflows.ts","../../src/services/stepExecutor/index.ts","../../src/services/webWorkflowCatalog/index.ts","../../src/services/workflowCatalogDeps/index.ts","../../src/services/workflowFence/index.ts","../../src/services/stepPaneTerminal/index.ts","../../src/services/workflowTerminal/index.ts","../../src/types/apiRoutes.ts","../../src/types/webWorkflowTerminal.ts","../../src/services/workflowHubApi/index.ts","../../src/services/workflowNarration/index.ts","../../src/services/workflowResource/index.ts","../../src/services/workflowSession/index.ts","../../src/services/workflowWatcher/index.ts","../../src/services/serverRuntime/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/index.server.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/services/workflowCatalogChannel/index.ts","../../src/services/workflowsHubChannel/index.ts","../../src/extensions/(backend)/_lib/index.server.ts","../../src/extensions/(backend)/api/workflow/route.server.ts","../../src/extensions/(backend)/channel/workflow-catalog.server.ts","../../src/extensions/(backend)/channel/workflows.server.ts","../../src/extensions/workspaces/sessions/(backend)/api/workflow/route.server.ts","../../src/extensions/workspaces/sessions/(backend)/command/workflow-launch.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/agent-start.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-start.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/tool-execution-end.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/po-author-workflow.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/po-use-workflow.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/workflow-recovery.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/workflow-session.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool-restriction/dispatcher.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/launch-workflow.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/list-workflows.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/workflow-run.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/workflow-tools.server.ts","../../generated/server.ts"],"sourcesContent":["export const LAUNCH_WORKFLOW_TOOL_NAME = 'launch_workflow';\nexport const WORKFLOW_TOOLS_TOOL_NAME = 'workflow_tools';\n/**\n * One launch's own id, carried in the run's environment.\n *\n * A launch answers once its run registers; matching on this id, rather than on\n * the workflow and the time, keeps two launches of one workflow apart.\n */\nexport const WORKFLOW_LAUNCH_ID_ENV = 'PO_WORKFLOW_LAUNCH_ID';\n\n/**\n * Provenance of the child session a launch creates to own and run one workflow.\n * Not 'workflow', which marks a step's session and keeps it out of the rail.\n */\nexport const WORKFLOW_SESSION_PROVENANCE = 'workflow-session';\n\n/**\n * Run env key naming the session that launched a run into its own workflow\n * session. PI_SESSION_ID names the owner; this names the launcher, which lists\n * the run, is told when it ends, and releases the workflow session after success.\n */\nexport const WORKFLOW_LAUNCHER_SESSION_ENV = 'PO_WORKFLOW_LAUNCHER_SESSION_ID';\n\n/** Message a workflow session sends its launcher to be released once its run succeeded. */\nexport const WORKFLOW_SESSION_RELEASE_TYPE = 'po-workflow.session-release';\n","import { z } from 'zod';\n\n/** A YAML list, or one comma-separated string, as `--domains a,b` accepts. */\nconst nameList = z\n .union([z.string(), z.array(z.string())])\n .transform((value) =>\n (Array.isArray(value) ? value : value.split(',')).map((name) => name.trim()).filter((name) => name.length > 0),\n );\n\nconst singleName = z.string().trim().min(1);\n\n/**\n * The Po keys of a workflow step's `runConfig`.\n *\n * The engine treats `runConfig` as an opaque map, so this is where a typo such\n * as `majormode` is caught instead of silently running on workspace defaults.\n */\nexport const poRunConfigSchema = z\n .object({\n majorMode: singleName.optional().describe('Major mode the step session runs in.'),\n minorModes: nameList.optional().describe('Minor modes activated in the step session.'),\n profile: singleName.optional().describe('Profile the step session runs as.'),\n domains: nameList.optional().describe('Domains selected for the step session. An empty list selects none.'),\n model: singleName.optional().describe('Model selector, provider/id.'),\n thinking: singleName.optional().describe('Thinking level for the model.'),\n subagentModel: singleName.optional().describe('Preferred Team subagent model, independent of the step model.'),\n subagentThinking: singleName.optional().describe('Preferred Team subagent thinking level.'),\n })\n .strict();\n\n/**\n * The same keys for a templated step, whose `runConfig` is also the data its\n * command template reads: keys Po does not use are left to the template.\n */\nexport const poTemplateRunConfigSchema = poRunConfigSchema.strip();\n\nexport type PoRunConfig = z.infer<typeof poRunConfigSchema>;\n\n/** The runConfig keys Po reads itself, the host keys `workflow-mcp doctor` checks steps against. */\nexport const PO_RUN_CONFIG_KEYS: readonly string[] = poRunConfigSchema.keyof().options;\n","import { z } from 'zod';\n\nconst RUN_SELECTOR_FIELDS = {\n runKey: z.string().min(1).describe('Run key of the workflow run.'),\n workspace: z.string().optional().describe('Workspace the run belongs to.'),\n} as const;\n\nexport const workflowRunInputSchema = z.discriminatedUnion('action', [\n z.object({ action: z.literal('status'), ...RUN_SELECTOR_FIELDS }).strict(),\n z.object({ action: z.literal('tail'), ...RUN_SELECTOR_FIELDS }).strict(),\n z.object({ action: z.literal('recovery-evidence'), ...RUN_SELECTOR_FIELDS }).strict(),\n z.object({ action: z.literal('follow'), ...RUN_SELECTOR_FIELDS }).strict(),\n z.object({ action: z.literal('open'), ...RUN_SELECTOR_FIELDS }).strict(),\n z.object({ action: z.literal('pause'), ...RUN_SELECTOR_FIELDS, reason: z.string().optional() }).strict(),\n z.object({ action: z.literal('resume'), ...RUN_SELECTOR_FIELDS, reason: z.string().optional() }).strict(),\n z.object({ action: z.literal('stop'), ...RUN_SELECTOR_FIELDS, reason: z.string().optional() }).strict(),\n z\n .object({\n action: z.literal('recover'),\n ...RUN_SELECTOR_FIELDS,\n dryRun: z.boolean().optional(),\n job: z.string().optional(),\n runner: z.string().optional(),\n })\n .strict(),\n]);\n\nexport type WorkflowRunInput = z.infer<typeof workflowRunInputSchema>;\n\nexport const dispatchInputSchema = z\n .object({\n description: z.string().optional().describe('Description shown for the workflow input.'),\n required: z.boolean().optional().describe('Whether the workflow input must be provided.'),\n default: z.string().optional().describe('Default value for the workflow input.'),\n type: z.string().optional().describe('Declared workflow input type.'),\n options: z.array(z.string()).optional().describe('Allowed values for the workflow input.'),\n })\n .passthrough();\n\nexport type DispatchInput = z.infer<typeof dispatchInputSchema>;\n\nexport const workflowDispatchInputsSchema = z\n .object({\n inputs: z.record(z.string(), dispatchInputSchema).optional().describe('Workflow dispatch input definitions.'),\n })\n .passthrough();\n\nexport const workflowCatalogPageSchema = z\n .object({\n directory: z.string().min(1).describe('Directory searched for workflow definitions.'),\n hasNextPage: z.boolean().describe('Whether another catalog page exists.'),\n page: z.number().int().positive().describe('One-based catalog page number.'),\n pageSize: z.number().int().positive().describe('Catalog page size.'),\n workflows: z\n .array(\n z\n .object({\n path: z.string().min(1).describe('Workflow path relative to the catalog directory.'),\n name: z.string().describe('Workflow display name.'),\n description: z.string().describe('Workflow description.'),\n tags: z.array(z.string()).describe('Workflow tags.'),\n })\n .passthrough(),\n )\n .describe('Workflow definitions on this page.'),\n })\n .passthrough();\n\nexport const workflowToolsInputSchema = z\n .object({\n action: z.enum(['recovery-evidence', 'recover']),\n ...RUN_SELECTOR_FIELDS,\n dryRun: z.boolean().optional().describe('recover only: print the replay without running it.'),\n runner: z.string().optional().describe('recover only: override the recorded runner.'),\n })\n .strict();\n","/**\n * Background-work registration for workflow runs.\n *\n * DESIGN PATTERNS:\n * - Hard dependency binding through Cordis injection\n * - Snapshot pattern: the extension pushes the current run set, the provider\n * only reads it\n *\n * CODING STANDARDS:\n * - Named exports only\n * - Explicit return types on exported functions\n *\n * AVOID:\n * - Process-global symbols or dynamic imports for extension communication\n * - Reporting runs owned by another Pi session\n */\n\nimport {\n DOOM_BACKGROUND_WORK_SERVICE,\n type BackgroundWorkProviderHandle,\n readDoomBackgroundWorkService,\n} from '@agimon-ai/po-core/backgroundWork';\nimport type { Context } from '@deepseek-ai/cordis';\n\nexport interface RunProviderItem {\n id: string;\n sessionId: string;\n}\n\nexport interface RunProviderHandle {\n /** Replace the reported run set. */\n update(items: RunProviderItem[]): void;\n /** Remove the registration. Safe to call when registration never happened. */\n dispose(): void;\n}\n\nconst PROVIDER_NAME = 'workflow-mcp';\n\n/**\n * Register a background-work provider for this session's workflow runs.\n *\n * The runtime pins all announcements to the active Pi session and validates\n * each snapshot before it reaches another extension.\n */\nexport function registerRunProvider(ctx: Context): RunProviderHandle {\n let items: RunProviderItem[] = [];\n let provider: BackgroundWorkProviderHandle | undefined;\n let disposed = false;\n ctx.inject([DOOM_BACKGROUND_WORK_SERVICE], (serviceContext) => {\n if (disposed) return undefined;\n const service = readDoomBackgroundWorkService(serviceContext);\n if (!service) return undefined;\n const registration = service.register({ provider: PROVIDER_NAME, listActiveWork: () => items });\n provider = registration;\n return () => {\n registration.dispose();\n if (provider === registration) provider = undefined;\n };\n });\n const handle: RunProviderHandle = {\n update(next) {\n items = next;\n provider?.update();\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n items = [];\n provider?.dispose();\n provider = undefined;\n },\n };\n return handle;\n}\n","/**\n * Pure bridging logic between MCP tool results and the Pi tool surface.\n *\n * DESIGN PATTERNS:\n * - Adapter pattern: MCP `CallToolResult` is converted to Pi's result shape\n * - Pure module: no service or tool-class imports, so this is unit-testable\n * without constructing the workflow execution stack\n *\n * CODING STANDARDS:\n * - Named exports only\n * - Explicit return types on exported functions\n *\n * AVOID:\n * - Importing tool classes or services here (that belongs in `piTools.ts`)\n * - Returning an error flag Pi does not read; Pi tools signal failure by throwing\n */\n\nimport type { WorkflowProgressJob, WorkflowRunRecord } from '@agimon-ai/workflow-mcp';\nimport type { AgentToolResult } from '@earendil-works/pi-coding-agent';\nimport type { CallToolResult } from '@modelcontextprotocol/server';\n\nimport { WORKFLOW_LAUNCHER_SESSION_ENV } from '../../constants/workflow';\n\n/**\n * Environment variable stamped onto every run launched from a Pi session.\n *\n * `RunWorkflowService` forwards `env` to the inner CLI invocation across the\n * `launch-command` delegation boundary and persists it on the run record, so\n * this survives backgrounding and identifies the launching session afterwards.\n */\nexport const PI_SESSION_ENV = 'PI_SESSION_ID';\n\n/** Operator override for the per-session launch ceiling. */\nconst MAX_CONCURRENT_ENV = 'WORKFLOW_MCP_MAX_CONCURRENT';\nconst DEFAULT_MAX_CONCURRENT = 5;\n\nexport interface WorkflowToolDetails {\n tool: string;\n}\n\n/** Resolve the per-session launch ceiling from the environment. */\nexport function resolveMaxConcurrent(env: NodeJS.ProcessEnv = process.env): number {\n const parsed = Number(env[MAX_CONCURRENT_ENV]);\n return Number.isInteger(parsed) && parsed > 0 ? parsed : DEFAULT_MAX_CONCURRENT;\n}\n\n/**\n * True when this session launched the run.\n *\n * Fails closed on a missing session id: an unstamped record (a CLI launch) and\n * a call arriving before the session id is known both match nothing, so no run\n * ever leaks across sessions through an undefined-equals-undefined comparison.\n */\nexport function isSessionRun(record: WorkflowRunRecord, sessionId: string | undefined): boolean {\n return sessionId !== undefined && record.env?.[PI_SESSION_ENV] === sessionId;\n}\n\n/** True when this session handed the run to a workflow session of its own: it is told, but does not own it. */\nexport function isLaunchedRun(record: WorkflowRunRecord, sessionId: string | undefined): boolean {\n return (\n sessionId !== undefined &&\n record.env?.[WORKFLOW_LAUNCHER_SESSION_ENV] === sessionId &&\n !isSessionRun(record, sessionId)\n );\n}\n\n/** The line a launcher's finish notice adds: where the run lived, and where to take it up. */\nexport function launchedRunHint(record: WorkflowRunRecord): string {\n const owner = record.env?.[PI_SESSION_ENV];\n return `It ran in workflow session ${owner ?? 'unknown'}; troubleshoot and recover it there.`;\n}\n\n/**\n * True when this session owns a run another session handed to it: it is the\n * run's workflow session, so a finished run is posted without starting a turn.\n */\nexport function isOwnedDelegatedRun(record: WorkflowRunRecord, sessionId: string | undefined): boolean {\n const launcher = record.env?.[WORKFLOW_LAUNCHER_SESSION_ENV];\n return isSessionRun(record, sessionId) && typeof launcher === 'string' && launcher !== '' && launcher !== sessionId;\n}\n\n/** Runs launched by one Pi session that are still running. */\nexport function runsForSession(records: WorkflowRunRecord[], sessionId: string): WorkflowRunRecord[] {\n return records.filter((record) => isSessionRun(record, sessionId) && record.stage === 'running');\n}\n\n/**\n * What the caller is told when the registry, not the launcher, acknowledged a\n * launch.\n *\n * Leads with the run key because it is the handle every other workflow action\n * takes, and it is no longer available any other way: the launcher's own output\n * is not waited for, so nothing else in this result carries it.\n */\nexport function launchedRunSummary(record: WorkflowRunRecord): string {\n return [\n `Started ${record.displayName} in workspace ${record.workspace}.`,\n `Run key: ${record.runKey}`,\n 'The run is registered and going. This call returned at that point rather than waiting for the launcher process to exit.',\n ].join('\\n');\n}\n\n/**\n * What the caller is told when the launch was handed off but no run has\n * registered inside the acknowledgement budget.\n *\n * Deliberately not an error: the launcher is slow rather than broken often\n * enough that failing here would strand runs that go on to start normally.\n * There is no run key to offer yet, so it points at the surfaces that do not\n * need one.\n */\nexport function launchHandoffSummary(workflowPath: string): string {\n return [\n `Launch handed off for ${workflowPath}, but no run has registered yet.`,\n 'Nothing was cancelled: the launcher is still starting, and a run that registers later still reports back here when it finishes.',\n 'Do not launch it again. Ask the user to check the active workflow list if they need to see it sooner.',\n ].join('\\n');\n}\n\n/**\n * Escape sequences a terminal consumes rather than prints.\n *\n * Built from a string with the rule silenced, the way `doom-runner`'s own\n * scrubber does it, because matching the escape byte is the entire job. Not\n * imported from there: that package's published build is a stale artifact\n * missing the export, and a launch notice should not need another package's\n * build to be current.\n */\n// oxlint-disable-next-line no-control-regex -- matching terminal control bytes is the point\nconst ESCAPE_SEQUENCE = new RegExp(\n ['\\\\u001B\\\\[[0-9;?]*[ -/]*[@-~]', '\\\\u001B\\\\][^\\\\u0007\\\\u001B]*(?:\\\\u0007|\\\\u001B\\\\\\\\)', '\\\\u001B[@-Z\\\\\\\\-_]'].join(\n '|',\n ),\n 'g',\n);\n\n/** Rows made only of box-drawing: separators that carry nothing once trimmed. */\nconst RULE_ROW = /^[\\s─-╿]*$/u;\nconst NOTICE_LINE_LIMIT = 3;\n/**\n * Widest a notice row may be before it is clipped.\n *\n * A three-line cap does not bound a toast on its own: the engine announces its\n * delegation by echoing the whole shell command, temp script path included, and\n * one line of that wraps across three rows of a narrow terminal and shoves the\n * transcript around. Clipped at a width every terminal can hold instead.\n */\nconst NOTICE_WIDTH_LIMIT = 100;\n\n/**\n * Cut a tool result down to something a toast can hold.\n *\n * The launch result used to reach `ui.notify` whole, and for a workflow that\n * executes in this process that result is the engine's entire console log:\n * banner, run directory, job tree, rules, colour. Pi rendered every line of it\n * over the transcript, which reads as a broken screen rather than as output.\n * Escape sequences go first: the log carries colour the notification would\n * render as literal text, and a stray clear or cursor-move would do to the\n * screen exactly what this function exists to prevent.\n */\nexport function launchNotice(text: string, limit: number = NOTICE_LINE_LIMIT): string {\n const lines = text\n .replace(ESCAPE_SEQUENCE, '')\n .split('\\n')\n .map((line) => line.trimEnd())\n .filter((line) => line.trim().length > 0 && !RULE_ROW.test(line))\n .map((line) => (line.length > NOTICE_WIDTH_LIMIT ? `${line.slice(0, NOTICE_WIDTH_LIMIT - 1)}…` : line));\n if (lines.length === 0) return 'Workflow started.';\n if (lines.length <= limit) return lines.join('\\n');\n return [...lines.slice(0, limit), `… ${lines.length - limit} more lines, in the run's own output.`].join('\\n');\n}\n\n/** Flatten MCP tool content to text for Pi. */\nexport function toolResultText(result: CallToolResult): string {\n return result.content\n .map((part) => (part.type === 'text' ? part.text : ''))\n .filter(Boolean)\n .join('\\n')\n .trim();\n}\n\n/**\n * Convert an MCP tool result into a Pi tool result.\n *\n * Pi signals tool failure by throwing: the agent loop catches it and builds the\n * error result. So an `isError` MCP result becomes a thrown error rather than a\n * successful result carrying a flag Pi would ignore.\n */\nexport function toAgentToolResult(\n tool: string,\n result: CallToolResult,\n errorOptions: string[] = [],\n): AgentToolResult<WorkflowToolDetails> {\n const text = toolResultText(result) || 'No output.';\n if (result.isError) throw new Error(withOptions(text, errorOptions));\n return { content: [{ type: 'text', text }], details: { tool } };\n}\n\n/**\n * Attach a short menu of next steps to a problem.\n *\n * An error with no route forward is where an agent invents one: retrying a\n * capacity limit, relaunching a run that should be recovered, or silently\n * giving up on work the user is waiting for. Naming two or three real options\n * turns an error into a decision, and the decision belongs to the user.\n */\nexport function withOptions(problem: string, options: string[]): string {\n if (options.length === 0) return problem;\n return [problem, '', 'Options, put these to the user rather than picking one yourself:', ...options.map(bullet)].join(\n '\\n',\n );\n}\n\nfunction bullet(option: string): string {\n return `- ${option}`;\n}\n\n/** The job and step a run died on, preferring the progress log to the record. */\nfunction failurePosition(\n record: WorkflowRunRecord,\n jobs: WorkflowProgressJob[],\n): { job?: string; step?: string; reason?: string } {\n // The progress log knows which step was in flight; the record only names the\n // job. Falling back keeps this working for runs that predate the log.\n const failedJob = jobs.find((job) => job.status === 'failed');\n const failedStep = failedJob?.steps.find((step) => step.status === 'failed');\n return {\n job: failedJob?.name ?? record.failedJob,\n step: failedStep?.name,\n reason: failedStep?.reason ?? failedJob?.reason,\n };\n}\n\n/**\n * Describe a finished run for the agent that launched it.\n *\n * Carries the job identifiers back so a dispatching agent can match the run to\n * the work item it launched it for without another lookup. When the run failed,\n * carries the failing step and a set of options too: the agent is being told\n * about this out of band, with no user question in flight, so without them it\n * has to guess whether to recover, relaunch, or report.\n */\nexport function finishedRunSummary(record: WorkflowRunRecord, jobs: WorkflowProgressJob[] = []): string {\n const outcome = record.stage === 'completed' ? 'completed' : `ended in ${record.stage}`;\n const failure = failurePosition(record, jobs);\n const lines: Array<string | undefined> = [\n `Workflow run ${record.runKey} in workspace ${record.workspace} ${outcome}.`,\n record.workflowId ? `Workflow: ${record.workflowId}` : undefined,\n failure.job ? `Failed job: ${failure.job}${failure.step ? ` (step: ${failure.step})` : ''}` : undefined,\n record.errorMessage ? `Error: ${record.errorMessage}` : undefined,\n failure.reason && failure.reason !== record.errorMessage ? `Step reported: ${failure.reason}` : undefined,\n ];\n const jobId = record.env?.AGIFLOW_JOB_ID;\n if (jobId) lines.push(`Agiflow job: ${record.env?.AGIFLOW_JOB_KIND ?? 'unknown'} ${jobId}`);\n\n const summary = lines.filter((line): line is string => Boolean(line)).join('\\n');\n if (record.stage === 'completed') return summary;\n\n // A run the user stopped is not a defect, so it gets no diagnosis step: the\n // question is only whether to pick it back up.\n const stopped = record.outcome === 'interrupted';\n if (stopped) {\n return withOptions(summary, [\n `workflow_run {\"action\":\"recover\",\"runKey\":${JSON.stringify(record.runKey)}}: pick it up where it stopped.`,\n 'Leave it stopped and move on.',\n ]);\n }\n\n const diagnosticText = [record.errorMessage, failure.reason].filter(Boolean).join('\\n');\n if (diagnosticText.includes('JOB_ALREADY_CLAIMED')) {\n return withOptions(summary, [\n 'Report contention: another worker owns this job. Do not unlock, release, or retry the claim automatically.',\n ]);\n }\n if (diagnosticText.includes('WORKFLOW_NOT_OWNED') || /release failed/i.test(diagnosticText)) {\n return withOptions(summary, [\n 'Inspect the current workflow ownership and ask the user before any release or unlock. Never force another worker’s lock.',\n ]);\n }\n if (/running workflow not found/i.test(diagnosticText)) {\n return withOptions(summary, [\n `workflow_run {\"action\":\"status\",\"runKey\":${JSON.stringify(record.runKey)}}: re-check current state before retrying.`,\n 'Report the recorded terminal state when no running owner remains.',\n ]);\n }\n\n return withOptions(summary, [\n `workflow_run {\"action\":\"tail\",\"runKey\":${JSON.stringify(record.runKey)}}: read the run's own output first, when the error above does not explain the failure.`,\n `workflow_run {\"action\":\"recover\",\"runKey\":${JSON.stringify(record.runKey)}}: resume from the failed job, keeping the work already done. Fits a transient or external cause.`,\n 'Report the failure and stop, when it needs a code change or a decision you cannot make.',\n ]);\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { resolveRootSessionId } from '@agimon-ai/po-core/childProcess';\nimport { type EmbeddedWorkflowFeature, type WorkflowRunRecord } from '@agimon-ai/workflow-mcp';\nimport type { AgentToolUpdateCallback, ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport type { CallToolResult } from '@modelcontextprotocol/server';\nimport { z } from 'zod';\n\nimport {\n launchedRunSummary,\n launchHandoffSummary,\n PI_SESSION_ENV,\n resolveMaxConcurrent,\n toolResultText,\n withOptions,\n} from '../piToolBridge';\n\nconst AGIFLOW_JOB_ID_ENV = 'AGIFLOW_JOB_ID';\nconst AGIFLOW_JOB_KIND_ENV = 'AGIFLOW_JOB_KIND';\nconst AGIFLOW_PROJECT_ID_ENV = 'AGIFLOW_PROJECT_ID';\n\nimport { WORKFLOW_LAUNCH_ID_ENV, LAUNCH_WORKFLOW_TOOL_NAME } from '../../constants/workflow';\n\nexport type WorkflowLaunchInput = z.infer<ReturnType<EmbeddedWorkflowFeature['runTool']['getInputSchema']>>;\n\n/**\n * Where a launch was answered from, which decides what the caller is told.\n *\n * Tagged rather than inferred from an absent field: the failure carries an\n * `unknown`, and `unknown` includes `undefined`, so only a tag can tell a\n * rejection apart from a result.\n */\ntype LaunchOutcome = { kind: 'value'; result: CallToolResult } | { kind: 'error'; error: unknown };\ntype LaunchAck =\n | { kind: 'settled'; outcome: LaunchOutcome }\n | { kind: 'record'; record: WorkflowRunRecord }\n | { kind: 'handoff' };\n\n/** How often the registry is asked whether the launch has produced a run. */\nconst LAUNCH_ACK_POLL_MS = 500;\n/**\n * How long to wait for that before answering without a run key.\n *\n * Long enough to cover a launcher that is merely slow, short enough that a\n * caller is never left holding a turn open for a launcher that will not answer.\n */\nconst LAUNCH_ACK_TIMEOUT_MS = 15_000;\n\nexport interface LaunchedRunQuery {\n /** The id this launch put in its run's environment; a run carrying it is this launch's. */\n launchId: string;\n sessionId: string | undefined;\n /** Epoch milliseconds the launch began, so an earlier run cannot match. */\n since: number;\n workflowPath: string;\n}\n\n/** What a launch reads off its caller: whose run it is. A Pi context is one; a server session adapts to it. */\nexport interface WorkflowLaunchContext {\n readonly sessionManager: { getSessionId(): string };\n}\n\nexport interface WorkflowLaunchExecutorDependencies<Ctx extends WorkflowLaunchContext = ExtensionContext> {\n readonly environment: Readonly<Record<string, string | undefined>>;\n activeRunCount?: () => Promise<number>;\n onLaunch?: (ctx: Ctx) => Promise<void> | void;\n observeSession?: (sessionId: string | undefined) => void;\n rejectRunner?: (workflowPath: string, runner: string) => string | undefined;\n runTool: Pick<EmbeddedWorkflowFeature['runTool'], 'execute'>;\n trackPendingRun: <T>(run: Promise<T>) => Promise<T>;\n /**\n * The run this launch registered, or undefined while none has appeared.\n *\n * Its presence is what lets a launch answer on the registry instead of on the\n * launcher process exiting. Left out, the launch waits for the process, which\n * is the behaviour every caller had before.\n */\n findLaunchedRun?: (query: LaunchedRunQuery) => Promise<WorkflowRunRecord | undefined>;\n /** Report a launch that fails after this call already answered \"started\". */\n onLateFailure?: (error: unknown, ctx: Ctx) => void;\n launchAckPollMs?: number;\n launchAckTimeoutMs?: number;\n}\n\nexport interface WorkflowLaunchExecutor<Ctx extends WorkflowLaunchContext = ExtensionContext> {\n execute(\n input: WorkflowLaunchInput,\n ctx: Ctx,\n onUpdate?: AgentToolUpdateCallback<{ tool: string }>,\n ): Promise<CallToolResult>;\n}\n\nexport function reportProgress(\n onUpdate: AgentToolUpdateCallback<{ tool: string }> | undefined,\n tool: string,\n message: string,\n): void {\n onUpdate?.({ content: [{ type: 'text', text: message }], details: { tool } });\n}\n\nexport const launchFailureOptions = [\n 'Report the failure to the user with the error above. A launch failure is usually a bad workflow path, a missing launcher, or a workflow whose own pre-conditions refused.',\n 'list_workflows: confirm the workflow path exists and its description matches the work, if the path may be wrong.',\n 'workflow_run with action status: check whether an earlier attempt is already running before launching again.',\n];\n\n/**\n * An Error, whatever the launch rejected with.\n *\n * A rejection reaches here as `unknown` because it crossed a promise boundary,\n * and rethrowing that as-is hands Pi's tool layer something it cannot read a\n * message or a stack off. The original is kept as the cause rather than\n * flattened into a string.\n */\nfunction asError(value: unknown): Error {\n return value instanceof Error ? value : new Error(String(value), { cause: value });\n}\n\n/** Resolves to undefined, so a race against it reads as \"nothing settled yet\". */\nfunction sleep(ms: number): Promise<undefined> {\n return new Promise((settle) => {\n const timer = setTimeout(() => settle(undefined), ms);\n timer.unref?.();\n });\n}\n\n/**\n * Wait for whichever answer arrives first: the launch settling, the run\n * appearing in the registry, or the budget running out.\n *\n * A launch that delegates to a terminal launcher settles when that launcher's\n * whole process chain closes, which on a loaded machine has been measured\n * minutes after the run itself was registered and working. The registry is the\n * earlier and more truthful signal: a run recorded there is a run that started.\n */\nasync function awaitLaunchAck<Ctx extends WorkflowLaunchContext>(\n settled: Promise<LaunchOutcome>,\n dependencies: WorkflowLaunchExecutorDependencies<Ctx>,\n query: LaunchedRunQuery,\n): Promise<LaunchAck> {\n const findLaunchedRun = dependencies.findLaunchedRun;\n if (!findLaunchedRun) return { kind: 'settled', outcome: await settled };\n\n return awaitRunAck(\n settled,\n () => findLaunchedRun(query),\n dependencies.launchAckPollMs,\n dependencies.launchAckTimeoutMs,\n );\n}\n\nexport async function awaitRunAck(\n settled: Promise<LaunchOutcome>,\n find: () => Promise<WorkflowRunRecord | undefined>,\n pollMs = LAUNCH_ACK_POLL_MS,\n timeoutMs = LAUNCH_ACK_TIMEOUT_MS,\n): Promise<LaunchAck> {\n const deadline = Date.now() + timeoutMs;\n for (;;) {\n const outcome = await Promise.race([settled, sleep(pollMs)]);\n if (outcome) return { kind: 'settled', outcome };\n // A registry read that throws must not fail the launch: the run may be\n // perfectly healthy, and the settled promise is still the fallback.\n const record = await find().catch(() => undefined);\n if (record) return { kind: 'record', record };\n if (Date.now() >= deadline) return { kind: 'handoff' };\n }\n}\n\n/**\n * Carry a failure that lands after the caller was told the run started.\n *\n * Answering early trades the launcher's exit code for timeliness. Dropping that\n * code entirely is not part of the trade: a launch that fails a minute later\n * would otherwise leave a user waiting on a run that never existed.\n */\nfunction reportLateFailure<Ctx extends WorkflowLaunchContext>(\n settled: Promise<LaunchOutcome>,\n dependencies: WorkflowLaunchExecutorDependencies<Ctx>,\n ctx: Ctx,\n): void {\n void settled.then((outcome) => {\n if (outcome.kind === 'error') {\n dependencies.onLateFailure?.(asError(outcome.error), ctx);\n return;\n }\n if (outcome.result.isError) {\n dependencies.onLateFailure?.(new Error(toolResultText(outcome.result) || 'Workflow launch failed.'), ctx);\n }\n });\n}\n\nexport function createWorkflowLaunchExecutor<Ctx extends WorkflowLaunchContext = ExtensionContext>(\n dependencies: WorkflowLaunchExecutorDependencies<Ctx>,\n): WorkflowLaunchExecutor<Ctx> {\n return {\n async execute(input, ctx, onUpdate) {\n const sessionId = resolveRootSessionId(ctx.sessionManager.getSessionId(), dependencies.environment);\n dependencies.observeSession?.(sessionId);\n const agiflowJobKind = input.env?.[AGIFLOW_JOB_KIND_ENV]?.trim();\n const agiflowJobId = input.env?.[AGIFLOW_JOB_ID_ENV]?.trim();\n const explicitProjectId = input.env?.[AGIFLOW_PROJECT_ID_ENV]?.trim();\n if (Boolean(agiflowJobKind) !== Boolean(agiflowJobId)) {\n throw new Error('Agiflow workflow launches require AGIFLOW_JOB_KIND and AGIFLOW_JOB_ID together.');\n }\n if (agiflowJobKind && agiflowJobKind !== 'task' && agiflowJobKind !== 'work-unit') {\n throw new Error('Agiflow workflow launches require AGIFLOW_JOB_KIND to be task or work-unit.');\n }\n if (agiflowJobKind && !explicitProjectId) {\n throw new Error('Agiflow workflow launches require AGIFLOW_PROJECT_ID with the job identity.');\n }\n if (agiflowJobKind && !input.prompt?.trim()) {\n throw new Error(\n 'Agiflow workflow launches require a non-empty prompt so user_prompt runs do not wait for terminal input.',\n );\n }\n reportProgress(onUpdate, LAUNCH_WORKFLOW_TOOL_NAME, 'Checking workflow capacity...');\n const maxConcurrent = resolveMaxConcurrent(dependencies.environment);\n const active = (await dependencies.activeRunCount?.()) ?? 0;\n if (active >= maxConcurrent) {\n throw new Error(\n withOptions(`This session is at capacity: ${active}/${maxConcurrent} workflows running.`, [\n 'Wait for a running workflow to finish, then launch again. The extension reports each one as it ends.',\n 'workflow_run with action status: show what is running, so the user can judge whether something is stuck.',\n 'workflow_run with action stop: free a slot by stopping a run the user no longer wants.',\n ]),\n );\n }\n\n if (input.runner) {\n const rejection = dependencies.rejectRunner?.(input.workflowPath, input.runner);\n if (rejection) throw new Error(rejection);\n }\n reportProgress(onUpdate, LAUNCH_WORKFLOW_TOOL_NAME, `Launching workflow ${input.workflowPath}...`);\n const workflowEnv = { ...input.env };\n const dispatcherContextFile = dependencies.environment.AGIFLOW_DISPATCH_CONTEXT_FILE;\n const dispatcherProjectId = dependencies.environment[AGIFLOW_PROJECT_ID_ENV]?.trim();\n if (\n dispatcherContextFile &&\n agiflowJobKind &&\n dispatcherProjectId &&\n explicitProjectId &&\n dispatcherProjectId !== explicitProjectId\n ) {\n throw new Error(\n `Agiflow workflow project identity conflicts with the dispatcher context (${explicitProjectId} versus ${dispatcherProjectId}).`,\n );\n }\n if (dispatcherContextFile) {\n for (const key of [\n 'AGIFLOW_ORGANIZATION_ID',\n 'AGIFLOW_PROJECT_ID',\n 'AGIFLOW_DEVICE_ID',\n 'BACKEND_AGIFLOW_API_ENDPOINT',\n 'AGIFLOW_DISPATCH_SECRET_FILE',\n ] as const) {\n const hostValue = dependencies.environment[key];\n if (hostValue) workflowEnv[key] = hostValue;\n }\n }\n const since = Date.now();\n const launchId = randomUUID();\n const launch = dependencies.trackPendingRun(\n dependencies.runTool.execute({\n ...input,\n env: { ...workflowEnv, [PI_SESSION_ENV]: sessionId, [WORKFLOW_LAUNCH_ID_ENV]: launchId },\n }),\n );\n // Folded into a value before anything races it. A promise this function\n // may stop awaiting must never be able to reject unobserved, which in\n // Node ends the whole process, Pi's TUI included.\n const settled = foldOutcome(launch);\n\n const ack = await awaitLaunchAck(settled, dependencies, {\n launchId,\n sessionId,\n since,\n workflowPath: input.workflowPath,\n });\n\n if (ack.kind === 'settled') {\n const outcome = ack.outcome;\n if (outcome.kind === 'error') throw asError(outcome.error);\n const result = outcome.result;\n if (result.isError)\n throw new Error(withOptions(toolResultText(result) || 'Workflow launch failed.', launchFailureOptions));\n await dependencies.onLaunch?.(ctx);\n return result;\n }\n\n reportLateFailure(settled, dependencies, ctx);\n await dependencies.onLaunch?.(ctx);\n return {\n content: [\n {\n type: 'text',\n text: ack.kind === 'record' ? launchedRunSummary(ack.record) : launchHandoffSummary(input.workflowPath),\n },\n ],\n };\n },\n };\n}\n\nexport function foldOutcome(promise: Promise<CallToolResult>): Promise<LaunchOutcome> {\n return promise.then(\n (result): LaunchOutcome => ({ kind: 'value', result }),\n (error: unknown): LaunchOutcome => ({ kind: 'error', error }),\n );\n}\n","import { resolve } from 'node:path';\n\nimport type { Step, Workflow } from '@agimon-ai/workflow-mcp';\n\nimport { WORKFLOW_LAUNCHER_SESSION_ENV } from '../../constants/workflow';\nimport type {\n WorkflowJobPhase,\n WorkflowJobView,\n WorkflowOutcome,\n WorkflowPosition,\n WorkflowProgressState,\n WorkflowRunView,\n WorkflowStage,\n WorkflowStepRefView,\n WorkflowStepView,\n} from '../../types/webWorkflows';\n\n/**\n * MIRRORS @agimon-ai/workflow-mcp's on-disk registry\n * (src/services/WorkflowRegistryService.ts and WorkflowProgressService.ts in\n * that package). The engine keeps one directory per run under\n * `<home>/workspaces/<workspace>/<stage>/<runKey>/` holding a `run.json`\n * record and an append-only `progress.ndjson` job/step log; the hub only ever\n * reads them. The derivation is duplicated rather than imported because\n * po-web must not depend on the engine at runtime; the unit suite pins\n * this mirror against the package's published types.\n */\nconst DEFAULT_WORKFLOW_HOME_DIR_NAME = '.workflow-mcp';\nexport const WORKFLOW_HOME_ENV = 'WORKFLOW_MCP_HOME';\nexport const WORKSPACES_DIR_NAME = 'workspaces';\nexport const RUN_RECORD_FILE_NAME = 'run.json';\nexport const PROGRESS_FILE_NAME = 'progress.ndjson';\nexport const WORKFLOW_STAGES: readonly WorkflowStage[] = ['running', 'completed', 'error'];\n\n/**\n * Errored runs stay a day, which is how long recovery has to act on them.\n *\n * Finished runs have no retention of their own: a session keeps every run it\n * launched, grouped by outcome, for as long as the session lives. A run leaves\n * the view when the engine prunes its registry directory, not on a timer here,\n * because \"what did this session run today\" is a question asked long after the\n * run settled.\n */\nexport const WORKFLOW_ERROR_RETENTION_MS = 24 * 60 * 60 * 1000;\n/**\n * Upper bound per outcome group rather than over the whole list.\n *\n * One cap across every run let a long stream of green runs push a failure out\n * of the list, which is the one thing that must never fall off the end.\n */\nexport const MAX_PRESENTED_WORKFLOW_RUNS_PER_GROUP = 24;\n\n/** The env key po-workflow stamps on runs it launches; ties a run to a Pi session. */\nexport const PI_SESSION_ENV = 'PI_SESSION_ID';\n\nconst PROGRESS_STATES: ReadonlySet<string> = new Set([\n 'running',\n 'completed',\n 'skipped',\n 'failed',\n 'pause_requested',\n 'paused',\n 'resumed',\n]);\nconst OUTCOMES: ReadonlySet<string> = new Set(['success', 'skipped', 'failed', 'interrupted']);\nconst EXECUTION_STATES: ReadonlySet<string> = new Set(['running', 'pause_requested', 'paused', 'resume_requested']);\nconst STEP_TERMINAL_STATES: ReadonlySet<WorkflowProgressState> = new Set(['completed', 'skipped', 'failed']);\n/** The engine records its pre:/post: blocks under these reserved pseudo-job names. */\nconst PHASE_JOB_PRE = 'pre';\nconst PHASE_JOB_POST = 'post';\n\n// oxlint-disable-next-line no-control-regex -- stripping terminal color codes from errorMessage is the point\nconst ANSI_ESCAPE_PATTERN = /\\u001b\\[[0-9;]*[A-Za-z]/g;\n\nexport interface WorkflowHomeInput {\n /** process.env.WORKFLOW_MCP_HOME, supplied by the caller. */\n envValue: string | undefined;\n /** os.homedir(), supplied by the caller. */\n homeDir: string;\n}\n\n/** Where workflow-mcp keeps its registry, mirroring the engine's own resolution. */\nexport function resolveWorkflowHome(input: WorkflowHomeInput): string {\n return resolve(\n input.envValue !== undefined && input.envValue !== ''\n ? input.envValue\n : resolve(input.homeDir, DEFAULT_WORKFLOW_HOME_DIR_NAME),\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction asOptionalString(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\nfunction asOptionalNumber(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\n/** Text without its terminal escape codes, as a log file or a reader wants it. */\nexport function withoutAnsi(text: string): string {\n return text.replace(ANSI_ESCAPE_PATTERN, '');\n}\n\nfunction stripAnsi(text: string): string {\n return withoutAnsi(text).trim();\n}\n\n/**\n * One run record plus the facts the hub needs for session scoping but the\n * page never sees.\n */\nexport interface ParsedWorkflowRun {\n /** The wire view, before the progress log is folded in (jobs empty). */\n view: WorkflowRunView;\n /** env.PI_SESSION_ID from the record, when the launcher stamped one. */\n piSessionId?: string;\n /** env[WORKFLOW_LAUNCHER_SESSION_ENV]: the session that handed this run to its own workflow session. */\n launcherSessionId?: string;\n}\n\n/**\n * Validates one run.json into the wire shape plus scoping facts.\n *\n * Returns undefined for anything unreadable or a foreign format. The record\n * is trusted for its own stage: the registry rewrites it when a run moves\n * between stage directories.\n */\nexport function parseWorkflowRunRecord(raw: string): ParsedWorkflowRun | undefined {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return undefined;\n }\n if (!isRecord(parsed)) return undefined;\n const runKey = asOptionalString(parsed.runKey);\n const workspace = asOptionalString(parsed.workspace);\n const workflowPath = asOptionalString(parsed.workflowPath);\n const startedAt = asOptionalString(parsed.startedAt);\n const stage = asOptionalString(parsed.stage);\n if (!runKey || !workspace || !workflowPath || !startedAt) return undefined;\n if (stage === undefined || !WORKFLOW_STAGES.includes(stage as WorkflowStage)) return undefined;\n\n const outcome = asOptionalString(parsed.outcome);\n const executionState = asOptionalString(parsed.executionState);\n const rawError = asOptionalString(parsed.errorMessage);\n const env = isRecord(parsed.env) ? parsed.env : undefined;\n const view: WorkflowRunView = {\n ...(asOptionalString(parsed.runId) === undefined ? {} : { runId: asOptionalString(parsed.runId) }),\n runKey,\n workspace,\n displayName: asOptionalString(parsed.displayName) ?? runKey,\n ...(asOptionalString(parsed.workflowName) === undefined\n ? {}\n : { workflowName: asOptionalString(parsed.workflowName) }),\n workflowPath,\n stage: stage as WorkflowStage,\n ...(outcome !== undefined && OUTCOMES.has(outcome) ? { outcome: outcome as WorkflowOutcome } : {}),\n ...(executionState !== undefined && EXECUTION_STATES.has(executionState)\n ? { executionState: executionState as WorkflowRunView['executionState'] }\n : {}),\n ...(asOptionalString(parsed.prompt) === undefined ? {} : { prompt: asOptionalString(parsed.prompt) }),\n startedAt,\n ...(asOptionalString(parsed.finishedAt) === undefined ? {} : { finishedAt: asOptionalString(parsed.finishedAt) }),\n ...(rawError === undefined ? {} : { errorMessage: stripAnsi(rawError) }),\n ...(asOptionalString(parsed.failedJob) === undefined ? {} : { failedJob: asOptionalString(parsed.failedJob) }),\n ...(parsed.stale === true ? { stale: true } : {}),\n ...(asOptionalString(parsed.staleReason) === undefined\n ? {}\n : { staleReason: asOptionalString(parsed.staleReason) }),\n ...(asOptionalString(parsed.worktreeBranch) === undefined\n ? {}\n : { worktreeBranch: asOptionalString(parsed.worktreeBranch) }),\n jobs: [],\n };\n const piSessionId = env === undefined ? undefined : asOptionalString(env[PI_SESSION_ENV]);\n const launcherSessionId = env === undefined ? undefined : asOptionalString(env[WORKFLOW_LAUNCHER_SESSION_ENV]);\n if (piSessionId !== undefined) view.ownerSessionId = piSessionId;\n if (launcherSessionId !== undefined) view.launcherSessionId = launcherSessionId;\n return {\n view,\n ...(piSessionId === undefined ? {} : { piSessionId }),\n ...(launcherSessionId === undefined ? {} : { launcherSessionId }),\n };\n}\n\ninterface WorkflowProgressEvent {\n type: 'job' | 'step';\n status: WorkflowProgressState;\n job: string;\n step?: string;\n index?: number;\n total?: number;\n reason?: string;\n ref?: WorkflowStepRefView;\n group?: string;\n at: string;\n}\n\nfunction parseStepRef(value: unknown): WorkflowStepRefView | undefined {\n if (!isRecord(value)) return undefined;\n const kind = asOptionalString(value.kind);\n const id = asOptionalString(value.id);\n if (!kind || !id) return undefined;\n const label = asOptionalString(value.label);\n return { kind, id, ...(label === undefined ? {} : { label }) };\n}\n\n/**\n * Parses the append-only progress log. Malformed lines are skipped rather\n * than failing the file: a reader routinely catches a torn final line\n * mid-append.\n */\nexport function parseWorkflowProgress(raw: string): WorkflowProgressEvent[] {\n const events: WorkflowProgressEvent[] = [];\n for (const line of raw.split('\\n')) {\n const trimmed = line.trim();\n if (trimmed === '') continue;\n let parsed: unknown;\n try {\n parsed = JSON.parse(trimmed);\n } catch {\n continue;\n }\n if (!isRecord(parsed)) continue;\n const type = parsed.type;\n const status = asOptionalString(parsed.status);\n const job = asOptionalString(parsed.job);\n const at = asOptionalString(parsed.at);\n if ((type !== 'job' && type !== 'step') || !job || !at) continue;\n if (status === undefined || !PROGRESS_STATES.has(status)) continue;\n const step = asOptionalString(parsed.step);\n const index = asOptionalNumber(parsed.index);\n const total = asOptionalNumber(parsed.total);\n const reason = asOptionalString(parsed.reason);\n const ref = parseStepRef(parsed.ref);\n const group = asOptionalString(parsed.group);\n events.push({\n type,\n status: status as WorkflowProgressState,\n job,\n ...(step === undefined ? {} : { step }),\n ...(index === undefined ? {} : { index }),\n ...(total === undefined ? {} : { total }),\n ...(reason === undefined ? {} : { reason }),\n ...(ref === undefined ? {} : { ref }),\n ...(group === undefined ? {} : { group }),\n at,\n });\n }\n return events;\n}\n\nfunction jobPhase(name: string): WorkflowJobPhase {\n if (name === PHASE_JOB_PRE) return PHASE_JOB_PRE;\n if (name === PHASE_JOB_POST) return PHASE_JOB_POST;\n return 'job';\n}\n\n/** Names match the engine's progress log, including unnamed parallel children. */\nfunction plannedSteps(steps: readonly Step[] = []): WorkflowStepView[] {\n return steps.flatMap((step, index) => {\n const name = step.name ?? `step ${index + 1}`;\n return step.parallel === undefined\n ? [{ name, status: 'pending' as const }]\n : step.parallel.map((child, childIndex) => ({\n name: child.name ?? `${name} ${childIndex + 1}`,\n status: 'pending' as const,\n group: name,\n }));\n });\n}\n\n/** The whole declared route, before any job or step has emitted progress. */\nexport function planWorkflowJobs(workflow: Workflow, order: readonly string[]): WorkflowJobView[] {\n const jobs: WorkflowJobView[] = order.map((name) => {\n const job = workflow.jobs[name]!;\n return {\n name,\n phase: 'job',\n status: 'pending',\n steps: [...plannedSteps(job.preJob?.steps), ...plannedSteps(job.steps), ...plannedSteps(job.postJob?.steps)],\n };\n });\n if (workflow.pre !== undefined) {\n jobs.unshift({ name: PHASE_JOB_PRE, phase: 'pre', status: 'pending', steps: plannedSteps(workflow.pre.steps) });\n }\n if (workflow.post !== undefined) {\n jobs.push({ name: PHASE_JOB_POST, phase: 'post', status: 'pending', steps: plannedSteps(workflow.post.steps) });\n }\n return jobs;\n}\n\n/** Overlay progress on the plan, retaining recorded jobs and steps absent from the current definition. */\nexport function foldWorkflowProgress(\n events: readonly WorkflowProgressEvent[],\n plan: readonly WorkflowJobView[] = [],\n): WorkflowJobView[] {\n const jobs = plan.map((job) => ({ ...job, steps: job.steps.map((step) => ({ ...step })) }));\n const jobByName = new Map(jobs.map((job) => [job.name, job]));\n for (const event of events) {\n let job = jobByName.get(event.job);\n if (job === undefined) {\n job = { name: event.job, phase: jobPhase(event.job), status: event.status, steps: [] };\n jobByName.set(event.job, job);\n jobs.push(job);\n }\n if (event.type === 'job') {\n if (event.status === 'running' && (event.index !== undefined || job.status !== 'running')) {\n delete job.reason;\n delete job.endedAt;\n delete job.startedAt;\n }\n job.status = event.status;\n if (event.reason !== undefined) job.reason = event.reason;\n if (event.index !== undefined) job.index = event.index;\n if (event.total !== undefined) job.total = event.total;\n if (event.status === 'running' && job.startedAt === undefined) job.startedAt = event.at;\n if (STEP_TERMINAL_STATES.has(event.status)) job.endedAt = event.at;\n continue;\n }\n if (event.step === undefined) continue;\n if (job.status === 'pending') job.status = event.status;\n let step: WorkflowStepView | undefined = job.steps.find((candidate) => candidate.name === event.step);\n if (step === undefined) {\n step = { name: event.step, status: event.status };\n job.steps.push(step);\n } else if (event.status === 'running' && (event.index !== undefined || step.status !== 'running')) {\n // An indexed start is a new attempt even if interruption left it running.\n // Started again, as a fix loop does: nothing of the previous attempt, its\n // session or pane included, belongs to this one. Guidance for the old\n // session would wake an agent working beside the new attempt.\n delete step.ref;\n delete step.reason;\n delete step.endedAt;\n delete step.startedAt;\n }\n step.status = event.status;\n if (event.reason !== undefined) step.reason = event.reason;\n if (event.ref !== undefined) step.ref = event.ref;\n if (event.group !== undefined) step.group = event.group;\n if (event.status === 'running' && step.startedAt === undefined) step.startedAt = event.at;\n if (STEP_TERMINAL_STATES.has(event.status)) step.endedAt = event.at;\n }\n for (const job of jobs) {\n if (job.status === 'skipped') {\n for (const step of job.steps) {\n if (step.status === 'pending') step.status = 'skipped';\n }\n }\n }\n return jobs;\n}\n\nconst ACTIVE_PROGRESS_STATES: ReadonlySet<WorkflowProgressState> = new Set([\n 'running',\n 'pause_requested',\n 'paused',\n 'resumed',\n]);\n\n/** The job and step a run is on right now, for the NOW breadcrumb. */\nexport function workflowPosition(jobs: readonly WorkflowJobView[]): WorkflowPosition | undefined {\n for (let jobIndex = jobs.length - 1; jobIndex >= 0; jobIndex -= 1) {\n const job = jobs[jobIndex]!;\n if (!ACTIVE_PROGRESS_STATES.has(job.status)) continue;\n for (let stepIndex = job.steps.length - 1; stepIndex >= 0; stepIndex -= 1) {\n const step = job.steps[stepIndex]!;\n if (ACTIVE_PROGRESS_STATES.has(step.status)) {\n return {\n job: job.name,\n step: step.name,\n ...(job.index === undefined ? {} : { index: job.index }),\n ...(job.total === undefined ? {} : { total: job.total }),\n };\n }\n }\n return {\n job: job.name,\n ...(job.index === undefined ? {} : { index: job.index }),\n ...(job.total === undefined ? {} : { total: job.total }),\n };\n }\n return undefined;\n}\n\n/** The finished view: record fields plus the folded job tree and position. */\nexport function completeWorkflowRunView(view: WorkflowRunView, jobs: WorkflowJobView[]): WorkflowRunView {\n const position = view.stage === 'running' ? workflowPosition(jobs) : undefined;\n return { ...view, jobs, ...(position === undefined ? {} : { position }) };\n}\n\n/**\n * Whether a run belongs on a session's workflow tab: launched by that Pi\n * session, which is the same env test po-workflow's isSessionRun applies.\n *\n * The registry is one directory under $HOME shared by every repository and\n * every Pi session on the machine, so repository proximity is not ownership.\n * Scoping on it as well let two sessions open in one repo read each other's\n * history, and kept a dead session's runs on the board of every session that\n * replaced it. Fails closed on an unstamped record, which is what a launch\n * from the CLI rather than from a session leaves behind.\n */\nexport function runBelongsToSession(run: ParsedWorkflowRun, sessionId: string): boolean {\n return run.piSessionId !== undefined && run.piSessionId === sessionId;\n}\n\n/** Whether the session handed this run to a workflow session of its own: it lists the run but does not own it. */\nexport function runLaunchedBySession(run: ParsedWorkflowRun, sessionId: string): boolean {\n return (\n run.launcherSessionId !== undefined && run.launcherSessionId === sessionId && !runBelongsToSession(run, sessionId)\n );\n}\n\nfunction parseTime(value: string | undefined): number {\n if (value === undefined) return 0;\n const time = Date.parse(value);\n return Number.isFinite(time) ? time : 0;\n}\n\nconst STAGE_ORDER: Readonly<Record<WorkflowStage, number>> = { running: 0, error: 1, completed: 2 };\n\n/**\n * Whether a run still belongs in the view.\n *\n * Only errored runs age out here, and slowly: everything else a session\n * started stays until the engine forgets the run itself.\n */\nfunction withinRetention(run: WorkflowRunView, now: number): boolean {\n if (run.stage !== 'error') return true;\n const settledAt = parseTime(run.finishedAt) || parseTime(run.startedAt);\n return now - settledAt < WORKFLOW_ERROR_RETENTION_MS;\n}\n\n/**\n * When a run last moved, which is what orders it within its group.\n *\n * A running run has only its start; a settled one is ordered by when it\n * settled, because a list kept for the whole session is read as a history and\n * two runs started together can finish an hour apart.\n */\nfunction lastMovedAt(run: WorkflowRunView): number {\n return run.stage === 'running' ? parseTime(run.startedAt) : parseTime(run.finishedAt) || parseTime(run.startedAt);\n}\n\n/**\n * Running runs first, then errored (recovery acts on them), then finished;\n * newest first within a group, and each group capped on its own.\n */\nexport function presentWorkflowRuns(runs: readonly WorkflowRunView[], now: number): WorkflowRunView[] {\n const groups = new Map<WorkflowStage, WorkflowRunView[]>();\n for (const run of runs) {\n if (!withinRetention(run, now)) continue;\n const group = groups.get(run.stage);\n if (group) group.push(run);\n else groups.set(run.stage, [run]);\n }\n return [...groups.entries()]\n .sort(([left], [right]) => STAGE_ORDER[left] - STAGE_ORDER[right])\n .flatMap(([, group]) =>\n group\n .sort((left, right) => lastMovedAt(right) - lastMovedAt(left))\n .slice(0, MAX_PRESENTED_WORKFLOW_RUNS_PER_GROUP),\n );\n}\n","import { randomUUID } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { Logger, WorkflowRunRecord, WorkflowRunRegistration } from '@agimon-ai/workflow-mcp';\nimport type { CallToolResult } from '@modelcontextprotocol/server';\n\nimport { WORKFLOW_LAUNCH_ID_ENV } from '../../constants/workflow';\nimport type { StepTelemetry } from '../stepExecutor/type';\nimport {\n awaitRunAck,\n foldOutcome,\n createWorkflowLaunchExecutor,\n type WorkflowLaunchContext,\n type WorkflowLaunchInput,\n} from '../workflowExecution';\nimport { PI_SESSION_ENV, withoutAnsi as plain } from '../workflowRuns';\nimport type { ServerLaunchDependencies, ServerLauncher } from './type';\n\n/** Beside the run's own files, so the run's artifacts list and its deletion both include it. */\nexport const RUN_LOG_FILENAME = 'engine.log';\n/** Exit codes a run ends with when nothing went wrong: finished, or skipped by its triggers. */\nconst SUCCESS_EXIT_CODES = new Set([0, 2]);\n/** Lines kept before a run has a directory to write them to. */\nconst PENDING_LINE_LIMIT = 500;\n/** How much of a failed run's output its telemetry keeps. */\nconst FAILURE_TAIL_LINES = 20;\n/** How long closing a session waits for its in-process runs to stop. */\nconst STOP_TIMEOUT_MS = 10_000;\nconst SESSION_CLOSED_REASON = 'The session that runs this workflow closed.';\nconst RUNNING_STAGE = 'running';\n\nconst LAUNCH_REQUESTED_EVENT = 'doom_workflow.launch_requested';\nconst RUN_STARTED_EVENT = 'doom_workflow.run_started';\nconst RUN_FINISHED_EVENT = 'doom_workflow.run_finished';\nconst RUN_FAILED_EVENT = 'doom_workflow.run_failed';\nconst ENGINE_ERROR_EVENT = 'doom_workflow.engine_error';\nconst ENGINE_WARNING_EVENT = 'doom_workflow.engine_warning';\nconst RUN_LOG_FAILED_EVENT = 'doom_workflow.run_log_failed';\nconst RUN_STOP_FAILED_EVENT = 'doom_workflow.run_stop_failed';\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((settle) => {\n const timer = setTimeout(settle, ms);\n timer.unref?.();\n });\n}\n\nfunction textResult(text: string, isError = false): CallToolResult {\n return { content: [{ type: 'text', text }], ...(isError ? { isError: true } : {}) };\n}\n\n/** An engine log for one run: its lines as they are written, then in the run directory. */\ninterface RunLog {\n readonly logger: Logger;\n /** Writes what was held so far into `file`, and every later line after it. */\n attach(file: string): void;\n /** Settles once every line written so far has reached the file. */\n flushed(): Promise<void>;\n}\n\n/**\n * The engine's log for one run, where a reader can find it.\n *\n * The engine writes why a step failed as a log line. Without a logger, those\n * lines exist only in the output the run returns at its end, so a run that is\n * still going, or one read later, has nothing to say about its failures. Here\n * every line goes to the run directory's `engine.log`, and errors and warnings\n * also go to telemetry, with the line as the exception so the text survives.\n */\nfunction createRunLog(telemetry: StepTelemetry | undefined): RunLog {\n const pending: string[] = [];\n let file: string | undefined;\n let writing = Promise.resolve();\n const reportLogFailure = (error: unknown): Promise<void> =>\n telemetry?.recordWarning(RUN_LOG_FAILED_EVENT, error) ?? Promise.resolve();\n const append = (line: string): void => {\n if (file === undefined) {\n pending.push(line);\n if (pending.length > PENDING_LINE_LIMIT) pending.shift();\n return;\n }\n const target = file;\n writing = writing.then(() => fs.promises.appendFile(target, `${line}\\n`, 'utf8')).catch(reportLogFailure);\n };\n return {\n logger: {\n info: (message) => append(plain(message)),\n warn: (message) => {\n const line = plain(message);\n append(line);\n void telemetry?.recordWarning(ENGINE_WARNING_EVENT, new Error(line.trim()));\n },\n error: (message) => {\n const line = plain(message);\n append(line);\n void telemetry?.recordError(ENGINE_ERROR_EVENT, new Error(line.trim()), {}, { includeException: true });\n },\n },\n attach(target) {\n file = target;\n const held = pending.splice(0);\n if (held.length === 0) return;\n writing = writing\n .then(() => fs.promises.appendFile(target, held.map((line) => `${line}\\n`).join(''), 'utf8'))\n .catch(reportLogFailure);\n },\n flushed: () => writing,\n };\n}\n\n/** A run this launcher started and has not seen end. */\ninterface ActiveRun {\n stopRequested?: boolean;\n target?: { workspace: string; runKey: string };\n registration?: WorkflowRunRegistration;\n settled: Promise<void>;\n}\n\n/**\n * Runs workflows inside the Po server for one session.\n *\n * It is the same launch the Pi extension runs, through the same executor:\n * the same Agiflow checks, capacity limit and runner check, and the same\n * answer once the run registers. What the server adds is where the run\n * happens, in this process with the host's step executor, and what it keeps:\n * each run's engine log, telemetry for its start and end, a notice when a run\n * fails after its launch already answered, and a stop for every run still\n * going when the session closes.\n */\nexport function createServerLauncher(dependencies: ServerLaunchDependencies): ServerLauncher {\n const { feature, telemetry } = dependencies;\n const active = new Map<string, ActiveRun>();\n let closing = false;\n const stopRun = async (run: ActiveRun): Promise<void> => {\n if (run.stopRequested) return;\n try {\n const record =\n run.registration ??\n (run.target\n ? await feature.registry.readRunByKey(run.target.workspace, RUNNING_STAGE, run.target.runKey)\n : undefined);\n if (\n !record ||\n !record.runId ||\n (run.target && 'env' in record && record.env?.[PI_SESSION_ENV] !== dependencies.sessionId)\n )\n return;\n await feature.registry.requestStop(record.workspace, record.runKey, SESSION_CLOSED_REASON, record.runId);\n run.stopRequested = true;\n } catch (error) {\n if (\n error instanceof Error &&\n (('code' in error && error.code === 'ENOENT') || error.message.startsWith('Workflow run not found: '))\n )\n return;\n await telemetry?.recordWarning(RUN_STOP_FAILED_EVENT, error);\n }\n };\n\n const runInProcess = async (input: WorkflowLaunchInput): Promise<CallToolResult> => {\n const launchId = input.env?.[WORKFLOW_LAUNCH_ID_ENV];\n if (launchId === undefined) throw new Error('An in-process launch needs its launch id.');\n const log = createRunLog(telemetry);\n const run: ActiveRun = { settled: Promise.resolve() };\n active.set(launchId, run);\n const runner = input.runner ?? input.cliAgent;\n const execution = (async (): Promise<CallToolResult> => {\n try {\n const result = await feature.createRunService({ logger: log.logger }).run({\n ...input,\n ...(runner === undefined ? {} : { runner }),\n // In this process the host's step executor reaches the run; a terminal launcher would not.\n skipLaunch: true,\n onRegistered: (registration) => {\n run.registration = registration;\n if (closing) void stopRun(run);\n log.attach(path.join(registration.runDir, RUN_LOG_FILENAME));\n void telemetry?.recordEvent(RUN_STARTED_EVENT, { outcome: 'started' });\n dependencies.onRunsChanged?.();\n },\n });\n if (SUCCESS_EXIT_CODES.has(result.exitCode)) {\n void telemetry?.recordEvent(RUN_FINISHED_EVENT, { outcome: 'success', exit_code: result.exitCode });\n return textResult(plain(result.output) || 'Workflow completed.');\n }\n const tail = plain(result.output).trim().split('\\n').slice(-FAILURE_TAIL_LINES).join('\\n');\n void telemetry?.recordError(\n RUN_FAILED_EVENT,\n new Error(tail || `The workflow exited with code ${String(result.exitCode)}.`),\n { exit_code: result.exitCode },\n { includeException: true },\n );\n // The engine's output is colored for a terminal; a notice or a tool result is not one.\n return textResult(`Workflow failed (exit code ${String(result.exitCode)}):\\n\\n${plain(result.output)}`, true);\n } catch (error) {\n void telemetry?.recordError(RUN_FAILED_EVENT, error, { outcome: 'error' }, { includeException: true });\n throw error;\n } finally {\n await log.flushed();\n active.delete(launchId);\n dependencies.onRunsChanged?.();\n }\n })();\n run.settled = execution.then(\n () => undefined,\n () => undefined,\n );\n return execution;\n };\n\n const executor = createWorkflowLaunchExecutor<WorkflowLaunchContext>({\n environment: dependencies.environment,\n activeRunCount: async () => active.size,\n ...(dependencies.rejectRunner === undefined ? {} : { rejectRunner: dependencies.rejectRunner }),\n runTool: { execute: runInProcess },\n // Every run is tracked in `active` by runInProcess itself.\n trackPendingRun: (pending) => pending,\n findLaunchedRun: async ({ launchId }): Promise<WorkflowRunRecord | undefined> => {\n const registration = active.get(launchId)?.registration;\n if (registration === undefined) return undefined;\n return feature.registry.readRunByKey(registration.workspace, RUNNING_STAGE, registration.runKey);\n },\n onLateFailure: (error) => {\n const detail = error instanceof Error ? error.message : String(error);\n void dependencies.notify(`Workflow launch failed after it was reported started.\\n${detail}`, 'warning');\n },\n onLaunch: () => {\n void telemetry?.recordEvent(LAUNCH_REQUESTED_EVENT, { outcome: 'requested' });\n dependencies.onRunsChanged?.();\n },\n ...(dependencies.launchAckPollMs === undefined ? {} : { launchAckPollMs: dependencies.launchAckPollMs }),\n ...(dependencies.launchAckTimeoutMs === undefined ? {} : { launchAckTimeoutMs: dependencies.launchAckTimeoutMs }),\n });\n const context: WorkflowLaunchContext = { sessionManager: { getSessionId: () => dependencies.sessionId } };\n\n return {\n launch: (input) => executor.execute(input, context),\n async recover(target, options) {\n if (closing) return textResult('The workflow session is closing.', true);\n const tool = dependencies.createRecoverTool({ ownerSessionId: () => dependencies.sessionId });\n // ponytail: recovery has no logger option in workflow-mcp; output reaches the result or late notice.\n if (options.dryRun) return tool.execute({ ...target, ...options });\n const key = `recover:${randomUUID()}`;\n const run: ActiveRun = { target, settled: Promise.resolve() };\n active.set(key, run);\n const execution = Promise.resolve()\n .then(() => tool.execute({ ...target, ...options }))\n .finally(() => {\n active.delete(key);\n dependencies.onRunsChanged?.();\n });\n run.settled = execution.then(\n () => undefined,\n () => undefined,\n );\n const find = async () => {\n const record = await feature.registry.readRunByKey(target.workspace, RUNNING_STAGE, target.runKey);\n return record?.env?.[PI_SESSION_ENV] === dependencies.sessionId ? record : undefined;\n };\n // Continue watching registration through shutdown, even after the acknowledgement deadline.\n void (async () => {\n while (active.has(key)) {\n if (closing) await stopRun(run);\n await Promise.race([run.settled, delay(dependencies.launchAckPollMs ?? 500)]);\n }\n })();\n const settled = foldOutcome(execution);\n const ack = await awaitRunAck(settled, find, dependencies.launchAckPollMs, dependencies.launchAckTimeoutMs);\n if (ack.kind === 'settled') {\n if (ack.outcome.kind === 'error')\n throw ack.outcome.error instanceof Error ? ack.outcome.error : new Error(String(ack.outcome.error));\n return ack.outcome.result;\n }\n if (ack.kind === 'record') {\n dependencies.onRunsChanged?.();\n }\n void settled.then((outcome) => {\n if (outcome.kind === 'error' || outcome.result.isError) {\n const detail = outcome.kind === 'error' ? String(outcome.error) : JSON.stringify(outcome.result.content);\n void dependencies.notify(`Workflow recovery failed after acknowledgement.\\n${detail}`, 'warning');\n }\n });\n return textResult(\n ack.kind === 'record'\n ? `Recovery started for ${ack.record.displayName} in workspace ${target.workspace}. Run key: ${target.runKey}. Started is not succeeded; check workflow_run status before reporting.`\n : 'Recovery requested, not running yet; nothing was cancelled; do not recover it again.',\n );\n },\n activeRunCount: () => active.size,\n async dispose() {\n closing = true;\n const runs = [...active.values()];\n if (runs.length === 0) return;\n await Promise.all(runs.map(stopRun));\n await Promise.race([\n Promise.all(runs.map((run) => run.settled)),\n delay(dependencies.stopTimeoutMs ?? STOP_TIMEOUT_MS),\n ]);\n },\n };\n}\n","/**\n * Workflow run view types shared by this package's hub channel and its web\n * plugin. The shapes mirror what the embedded workflow-mcp engine records;\n * the cockpit renders them as 'workflow_runs' channel payloads.\n */\n\n/** workflow-mcp's own stage vocabulary; the registry bucket a run record sits in. */\nexport type WorkflowStage = 'running' | 'completed' | 'error';\n\n/** workflow-mcp's terminal outcome for a finished run. */\nexport type WorkflowOutcome = 'success' | 'skipped' | 'failed' | 'interrupted';\n\n/** Recorded job/step states, plus pending entries from the workflow definition. */\nexport type WorkflowProgressState =\n | 'pending'\n | 'running'\n | 'completed'\n | 'skipped'\n | 'failed'\n | 'pause_requested'\n | 'paused'\n | 'resumed';\n\n/** A customRun step ran as this child session. */\nexport const STEP_SESSION_REF_KIND = 'session';\n/** A command step ran in this terminal pane. */\nexport const STEP_PANE_REF_KIND = 'pane';\n\n/** Where a host executor ran a step: `session` for a customRun agent, `pane` for a command. */\nexport interface WorkflowStepRefView {\n kind: string;\n id: string;\n label?: string;\n}\n\nexport interface WorkflowStepView {\n name: string;\n status: WorkflowProgressState;\n /** Kept after the step ends, so a finished agent step still opens its conversation. */\n ref?: WorkflowStepRefView;\n /** Why the step is in its state, when the engine recorded one (e.g. a skip condition). */\n reason?: string;\n /** The parallel group the step ran in, beside the group's other steps. */\n group?: string;\n /** ISO 8601 of the step's first running event. */\n startedAt?: string;\n /** ISO 8601 of the step's terminal event. */\n endedAt?: string;\n}\n\n/** 'pre' and 'post' are the engine's pseudo-jobs for its pre:/post: blocks. */\nexport type WorkflowJobPhase = 'pre' | 'job' | 'post';\n\nexport interface WorkflowJobView {\n name: string;\n phase: WorkflowJobPhase;\n status: WorkflowProgressState;\n reason?: string;\n /** Position among the run's jobs, when the engine recorded one. */\n index?: number;\n total?: number;\n startedAt?: string;\n endedAt?: string;\n steps: WorkflowStepView[];\n}\n\n/** The job and step a run is on right now; drives the NOW breadcrumb. */\nexport interface WorkflowPosition {\n job: string;\n step?: string;\n index?: number;\n total?: number;\n}\n\n/**\n * One workflow run of a session, read from workflow-mcp's registry: the\n * run.json record plus the folded progress.ndjson job tree.\n */\nexport interface WorkflowRunView {\n /** Engine generation identity, distinct from a reused run key. */\n runId?: string;\n /** Registry identity within its workspace; unique per workspace+stage. */\n runKey: string;\n workspace: string;\n displayName: string;\n workflowName?: string;\n workflowPath: string;\n stage: WorkflowStage;\n outcome?: WorkflowOutcome;\n /** Present while the engine is pausing or paused; absent for plain running. */\n executionState?: 'running' | 'pause_requested' | 'paused' | 'resume_requested';\n /** The prompt the run was launched with, when one was recorded. */\n prompt?: string;\n /** ISO 8601, from the run record. */\n startedAt: string;\n finishedAt?: string;\n /** Failure cause with ANSI escapes stripped, present when the run errored. */\n errorMessage?: string;\n /** The job the engine blamed for the failure, when it recorded one. */\n failedJob?: string;\n /** True when reconciliation decided the recorded pid is no longer alive. */\n stale?: boolean;\n staleReason?: string;\n worktreeBranch?: string;\n /** The session that owns the run (its PI_SESSION_ID); absent on records that carry none. */\n ownerSessionId?: string;\n /** The session that launched the run into its own workflow session, when it was handed off. */\n launcherSessionId?: string;\n position?: WorkflowPosition;\n jobs: WorkflowJobView[];\n}\n\n/** What the workflow runs channel publishes for one session. */\nexport interface WorkflowRunsPayload {\n runs: WorkflowRunView[];\n}\n\nexport const WORKFLOW_RUNS_TYPE = 'workflow_runs';\n\n/**\n * One workflow the session's directory can launch, as the catalog drawer\n * lists it: the engine's own catalog entry plus the parsed detail the drawer\n * unfolds and the launch dialog turns into fields.\n */\nexport interface WorkflowCatalogEntryView {\n /** Absolute path, the row's stable identity. */\n path: string;\n relativePath: string;\n name: string;\n description: string;\n tags: string[];\n /** The trigger names the file declares, such as workflow_dispatch. */\n triggers: string[];\n inputs: WorkflowCatalogInputView[];\n jobs: WorkflowCatalogJobView[];\n artifacts: WorkflowCatalogArtifactView[];\n /** Absent when the workflow names no runner map, which means any runner will do. */\n runners?: string[];\n /** Commands every templated step offers; absent when no step is templated. */\n commands?: string[];\n /** Declared model choices; `default` is used when a launch names none. */\n choices?: string[];\n /** Set when the file could not be parsed; the row shows this instead of guessing. */\n error?: string;\n}\n\nexport interface WorkflowCatalogInputView {\n name: string;\n description?: string;\n required?: boolean;\n default?: string;\n type?: string;\n options?: string[];\n}\n\nexport interface WorkflowCatalogJobView {\n name: string;\n steps: string[];\n}\n\nexport interface WorkflowCatalogArtifactView {\n path: string;\n kind: 'file' | 'directory';\n description: string;\n producedBy: string[];\n}\n\n/** What the catalog channel publishes for one session. */\nexport interface WorkflowCatalogPayload {\n /** The directory the catalog was read from, which is the session's own. */\n cwd: string;\n workflows: WorkflowCatalogEntryView[];\n /** Present when the directory could not be read at all. */\n warning?: string;\n}\n\nexport const WORKFLOW_CATALOG_TYPE = 'workflow_catalog';\n\nexport interface WorkflowInputSummary {\n name: string;\n description?: string;\n required?: boolean;\n default?: string;\n options?: readonly string[];\n}\n\nexport interface WorkflowJobSummary {\n name: string;\n steps: readonly string[];\n}\n\n/**\n * What the detail pane shows for one workflow. `runners` is undefined when the\n * workflow names no runner map at all, which is not the same as naming an empty\n * one - see `compatibleRunners`.\n */\nexport interface WorkflowCatalogDetail {\n triggers: readonly string[];\n inputs: readonly WorkflowInputSummary[];\n jobs: readonly WorkflowJobSummary[];\n runners?: readonly string[];\n /** Commands every templated step offers; absent when no step is templated. */\n commands?: readonly string[];\n /** Declared model choices. */\n choices?: readonly string[];\n /** Set when the file could not be parsed; the pane shows this instead of guessing. */\n error?: string;\n}\n","import fs from 'node:fs';\n\nimport { BACKGROUND_WORK_HOLDING_PROVIDERS, holdsSettledSession } from '@agimon-ai/po-core/backgroundWork';\nimport { type DoomHubSessionSelection, WORKFLOW_STEP_SESSION_PROVENANCE } from '@agimon-ai/po-core/hubChannel';\nimport {\n gateStepDecision,\n NativeTerminalService,\n readStepDecision,\n serveNativeTerminal,\n type StepExecution,\n type StepExecutionOutcome,\n type StepExecutor,\n terminalSocketPath,\n WORKFLOW_DECISION_FILE_ENV,\n WORKFLOW_DECISION_STEERING_ENV,\n WORKFLOW_DECISION_STEERING_HOST,\n} from '@agimon-ai/workflow-mcp';\n\nimport {\n PO_RUN_CONFIG_KEYS,\n type PoRunConfig,\n poRunConfigSchema,\n poTemplateRunConfigSchema,\n} from '../../schemas/runConfig';\nimport { STEP_PANE_REF_KIND, STEP_SESSION_REF_KIND } from '../../types/webWorkflows';\nimport type { StepExecutorDependencies, StepPaneLauncher, StepTelemetry } from './type';\n\nconst STEP_DISPLAY_ENV = 'WORKFLOW_STEP_DISPLAY';\nconst WORKFLOW_NAME_ENV = 'WORKFLOW_NAME';\n/** The engine's completion signal for terminal agents; a session this host steers never uses it. */\nconst WORKFLOW_STATUS_FILE_ENV = 'WORKFLOW_STATUS_FILE';\n/** How long a busy step session is left to finish a turn it was given elsewhere, such as web guidance. */\nconst BUSY_RETRY_MS = 2_000;\n/** How long ending a step's session may take before the step stops waiting for it. */\nconst RELEASE_TIMEOUT_MS = 10_000;\n/** What the runtime says when a turn is already running; the reminder then waits for it. */\nconst BUSY_SESSION_PATTERN = /\\bbusy\\b|LaneBusy/i;\n\nconst STEP_SESSION_STARTED_EVENT = 'doom_workflow.step_session_started';\nconst STEP_SESSION_FAILED_EVENT = 'doom_workflow.step_session_failed';\nconst STEP_REMINDER_EVENT = 'doom_workflow.step_reminder';\nconst STEP_WAITING_EVENT = 'doom_workflow.step_waiting';\nconst STEP_SESSION_RELEASE_FAILED_EVENT = 'doom_workflow.step_session_release_failed';\nconst STEP_PANE_FAILED_EVENT = 'doom_workflow.step_pane_failed';\n\n/** The command template a templated step runs through: its name, and the values it reads. */\nexport interface RunConfigTemplate {\n readonly name: string;\n readonly reads?: readonly string[];\n}\n\nconst PO_KEYS: ReadonlySet<string> = new Set(PO_RUN_CONFIG_KEYS);\n\n/**\n * A step's `runConfig`, validated against the keys Po understands.\n *\n * A templated step's may also carry keys its command template reads. A key\n * that is neither, such as `majormode`, fails the step rather than running it\n * on workspace defaults. An engine that does not say what its template reads\n * leaves such keys unchecked.\n */\nexport function readPoRunConfig(runConfig: unknown, template?: RunConfigTemplate): PoRunConfig {\n const parsed = (template === undefined ? poRunConfigSchema : poTemplateRunConfigSchema).safeParse(runConfig ?? {});\n if (!parsed.success) {\n const problems = parsed.error.issues.map((issue) => `${issue.path.join('.') || 'runConfig'}: ${issue.message}`);\n throw new Error(`Invalid runConfig: ${problems.join('; ')}`);\n }\n if (template?.reads !== undefined && typeof runConfig === 'object' && runConfig !== null) {\n const reads = new Set(template.reads);\n const unknown = Object.keys(runConfig).filter((key) => !PO_KEYS.has(key) && !reads.has(key));\n if (unknown.length > 0) {\n throw new Error(\n `Invalid runConfig: ${unknown.join(', ')} is neither a Po setting nor read by the \"${template.name}\" command.`,\n );\n }\n }\n return parsed.data;\n}\n\n/** The selection a step session is pinned to; unset keys keep the workspace defaults. */\nexport function sessionSelection(config: PoRunConfig): DoomHubSessionSelection {\n return {\n ...(config.majorMode === undefined ? {} : { majorMode: config.majorMode }),\n ...(config.minorModes === undefined ? {} : { minorModes: config.minorModes }),\n ...(config.profile === undefined ? {} : { profile: config.profile }),\n ...(config.domains === undefined ? {} : { domains: config.domains }),\n };\n}\n\n/**\n * What a step adds to the host environment.\n *\n * The step environment is the whole process environment plus the run's own\n * keys. Handing all of it to the session would pin a copy of the host's\n * variables into it; the difference is the part the agent actually needs, such\n * as WORKFLOW_RUN_DIR for the artifacts its prompt names.\n */\nexport function stepEnvironment(\n env: Readonly<Record<string, string>>,\n host: Readonly<Record<string, string | undefined>>,\n): Record<string, string> {\n return Object.fromEntries(Object.entries(env).filter(([key, value]) => host[key] !== value));\n}\n\nfunction stepSessionName(env: Readonly<Record<string, string>>, stepName: string): string {\n const display = env[STEP_DISPLAY_ENV] ?? stepName;\n const workflow = env[WORKFLOW_NAME_ENV];\n return workflow ? `${workflow}: ${display}` : display;\n}\n\nfunction asError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((settle) => {\n const timer = setTimeout(settle, ms);\n timer.unref?.();\n });\n}\n\n/** A promise settled by `settle`, so a stop can end a wait that nothing else would. */\nfunction signal(): { promise: Promise<void>; settle: () => void } {\n let settle: () => void = () => undefined;\n const promise = new Promise<void>((resolve) => {\n settle = resolve;\n });\n return { promise, settle };\n}\n\n/**\n * An execution that already failed, with why.\n *\n * Returned instead of throwing: the engine reports a thrown start as a spawn\n * error about shells and permissions, while a failed completion keeps this\n * message as the step's reason.\n */\nfunction failedExecution(error: unknown): StepExecution {\n return { completion: Promise.resolve({ error: asError(error) }), stop: async () => undefined };\n}\n\n/** What one step session runs: its settings, what it is asked, and the step it reports on. */\ninterface StepSessionRequest {\n readonly cwd: string;\n readonly env: Readonly<Record<string, string>>;\n readonly stepName: string;\n readonly runConfig: unknown;\n readonly prompt: string;\n readonly systemPrompt?: string;\n /** A templated step's command: its runConfig also feeds that command's template. */\n readonly template?: RunConfigTemplate;\n}\n\n/**\n * Runs workflow steps inside Po instead of a shell.\n *\n * A customRun step becomes a child session of the launching session, with the\n * step's major mode, minor modes, profile, domains and model, so its messages\n * stream like any other conversation. Command steps go to their own terminal\n * pane when a launcher is available and fall back to the engine's spawn when\n * it is not.\n */\nexport function createStepExecutor(dependencies: StepExecutorDependencies): StepExecutor {\n const { sessionService, launchPane, telemetry } = dependencies;\n const prompt = sessionService.prompt?.bind(sessionService);\n const readExecutionState = sessionService.readExecutionState?.bind(sessionService);\n\n /**\n * Run a step as a child session of the launching session, with the step's\n * major mode, minor modes, profile, domains and model.\n *\n * The session keeps going until the step has what the workflow needs: each\n * time the agent settles, the engine's decision gate is asked, and while\n * the step still lacks a decision (or its declared artifacts) the session is\n * prompted with the gate's reminder. The gate counts reminders against its\n * cap, so a stuck agent ends and the engine fails the step.\n */\n async function runSession(request: StepSessionRequest): Promise<StepExecution> {\n if (prompt === undefined) return failedExecution('This host cannot prompt sessions, so this step cannot run here.');\n if (readExecutionState === undefined)\n return failedExecution('This host cannot read execution state, so this step cannot run here.');\n const attributes = { 'workflow.step.name': request.stepName, templated: request.template !== undefined };\n let scope: Awaited<ReturnType<typeof sessionService.create>>;\n let name: string;\n try {\n const config = readPoRunConfig(request.runConfig, request.template);\n if (config.majorMode === undefined) throw new Error('Agent steps require an effective runConfig.majorMode.');\n name = stepSessionName(request.env, request.stepName);\n const environment = stepEnvironment(request.env, dependencies.hostEnvironment);\n // This host ends the step when the agent settles and steers it itself, so\n // hooks inside the session must neither end the step nor nudge the agent.\n delete environment[WORKFLOW_STATUS_FILE_ENV];\n environment[WORKFLOW_DECISION_STEERING_ENV] = WORKFLOW_DECISION_STEERING_HOST;\n scope = await sessionService.create({\n cwd: request.cwd,\n name,\n parentSessionId: dependencies.parentSessionId,\n // Keeps the session out of the rail: its conversation is read in the workflow's view.\n sessionProvenance: WORKFLOW_STEP_SESSION_PROVENANCE,\n selection: sessionSelection(config),\n ...(config.model === undefined ? {} : { model: config.model }),\n ...(config.thinking === undefined ? {} : { thinking: config.thinking }),\n ...(request.systemPrompt === undefined ? {} : { appendSystemPrompt: request.systemPrompt }),\n environment,\n });\n } catch (error) {\n void telemetry?.recordError(STEP_SESSION_FAILED_EVENT, error, attributes, { includeException: true });\n return failedExecution(error);\n }\n void telemetry?.recordEvent(STEP_SESSION_STARTED_EVENT, { ...attributes, outcome: 'started' });\n const sessionId = scope.sessionId;\n const stopped = signal();\n let stopRequested = false;\n const decided = (): boolean => {\n const path = request.env[WORKFLOW_DECISION_FILE_ENV];\n return path !== undefined && readStepDecision(path) !== undefined;\n };\n\n /**\n * Give the agent the gate's reminder. A session busy with a turn it was\n * given elsewhere, like web guidance, is left to finish it, then reminded\n * unless it decided meanwhile. Undefined means the step needs no more turns.\n */\n const remind = async (message: string): Promise<{ settled: Promise<void> } | undefined> => {\n for (;;) {\n try {\n return await prompt(sessionId, message);\n } catch (error) {\n if (!BUSY_SESSION_PATTERN.test(asError(error).message)) throw error;\n void telemetry?.recordEvent(STEP_REMINDER_EVENT, { ...attributes, outcome: 'busy' });\n await Promise.race([delay(dependencies.busyRetryMs ?? BUSY_RETRY_MS), stopped.promise]);\n if (stopRequested || decided()) return undefined;\n }\n }\n };\n\n /**\n * End the session once the step is over. Released, it stays readable in the\n * workflow's view without holding a model, tools and extensions in the host.\n * A host that cannot release it is asked to abort a stopped turn instead.\n */\n const endSession = async (): Promise<void> => {\n const ending = sessionService.release\n ? sessionService.release(sessionId)\n : stopRequested\n ? (sessionService.abort?.(sessionId) ?? Promise.resolve())\n : Promise.resolve();\n const timeout = delay(dependencies.releaseTimeoutMs ?? RELEASE_TIMEOUT_MS).then(() => {\n throw new Error(\n `The step session did not end within ${String(dependencies.releaseTimeoutMs ?? RELEASE_TIMEOUT_MS)}ms.`,\n );\n });\n try {\n await Promise.race([ending, timeout]);\n } catch (error) {\n // The step's outcome is already decided; a session left running is reported, not fatal.\n void telemetry?.recordWarning(STEP_SESSION_RELEASE_FAILED_EVENT, error, attributes);\n }\n };\n\n const completion = async (): Promise<StepExecutionOutcome> => {\n let receipt: { settled: Promise<void> } | undefined = await prompt(sessionId, request.prompt);\n while (receipt !== undefined) {\n // A stop ends the wait even when the turn itself never settles.\n await Promise.race([receipt.settled, stopped.promise]);\n if (stopRequested) return { exitCode: 0 };\n let waiting = false;\n for (;;) {\n const state = await Promise.race([\n readExecutionState(sessionId, { parentSessionId: dependencies.parentSessionId }),\n stopped.promise.then(() => undefined),\n ]);\n if (stopRequested) return { exitCode: 0 };\n const snapshot = state?.backgroundWork;\n const items = snapshot?.items.filter(holdsSettledSession) ?? [];\n const errors =\n snapshot?.errors.filter((error) => BACKGROUND_WORK_HOLDING_PROVIDERS.includes(error.provider)) ?? [];\n if (\n state?.isIdle &&\n !state.hasPendingMessages &&\n snapshot !== undefined &&\n items.length === 0 &&\n errors.length === 0\n )\n break;\n if (!waiting) {\n waiting = true;\n void telemetry?.recordEvent(STEP_WAITING_EVENT, {\n ...attributes,\n items: items.map((item) => `${item.provider}:${item.id}`).join(', '),\n errors: errors.map((error) => `${error.provider}: ${error.message}`).join(', '),\n coordinator: snapshot === undefined ? 'missing' : 'available',\n });\n }\n await Promise.race([delay(dependencies.busyRetryMs ?? BUSY_RETRY_MS), stopped.promise]);\n if (stopRequested) return { exitCode: 0 };\n }\n const gate = await gateStepDecision(request.env);\n if (gate.action === 'allow') return { exitCode: 0 };\n void telemetry?.recordEvent(STEP_REMINDER_EVENT, { ...attributes, outcome: 'sent' });\n receipt = await remind(gate.message);\n }\n return { exitCode: 0 };\n };\n return {\n ref: { kind: STEP_SESSION_REF_KIND, id: sessionId, label: name },\n completion: completion()\n .catch((error: unknown): StepExecutionOutcome => ({ error: asError(error) }))\n .then(async (outcome) => {\n await endSession();\n return outcome;\n }),\n stop: async () => {\n stopRequested = true;\n stopped.settle();\n },\n };\n }\n\n return {\n async custom(request) {\n return runSession({\n cwd: request.cwd,\n env: request.env,\n stepName: request.stepName,\n runConfig: request.runConfig,\n prompt: request.customRun.prompt,\n ...(request.customRun.systemPrompt === undefined ? {} : { systemPrompt: request.customRun.systemPrompt }),\n });\n },\n async command(request) {\n // A templated command that allows it runs in-process from its values;\n // its rendered shell command is only the fallback for other hosts.\n const template = request.template;\n if (template?.inProcess && prompt !== undefined) {\n return runSession({\n cwd: request.cwd,\n env: request.env,\n stepName: request.stepName,\n runConfig: request.runConfig,\n template: { name: template.name, ...(template.reads === undefined ? {} : { reads: template.reads }) },\n prompt: template.prompt,\n ...(template.systemPrompt === undefined ? {} : { systemPrompt: template.systemPrompt }),\n });\n }\n if (launchPane === undefined) return undefined;\n let pane: Awaited<ReturnType<StepPaneLauncher>>;\n try {\n pane = await launchPane({\n id: dependencies.createId(),\n command: request.command,\n cwd: request.cwd,\n env: request.env,\n });\n } catch (error) {\n void telemetry?.recordError(\n STEP_PANE_FAILED_EVENT,\n error,\n { 'workflow.step.name': request.stepName },\n {\n includeException: true,\n },\n );\n return failedExecution(error);\n }\n if (pane === undefined) return undefined;\n return {\n ref: { kind: STEP_PANE_REF_KIND, id: pane.target, label: request.stepName },\n completion: pane.completion.then(\n (result): StepExecutionOutcome => result,\n (error: unknown): StepExecutionOutcome => ({ error: asError(error) }),\n ),\n stop: async () => {\n await pane.stop();\n },\n };\n },\n };\n}\n\n/** The shell a command step runs in, the same one the engine spawns it with. */\nconst STEP_SHELL = '/bin/zsh';\n/** Namespace for step pane sockets, apart from whole-run terminal sockets. */\nconst STEP_PANE_SOCKET_SCOPE = 'po-workflow-steps';\nconst PANE_LOG_SUFFIX = '.log';\nconst PANE_CAPTURE_COLUMNS = 120;\nconst PANE_CAPTURE_ROWS = 40;\n\n/** Where a finished step pane's last screen is kept: beside the socket that served it. */\nexport function stepPaneLogPath(socketPath: string): string {\n return `${socketPath}${PANE_LOG_SUFFIX}`;\n}\n\n/** The pane's current screen, or undefined once there is no pane left to read. */\nasync function lastScreen(service: NativeTerminalService, key: string): Promise<string | undefined> {\n try {\n const viewer = await service.attach(key, PANE_CAPTURE_COLUMNS, PANE_CAPTURE_ROWS);\n const lines = await viewer.snapshot();\n viewer.detach();\n return `${lines.join('\\n')}\\n`;\n } catch {\n // Nothing is left to read; the step's outcome does not depend on its last screen.\n return undefined;\n }\n}\n\n/**\n * Opens each command step in its own RMUX pane, through workflow-mcp's terminal host.\n *\n * The pane gets the step's whole environment, which is what lets an agent's\n * Stop hook end an interactive step through WORKFLOW_STATUS_FILE. A unix\n * socket serves the pane to the run terminal in any scope; the socket path is\n * the pane's target. When the step ends or is stopped, its last screen is kept\n * beside the socket and the pane is released, whatever fails on the way.\n */\nexport function createNativeStepPaneLauncher(\n service = new NativeTerminalService(),\n telemetry?: StepTelemetry,\n): StepPaneLauncher {\n const report = (stage: string) => (error: unknown) =>\n telemetry?.recordWarning(STEP_PANE_FAILED_EVENT, error, { stage }) ?? Promise.resolve();\n return async (request) => {\n if (!(await service.available())) return undefined;\n await service.spawn({\n command: STEP_SHELL,\n args: ['-c', request.command],\n cwd: request.cwd,\n env: { ...request.env },\n runKey: request.id,\n });\n const target = terminalSocketPath(STEP_PANE_SOCKET_SCOPE, request.id);\n let server: Awaited<ReturnType<typeof serveNativeTerminal>>;\n try {\n server = await serveNativeTerminal({ service, runKey: request.id, socketPath: target });\n } catch (error) {\n // A pane nobody can reach must not keep running its command untracked.\n await service.kill(request.id).catch(report('kill'));\n throw error;\n }\n let finishing: Promise<string | undefined> | undefined;\n const finish = (): Promise<string | undefined> =>\n (finishing ??= (async () => {\n let screen: string | undefined;\n try {\n screen = await lastScreen(service, request.id);\n if (screen !== undefined) await fs.promises.writeFile(stepPaneLogPath(target), screen, 'utf8');\n } catch (error) {\n // Keeping the last screen is a courtesy; the step's outcome is its exit code.\n await report('keep-screen')(error);\n } finally {\n await server.close().catch(report('close-socket'));\n await service.kill(request.id).catch(report('kill'));\n }\n return screen;\n })());\n return {\n target,\n // The last screen is the step's output tail, the reason a failing restart-from check reports.\n completion: service.ended(request.id).then(async (exitCode) => {\n const screen = (await finish())?.trimEnd();\n return screen ? { exitCode, outputTail: screen } : { exitCode };\n }),\n stop: async () => {\n await finish();\n return true;\n },\n };\n };\n}\n","import type {\n WorkflowCatalogArtifactView,\n WorkflowCatalogEntryView,\n WorkflowCatalogInputView,\n WorkflowCatalogJobView,\n} from '../../types/webWorkflows';\n/**\n * The cockpit's view of the workflows a session can launch.\n *\n * The engine already reads a repository's workflow files and parses one of\n * them into triggers, inputs, jobs, artifacts and compatible runners, so this\n * module only shapes that answer for the wire and remembers what it read.\n *\n * WHY A CACHE:\n * A session reads the catalog for its initial projection and when its lifecycle\n * publishes a workflow update. Entries are kept per path and reused while the\n * file's size and modification time are unchanged, which is the same test a\n * build tool makes and costs one stat per file.\n */\n\n/** What the engine reports for one workflow file before it is parsed. */\nexport interface CatalogListEntry {\n path: string;\n relativePath: string;\n name: string;\n description: string;\n tags: string[];\n}\n\n/** One file's parsed detail, or the reason it could not be read. */\nexport interface CatalogDetail {\n triggers: string[];\n inputs: WorkflowCatalogInputView[];\n jobs: WorkflowCatalogJobView[];\n artifacts: WorkflowCatalogArtifactView[];\n runners?: string[];\n commands?: string[];\n choices?: string[];\n error?: string;\n}\n\n/** What a file looked like when it was last parsed. */\nexport interface CatalogFileStamp {\n size: number;\n modifiedAt: number;\n}\n\nexport interface WorkflowCatalogReaderDeps {\n /** Every workflow file under a directory. */\n list(directory: string): Promise<CatalogListEntry[]>;\n /** One file's parsed detail; never throws, so a bad file cannot empty a board. */\n summarize(path: string): CatalogDetail;\n /** Size and modification time, or undefined when the file is gone. */\n stamp(path: string): CatalogFileStamp | undefined;\n}\n\ninterface CachedEntry {\n stamp: CatalogFileStamp;\n detail: CatalogDetail;\n}\n\n/** Reads one directory's catalog, reusing what it parsed last time. */\nexport interface WorkflowCatalogReader {\n read(directory: string): Promise<WorkflowCatalogEntryView[]>;\n /** Drops what was parsed for files no longer listed, so a cache cannot grow forever. */\n forget(keep: ReadonlySet<string>): void;\n}\n\nfunction unchanged(left: CatalogFileStamp | undefined, right: CatalogFileStamp | undefined): boolean {\n return left !== undefined && right !== undefined && left.size === right.size && left.modifiedAt === right.modifiedAt;\n}\n\nexport function createWorkflowCatalogReader(deps: WorkflowCatalogReaderDeps): WorkflowCatalogReader {\n const cache = new Map<string, CachedEntry>();\n\n const detailFor = (path: string): CatalogDetail => {\n const stamp = deps.stamp(path);\n const cached = cache.get(path);\n if (cached && unchanged(cached.stamp, stamp)) return cached.detail;\n const detail = deps.summarize(path);\n // A file that vanished between listing and stat is parsed anyway, which\n // answers with its own error; it just cannot be cached against a stamp.\n if (stamp !== undefined) cache.set(path, { stamp, detail });\n return detail;\n };\n\n return {\n async read(directory) {\n const listed = await deps.list(directory);\n return listed.map((entry) => {\n const detail = detailFor(entry.path);\n return {\n path: entry.path,\n relativePath: entry.relativePath,\n name: entry.name === '' ? entry.relativePath : entry.name,\n description: entry.description,\n tags: entry.tags,\n triggers: detail.triggers,\n inputs: detail.inputs,\n jobs: detail.jobs,\n artifacts: detail.artifacts,\n ...(detail.runners === undefined ? {} : { runners: detail.runners }),\n ...(detail.commands === undefined ? {} : { commands: detail.commands }),\n ...(detail.choices === undefined ? {} : { choices: detail.choices }),\n ...(detail.error === undefined ? {} : { error: detail.error }),\n };\n });\n },\n forget(keep) {\n for (const path of cache.keys()) {\n if (!keep.has(path)) cache.delete(path);\n }\n },\n };\n}\n\n/** The launchable rows first, then the ones that would not parse, name ordered. */\nexport function presentWorkflowCatalog(entries: readonly WorkflowCatalogEntryView[]): WorkflowCatalogEntryView[] {\n return [...entries].sort((left, right) => {\n if ((left.error === undefined) !== (right.error === undefined)) return left.error === undefined ? -1 : 1;\n return left.name.localeCompare(right.name);\n });\n}\n","import { statSync } from 'node:fs';\n\nimport { diagnoseWorkflow, readWorkflowCatalog, summarizeWorkflow } from '@agimon-ai/workflow-mcp';\n\nimport { PO_RUN_CONFIG_KEYS } from '../../schemas/runConfig';\nimport type { WorkflowCatalogReaderDeps } from '../webWorkflowCatalog';\n\n/**\n * Connect the pure catalog projection service to the workflow engine and filesystem.\n *\n * A workflow that parses can still be one Po would fail mid-run, such as\n * a step whose runConfig misspells `majorMode`. The engine's doctor, told the\n * keys Po reads, finds those; its errors mark the workflow as one that\n * cannot launch, in the catalog and at every launch, rather than at the step.\n */\nexport function defaultCatalogDeps(): WorkflowCatalogReaderDeps {\n return {\n list: (directory) => readWorkflowCatalog(directory),\n summarize: (workflowPath) => {\n const detail = summarizeWorkflow(workflowPath);\n if (detail.error !== undefined) return detail;\n const errors = diagnoseWorkflow(workflowPath, { runConfigKeys: PO_RUN_CONFIG_KEYS }).diagnostics.filter(\n (diagnostic) => diagnostic.level === 'error',\n );\n if (errors.length === 0) return detail;\n return {\n ...detail,\n error: errors\n .map((diagnostic) =>\n diagnostic.location === undefined ? diagnostic.message : `${diagnostic.location}: ${diagnostic.message}`,\n )\n .join('\\n'),\n };\n },\n stamp: (workflowPath) => {\n try {\n const stats = statSync(workflowPath);\n return { size: stats.size, modifiedAt: stats.mtimeMs };\n } catch {\n return undefined;\n }\n },\n };\n}\n","import { readChildProcessContext, SUBAGENT_PARENT_SESSION_ENV } from '@agimon-ai/po-core/childProcess';\n\nconst DISPATCHER_AGENT_NAME = 'agiflow-dispatcher';\n\nexport function resolveDispatcherParentSession(\n environment: Readonly<Record<string, string | undefined>>,\n): string | undefined {\n const childContext = readChildProcessContext(environment);\n return childContext?.parentSessionId ?? (environment[SUBAGENT_PARENT_SESSION_ENV]?.trim() || undefined);\n}\n\nexport function isWorkflowDispatcherProcess(environment: Readonly<Record<string, string | undefined>>): boolean {\n const childContext = readChildProcessContext(environment);\n if (childContext?.mode === DISPATCHER_AGENT_NAME) return true;\n return (\n environment.PI_SUBAGENT_CHILD_AGENT === DISPATCHER_AGENT_NAME &&\n Boolean(environment[SUBAGENT_PARENT_SESSION_ENV]?.trim())\n );\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { connectNativeTerminal, type WorkflowRegistryService, type WorkflowRunRecord } from '@agimon-ai/workflow-mcp';\n\nimport { STEP_PANE_REF_KIND, STEP_SESSION_REF_KIND } from '../../types/webWorkflows';\nimport type { WorkflowTerminalCapabilitiesView } from '../../types/webWorkflowTerminal';\nimport { stepPaneLogPath } from '../stepExecutor';\nimport { parseWorkflowProgress } from '../workflowRuns';\nimport type { TerminalPort } from '../workflowTerminal';\nimport type { RunStepRefs, RunTerminalTarget, StepPaneTerminalDependencies, StepRef } from './type';\n\nconst PROGRESS_FILENAME = 'progress.ndjson';\nconst NATIVE_LAUNCHER = 'native';\n/** Runs whose folded refs are kept between reads; a screen stream reads its run twice a second. */\nconst REFS_CACHE_LIMIT = 256;\nconst PANE_CAPABILITIES: WorkflowTerminalCapabilitiesView = { readable: true, writable: true, resizable: false };\nconst PANE_LOG_CAPABILITIES: WorkflowTerminalCapabilitiesView = {\n readable: true,\n writable: false,\n resizable: false,\n reason: 'That step has finished; this is the output it left.',\n};\nconst SESSION_STEP_REASON =\n 'This step runs as an agent session; its conversation appears here as soon as the session starts.';\nconst PANE_GONE_LINE = 'The step pane has closed.';\n\n/** The step events this fold reads, as the shared progress parser returns them. */\ninterface StepProgressEvent {\n readonly type: string;\n readonly status: string;\n readonly job: string;\n readonly step?: string;\n readonly index?: number;\n readonly ref?: StepRef;\n}\n\n/**\n * The steps a run is on and its latest pane, folded from its progress log.\n *\n * Later events win, as in the engine's own summary. Steps of a parallel group\n * run at once, so every running step is kept, and the current one is the\n * latest-started step still running. A step that starts again is a new\n * attempt: its previous session or pane is not this attempt's, so the ref is\n * dropped until the new one is recorded. The latest pane is kept after it\n * finishes so a run between steps, or one that has ended, can still show what\n * its last command printed.\n */\nexport function stepRefsFrom(events: readonly StepProgressEvent[]): RunStepRefs {\n // Insertion order is start order: a step that starts again moves to the end.\n const steps = new Map<string, { running: boolean; ref?: StepRef }>();\n const known = new Map<string, StepRef>();\n let lastPane: StepRef | undefined;\n for (const event of events) {\n if (event.type !== 'step' || event.step === undefined) continue;\n const key = `${event.job}\\u0000${event.step}`;\n const previous = steps.get(key);\n const running = event.status === 'running';\n // Indexed starts also replace attempts interrupted while still running.\n const restarted = running && (event.index !== undefined || previous?.running !== true);\n if (restarted) steps.delete(key);\n const ref = event.ref ?? (restarted ? undefined : previous?.ref);\n steps.set(key, { running, ...(ref === undefined ? {} : { ref }) });\n if (event.ref !== undefined) known.set(event.ref.id, event.ref);\n if (event.ref?.kind === STEP_PANE_REF_KIND) lastPane = event.ref;\n }\n const running = [...steps.values()]\n .filter((step) => step.running && step.ref !== undefined)\n .map((step) => step.ref as StepRef);\n const current = running.at(-1);\n return {\n ...(current === undefined ? {} : { current }),\n ...(running.length === 0 ? {} : { running }),\n ...(lastPane === undefined ? {} : { lastPane }),\n ...(known.size === 0 ? {} : { known: [...known.values()] }),\n };\n}\n\n/**\n * Reads a run's refs, folding its progress log again only when the log changed.\n *\n * Every screen, keystroke and capability check asks for them, and the log grows\n * with every fix loop, so an unchanged file (same size and modification time)\n * answers from the last fold.\n */\nfunction createStepRefsReader(): (file: string) => RunStepRefs {\n const cache = new Map<string, { size: number; mtimeMs: number; refs: RunStepRefs }>();\n return (file) => {\n let stats: fs.Stats;\n try {\n stats = fs.statSync(file);\n } catch {\n // No log yet: a run records progress only once its first step starts.\n return {};\n }\n const cached = cache.get(file);\n if (cached !== undefined && cached.size === stats.size && cached.mtimeMs === stats.mtimeMs) return cached.refs;\n let raw: string;\n try {\n raw = fs.readFileSync(file, 'utf8');\n } catch {\n // Removed between the stat and the read, as a deleted run is; nothing is left to follow.\n return {};\n }\n const refs = stepRefsFrom(parseWorkflowProgress(raw));\n cache.delete(file);\n cache.set(file, { size: stats.size, mtimeMs: stats.mtimeMs, refs });\n if (cache.size > REFS_CACHE_LIMIT) cache.delete(cache.keys().next().value as string);\n return refs;\n };\n}\n\n/**\n * Real dependencies: the registry's run directory, and the step executor's pane sockets.\n *\n * A pane is reached through the socket its step was served on, so any scope\n * of the server can read it, and a finished one through the screen kept\n * beside that socket.\n */\nexport function createStepPaneTerminalDependencies(registry: WorkflowRegistryService): StepPaneTerminalDependencies {\n const native = connectNativeTerminal();\n const readRefs = createStepRefsReader();\n return {\n stepRefs: (record) => readRefs(path.join(registry.runDirectoryFor(record), PROGRESS_FILENAME)),\n paneClient: () => ({\n capture: (target) =>\n native.snapshot(target, {}).then(\n (lines) => lines.join('\\n'),\n // A pane that already closed has no screen; its kept log answers instead.\n () => undefined,\n ),\n input: (target, text) =>\n native.write(target, text).then(\n () => true,\n () => false,\n ),\n }),\n paneLog: (_record, pane) =>\n fs.promises.readFile(stepPaneLogPath(pane.id), 'utf8').catch(\n // Kept screens live in the temp directory, which the system may already have cleared.\n () => undefined,\n ),\n };\n}\n\n/** Removes the screens a run's finished panes left behind, once the run itself is deleted. */\nexport async function removeStepPaneLogs(refs: RunStepRefs): Promise<void> {\n const panes = (refs.known ?? []).filter((ref) => ref.kind === STEP_PANE_REF_KIND);\n await Promise.all(panes.map((pane) => fs.promises.rm(stepPaneLogPath(pane.id), { force: true })));\n}\n\nfunction lastLines(text: string, count: number | undefined): string[] {\n const lines = text.replace(/\\n+$/, '').split('\\n');\n return count === undefined ? lines : lines.slice(-count);\n}\n\n/** The ref a request reads, and whether its step is still running. */\ninterface ResolvedStep {\n readonly ref: StepRef;\n readonly running: boolean;\n}\n\n/**\n * A run terminal that follows the step a host executor placed.\n *\n * A run executing in the server has no launcher pane of its own; each command\n * step gets one instead. A request naming a step reads that step's pane, which\n * is how each step of a parallel group gets its own screen and keyboard.\n * Without one it follows the current step. While a customRun step runs, there\n * is no terminal to show, so it says where the agent's messages are. Between\n * steps and after the run, an in-process run shows what its latest command\n * printed. A run delegated to a terminal launcher keeps the engine's facade.\n */\nexport function createStepPaneTerminal(\n facade: TerminalPort<WorkflowRunRecord>,\n dependencies: StepPaneTerminalDependencies,\n): TerminalPort<RunTerminalTarget> {\n // A server run records the server itself as its native launcher and has no terminal socket.\n const inProcess = (record: WorkflowRunRecord): boolean =>\n record.launcher?.type === NATIVE_LAUNCHER && record.terminalSocket === undefined;\n const resolveStep = (target: RunTerminalTarget): ResolvedStep | undefined => {\n const refs = dependencies.stepRefs(target.record);\n const isRunning = (ref: StepRef): boolean => refs.running?.some((candidate) => candidate.id === ref.id) === true;\n if (target.step !== undefined) {\n const named = refs.known?.find((ref) => ref.id === target.step);\n if (named !== undefined) return { ref: named, running: isRunning(named) };\n }\n if (refs.current !== undefined) return { ref: refs.current, running: true };\n if (refs.lastPane !== undefined && inProcess(target.record)) return { ref: refs.lastPane, running: false };\n return undefined;\n };\n const readLog = async (record: WorkflowRunRecord, pane: StepRef, lines: number | undefined): Promise<string[]> => {\n const log = await dependencies.paneLog(record, pane);\n return log === undefined ? [PANE_GONE_LINE] : lastLines(log, lines);\n };\n\n return {\n capabilities(target) {\n const step = resolveStep(target);\n if (step === undefined) return facade.capabilities(target.record);\n if (step.ref.kind === STEP_SESSION_REF_KIND) {\n return { readable: false, writable: false, resizable: false, reason: SESSION_STEP_REASON };\n }\n return step.running ? PANE_CAPABILITIES : PANE_LOG_CAPABILITIES;\n },\n async screen(target, options) {\n const step = resolveStep(target);\n if (step === undefined) return facade.screen(target.record, options);\n if (step.ref.kind === STEP_SESSION_REF_KIND) return [SESSION_STEP_REASON];\n if (step.running) {\n const screen = await dependencies.paneClient(target.record).capture(step.ref.id);\n if (screen !== undefined) return lastLines(screen, options.lines);\n // The pane closed between the progress read and the capture; its log has the same text.\n }\n return readLog(target.record, step.ref, options.lines);\n },\n async write(target, data) {\n const step = resolveStep(target);\n if (step === undefined) return facade.write(target.record, data);\n if (step.ref.kind !== STEP_PANE_REF_KIND || !step.running) throw new Error(PANE_GONE_LINE);\n if (!(await dependencies.paneClient(target.record).input(step.ref.id, data))) throw new Error(PANE_GONE_LINE);\n },\n async resize(target, columns, rows) {\n if (resolveStep(target) !== undefined) return false;\n return facade.resize(target.record, columns, rows);\n },\n };\n}\n","import type { WorkflowTerminalCapabilitiesView } from '../../types/webWorkflowTerminal';\n\n/**\n * One run's terminal, shared by every surface watching it.\n *\n * WHY COALESCING LIVES HERE:\n * Reading a multiplexer's screen forks a CLI, measured at roughly 75ms a call.\n * Several readers on one run (a step tab, a second browser, the session's own\n * panel) would otherwise each fork on their own timer, and a read that runs\n * long would have the next one start on top of it, unbounded. One read per run\n * at a time, no faster than the interval, however many surfaces are watching.\n *\n * WHY A CONTROL LEASE:\n * A run's terminal takes keystrokes from anyone who can reach it, so two\n * readers typing into one nested agent is a real state, not a hypothetical.\n * The lease does not make it impossible, since the session's own panel can\n * still type; it makes it visible, and keeps two cockpit tabs from fighting.\n */\n\n/** The engine's terminal facade, as this service needs it. */\nexport interface TerminalPort<Record> {\n capabilities(record: Record): WorkflowTerminalCapabilitiesView;\n screen(record: Record, options: { lines?: number }): Promise<string[]>;\n write(record: Record, data: string): Promise<void>;\n resize(record: Record, columns: number, rows: number): Promise<boolean>;\n}\n\nexport interface WorkflowTerminalDeps<Record> {\n terminal: TerminalPort<Record>;\n /** Injected so the cadence and the lease clock are assertable. */\n now: () => number;\n /** Shortest gap between two reads of one run. */\n refreshMs?: number;\n /** How long a keyboard lease survives without being renewed. */\n leaseMs?: number;\n}\n\n/** A read in flight, and what the last one returned. */\ninterface ScreenEntry {\n /**\n * When the last read finished, absent until one has.\n *\n * Absent rather than zero: zero is a real instant, and a service whose clock\n * starts near it would answer the very first read from an empty cache and\n * paint nothing until the interval had passed.\n */\n at?: number;\n lines: string[];\n inFlight?: Promise<string[]>;\n}\n\ninterface Lease {\n token: string;\n expiresAt: number;\n}\n\nconst DEFAULT_REFRESH_MS = 750;\nconst DEFAULT_LEASE_MS = 60_000;\nconst NOT_HELD = 'Another reader holds the keyboard for this run.';\n\nexport interface WorkflowTerminalService<Record> {\n /** The run's recent screen, reusing a recent read rather than forking again. */\n screen(identity: string, record: Record, lines: number): Promise<string[]>;\n capabilities(record: Record): WorkflowTerminalCapabilitiesView;\n /** Takes the keyboard, or reports who has it. Renews when the holder asks again. */\n takeControl(identity: string, token: string): boolean;\n releaseControl(identity: string, token: string): void;\n /** Writes on behalf of a lease holder; throws when the lease is not theirs. */\n write(identity: string, record: Record, token: string, data: string): Promise<void>;\n /**\n * Matches the run's terminal to the holder's viewport.\n *\n * Behind the same lease as writing: geometry is shared by everyone watching,\n * so a passive reader must not reflow the screen under the person typing.\n */\n resize(identity: string, record: Record, token: string, columns: number, rows: number): Promise<boolean>;\n /** Drops what is remembered for runs that can never change again. */\n forget(live: ReadonlySet<string>): void;\n /**\n * Drops what is remembered for one run that has settled.\n *\n * A surface that only knows its own run uses this rather than `forget`, which\n * would also clear every other run's screen and keyboard lease.\n */\n forgetRun(identity: string): void;\n}\n\nexport function createWorkflowTerminalService<Record>(\n deps: WorkflowTerminalDeps<Record>,\n): WorkflowTerminalService<Record> {\n const refreshMs = deps.refreshMs ?? DEFAULT_REFRESH_MS;\n const leaseMs = deps.leaseMs ?? DEFAULT_LEASE_MS;\n const screens = new Map<string, ScreenEntry>();\n const leases = new Map<string, Lease>();\n\n const heldBy = (identity: string): Lease | undefined => {\n const lease = leases.get(identity);\n if (lease === undefined) return undefined;\n if (lease.expiresAt > deps.now()) return lease;\n leases.delete(identity);\n return undefined;\n };\n\n return {\n async screen(identity, record, lines) {\n const entry = screens.get(identity) ?? { lines: [] };\n screens.set(identity, entry);\n if (entry.inFlight) return entry.lines;\n if (entry.at !== undefined && deps.now() - entry.at < refreshMs) return entry.lines;\n entry.inFlight = deps.terminal.screen(record, { lines });\n try {\n entry.lines = await entry.inFlight;\n } finally {\n // Stamped after the read, not before: the interval is a gap between\n // reads, so a slow scrape must not immediately earn another one.\n entry.at = deps.now();\n entry.inFlight = undefined;\n }\n return entry.lines;\n },\n capabilities(record) {\n return deps.terminal.capabilities(record);\n },\n takeControl(identity, token) {\n const holder = heldBy(identity);\n if (holder !== undefined && holder.token !== token) return false;\n leases.set(identity, { token, expiresAt: deps.now() + leaseMs });\n return true;\n },\n releaseControl(identity, token) {\n if (heldBy(identity)?.token === token) leases.delete(identity);\n },\n async write(identity, record, token, data) {\n const holder = heldBy(identity);\n if (holder === undefined || holder.token !== token) throw new Error(NOT_HELD);\n leases.set(identity, { token, expiresAt: deps.now() + leaseMs });\n await deps.terminal.write(record, data);\n },\n async resize(identity, record, token, columns, rows) {\n const holder = heldBy(identity);\n if (holder === undefined || holder.token !== token) throw new Error(NOT_HELD);\n return deps.terminal.resize(record, columns, rows);\n },\n forget(live) {\n for (const identity of screens.keys()) {\n if (!live.has(identity)) screens.delete(identity);\n }\n for (const identity of leases.keys()) {\n if (!live.has(identity)) leases.delete(identity);\n }\n },\n forgetRun(identity) {\n screens.delete(identity);\n leases.delete(identity);\n },\n };\n}\n","import { apiResponse, defineApiRoutes } from '@agimon-ai/po-core/web';\n\nimport type {\n WorkflowArtifactContentResponse,\n WorkflowArtifactsResponse,\n WorkflowControlResponse,\n WorkflowDeleteResponse,\n WorkflowLaunchResponse,\n WorkflowOpenRunDirectoryResponse,\n WorkflowSteerResponse,\n WorkflowStopResponse,\n} from './webWorkflowTerminal';\n\n/**\n * This package's routes, as data.\n *\n * No scope and no base path. The build reads both off\n * `src/extensions/(backend)/api/workflow/`, so the mount is stated once, by the\n * folder that creates it. The same API answers at all three scopes, because a\n * global contribution cascades into workspace and session; the folder under\n * `workspaces/sessions/` only re-mounts it for a session's own server.\n *\n * This is the one file the routes, the Hono app and the browser all read, so a\n * path cannot move on one side alone. The page used to build the hub's own\n * absolute URL and then rewrite its plugin prefix with String.replace to reach\n * a session, which is exactly the kind of copy that can move by one character\n * without anything noticing.\n *\n * `:workspace` and `:runKey` are Hono's own parameter syntax, because the app\n * registers `path` verbatim.\n */\n\n/** One run, which every route below addresses. */\nconst RUN = '/runs/:workspace/:runKey';\n\n/**\n * The artifact route's parameter, as Hono spells a multi-segment match.\n *\n * An artifact is named by its path inside the run directory, so `reports/a.md`\n * is one parameter across two segments. The client's `params` substitution\n * fills a single segment and percent-encodes the slash with it, so the page\n * substitutes this one itself; see the page's `_lib/terminalApi.ts`.\n */\nexport const ARTIFACT_NAME_PARAM = ':name{.+}';\n\n/**\n * The step whose pane a terminal route reads: a step ref's id. Absent, the\n * route follows the run's current step, which is one of a parallel group's.\n */\nexport const STEP_TARGET_PARAM = 'step';\n\n/** Query parameters the artifact route reads, spelled once for both halves. */\nexport const ARTIFACT_RAW_PARAM = 'raw';\nexport const ARTIFACT_DOWNLOAD_PARAM = 'download';\n\nexport default defineApiRoutes({\n /**\n * The terminal, as server-sent events.\n *\n * `stream: true` gets a URL and no call method: the consumer is the browser's\n * own `EventSource`, and a relayed call would buffer a stream that never ends.\n */\n screen: {\n method: 'GET',\n path: `${RUN}/screen/stream`,\n query: [STEP_TARGET_PARAM],\n stream: true,\n },\n control: {\n method: 'POST',\n path: `${RUN}/control`,\n response: apiResponse<WorkflowControlResponse>(),\n },\n keys: {\n method: 'POST',\n path: `${RUN}/keys`,\n },\n resize: {\n method: 'POST',\n path: `${RUN}/resize`,\n response: apiResponse<{ resized: boolean }>(),\n },\n remove: {\n method: 'DELETE',\n path: RUN,\n response: apiResponse<WorkflowDeleteResponse>(),\n },\n stop: {\n method: 'POST',\n path: `${RUN}/stop`,\n response: apiResponse<WorkflowStopResponse>(),\n },\n /** Guidance for the agent session the running step is in, like steering a Team sub-agent. */\n steer: {\n method: 'POST',\n path: `${RUN}/steer`,\n response: apiResponse<WorkflowSteerResponse>(),\n },\n /**\n * Launch a workflow into the mounting session's own runtime, which then owns\n * the run. A dispatcher session reaches its root's session mount through this.\n */\n launch: {\n method: 'POST',\n path: '/launch',\n response: apiResponse<WorkflowLaunchResponse>(),\n },\n openRunDirectory: {\n method: 'POST',\n path: `${RUN}/open-directory`,\n response: apiResponse<WorkflowOpenRunDirectoryResponse>(),\n },\n artifacts: {\n method: 'GET',\n path: `${RUN}/artifacts`,\n query: ['directory'],\n response: apiResponse<WorkflowArtifactsResponse>(),\n },\n /** One artifact: its metadata and text, or its raw bytes under `raw=1`. */\n artifact: {\n method: 'GET',\n path: `${RUN}/artifacts/${ARTIFACT_NAME_PARAM}`,\n query: [ARTIFACT_RAW_PARAM, ARTIFACT_DOWNLOAD_PARAM],\n response: apiResponse<WorkflowArtifactContentResponse>(),\n },\n});\n","/**\n * The wire contract between this package's hub API and its cockpit client:\n * one run's terminal, and the files its run directory holds.\n *\n * Both halves of the cockpit import these names, so the route strings and the\n * event names live here rather than being spelled twice.\n */\n\n/**\n * Segment this package's API is mounted under, below /api/plugins/.\n *\n * The same word names `src/extensions/(backend)/api/workflow/`, which is where\n * the build reads the mount for the browser's client, so the two cannot drift.\n * The routes themselves are declared in `apiRoutes.ts`.\n */\nexport const WORKFLOW_API_BASE_PATH = 'workflow';\n\n/** The SSE event name the screen stream writes. */\nexport const WORKFLOW_SCREEN_EVENT = 'screen';\n\n/** What a surface may do with one run's terminal, and why anything is missing. */\nexport interface WorkflowTerminalCapabilitiesView {\n readable: boolean;\n writable: boolean;\n resizable: boolean;\n reason?: string;\n}\n\n/** One frame of a run's terminal, as the stream pushes it. */\nexport interface WorkflowScreenEvent {\n /** The visible screen, newest line last, carrying the colour the run printed. */\n lines: string[];\n capabilities: WorkflowTerminalCapabilitiesView;\n /** True once the run has settled, after which the stream ends. */\n ended?: boolean;\n}\n\n/** Answer to taking or releasing the keyboard for one run. */\nexport interface WorkflowControlResponse {\n /** True when this caller now holds the keyboard. */\n held: boolean;\n /** The token later writes must carry; absent when control was refused or released. */\n token?: string;\n /** Why control was refused, worded for a reader. */\n reason?: string;\n}\n\n/** Answer after a settled run and its directory have been permanently removed. */\nexport interface WorkflowDeleteResponse {\n deleted: true;\n}\n\n/** Answer once a stop request is recorded; the engine ends the run at its next check. */\nexport interface WorkflowStopResponse {\n requested: true;\n}\n\n/** Answer once guidance reached the running step's agent session. */\nexport interface WorkflowSteerResponse {\n delivered: true;\n}\n\n/** What launching a workflow into a session answered, as the launch tool reports it. */\nexport interface WorkflowLaunchResponse {\n text: string;\n isError?: boolean;\n}\n\n/** How a declared run-directory entry compares with what is on disk. */\nexport type WorkflowArtifactState = 'written' | 'empty' | 'pending' | 'unreadable';\n\n/** One file or directory in a run's own folder. */\nexport interface WorkflowArtifactView {\n /** Path relative to the run directory, which is also the read route's parameter. */\n path: string;\n kind: 'file' | 'directory';\n /** What the workflow says this file is for; empty for a file it never declared. */\n description: string;\n /** The jobs the workflow says write it. */\n producedBy: string[];\n /** True when the workflow's run-directory block names this entry. */\n declared: boolean;\n state: WorkflowArtifactState;\n /** Bytes on disk, absent until the file exists. */\n size?: number;\n /** ISO 8601 of the last write, absent until the file exists. */\n modifiedAt?: string;\n}\n\nexport interface WorkflowArtifactsResponse {\n /** Absolute path of the run's own directory, which the reader may want to open. */\n runDir: string;\n /** What the workflow says the directory is for. */\n description: string;\n artifacts: WorkflowArtifactView[];\n}\n\n/** One artifact's metadata and optional text, as the viewer tab reads it. */\nexport interface WorkflowArtifactContentResponse {\n path: string;\n size: number;\n modifiedAt: string;\n /** Media type inferred from the file extension by the trusted hub. Absent on older hubs. */\n mimeType?: string;\n /** Present for text formats; binary files are streamed from the raw route instead. */\n text?: string;\n /** True when textual content was longer than the reader's byte budget. */\n truncated: boolean;\n}\n\n/** Acknowledges opening the registered run folder in Finder. */\nexport interface WorkflowOpenRunDirectoryResponse {\n opened: true;\n}\n","import { execFile } from 'node:child_process';\nimport { randomUUID } from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { Readable } from 'node:stream';\n\nimport {\n doomApiCallerFrom,\n type DoomApi,\n type DoomApiContext,\n type DoomApiHandler,\n} from '@agimon-ai/po-core/packageApi';\nimport {\n WorkflowRegistryService,\n WorkflowTerminalService as WorkflowTerminalFacade,\n type WorkflowRunRecord,\n type WorkflowStage,\n} from '@agimon-ai/workflow-mcp';\nimport { type Context, Hono } from 'hono';\nimport { streamSSE } from 'hono/streaming';\n\nimport {\n createStepPaneTerminal,\n createStepPaneTerminalDependencies,\n removeStepPaneLogs,\n} from '../../services/stepPaneTerminal';\nimport type { RunTerminalTarget } from '../../services/stepPaneTerminal/type';\nimport { createWorkflowTerminalService } from '../../services/workflowTerminal';\nimport routes, { ARTIFACT_DOWNLOAD_PARAM, ARTIFACT_RAW_PARAM, STEP_TARGET_PARAM } from '../../types/apiRoutes';\nimport { STEP_SESSION_REF_KIND } from '../../types/webWorkflows';\nimport {\n WORKFLOW_API_BASE_PATH,\n WORKFLOW_SCREEN_EVENT,\n type WorkflowArtifactContentResponse,\n type WorkflowArtifactsResponse,\n type WorkflowArtifactView,\n type WorkflowControlResponse,\n type WorkflowDeleteResponse,\n type WorkflowLaunchResponse,\n type WorkflowScreenEvent,\n type WorkflowSteerResponse,\n type WorkflowStopResponse,\n} from '../../types/webWorkflowTerminal';\n\n/** Stages a run can be recorded under, newest first: a live run is the common case. */\nconst STAGES: readonly WorkflowStage[] = ['running', 'error', 'completed'];\n/** Lines of screen the stream sends, which is a terminal's visible height plus room. */\nconst SCREEN_LINES = 48;\n/** How often the stream re-reads; the service coalesces, so this is an upper bound. */\nconst STREAM_TICK_MS = 500;\n/** How often a settled run is re-checked before the stream closes itself. */\nconst SETTLED_POLL_TICKS = 4;\n/** Bytes of one textual artifact returned as JSON; binary previews use a stream. */\nconst MAX_ARTIFACT_BYTES = 512 * 1024;\n/** Recorded with a stop the web panel asks for, so the run log says where it came from. */\nconst WEB_STOP_REASON = 'Stopped from the web workflow panel.';\n/** Path segments a client supplies are names, never paths. */\nconst SAFE_SEGMENT = /^[\\w.@-]+$/;\nconst ARTIFACT_MIME_TYPES: Readonly<Record<string, string>> = {\n '.aac': 'audio/aac',\n '.bmp': 'image/bmp',\n '.css': 'text/css',\n '.csv': 'text/csv',\n '.gif': 'image/gif',\n '.htm': 'text/html',\n '.html': 'text/html',\n '.ico': 'image/x-icon',\n '.jpeg': 'image/jpeg',\n '.jpg': 'image/jpeg',\n '.js': 'text/javascript',\n '.json': 'application/json',\n '.jsx': 'text/jsx',\n // A run's engine log, which a reader opens to see why a step failed.\n '.log': 'text/plain',\n '.m4a': 'audio/mp4',\n '.markdown': 'text/markdown',\n '.md': 'text/markdown',\n '.mov': 'video/quicktime',\n '.mp3': 'audio/mpeg',\n '.mp4': 'video/mp4',\n '.oga': 'audio/ogg',\n '.ogg': 'audio/ogg',\n '.ogv': 'video/ogg',\n '.pdf': 'application/pdf',\n '.png': 'image/png',\n '.sh': 'text/x-shellscript',\n '.svg': 'image/svg+xml',\n '.toml': 'text/toml',\n '.ts': 'text/typescript',\n '.tsv': 'text/tab-separated-values',\n '.tsx': 'text/tsx',\n '.txt': 'text/plain',\n '.wav': 'audio/wav',\n '.webm': 'video/webm',\n '.webp': 'image/webp',\n '.xml': 'application/xml',\n '.yaml': 'text/yaml',\n '.yml': 'text/yaml',\n};\n\n/**\n * One request's JSON body as a plain record.\n *\n * A body that is absent, malformed, or not an object reads as empty rather\n * than failing the route: every field is checked by the route anyway, and a\n * 400 naming the missing field beats a parse error naming nothing.\n */\nasync function jsonBody(context: Context): Promise<Record<string, unknown>> {\n const parsed: unknown = await context.req.json().catch(() => undefined);\n return parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : {};\n}\n\n/** Rejects anything that could climb out of the registry before a path is built. */\nfunction isSafeSegment(value: string): boolean {\n return value !== '' && value !== '../adapters' && value !== '..' && SAFE_SEGMENT.test(value);\n}\n\n/**\n * One terminal's identity for caches and leases, stable across stage moves: a\n * run's, or one step's pane in it, which keeps its own screen and keyboard.\n */\nfunction runIdentityOf(workspace: string, runKey: string, step?: string): string {\n return step === undefined ? `${workspace}/${runKey}` : `${workspace}/${runKey}#${step}`;\n}\n\n/** The step a terminal request names, from its query or body; absent follows the current step. */\nfunction stepOf(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\nexport interface WorkflowHubApiOptions {\n registry?: WorkflowRegistryService;\n terminal?: WorkflowTerminalFacade;\n now?: () => number;\n /**\n * Guides a live session that the mounting session started. Present only on a\n * session mount, whose session service refuses sessions it did not start.\n */\n steer?: (sessionId: string, message: string) => Promise<void>;\n /**\n * Runs a workflow in the mounting session, which then owns it. Present only on\n * the mount of a session with a workflow runtime.\n */\n launch?: (parameters: Record<string, unknown>) => Promise<WorkflowLaunchResponse>;\n}\n\n/**\n * This package's HTTP surface: one workflow run's terminal, and the files its\n * run directory holds.\n *\n * Mounted in the hub rather than in a session's server, because a run's\n * terminal belongs to its multiplexer rather than to the session that launched\n * it: any process can read a tmux pane, and the session's own server cannot\n * reach anything more. The routes therefore name a run, never a session.\n */\nexport function createWorkflowHubApi(options: WorkflowHubApiOptions = {}): Hono {\n const registry = options.registry ?? new WorkflowRegistryService();\n const facade = options.terminal ?? new WorkflowTerminalFacade();\n const stepPanes = createStepPaneTerminalDependencies(registry);\n const terminal = createWorkflowTerminalService<RunTerminalTarget>({\n // A run executing in the server has a pane per command step instead of one for the whole run.\n terminal: createStepPaneTerminal(facade, stepPanes),\n now: options.now ?? (() => Date.now()),\n });\n const app = new Hono();\n\n /** The record behind a request, whichever stage it now sits in. */\n const runOf = async (workspace: string, runKey: string): Promise<WorkflowRunRecord | undefined> => {\n if (!isSafeSegment(workspace) || !isSafeSegment(runKey)) return undefined;\n for (const stage of STAGES) {\n try {\n return await registry.readRunByKey(workspace, stage, runKey);\n } catch {\n // Not in this stage. A run moves between them as it settles, so a miss\n // here is ordinary; only a miss in every stage means no such run.\n }\n }\n return undefined;\n };\n\n const missing = (workspace: string, runKey: string): { error: string } => ({\n error: `No workflow run '${runKey}' in workspace '${workspace}'.`,\n });\n\n app.get(routes.screen.path, async (context) => {\n const workspace = context.req.param('workspace');\n const runKey = context.req.param('runKey');\n const record = await runOf(workspace, runKey);\n if (record === undefined) return context.json(missing(workspace, runKey), 404);\n const step = stepOf(context.req.query(STEP_TARGET_PARAM));\n const identity = runIdentityOf(workspace, runKey, step);\n\n return streamSSE(context, async (stream) => {\n let settledTicks = 0;\n let running = true;\n let latest = record;\n stream.onAbort(() => {\n running = false;\n });\n while (running) {\n const current = (await runOf(workspace, runKey)) ?? record;\n latest = current;\n const target: RunTerminalTarget = { record: current, ...(step === undefined ? {} : { step }) };\n const capabilities = terminal.capabilities(target);\n const lines = capabilities.readable ? await terminal.screen(identity, target, SCREEN_LINES) : [];\n // A settled run is read a few more times before the stream closes: the\n // last thing a failing step printed is what the reader came for, and it\n // lands after the record has already moved to its final stage.\n const settled = current.stage !== 'running';\n if (settled) settledTicks += 1;\n const ended = settled && settledTicks >= SETTLED_POLL_TICKS;\n const event: WorkflowScreenEvent = { lines, capabilities, ...(ended ? { ended: true } : {}) };\n await stream.writeSSE({ event: WORKFLOW_SCREEN_EVENT, data: JSON.stringify(event) });\n if (ended) break;\n await stream.sleep(STREAM_TICK_MS);\n }\n // Only a settled run is forgotten, and only this one. A reader closing its\n // stream, which happens whenever a panel unmounts, must not drop the\n // keyboard lease someone just took on another panel, or on another run.\n if (latest.stage !== 'running') terminal.forgetRun(identity);\n });\n });\n\n app.post(routes.control.path, async (context) => {\n const workspace = context.req.param('workspace');\n const runKey = context.req.param('runKey');\n const record = await runOf(workspace, runKey);\n if (record === undefined) return context.json(missing(workspace, runKey), 404);\n const body = await jsonBody(context);\n const step = stepOf(body.step);\n const identity = runIdentityOf(workspace, runKey, step);\n const capabilities = terminal.capabilities({ record, ...(step === undefined ? {} : { step }) });\n\n if (body.release === true) {\n if (typeof body.token === 'string') terminal.releaseControl(identity, body.token);\n const released: WorkflowControlResponse = { held: false };\n return context.json(released);\n }\n if (!capabilities.writable) {\n const refused: WorkflowControlResponse = { held: false, reason: capabilities.reason };\n return context.json(refused, 409);\n }\n const token = typeof body.token === 'string' && body.token !== '' ? body.token : randomUUID();\n if (!terminal.takeControl(identity, token)) {\n const taken: WorkflowControlResponse = { held: false, reason: 'Another reader holds the keyboard.' };\n return context.json(taken, 409);\n }\n const held: WorkflowControlResponse = { held: true, token };\n return context.json(held);\n });\n\n app.post(routes.keys.path, async (context) => {\n const workspace = context.req.param('workspace');\n const runKey = context.req.param('runKey');\n const record = await runOf(workspace, runKey);\n if (record === undefined) return context.json(missing(workspace, runKey), 404);\n const body = await jsonBody(context);\n if (typeof body.token !== 'string' || typeof body.data !== 'string') {\n return context.json({ error: 'A keystroke needs a control token and its data.' }, 400);\n }\n const step = stepOf(body.step);\n try {\n await terminal.write(\n runIdentityOf(workspace, runKey, step),\n { record, ...(step === undefined ? {} : { step }) },\n body.token,\n body.data,\n );\n } catch (error) {\n return context.json({ error: error instanceof Error ? error.message : String(error) }, 409);\n }\n return context.body(null, 204);\n });\n\n app.post(routes.resize.path, async (context) => {\n const workspace = context.req.param('workspace');\n const runKey = context.req.param('runKey');\n const record = await runOf(workspace, runKey);\n if (record === undefined) return context.json(missing(workspace, runKey), 404);\n const body = await jsonBody(context);\n const { token, columns, rows } = body;\n if (typeof token !== 'string' || typeof columns !== 'number' || typeof rows !== 'number') {\n return context.json({ error: 'A resize needs a control token, columns and rows.' }, 400);\n }\n const step = stepOf(body.step);\n try {\n const resized = await terminal.resize(\n runIdentityOf(workspace, runKey, step),\n { record, ...(step === undefined ? {} : { step }) },\n token,\n columns,\n rows,\n );\n return context.json({ resized });\n } catch (error) {\n return context.json({ error: error instanceof Error ? error.message : String(error) }, 409);\n }\n });\n\n app.post(routes.stop.path, async (context) => {\n const workspace = context.req.param('workspace');\n const runKey = context.req.param('runKey');\n const record = await runOf(workspace, runKey);\n if (record === undefined) return context.json(missing(workspace, runKey), 404);\n if (record.stage !== 'running' || record.runId === undefined) {\n return context.json({ error: 'Only a running workflow can be stopped.' }, 409);\n }\n try {\n // The same request the workflow tool's stop writes; the engine that owns the\n // run reads it wherever that engine lives, in this server or in a terminal.\n await registry.requestStop(workspace, runKey, WEB_STOP_REASON, record.runId);\n } catch (error) {\n return context.json({ error: error instanceof Error ? error.message : String(error) }, 409);\n }\n const response: WorkflowStopResponse = { requested: true };\n return context.json(response);\n });\n\n app.post(routes.steer.path, async (context) => {\n const workspace = context.req.param('workspace');\n const runKey = context.req.param('runKey');\n const record = await runOf(workspace, runKey);\n if (record === undefined) return context.json(missing(workspace, runKey), 404);\n const body = await jsonBody(context);\n const message = typeof body.message === 'string' ? body.message.trim() : '';\n if (message === '') return context.json({ error: 'Guidance needs a message.' }, 400);\n if (record.stage !== 'running') return context.json({ error: 'Only a running workflow can be steered.' }, 409);\n // Only a step running now, and only an agent session. A browser names the\n // run, and inside a parallel group the step's own session; any other\n // session is out of reach.\n const refs = stepPanes.stepRefs(record);\n const step = typeof body.step === 'string' ? body.step : undefined;\n const current = step === undefined ? refs.current : (refs.running ?? []).find((candidate) => candidate.id === step);\n if (current?.kind !== STEP_SESSION_REF_KIND) {\n return context.json({ error: 'The running step is not an agent session.' }, 409);\n }\n if (options.steer === undefined) {\n return context.json({ error: 'Steering is available from the session that launched this run.' }, 409);\n }\n try {\n await options.steer(current.id, message);\n } catch (error) {\n return context.json({ error: error instanceof Error ? error.message : String(error) }, 409);\n }\n const response: WorkflowSteerResponse = { delivered: true };\n return context.json(response);\n });\n\n app.post(routes.launch.path, async (context) => {\n if (options.launch === undefined) {\n return context.json({ error: 'Launching needs the mount of a session with a workflow runtime.' }, 409);\n }\n const response: WorkflowLaunchResponse = await options.launch(await jsonBody(context));\n return context.json(response);\n });\n\n app.delete(routes.remove.path, async (context) => {\n const workspace = context.req.param('workspace');\n const runKey = context.req.param('runKey');\n const record = await runOf(workspace, runKey);\n if (record === undefined) return context.json(missing(workspace, runKey), 404);\n if (record.stage === 'running') {\n return context.json({ error: 'A running workflow must be stopped before it can be deleted.' }, 409);\n }\n // Read before the run directory goes: its progress log is what names the panes.\n const refs = stepPanes.stepRefs(record);\n try {\n fs.rmSync(registry.runDirectoryFor(record), { recursive: true, force: true });\n await removeStepPaneLogs(refs);\n } catch (error) {\n return context.json({ error: error instanceof Error ? error.message : String(error) }, 409);\n }\n const response: WorkflowDeleteResponse = { deleted: true };\n return context.json(response);\n });\n\n app.post(routes.openRunDirectory.path, async (context) => {\n if (doomApiCallerFrom(context.req.raw.headers)?.locality !== 'local') {\n return context.json({ error: 'Opening Finder is only available on the host.' }, 403);\n }\n const workspace = context.req.param('workspace');\n const runKey = context.req.param('runKey');\n const record = await runOf(workspace, runKey);\n if (record === undefined) return context.json(missing(workspace, runKey), 404);\n if (process.platform !== 'darwin') {\n return context.json({ error: 'Finder is only available on macOS.' }, 409);\n }\n try {\n const runDir = path.resolve(registry.runDirectoryFor(record));\n if (!fs.statSync(runDir).isDirectory()) {\n return context.json({ error: 'The run directory is not a folder.' }, 409);\n }\n await new Promise<void>((resolve, reject) => {\n execFile('/usr/bin/open', ['-a', 'Finder', runDir], { timeout: 5_000 }, (error) => {\n if (error) reject(error);\n else resolve();\n });\n });\n return context.json({ opened: true });\n } catch (error) {\n return context.json({ error: error instanceof Error ? error.message : String(error) }, 409);\n }\n });\n\n app.get(routes.artifacts.path, async (context) => {\n const workspace = context.req.param('workspace');\n const runKey = context.req.param('runKey');\n const record = await runOf(workspace, runKey);\n if (record === undefined) return context.json(missing(workspace, runKey), 404);\n const runDir = registry.runDirectoryFor(record);\n const directory = context.req.query('directory') ?? '';\n const resolved = resolveInside(runDir, directory);\n if (resolved === undefined) return context.json({ error: 'That folder is not inside this run.' }, 400);\n try {\n const body: WorkflowArtifactsResponse = {\n runDir,\n description: record.runDirectory?.description ?? '',\n artifacts: readArtifacts(runDir, record, directory),\n };\n return context.json(body);\n } catch (error) {\n return context.json({ error: error instanceof Error ? error.message : String(error) }, 409);\n }\n });\n\n app.get(routes.artifact.path, async (context) => {\n const workspace = context.req.param('workspace');\n const runKey = context.req.param('runKey');\n const record = await runOf(workspace, runKey);\n if (record === undefined) return context.json(missing(workspace, runKey), 404);\n const runDir = registry.runDirectoryFor(record);\n const requested = context.req.param('name');\n const resolved = resolveInside(runDir, requested);\n if (resolved === undefined) return context.json({ error: `'${requested}' is not inside this run.` }, 400);\n if (context.req.query(ARTIFACT_RAW_PARAM) === '1') {\n const response = streamArtifact(\n resolved,\n requested,\n context.req.header('range'),\n context.req.query(ARTIFACT_DOWNLOAD_PARAM) === '1',\n );\n return response ?? context.json({ error: `'${requested}' has not been written.` }, 404);\n }\n const body = readArtifact(resolved, requested);\n if (body === undefined) return context.json({ error: `'${requested}' has not been written.` }, 404);\n return context.json(body);\n });\n\n return app;\n}\n\n/**\n * A path inside the run directory, or undefined when it points anywhere else.\n *\n * The client supplies this one verbatim, unlike the run key, so it is resolved\n * and then checked rather than trusted: without the check the route would read\n * any file the hub can reach.\n */\nfunction resolveInside(runDir: string, requested: string): string | undefined {\n const resolved = path.resolve(runDir, requested);\n const root = path.resolve(runDir);\n if (resolved !== root && !resolved.startsWith(`${root}${path.sep}`)) return undefined;\n try {\n const realRoot = fs.realpathSync(root);\n // Check the nearest existing ancestor too, so pending paths through symlinks stay confined.\n let ancestor = resolved;\n while (!fs.existsSync(ancestor)) {\n const parent = path.dirname(ancestor);\n if (parent === ancestor) return undefined;\n ancestor = parent;\n }\n const real = fs.realpathSync(ancestor);\n if (real !== realRoot && !real.startsWith(`${realRoot}${path.sep}`)) return undefined;\n return resolved;\n } catch {\n return undefined; // Missing or inaccessible run roots cannot safely be read.\n }\n}\n\n/** Size and modification time of one path, or undefined when it is not there. */\nfunction statOf(target: string): fs.Stats | undefined {\n try {\n return fs.statSync(target);\n } catch {\n return undefined; // Not written yet, which is an ordinary state for an artifact.\n }\n}\n\nfunction stateOf(stats: fs.Stats | undefined): WorkflowArtifactView['state'] {\n if (stats === undefined) return 'pending';\n if (stats.isDirectory()) return 'written';\n return stats.size === 0 ? 'empty' : 'written';\n}\n\nfunction viewOf(\n runDir: string,\n entry: Omit<WorkflowArtifactView, 'state' | 'size' | 'modifiedAt'>,\n): WorkflowArtifactView {\n const target = resolveInside(runDir, entry.path);\n const stats = target === undefined ? undefined : statOf(target);\n return {\n ...entry,\n kind: stats?.isDirectory() ? 'directory' : entry.kind,\n state: target === undefined ? 'unreadable' : stateOf(stats),\n ...(stats === undefined ? {} : { size: stats.size, modifiedAt: stats.mtime.toISOString() }),\n };\n}\n\n/**\n * What the run directory holds: the workflow's own declaration first, then the\n * files nobody declared.\n *\n * The declaration is the point of the folder, so it leads and keeps its order\n * even for entries no job has written yet. The rest follows rather than being\n * hidden: the engine's own context.md and progress log are often exactly what a\n * reader is looking for.\n */\nfunction readArtifacts(runDir: string, record: WorkflowRunRecord, directory = ''): WorkflowArtifactView[] {\n const declared = (record.runDirectory?.entries ?? []).map((entry) =>\n viewOf(runDir, {\n path: entry.path,\n kind: entry.kind,\n description: entry.description,\n producedBy: entry['produced-by'] ?? [],\n declared: true,\n }),\n );\n const children = declared.filter((entry) => path.posix.dirname(entry.path) === (directory || '.'));\n const claimed = new Set(children.map((entry) => entry.path));\n const names = fs.readdirSync(path.join(runDir, directory), { withFileTypes: true });\n const found = names\n .filter((entry) => !claimed.has(path.posix.join(directory, entry.name)))\n .map((entry) =>\n viewOf(runDir, {\n path: path.posix.join(directory, entry.name),\n kind: entry.isDirectory() ? 'directory' : 'file',\n description: '',\n producedBy: [],\n declared: false,\n }),\n )\n .sort((left, right) => left.path.localeCompare(right.path));\n return [...(directory === '' ? declared : children), ...found];\n}\n\n/** Browser content type inferred from a filename without trusting client input. */\nfunction artifactMimeType(requested: string): string {\n return ARTIFACT_MIME_TYPES[path.extname(requested).toLowerCase()] ?? 'application/octet-stream';\n}\n\nfunction isTextArtifact(mimeType: string): boolean {\n return mimeType.startsWith('text/') || mimeType === 'application/json' || mimeType === 'application/xml';\n}\n\n/** One artifact's metadata and bounded text, or undefined when it is not readable. */\nfunction readArtifact(resolved: string, requested: string): WorkflowArtifactContentResponse | undefined {\n const stats = statOf(resolved);\n if (stats === undefined || stats.isDirectory()) return undefined;\n const mimeType = artifactMimeType(requested);\n let text: string | undefined;\n if (isTextArtifact(mimeType)) {\n try {\n const handle = fs.openSync(resolved, 'r');\n try {\n const buffer = Buffer.alloc(Math.min(stats.size, MAX_ARTIFACT_BYTES));\n fs.readSync(handle, buffer, 0, buffer.length, 0);\n text = buffer.toString('utf8');\n } finally {\n fs.closeSync(handle);\n }\n } catch {\n return undefined;\n }\n }\n return {\n path: requested,\n size: stats.size,\n modifiedAt: stats.mtime.toISOString(),\n mimeType,\n ...(text === undefined ? {} : { text }),\n truncated: text !== undefined && stats.size > MAX_ARTIFACT_BYTES,\n };\n}\n\n/** Streams media with byte-range support so browser audio, video, and PDF controls can seek. */\nfunction streamArtifact(\n resolved: string,\n requested: string,\n rangeHeader: string | undefined,\n download: boolean,\n): Response | undefined {\n const stats = statOf(resolved);\n if (stats === undefined || stats.isDirectory()) return undefined;\n const mimeType = artifactMimeType(requested);\n let start = 0;\n let end = Math.max(0, stats.size - 1);\n let partial = false;\n const match = rangeHeader?.match(/^bytes=(\\d*)-(\\d*)$/);\n if (match !== null && match !== undefined && stats.size > 0) {\n const requestedStart = match[1] === '' ? undefined : Number(match[1]);\n const requestedEnd = match[2] === '' ? undefined : Number(match[2]);\n if (requestedStart === undefined && requestedEnd !== undefined) {\n start = Math.max(0, stats.size - requestedEnd);\n } else if (requestedStart !== undefined) {\n start = requestedStart;\n end = requestedEnd === undefined ? end : Math.min(requestedEnd, end);\n }\n if (start >= stats.size || start > end) {\n return new Response(null, { status: 416, headers: { 'content-range': `bytes */${String(stats.size)}` } });\n }\n partial = true;\n }\n const filename = path.basename(requested).replace(/[\"\\\\\\r\\n]/g, '_');\n const forceDownload = download || mimeType === 'text/html';\n const headers = new Headers({\n 'accept-ranges': 'bytes',\n 'content-disposition': `${forceDownload ? 'attachment' : 'inline'}; filename=\"${filename}\"`,\n 'content-length': String(stats.size === 0 ? 0 : end - start + 1),\n 'content-type': mimeType,\n 'x-content-type-options': 'nosniff',\n });\n if (partial) headers.set('content-range', `bytes ${String(start)}-${String(end)}/${String(stats.size)}`);\n if (stats.size === 0) return new Response(null, { status: 200, headers });\n const body = Readable.toWeb(fs.createReadStream(resolved, { start, end }));\n return new Response(body, { status: partial ? 206 : 200, headers });\n}\n\n/**\n * This package's API, mounted by a session with its runtime's `launch` and by\n * the hub without one.\n */\nexport function createWorkflowApi(launch?: WorkflowHubApiOptions['launch']): DoomApi {\n return {\n basePath: WORKFLOW_API_BASE_PATH,\n start(context: DoomApiContext): DoomApiHandler {\n // A run is addressed by its registry identity, which is machine-wide. Only\n // steering and launching need a session: the one mounting this API, which\n // may guide only the step sessions it started.\n const steer = context.sessionService?.steer?.bind(context.sessionService);\n const app = createWorkflowHubApi({\n ...(steer === undefined ? {} : { steer: (sessionId, message) => steer(sessionId, message) }),\n ...(launch === undefined ? {} : { launch }),\n });\n return {\n fetch: (request) => app.fetch(request),\n // Nothing outlives a request: a stream's loop ends when its own socket\n // aborts, and the caches it touched are per run rather than per client.\n close: () => undefined,\n };\n },\n };\n}\n\n/** The named export a host imports from this package's built hub entry. */\nexport const api: DoomApi = createWorkflowApi();\n","import type { WorkflowRunRecord, WorkflowStage } from '@agimon-ai/workflow-mcp';\n\n/** Package-local narration sink; the Pi adapter binds it to the injected Cordis service. */\nexport interface WorkflowNarrationSink {\n narrate(text: string): void;\n}\n\nconst RUNNING_STAGE: WorkflowStage = 'running';\nconst COMPLETED_STAGE: WorkflowStage = 'completed';\nconst ERROR_STAGE: WorkflowStage = 'error';\n\ntype NarratedWorkflow = Pick<WorkflowRunRecord, 'displayName' | 'stage'>;\n\n/**\n * Translate an observed workflow lifecycle transition into generic speech.\n * Voice owns delivery and ignores requests while its minor mode is inactive.\n */\nexport function narrateWorkflowTransition(\n requester: WorkflowNarrationSink,\n record: NarratedWorkflow,\n previousStage: WorkflowStage | undefined,\n startedDuringSession: boolean,\n): void {\n const newlyLaunched = previousStage === undefined && startedDuringSession;\n if (newlyLaunched) requester.narrate(`Workflow launched: ${record.displayName}.`);\n\n if (previousStage !== RUNNING_STAGE && !newlyLaunched) return;\n if (record.stage === COMPLETED_STAGE) requester.narrate(`Workflow succeeded: ${record.displayName}.`);\n if (record.stage === ERROR_STAGE) requester.narrate(`Workflow failed: ${record.displayName}.`);\n}\n","import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nfunction packageRoot(): string {\n let directory = path.dirname(fileURLToPath(import.meta.url));\n while (!existsSync(path.join(directory, 'package.json'))) {\n const parent = path.dirname(directory);\n if (parent === directory) throw new Error('Workflow package resources are unavailable.');\n directory = parent;\n }\n return directory;\n}\nexport function workflowSkillDirectory(): string {\n return path.join(packageRoot(), 'skills');\n}\nexport async function readWorkflowSkill(name: string): Promise<string> {\n return readFile(\n path.join(packageRoot(), name === 'workflow-recovery' ? 'skills' : 'src/prompts', name, 'SKILL.md'),\n 'utf8',\n );\n}\n","/**\n * The workflow session: the child session a launch creates to own and run one\n * workflow, nested under the session that launched it.\n *\n * DESIGN PATTERNS:\n * - Pure presenters for the rail line and the owner agent's brief\n * - A lifecycle driven by the run snapshots the runtime already publishes,\n * with every host effect injected\n *\n * AVOID:\n * - Posting or releasing on startup: a woken session reports nothing it did\n * not see change, so opening a stopped session never stops it again\n */\n\nimport { basename } from 'node:path';\n\nimport type { DoomSessionActivity } from '@agimon-ai/po-core/hubChannel';\n\nimport { WORKFLOW_SESSION_PROVENANCE } from '../../constants/workflow';\nimport type { WorkflowRunView } from '../../types/webWorkflows';\nimport type { WorkflowSessionLifecycle, WorkflowSessionLifecycleDeps, WorkflowSessionNotice } from './type';\n\nexport type { WorkflowSessionLifecycle, WorkflowSessionLifecycleDeps, WorkflowSessionNotice } from './type';\n\nconst MINUTE_MS = 60_000;\nconst HOUR_MS = 3_600_000;\n/** A failure cause is a line in a notice, not the log; a longer one is cut. */\nconst MAX_CAUSE = 1_000;\nconst WORKFLOW_FILE_SUFFIX = /\\.workflow\\.ya?ml$|\\.ya?ml$/u;\n\n/** Whether this session was created to own a workflow run. */\nexport function isWorkflowSession(context: { readonly sessionContext?: { readonly provenance?: string } }): boolean {\n return context.sessionContext?.provenance === WORKFLOW_SESSION_PROVENANCE;\n}\n\n/** The rail name of a workflow session: the catalog's name, else the file's stem. */\nexport function workflowSessionName(workflowPath: string, catalogName?: string): string {\n if (catalogName !== undefined && catalogName.trim() !== '') return catalogName.trim();\n return basename(workflowPath).replace(WORKFLOW_FILE_SUFFIX, '') || 'workflow';\n}\n\nfunction isPaused(run: WorkflowRunView): boolean {\n return run.stage === 'running' && (run.executionState === 'paused' || run.executionState === 'pause_requested');\n}\n\nfunction needsAttention(run: WorkflowRunView): boolean {\n return run.stage === 'error' || run.stale === true || isPaused(run);\n}\n\nfunction succeeded(run: WorkflowRunView): boolean {\n return (\n run.stage === 'completed' && (run.outcome === undefined || run.outcome === 'success' || run.outcome === 'skipped')\n );\n}\n\nfunction duration(run: WorkflowRunView): string | undefined {\n const start = Date.parse(run.startedAt);\n const end = run.finishedAt === undefined ? Number.NaN : Date.parse(run.finishedAt);\n if (!Number.isFinite(start) || !Number.isFinite(end)) return undefined;\n const elapsed = Math.max(0, end - start);\n if (elapsed < MINUTE_MS) return 'under a minute';\n if (elapsed < HOUR_MS) return `${Math.floor(elapsed / MINUTE_MS)}m`;\n return `${Math.floor(elapsed / HOUR_MS)}h ${String(Math.floor((elapsed % HOUR_MS) / MINUTE_MS)).padStart(2, '0')}m`;\n}\n\n/**\n * The line the rail shows for a workflow session, in place of an idle agent's\n * copy. A failure or pause outranks a run in progress, because it is the one\n * that needs the reader.\n */\nexport function workflowSessionActivity(runs: readonly WorkflowRunView[]): DoomSessionActivity | undefined {\n if (runs.length === 0) return undefined;\n const failed = runs.find((run) => run.stage === 'error');\n if (failed !== undefined)\n return { label: `workflow failed · ${failed.failedJob ?? failed.displayName}`, attention: true };\n const paused = runs.find(isPaused);\n if (paused !== undefined) {\n return {\n label: paused.position === undefined ? 'workflow paused' : `workflow paused · ${paused.position.job}`,\n attention: true,\n };\n }\n const stale = runs.find((run) => run.stage === 'running' && run.stale === true);\n if (stale !== undefined) return { label: 'workflow interrupted', attention: true };\n const running = runs.find((run) => run.stage === 'running');\n if (running !== undefined) {\n const where = [running.position?.job, running.position?.step].filter(Boolean).join(' › ');\n return { label: where === '' ? 'workflow · starting' : `workflow · ${where}`, since: running.startedAt };\n }\n if (runs.every(succeeded)) return { label: 'workflow succeeded' };\n return { label: `workflow ${runs[0]!.outcome ?? 'ended'}`, attention: true };\n}\n\nfunction runState(run: WorkflowRunView): string {\n if (run.stage === 'error') return 'failed';\n if (run.stale === true) return 'interrupted (its process is gone)';\n if (isPaused(run)) return 'paused';\n if (run.stage === 'running') return 'running';\n return run.outcome ?? 'completed';\n}\n\n/**\n * The owner agent's live brief, added to its system prompt on every turn.\n *\n * Read from the registry each time rather than written once, so it survives a\n * wake and never describes a run that has since moved on.\n */\nexport function workflowSessionBrief(runs: readonly WorkflowRunView[]): string {\n if (runs.length === 0) return '';\n const lines = runs.map((run) => {\n const where = [run.position?.job, run.position?.step].filter(Boolean).join(' › ');\n const failure =\n run.stage === 'error'\n ? `; ${run.failedJob === undefined ? '' : `job '${run.failedJob}' `}failed: ${run.errorMessage ?? 'no cause recorded'}`\n : '';\n return `- ${run.displayName} (runKey ${run.runKey}, workspace ${run.workspace}): ${runState(run)}${where === '' ? '' : ` at ${where}`}${failure}`;\n });\n return [\n '# Workflow session',\n 'You are the owner agent of this workflow session. It runs the workflow below for the session that launched it, and you troubleshoot it.',\n ...lines,\n 'On a workflow error, diagnose it locally and summarize the cause here. Do not wake the launcher to diagnose it, automatically restart it, or diagnose a user-requested stop. When the user or launcher session asks: use workflow_run status with the runKey and workspace for progress, workflow_tools recovery-evidence to read a failure, and load the workflow-recovery skill before workflow_tools recover. Recover, pause, resume or stop a run only when the user asks or the launcher explicitly delegates it through intercom.',\n ].join('\\n');\n}\n\nfunction failureNotice(run: WorkflowRunView): WorkflowSessionNotice {\n const cause = (run.errorMessage ?? 'the run ended in the error stage').slice(0, MAX_CAUSE);\n const job = run.failedJob === undefined ? '' : ` at job \"${run.failedJob}\"`;\n return {\n title: 'Workflow failed',\n body: `Workflow \"${run.displayName}\" failed${job}: ${cause}. Ask me to diagnose or recover it.`,\n level: 'error',\n };\n}\n\nfunction finishNotice(run: WorkflowRunView): WorkflowSessionNotice {\n const took = duration(run);\n if (succeeded(run)) {\n return {\n title: 'Workflow succeeded',\n body: `Workflow \"${run.displayName}\" ${run.outcome === 'skipped' ? 'was skipped' : 'succeeded'}${took === undefined ? '' : ` in ${took}`}.`,\n level: 'info',\n };\n }\n return {\n title: 'Workflow ended',\n body: `Workflow \"${run.displayName}\" ended: ${run.outcome ?? 'no outcome recorded'}. Ask me to look into it.`,\n level: 'error',\n };\n}\n\nconst identity = (run: WorkflowRunView): string => `${run.workspace}/${run.runKey}`;\n\n/**\n * What a workflow session does as its runs move: keep the rail line current,\n * post a notice when a handed-off run fails or finishes, and ask its parent to\n * release it after an untouched success.\n *\n * \"Untouched\" means no run ever needed attention and nobody started a turn\n * here. A session you are reading or troubleshooting stays live until you\n * remove it.\n */\nexport function createWorkflowSessionLifecycle(deps: WorkflowSessionLifecycleDeps): WorkflowSessionLifecycle {\n const stages = new Map<string, WorkflowRunView['stage']>();\n let seeded = false;\n let attention = false;\n let engaged = false;\n let requested = false;\n let disposed = false;\n let stopWaiting: (() => void) | undefined;\n\n const releasable = (runs: readonly WorkflowRunView[]): boolean =>\n deps.parentSessionId !== undefined &&\n !attention &&\n !engaged &&\n !disposed &&\n runs.length > 0 &&\n runs.every(succeeded) &&\n runs.some((run) => run.launcherSessionId === deps.parentSessionId);\n\n const requestRelease = async (runs: readonly WorkflowRunView[]): Promise<void> => {\n const parent = deps.parentSessionId;\n if (parent === undefined || requested || deps.requestRelease === undefined || !releasable(runs)) return;\n if (!(await deps.isIdle()) || disposed) return;\n requested = true;\n const runKeys = runs.map((run) => run.runKey);\n if (deps.requestRelease(parent, runKeys)) return;\n // ponytail: one retry when the parent can hear again; a parent that never returns leaves this session live.\n stopWaiting = deps.onPeerReady?.((peer) => {\n if (peer !== parent) return;\n stopWaiting?.();\n stopWaiting = undefined;\n if (releasable(runs)) deps.requestRelease?.(parent, runKeys);\n });\n };\n\n return {\n async observe(runs) {\n if (disposed) return;\n deps.publishActivity?.(workflowSessionActivity(runs));\n if (runs.some(needsAttention)) attention = true;\n if (!seeded) {\n for (const run of runs) stages.set(identity(run), run.stage);\n seeded = true;\n return;\n }\n let finished = false;\n for (const run of runs) {\n const previous = stages.get(identity(run));\n stages.set(identity(run), run.stage);\n // Only runs handed to this session get a notice: one its own agent launched reports to that agent.\n if (previous === run.stage || run.launcherSessionId === undefined) continue;\n if (run.stage === 'error') await deps.postNotice(failureNotice(run));\n else if (run.stage === 'completed') {\n await deps.postNotice(finishNotice(run));\n finished = true;\n }\n }\n if (finished) await requestRelease(runs);\n },\n agentStarted() {\n engaged = true;\n },\n dispose() {\n disposed = true;\n stopWaiting?.();\n stopWaiting = undefined;\n },\n };\n}\n","import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { createEmbeddedWorkflowFeature } from '@agimon-ai/workflow-mcp';\n\nimport {\n completeWorkflowRunView,\n foldWorkflowProgress,\n type ParsedWorkflowRun,\n parseWorkflowProgress,\n parseWorkflowRunRecord,\n planWorkflowJobs,\n PROGRESS_FILE_NAME,\n resolveWorkflowHome,\n RUN_RECORD_FILE_NAME,\n WORKFLOW_HOME_ENV,\n WORKFLOW_STAGES,\n WORKSPACES_DIR_NAME,\n} from '../workflowRuns';\n\nconst { parser } = createEmbeddedWorkflowFeature();\n\nexport interface ReadWorkflowRunsOptions {\n /** Registry home override, primarily for tests. */\n homeDir?: string;\n /** Admitted session environment used to resolve the registry home. */\n environment?: Readonly<Record<string, string | undefined>>;\n}\n\n/**\n * Read the durable workflow registry once.\n *\n * The registry is an initial snapshot only. Live delivery belongs to the\n * session lifecycle and is routed through the host-owned direct event bus.\n */\nexport function readWorkflowRuns(options: ReadWorkflowRunsOptions = {}): ParsedWorkflowRun[] {\n const environment = options.environment;\n const homeDir =\n options.homeDir ??\n resolveWorkflowHome({\n envValue: environment?.[WORKFLOW_HOME_ENV],\n homeDir: os.homedir(),\n });\n const workspacesDir = path.join(homeDir, WORKSPACES_DIR_NAME);\n const recordCache = new Map<string, { size: number; mtimeMs: number; value: ParsedWorkflowRun | undefined }>();\n const progressCache = new Map<\n string,\n { size: number; mtimeMs: number; value: ReturnType<typeof parseWorkflowProgress> }\n >();\n\n const cachedParse = <T>(\n cache: Map<string, { size: number; mtimeMs: number; value: T }>,\n filePath: string,\n parse: (raw: string) => T,\n empty: T,\n ): T => {\n let stat: fs.Stats;\n try {\n stat = fs.statSync(filePath);\n } catch {\n cache.delete(filePath);\n return empty;\n }\n const cached = cache.get(filePath);\n if (cached && cached.size === stat.size && cached.mtimeMs === stat.mtimeMs) return cached.value;\n let raw: string;\n try {\n raw = fs.readFileSync(filePath, 'utf8');\n } catch {\n cache.delete(filePath);\n return empty;\n }\n const value = parse(raw);\n cache.set(filePath, { size: stat.size, mtimeMs: stat.mtimeMs, value });\n return value;\n };\n\n const listDir = (directory: string): string[] => {\n try {\n return fs.readdirSync(directory).sort();\n } catch {\n return [];\n }\n };\n\n const plans = new Map<string, ReturnType<typeof planWorkflowJobs>>();\n const planFor = (workflowPath: string): ReturnType<typeof planWorkflowJobs> => {\n const cached = plans.get(workflowPath);\n if (cached !== undefined) return cached;\n let plan: ReturnType<typeof planWorkflowJobs> = [];\n try {\n const workflow = parser.parseWorkflowFile(workflowPath);\n plan = planWorkflowJobs(workflow, parser.resolveJobOrder(workflow.jobs, null));\n } catch {\n // ponytail: old runs have no definition snapshot. Keep recorded progress when the source is gone.\n }\n plans.set(workflowPath, plan);\n return plan;\n };\n\n const runs: ParsedWorkflowRun[] = [];\n for (const workspace of listDir(workspacesDir)) {\n for (const stage of WORKFLOW_STAGES) {\n const stageDir = path.join(workspacesDir, workspace, stage);\n for (const runKey of listDir(stageDir)) {\n const runDir = path.join(stageDir, runKey);\n const recordPath = path.join(runDir, RUN_RECORD_FILE_NAME);\n const progressPath = path.join(runDir, PROGRESS_FILE_NAME);\n const parsed = cachedParse(recordCache, recordPath, parseWorkflowRunRecord, undefined);\n if (parsed === undefined) continue;\n const events = cachedParse(progressCache, progressPath, parseWorkflowProgress, []);\n const jobs = foldWorkflowProgress(events, planFor(parsed.view.workflowPath));\n runs.push({ ...parsed, view: completeWorkflowRunView(parsed.view, jobs) });\n }\n }\n }\n return runs;\n}\n","import { randomUUID } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { isAbsolute, relative, resolve } from 'node:path';\n\nimport {\n BACKGROUND_WORK_HOLDING_PROVIDERS,\n holdsSettledSession,\n readDoomBackgroundWorkService,\n} from '@agimon-ai/po-core/backgroundWork';\nimport { resolveRootSessionId } from '@agimon-ai/po-core/childProcess';\nimport {\n type DoomHeadlessExecutionContext,\n type DoomHeadlessContent,\n type DoomHeadlessToolResult,\n} from '@agimon-ai/po-core/headless';\nimport {\n createNarrationRequest,\n DOOM_NARRATION_SERVICE,\n requireDoomNarrationService,\n type DoomNarrationService,\n} from '@agimon-ai/po-core/narration';\nimport { createDoomNotificationEntryData, DOOM_NOTIFICATION_ENTRY_TYPE } from '@agimon-ai/po-core/notification';\nimport {\n createDoomReadinessCoordinator,\n readDoomReadinessCoordinator,\n type DoomReadinessCoordinator,\n type DoomReadinessHandle,\n} from '@agimon-ai/po-core/readiness';\nimport { serverMinorModes } from '@agimon-ai/po-minor-mode';\nimport { defineMinorMode, type MinorModeOwner, type MinorModeState } from '@agimon-ai/po-minor-mode';\nimport { createDoomTelemetry } from '@agimon-ai/po-telemetry';\nimport {\n gateStepDecision,\n WORKFLOW_DECISION_FILE_ENV,\n WORKFLOW_DECISION_STEERING_ENV,\n WORKFLOW_DECISION_STEERING_HOST,\n createEmbeddedWorkflowFeature,\n readWorkflowProgress,\n summarizeWorkflowProgress,\n} from '@agimon-ai/workflow-mcp';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { CallToolResult } from '@modelcontextprotocol/server';\nimport { z } from 'zod';\n\nimport {\n WORKFLOW_LAUNCHER_SESSION_ENV,\n WORKFLOW_SESSION_PROVENANCE,\n WORKFLOW_SESSION_RELEASE_TYPE,\n WORKFLOW_TOOLS_TOOL_NAME,\n} from '../../constants/workflow';\nimport { poTemplateRunConfigSchema } from '../../schemas/runConfig';\nimport { workflowToolsInputSchema } from '../../schemas/workflowPi';\nimport { registerRunProvider, type RunProviderHandle } from '../../services/backgroundWork';\nimport {\n finishedRunSummary,\n isLaunchedRun,\n isOwnedDelegatedRun,\n isSessionRun,\n launchedRunHint,\n resolveMaxConcurrent,\n} from '../../services/piToolBridge';\nimport { createServerLauncher } from '../../services/serverLaunch';\nimport { createNativeStepPaneLauncher, createStepExecutor, sessionSelection } from '../../services/stepExecutor';\nimport { createWorkflowCatalogReader, presentWorkflowCatalog } from '../../services/webWorkflowCatalog';\nimport { defaultCatalogDeps } from '../../services/workflowCatalogDeps';\nimport type { WorkflowLaunchInput } from '../../services/workflowExecution';\nimport { isWorkflowDispatcherProcess, resolveDispatcherParentSession } from '../../services/workflowFence';\nimport { createWorkflowApi } from '../../services/workflowHubApi';\nimport {\n parseWorkflowLaunchCommand,\n resolveWorkflowEntry,\n validateWorkflowLaunch,\n} from '../../services/workflowLaunchCommand';\nimport { narrateWorkflowTransition } from '../../services/workflowNarration';\nimport { readWorkflowSkill as skill } from '../../services/workflowResource';\nimport {\n type ParsedWorkflowRun,\n presentWorkflowRuns,\n runBelongsToSession,\n runLaunchedBySession,\n} from '../../services/workflowRuns';\nimport {\n createWorkflowSessionLifecycle,\n isWorkflowSession,\n workflowSessionBrief,\n workflowSessionName,\n} from '../../services/workflowSession';\nimport { readWorkflowRuns } from '../../services/workflowWatcher';\nimport routes from '../../types/apiRoutes';\nimport { WORKFLOW_CATALOG_TYPE, WORKFLOW_RUNS_TYPE } from '../../types/webWorkflows';\nimport { WORKFLOW_API_BASE_PATH, type WorkflowLaunchResponse } from '../../types/webWorkflowTerminal';\n\nconst SOURCE = '@agimon-ai/po-workflow';\nconst WORKFLOW_MODE_ID = 'workflow';\nconst LIST_TOOL = 'list_workflows';\nconst LAUNCH_TOOL = 'launch_workflow';\nconst RUN_TOOL = 'workflow_run';\n/** Origin of a request dispatched in process to another mount; nothing resolves it. */\nconst IN_PROCESS_ORIGIN = 'http://po.local';\n/** A burst of job and step events is published once, this long after the first. */\nconst RUNS_PUBLISH_DEBOUNCE_MS = 100;\n/** A notification body's limit; a longer failure is cut to it. */\nconst NOTICE_BODY_LIMIT = 4_000;\n\ntype LaunchResult = { content: { type: 'text'; text: string }[]; isError?: boolean };\n/** Where a launch comes from: the directory it names paths against, and the repository they must stay in. */\ntype LaunchLocation = { readonly cwd: string; readonly repoRoot: string };\n\n/**\n * A launch refused because the workflow needs fixing. The doctor's findings\n * name only a job and a step, so the notice names the workflow and says\n * nothing ran; in a conversation it otherwise reads as part of whatever run\n * was reported just before it.\n */\nfunction needsFixingNotice(workflow: string, error: string): string {\n return `Workflow \"${workflow}\" was not launched: it needs fixing.\\n${error}`;\n}\n\nfunction textResult(text: string, isError = false): LaunchResult {\n return { content: [{ type: 'text', text }], ...(isError ? { isError: true } : {}) };\n}\n\nfunction isLaunchResponse(value: unknown): value is WorkflowLaunchResponse {\n return typeof value === 'object' && value !== null && 'text' in value && typeof value.text === 'string';\n}\n\nfunction errorOf(value: unknown): string | undefined {\n return typeof value === 'object' && value !== null && 'error' in value && typeof value.error === 'string'\n ? value.error\n : undefined;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/** The text of a launch's tool result, as the launch tool and the API report it. */\nfunction launchResultOf(result: CallToolResult): LaunchResult {\n const text = result.content\n .map((item) => (item.type === 'text' ? item.text : ''))\n .filter((line) => line !== '')\n .join('\\n');\n return textResult(text || 'Workflow launch requested.', result.isError === true);\n}\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 {\n content,\n details: value,\n ...(typeof value === 'object' && value !== null && 'isError' in value && value.isError === true\n ? { isError: true }\n : {}),\n };\n}\n\nimport { type DoomHeadlessHostService } from '@agimon-ai/po-core/headless';\nimport { type DoomServerHostService, type DoomServerSessionPlugin } from '@agimon-ai/po-core/serverFacet';\nfunction untilAborted<T>(work: Promise<T>, signal: AbortSignal): Promise<T> {\n if (signal.aborted) return Promise.reject(signal.reason);\n return new Promise<T>((resolveWork, rejectWork) => {\n const onAbort = (): void => rejectWork(signal.reason);\n signal.addEventListener('abort', onAbort, { once: true });\n work.then(resolveWork, rejectWork).finally(() => signal.removeEventListener('abort', onAbort));\n });\n}\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 disposed = false;\n let runProvider: RunProviderHandle | undefined;\n let narration: DoomNarrationService | undefined;\n let readiness: DoomReadinessCoordinator | undefined;\n let ownedReadiness: DoomReadinessCoordinator | undefined;\n let ready: DoomReadinessHandle<void> | undefined;\n const generation = randomUUID();\n const startupAbort = new AbortController();\n const sessionStartedAt = Date.now();\n let narrationReady = false;\n let previousStages = new Map<string, 'running' | 'completed' | 'error'>();\n let activeRunCount = 0;\n let stepGatePending = false;\n let serviceContext: Context | undefined;\n const runIdentity = ({ view }: ParsedWorkflowRun): string =>\n view.runId ?? `${view.workspace}/${view.runKey}/${view.startedAt}`;\n type CompletionBatch = {\n identities: string[];\n outcomes: string[];\n quiet: boolean;\n requestId: string;\n message: { type: string; text: string; display: true; details: Record<string, unknown> };\n attempts: number;\n };\n const pendingCompletions = new Map<string, { run: ParsedWorkflowRun; attempts: number; batched?: boolean }>();\n // Like the Pi owner, one delivery posts quiet runs together and admits loud runs together, frozen across retries.\n const completionBatches: CompletionBatch[] = [];\n const deliveredCompletions = new Set<string>();\n let delivery: Promise<void> | undefined;\n let deliveryRetry: ReturnType<typeof setTimeout> | undefined;\n const catalogDeps = defaultCatalogDeps();\n const catalogReader = createWorkflowCatalogReader(catalogDeps);\n const telemetry = createDoomTelemetry({\n serviceName: 'doom-workflow',\n packageName: SOURCE,\n cwd: host.context.cwd,\n env: host.context.environment,\n enableLogs: true,\n enableTraces: true,\n });\n /** True when this session was created to own one workflow run for the session that launched it. */\n const workflowSession = isWorkflowSession(host.context);\n const communication = serverHost.context.sessionCommunication;\n const lifecycle = workflowSession\n ? createWorkflowSessionLifecycle({\n parentSessionId: host.context.sessionContext?.parentSessionId,\n publishActivity: (activity) => serverHost.context.publishActivity?.(activity),\n postNotice: async (notice) => {\n // The same entry the notification provider appends in a web session: a notice, never a turn.\n const data = createDoomNotificationEntryData({ title: notice.title, body: notice.body, level: notice.level });\n if (data !== undefined) await host.context.session.appendCustomEntry(DOOM_NOTIFICATION_ENTRY_TYPE, data);\n },\n isIdle: async () => {\n const activity = await host.context.session.activity();\n return activity.isIdle && !activity.hasPendingMessages;\n },\n ...(communication === undefined\n ? {}\n : {\n requestRelease: (parent: string, runKeys: readonly string[]) =>\n communication.publish(parent, WORKFLOW_SESSION_RELEASE_TYPE, { runKeys }),\n onPeerReady: (listener: (peer: string) => void) => communication.onPeerReady(listener),\n }),\n })\n : undefined;\n const reportLifecycleFailure = (error: unknown): void => {\n void telemetry.recordWarning('doom_workflow.session_lifecycle_failed', error);\n };\n /** This session's runs, published to its panel and counted as its background work. */\n const publishRuns = (executionContext: typeof host.context): boolean => {\n const records = readWorkflowRuns({ environment: executionContext.environment }).filter(\n (run) =>\n runBelongsToSession(run, executionContext.sessionId) || runLaunchedBySession(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 activeRunCount = activeItems.length;\n const nextStages = new Map<string, 'running' | 'completed' | 'error'>();\n for (const record of records) {\n const { view } = record;\n const identity = runIdentity(record);\n const previous = previousStages.get(identity);\n nextStages.set(identity, view.stage);\n if (view.stage === 'error' && previous !== 'error' && runLaunchedBySession(record, executionContext.sessionId)) {\n void Promise.resolve(\n executionContext.client.notify({\n body: `Workflow \"${view.displayName}\" failed: ${view.errorMessage ?? 'no cause recorded'}. Diagnose it in its workflow-owner session.`,\n level: 'error',\n }),\n ).catch(reportLifecycleFailure);\n }\n if (\n !dispatcher &&\n view.stage !== 'running' &&\n !(view.stage === 'error' && runLaunchedBySession(record, host.context.sessionId)) &&\n !deliveredCompletions.has(identity) &&\n (previous === 'running' || (previous === undefined && Date.parse(view.startedAt) >= sessionStartedAt))\n ) {\n if (!pendingCompletions.has(identity)) pendingCompletions.set(identity, { run: record, attempts: 0 });\n }\n if (\n narrationReady &&\n !disposed &&\n narration !== undefined &&\n runBelongsToSession(record, executionContext.sessionId)\n ) {\n const startedAt = Date.parse(view.startedAt);\n narrateWorkflowTransition(\n {\n narrate(text) {\n const request = createNarrationRequest(text);\n if (request === undefined || narration === undefined) return;\n try {\n void Promise.resolve(narration.request(request)).catch((error: unknown) =>\n telemetry.recordWarning('doom_workflow.narration_failed', error),\n );\n } catch (error) {\n void telemetry.recordWarning('doom_workflow.narration_failed', error);\n }\n },\n },\n view,\n previous,\n previous === undefined && (!Number.isFinite(startedAt) || startedAt >= sessionStartedAt),\n );\n }\n }\n previousStages = nextStages;\n const retained = new Map(activeItems.map((item) => [item.id, item]));\n for (const { run } of pendingCompletions.values()) {\n const id = `${run.view.workspace}/${run.view.runKey}`;\n retained.set(id, { id, sessionId: executionContext.sessionId });\n }\n runProvider?.update([...retained.values()]);\n const runs = presentWorkflowRuns(\n records.map((run) => run.view),\n Date.now(),\n );\n if (disposed) return false;\n directEvents.publish(WORKFLOW_RUNS_TYPE, executionContext.sessionId, { runs });\n lifecycle?.observe(runs).catch(reportLifecycleFailure);\n return retained.size > 0;\n };\n /** Retain terminal work until its batch is durably posted or, when loud, admitted. */\n const deliverCompletions = (automatic = false): Promise<void> => {\n if (disposed || delivery !== undefined) return delivery ?? Promise.resolve();\n delivery = (async () => {\n const prepared: {\n identity: string;\n record: Awaited<ReturnType<typeof feature.registry.listRuns>>[number];\n text: string;\n }[] = [];\n for (const [identity, pending] of pendingCompletions) {\n if (disposed) return;\n if (pending.batched || (automatic && pending.attempts >= 5)) continue;\n try {\n const view = pending.run.view;\n const records = await feature.registry.listRuns(view.workspace);\n if (disposed) return;\n const record = records.find(\n (candidate) =>\n candidate.runKey === view.runKey &&\n candidate.stage === view.stage &&\n (view.runId !== undefined ? candidate.runId === view.runId : candidate.startedAt === view.startedAt),\n );\n if (record === undefined) throw new Error(`Completion record is unavailable: ${identity}`);\n const events =\n record.stage === 'completed' ? [] : await readWorkflowProgress(feature.registry.runDirectoryFor(record));\n if (disposed) return;\n const startedAt = Date.parse(record.startedAt);\n const jobs = summarizeWorkflowProgress(\n events.filter(\n (event) =>\n !Number.isFinite(startedAt) ||\n !Number.isFinite(Date.parse(event.at)) ||\n Date.parse(event.at) >= startedAt,\n ),\n );\n const summary = finishedRunSummary(record, jobs);\n const text = isLaunchedRun(record, host.context.sessionId)\n ? `${summary}\\n${launchedRunHint(record)}`\n : summary;\n prepared.push({ identity, record, text });\n } catch (error) {\n if (disposed) return;\n pending.attempts += 1;\n await telemetry.recordError('doom_workflow.terminal_delivery_failed', error, {\n 'workflow.pending_terminal_count': pendingCompletions.size,\n });\n }\n }\n for (const quiet of [true, false]) {\n const members = prepared.filter(\n ({ record }) => (isOwnedDelegatedRun(record, host.context.sessionId) && record.stage !== 'error') === quiet,\n );\n if (members.length === 0) continue;\n for (const { identity } of members) pendingCompletions.get(identity)!.batched = true;\n completionBatches.push({\n identities: members.map(({ identity }) => identity),\n outcomes: members.map(({ record }) => record.stage),\n quiet,\n requestId: `workflow-finished:${generation}:${members.map(({ identity }) => identity).join(',')}`,\n message: {\n type: 'workflow-run-finished',\n text: members.map(({ text }) => text).join('\\n\\n'),\n display: true,\n details: {\n runIds: members.map(({ identity, record }) => record.runId ?? identity),\n runs: members.map(({ record }) => ({\n runKey: record.runKey,\n workspace: record.workspace,\n stage: record.stage,\n ...(record.workflowId ? { workflowId: record.workflowId } : {}),\n ...(record.failedJob ? { failedJob: record.failedJob } : {}),\n ...(record.errorMessage ? { error: record.errorMessage } : {}),\n })),\n },\n },\n attempts: 0,\n });\n }\n for (const batch of completionBatches.slice()) {\n if (disposed) return;\n if (automatic && batch.attempts >= 5) continue;\n try {\n if (batch.quiet) {\n if (host.context.session.appendMessage === undefined)\n throw new Error('Workflow completion requires informational message support.');\n await host.context.session.appendMessage(batch.message);\n } else {\n if (host.context.session.admitMessage === undefined)\n throw new Error('Workflow completion requires custom message admission support.');\n await host.context.session.admitMessage(batch.message, 'steer', batch.requestId);\n }\n if (disposed) return;\n completionBatches.splice(completionBatches.indexOf(batch), 1);\n for (const identity of batch.identities) {\n deliveredCompletions.add(identity);\n pendingCompletions.delete(identity);\n }\n for (const outcome of batch.outcomes) void telemetry.recordEvent('doom_workflow.run_transition', { outcome });\n publishRuns(host.context);\n } catch (error) {\n if (disposed) return;\n batch.attempts += 1;\n await telemetry.recordError('doom_workflow.terminal_delivery_failed', error, {\n 'workflow.pending_terminal_count': pendingCompletions.size,\n });\n }\n }\n })().finally(() => {\n delivery = undefined;\n // Bounded automatic attempts, retained work can be retried on the next lifecycle event.\n if (\n !disposed &&\n ([...pendingCompletions.values()].some((pending) => !pending.batched && pending.attempts < 5) ||\n completionBatches.some((batch) => batch.attempts < 5)) &&\n deliveryRetry === undefined\n ) {\n deliveryRetry = setTimeout(() => {\n deliveryRetry = undefined;\n void deliverCompletions(true);\n }, 1_000);\n deliveryRetry.unref?.();\n }\n });\n return delivery;\n };\n /** The workflows this session can launch. Runs moving on do not change them, so their events skip this. */\n const publishCatalog = async (executionContext: typeof host.context): Promise<void> => {\n try {\n const workflows = presentWorkflowCatalog(await catalogReader.read(executionContext.cwd));\n if (disposed) return;\n directEvents.publish(WORKFLOW_CATALOG_TYPE, executionContext.sessionId, {\n cwd: executionContext.cwd,\n workflows,\n });\n } catch (error) {\n if (disposed) return;\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 publishLifecycle = async (executionContext: typeof host.context): Promise<boolean> => {\n publishRuns(executionContext);\n await deliverCompletions();\n await publishCatalog(executionContext);\n return activeRunCount > 0 || pendingCompletions.size > 0;\n };\n let runsTimer: ReturnType<typeof setTimeout> | undefined;\n let runsAfter: ((active: boolean) => void) | undefined;\n /** Publishes the runs once for a burst of job and step events, which a fix loop can produce by the dozen. */\n const publishRunsSoon = (executionContext: typeof host.context, after?: (active: boolean) => void): void => {\n if (disposed) return;\n if (after !== undefined) runsAfter = after;\n if (runsTimer !== undefined) return;\n runsTimer = setTimeout(() => {\n runsTimer = undefined;\n const done = runsAfter;\n runsAfter = undefined;\n try {\n publishRuns(executionContext);\n void deliverCompletions().then(() => done?.(activeRunCount > 0 || pendingCompletions.size > 0));\n } catch (error) {\n void telemetry.recordWarning('doom_workflow.publish_failed', error);\n }\n }, RUNS_PUBLISH_DEBOUNCE_MS);\n runsTimer.unref?.();\n };\n // Steps run in this process: customRun as child sessions of this one, commands in their own panes.\n const sessionService = serverHost.context.sessionService;\n const featureOptions =\n sessionService === undefined\n ? {}\n : {\n stepExecutor: createStepExecutor({\n sessionService,\n parentSessionId: host.context.sessionId,\n hostEnvironment: process.env,\n launchPane: createNativeStepPaneLauncher(undefined, telemetry),\n createId: () => `workflow-${randomUUID()}`,\n telemetry,\n }),\n };\n const feature = createEmbeddedWorkflowFeature(featureOptions);\n type LaunchParameters = Parameters<typeof feature.runTool.execute>[0];\n const launcher = createServerLauncher({\n feature,\n // Each replay owns its recovery service while sharing the registry and host step executor.\n createRecoverTool: (options) =>\n createEmbeddedWorkflowFeature({ ...featureOptions, registry: feature.registry }).createRecoverTool(options),\n sessionId: host.context.sessionId,\n environment: host.context.environment,\n telemetry,\n notify: (body, level) => host.context.client.notify({ body: body.slice(0, NOTICE_BODY_LIMIT), level }),\n onRunsChanged: () => publishRunsSoon(host.context),\n });\n /**\n * Why this session cannot run a launch, or undefined when it can.\n *\n * The checks the slash command makes through the catalog, made for every\n * launch whatever asked for it: the launch tool, another session, or the\n * browser. The workflow must be a file in the repository the launch comes\n * from, a worktree's own when it runs in one, and its runner, command,\n * choice, inputs and prompt must be ones it declares.\n */\n const refuseLaunch = (input: WorkflowLaunchInput, where: LaunchLocation): string | undefined => {\n if (typeof input.workflowPath !== 'string' || input.workflowPath === '') return 'A launch needs a workflowPath.';\n const workflowPath = resolve(where.cwd, input.workflowPath);\n const inside = relative(where.repoRoot, workflowPath);\n if (inside.startsWith('..') || isAbsolute(inside)) {\n return `Workflow ${input.workflowPath} is outside this session's repository, so it cannot be launched here.`;\n }\n const detail = catalogDeps.summarize(workflowPath);\n if (detail.error !== undefined) return needsFixingNotice(inside, detail.error);\n const problems = validateWorkflowLaunch(detail, {\n inputs: input.inputs ?? {},\n ...(input.prompt === undefined ? {} : { prompt: input.prompt }),\n ...((input.runner ?? input.cliAgent) === undefined ? {} : { runner: input.runner ?? input.cliAgent }),\n ...(input.command === undefined ? {} : { command: input.command }),\n ...(input.choice === undefined ? {} : { choice: input.choice }),\n });\n return problems.length === 0 ? undefined : problems.join('\\n');\n };\n /**\n * Run a workflow in this process and answer once it has registered.\n *\n * The launch goes through the same executor the Pi extension uses; see\n * `createServerLauncher` for what the server adds around it.\n */\n const launchHere = async (\n parameters: LaunchParameters,\n where: LaunchLocation = host.context,\n ): Promise<LaunchResult> => {\n let input: WorkflowLaunchInput;\n try {\n input = feature.runTool.getInputSchema().parse(parameters);\n } catch (error) {\n return textResult(`Error: ${errorMessage(error)}`, true);\n }\n const refusal = refuseLaunch(input, where);\n if (refusal !== undefined) return textResult(`Error: ${refusal}`, true);\n try {\n return launchResultOf(await launcher.launch({ ...input, workflowPath: resolve(where.cwd, input.workflowPath) }));\n } catch (error) {\n return textResult(`Error: ${errorMessage(error)}`, true);\n }\n };\n /**\n * Hand a launch to the session that owns this session's runs, through that\n * session's own mount of this package's API. The owner runs it, so the run\n * and its step sessions outlive this session, as a dispatcher's launches must.\n */\n const launchIn = async (owner: string, parameters: LaunchParameters): Promise<LaunchResult> => {\n if (serverHost.context.requestApi === undefined) {\n return textResult(`Error: this host cannot reach session ${owner} to launch the workflow there.`, true);\n }\n const response = await serverHost.context.requestApi(\n { scope: 'session', sessionId: owner },\n WORKFLOW_API_BASE_PATH,\n new Request(`${IN_PROCESS_ORIGIN}${routes.launch.path}`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(parameters),\n }),\n );\n const body: unknown = await response.json().catch((error: unknown) => ({ error: String(error) }));\n if (response.ok && isLaunchResponse(body)) return textResult(body.text, body.isError === true);\n const reason = errorOf(body) ?? `HTTP ${String(response.status)}`;\n return textResult(`Error: session ${owner} did not launch the workflow (${reason}).`, true);\n };\n /**\n * A workflow dispatcher launches for its root session, the way a CLI\n * dispatcher child does: the same markers name it, and the root runs what\n * it launches. Any other session runs its own launches.\n */\n const dispatcher = isWorkflowDispatcherProcess(host.context.environment);\n const launchOwner = (): string | undefined => {\n if (!dispatcher) return undefined;\n const parent = resolveDispatcherParentSession(host.context.environment);\n if (parent === undefined) return undefined;\n const owner = resolveRootSessionId(parent, host.context.environment);\n return owner === host.context.sessionId ? undefined : owner;\n };\n /** Sessions this one is creating to hand launches to; they count toward its capacity before their runs register. */\n let creatingWorkflowSessions = 0;\n /** A host that can create a session and reach its API, for a session that is not itself a workflow session. */\n const canHandOff = (): boolean =>\n !workflowSession && sessionService !== undefined && serverHost.context.requestApi !== undefined;\n /**\n * Create a workflow session under this one and hand it the launch, so the\n * run, its step sessions and its owner agent live there, nested under this\n * session in the rail. The launch is checked here first: a refused launch\n * creates nothing.\n */\n const launchInWorkflowSession = async (\n parameters: LaunchParameters,\n where: LaunchLocation = host.context,\n ): Promise<LaunchResult> => {\n let input: WorkflowLaunchInput;\n try {\n input = feature.runTool.getInputSchema().parse(parameters);\n } catch (error) {\n return textResult(`Error: ${errorMessage(error)}`, true);\n }\n const refusal = refuseLaunch(input, where);\n if (refusal !== undefined) return textResult(`Error: ${refusal}`, true);\n const self = host.context.sessionId;\n const running = readWorkflowRuns({ environment: host.context.environment }).filter(\n (run) =>\n run.view.stage === 'running' &&\n run.view.stale !== true &&\n (runBelongsToSession(run, self) || runLaunchedBySession(run, self)),\n ).length;\n const ceiling = resolveMaxConcurrent(host.context.environment);\n if (running + creatingWorkflowSessions >= ceiling) {\n return textResult(\n `Error: This session is at capacity: ${String(running + creatingWorkflowSessions)}/${String(ceiling)} workflows running.`,\n true,\n );\n }\n const workflowPath = resolve(where.cwd, input.workflowPath);\n creatingWorkflowSessions += 1;\n let child: string | undefined;\n try {\n const entry = (await catalogReader.read(where.cwd)).find((candidate) => candidate.path === workflowPath);\n const name = workflowSessionName(workflowPath, entry?.name);\n const config = poTemplateRunConfigSchema.parse(feature.parser.parseWorkflowFile(workflowPath).runConfig ?? {});\n if (config.majorMode === undefined) throw new Error('Delegated workflows require top-level runConfig.majorMode.');\n const selection = sessionSelection(config);\n // No environment: nothing of this session's is copied, and no root-session marker moves ownership back here.\n const scope = await sessionService!.create({\n cwd: where.cwd,\n name,\n parentSessionId: self,\n sessionProvenance: WORKFLOW_SESSION_PROVENANCE,\n selection: {\n ...selection,\n minorModes: [...(selection.minorModes ?? []).filter((mode) => mode !== WORKFLOW_MODE_ID), WORKFLOW_MODE_ID],\n },\n });\n child = scope.sessionId;\n const result = await launchIn(child, {\n ...parameters,\n workflowPath,\n env: { ...input.env, [WORKFLOW_LAUNCHER_SESSION_ENV]: self },\n } as LaunchParameters);\n if (result.isError === true) {\n await sessionService!.close(child).catch(reportLifecycleFailure);\n return result;\n }\n const text = result.content.map((item) => item.text).join('\\n');\n return textResult(\n `${text}\\nRuns in workflow session \"${name}\" (${child}), nested under this session. Failures notify you here without waking this agent. Its owner diagnoses failures locally, but recovers only on request; delegate to its owner with intercom send to \"${child}\".`,\n );\n } catch (error) {\n if (child !== undefined) await sessionService!.close(child).catch(reportLifecycleFailure);\n return textResult(`Error: ${errorMessage(error)}`, true);\n } finally {\n creatingWorkflowSessions -= 1;\n }\n };\n const launch = async (parameters: LaunchParameters, where?: LaunchLocation): Promise<LaunchResult> => {\n const owner = launchOwner();\n if (owner !== undefined) return launchIn(owner, parameters);\n return canHandOff() ? launchInWorkflowSession(parameters, where) : launchHere(parameters, where);\n };\n /**\n * A launch another session handed this one. A hand-off from a launcher\n * carries its stamp and runs here; any other, such as a dispatcher's, goes\n * through the same routing as a launch made here.\n */\n const launchFromApi = async (parameters: Record<string, unknown>): Promise<WorkflowLaunchResponse> => {\n const env = parameters.env;\n const handedOff =\n typeof env === 'object' &&\n env !== null &&\n typeof (env as Record<string, unknown>)[WORKFLOW_LAUNCHER_SESSION_ENV] === 'string';\n const result = handedOff\n ? await launchHere(parameters as LaunchParameters)\n : await launch(parameters as LaunchParameters);\n // No tool call ends here to refresh the panel, so publish the new run now.\n publishRunsSoon(host.context);\n return {\n text: result.content.map((item) => item.text).join('\\n'),\n ...(result.isError === true ? { isError: true } : {}),\n };\n };\n /**\n * A workflow session asks to be released after an untouched success. Only\n * the hub-attached source is trusted, and the registry, not the message,\n * decides: every run it owns succeeded and one was launched from here.\n */\n const releaseWorkflowSession = async (source: string): Promise<void> => {\n if (sessionService?.release === undefined) return;\n const owned = readWorkflowRuns({ environment: host.context.environment }).filter((run) =>\n runBelongsToSession(run, source),\n );\n const succeeded = (run: ParsedWorkflowRun): boolean =>\n run.view.stage === 'completed' &&\n (run.view.outcome === undefined || run.view.outcome === 'success' || run.view.outcome === 'skipped');\n if (owned.length === 0 || !owned.every(succeeded)) return;\n if (!owned.some((run) => runLaunchedBySession(run, host.context.sessionId))) return;\n await sessionService.release(source);\n void telemetry.recordEvent('doom_workflow.session_released', { outcome: 'released' });\n };\n const stopReleaseRequests = communication?.subscribe(WORKFLOW_SESSION_RELEASE_TYPE, (source) => {\n releaseWorkflowSession(source).catch(reportLifecycleFailure);\n });\n // A session hears its children only once it has said it is ready to.\n const stopPeerReady = communication?.onPeerReady(() => undefined);\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?.snapshot().state === 'failed' ? 'failed' : '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 (ready?.snapshot().state !== 'ready') await waitForReadiness(execution.signal);\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 let startingControl: Promise<NonNullable<typeof control>> | undefined;\n const startControl = (executionContext: typeof host.context): Promise<NonNullable<typeof control>> => {\n startingControl ??= (async () => {\n if (control !== undefined) {\n const ownedControl = control;\n await publishLifecycle(executionContext);\n return ownedControl;\n }\n if (disposed) throw new Error('Workflow runtime is disposed.');\n control = feature.createRunControl({\n recordFilter: (record) =>\n isSessionRun(record, host.context.sessionId) || isLaunchedRun(record, host.context.sessionId),\n });\n const ownedControl = control;\n const refresh = (): void => {\n publishRunsSoon(executionContext, (active) => {\n if (!active && !modeSelected() && control === ownedControl) disposeControl();\n });\n };\n // Job and step transitions live only in the progress log. A step's execution\n // ref, which tells the web view to show an agent session instead of a\n // terminal, lands there after the step started, with no run record change.\n controlDisposers = [\n ownedControl.on('runStarted', refresh),\n ownedControl.on('runUpdated', refresh),\n ownedControl.on('runFinished', refresh),\n ownedControl.on('job', refresh),\n ownedControl.on('step', refresh),\n ];\n try {\n await ownedControl.start();\n if (disposed || control !== ownedControl) throw new Error('Workflow observer was superseded.');\n await publishLifecycle(executionContext);\n return ownedControl;\n } catch (error) {\n if (control === ownedControl) disposeControl();\n throw error;\n }\n })().finally(() => {\n startingControl = undefined;\n });\n return startingControl;\n };\n const waitForReadiness = async (signal?: AbortSignal): Promise<void> => {\n signal?.throwIfAborted();\n if (disposed) throw new Error('Workflow runtime is disposed.');\n if (ready === undefined) throw new Error('Workflow session initialization has not started.');\n await ready.wait(signal === undefined ? undefined : { signal });\n if (disposed) throw new Error('Workflow runtime is disposed.');\n };\n return {\n api: [\n createWorkflowApi(async (parameters) => {\n await waitForReadiness();\n return launchFromApi(parameters);\n }),\n ],\n async onStart() {\n readiness ??= ownedReadiness = createDoomReadinessCoordinator({\n notify: (notice) => {\n void host.context.client.notify({\n body: `${SOURCE} initialization ${notice.state}: ${notice.error?.message ?? notice.diagnostics.join('; ')}`,\n level: 'warning',\n });\n },\n });\n ready = readiness.start(SOURCE, generation, async (signal) => {\n signal.throwIfAborted();\n await untilAborted(startControl(host.context), AbortSignal.any([signal, startupAbort.signal]));\n signal.throwIfAborted();\n if (disposed) throw new Error('Workflow runtime is disposed.');\n narrationReady = true;\n return { value: undefined };\n });\n await Promise.allSettled([ready.wait()]);\n modeOwner?.publish();\n },\n services: [\n (context) => {\n readiness = readDoomReadinessCoordinator(context);\n context.inject([DOOM_NARRATION_SERVICE], (serviceContext) => {\n const service = requireDoomNarrationService(serviceContext);\n narration = service;\n return () => {\n if (narration === service) narration = undefined;\n };\n });\n },\n serverMinorModes([modeOwner]),\n (context) => {\n serviceContext = context;\n const provider = registerRunProvider(context);\n runProvider = provider;\n return () => {\n provider.dispose();\n if (serviceContext === context) serviceContext = undefined;\n if (runProvider === provider) runProvider = undefined;\n };\n },\n ],\n hooks: [\n {\n event: 'tool_execution_end',\n handle: async (_event, executionContext) => {\n await publishLifecycle(executionContext);\n },\n },\n {\n event: 'session_shutdown',\n handle: disposeControl,\n },\n // Routed by position (hook/*.server.ts): new hooks go at the end.\n {\n event: 'session_start',\n handle: async () => {\n // A woken workflow session comes back without the modes it was created with.\n if ((workflowSession || dispatcher || host.context.environment.WORKFLOW_MCP_MODE === 'on') && !modeSelected())\n await selectMode(true);\n },\n },\n {\n event: 'agent_start',\n handle: () => {\n lifecycle?.agentStarted();\n },\n },\n {\n event: 'agent_settled',\n handle: async (_event, execution) => {\n const environment = execution.environment;\n if (\n disposed ||\n stepGatePending ||\n !environment[WORKFLOW_DECISION_FILE_ENV] ||\n environment[WORKFLOW_DECISION_STEERING_ENV] === WORKFLOW_DECISION_STEERING_HOST ||\n environment.PI_SUBAGENT_CHILD\n )\n return;\n stepGatePending = true;\n try {\n const activity = await execution.session.activity();\n if (disposed || !activity.isIdle || activity.hasPendingMessages) return;\n const snapshot =\n serviceContext === undefined\n ? undefined\n : readDoomBackgroundWorkService(serviceContext)?.snapshot(execution.sessionId);\n if (\n snapshot === undefined ||\n snapshot.items.some(holdsSettledSession) ||\n snapshot.errors.some((error) => BACKGROUND_WORK_HOLDING_PROVIDERS.includes(error.provider))\n )\n return;\n const gate = await gateStepDecision(environment);\n if (disposed || gate.action !== 'block') return;\n if (execution.session.admitPrompt === undefined)\n throw new Error('This host cannot admit workflow reminders.');\n await execution.session.admitPrompt(gate.message, 'steer');\n } finally {\n stepGatePending = false;\n }\n },\n },\n ],\n resources: [\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: 'po-author-workflow',\n kind: 'skill',\n read: () => skill('po-author-workflow'),\n },\n {\n when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: 'po-use-workflow',\n kind: 'skill',\n read: () => skill('po-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 when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: 'workflow-session',\n kind: 'context',\n // Live state: rebuilt from the registry on every turn, so it survives a wake and never goes stale.\n read: (executionContext) =>\n workflowSession\n ? workflowSessionBrief(\n presentWorkflowRuns(\n readWorkflowRuns({ environment: executionContext.environment })\n .filter((run) => runBelongsToSession(run, executionContext.sessionId))\n .map((run) => run.view),\n Date.now(),\n ),\n )\n : '',\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 const ownedControl = await startControl(executionContext);\n return stopFor(ownedControl);\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 in this repository, not existing runs.',\n promptGuidelines: ['Use list_workflows to discover definitions, not to find an existing run.'],\n parameters: z.toJSONSchema(feature.listWorkflowsTool.getInputSchema()),\n executionMode: 'serial',\n async execute(_toolCallId, parameters, signal, _onUpdate, context) {\n signal?.throwIfAborted();\n await waitForReadiness(signal);\n const input = parameters as Parameters<typeof feature.listWorkflowsTool.execute>[0];\n return callResult(\n await feature.listWorkflowsTool.execute({\n ...input,\n directory:\n input?.directory === undefined\n ? context.cwd\n : typeof input.directory === 'string'\n ? resolve(context.cwd, input.directory)\n : input.directory,\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:\n 'Start a workflow run. Prefer in-process Pi execution with command: \"pi\" when supported; runner: \"codex\" is not an alias for it. A successful launch is not a completed workflow.',\n promptGuidelines: [\n 'Before launching, inspect the workflow and its imports for commands and interactiveRun choices. Prefer a supported Pi template with inProcess: true, selected explicitly with command: \"pi\" (or a supported in-process \"pi-claude\" command when requested). Only use an external CLI when the user requests it or no in-process option exists.',\n 'command selects the exact template. Without it, runner only matches an exact command name; otherwise each step uses its first command. runner: \"codex\" does not imply command: \"pi\", so pass command explicitly to avoid switching to \"claude\" on later steps.',\n 'Launch returns when a run starts, not when it finishes. Use the exact run key and separate workspace from its launch result for workflow_run status, not Agiflow project or job identifiers.',\n 'Do not relaunch a healthy running workflow merely because it has not completed.',\n ],\n parameters: z.toJSONSchema(feature.runTool.getInputSchema()),\n executionMode: 'serial',\n async execute(_toolCallId, parameters, signal, _onUpdate, context) {\n signal?.throwIfAborted();\n await waitForReadiness(signal);\n const input = parameters as Parameters<typeof feature.runTool.execute>[0];\n return callResult(\n await launch(\n {\n ...input,\n ...(typeof input.workflowPath === 'string'\n ? { workflowPath: resolve(context.cwd, input.workflowPath) }\n : {}),\n },\n context,\n ),\n );\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:\n 'Inspect a session-owned workflow by exact run key and separate workspace, or request cooperative control.',\n promptGuidelines: [\n 'Use workflow_run status for the recorded stage, outcome, position, jobs, and steps. A successful status lookup is not evidence that the workflow completed.',\n 'For a healthy running workflow, summarize the recorded progress. Do not automatically search CLI commands or filesystem logs, relaunch, or diagnose failure merely because it remains running.',\n 'Investigate further when the run reports failure or staleness, or when the user requests diagnostics. Only status, pause, resume, and stop are supported here; stop only on user request.',\n 'Use exact registry runKey and separate workspace from the launch or status result. Agiflow project and job identifiers are not workflow run keys.',\n ],\n parameters: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['status', 'pause', 'resume', 'stop'] },\n runKey: {\n type: 'string',\n minLength: 1,\n description:\n 'Exact registry run key from the launch result, without the workspace prefix. Not an Agiflow job ID.',\n },\n workspace: {\n type: 'string',\n description: 'Workspace from the launch result, passed separately from runKey.',\n },\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 await waitForReadiness(signal);\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) || runLaunchedBySession(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 ? 'No matching workflow run was found in this session. This is a lookup failure, not evidence that the workflow failed. Use the exact runKey and separate workspace from its launch result, not Agiflow job identifiers.'\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 (!runBelongsToSession(runs[0]!, host.context.sessionId)) {\n return callResult({\n error: `This run belongs to workflow session ${run.ownerSessionId ?? 'unknown'}; pause, resume or stop it there.`,\n });\n }\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 when: { state: { 'minor-mode': WORKFLOW_MODE_ID }, attribution: { kind: 'minor', mode: WORKFLOW_MODE_ID } },\n name: WORKFLOW_TOOLS_TOOL_NAME,\n label: 'Workflow Tools',\n description:\n \"Workflow actions beyond workflow_run: recovery-evidence reads a failed run's durable evidence, including one an earlier session launched; recover resumes it from its active repair in this session.\",\n promptGuidelines: [\n 'Load workflow-recovery and read recovery-evidence before recover; recover is not a fresh launch.',\n 'A recover answer means the replay started, not that it succeeded; verify with workflow_run status.',\n 'Already claimed means another recovery won: do not retry or launch fresh. Never edit issue.md or repair.json.',\n ],\n parameters: z.toJSONSchema(workflowToolsInputSchema),\n executionMode: 'serial',\n async execute(_toolCallId, parameters, signal) {\n try {\n signal?.throwIfAborted();\n await waitForReadiness(signal);\n const input = workflowToolsInputSchema.parse(parameters);\n const matches = (await feature.registry.listRuns(input.workspace)).filter(\n (record) => record.runKey === input.runKey && record.stage === 'error',\n );\n if (matches.length > 1)\n throw new Error('Run key exists in more than one workspace; retry with its workspace.');\n const record = matches[0];\n if (!record)\n throw new Error(\n 'No failed workflow run matches this key; do not recover a running or completed workflow.',\n );\n const owner = record.env?.PI_SESSION_ID;\n if (\n input.action === 'recover' &&\n owner !== undefined &&\n owner !== host.context.sessionId &&\n sessionService?.isLive(owner) === true\n ) {\n throw new Error(`Run ${record.runKey} belongs to live workflow session ${owner}; recover it there.`);\n }\n if (input.action === 'recover')\n return launchResultOf(\n await launcher.recover(\n { runKey: record.runKey, workspace: record.workspace },\n { dryRun: input.dryRun, runner: input.runner },\n ),\n );\n void telemetry.recordEvent('doom_workflow.recovery_evidence_requested', { outcome: 'requested' });\n // ponytail: mirrors the TUI evidence tail; extract if a third caller appears.\n const sections: string[] = [];\n for (const name of ['changelog.md', 'context.md', 'progress.ndjson']) {\n try {\n const bytes = await readFile(join(feature.registry.runDirectoryFor(record), name));\n sections.push(`--- ${name} ---\\n${bytes.subarray(-64 * 1024).toString('utf8')}`);\n } catch (error) {\n if (!(error instanceof Error && 'code' in error && error.code === 'ENOENT')) throw error;\n }\n }\n const text = `Workflow: ${record.displayName} (${record.runKey})\\n${sections.length ? '' : 'No durable evidence files found.\\n'}--- run.json ---\\n${JSON.stringify(record, null, 2)}${sections.length ? '\\n' + sections.join('\\n') : ''}`;\n return { content: [{ type: 'text', text }] };\n } catch (error) {\n return {\n content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }],\n isError: true,\n };\n }\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 try {\n const entry = resolveWorkflowEntry(await catalogReader.read(execution.cwd), parsed.workflow);\n if (!entry || entry.error) {\n await execution.client.notify({\n body: entry?.error\n ? needsFixingNotice(entry.name, entry.error)\n : `Workflow not found: ${parsed.workflow}`,\n level: 'error',\n });\n return;\n }\n const problems = validateWorkflowLaunch(entry, parsed);\n if (problems.length > 0) {\n await execution.client.notify({ body: problems.join('\\n'), level: 'error' });\n return;\n }\n const result = callResult(\n await launch(\n {\n workflowPath: entry.path,\n ...(parsed.runner === undefined ? {} : { runner: parsed.runner }),\n ...(parsed.command === undefined ? {} : { command: parsed.command }),\n ...(parsed.choice === undefined ? {} : { choice: parsed.choice }),\n ...(Object.keys(parsed.inputs).length === 0 ? {} : { inputs: parsed.inputs }),\n ...(parsed.prompt === undefined ? {} : { prompt: parsed.prompt }),\n },\n execution,\n ),\n );\n const rendered = result.content.find((item) => item.type === 'text');\n await execution.client.notify({\n body: rendered?.type === 'text' ? rendered.text : 'Workflow launch requested.',\n level: result.isError ? 'error' : 'info',\n });\n } catch (error) {\n await execution.client.notify({ body: String(error), level: 'error' });\n }\n },\n },\n ],\n // A dispatcher launches for its root and never works a run itself, as a CLI dispatcher child.\n ...(dispatcher ? { toolRestrictions: [{ excludedTools: [RUN_TOOL, WORKFLOW_TOOLS_TOOL_NAME] }] } : {}),\n async onDispose() {\n disposed = true;\n startupAbort.abort();\n if (deliveryRetry !== undefined) clearTimeout(deliveryRetry);\n deliveryRetry = undefined;\n pendingCompletions.clear();\n narrationReady = false;\n narration = undefined;\n await ownedReadiness?.dispose();\n disposeControl();\n lifecycle?.dispose();\n stopReleaseRequests?.();\n stopPeerReady?.();\n if (runsTimer !== undefined) clearTimeout(runsTimer);\n runsTimer = undefined;\n runsAfter = undefined;\n // Runs this session is running stop with it, rather than going on under a parent that is gone.\n await launcher.dispose();\n runProvider?.dispose();\n runProvider = undefined;\n await telemetry.shutdown();\n },\n };\n}\n","import type { DoomServerPluginDefinition } from '@agimon-ai/po-core/serverFacet';\n\nimport { createWorkflowServerRuntime } from '../../../../../services/serverRuntime';\nimport { api } from '../../../../../services/workflowHubApi';\n\n// A session with an agent mounts the API with its runtime, which can launch into this session.\nexport default (({ agent, host }) =>\n agent ? createWorkflowServerRuntime(agent, host) : { api: [api] }) satisfies NonNullable<\n DoomServerPluginDefinition['session']\n>;\n","import { defineRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport runtime from './_lib/index.server';\n\nexport default defineRoot((context: Parameters<typeof runtime>[0]) => {\n const value = runtime(context);\n return {\n value,\n services: value.services,\n activities: value.activities,\n onStart: value.onStart,\n onStop: value.onStop,\n onDispose: value.onDispose,\n };\n});\n","import type { DoomHubChannelSource, DoomHubSessionScope, DoomHubChannel } from '@agimon-ai/po-core/hubChannel';\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","import type { DoomHubChannelSource, DoomHubSessionScope, DoomHubChannel } from '@agimon-ai/po-core/hubChannel';\n\nimport {\n presentWorkflowRuns,\n runBelongsToSession,\n runLaunchedBySession,\n type ParsedWorkflowRun,\n} from '../../services/workflowRuns';\nimport { readWorkflowRuns, type ReadWorkflowRunsOptions } from '../../services/workflowWatcher';\nimport { WORKFLOW_RUNS_TYPE, type WorkflowRunView, type WorkflowRunsPayload } from '../../types/webWorkflows';\n\nexport interface WorkflowsChannelOptions {\n /** Injectable durable initial snapshot reader for tests. */\n read?: (options: ReadWorkflowRunsOptions) => ParsedWorkflowRun[];\n}\n\nfunction isWorkflowRunsPayload(value: unknown): value is WorkflowRunsPayload {\n return typeof value === 'object' && value !== null && Array.isArray((value as { runs?: unknown }).runs);\n}\n\n/**\n * The workflow runs data channel. Durable registry state seeds each session\n * once; subsequent updates arrive through the host-owned direct event bus.\n *\n * A session sees the runs it owns and, beside them, the runs it handed to its\n * own workflow sessions, so its Activity rows can open each one. Those come\n * from the owners' updates, routed here by the launcher stamp on each run, and\n * from the registry for workflow sessions that are no longer live.\n */\nexport function createWorkflowsChannel(options: WorkflowsChannelOptions = {}): DoomHubChannel {\n const read = options.read ?? readWorkflowRuns;\n return {\n frameType: WORKFLOW_RUNS_TYPE,\n start(host) {\n const scopes = new Map<string, DoomHubSessionScope>();\n const latest = new Map<string, WorkflowRunsPayload>();\n const subscriptions = new Map<string, () => void>();\n /** Each session's own runs, as it last reported them. */\n const own = new Map<string, readonly WorkflowRunView[]>();\n /** Launcher, then owning workflow session, then the runs one handed the other. */\n const delegated = new Map<string, Map<string, readonly WorkflowRunView[]>>();\n\n const publish = (sessionId: string): void => {\n if (!scopes.has(sessionId)) return;\n const handed = [...(delegated.get(sessionId)?.values() ?? [])].flat();\n const payload = { runs: presentWorkflowRuns([...(own.get(sessionId) ?? []), ...handed], Date.now()) };\n latest.set(sessionId, payload);\n host.publish(sessionId, payload);\n };\n\n /** Hands an owner's update to every session that launched one of its runs, or did until now. */\n const routeToLaunchers = (owner: string, runs: readonly WorkflowRunView[]): void => {\n const launchers = new Set<string>();\n for (const run of runs) {\n if (run.launcherSessionId !== undefined && run.launcherSessionId !== owner)\n launchers.add(run.launcherSessionId);\n }\n for (const [launcher, byOwner] of delegated) if (byOwner.has(owner)) launchers.add(launcher);\n for (const launcher of launchers) {\n if (!scopes.has(launcher)) continue;\n const mine = runs.filter((run) => run.launcherSessionId === launcher);\n const byOwner = delegated.get(launcher) ?? new Map<string, readonly WorkflowRunView[]>();\n delegated.set(launcher, byOwner);\n if (mine.length === 0) byOwner.delete(owner);\n else byOwner.set(owner, mine);\n publish(launcher);\n }\n };\n\n const source: DoomHubChannelSource = {\n payloadFor(scope) {\n return scopes.has(scope.sessionId) ? latest.get(scope.sessionId) : undefined;\n },\n sessionAdded(scope) {\n const sessionId = scope.sessionId;\n scopes.set(sessionId, scope);\n const parsed = read({ environment: scope.environment });\n own.set(\n sessionId,\n parsed.filter((run) => runBelongsToSession(run, sessionId)).map((run) => run.view),\n );\n // Workflow sessions that were released or closed still list their runs here.\n const byOwner = new Map<string, WorkflowRunView[]>();\n for (const run of parsed) {\n if (!runLaunchedBySession(run, sessionId) || run.piSessionId === undefined) continue;\n byOwner.set(run.piSessionId, [...(byOwner.get(run.piSessionId) ?? []), run.view]);\n }\n delegated.set(sessionId, byOwner);\n subscriptions.get(sessionId)?.();\n const unsubscribe = host.directEvents.subscribe(\n WORKFLOW_RUNS_TYPE,\n sessionId,\n (value) => {\n if (!isWorkflowRunsPayload(value)) return;\n own.set(sessionId, value.runs);\n publish(sessionId);\n routeToLaunchers(sessionId, value.runs);\n },\n { replayLatest: true },\n );\n subscriptions.set(sessionId, unsubscribe);\n publish(sessionId);\n },\n sessionRemoved(sessionId) {\n subscriptions.get(sessionId)?.();\n subscriptions.delete(sessionId);\n scopes.delete(sessionId);\n latest.delete(sessionId);\n own.delete(sessionId);\n // Its slices in its launchers stay: a released workflow session's rows persist there.\n delegated.delete(sessionId);\n },\n close() {\n for (const unsubscribe of subscriptions.values()) unsubscribe();\n subscriptions.clear();\n scopes.clear();\n latest.clear();\n own.clear();\n delegated.clear();\n },\n };\n return source;\n },\n };\n}\n","import type { DoomServerPluginDefinition } from '@agimon-ai/po-core/serverFacet';\n\nimport { createWorkflowCatalogChannel } from '../../../services/workflowCatalogChannel';\nimport { api } from '../../../services/workflowHubApi';\nimport { createWorkflowsChannel } from '../../../services/workflowsHubChannel';\n\nexport default (({ host }) =>\n host.scope === 'session'\n ? {}\n : { channels: [createWorkflowsChannel, createWorkflowCatalogChannel], api: [api] }) satisfies NonNullable<\n DoomServerPluginDefinition['global']\n>;\n","import { defineRoutedContribution } from '@agimon-ai/po-core/extensionFile';\n\nimport legacy from '../../_lib/index.server';\n\nexport default defineRoutedContribution((context: Parameters<typeof legacy>[0]) => legacy(context).api?.[0], {\n cardinality: 'optional',\n});\n","import { defineChannel } from '@agimon-ai/po-core/extensionFile';\n\nimport { createWorkflowCatalogChannel } from '../../../services/workflowCatalogChannel';\n\nexport default defineChannel(createWorkflowCatalogChannel);\n","import { defineChannel } from '@agimon-ai/po-core/extensionFile';\n\nimport { createWorkflowsChannel } from '../../../services/workflowsHubChannel';\n\nexport default defineChannel(createWorkflowsChannel);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport runtime from '../../_lib/index.server';\n\nexport default defineRoutedContribution(\n (context: WithRoot<unknown, ReturnType<typeof runtime>>) => context.root.api?.[0],\n { cardinality: 'optional' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport runtime from '../_lib/index.server';\n\nexport default defineRoutedContribution(\n (context: WithRoot<unknown, ReturnType<typeof runtime>>) => context.root.commands?.[0],\n { cardinality: 'optional' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport runtime from '../_lib/index.server';\n\nexport default defineRoutedContribution(\n (context: WithRoot<unknown, ReturnType<typeof runtime>>) => context.root.hooks?.[4],\n { cardinality: 'optional' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport runtime from '../_lib/index.server';\n\nexport default defineRoutedContribution(\n (context: WithRoot<unknown, ReturnType<typeof runtime>>) => context.root.hooks?.[3],\n { cardinality: 'optional' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport runtime from '../_lib/index.server';\n\nexport default defineRoutedContribution(\n (context: WithRoot<unknown, ReturnType<typeof runtime>>) => context.root.hooks?.[1],\n { cardinality: 'optional' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport runtime from '../_lib/index.server';\n\nexport default defineRoutedContribution(\n (context: WithRoot<unknown, ReturnType<typeof runtime>>) => context.root.hooks?.[2],\n { cardinality: 'optional' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport runtime from '../_lib/index.server';\n\nexport default defineRoutedContribution(\n (context: WithRoot<unknown, ReturnType<typeof runtime>>) => context.root.hooks?.[0],\n { cardinality: 'optional' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport runtime from '../_lib/index.server';\n\nexport default defineRoutedContribution(\n (context: WithRoot<unknown, ReturnType<typeof runtime>>) => context.root.resources?.[0],\n { cardinality: 'optional' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport runtime from '../_lib/index.server';\n\nexport default defineRoutedContribution(\n (context: WithRoot<unknown, ReturnType<typeof runtime>>) => context.root.resources?.[1],\n { cardinality: 'optional' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport runtime from '../_lib/index.server';\n\nexport default defineRoutedContribution(\n (context: WithRoot<unknown, ReturnType<typeof runtime>>) => context.root.resources?.[2],\n { cardinality: 'optional' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport runtime from '../_lib/index.server';\n\nexport default defineRoutedContribution(\n (context: WithRoot<unknown, ReturnType<typeof runtime>>) => context.root.resources?.[3],\n { cardinality: 'optional' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport runtime from '../_lib/index.server';\n\ntype Restriction = NonNullable<WithRoot<unknown, ReturnType<typeof runtime>>['root']['toolRestrictions']>[number];\n\nexport default defineRoutedContribution(\n (context: WithRoot<unknown, ReturnType<typeof runtime>>): Restriction | undefined =>\n context.root.toolRestrictions?.[0],\n { cardinality: 'optional' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport runtime from '../_lib/index.server';\n\nexport default defineRoutedContribution(\n (context: WithRoot<unknown, ReturnType<typeof runtime>>) => context.root.tools?.[1],\n { cardinality: 'optional' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport runtime from '../_lib/index.server';\n\nexport default defineRoutedContribution(\n (context: WithRoot<unknown, ReturnType<typeof runtime>>) => context.root.tools?.[0],\n { cardinality: 'optional' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport runtime from '../_lib/index.server';\n\nexport default defineRoutedContribution(\n (context: WithRoot<unknown, ReturnType<typeof runtime>>) => context.root.tools?.[2],\n { cardinality: 'optional' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport runtime from '../_lib/index.server';\n\nexport default defineRoutedContribution(\n (context: WithRoot<unknown, ReturnType<typeof runtime>>) => context.root.tools?.[3],\n { cardinality: 'optional' },\n);\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/po-core/serverFacet';\nimport { composeServerProviderOverrides } from '@agimon-ai/po-core/serverFacet';\nimport { composeRootHooks } from '@agimon-ai/po-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport apiRoute from '../src/extensions/(backend)/api/workflow/route.server';\nimport channelWorkflowCatalog from '../src/extensions/(backend)/channel/workflow-catalog.server';\nimport channelWorkflows from '../src/extensions/(backend)/channel/workflows.server';\nimport apiRoute2 from '../src/extensions/workspaces/sessions/(backend)/api/workflow/route.server';\nimport commandWorkflowLaunch from '../src/extensions/workspaces/sessions/(backend)/command/workflow-launch.server';\nimport hookAgentSettled from '../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.server';\nimport hookAgentStart from '../src/extensions/workspaces/sessions/(backend)/hook/agent-start.server';\nimport hookSessionShutdown from '../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server';\nimport hookSessionStart from '../src/extensions/workspaces/sessions/(backend)/hook/session-start.server';\nimport hookToolExecutionEnd from '../src/extensions/workspaces/sessions/(backend)/hook/tool-execution-end.server';\nimport resourcePoAuthorWorkflow from '../src/extensions/workspaces/sessions/(backend)/resource/po-author-workflow.server';\nimport resourcePoUseWorkflow from '../src/extensions/workspaces/sessions/(backend)/resource/po-use-workflow.server';\nimport resourceWorkflowRecovery from '../src/extensions/workspaces/sessions/(backend)/resource/workflow-recovery.server';\nimport resourceWorkflowSession from '../src/extensions/workspaces/sessions/(backend)/resource/workflow-session.server';\nimport toolRestrictionDispatcher from '../src/extensions/workspaces/sessions/(backend)/tool-restriction/dispatcher.server';\nimport toolLaunchWorkflow from '../src/extensions/workspaces/sessions/(backend)/tool/launch-workflow.server';\nimport toolListWorkflows from '../src/extensions/workspaces/sessions/(backend)/tool/list-workflows.server';\nimport toolWorkflowRun from '../src/extensions/workspaces/sessions/(backend)/tool/workflow-run.server';\nimport toolWorkflowTools from '../src/extensions/workspaces/sessions/(backend)/tool/workflow-tools.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\n/* v8 ignore next -- generated normalization branch */\nconst defined = <T>(values: readonly (T | undefined)[]): T[] =>\n values.filter((value): value is T => value !== undefined);\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const facet = defineServerPlugin({\n name: '@agimon-ai/po-workflow',\n providerOverrides: composeServerProviderOverrides(rootSession),\n global: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return defined([at(apiRoute, context)]); },\n get channels(): DoomServerSessionPlugin['channels'] { return [() => via({ frameType: 'workflow_catalog' }, channelWorkflowCatalog()), () => via({ frameType: 'workflows' }, channelWorkflows())]; },\n }),\n workspace: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return defined([at(apiRoute, context)]); },\n get channels(): DoomServerSessionPlugin['channels'] { return [() => via({ frameType: 'workflow_catalog' }, channelWorkflowCatalog()), () => via({ frameType: 'workflows' }, channelWorkflows())]; },\n }),\n session: async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get api(): DoomServerSessionPlugin['api'] { return defined([at(apiRoute, context), at(apiRoute2, contextSession)]); },\n get channels(): DoomServerSessionPlugin['channels'] { return [() => via({ frameType: 'workflow_catalog' }, channelWorkflowCatalog()), () => via({ frameType: 'workflows' }, channelWorkflows())]; },\n get commands(): DoomServerSessionPlugin['commands'] { return defined([via({ name: 'workflow-launch' }, at(commandWorkflowLaunch, contextSession))]); },\n get hooks(): DoomServerSessionPlugin['hooks'] { return defined([via({ event: 'agent_settled' }, at(hookAgentSettled, contextSession)), via({ event: 'agent_start' }, at(hookAgentStart, contextSession)), via({ event: 'session_shutdown' }, at(hookSessionShutdown, contextSession)), via({ event: 'session_start' }, at(hookSessionStart, contextSession)), via({ event: 'tool_execution_end' }, at(hookToolExecutionEnd, contextSession))]); },\n get resources(): DoomServerSessionPlugin['resources'] { return defined([at(resourcePoAuthorWorkflow, contextSession), at(resourcePoUseWorkflow, contextSession), at(resourceWorkflowRecovery, contextSession), at(resourceWorkflowSession, contextSession)]); },\n get toolRestrictions(): DoomServerSessionPlugin['toolRestrictions'] { return defined([at(toolRestrictionDispatcher, contextSession)]); },\n get tools(): DoomServerSessionPlugin['tools'] { return defined([via({ name: 'launch_workflow' }, at(toolLaunchWorkflow, contextSession)), via({ name: 'list_workflows' }, at(toolListWorkflows, contextSession)), via({ name: 'workflow_run' }, at(toolWorkflowRun, contextSession)), via({ name: 'workflow_tools' }, at(toolWorkflowTools, contextSession))]); },\n services: [...(scopeSession.services ?? [])],\n get activities(): DoomServerSessionPlugin['activities'] { return [...(scopeSession.activities ?? [])]; },\n };\n },\n});\n\nexport default facet;\n"],"mappings":"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"}