@particle-academy/fancy-flow 0.74.1 → 0.75.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.
Files changed (41) hide show
  1. package/dist/{chunk-2GU3V2ZD.js → chunk-2H5H2DDP.js} +4 -4
  2. package/dist/{chunk-2GU3V2ZD.js.map → chunk-2H5H2DDP.js.map} +1 -1
  3. package/dist/{chunk-3RXQGYGH.js → chunk-4BPCA3ZO.js} +3 -3
  4. package/dist/{chunk-3RXQGYGH.js.map → chunk-4BPCA3ZO.js.map} +1 -1
  5. package/dist/{chunk-K7KO3UJ3.js → chunk-LKEDPVR3.js} +3 -3
  6. package/dist/{chunk-K7KO3UJ3.js.map → chunk-LKEDPVR3.js.map} +1 -1
  7. package/dist/{chunk-7DJ56PUA.js → chunk-T7E7QPHI.js} +4 -4
  8. package/dist/{chunk-7DJ56PUA.js.map → chunk-T7E7QPHI.js.map} +1 -1
  9. package/dist/{chunk-EX34GCKK.js → chunk-W7DMO3H7.js} +18 -6
  10. package/dist/chunk-W7DMO3H7.js.map +1 -0
  11. package/dist/{chunk-VAF2SWTC.js → chunk-XZFLPKO2.js} +3 -3
  12. package/dist/{chunk-VAF2SWTC.js.map → chunk-XZFLPKO2.js.map} +1 -1
  13. package/dist/{chunk-GQ5LEA7Q.js → chunk-ZBHIEKCN.js} +3 -3
  14. package/dist/{chunk-GQ5LEA7Q.js.map → chunk-ZBHIEKCN.js.map} +1 -1
  15. package/dist/durable.cjs +16 -4
  16. package/dist/durable.cjs.map +1 -1
  17. package/dist/durable.js +1 -1
  18. package/dist/engine.cjs +16 -4
  19. package/dist/engine.cjs.map +1 -1
  20. package/dist/engine.js +4 -4
  21. package/dist/index.cjs +16 -4
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.js +12 -12
  24. package/dist/registry.cjs +16 -4
  25. package/dist/registry.cjs.map +1 -1
  26. package/dist/registry.js +2 -2
  27. package/dist/runtime.cjs +16 -4
  28. package/dist/runtime.cjs.map +1 -1
  29. package/dist/runtime.js +3 -3
  30. package/dist/schema.cjs +16 -4
  31. package/dist/schema.cjs.map +1 -1
  32. package/dist/schema.js +3 -3
  33. package/dist/screens.cjs +16 -4
  34. package/dist/screens.cjs.map +1 -1
  35. package/dist/screens.js +4 -4
  36. package/dist/ux.cjs +17 -5
  37. package/dist/ux.cjs.map +1 -1
  38. package/dist/ux.js +2 -2
  39. package/dist/ux.js.map +1 -1
  40. package/package.json +2 -2
  41. package/dist/chunk-EX34GCKK.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/FlowEditor/human-fields.ts","../src/registry/capabilities.ts","../src/registry/llm-router.ts","../src/registry/ports.ts","../src/runtime/run-identity.ts","../src/runtime/terminal-transcript.ts","../src/runtime/terminal-sessions.ts","../src/expressions/variables.ts","../src/runtime/undelivered-edges.ts","../src/runtime/workflow-props.ts","../src/runtime/run-flow.ts","../src/registry/subflow.ts","../src/expressions/expr.ts","../src/registry/logic.ts","../src/registry/terminal-nodes.ts","../src/registry/builtin-kinds.ts","../src/registry/registry.ts","../src/analysis/graph-connectivity.ts","../src/schema/workflow-schema.ts"],"names":["resolve","text","configOf"],"mappings":"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","file":"schema.cjs","sourcesContent":["/**\n * The field vocabulary a `user_input` node declares, and the normalizer that\n * turns whatever was actually written into something renderable.\n *\n * ## Why this is a separate module from `HumanPrompt.tsx`\n *\n * `src/registry/builtin.ts` needs `humanFieldType` for the `user_input` kind's\n * `outputShape`, and `builtin.ts` is in the import graph of the `/engine`\n * entry — the one `tests/core-nodes.test.ts` guards as React-free so a queue\n * worker or a CLI can register kinds without dragging React in. Importing the\n * modal's `.tsx` from there put a React module on that path and left the guard\n * standing only because treeshaking happened to drop it.\n *\n * Pure functions over plain data, in a `.ts` file, so the headless path cannot\n * regress on a future edit to the component.\n */\n\n/**\n * The control a field renders as, after {@link humanInputFields} has resolved\n * whatever the author, a peer runtime or an agent actually wrote.\n *\n * These are the CANONICAL names. The vocabulary an author may write is wider —\n * see {@link HUMAN_FIELD_TYPE_ALIASES} — because a `fields` array arrives from\n * three places (the config panel, a hand-written workflow JSON, and the PHP /\n * Python runtimes) and each has its own habits for spelling \"boolean\".\n */\nexport type HumanFieldType =\n | \"text\"\n | \"textarea\"\n | \"number\"\n | \"select\"\n | \"switch\"\n | \"date\"\n | \"datetime\"\n | \"time\"\n | \"email\"\n | \"url\"\n | \"tel\"\n | \"password\";\n\n/** One choice in a `select` field, after normalization. */\nexport type HumanFieldOption = { value: string; label: string };\n\n/** A field the input modal renders. Mirrors a `user_input` `fields` row. */\nexport type HumanField = {\n key: string;\n label?: string;\n type?: HumanFieldType;\n required?: boolean;\n placeholder?: string;\n options?: HumanFieldOption[];\n default?: unknown;\n};\n\n/**\n * Every spelling of a field type this accepts, mapped onto its canonical\n * control.\n *\n * The bug this table exists to fix: the old normalizer accepted exactly five\n * literal names and coerced everything else to `text`, so `boolean`, `date`,\n * `email` and `enum` — the words a person reaches for first, and the words the\n * peer runtimes' own docs use — all arrived at the form as a plain text box.\n * The person then typed a date into a text field and the run resumed with a\n * string where a date was declared, which nothing downstream could detect.\n *\n * Aliases rather than a stricter schema because the declaration is DATA. It is\n * written by hand and emitted by agents, and rejecting `boolean` on a spelling\n * technicality would be a worse failure than accepting it.\n */\nexport const HUMAN_FIELD_TYPE_ALIASES: Readonly<Record<string, HumanFieldType>> = {\n text: \"text\",\n string: \"text\",\n str: \"text\",\n input: \"text\",\n\n textarea: \"textarea\",\n long_text: \"textarea\",\n longtext: \"textarea\",\n \"long-text\": \"textarea\",\n multiline: \"textarea\",\n paragraph: \"textarea\",\n markdown: \"textarea\",\n\n number: \"number\",\n numeric: \"number\",\n integer: \"number\",\n int: \"number\",\n float: \"number\",\n decimal: \"number\",\n\n select: \"select\",\n enum: \"select\",\n choice: \"select\",\n choices: \"select\",\n dropdown: \"select\",\n options: \"select\",\n radio: \"select\",\n\n switch: \"switch\",\n bool: \"switch\",\n boolean: \"switch\",\n checkbox: \"switch\",\n toggle: \"switch\",\n\n date: \"date\",\n\n datetime: \"datetime\",\n \"datetime-local\": \"datetime\",\n datetimelocal: \"datetime\",\n timestamp: \"datetime\",\n\n time: \"time\",\n\n email: \"email\",\n \"e-mail\": \"email\",\n\n url: \"url\",\n uri: \"url\",\n link: \"url\",\n\n tel: \"tel\",\n phone: \"tel\",\n telephone: \"tel\",\n\n password: \"password\",\n secret: \"password\",\n};\n\n/**\n * Resolve a declared type name to a control.\n *\n * An unrecognised name becomes `text` — never a crash and never a dropped\n * field. A field the form refuses to render is a value the run will never\n * receive, which is strictly worse than rendering it as free text.\n */\nexport function humanFieldType(raw: unknown): HumanFieldType {\n if (typeof raw !== \"string\") return \"text\";\n return HUMAN_FIELD_TYPE_ALIASES[raw.trim().toLowerCase()] ?? \"text\";\n}\n\n/**\n * Normalize whatever an author wrote for a select's choices.\n *\n * Accepts the three shapes that actually turn up:\n *\n * - `[\"small\", \"large\"]` — bare strings, the shorthand `TextConfigField.choices`\n * already accepts elsewhere in this package.\n * - `[{ value: \"s\", label: \"Small\" }]` — the explicit form.\n * - `{ s: \"Small\", l: \"Large\" }` — what the config panel's `keyvalue` control\n * stores, which is how choices are authored on the `user_input` node.\n *\n * A missing `label` falls back to the value rather than rendering an empty\n * option — the old code read `o.label` off a bare string and put `undefined`\n * into both the value and the text, so a shorthand list rendered as a dropdown\n * of blank rows.\n */\nexport function humanFieldOptions(raw: unknown): HumanFieldOption[] | undefined {\n const entries: HumanFieldOption[] = [];\n\n if (Array.isArray(raw)) {\n for (const item of raw) {\n if (typeof item === \"string\" || typeof item === \"number\") {\n const value = String(item);\n if (value !== \"\") entries.push({ value, label: value });\n continue;\n }\n if (item && typeof item === \"object\") {\n const value = (item as { value?: unknown }).value;\n if (value === undefined || value === null || value === \"\") continue;\n const label = (item as { label?: unknown }).label;\n entries.push({\n value: String(value),\n label: typeof label === \"string\" && label !== \"\" ? label : String(value),\n });\n }\n }\n } else if (raw && typeof raw === \"object\") {\n for (const [value, label] of Object.entries(raw as Record<string, unknown>)) {\n if (value === \"\") continue;\n entries.push({ value, label: typeof label === \"string\" && label !== \"\" ? label : value });\n }\n }\n\n return entries.length ? entries : undefined;\n}\n\n/**\n * Normalize a `user_input` node's `fields` config into renderable fields. Falls\n * back to a single text field so even an unconfigured User Input node still\n * collects something rather than silently returning nothing.\n */\nexport function humanInputFields(config: Record<string, unknown>): HumanField[] {\n const raw = Array.isArray((config as any)?.fields) ? ((config as any).fields as any[]) : [];\n const fields: HumanField[] = raw\n .filter((f) => f && typeof f === \"object\" && typeof (f as any).key === \"string\" && (f as any).key)\n .map((f: any) => ({\n key: f.key,\n label: typeof f.label === \"string\" && f.label ? f.label : f.key,\n type: humanFieldType(f.type),\n required: !!f.required,\n placeholder: typeof f.placeholder === \"string\" ? f.placeholder : undefined,\n options: humanFieldOptions(f.options ?? f.choices),\n default: f.default,\n }));\n if (fields.length) return fields;\n const title = typeof (config as any)?.title === \"string\" && (config as any).title ? (config as any).title : \"Your answer\";\n return [{ key: \"value\", label: title, type: \"textarea\", required: true }];\n}\n\n","import type { FlowGraph } from \"../types\";\n\n/**\n * Host capabilities — the services core nodes need but must never depend on.\n *\n * A node that imports a provider SDK forces every consumer to install it: a\n * workflow app that never calls a model should not inherit an LLM dependency.\n * So core declares the CONTRACT and the host supplies the implementation, the\n * same arrangement `renderDocumentField` already uses for documents.\n *\n * That keeps opinionated nodes in core without their opinions: `llm_branch`\n * ships the routing semantics, port derivation and config UI, while whichever\n * client the host registers — Prism, an OpenAI SDK, a local model, a fake in a\n * test — decides how the question actually gets asked.\n *\n * Registration is deliberately explicit and typed per capability rather than a\n * stringly-keyed bag, so a missing one is a clear error at the seam instead of\n * an undefined somewhere downstream.\n */\n\n// ── LLM ─────────────────────────────────────────────────────────────────────\n\nexport type LlmRoute = { port: string; description?: string };\n\nexport type LlmRouteRequest = {\n /** Optional framing for the decision. */\n system?: string;\n /** What the model is deciding about. */\n prompt: string;\n /** The ports it must choose between. */\n routes: LlmRoute[];\n provider?: string;\n model?: string;\n /** Host-resolved credential reference, never a raw key. */\n credential?: string;\n};\n\nexport type LlmRouteChoice = {\n /** Must be one of the requested route ports. */\n port: string;\n /** Why — carried down the chosen port so a run is explainable afterwards. */\n reason?: string;\n};\n\n/**\n * The only thing core asks of an LLM: given routes, pick one.\n *\n * Deliberately not a general chat interface. A narrow contract is one a host\n * can satisfy in a few lines over any SDK, and it keeps the choice\n * machine-checkable — an implementation should constrain the model to the\n * declared ports (structured output / enum) rather than parsing prose.\n */\nexport type LlmClient = {\n chooseRoute: (request: LlmRouteRequest) => Promise<LlmRouteChoice> | LlmRouteChoice;\n};\n\nlet llmClient: LlmClient | null = null;\n\n/** Install the host's LLM client. Returns an unregister function. */\nexport function registerLlmClient(client: LlmClient): () => void {\n llmClient = client;\n return () => {\n if (llmClient === client) llmClient = null;\n };\n}\n\nexport function getLlmClient(): LlmClient | null {\n return llmClient;\n}\n\n// ── Terminal ────────────────────────────────────────────────────────────────\n\n/** What to launch. Omit `command` for the host's default shell. */\nexport type TerminalSessionSpec = {\n command?: string;\n args?: string[];\n cwd?: string;\n env?: Record<string, string>;\n cols?: number;\n rows?: number;\n};\n\nexport type TerminalExit = { exitCode: number; signal?: string };\n\n/**\n * One live terminal, owned by the host for as long as the run needs it.\n *\n * Output arrives by SUBSCRIPTION rather than a `read()` the engine calls. A TUI\n * emits continuously and on its own schedule — repainting, streaming a reply,\n * redrawing a spinner — so a polled read either misses bytes between calls or\n * has to buffer them anyway, and every host would invent that buffer\n * differently.\n */\nexport type TerminalSession = {\n id: string;\n write: (data: string) => void | Promise<void>;\n /** Subscribe to output. Returns an unsubscribe. */\n onData: (listener: (chunk: string) => void) => () => void;\n /**\n * Resolves when the process exits.\n *\n * A promise rather than an `exited` flag the engine polls, so \"the agent\n * quit\" and \"the agent has not answered yet\" are distinguishable while\n * waiting. Without it a node awaiting output cannot tell a slow reply from a\n * dead process, and waits out its timeout either way.\n */\n exited: Promise<TerminalExit>;\n close: () => void | Promise<void>;\n};\n\n/**\n * The only thing core asks of a terminal: open one.\n *\n * ## Why the contract stops at the PTY\n *\n * There is deliberately no `waitForOutput(pattern)` here, though every terminal\n * node needs one. Matching is derivable from `onData`, so putting it in the\n * contract would mean every host implements it — and two implementations of one\n * agreed rule is precisely how a week of registry defects happened: both sides\n * agreed output matching should work, and would have disagreed on whether a\n * pattern spans chunk boundaries, whether ANSI escapes are stripped first, and\n * what a timeout returns.\n *\n * So core owns the matching and the host owns the process. A host satisfies\n * this in a few lines over `node-pty`; nothing about how a run interprets the\n * bytes is up to it.\n *\n * ## Why this exists at all\n *\n * A terminal cannot live in the engine. `node-pty` is a native addon, so\n * importing it would break every browser build of this package and force the\n * dependency on consumers who never run a terminal node — the same reason the\n * LLM client is a contract rather than an SDK import. The desktop app that CAN\n * spawn a PTY registers one; everyone else never notices the capability exists.\n */\nexport type TerminalHost = {\n open: (spec: TerminalSessionSpec) => Promise<TerminalSession> | TerminalSession;\n};\n\nlet terminalHost: TerminalHost | null = null;\n\n/** Install the host's terminal. Returns an unregister function. */\nexport function registerTerminalHost(host: TerminalHost): () => void {\n terminalHost = host;\n return () => {\n if (terminalHost === host) terminalHost = null;\n };\n}\n\nexport function getTerminalHost(): TerminalHost | null {\n return terminalHost;\n}\n\n// ── Workflow resolution ─────────────────────────────────────────────────────\n\n/**\n * Why a workflow reference could not be resolved.\n *\n * `missing` and `version-mismatch` are deliberately distinct. Collapsing them\n * into a bare null makes \"no such workflow\" indistinguishable from \"that\n * workflow exists, but it is not the one you pinned\" — and the second wants an\n * error naming both versions, because it is the interesting failure.\n */\nexport type WorkflowResolutionFailure = {\n reason: \"missing\" | \"version-mismatch\";\n /** The version the host actually holds, when it holds one. */\n available?: number;\n message?: string;\n};\n\nexport type WorkflowResolution = FlowGraph | WorkflowResolutionFailure | null;\n\n/**\n * Resolve a workflow reference to a runnable graph.\n *\n * `subflow` names another workflow rather than embedding it, so the host owns\n * where workflows live — a database, a file, an API.\n *\n * ## Why `version` is here\n *\n * A workflow another workflow depends on is an INTERFACE, and interfaces need\n * pins. Without a version, a parent goes on calling `invoice-triage`, someone\n * edits that child, and the parent now runs different logic having reported\n * success the whole time — correct-looking, no error, wrong behaviour. The same\n * failure family as the 0.9.0 routing divergence.\n *\n * The parameter lives on the resolver rather than being encoded into the ref\n * string (`invoice-triage@3`) because a stringly-typed protocol is one every\n * host invents differently — the \"three vocabularies for one node\" problem.\n *\n * Raised by the MOIC Suite consumer, whose `workflow_ref` pins versions and\n * fails loudly on mismatch. Their point: a host COULD NOT implement pinning\n * before this, because the node had no way to ask and the resolver no way to\n * receive.\n *\n * Returning `null` still means \"no such workflow\". Return a\n * {@link WorkflowResolutionFailure} to distinguish a version mismatch.\n */\nexport type WorkflowResolver = (\n ref: string,\n version?: number,\n) => Promise<WorkflowResolution> | WorkflowResolution;\n\n/** Narrow a resolver's return value to an explicit failure. */\nexport function isResolutionFailure(value: WorkflowResolution): value is WorkflowResolutionFailure {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"reason\" in value &&\n (value as WorkflowResolutionFailure).reason !== undefined\n );\n}\n\nlet workflowResolver: WorkflowResolver | null = null;\n\n/** Install the host's workflow resolver. Returns an unregister function. */\nexport function registerWorkflowResolver(resolver: WorkflowResolver): () => void {\n workflowResolver = resolver;\n return () => {\n if (workflowResolver === resolver) workflowResolver = null;\n };\n}\n\nexport function getWorkflowResolver(): WorkflowResolver | null {\n return workflowResolver;\n}\n\n// ── Introspection ───────────────────────────────────────────────────────────\n\nexport type CapabilityId = \"llm\" | \"workflow_resolver\" | \"document\" | \"terminal\";\n\n/**\n * Which capabilities are currently satisfied.\n *\n * Exists so a host (or the CLI, or an agent over MCP) can answer \"what does\n * this graph need that I haven't wired?\" BEFORE a run fails halfway through.\n */\nexport function capabilityStatus(): Record<CapabilityId, boolean> {\n // Imported lazily to avoid dragging the React-dependent rich-input module\n // into the headless engine.\n let documentReady = false;\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires, no-undef\n documentReady = Boolean((globalThis as any).__fancyFlowDocumentAdapter);\n } catch {\n documentReady = false;\n }\n return {\n llm: llmClient !== null,\n workflow_resolver: workflowResolver !== null,\n document: documentReady,\n // Listed here for the reason this function exists at all. A graph with a\n // terminal lane and no host registered fails PART WAY THROUGH — after the\n // nodes before it have already run and possibly written somewhere — and the\n // whole point of asking up front is to learn that before starting. Leaving\n // it out would have made the one check designed to catch this report\n // all-clear for exactly the case it was built for.\n terminal: terminalHost !== null,\n };\n}\n","import { getLlmClient, type LlmRoute } from \"./capabilities\";\nimport type { NodeExecutor } from \"../types\";\n\n/**\n * `@fancy/llm_branch` — a SHUTTLE, not an engine.\n *\n * It carries the declared routes and the decision prompt out to whatever LLM\n * client the host registered, and carries the chosen port back down the graph.\n * It contains no provider SDK, no prompt engineering, no response parsing and\n * no retry policy — all of that belongs to the host's client, which is what\n * lets this node live in core without every consumer inheriting an LLM\n * dependency.\n *\n * The one thing it does own is graph integrity, because that is a workflow\n * concern rather than an AI one: a port the model invents must never route.\n */\n\n/** Read the node's declared routes out of config. */\nexport function declaredRoutes(config: Record<string, unknown>): LlmRoute[] {\n const raw = config.routes;\n if (!Array.isArray(raw)) return [];\n return raw\n .map((r) => ({ port: String((r as any)?.port ?? \"\").trim(), description: (r as any)?.description }))\n .filter((r) => r.port !== \"\");\n}\n\n/**\n * Where a run goes when the model returns a port that was never offered.\n *\n * Emitting on a port with no edge silently ends the branch — the worst failure\n * mode in a workflow engine, because the run reports success having done\n * nothing. So: the `fallback` port when it exists, else the first declared\n * route, and always loudly.\n */\nexport function resolveFallbackPort(routes: LlmRoute[], fallbackEnabled: boolean): string {\n if (fallbackEnabled) return \"fallback\";\n // Callers only reach this with at least one declared route (a node with none\n // aborts earlier), so there is always somewhere safe to land.\n return routes[0]?.port ?? \"out\";\n}\n\nexport const llmRouterExecutor: NodeExecutor = async (ctx) => {\n const config = ((ctx.node.data as any)?.config ?? {}) as Record<string, unknown>;\n const routes = declaredRoutes(config);\n\n if (routes.length === 0) {\n ctx.abort(\"llm_router has no routes configured\");\n }\n\n const client = getLlmClient();\n if (!client) {\n // Fail loudly rather than guessing a branch. A silent default here would\n // look like the model made a choice.\n ctx.abort(\n \"No LLM client registered. Call registerLlmClient() with your provider adapter — fancy-flow ships the routing, not the model call.\",\n );\n }\n\n const fallbackEnabled = config.fallback !== false;\n\n const choice = await client!.chooseRoute({\n system: typeof config.system === \"string\" ? config.system : undefined,\n prompt: String(config.prompt ?? ctx.inputs ?? \"\"),\n routes,\n provider: typeof config.provider === \"string\" ? config.provider : undefined,\n model: typeof config.model === \"string\" ? config.model : undefined,\n credential: typeof config.credential === \"string\" ? config.credential : undefined,\n });\n\n const offered = new Set(routes.map((r) => r.port));\n let port = choice?.port ?? \"\";\n let reason = choice?.reason;\n\n if (!offered.has(port)) {\n const safe = resolveFallbackPort(routes, fallbackEnabled);\n ctx.emit({\n type: \"log\",\n nodeId: ctx.node.id,\n level: \"warn\",\n message: `llm_router: model returned \"${port || \"(nothing)\"}\", which is not a declared route. Routing to \"${safe}\".`,\n });\n reason = reason ?? `unrecognised route \"${port}\"`;\n port = safe;\n }\n\n // The reason travels WITH the value, so a completed run explains itself\n // without needing the model call replayed.\n return { __port: port, value: { route: port, reason, input: ctx.inputs } };\n};\n","import type { FlowNode, PortDescriptor } from \"../types\";\nimport type { NodeKindDefinition, PortSpec } from \"./types\";\n\n/**\n * Port resolution — the single place a node's ports are derived, shared by\n * the canvas renderer and the headless runtime.\n *\n * This module is deliberately React-free: `runFlow` (the `/engine` entry)\n * imports it, and the engine bundle must stay free of React.\n *\n * ## Why this is centralized\n *\n * Ports used to be read in two places that disagreed — the canvas consulted\n * `data.outputs ?? kind.outputs`, while the runtime consulted `data.outputs`\n * ONLY and fell back to a single `out` port. A kind that declared branch ports\n * therefore drew correctly and then routed as if it had one output, unless the\n * host remembered to mirror the ports onto every node's `data`. Both callers\n * now go through `resolveNodePorts`, so declared ports and executed ports\n * cannot drift apart.\n */\n\n/**\n * Resolve a `PortSpec` against a config object.\n *\n * A config-driven spec is author-supplied and runs on every render, so a throw\n * is contained: it degrades to \"undeclared\" (letting the caller fall back)\n * rather than taking out the canvas or aborting a run mid-flight.\n */\nexport function resolvePortSpec<TConfig>(\n spec: PortSpec<TConfig> | undefined,\n config: TConfig,\n): PortDescriptor[] | undefined {\n if (spec === undefined) return undefined;\n if (typeof spec !== \"function\") return spec;\n try {\n const resolved = (spec as (c: TConfig) => PortDescriptor[])(config);\n return Array.isArray(resolved) ? resolved : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** Read the config bag off a node, tolerating the FlowNodeData union. */\nexport function nodeConfig(node: Pick<FlowNode, \"data\">): Record<string, unknown> {\n return ((node.data as any)?.config ?? {}) as Record<string, unknown>;\n}\n\n/**\n * Resolve a node's effective ports.\n *\n * Precedence: explicit `data.inputs`/`data.outputs` (a per-node host override)\n * beats the kind's declaration. `undefined` means \"nothing declared\" — the\n * caller applies its own category default.\n */\nexport function resolveNodePorts(\n node: Pick<FlowNode, \"data\">,\n kind?: Pick<NodeKindDefinition<any>, \"inputs\" | \"outputs\">,\n): { inputs?: PortDescriptor[]; outputs?: PortDescriptor[] } {\n const config = nodeConfig(node);\n const data = node.data as any;\n return {\n inputs: data?.inputs ?? resolvePortSpec(kind?.inputs, config),\n outputs: data?.outputs ?? resolvePortSpec(kind?.outputs, config),\n };\n}\n","/**\n * Who is running, which step this is, and how many times it has been tried.\n *\n * ## Why an engine needs this at all\n *\n * A node that WRITES to somebody else's system — charge a card, send a message,\n * open a pull request — can only survive a retry if the retry carries the same\n * idempotency key the first attempt did. Otherwise the provider treats the\n * second call as a new request and the customer is charged twice.\n *\n * Until this existed the executor context was `{ node, inputs, emit, abort }`,\n * which is not enough to derive one. Both obvious fallbacks are worse than\n * sending no key at all:\n *\n * - **the node id alone** is stable across retries, and also across RUNS — two\n * legitimate payments share a key and the provider silently collapses the\n * second into the first. A payment that never happened, reported as success;\n * - **a fresh random value** is unique per run, and also per ATTEMPT — a retry\n * creates a second charge, which is the thing being avoided.\n *\n * ## What actually identifies a step\n *\n * Not `(run, node)`. A node legitimately executes more than once inside one\n * run: once per subflow invocation, once per iteration of a loop an executor\n * drives itself. `(run, node)` would give every one of those the same key, and\n * a provider would honour exactly one of them.\n *\n * So a step is identified by the **path of invocations that led to it**, plus\n * an optional **occurrence** for repetition at the same level:\n *\n * ```text\n * runKey \":\" segment (\"/\" segment)* segment := escape(id) [\"#\" occurrence]\n * ```\n *\n * And the part that is easy to get backwards: **`attempt` is NOT in the key.**\n * It is carried here for logging and for {@link RunIdentity.isReplaySafe}, and\n * putting it in the key would restore the exact bug the key exists to prevent.\n *\n * Pinned cross-runtime by `shared/flow-run-identity` in\n * `@particle-academy/fancy-conformance`.\n */\n\n/** The wire shape — what a queue job payload carries. */\nexport type RunIdentityJson = {\n runKey: string;\n path?: string[];\n attempt?: number;\n firstAttemptAt?: string;\n};\n\n/**\n * Escape one segment so the composition is injective.\n *\n * `%` FIRST, or the escaping is not reversible: escaping `/` before `%` turns a\n * literal `a%2Fb` into the same text as the escaped form of `a/b`, which is the\n * collision this exists to prevent, reintroduced by its own fix.\n */\nexport function escapeSegment(value: string): string {\n // Not `replaceAll` — the package targets ES2020, and this must produce the\n // identical string on every runtime that reads the conformance table.\n return value.replace(/%/g, \"%25\").replace(/\\//g, \"%2F\").replace(/#/g, \"%23\");\n}\n\nfunction renderSegment(value: string, occurrence?: number | null): string {\n const escaped = escapeSegment(value);\n // `occurrence === 0` is a real occurrence. A truthiness check here silently\n // collapses iteration 0 into the un-iterated key.\n return occurrence === undefined || occurrence === null ? escaped : `${escaped}#${occurrence}`;\n}\n\nfunction instant(value: string): number {\n const ms = Date.parse(value);\n if (Number.isNaN(ms)) {\n throw new Error(\n `RunIdentity: firstAttemptAt is not a parseable timestamp: ${JSON.stringify(value)}`,\n );\n }\n return ms;\n}\n\n/**\n * A run, a position inside it, and how many times this position has been tried.\n *\n * Immutable. {@link descend} returns a new identity rather than mutating, so an\n * executor cannot change what its siblings see.\n */\nexport class RunIdentity {\n /** Stable for the whole run: same across retries, resumes, workers and hosts. */\n readonly runKey: string;\n\n /**\n * Enclosing invocation segments, outermost first, ALREADY RENDERED.\n *\n * Empty at the top level. A subflow pushes the invoking node's id; an\n * executor that loops pushes `id#i`.\n */\n readonly path: readonly string[];\n\n /**\n * 1-based attempt of THIS logical step. Never part of the key.\n *\n * The durable driver sets it from the node's claim row, which is exact. A\n * plain in-process `runFlow` gets whatever the host passed, which is\n * run-scoped and therefore conservative — see `isReplaySafe`.\n */\n readonly attempt: number;\n\n /** ISO-8601 UTC instant of attempt 1 of this step. */\n readonly firstAttemptAt: string;\n\n constructor(\n runKey: string,\n path: readonly string[] = [],\n attempt = 1,\n firstAttemptAt: string = new Date().toISOString(),\n ) {\n if (!runKey || runKey.trim() === \"\") {\n throw new Error(\"RunIdentity: runKey must be a non-empty string.\");\n }\n this.runKey = runKey;\n this.path = Object.freeze([...path]);\n this.attempt = Math.max(1, Math.trunc(attempt));\n this.firstAttemptAt = firstAttemptAt;\n Object.freeze(this);\n }\n\n /**\n * The identity of one execution of one node — stable across retries of that\n * execution, distinct from every other execution of the same node.\n *\n * Pass `occurrence` when an executor runs the same node more than once at the\n * same level (a loop body, one item of a fan-out it drives itself).\n */\n stepKey(nodeId: string, occurrence?: number | null): string {\n return `${this.runKey}:${[...this.path, renderSegment(nodeId, occurrence)].join(\"/\")}`;\n }\n\n /**\n * A child identity for work nested inside this step.\n *\n * `subflow` pushes the invoking node's id, so a node inside the child graph\n * cannot collide with a same-named node in the parent. Attempt and\n * `firstAttemptAt` are carried down unchanged: the nested work happens inside\n * this step's attempt, and shares its clock.\n */\n descend(segment: string, occurrence?: number | null): RunIdentity {\n return new RunIdentity(\n this.runKey,\n [...this.path, renderSegment(segment, occurrence)],\n this.attempt,\n this.firstAttemptAt,\n );\n }\n\n /** A copy on a different attempt, first-attempt clock preserved. */\n withAttempt(attempt: number, firstAttemptAt?: string): RunIdentity {\n return new RunIdentity(\n this.runKey,\n this.path,\n attempt,\n firstAttemptAt ?? this.firstAttemptAt,\n );\n }\n\n /**\n * May this attempt reuse the step key and still be deduplicated?\n *\n * Providers forget idempotency keys — Stripe after 24 hours. Past that\n * window, resending the key creates a second charge and sending a fresh one\n * creates a second charge, so **the caller must refuse rather than pick\n * between them**: a loud stuck run beats a silent double write.\n *\n * `true` on attempt 1 whatever the elapsed time — nothing was sent on an\n * earlier attempt, so there is nothing for the provider to have forgotten.\n * That is what lets a run park on a human gate for a week and then write.\n *\n * `windowSeconds: null` means the provider does not expire keys. `0` means\n * it does not dedupe at all, so no retry may reuse a key — it is a real\n * window, not an absent one, and the two must not be conflated: reading `0`\n * as `null` turns \"this provider does not dedupe\" into \"this provider\n * dedupes forever\", which is the more dangerous of the two by a distance.\n */\n isReplaySafe(windowSeconds: number | null | undefined, now: Date | string = new Date()): boolean {\n if (this.attempt <= 1) return true;\n if (windowSeconds === null || windowSeconds === undefined) return true;\n if (windowSeconds <= 0) return false;\n\n const nowMs = typeof now === \"string\" ? instant(now) : now.getTime();\n // Clock skew between two workers must not turn a legitimate retry into a\n // refusal, so a negative elapsed clamps to zero.\n const elapsedSeconds = Math.max(0, (nowMs - instant(this.firstAttemptAt)) / 1000);\n\n // Inclusive: a key written at T is remembered THROUGH T + window.\n return elapsedSeconds <= windowSeconds;\n }\n\n toJSON(): Required<RunIdentityJson> {\n return {\n runKey: this.runKey,\n path: [...this.path],\n attempt: this.attempt,\n firstAttemptAt: this.firstAttemptAt,\n };\n }\n\n /** Rebuild from a queue payload. */\n static from(value: RunIdentity | RunIdentityJson | string): RunIdentity {\n if (value instanceof RunIdentity) return value;\n if (typeof value === \"string\") return new RunIdentity(value);\n return new RunIdentity(\n value.runKey,\n value.path ?? [],\n value.attempt ?? 1,\n value.firstAttemptAt ?? new Date().toISOString(),\n );\n }\n}\n","/**\n * What a terminal has said, in a form a node can wait on.\n *\n * A raw `onData` stream is not something a workflow can match against, for\n * three reasons that all fail the same way — intermittently, and usually only\n * once there is real output moving:\n *\n * 1. **Chunks are arbitrary.** A PTY splits wherever it splits, so `Ready >`\n * can arrive as `Rea` + `dy >`. Testing each chunk on its own finds the\n * pattern when output is small enough to land in one write and misses it\n * when it is not. So matching runs against an ACCUMULATED buffer, never a\n * chunk.\n *\n * 2. **Output arrives before anyone is listening.** A node that types at a\n * process and a node that waits for its reply are two steps, and anything\n * printed between them is gone if the buffer starts when the wait does.\n * So the transcript is attached when the SESSION opens, and a wait reads\n * what has already accumulated before it subscribes to anything new.\n *\n * 3. **Escape sequences are everywhere and they also straddle.** An agent TUI\n * writes `Ready` as `ESC[32m Ready ESC[0m`, so matching raw bytes fails on\n * text a person can plainly read. Stripping per chunk reintroduces problem\n * 1 in a second guise — `ESC[3` + `2mReady` strips to `ESC[32mReady` with\n * the escape now INSIDE the text. So an incomplete trailing sequence is\n * held back until the rest of it arrives.\n *\n * Text is consumed through a match, so two waits for the same pattern do not\n * both resolve on the first occurrence — which would let a loop appear to make\n * progress while reading one old line forever.\n */\n\n/**\n * The control characters, by code point rather than as literals.\n *\n * A raw ESC byte sitting in a `.ts` file survives most tools and not all of\n * them, and the failure is the quiet kind: strip one out and the pattern below\n * still parses, still looks right in review, and matches nothing — so every\n * wait fails on coloured output while the code reads as correct. It happened\n * twice while this file was being written, which is the argument.\n */\nconst ESC = String.fromCharCode(0x1b);\nconst CSI = String.fromCharCode(0x9b);\nconst BEL = String.fromCharCode(0x07);\n\n/**\n * CSI (`ESC [ ... final`), OSC (`ESC ] ... BEL|ST`), and the two-character\n * escapes. Written out rather than taken from a dependency: it is a regex, and\n * the suite's rule is that third-party code is a liability carried for years.\n */\nconst ANSI = new RegExp(\n `[${ESC}${CSI}](?:\\\\[[0-?]*[ -/]*[@-~]|\\\\][^${BEL}${ESC}]*(?:${BEL}|${ESC}\\\\\\\\)|[@-Z\\\\\\\\-_])`,\n \"g\",\n);\n\n/**\n * How much unterminated escape to hold back before giving up on it.\n *\n * An OSC sequence carrying a window title is legitimately long, but a lone\n * `ESC` that never terminates is just a byte — holding the rest of the stream\n * hostage behind it would stall a wait forever, which is a worse failure than\n * one stray character in the output.\n */\nconst MAX_PENDING_ESCAPE = 1024;\n\n/**\n * Cap on retained text. A chatty process across a long run would otherwise grow\n * this without limit. Dropping from the FRONT keeps the recent output — which\n * is what a wait is about to match — and a pattern spanning a megabyte of\n * output is not a pattern anybody wrote.\n */\nconst MAX_BUFFER = 1_000_000;\n\nexport type TranscriptWaitResult =\n | { status: \"matched\"; text: string; match: RegExpMatchArray }\n | { status: \"timeout\"; text: string }\n | { status: \"exited\"; text: string; exitCode: number; signal?: string };\n\nexport class TerminalTranscript {\n /** Stripped, complete text not yet consumed by a wait. */\n private text = \"\";\n\n /** Raw bytes held back because they may be the start of an escape sequence. */\n private tail = \"\";\n\n private readonly waiters = new Set<() => void>();\n\n /** Feed raw terminal output in. Safe to call with any chunking. */\n append(chunk: string): void {\n this.tail += chunk;\n\n const safe = this.safeLength();\n if (safe > 0) {\n this.text += this.tail.slice(0, safe).replace(ANSI, \"\");\n this.tail = this.tail.slice(safe);\n }\n\n if (this.text.length > MAX_BUFFER) {\n this.text = this.text.slice(this.text.length - MAX_BUFFER);\n }\n\n for (const wake of [...this.waiters]) wake();\n }\n\n /**\n * How much of `tail` can be stripped now.\n *\n * Everything, unless the final `ESC` has not yet been terminated — in which\n * case processing stops there and resumes when the rest arrives.\n */\n private safeLength(): number {\n const lastEsc = Math.max(this.tail.lastIndexOf(ESC), this.tail.lastIndexOf(CSI));\n if (lastEsc === -1) return this.tail.length;\n\n // A complete sequence starting there means nothing is pending.\n ANSI.lastIndex = lastEsc;\n const match = ANSI.exec(this.tail);\n ANSI.lastIndex = 0;\n if (match && match.index === lastEsc) return this.tail.length;\n\n // Unterminated, but long enough that it is not really an escape.\n if (this.tail.length - lastEsc > MAX_PENDING_ESCAPE) return this.tail.length;\n\n return lastEsc;\n }\n\n /** Unconsumed output, escape sequences removed. */\n peek(): string {\n return this.text;\n }\n\n /** Drop everything currently buffered — used before typing a new command. */\n clear(): void {\n this.text = \"\";\n this.tail = \"\";\n }\n\n /**\n * Wait until `pattern` matches the unconsumed text.\n *\n * Checks what has ALREADY arrived before subscribing, because the common case\n * is that the process answered while the previous node was still finishing.\n *\n * `exited` is raced deliberately. Without it, a shell that dies reports as\n * \"timed out waiting for X\" — sending whoever reads it to lengthen a timeout\n * for a process that is not running. Naming the exit is the difference\n * between a diagnosis and a wrong lead.\n */\n waitFor(\n pattern: RegExp,\n options: { timeoutMs: number; exited?: Promise<{ exitCode: number; signal?: string }> },\n ): Promise<TranscriptWaitResult> {\n return new Promise<TranscriptWaitResult>((resolve) => {\n let settled = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const finish = (result: TranscriptWaitResult) => {\n if (settled) return;\n settled = true;\n this.waiters.delete(check);\n if (timer) clearTimeout(timer);\n resolve(result);\n };\n\n const check = () => {\n // A global or sticky pattern carries `lastIndex` between calls, so it\n // would start each attempt part-way through a buffer it has not read.\n pattern.lastIndex = 0;\n const match = pattern.exec(this.text);\n if (!match) return;\n\n // `|| 1` so a pattern that can match empty still makes progress rather\n // than consuming nothing and matching the same position forever.\n const through = match.index + (match[0].length || 1);\n const text = this.text.slice(0, through);\n this.text = this.text.slice(through);\n finish({ status: \"matched\", text, match });\n };\n\n this.waiters.add(check);\n check();\n if (settled) return;\n\n if (options.timeoutMs > 0) {\n timer = setTimeout(() => {\n const text = this.text;\n this.text = \"\";\n finish({ status: \"timeout\", text });\n }, options.timeoutMs);\n // Never hold a Node process open just to time out a wait nobody wants.\n (timer as unknown as { unref?: () => void }).unref?.();\n }\n\n options.exited?.then(\n (exit) => {\n // No re-check here, deliberately. `append` wakes every waiter the\n // instant data lands, so a process that prints its answer and then\n // exits has already matched by the time this runs — `settled` is\n // true and this returns. A re-check looked like it was guarding that\n // race and was in fact unreachable, which is worse than absent: it\n // read as a guarantee while the actual guarantee lived elsewhere.\n if (settled) return;\n const text = this.text;\n this.text = \"\";\n finish({ status: \"exited\", text, exitCode: exit.exitCode, signal: exit.signal });\n },\n () => {},\n );\n });\n }\n}\n","import { getTerminalHost, type TerminalSession, type TerminalSessionSpec } from \"../registry/capabilities\";\nimport { TerminalTranscript } from \"./terminal-transcript\";\nimport type { FlowGraph, FlowNode } from \"../types\";\n\n/**\n * One terminal per terminal lane, for the length of a run.\n *\n * ## The lifetime, and why it is not per-node\n *\n * A terminal node is only useful if the process it talks to is the SAME one the\n * last node talked to. `cd` has to persist; an agent TUI has to still be\n * running with its conversation intact. A session opened per node would give\n * every node a fresh shell and quietly turn a sequence of steps into a series\n * of unrelated ones — each individually correct, the whole thing meaningless.\n *\n * So the session is keyed on the LANE, opened lazily by the first node inside\n * it, and closed once when the run ends. A graph that never reaches a terminal\n * node spawns no process at all, which is what makes it safe for the lane to\n * exist on a canvas that mostly does other things.\n *\n * ## Why membership is `parentId`\n *\n * It is what the canvas already means by \"inside\", and it already persists into\n * the WorkflowSchema — so a headless runtime resolves exactly the grouping a\n * person drew, with no second association to keep in step. The alternative, a\n * lane id typed into each node's config, is the same fact in two places and\n * would drift the first time somebody dragged a node out of a lane.\n *\n * Nesting is followed to the nearest terminal lane, so an ordinary lane inside\n * a terminal lane still resolves — grouping for looks should not change which\n * terminal a node talks to.\n */\nexport class TerminalSessions {\n private readonly open = new Map<string, Promise<TerminalSession>>();\n\n private readonly laneOf = new Map<string, string | null>();\n\n private readonly transcripts = new Map<string, TerminalTranscript>();\n\n private readonly listening = new Map<string, () => void>();\n\n constructor(private readonly graph: FlowGraph) {}\n\n /**\n * The terminal lane a node belongs to, or null.\n *\n * Walks up `parentId` rather than checking only the immediate parent, and\n * caches per node id — a graph is walked once per run, and the answer cannot\n * change while it runs.\n */\n laneFor(nodeId: string, isTerminalLane: (node: FlowNode) => boolean): string | null {\n const cached = this.laneOf.get(nodeId);\n if (cached !== undefined) return cached;\n\n const byId = new Map(this.graph.nodes.map((n) => [n.id, n]));\n const seen = new Set<string>();\n\n let current = byId.get(nodeId);\n let answer: string | null = null;\n\n while (current) {\n // A cycle in `parentId` is malformed rather than impossible — a dragged\n // node with a stale parent can produce one — and walking it forever would\n // hang the run rather than fail it.\n if (seen.has(current.id)) break;\n seen.add(current.id);\n\n if (current.id !== nodeId && isTerminalLane(current)) {\n answer = current.id;\n break;\n }\n\n const parentId = (current as unknown as { parentId?: string }).parentId;\n current = parentId ? byId.get(parentId) : undefined;\n }\n\n this.laneOf.set(nodeId, answer);\n return answer;\n }\n\n /**\n * The session for a lane, opening it on first use.\n *\n * The PROMISE is cached, not the resolved session. Two nodes cannot run\n * concurrently in the current engine, but a caller that awaits a\n * half-finished open would otherwise start a second process — and two shells\n * where a graph says one is the failure this class exists to prevent, arriving\n * only under concurrency and therefore only sometimes.\n */\n session(laneId: string, spec: TerminalSessionSpec): Promise<TerminalSession> {\n const existing = this.open.get(laneId);\n if (existing) return existing;\n\n const host = getTerminalHost();\n\n if (!host) {\n // Named as a MISSING HOST rather than a failed open. A node in a terminal\n // lane with no host registered is a configuration problem — the desktop\n // app did not install one — and reporting it as \"the terminal failed\"\n // sends someone to debug a process that was never started.\n const failed = Promise.reject(\n new Error(\n \"No terminal host is registered. A terminal lane needs one — call registerTerminalHost() \"\n + \"from the desktop app, or install @particle-academy/fancy-flow/terminal/fancy-term-host.\",\n ),\n );\n // Cached so every node in the lane fails the same way rather than the\n // first one failing and the rest re-asking a question already answered.\n this.open.set(laneId, failed);\n // Nothing awaits this until a node does; keep node from warning meanwhile.\n failed.catch(() => {});\n return failed;\n }\n\n // Subscribed the moment the session resolves, not when a node first waits.\n //\n // A process answers on its own schedule, and the node that types at it and\n // the node that reads the reply are two separate steps. Anything printed in\n // between is unrecoverable if the buffer starts when the WAIT does — so a\n // fast process would be missed and a slow one caught, which is the same bug\n // presenting as flakiness rather than as a bug.\n const opening = Promise.resolve(host.open(spec)).then((session) => {\n const transcript = this.transcriptFor(laneId);\n this.listening.set(laneId, session.onData((chunk) => transcript.append(chunk)));\n return session;\n });\n\n this.open.set(laneId, opening);\n opening.catch(() => {});\n return opening;\n }\n\n /**\n * The accumulated output for a lane.\n *\n * Created on demand and kept for the run, so it exists before the session\n * resolves and survives every node that reads it. Consuming is the reader's\n * job — see `TerminalTranscript.waitFor`.\n */\n transcriptFor(laneId: string): TerminalTranscript {\n const existing = this.transcripts.get(laneId);\n if (existing) return existing;\n\n const created = new TerminalTranscript();\n this.transcripts.set(laneId, created);\n return created;\n }\n\n /** True once a lane has a session — used to avoid opening one during teardown. */\n isOpen(laneId: string): boolean {\n return this.open.has(laneId);\n }\n\n /**\n * Close every session this run opened.\n *\n * Every close is attempted even if one throws: a host that fails to close one\n * PTY must not strand the others, which would leave processes alive after the\n * run reported that it had finished. Errors are returned rather than thrown,\n * because teardown runs in a `finally` and throwing there would replace the\n * run's real error with a cleanup error.\n */\n async closeAll(): Promise<Error[]> {\n const errors: Error[] = [];\n\n for (const [laneId, pending] of this.open) {\n try {\n // Unsubscribe BEFORE closing. A host that emits a final chunk while\n // shutting down would otherwise append to a transcript nobody will read\n // again, and a listener outliving its session is how a closed terminal\n // keeps a run's objects alive.\n this.listening.get(laneId)?.();\n this.listening.delete(laneId);\n\n const session = await pending;\n await session.close();\n } catch (e) {\n errors.push(e instanceof Error ? e : new Error(`${laneId}: ${String(e)}`));\n }\n }\n\n this.open.clear();\n this.listening.clear();\n this.transcripts.clear();\n return errors;\n }\n}\n\n/** The spec a terminal lane node declares. */\nexport function specForLane(lane: FlowNode): TerminalSessionSpec {\n const config = ((lane.data as { config?: Record<string, unknown> } | undefined)?.config ?? {}) as Record<\n string,\n unknown\n >;\n\n const text = (key: string): string | undefined => {\n const value = config[key];\n return typeof value === \"string\" && value !== \"\" ? value : undefined;\n };\n\n const env = config.env;\n\n return {\n command: text(\"command\"),\n cwd: text(\"cwd\"),\n env:\n env && typeof env === \"object\" && !Array.isArray(env)\n ? Object.fromEntries(\n Object.entries(env as Record<string, unknown>).map(([k, v]) => [k, String(v)]),\n )\n : undefined,\n };\n}\n","import { getNodeKind } from \"../registry/registry\";\nimport type { FlowGraph, FlowNode } from \"../types\";\n\n/**\n * What a node emits, described well enough for an author to reference it.\n *\n * This is deliberately NOT `outputs` — that is a `PortSpec`, which describes\n * WIRES (port ids and labels). Nothing in the registry described the DATA on\n * those wires, so \"what can I write in this field\" had no answer to derive\n * from. Hence a second, small declaration.\n */\nexport type OutputField = {\n /** Dot-path relative to the emitted value: `text`, `user.email`. */\n path: string;\n type?: \"string\" | \"number\" | \"boolean\" | \"object\" | \"array\" | \"unknown\";\n description?: string;\n};\n\n/**\n * A kind's output shape — static, or computed from the node's config.\n *\n * The function form is the important one. A `user_input` step emits exactly the\n * field keys its author defined, and a `transform` emits the keys it was told\n * to build; no static list can know either. A static list would have forced\n * every dynamic kind to declare nothing, which is the case an author most needs\n * help with.\n */\nexport type OutputShape<TConfig = Record<string, unknown>> =\n | OutputField[]\n | ((config: TConfig) => OutputField[]);\n\n/** One entry in the variable picker. */\nexport type AvailableVariable = {\n /** Exactly what gets inserted, including the braces. */\n expression: string;\n /** The bare path, for display: `$json.text`. */\n path: string;\n type?: OutputField[\"type\"];\n description?: string;\n /** Label of the upstream node this came from, for disambiguation. */\n source?: string;\n};\n\n/**\n * `$json` and `$input` both alias the `in` port value in the PHP resolver\n * (`Expr::resolvePath`). We suggest ONE of them so the picker does not present\n * the same variable twice under two names; `$json` is the spelling every\n * builtin kind's `example` already uses.\n */\nconst ROOT = \"$json\";\n\nfunction expr(path: string): string {\n return `{{ ${path} }}`;\n}\n\n/** Resolve a kind's output shape for a specific node. */\nexport function outputFieldsFor(node: FlowNode): OutputField[] {\n const kindName = (node.data as { kind?: string } | undefined)?.kind ?? node.type;\n if (!kindName) return [];\n\n const kind = getNodeKind(kindName) as { outputShape?: OutputShape } | undefined;\n const shape = kind?.outputShape;\n if (!shape) return [];\n\n if (typeof shape === \"function\") {\n // A kind computes this from author-supplied config, which is exactly where\n // a throw would be easiest to write and worst to ship — a malformed config\n // would take the whole panel down rather than showing one short list.\n try {\n const config = (node.data as { config?: Record<string, unknown> } | undefined)?.config ?? {};\n return shape(config) ?? [];\n } catch {\n return [];\n }\n }\n return shape;\n}\n\n/**\n * The variables an author can reference from `nodeId`, in this graph.\n *\n * Only the DIRECT predecessors are consulted, because `in` is the value on the\n * incoming wire. Walking further would offer a grandparent's fields, which\n * resolve to `null` at runtime — a suggestion that silently produces nothing is\n * worse than no suggestion, since the author has no reason to doubt it.\n *\n * Always includes the whole input. That one exists no matter what upstream\n * declared, and it is the escape hatch when a kind has no `outputShape` yet.\n */\nexport function baseVariables(): AvailableVariable[] {\n return [\n { expression: expr(ROOT), path: ROOT, type: \"unknown\", description: \"The whole incoming value.\" },\n ];\n}\n\nexport function availableVariables(graph: FlowGraph, nodeId: string): AvailableVariable[] {\n const out: AvailableVariable[] = baseVariables();\n const seen = new Set<string>([ROOT]);\n\n const byId = new Map(graph.nodes.map((n) => [n.id, n]));\n const upstreamIds = graph.edges.filter((e) => e.target === nodeId).map((e) => e.source);\n\n for (const id of upstreamIds) {\n if (id === nodeId) continue; // a self-edge is not an input shape\n const upstream = byId.get(id);\n if (!upstream) continue;\n\n const kindName = (upstream.data as { kind?: string } | undefined)?.kind ?? upstream.type;\n const label =\n (upstream.data as { label?: string } | undefined)?.label ??\n (kindName ? getNodeKind(kindName)?.label : undefined);\n\n for (const field of outputFieldsFor(upstream)) {\n const path = `${ROOT}.${field.path}`;\n if (seen.has(path)) continue;\n seen.add(path);\n out.push({\n expression: expr(path),\n path,\n type: field.type,\n description: field.description,\n source: label,\n });\n }\n }\n\n return out;\n}\n\n/** One documented form of the expression grammar. */\nexport type ExpressionForm = { syntax: string; meaning: string };\n\nexport type ExpressionGrammarHelp = {\n forms: ExpressionForm[];\n note: string;\n};\n\n/**\n * The reference help shown beside an expression field.\n *\n * Every form here is one `Expr::resolvePath` implements — a dot-path and\n * nothing else. It is tempting to document `{{ a && b }}` or `{{ a + b }}`\n * because they look like expressions; the resolver would return `null` for\n * both, and an author following the help would have no way to tell why.\n */\nexport function describeExpressionGrammar(): ExpressionGrammarHelp {\n return {\n forms: [\n { syntax: \"{{ $json }}\", meaning: \"The whole value arriving on this node's input.\" },\n { syntax: \"{{ $json.field }}\", meaning: \"One key of that value. Dot-paths nest: $json.user.email.\" },\n { syntax: \"{{ $input.field }}\", meaning: \"An alias for $json — the same value, either spelling.\" },\n { syntax: \"{{ in }}\", meaning: \"The input by its context key, rather than through the alias.\" },\n ],\n note:\n \"Dot-paths only — no arithmetic, comparisons or function calls; anything else resolves to nothing. \" +\n \"A field that is exactly one expression keeps the resolved value's type; mixed text interpolates as a string. \" +\n \"fancy-flow's own runFlow does not interpolate: it hands config to your executor verbatim, and the \" +\n \"fancy-flow-php runtime is what resolves these.\",\n };\n}\n","/**\n * AN EDGE THAT DELIVERS NOTHING MUST SAY SO — the one implementation of that\n * check, shared by every path that can reach it.\n *\n * `runFlow` asks it of each node it reaches. The durable `Coordinator` asks it\n * of each node its frontier SKIPS, because a skipped node never gets a job and\n * so never replays to ask it for itself. Two copies of this check would agree\n * for a while and then disagree on one handle — which is exactly the kind of\n * divergence the warning exists to report — so there is one, and it EMITS\n * nothing. It returns the events and each caller decides where they go.\n *\n * Kept React-free on purpose: `run-flow.ts` imports it, and the `/engine` entry\n * must not reach React.\n */\nimport type { FlowEdge, FlowNode, RunEvent } from \"../types\";\n// React-free modules, imported directly rather than via the `registry` barrel,\n// which re-exports the RegistryNode component.\nimport { defaultConfigFor, getNodeKind } from \"../registry/registry\";\nimport { nodeConfig, resolvePortSpec } from \"../registry/ports\";\nimport { outputFieldsFor } from \"../expressions/variables\";\n\n/**\n * The `log` / `warn` events for every inbound edge of `target` that delivers\n * nothing and never could.\n *\n * Asked BEFORE the activity gate, because the two outcomes are both silent and\n * only one reaches `collectInputs`. If the bad edge is the node's only inbound\n * one the node is SKIPPED; if it has another live edge it RUNS with that port\n * simply missing -- and then a downstream template that is entirely correct\n * renders empty, because the payload never arrived to have a field in it.\n *\n * Keyed on the source having COMPLETED and on the handle being a port the source\n * could NEVER publish. A branch that was not taken is ordinary and must never\n * warn; a source that finished and cannot publish this port is a\n * misconfiguration that delivers nothing on any run. A warning that fires on\n * ordinary branching is noise, and noise is how a real warning stops being read.\n * PHP has always said this; this runtime ran the same graph and said nothing\n * (fancy-flow#17). Pinned by `flow/run-diagnostics`.\n *\n * - `incoming` — the target's inbound edges, in graph order.\n * - `portValues` — keyed `\"<nodeId>:<portId>\"`, one key per port a node\n * published, in publication order. Only the KEYS are read: which ports\n * published, never what they carried.\n * - `completed` — the ids of nodes that ran to an output. A source that did not\n * complete is never judged (row 0014).\n * - `nodesById` — every node of the graph, to resolve a source's ports and\n * output fields.\n */\nexport function undeliveredEdgeWarnings(\n target: FlowNode,\n incoming: readonly FlowEdge[],\n portValues: ReadonlyMap<string, unknown>,\n completed: ReadonlySet<string>,\n nodesById: ReadonlyMap<string, FlowNode>,\n): RunEvent[] {\n const events: RunEvent[] = [];\n\n for (const e of incoming) {\n const handle = e.sourceHandle ?? \"out\";\n if (portValues.has(`${e.source}:${handle}`) || !completed.has(e.source)) continue;\n if (possiblePortIds(nodesById.get(e.source)).includes(handle)) continue;\n\n events.push({\n type: \"log\",\n nodeId: target.id,\n level: \"warn\",\n message: undeliveredEdgeMessage(e, target, portValues, nodesById),\n detail: { edge: e.id, source: e.source, sourceHandle: handle },\n });\n }\n\n return events;\n}\n\n/**\n * Every port this node COULD publish — not the ones it did.\n *\n * The distinction that keeps the undelivered-edge warning honest. A `branch`\n * that took `true` publishes no `false`, and the edge leaving `false` binds\n * nothing: that is ORDINARY BRANCHING. A handle that is not a port of the node\n * at all can never bind on any run. \"Did it publish?\" cannot tell those apart —\n * both are absent — so this asks what is POSSIBLE.\n *\n * The rule is the PHP twin's `PortResolution::possible`, precedence and all,\n * because a warning one runtime raises and another does not is a parity failure:\n *\n * 1. the node's own declared `outputs`;\n * 2. the kind's CONFIG-DERIVED ports, when the config declares any;\n * 3. the kind's declared ports;\n * 4. `out`.\n *\n * It differs from `resolveNodePorts` in exactly one place, on purpose. A kind\n * whose ports come from config — `switch_case`, `llm_router` — and whose config\n * declares none yet answers with its DEFAULT-config shape (`case_a`, `case_b`,\n * `default`), which is what PHP's static declaration for that kind is.\n * `resolveNodePorts` answers with what that empty config yields (`default`\n * alone), which is right for the canvas and for `activatedPorts`, so it is left\n * alone: this only decides whether to warn, never what routes.\n */\nfunction possiblePortIds(node: FlowNode | undefined): string[] {\n if (!node) return [\"out\"];\n\n const own = (node.data as { outputs?: unknown } | undefined)?.outputs;\n if (Array.isArray(own)) return own.map((p: { id: string }) => p.id);\n\n // An unregistered kind is not ambiguous: `activatedPorts` falls back to\n // exactly `out` for a kind it cannot resolve, so that is all it publishes.\n const kind = getNodeKind((node.data as any)?.kind ?? node.type ?? \"\");\n if (!kind) return [\"out\"];\n\n const config = nodeConfig(node);\n const representative = typeof kind.outputs === \"function\" && !configDeclaresPorts(kind.name, config);\n const ids = (resolvePortSpec(kind.outputs, representative ? defaultConfigFor(kind) : config) ?? [])\n .map((p) => p.id);\n\n return ids.length > 0 ? ids : [\"out\"];\n}\n\n/**\n * Whether a config-driven kind's config declares any ports of its own — PHP's\n * `configDerived` returning non-empty. Matched on the BARE kind name, as there:\n * graphs carry both `switch_case` and `@particle-academy/switch_case`.\n */\nfunction configDeclaresPorts(kindName: string, config: Record<string, unknown>): boolean {\n const bare = kindName.startsWith(\"@\") ? kindName.slice(kindName.lastIndexOf(\"/\") + 1) : kindName;\n\n if (bare === \"switch_case\") {\n // `cases` maps VALUE => PORT, so the ports are its values.\n const cases = config.cases;\n return !!cases && typeof cases === \"object\"\n && Object.values(cases).some((port) => typeof port === \"string\" && port !== \"\");\n }\n\n if (bare === \"llm_router\") {\n const routes = config.routes;\n return Array.isArray(routes)\n && routes.some((route) => (route as { port?: unknown } | null)?.port != null && (route as { port: unknown }).port !== \"\");\n }\n\n return true;\n}\n\n/**\n * The message for an edge whose source port publishes nothing.\n *\n * The PHP twin's wording, byte for byte, and each part earns its place:\n *\n * 1. THE EDGE ID FIRST — the thing the author, looking at a graph, can act on.\n * 2. THE CONSEQUENCE, IN RUNTIME TERMS. Without \"nothing would reach X\" this\n * reads as a schema nit, and a handle string feels cosmetic.\n * 3. THE AVAILABLE PORTS — what the source ACTUALLY published on this run, in\n * publication order, so a config-driven kind reports its real ports.\n * 4. THE REMEDY FOR THE COMMON CASE. Nearly every occurrence is an agent\n * ADDING a handle that should not be there, so \"leave sourceHandle off\" —\n * offered only when there is a handle to leave off.\n *\n * Plus the part only the engine can supply: when the handle names a FIELD of\n * the source kind's output shape, say so. That is the actual confusion — a field\n * name where a port belongs — and naming it turns a correction into an\n * explanation.\n */\nfunction undeliveredEdgeMessage(\n edge: FlowEdge,\n target: FlowNode,\n portValues: ReadonlyMap<string, unknown>,\n nodesById: ReadonlyMap<string, FlowNode>,\n): string {\n const handle = edge.sourceHandle ?? \"out\";\n\n const prefix = `${edge.source}:`;\n const available: string[] = [];\n for (const key of portValues.keys()) {\n if (key.startsWith(prefix)) available.push(key.slice(prefix.length));\n }\n\n let message =\n `Edge ${edge.id} reads port \"${handle}\" from node ${edge.source}, which never publishes it — ` +\n `nothing would reach ${target.id} at run time.`;\n\n if (available.length > 0) message += ` Available: ${available.join(\", \")}.`;\n\n // The near-miss: a FIELD of that name, where a PORT was expected.\n const source = nodesById.get(edge.source);\n if (source && outputFieldsFor(source).some((field) => field?.path === handle)) {\n message +=\n ` Note: \"${handle}\" is a FIELD this node emits, not a port — read it downstream as ` +\n `{{ in.${handle} }} rather than naming it as a source handle.`;\n }\n\n if (edge.sourceHandle != null) message += \" Leave sourceHandle off to read the node's output.\";\n\n return message;\n}\n","import type { WorkflowInput } from \"../types\";\n\n/**\n * Resolving what a caller passed against what a workflow declared.\n *\n * Kept in its own module, and deliberately a pure function over two plain\n * objects, because the PHP and Python runtimes implement the same rules and\n * `suites/flow/workflow-props` in `@particle-academy/fancy-conformance` is the\n * table all three run. A rule that lives inside a runner is a rule each runtime\n * re-derives; a rule that is a function over maps is one they can share a\n * fixture for.\n *\n * ## Every branch here exists to make a mistake LOUD\n *\n * The failure this replaces was silence. `initialInputs` was keyed by node id,\n * so a caller passed `{ t: { topic: \"otters\" } }` and had to know the trigger\n * was named `t`; and nothing declared what a workflow accepted, so a\n * misspelled key was not an error — the value sat unread, the node saw\n * nothing, and the run reported success with output that was quietly wrong.\n *\n * So: an unknown key fails, a missing required value fails, and a wrong type\n * fails. None of those is a warning. A warning on a queue worker is a line in a\n * log nobody opens.\n */\n\n/**\n * Why a resolution failed, in a vocabulary that is the same in every runtime.\n *\n * The MESSAGE is English prose and each runtime words it slightly differently,\n * which is fine for a human and useless for a shared fixture table. The CODE is\n * what `suites/flow/workflow-props` asserts, so parity is pinned on the\n * decision rather than on the phrasing — otherwise the three implementations\n * would be held to a translation instead of a behaviour.\n */\nexport type PropsErrorCode = \"unknown_input\" | \"missing_required\" | \"type_mismatch\";\n\n/** The outcome of checking a caller's props against a declaration. */\nexport type PropsResolution =\n | { ok: true; props: Record<string, unknown> }\n | { ok: false; code: PropsErrorCode; error: string };\n\n/**\n * The runtime type of a value, in the vocabulary a declaration uses.\n *\n * Arrays are checked before objects because `typeof []` is `\"object\"` and a\n * declaration that says `array` means a list — accepting `{}` there would be\n * the check passing while meaning nothing.\n */\nfunction typeOf(value: unknown): string {\n if (value === null) return \"null\";\n if (Array.isArray(value)) return \"array\";\n return typeof value;\n}\n\n/**\n * Check and fill a caller's props.\n *\n * Returns the resolved map — declared defaults filled in, nothing else added —\n * or the first error. One error rather than a list, because a run stops at the\n * first one anyway and a caller fixing a call wants the thing to fix, not a\n * report.\n */\nexport function resolveWorkflowProps(\n declared: WorkflowInput[] | undefined,\n passed: Record<string, unknown> | undefined,\n): PropsResolution {\n const inputs = declared ?? [];\n const given = passed ?? {};\n const byName = new Map(inputs.map((input) => [input.name, input]));\n\n // UNKNOWN KEYS FIRST, and this is the check the whole feature is for.\n //\n // A caller who misspells `topic` as `topik` has configured nothing, and\n // before this the run went ahead and looked fine. Checking it before\n // anything else means the error names what they typed rather than\n // complaining that the thing they thought they passed is missing.\n for (const name of Object.keys(given)) {\n if (!byName.has(name)) {\n const known = inputs.map((input) => input.name);\n const suffix = known.length === 0\n ? \"this workflow declares no inputs\"\n : `known inputs: ${known.join(\", \")}`;\n\n return {\n ok: false,\n code: \"unknown_input\",\n error: `Unknown workflow input \"${name}\" — ${suffix}.`,\n };\n }\n }\n\n const resolved: Record<string, unknown> = {};\n\n for (const input of inputs) {\n // `hasOwnProperty`, not a truthiness or `??` check. `0`, `false` and `\"\"`\n // are real values a caller meant to pass, and a default applied over them\n // is a silent override — a limit of 0 quietly becoming 10 is not an error\n // anybody sees.\n const supplied = Object.prototype.hasOwnProperty.call(given, input.name);\n const hasDefault = Object.prototype.hasOwnProperty.call(input, \"default\");\n\n if (!supplied) {\n if (hasDefault) {\n resolved[input.name] = input.default;\n continue;\n }\n\n if (input.required) {\n return {\n ok: false,\n code: \"missing_required\",\n error: `Missing required workflow input \"${input.name}\"${\n input.type ? ` (${input.type})` : \"\"\n }.`,\n };\n }\n\n // Not supplied, no default, not required — absent rather than\n // `undefined`, so `{{ $props.x }}` resolves to null on both runtimes\n // instead of one of them inventing a key.\n continue;\n }\n\n const value = given[input.name];\n\n // An undeclared type accepts anything. \"I am not asserting a shape\" must\n // not degrade into \"nothing is allowed\".\n if (input.type !== undefined) {\n const actual = typeOf(value);\n if (actual !== input.type) {\n return {\n ok: false,\n code: \"type_mismatch\",\n error: `Workflow input \"${input.name}\" expects ${input.type}, got ${actual}.`,\n };\n }\n }\n\n resolved[input.name] = value;\n }\n\n return { ok: true, props: resolved };\n}\n","import type {\n ExecutorRegistry,\n FlowEdge,\n FlowGraph,\n FlowNode,\n NodeExecutor,\n RunEvent,\n} from \"../types\";\n// Both modules are React-free by design — the `/engine` entry must not pull in\n// React. Import them directly rather than via the `registry` barrel, which\n// re-exports the RegistryNode component.\nimport { getNodeKind, kindIds } from \"../registry/registry\";\nimport { resolveNodePorts } from \"../registry/ports\";\nimport { RunIdentity, type RunIdentityJson } from \"./run-identity\";\nimport { TerminalSessions, specForLane } from \"./terminal-sessions\";\nimport { undeliveredEdgeWarnings } from \"./undelivered-edges\";\nimport { resolveWorkflowProps } from \"./workflow-props\";\n\nexport type RunOptions = {\n /** Stop the run after this many ms. Default: no timeout. */\n timeoutMs?: number;\n /** Abort signal — host can cancel the run. */\n signal?: AbortSignal;\n /** Initial inputs supplied to entry-point nodes (no incoming edges). */\n initialInputs?: Record<string, Record<string, unknown>>;\n /**\n * Values for the inputs the graph DECLARES, passed by name.\n *\n * The flat, node-id-free way to configure a run. `initialInputs` is keyed by\n * node id, so a caller had to know the trigger was called `t` and a rename\n * broke every caller while the graph stayed valid. Props are checked against\n * `graph.inputs`, so a misspelling fails the run instead of sitting unread.\n */\n props?: Record<string, unknown>;\n /**\n * Which ENTRY POINTS are live — the ids of nodes with NO incoming edges this\n * run should start from. Omit it and every entry point runs, exactly as\n * before the option existed.\n *\n * A graph may hold more than one trigger — a `manual_trigger` for\n * hand-testing beside the event trigger that runs it for real — and a trigger\n * has no inbound edges, which IS the readiness rule. So without this, every\n * trigger's branch runs on every run, whichever one fired. The triggers\n * themselves are harmless; everything DOWNSTREAM of the ones that did not\n * fire is not. A `user_input` stranded on the manual branch parks an\n * event-driven run to ask a person for data the event already supplied,\n * which from outside looks like the event trigger being ignored.\n *\n * Naming the live entry points makes the others INACTIVE, and the existing\n * \"at least one active inbound edge\" rule then skips everything reachable\n * only from them. No new routing logic.\n *\n * Three edges, each pinned by `flow/entry-points` in\n * `@particle-academy/fancy-conformance`:\n * - `undefined` is NOT `[]`. Unset runs every entry point; an empty array\n * says none is live and runs nothing.\n * - A node reachable from SEVERAL entry points still runs when any one of\n * them fires — one active inbound edge is enough, as always.\n * - Naming a node that HAS inbound edges names no entry point, so every real\n * entry is inactive and nothing runs. That falls out of the rule rather\n * than being special-cased; validate your ids if you want a typo to be\n * loud, because the runtime cannot tell one from a deliberate empty\n * selection.\n */\n entryNodes?: string[];\n /** Nesting depth — set by `subflow` when it runs a child graph. */\n depth?: number;\n /**\n * Who is running, so a writing node can derive a stable idempotency key.\n *\n * A bare string is taken as the run key. **Deliberately not defaulted:** a\n * minted-per-call key would change on every whole-run retry, which is exactly\n * the failure an idempotency key exists to prevent — so a host that has not\n * supplied one gets `ctx.run === undefined` and a connector that declines to\n * write blind, rather than a plausible-looking key that double-charges.\n */\n run?: RunIdentity | RunIdentityJson | string;\n /**\n * Outputs already checkpointed for this run, keyed by node id.\n *\n * A node present here is **republished, not re-executed** — its stored value\n * goes back onto the same ports, so downstream routing reproduces exactly\n * what it did the first time. This is what makes a per-node durable driver\n * possible without a second copy of the routing rules, and it is how the PHP\n * and Python runtimes have always resumed.\n */\n resumeOutputs?: Record<string, unknown>;\n /**\n * Executors bound to ONE node id each, matched against `node.id` and nothing\n * else. They outrank every entry of the executor registry.\n *\n * The registry cannot say this. It is one flat object, and `executorLookupIds`\n * tries a key as the node's id AND as its kind, so a key that is both is both:\n * binding `host_kind` to pin the node CALLED `host_kind` also rebinds every\n * node whose kind is `host_kind`. That is the registry's contract (pinned by\n * `flow/executor-resolution`) and it stays. This is the separate channel for a\n * binding that must not leak into the kind namespace -- the PHP twin's\n * `bindNode`, which has always been kept apart from `bind`.\n *\n * The durable replay fences every node but its target through this. Through\n * the registry, a node whose id matched a kind fenced every node of that kind,\n * and the durable run reported success having run nothing.\n *\n * NOT handed down to a nested run. Node ids belong to one graph: a `subflow`\n * child's `t` is not its parent's `t`, so `ctx.executors` stays the registry\n * alone.\n */\n nodeExecutors?: Record<string, NodeExecutor>;\n};\n\nexport type RunResult = {\n ok: boolean;\n /** Outputs collected per node, keyed by node id. */\n outputs: Record<string, unknown>;\n /** Error captured if any node threw. */\n error?: string;\n};\n\n/**\n * runFlow — topological execution of a FlowGraph against an ExecutorRegistry.\n *\n * Each node runs once, when all upstream nodes have produced outputs on the\n * connected ports. Decision nodes (or any executor that returns `{ branch:\n * 'true' }`) can short-circuit specific output ports — only edges leaving\n * an \"active\" port propagate to downstream nodes.\n *\n * Cycles are detected and abort the run with an error.\n *\n * The `onEvent` callback receives a stream of `RunEvent`s — wire it to a\n * status feed, log panel, or store.\n */\nexport async function runFlow(\n graph: FlowGraph,\n executors: ExecutorRegistry,\n onEvent: (event: RunEvent) => void = () => {},\n options: RunOptions = {},\n): Promise<RunResult> {\n const { signal, initialInputs = {}, timeoutMs, depth = 0, resumeOutputs = {}, entryNodes, nodeExecutors } = options;\n const run = options.run === undefined ? undefined : RunIdentity.from(options.run);\n const outputs: Record<string, unknown> = {};\n const portValues = new Map<string, unknown>(); // key: `${nodeId}:${portId}`\n const completed = new Set<string>();\n const errors: string[] = [];\n\n // Topological order via Kahn's algorithm. We allow nodes to run as soon\n // as their incoming edges' source ports have produced values, so the\n // order here is just a deterministic baseline used for cycle detection.\n const order = topoSort(graph);\n if (order === null) {\n const msg = \"Cycle detected in flow graph — aborting.\";\n onEvent({ type: \"run-error\", error: msg });\n return { ok: false, outputs, error: msg };\n }\n\n // Props are checked BEFORE anything runs, and a failure aborts the run.\n //\n // Before a node executes, not after: a workflow whose third node needed a\n // value the caller misspelled would otherwise do two nodes' worth of real\n // work — sending, writing, charging — and only then discover the call was\n // malformed. Validation that happens after a side effect is not validation.\n const propsCheck = resolveWorkflowProps(graph.inputs, options.props);\n if (!propsCheck.ok) {\n onEvent({ type: \"run-error\", error: propsCheck.error });\n return { ok: false, outputs, error: propsCheck.error };\n }\n const props = propsCheck.props;\n const declaresProps = (graph.inputs?.length ?? 0) > 0;\n\n const incomingByNode = indexIncoming(graph.edges);\n // Built ONCE. Used only to explain an undelivered edge, but building it per\n // node would make a diagnostic quietly O(n^2) on the hot path.\n const nodesById = new Map(graph.nodes.map((n) => [n.id, n]));\n\n // Terminal lanes. Constructed unconditionally and costing nothing until a\n // node inside one actually runs — a graph with no terminal lane never asks\n // for a host, so nothing spawns and nothing needs one registered.\n const sessions = new TerminalSessions(graph);\n const isTerminalLane = (candidate: FlowNode): boolean =>\n getNodeKind(candidate.type ?? \"\")?.name === \"@particle-academy/terminal_lane\";\n\n const terminalAccessorFor = (node: FlowNode) => {\n const laneId = sessions.laneFor(node.id, isTerminalLane);\n if (laneId === null) return undefined;\n\n const lane = graph.nodes.find((n) => n.id === laneId);\n if (!lane) return undefined;\n\n // Returned as a FUNCTION rather than an open session, so the terminal opens\n // on first USE rather than when a node in the lane starts. A node that\n // never touches its terminal never spawns one, which is what makes the\n // lane safe to draw around nodes that mostly do other things.\n return {\n session: () => sessions.session(laneId, specForLane(lane)),\n // Awaits the session first on purpose. A transcript handed out before\n // anything is feeding it would look perfectly healthy and match nothing,\n // and \"waited and nothing came\" is the hardest failure here to tell apart\n // from a process that is simply slow.\n transcript: async () => {\n await sessions.session(laneId, specForLane(lane));\n return sessions.transcriptFor(laneId);\n },\n };\n };\n\n const timer = timeoutMs ? setTimeout(() => errors.push(`Run timed out after ${timeoutMs}ms`), timeoutMs) : null;\n\n onEvent({ type: \"run-start\" });\n\n try {\n for (const node of order) {\n if (signal?.aborted) throw new Error(\"aborted\");\n if (errors.length) break;\n\n // A checkpointed node is republished, never re-executed. Publishing the\n // stored value back onto its own ports is what makes the resume exact:\n // the branch it took, the ports it lit and the inputs its successors\n // collect are all reproduced by the engine's own rules rather than by a\n // driver's recollection of them.\n if (Object.prototype.hasOwnProperty.call(resumeOutputs, node.id)) {\n const stored = resumeOutputs[node.id];\n outputs[node.id] = stored;\n const activated = activatedPorts(node, stored);\n for (const portId of activated.ports) {\n portValues.set(`${node.id}:${portId}`, activated.value);\n onEvent({ type: \"node-output\", nodeId: node.id, portId, value: activated.value });\n }\n completed.add(node.id);\n onEvent({ type: \"node-status\", nodeId: node.id, status: \"done\", text: \"resumed\" });\n continue;\n }\n\n const incoming = incomingByNode.get(node.id) ?? [];\n\n // An ENTRY POINT this run did not start from is inactive.\n //\n // A node with no inbound edges is unconditionally ready -- that IS the\n // readiness rule -- so a graph with two triggers ran both branches on\n // every run, whichever trigger actually fired. Marking the unnamed ones\n // inactive here lets the \"at least one active inbound edge\" test below\n // skip everything reachable only from them, with no new routing logic.\n //\n // Gates only nodes with NO incoming edges: a node further down the graph\n // is not an entry point, and its readiness is still decided by its edges.\n if (incoming.length === 0 && entryNodes !== undefined && !entryNodes.includes(node.id)) {\n onEvent({ type: \"node-status\", nodeId: node.id, status: \"idle\", text: \"skipped\" });\n continue;\n }\n\n // AN EDGE THAT DELIVERS NOTHING MUST SAY SO.\n //\n // Checked HERE, before the activity gate, because the two outcomes are\n // both silent and only one reaches `collectInputs`: a node whose only\n // inbound edge is bad is SKIPPED, and one with another live edge RUNS with\n // that port missing. The rule itself lives in `undeliveredEdgeWarnings`,\n // which the durable coordinator also asks at its skip decision -- one\n // implementation, so the two paths cannot disagree about a handle.\n for (const warning of undeliveredEdgeWarnings(node, incoming, portValues, completed, nodesById)) {\n onEvent(warning);\n }\n\n // Run a node once any upstream branch reaches it. We iterate in\n // topological order, so by the time we reach this node every upstream\n // node has been processed — each incoming edge is therefore *settled*\n // (active or dead, never still-pending). Requiring ALL incoming edges to\n // be active wrongly skipped MERGE POINTS: when a Decision routes down one\n // branch, the other branch's edge stays dead forever, so an `every` check\n // skipped the shared continuation node and halted the run after the first\n // branch (#1). Run when AT LEAST ONE incoming edge is active —\n // collectInputs() only reads from the active ones. A genuine parallel\n // join still works: in topo order both of its inputs are already active.\n if (incoming.length > 0) {\n const anyActive = incoming.some((e) => portValues.has(`${e.source}:${e.sourceHandle ?? \"out\"}`));\n if (!anyActive) {\n onEvent({ type: \"node-status\", nodeId: node.id, status: \"idle\", text: \"skipped\" });\n continue;\n }\n }\n\n // Notes/annotations + layout (lane/pool) nodes are visual only — never\n // executed and never fed to runners. Their config (a note's text, a lane's\n // title) stays in the document for editors + MCP tools, but the engine\n // walks straight past them. Edges cross lanes freely, so grouping never\n // affects topology.\n const visualKind = getNodeKind(node.type ?? \"\");\n const isLayout = visualKind?.category === \"layout\";\n const isAnnotation = node.type === \"note\" || visualKind?.category === \"annotation\";\n if (isLayout || isAnnotation) {\n onEvent({\n type: \"node-status\",\n nodeId: node.id,\n status: \"idle\",\n text: isLayout ? \"lane\" : \"annotation\",\n });\n continue;\n }\n\n onEvent({ type: \"node-status\", nodeId: node.id, status: \"running\" });\n announce(onEvent, node, \"start\");\n\n const inputs = collectInputs(node, incoming, portValues, initialInputs, props, declaresProps);\n const exec = pickExecutor(executors, node, nodeExecutors);\n if (!exec) {\n // Name what was LOOKED FOR, not just what the node calls itself.\n //\n // This said `kind=${node.type}` — so a registry keyed under one of the\n // kind's other ids produced \"kind=manual_trigger is missing\" about a\n // kind that exists AND is registered, just under a different key. The\n // consumer who reported it reasonably read that as the kind being\n // absent and went looking for a missing package.\n // The wildcard is part of `executorLookupIds` now, so it is already in\n // the list — appending \"and the wildcard\" as well made the message name\n // it twice, and the test that reads the ids back out of the message\n // parsed the prose between the two quoted stars as an id.\n const tried = executorLookupIds(node);\n const msg = `No executor registered for kind=${node.type}`\n + ` — tried ${tried.map((id) => `\"${id}\"`).join(\", \")}`\n + `. Key your registry by one of those.`;\n errors.push(msg);\n onEvent({ type: \"node-status\", nodeId: node.id, status: \"error\", text: msg });\n onEvent({ type: \"log\", nodeId: node.id, level: \"error\", message: msg });\n break;\n }\n\n try {\n const result = await Promise.resolve(\n exec({\n node,\n inputs,\n abort: (reason) => { throw new Error(reason ?? \"aborted\"); },\n emit: onEvent,\n executors,\n depth,\n run,\n terminal: terminalAccessorFor(node),\n }),\n );\n outputs[node.id] = result;\n\n // Decide which output ports were activated. Three conventions:\n // 1) If result is `{ __port: \"out\", value: x }`, only that port emits.\n // 2) If result has `branch: <portId>`, only that port emits (decision sugar).\n // 3) Otherwise, the value is published on every declared output port.\n const activated = activatedPorts(node, result);\n for (const portId of activated.ports) {\n portValues.set(`${node.id}:${portId}`, activated.value);\n onEvent({ type: \"node-output\", nodeId: node.id, portId, value: activated.value });\n }\n completed.add(node.id);\n onEvent({ type: \"node-status\", nodeId: node.id, status: \"done\" });\n // Only on the success path, and deliberately so: a `stoppingMsg` of\n // \"Analysis complete\" emitted after a throw tells a human the opposite\n // of what happened, in the part of the UI they trust most. A failure\n // reports through node-status/log, which is what those exist for.\n announce(onEvent, node, \"end\");\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n errors.push(msg);\n onEvent({ type: \"node-status\", nodeId: node.id, status: \"error\", text: msg });\n onEvent({ type: \"log\", nodeId: node.id, level: \"error\", message: msg });\n break;\n }\n }\n } finally {\n if (timer) clearTimeout(timer);\n\n // Terminals close HERE, in the same `finally` that clears the timer, so\n // they go away on the error and abort paths too — not only when a run ends\n // tidily. A PTY that outlives its run is a process nobody is watching and\n // nothing will close.\n //\n // Failures are reported and swallowed rather than thrown: this is the\n // teardown path, and throwing would replace the run's real error with a\n // cleanup error, hiding what actually went wrong behind the consequence.\n for (const error of await sessions.closeAll()) {\n onEvent({ type: \"log\", level: \"warn\", message: `terminal close failed: ${error.message}` });\n }\n }\n\n const ok = errors.length === 0;\n onEvent({ type: \"run-end\", ok });\n return ok ? { ok, outputs } : { ok, outputs, error: errors[0] };\n}\n\nfunction indexIncoming(edges: FlowEdge[]): Map<string, FlowEdge[]> {\n const map = new Map<string, FlowEdge[]>();\n for (const e of edges) {\n const list = map.get(e.target) ?? [];\n list.push(e);\n map.set(e.target, list);\n }\n return map;\n}\n\nfunction topoSort(graph: FlowGraph): FlowNode[] | null {\n const inDegree = new Map<string, number>();\n for (const n of graph.nodes) inDegree.set(n.id, 0);\n for (const e of graph.edges) inDegree.set(e.target, (inDegree.get(e.target) ?? 0) + 1);\n const queue: string[] = [];\n for (const [id, d] of inDegree) if (d === 0) queue.push(id);\n const ordered: string[] = [];\n while (queue.length) {\n const id = queue.shift()!;\n ordered.push(id);\n for (const e of graph.edges) {\n if (e.source !== id) continue;\n const next = (inDegree.get(e.target) ?? 0) - 1;\n inDegree.set(e.target, next);\n if (next === 0) queue.push(e.target);\n }\n }\n if (ordered.length !== graph.nodes.length) return null;\n const byId = new Map(graph.nodes.map((n) => [n.id, n]));\n return ordered.map((id) => byId.get(id)!).filter(Boolean);\n}\n\nfunction collectInputs(\n node: FlowNode,\n incoming: FlowEdge[],\n portValues: Map<string, unknown>,\n initial: Record<string, Record<string, unknown>>,\n props: Record<string, unknown>,\n declaresProps: boolean,\n): Record<string, unknown> {\n const inputs: Record<string, unknown> = { ...(initial[node.id] ?? {}) };\n\n // ENTRY POINTS are seeded with the props by their bare names.\n //\n // This is what lets an existing graph keep working unchanged. A trigger that\n // reads `{{ topic }}` was fed by `initialInputs[triggerId].topic`; a caller\n // moving to props passes `{ topic }` and the node sees exactly what it saw\n // before. Only entry points, because a node in the middle of a graph reading\n // a bare `topic` would be shadowing whatever its upstream edge is called.\n //\n // Never clobbers: a value already seeded by the host is the host's.\n if (incoming.length === 0) {\n for (const [name, value] of Object.entries(props)) {\n if (!(name in inputs)) inputs[name] = value;\n }\n }\n for (const e of incoming) {\n const portId = e.targetHandle ?? \"in\";\n const key = `${e.source}:${e.sourceHandle ?? \"out\"}`;\n // A branch that never fired has no entry in portValues. Assigning its\n // `undefined` would CLOBBER the value the branch that DID fire already\n // contributed on this same handle — emptying every merge point downstream\n // of a decision, silently, with the run still reporting success.\n //\n // This is the other half of the merge-point bug above: that fix stopped the\n // shared continuation node being skipped, but it still arrived with nothing\n // whenever a later inactive edge happened to be last in `incoming`.\n if (!portValues.has(key)) continue;\n inputs[portId] = portValues.get(key);\n\n // ALSO address it by the SOURCE NODE'S ID, when the edge named no handle.\n //\n // Authors reach for node ids -- every graph tool addresses nodes that way,\n // so `{{ n2.text }}` is the first thing written, by people and far more\n // often by assistants generating graphs. That resolved to nothing, and\n // NOTHING FAILED: an unresolvable path yields \"\", so the node ran, the run\n // reported success, and the damage was output that was quietly wrong. A\n // consumer shipped a file named `document.md` containing the literal text\n // of its own template, on a green run (fancy-flow-php#8).\n //\n // `targetHandle` already covers this and stays the right mechanism for\n // reading something other than the immediate predecessor -- but it is set\n // on the EDGE, which is not where an author is looking while writing a\n // node's config. The model was not wrong; the obvious spelling meant\n // nothing.\n //\n // Only for edges that declared NO handle: an edge that named one said what\n // it meant, and a second key under the source id would quietly widen a\n // deliberate contract. `??=` so nothing already seeded -- by the host's\n // initialInputs or an earlier edge -- is ever clobbered.\n if (e.targetHandle == null && !(e.source in inputs)) {\n inputs[e.source] = portValues.get(key);\n }\n }\n\n // EVERY node gets `$props` — but ONLY when the workflow declares inputs.\n //\n // The first half is what makes props usable at depth. Seeding entry points\n // alone would mean a node six hops downstream had the value threaded through\n // every edge in between, and every hop is somewhere it can be dropped. It\n // costs nothing to resolve because `$props` is an ORDINARY KEY in the inputs\n // object: `resolvePath` already walks dot-paths against it, so\n // `{{ $props.topic }}` works with no change to any expression resolver in any\n // of the three runtimes.\n //\n // The second half is a CORRECTION, and the golden parity fixtures caught it.\n // An earlier draft wrote `$props` unconditionally, justified as \"so\n // `{{ $props.x }}` resolves to null rather than throwing\" — which is not\n // true. `resolvePath` returns null for any unresolvable path, so on a graph\n // declaring nothing the key changes no behaviour at all. What it DOES do is\n // add a key to every executor's inputs, on every graph, forever — which\n // showed up instantly as a diff in every stored golden.\n //\n // `ConnectorFacet::from` states the same rule for the same reason: a payload\n // gaining a key on every entry is a wire change for no gain, and the ABSENCE\n // of a key is already the honest way to say \"this one takes no props\".\n //\n // Keyed on the DECLARATION rather than on whether a value arrived: a workflow\n // whose inputs are all optional and all omitted still declared a contract, so\n // `$props` is present and empty.\n if (declaresProps) inputs.$props = props;\n\n return inputs;\n}\n\n/**\n * Every key a node's executor may legitimately be registered under, in\n * precedence order. **This is the resolution rule** — `pickExecutor` walks this\n * list and takes the first hit, and the failure message lists the same ids.\n *\n * That sharing is the point, and it used to be a claim rather than a fact: this\n * docblock already said \"shared by the lookup and by its failure message\" while\n * `pickExecutor` re-implemented the walk beside it. The two agreed until the\n * precedence changed, and then the message listed an id the lookup no longer\n * tried — sending a reader to check something that never happened, which the\n * comment correctly named as worse than listing nothing. **Prose next to a check\n * is not the check.** One list now, walked by both, so they cannot drift.\n *\n * The order, and why:\n *\n * 1. `node.id` — the per-node override. First so a graph can pin ONE node to a\n * stub without unbinding that kind for every other node using it.\n * 2. `node.type`, then every id its kind answers to — **if `node.type` names a\n * registered kind, it is authoritative and `data.kind` is not consulted at\n * all.** A node that says it is an `llm_call` must never quietly run another\n * kind's code; it fails closed instead.\n * 3. Otherwise `data.kind` and its kind's ids. A `node.type` naming no\n * registered kind is not a claim about behaviour — usually it is an xyflow\n * RENDERER type (`\"fancyNode\"`), which is ordinary practice, and then\n * `data.kind` is the only real answer. This branch also covers `type` absent.\n * 4. `\"*\"` — the wildcard, last, and a sentinel rather than a kind: it is never\n * expanded through the alias machinery, or every unmatched node would bind to\n * whatever a kind literally named `*` aliased to.\n *\n * Pinned as `flow/executor-resolution` in `@particle-academy/fancy-conformance`.\n */\nfunction executorLookupIds(node: FlowNode): string[] {\n const ids: string[] = [node.id];\n if (node.type) ids.push(node.type);\n\n const typeKind = node.type ? getNodeKind(node.type) : null;\n\n if (typeKind) {\n for (const id of kindIds(typeKind)) ids.push(id);\n } else {\n const declared = (node.data as { kind?: unknown } | undefined)?.kind;\n const kindName = typeof declared === \"string\" && declared !== \"\" ? declared : null;\n\n if (kindName) {\n ids.push(kindName);\n const dataKind = getNodeKind(kindName);\n if (dataKind) {\n for (const id of kindIds(dataKind)) ids.push(id);\n }\n }\n }\n\n ids.push(\"*\");\n\n return [...new Set(ids)];\n}\n\nfunction pickExecutor(\n executors: ExecutorRegistry,\n node: FlowNode,\n nodeExecutors?: Record<string, NodeExecutor>,\n): NodeExecutor | undefined {\n // A node-only binding is looked up by the node's id and NO other key, which\n // is the whole reason it is not an entry in `executors` (see\n // `RunOptions.nodeExecutors`). Own properties only: a node called\n // `constructor` must not find `Object`.\n const pinned = nodeExecutors && Object.prototype.hasOwnProperty.call(nodeExecutors, node.id)\n ? nodeExecutors[node.id]\n : undefined;\n if (pinned) return pinned;\n\n // The whole rule lives in `executorLookupIds` -- see its docblock. Walking\n // that one list is what keeps the resolution and the failure message from\n // ever disagreeing about which keys were tried.\n //\n // The HOST registry is consulted first, and that order is the contract: a\n // kind ships an executor as a default, and a host that registers its own\n // takes over. Reversing it would make a builtin unoverridable.\n for (const id of executorLookupIds(node)) {\n if (executors[id]) return executors[id];\n }\n\n // Then the kind's own, for the kinds that ship one.\n //\n // This fallback did not exist, and `NodeKindDefinition.executor` was\n // therefore a field nothing read. `subflow` and `llm_router` have both\n // declared one since they were written, and both were unreachable through\n // `runFlow`: a consumer who called `registerBuiltinKinds()` and ran a graph\n // containing a subflow node got \"No executor registered for kind=subflow\"\n // about a kind that ships its executor in the same object as its schema.\n //\n // It survived because the two are unit-tested by calling the executor\n // directly — which proves the executor works and says nothing about whether\n // anything can reach it. A declared capability with no reader is the shape\n // this estate keeps finding, and the only reliable way to catch it is a test\n // that goes through the front door.\n return getNodeKind(node.type ?? \"\")?.executor;\n}\n\nfunction activatedPorts(node: FlowNode, result: unknown): { ports: string[]; value: unknown } {\n if (result && typeof result === \"object\") {\n const r = result as Record<string, unknown>;\n if (typeof r.__port === \"string\") {\n return { ports: [r.__port], value: r.value };\n }\n if (typeof r.branch === \"string\") {\n // `Object.hasOwn`, NOT `??`. The two are different questions:\n // no `value` key at all -> the whole result IS the payload (the case\n // this fallback exists for)\n // `value` present, null -> the payload is null; pass null on\n // `r.value ?? r` cannot tell them apart, so a branch whose payload was\n // null leaked the WRAPPER downstream -- every following node received\n // `{ branch, value }`, two fields no kind declares, while the fields it\n // does declare were absent. The reachable path is an upstream `transform`\n // whose dot-path did not resolve, which is exactly the silent-null case.\n // `Port.only`'s `?? null` never had it. All four runtimes shared this,\n // identically -- so no parity table could catch it; they agreed on being\n // wrong.\n return { ports: [r.branch], value: Object.prototype.hasOwnProperty.call(r, \"value\") ? r.value : r };\n }\n }\n // Resolve through the shared helper so the ports the runtime activates are\n // the same ones the canvas drew — including config-driven ports, which the\n // node's `data` does not carry. Falls back to a lone `out` when a node\n // declares nothing.\n const kind = getNodeKind((node.data as any)?.kind ?? node.type ?? \"\") ?? undefined;\n const declared = resolveNodePorts(node, kind).outputs?.map((p) => p.id);\n return { ports: declared?.length ? declared : [\"out\"], value: result };\n}\n\n/**\n * Emit a node's own status message for one phase of its execution, if it\n * declared one.\n *\n * Opt-in by absence: a node with no `startingMsg` / `stoppingMsg` says nothing,\n * because most nodes in a real graph are plumbing and narrating all of them\n * buries the two or three steps a person actually wants to follow.\n *\n * A message must be a non-empty string after trimming. An empty string is the\n * shape a cleared editor field takes, and a blank line in a progress feed is\n * indistinguishable from a real message that happens to render as nothing —\n * so it is treated as \"not set\" rather than as \"announce nothing visible\".\n */\nfunction announce(\n onEvent: (event: RunEvent) => void,\n node: FlowNode,\n phase: \"start\" | \"end\",\n): void {\n const data = node.data as { startingMsg?: unknown; stoppingMsg?: unknown } | undefined;\n const raw = phase === \"start\" ? data?.startingMsg : data?.stoppingMsg;\n if (typeof raw !== \"string\") return;\n\n const message = raw.trim();\n if (message === \"\") return;\n\n onEvent({ type: \"node-message\", nodeId: node.id, phase, message });\n}\n","import { getWorkflowResolver, isResolutionFailure } from \"./capabilities\";\nimport { runFlow } from \"../runtime/run-flow\";\nimport type { FlowGraph, NodeExecutor, RunEvent } from \"../types\";\n\n/**\n * `@fancy/subflow` — run another workflow and bring its result home.\n *\n * Core, not marketplace: it introduces no third-party dependency. It runs a\n * child graph through the very same engine, so the only thing it needs from the\n * host is where workflows live (`registerWorkflowResolver`).\n *\n * Three output modes, because both halves are genuinely useful:\n *\n * - `output` — the child's outputs arrive on `out` when it finishes.\n * - `stream` — the child's events are forwarded live on `stream` as they\n * happen, so a parent can show progress instead of a spinner.\n * - `both` — stream while running AND deliver the final outputs.\n *\n * Recursion is guarded by depth. A workflow that references itself (directly or\n * through a chain) would otherwise recurse until the stack dies, which surfaces\n * as an opaque crash rather than \"you built a loop\".\n */\n\nexport const DEFAULT_MAX_DEPTH = 8;\n\nexport type SubflowMode = \"output\" | \"stream\" | \"both\";\n\nexport function subflowMode(config: Record<string, unknown>): SubflowMode {\n const mode = config.mode;\n return mode === \"stream\" || mode === \"both\" ? mode : \"output\";\n}\n\n/** Ports follow the mode — `stream` only exists when something streams. */\nexport function subflowPorts(config: Record<string, unknown>) {\n const mode = subflowMode(config);\n const ports = [{ id: \"out\", label: \"result\" }];\n if (mode === \"stream\" || mode === \"both\") ports.unshift({ id: \"stream\", label: \"stream\" });\n return ports;\n}\n\n/**\n * Entry-point inputs for the child run: the node's explicit `inputs` mapping,\n * or — absent or empty — the parent's inputs handed to every entry node (a node\n * with no incoming edge), so the simple case needs no configuration at all.\n *\n * The same rule as the PHP and Python engines. This used to seed\n * `{ __parent: inputs }`: `initialInputs` is keyed by node id and nothing is\n * called `__parent`, so the child ran with no inputs and nothing said so.\n */\nexport function childInputs(\n config: Record<string, unknown>,\n child: FlowGraph,\n inputs: Record<string, unknown>,\n): Record<string, Record<string, unknown>> {\n const mapping = config.inputs;\n\n if (mapping && typeof mapping === \"object\" && !Array.isArray(mapping) && Object.keys(mapping).length > 0) {\n return mapping as Record<string, Record<string, unknown>>;\n }\n\n const hasIncoming = new Set(child.edges.map((edge) => edge.target));\n const seeded: Record<string, Record<string, unknown>> = {};\n\n for (const node of child.nodes) {\n if (!hasIncoming.has(node.id)) seeded[node.id] = inputs;\n }\n\n return seeded;\n}\n\nexport const subflowExecutor: NodeExecutor = async (ctx) => {\n const config = ((ctx.node.data as any)?.config ?? {}) as Record<string, unknown>;\n const ref = String(config.workflow ?? \"\").trim();\n if (!ref) ctx.abort(\"subflow has no workflow reference configured\");\n\n const resolver = getWorkflowResolver();\n if (!resolver) {\n ctx.abort(\n \"No workflow resolver registered. Call registerWorkflowResolver() so subflow can find the workflow it references.\",\n );\n }\n\n const maxDepth = Number.isFinite(config.maxDepth) ? Number(config.maxDepth) : DEFAULT_MAX_DEPTH;\n const depth = ctx.depth ?? 0;\n if (depth + 1 > maxDepth) {\n // Name the cause. \"Maximum call stack exceeded\" tells an author nothing\n // about the workflow they wired into itself.\n ctx.abort(\n `subflow depth limit reached (${maxDepth}) at \"${ref}\" — a workflow is referencing itself, directly or through a chain.`,\n );\n }\n\n // An optional pin. A workflow another workflow depends on is an interface:\n // without a pin, someone edits the child and the parent silently runs\n // different logic while still reporting success.\n const pinned = config.version === undefined || config.version === \"\" ? undefined : Number(config.version);\n if (pinned !== undefined && !Number.isInteger(pinned)) {\n ctx.abort(`subflow \"${ref}\" has a non-integer version pin (${String(config.version)}).`);\n }\n\n const resolved = await resolver!(ref, pinned);\n\n // A mismatch names BOTH versions. Reporting it as \"not found\" would send an\n // author looking for a workflow that is sitting right there — which is why\n // the resolver can say which of the two failures it hit.\n const child = isResolutionFailure(resolved)\n ? ctx.abort(\n resolved.reason === \"version-mismatch\"\n ? (resolved.message ??\n `subflow \"${ref}\" is pinned to version ${pinned}, but the host has ${resolved.available ?? \"a different version\"}.`)\n : (resolved.message ?? `subflow could not resolve workflow \"${ref}\"`),\n )\n : resolved;\n\n if (!child) ctx.abort(`subflow could not resolve workflow \"${ref}\"`);\n\n const mode = subflowMode(config);\n const streaming = mode === \"stream\" || mode === \"both\";\n\n const forward = (event: RunEvent) => {\n if (!streaming) return;\n // Surface the child's progress on the PARENT's feed as a log line against\n // this node. Re-emitting the child's raw events would collide with the\n // parent's own node ids — a child's \"node-status\" for its `output` node is\n // not a status for anything in the parent graph.\n const detail =\n event.type === \"node-status\"\n ? `${event.nodeId} ${event.status}`\n : event.type === \"run-end\"\n ? `finished (${event.ok ? \"ok\" : \"failed\"})`\n : event.type;\n ctx.emit({\n type: \"log\",\n nodeId: ctx.node.id,\n level: \"info\",\n message: `[${ref}] ${detail}`,\n });\n };\n\n const result = await runFlow(\n child!,\n // Inherit the parent's registry, then let the graph layer its own on top.\n // The inherited half is the fix; the layered half keeps a graph that\n // deliberately hands its child extra or different executors working.\n { ...(ctx.executors ?? {}), ...((config.executors as Record<string, unknown>) ?? {}) } as never,\n forward,\n {\n initialInputs: childInputs(config, child!, ctx.inputs as Record<string, unknown>),\n depth: depth + 1,\n // Push THIS node onto the identity path, so a node inside the child graph\n // cannot share an idempotency key with a same-named node in the parent —\n // or with the same child graph invoked from a different parent node.\n // Attempt and the first-attempt clock ride down unchanged: the child's\n // work happens inside this node's attempt.\n run: ctx.run?.descend(ctx.node.id),\n },\n );\n\n if (!result.ok) {\n ctx.abort(`subflow \"${ref}\" failed: ${result.error ?? \"unknown error\"}`);\n }\n\n // `stream` alone still emits a final value on `stream` so downstream nodes\n // have something to run on; `both` publishes on every declared port.\n if (mode === \"stream\") {\n return { __port: \"stream\", value: result.outputs };\n }\n if (mode === \"both\") {\n return result.outputs;\n }\n return { __port: \"out\", value: result.outputs };\n};\n","/**\n * `{{ }}` resolution — the TypeScript twin of `FancyFlow\\Nodes\\Support\\Expr`.\n *\n * ## Why this is opt-in and not wired into `runFlow`\n *\n * The PHP runtime resolves expressions inside its batteries-included executors.\n * The JS runtime never has: `runFlow` hands `node.data.config` to your executor\n * verbatim, so every host that uses `{{ }}` today already resolves it itself.\n * Turning resolution on inside `runFlow` would interpolate a second time over\n * values those hosts had already substituted — silently, and only for graphs\n * that happen to contain `{{` in their DATA.\n *\n * So this exports the semantics and changes no behaviour. Call it yourself:\n *\n * ```ts\n * const url = evaluateExpression(node.data.config.url, inputs);\n * ```\n *\n * ## The semantics are the PHP file's, deliberately\n *\n * This is not a general expression language and must not grow into one. It\n * resolves a dot-path against a context and nothing else — no arithmetic, no\n * comparisons, no calls. Hosts that want real expressions override the executor\n * (the PHP docblock points at symfony/expression-language for the same reason).\n *\n * Divergence here is a correctness bug rather than a style difference: the same\n * graph is authored once and may run on either runtime. `suites/shared/expr`\n * in `@particle-academy/fancy-conformance` is the fixture table both sides run,\n * so parity is a test result instead of a claim.\n */\n\n/** Anything a context or a resolved value can be. */\nexport type ExprValue = unknown;\n\n/** The context an expression resolves against — the executor's `inputs`. */\nexport type ExprContext = Record<string, ExprValue>;\n\n/**\n * `{{ … }}` is parsed by SCANNING, not by a regular expression.\n *\n * Two CodeQL `js/polynomial-redos` alerts (#2, #3) came out of the regex\n * version, and the second survived the obvious fix — which is the useful part.\n * Dropping the ambiguous `\\s*` around the capture killed one witness\n * (`'{{{{' + ' '.repeat(n)`) and CodeQL immediately produced another\n * (`'{{{{a'` repeated). That is not a pattern bug: a GLOBAL lazy scan for a\n * delimiter that never arrives is quadratic by construction — O(n) starts, each\n * scanning O(n) forward — and no amount of tuning the pattern removes it.\n *\n * `indexOf` has no backtracking at all. Each character is visited a bounded\n * number of times, so this is linear by construction rather than by careful\n * pattern-writing, and there is no next witness to find.\n *\n * The behaviour matches the PHP twin's regexes, and `shared/expr` is what holds\n * the two together.\n */\n\n/**\n * The inner text of a template that is EXACTLY one expression, else `null`.\n *\n * Starting with `{{` and ending with `}}` is not enough: the inner text may\n * contain neither `}}` nor `{{`. Without that check `{{ in.text }} --- {{\n * user.transcript }}` was ONE path, `in.text }} --- {{ user.transcript`, that\n * resolves to nothing, so the template returned null (fancy-flow-php#16). That\n * corner came from PHP's end-anchored pattern, whose lazy capture grew to reach\n * the end; it was documented here as deliberate and mirrored in every runtime,\n * so no parity table could see it. A template with several references now\n * interpolates each, and `{{a}}{{b}}` is two references.\n */\nfunction wholeExpression(trimmed: string): string | null {\n if (trimmed.length < 4) return null;\n if (!trimmed.startsWith(\"{{\") || !trimmed.endsWith(\"}}\")) return null;\n const inner = trimmed.slice(2, -2);\n if (inner.includes(\"}}\") || inner.includes(\"{{\")) return null;\n return inner;\n}\n\n/**\n * Replace every `{{ … }}` run, left to right, in a single pass.\n *\n * An unterminated `{{` is literal text — the same thing the regex did by simply\n * not matching, and the case an author hits constantly while typing.\n */\nfunction interpolate(template: string, resolve: (path: string) => string): string {\n let out = \"\";\n let i = 0;\n\n for (;;) {\n const open = template.indexOf(\"{{\", i);\n if (open === -1) return out + template.slice(i);\n\n const close = template.indexOf(\"}}\", open + 2);\n if (close === -1) return out + template.slice(i);\n\n out += template.slice(i, open) + resolve(template.slice(open + 2, close));\n i = close + 2;\n }\n}\n\n/**\n * Strings PHP's `Expr::truthy` treats as false.\n *\n * `\"0\"` and `\"false\"` are the ones that matter: a branch condition arriving as\n * text from a form or a JSON body would otherwise be truthy for every non-empty\n * string, and `\"false\"` taking the true branch is the kind of bug that looks\n * like the engine is broken.\n */\nconst FALSY_STRINGS = new Set([\"\", \"0\", \"false\", \"no\", \"off\", \"null\"]);\n\n/**\n * What a resolution attempt ANSWERS — did the path resolve, and to what.\n *\n * `resolvePath` cannot express this, and that is the defect it exists to fix:\n * it returns `null` both for \"this path does not exist\" and for \"this path\n * exists and holds null\". One value standing for two states.\n *\n * At the interpolation layer the collapse is worse, because `null` stringifies\n * to `\"\"`. A consumer put it exactly:\n *\n * > \"An unresolvable path yields `''`, so a wrong field is indistinguishable\n * > from an empty one at runtime.\"\n *\n * A misspelled field renders as an empty string, which looks precisely like a\n * field that is legitimately empty. The graph runs, the node succeeds, and the\n * output is quietly missing a value nobody is told about — worst on\n * LLM-authored graphs, where the field name was guessed in the first place.\n *\n * Same shape as the four `??` collapses fixed across all four runtimes on\n * 2026-08-26 (absent vs null), one layer up: **presence is the only correct\n * test, and a return value that cannot express presence cannot be tested for\n * it.** Hence a second return channel rather than a cleverer sentinel — every\n * sentinel is a legal value for somebody.\n */\nexport interface Resolution {\n /** Whether the path resolved at all. `false` means it does not exist. */\n resolved: boolean;\n /** The value, when `resolved`. `null` when not — do not read it blind. */\n value: ExprValue;\n}\n\n/** Thrown by the `\"throw\"` policy when a path does not resolve. */\nexport class UnresolvedPathError extends Error {\n constructor(readonly path: string) {\n super(\n `Expression path \"${path}\" did not resolve. ` +\n `Under the \"throw\" policy an unresolvable path is an error rather than an empty string.`,\n );\n this.name = \"UnresolvedPathError\";\n }\n}\n\n/**\n * What evaluation does with a path that does not resolve.\n *\n * - `\"empty\"` — today's behaviour, and the DEFAULT. Interpolates to `\"\"`; a\n * whole expression yields `null`. Unchanged so that widening this API breaks\n * nobody: 40 call sites across the runtimes assume it.\n * - `\"keep\"` — leave the `{{ … }}` text in place. The failure becomes VISIBLE\n * in the output without stopping the run, which is what you want for\n * human-reviewed content: a rendered `{{ in.recipient_naem }}` is self-\n * diagnosing in a way an absence never is.\n * - `\"throw\"` — refuse. For hosts that would rather fail a run than deliver a\n * silently incomplete result.\n *\n * Opt-in before default at the request of the consumer who reported it — the\n * host with the most LLM-authored graphs, and so both the biggest beneficiary\n * and the right place for it to break first if it is going to.\n */\nexport type UnresolvedPolicy = \"empty\" | \"keep\" | \"throw\";\n\n/** Options for {@link evaluateExpression} / {@link evaluateConfig}. */\nexport interface EvaluateOptions {\n /** What to do with a path that does not resolve. Default `\"empty\"`. */\n onUnresolved?: UnresolvedPolicy;\n}\n\n/**\n * Resolve a dot-path, reporting WHETHER it resolved.\n *\n * The same walk as `resolvePath` — deliberately, so the two can never disagree\n * about what resolves; `resolvePath` is defined in terms of this one below.\n *\n * A note on JS having two absent values: a key present with the value\n * `undefined` reports `resolved: false`, matching `resolvePath`'s long-standing\n * behaviour. It cannot arise from graph data (JSON has no `undefined`), and\n * changing it would make the two functions disagree for no reachable gain.\n */\nexport function tryResolvePath(path: string, context: ExprContext): Resolution {\n const unresolved: Resolution = { resolved: false, value: null };\n\n const trimmed = path.trim();\n if (trimmed === \"\") return unresolved;\n\n const segments = trimmed.split(\".\");\n let cursor: ExprValue;\n\n const head = segments[0];\n if (head === \"$json\" || head === \"$input\") {\n cursor = context !== null && typeof context === \"object\" && \"in\" in context ? context.in : context;\n segments.shift();\n } else {\n cursor = context;\n }\n\n for (const segment of segments) {\n if (cursor === null || cursor === undefined) return unresolved;\n if (typeof cursor !== \"object\") return unresolved;\n // Arrays are indexed by their numeric keys, matching PHP's list access.\n const next = (cursor as Record<string, ExprValue>)[segment];\n if (next === undefined) return unresolved;\n cursor = next;\n }\n\n return { resolved: true, value: cursor === undefined ? null : cursor };\n}\n\n/**\n * Resolve a dot-path against the context, honouring the `$json` / `$input`\n * alias.\n *\n * Both aliases point at the `in` port value when the context has one, and at\n * the whole context otherwise — the same fallback the PHP does, which is what\n * makes `{{ $json.x }}` work on a trigger node that has no upstream input.\n *\n * A path that does not resolve returns `null`, never `undefined`: PHP has one\n * absent value and JS has two, and letting the difference leak would make the\n * two runtimes disagree about `{{ missing }}` for no useful reason.\n */\nexport function resolvePath(path: string, context: ExprContext): ExprValue {\n // Defined in terms of `tryResolvePath` rather than repeating the walk. Two\n // copies of a traversal agree right up until someone edits one of them, and\n // nothing anywhere reports that -- the same reason the shared conformance\n // tables exist instead of hand-copied fixture rows.\n return tryResolvePath(path, context).value;\n}\n\n/**\n * Evaluate a template against a context.\n *\n * A string that is EXACTLY one expression returns the resolved value with its\n * type intact — `{{ $json.count }}` gives you a number, not `\"3\"`. Anything\n * else interpolates each run as text. That distinction is load-bearing: it is\n * what lets a config field carry either a value or a sentence.\n *\n * Non-string templates pass through untouched, so this is safe to map over a\n * whole config object.\n */\nexport function evaluateExpression(\n template: ExprValue,\n context: ExprContext,\n options: EvaluateOptions = {},\n): ExprValue {\n if (typeof template !== \"string\") return template;\n\n const policy = options.onUnresolved ?? \"empty\";\n\n const whole = wholeExpression(template.trim());\n if (whole !== null) {\n const r = tryResolvePath(whole, context);\n if (r.resolved) return r.value;\n\n // The whole-expression branch returns `null` under `\"empty\"`, not `\"\"` --\n // that is what it has always done, and the asymmetry is deliberate: this\n // branch preserves TYPE, so its absent value is the typed one.\n if (policy === \"throw\") throw new UnresolvedPathError(whole);\n return policy === \"keep\" ? template : null;\n }\n\n return interpolate(template, (path) => {\n const r = tryResolvePath(path, context);\n if (r.resolved) return stringify(r.value);\n if (policy === \"throw\") throw new UnresolvedPathError(path);\n return policy === \"keep\" ? `{{${path}}}` : \"\";\n });\n}\n\n/**\n * Truthiness for branch / switch decisions.\n *\n * Mirrors PHP's rules rather than JavaScript's, because the graph is authored\n * once and may run on either side. The two disagree in exactly the places a\n * workflow hits: `\"0\"` and `\"false\"` are truthy in JS and falsy here, and an\n * empty array is truthy in JS and falsy here.\n */\nexport function truthy(value: ExprValue): boolean {\n if (typeof value === \"boolean\") return value;\n if (value === null || value === undefined) return false;\n if (typeof value === \"string\") return !FALSY_STRINGS.has(value.trim().toLowerCase());\n if (Array.isArray(value)) return value.length > 0;\n if (typeof value === \"number\") return value !== 0;\n return Boolean(value);\n}\n\n/** Coerce a value to text the way interpolation does. */\nexport function text(value: ExprValue): string {\n return stringify(value);\n}\n\nfunction stringify(value: ExprValue): string {\n if (typeof value === \"string\") return value;\n if (typeof value === \"boolean\") return value ? \"true\" : \"false\";\n if (value === null || value === undefined) return \"\";\n if (typeof value === \"number\" || typeof value === \"bigint\") return String(value);\n try {\n return JSON.stringify(value) ?? \"\";\n } catch {\n return \"\";\n }\n}\n\n/**\n * Resolve every string in a config object, one level of nesting at a time.\n *\n * The convenience most hosts actually want, and the shape their hand-rolled\n * version usually takes. Opt-in like the rest of this module.\n */\nexport function evaluateConfig<T extends Record<string, ExprValue>>(\n config: T,\n context: ExprContext,\n options: EvaluateOptions = {},\n): T {\n const out: Record<string, ExprValue> = {};\n for (const [key, value] of Object.entries(config)) {\n out[key] = Array.isArray(value)\n ? value.map((v) => evaluateExpression(v, context, options))\n : value !== null && typeof value === \"object\"\n ? evaluateConfig(value as Record<string, ExprValue>, context, options)\n : evaluateExpression(value, context, options);\n }\n return out as T;\n}\n","import { evaluateExpression, truthy, text, tryResolvePath } from \"../expressions/expr\";\nimport type { NodeExecutor } from \"../types\";\n\n/**\n * Default executors for the four PURE-LOGIC builtins.\n *\n * ## Why these four ship one and `api_request` does not\n *\n * The kit's rule is that a kind ships schema + UI and the HOST wires the\n * executor, so it controls where memory, network and model calls actually go.\n * That reasoning is exactly right for `api_request`, `llm_call`, `memory_store`\n * — anything that touches the outside world, where a default would be a\n * decision made on the host's behalf about its own infrastructure.\n *\n * It is much weaker for `transform`, which does no I/O at all. `branch`,\n * `transform`, `merge` and `for_each` are pure functions of their inputs and\n * their config: there is exactly one correct answer and no infrastructure to\n * choose. Leaving them out meant every host reimplemented the same four, from\n * a schema, with no reference implementation to check against — and a consumer\n * asked whether that was deliberate (#13), which is a fair question to have to\n * ask.\n *\n * Host executors still take precedence: `pickExecutor` consults the host\n * registry first and falls back to the kind's own. Anyone who already wrote\n * these keeps theirs, unchanged.\n *\n * ## They implement the TypeScript schema, which is wider than the twin's\n *\n * `branch` and `transform` each have TWO authoring paths: a builder\n * (`conditions[]` / `fields[]`), which is what the editor produces by default,\n * and a raw-expression escape hatch (`condition` / `expression`). The Python\n * twin implements only the escape hatches. See the note in `docs/` — a graph\n * drawn the default way and run there routes or reshapes wrongly, silently.\n * These implement BOTH, so the TypeScript side is the complete one.\n */\n\ntype Config = Record<string, unknown>;\n\nfunction configOf(node: unknown): Config {\n return (((node as { data?: { config?: Config } })?.data?.config) ?? {}) as Config;\n}\n\n/** The expression context every one of these resolves against. */\nfunction contextOf(inputs: Record<string, unknown>): Record<string, unknown> {\n return inputs as Record<string, unknown>;\n}\n\n/** `{{ }}`-aware resolve. A non-string config value is already a value. */\nfunction resolve(value: unknown, inputs: Record<string, unknown>): unknown {\n if (typeof value !== \"string\") return value;\n return evaluateExpression(value, contextOf(inputs) as never);\n}\n\n/**\n * Warn when a routing decision was made on a path that DID NOT RESOLVE.\n *\n * `branch` asks `truthy()` of its resolved condition. An unresolvable path\n * yields `null`, `null` is falsy, and the run takes `false` — silently, and for\n * a reason that has nothing to do with the data. `switch_case` has the same\n * shape one step over: a `value` that does not resolve matches no case and\n * falls to `default`. From outside, both look exactly like a legitimate answer,\n * and half the graph then never runs on a run that reports success.\n *\n * Routing is deliberately UNCHANGED. Re-routing would silently change graphs\n * that have been running for months; the warning supplies the missing part,\n * which is the reason. A host that would rather fail can register its own\n * executor resolving with `evaluateExpression(…, { onUnresolved: \"throw\" })`.\n *\n * Only for a WHOLE `{{ path }}`. A condition mixing text with expressions is\n * being used as a string, and an unresolved fragment there is interpolation,\n * not routing. Absent is not null: a key holding `null` RESOLVED, and is silent.\n *\n * Ported from the PHP twin's `RoutingDiagnostics::warnIfUnresolved`, message and\n * detail verbatim — pinned by `flow/run-diagnostics` (fancy-flow#17). Found by\n * `flabs`: a triage graph whose urgency check named a field that did not\n * resolve routed every request, total payment failure included, as non-urgent.\n */\nfunction warnIfUnresolved(\n ctx: Parameters<NodeExecutor>[0],\n condition: unknown,\n tookPort: string,\n configKey = \"condition\",\n): void {\n if (typeof condition !== \"string\") return;\n\n const trimmed = condition.trim();\n if (trimmed.length < 4 || !trimmed.startsWith(\"{{\") || !trimmed.endsWith(\"}}\")) return;\n\n const path = trimmed.slice(2, -2).trim();\n\n // `{{ a }}{{ b }}` would otherwise read as one \"path\" spanning `}}{{` — a\n // template of two references rather than a missing field, and reporting it\n // as a missing field sends the reader somewhere useless.\n if (path === \"\" || path.includes(\"}}\")) return;\n\n if (tryResolvePath(path, ctx.inputs as never).resolved) return;\n\n const nodeId = ctx.node.id;\n ctx.emit({\n type: \"log\",\n nodeId,\n level: \"warn\",\n message:\n `Node ${nodeId} took the \"${tookPort}\" port because \\`${configKey}\\` resolved to NOTHING — ` +\n `the path ${path} names no field on this node's inputs. That is not the same as a false ` +\n `condition: the route was decided by an absent value rather than by the data.`,\n detail: { node: nodeId, configKey, path, tookPort },\n });\n}\n\n/**\n * One row of the `conditions` repeater.\n *\n * `left` is an expression; `right` is plain text in the schema but is resolved\n * too, because an author who types `{{ $json.threshold }}` there means it.\n */\nfunction conditionHolds(row: Config, inputs: Record<string, unknown>): boolean {\n const left = resolve(row.left, inputs);\n const right = resolve(row.right, inputs);\n const operator = typeof row.operator === \"string\" ? row.operator : \"eq\";\n\n const asText = (v: unknown) => text(v as never);\n const asNumber = (v: unknown) => {\n const n = typeof v === \"number\" ? v : Number(asText(v));\n return Number.isFinite(n) ? n : NaN;\n };\n // A number comparison against something unparseable is FALSE rather than a\n // throw: an author comparing a missing field to 10 wants the branch not to\n // take, not the run to die.\n const numeric = (fn: (a: number, b: number) => boolean) => {\n const a = asNumber(left);\n const b = asNumber(right);\n return Number.isFinite(a) && Number.isFinite(b) ? fn(a, b) : false;\n };\n const isEmpty = (v: unknown) =>\n v === null\n || v === undefined\n || v === \"\"\n || (Array.isArray(v) && v.length === 0)\n || (typeof v === \"object\" && !Array.isArray(v) && Object.keys(v as object).length === 0);\n\n switch (operator) {\n // Compared as TEXT, deliberately. `right` is a text field in the schema, so\n // `status == \"2\"` must match the number 2 an upstream node produced —\n // strict equality there would fail on a difference the author cannot see.\n case \"eq\": return asText(left) === asText(right);\n case \"neq\": return asText(left) !== asText(right);\n case \"contains\": return asText(left).includes(asText(right));\n case \"not_contains\": return !asText(left).includes(asText(right));\n case \"gt\": return numeric((a, b) => a > b);\n case \"gte\": return numeric((a, b) => a >= b);\n case \"lt\": return numeric((a, b) => a < b);\n case \"lte\": return numeric((a, b) => a <= b);\n case \"truthy\": return truthy(left as never);\n case \"falsy\": return !truthy(left as never);\n case \"empty\": return isEmpty(left);\n case \"not_empty\": return !isEmpty(left);\n default:\n // An operator the schema does not declare is a config error, not a\n // silent false — false would look exactly like a condition that did not\n // match, which is the answer an author would then try to debug.\n return false;\n }\n}\n\n/**\n * `branch` — two ports, exactly one taken.\n *\n * The raw `condition` WINS when set, because its own schema description says so\n * (\"Overrides the conditions above when set\"). The input passes through\n * unchanged down whichever side is taken and the other edge stays dead.\n */\nexport const branchExecutor: NodeExecutor = (ctx) => {\n const config = configOf(ctx.node);\n const inputs = ctx.inputs as Record<string, unknown>;\n\n let taken: boolean;\n\n const raw = config.condition;\n if (typeof raw === \"string\" && raw.trim() !== \"\") {\n taken = truthy(resolve(raw, inputs) as never);\n // A condition that did not RESOLVE is falsy, so the run takes `false`\n // silently and for the wrong reason. Routing is unchanged; the reason is\n // now visible.\n warnIfUnresolved(ctx, raw, taken ? \"true\" : \"false\");\n } else {\n const rows = Array.isArray(config.conditions) ? (config.conditions as Config[]) : [];\n // No conditions at all is FALSE, not true. An empty `all` is vacuously\n // true in logic, and that would send an unconfigured branch down the\n // success path — the one place a half-built graph should not go.\n if (rows.length === 0) {\n taken = false;\n } else {\n const results = rows.map((row) => conditionHolds(row, inputs));\n taken = config.match === \"any\" ? results.some(Boolean) : results.every(Boolean);\n }\n }\n\n return { __port: taken ? \"true\" : \"false\", value: ctx.inputs.in ?? ctx.inputs };\n};\n\n/**\n * `transform` — reshape in place. One `out` port, always active.\n *\n * `mode` decides which authoring path is read, defaulting to `fields` exactly\n * as the schema does.\n */\nexport const transformExecutor: NodeExecutor = (ctx) => {\n const config = configOf(ctx.node);\n const inputs = ctx.inputs as Record<string, unknown>;\n const passthrough = ctx.inputs.in ?? ctx.inputs;\n\n if (config.mode === \"expression\") {\n const expression = config.expression;\n if (typeof expression !== \"string\" || expression.trim() === \"\") return passthrough;\n return resolve(expression, inputs);\n }\n\n const rows = Array.isArray(config.fields) ? (config.fields as Config[]) : [];\n // Nothing configured passes the input through untouched rather than\n // returning `{}`. A half-built transform that silently empties the payload\n // breaks every node downstream of it with no clue where the data went.\n if (rows.length === 0) return passthrough;\n\n const out: Record<string, unknown> = {};\n let wrote = false;\n for (const row of rows) {\n const key = typeof row.key === \"string\" ? row.key.trim() : \"\";\n if (key === \"\") continue;\n out[key] = resolve(row.value, inputs);\n wrote = true;\n }\n return wrote ? out : passthrough;\n};\n\n/**\n * `merge` — several inputs, one value.\n *\n * `merge` combines into one object: a plain object is spread in by key,\n * anything else is keyed by its PORT id. `concat` flattens into one list.\n *\n * `null`/`undefined` inputs are skipped, and dead edges never reach the\n * executor at all — so a merge downstream of a branch receives only the side\n * that actually ran, which is what makes it a merge point rather than a join.\n */\nexport const mergeExecutor: NodeExecutor = (ctx) => {\n const entries = Object.entries(ctx.inputs as Record<string, unknown>);\n\n if (configOf(ctx.node).mode === \"concat\") {\n const out: unknown[] = [];\n for (const [, value] of entries) {\n if (value === null || value === undefined) continue;\n if (Array.isArray(value)) out.push(...value);\n else out.push(value);\n }\n return out;\n }\n\n const merged: Record<string, unknown> = {};\n for (const [port, value] of entries) {\n if (value === null || value === undefined) continue;\n if (typeof value === \"object\" && !Array.isArray(value)) Object.assign(merged, value);\n else merged[port] = value;\n }\n return merged;\n};\n\n/**\n * `for_each` — fan-out as DATA, not as jobs.\n *\n * Publishes the resolved collection and its size. It does NOT spawn one job per\n * item, and that is deliberate rather than unfinished: on a durable run a\n * `for_each` over 10,000 rows is one node, one claim, one checkpoint — not\n * 10,000. A host that wants true per-item iteration overrides this, which is\n * exactly what the executor seam is for.\n *\n * Matches the Python twin, including `concurrency` being carried for a host\n * that does iterate rather than acted on here.\n */\nexport const forEachExecutor: NodeExecutor = (ctx) => {\n const source = resolve(configOf(ctx.node).source, ctx.inputs as Record<string, unknown>);\n\n let items: unknown[];\n if (Array.isArray(source)) items = source;\n else if (source === null || source === undefined) items = [];\n else if (typeof source === \"object\") items = Object.values(source as object);\n else items = [source];\n\n return { items, count: items.length };\n};\n\n/*\n * ---------------------------------------------------------------------------\n * The DEPS-FREE remainder.\n *\n * The four above shipped because \"the host decides where I/O goes\" does not\n * apply to a pure function. The same argument covers five more, and leaving\n * them out was omission rather than a decision: `manual_trigger`, `output`,\n * `log`, `variable` and `switch_case` need no notifier, no store, no client and\n * no network. The PHP and Python twins ship all five, and they are four lines\n * each there.\n *\n * The cost of the gap was measured rather than guessed. A connector lab running\n * one WorkflowSchema on three engines had to hand-write `manual_trigger` and\n * `output` for its Node lane while PHP and Python got them from the engine, and\n * left a comment above them saying so — because a future parity failure on\n * those two kinds would otherwise be misattributed to this package. Every host\n * writes the same one-liners, slightly differently, and a parity suite cannot\n * tell \"the runtimes disagree\" from \"the two hosts disagree\".\n *\n * Ported from the PHP twin line for line, because parity is the contract: same\n * WorkflowSchema in, same `RunResult.outputs` out. A \"better\" implementation\n * here would be a divergence.\n *\n * `wait`, `user_input` and `human_approval` stay out. They look pure and are\n * not: each halts a run, and how a run halts is the host's decision (a durable\n * pause, a sleep, a queue re-drive) rather than a default anyone can pick.\n * ---------------------------------------------------------------------------\n */\n\n/**\n * `manual_trigger` — the entry point, publishing whatever started the run.\n *\n * Returns `ctx.inputs` whole. On a trigger those inputs ARE the run's initial\n * inputs, so this is what makes `{{ trigger.field }}` resolve downstream.\n */\nexport const manualTriggerExecutor: NodeExecutor = (ctx) => ctx.inputs;\n\n/**\n * `output` — the terminal node, publishing what reached it.\n *\n * `in ?? inputs`, not `inputs`: a node wired through its declared `in` port\n * publishes that port's value UNWRAPPED, which is what makes the terminal entry\n * in `RunResult.outputs` the plain result rather than a port map. Falling back\n * to the whole input map keeps a node with no inbound edge meaningful.\n */\nexport const outputExecutor: NodeExecutor = (ctx) => {\n const inputs = ctx.inputs as Record<string, unknown>;\n\n return inputs.in ?? inputs;\n};\n\n/**\n * `variable` — resolve an expression and publish it.\n *\n * The value is returned bare, not under a key. `{{ }}`-resolution is the whole\n * behaviour; a non-string config value is already a value and passes through.\n */\nexport const variableExecutor: NodeExecutor = (ctx) =>\n resolve(configOf(ctx.node).value, ctx.inputs as Record<string, unknown>);\n\n/**\n * `log` — emit a log event, and say what was logged.\n *\n * The message is emitted through `ctx.emit`, never written to a console: where\n * a host's logs GO is a host decision, and a `console.log` here would be this\n * package choosing one. The return value records what was emitted so a\n * downstream node can read it, matching the twins.\n */\nexport const logExecutor: NodeExecutor = (ctx) => {\n const config = configOf(ctx.node);\n const inputs = ctx.inputs as Record<string, unknown>;\n\n const level = (config.level as \"info\" | \"warn\" | \"error\") ?? \"info\";\n const message = text(resolve(config.message ?? \"\", inputs) as never);\n\n ctx.emit({ type: \"log\", nodeId: ctx.node.id, level, message });\n\n return { logged: message, level };\n};\n\n/**\n * `switch_case` — route to the port its resolved value names.\n *\n * An unmatched value falls to `default`, which is the same silent mis-route\n * `branch` has one step over: an expression that does not resolve becomes `\"\"`,\n * matches no case, and takes `default` — indistinguishable from a value that\n * genuinely matched nothing.\n *\n * So it warns when the value did not RESOLVE, and only then. This used to warn\n * on ANY unmatched value that came from an expression, including one that\n * resolved to a real value no case names — which is what `default` is FOR, and\n * a warning on a node's intended behaviour is noise that trains people to\n * ignore the one that matters. The twin warns on the unresolved path alone.\n */\nexport const switchCaseExecutor: NodeExecutor = (ctx) => {\n const config = configOf(ctx.node);\n const inputs = ctx.inputs as Record<string, unknown>;\n\n const expression = config.value;\n const value = text(resolve(expression, inputs) as never);\n const cases = (config.cases ?? {}) as Record<string, unknown>;\n\n const matched = Object.prototype.hasOwnProperty.call(cases, value);\n const port = matched ? String(cases[value]) : \"default\";\n\n warnIfUnresolved(ctx, expression, port, \"value\");\n\n return { __port: port, value: inputs.in ?? inputs };\n};\n","import type { NodeExecutor } from \"../types\";\nimport type { TranscriptWaitResult } from \"../runtime/terminal-transcript\";\n\n/**\n * The three terminal primitives.\n *\n * They are core rather than marketplace for the same reason `subflow` is: they\n * introduce no third-party dependency. The PTY lives behind\n * `registerTerminalHost`, so this file imports nothing that a browser build\n * would choke on.\n *\n * ## Why three, and not one\n *\n * A terminal is two different things depending on what is running in it, and\n * one node cannot serve both:\n *\n * - **A shell** answers a question and finishes, so the useful unit is\n * \"run this, tell me what it said and whether it worked\" — `terminal_run`.\n * - **A TUI** (Claude Code, Codex, a REPL, an installer asking a question)\n * never finishes. There is no exit code to wait for and no prompt to return\n * to; there is only text going in and text coming out. That is\n * `terminal_send` + `terminal_await`, and it is the pair that makes an agent\n * TUI drivable at all.\n *\n * Collapsing them into one node would mean guessing which mode the author\n * meant, and guessing wrong on a TUI means hanging until a timeout.\n */\n\nconst DEFAULT_TIMEOUT_MS = 120_000;\n\n/** Enter, in a PTY, is a carriage return. */\nconst ENTER = \"\\r\";\n\nfunction configOf(node: unknown): Record<string, unknown> {\n return (((node as { data?: { config?: Record<string, unknown> } })?.data?.config) ?? {}) as Record<\n string,\n unknown\n >;\n}\n\nfunction text(config: Record<string, unknown>, key: string): string {\n const value = config[key];\n return typeof value === \"string\" ? value : \"\";\n}\n\nfunction millis(config: Record<string, unknown>, key: string, fallback: number): number {\n const value = Number(config[key]);\n return Number.isFinite(value) && value >= 0 ? value : fallback;\n}\n\n/**\n * The marker `terminal_run` appends so it can tell when a command finished and\n * what it returned.\n *\n * A persistent shell has no completion channel — output just stops arriving,\n * and \"stopped arriving\" is indistinguishable from \"still thinking\". So the\n * command is followed by an echo of its own exit status, and THAT is what the\n * node waits for.\n *\n * The nonce matters: without it, a command whose own output happened to contain\n * the marker would end the wait early, and a run that left a stale marker in\n * the buffer would satisfy the NEXT command instantly. One per execution.\n */\nexport function exitMarker(nonce: string): { token: string; pattern: RegExp } {\n const token = `__fancy_flow_exit_${nonce}__`;\n return {\n token,\n // The expanded status is required to be digits. The shell ECHOES the typed\n // command back first, and that echo contains the marker with `$?`\n // unexpanded — so requiring digits is what stops the node matching its own\n // command line and reporting success before anything has run.\n pattern: new RegExp(`${token}:(\\\\d+)`),\n };\n}\n\nlet counter = 0;\n\nfunction newNonce(): string {\n counter += 1;\n return `${Date.now().toString(36)}${counter.toString(36)}${Math.random().toString(36).slice(2, 8)}`;\n}\n\n/**\n * Drop every line carrying the marker.\n *\n * Two of them exist in a normal run — the shell's echo of the command that was\n * typed, and the marker line itself — and neither is output the author asked\n * for. Filtering by line rather than slicing by index survives an echo that is\n * wrapped, disabled, or reordered, none of which is under our control.\n */\nfunction withoutMarker(output: string, token: string): string {\n return output\n .split(\"\\n\")\n .filter((line) => !line.includes(token))\n .join(\"\\n\")\n .trim();\n}\n\ntype Ctx = Parameters<NodeExecutor>[0];\n\n/**\n * Abort, in a shape the compiler believes.\n *\n * `ctx.abort` is declared `=> never`, but TypeScript only narrows control flow\n * through a never-returning call when the callee is a plain function name — not\n * a mutable property on a parameter. So calling `ctx.abort` directly left every\n * later line thinking the run might have continued, and the code had to be\n * written as if a value could still be `undefined` after it had been rejected.\n *\n * That is not a cosmetic complaint: the workaround is a non-null assertion, and\n * a `!` on a line that \"cannot be reached\" is indistinguishable from a `!` on a\n * line that can.\n */\nfunction fail(ctx: Ctx, message: string): never {\n ctx.abort(message);\n // Unreachable — `abort` throws. Present so this function's own return type is\n // honest without depending on the narrowing that is missing above.\n throw new Error(message);\n}\n\n/** Shared: resolve the lane's terminal, or abort naming the real problem. */\nfunction requireTerminal(ctx: Ctx): NonNullable<Ctx[\"terminal\"]> {\n if (!ctx.terminal) {\n fail(\n ctx,\n `\"${String(ctx.node.data?.label ?? ctx.node.id)}\" is a terminal node but is not inside a terminal lane. `\n + \"Drag it into one — a terminal node outside a lane has no session to talk to, and opening a private \"\n + \"shell for it would defeat the point of the lane.\",\n );\n }\n return ctx.terminal;\n}\n\n/**\n * The pattern a `terminal_await` waits for.\n *\n * Plain text is the default and is ESCAPED, so a prompt like `? (y/n)` matches\n * itself instead of being read as a regex and either failing to compile or —\n * worse — matching something else entirely while looking like it works.\n *\n * `g` and `y` are stripped from author-supplied flags. Both make a regex carry\n * `lastIndex` between calls, so the same pattern would resume part-way through\n * a buffer it had never read, and a wait would miss a match sitting in plain\n * view. The transcript resets `lastIndex` too; this is the belt to that\n * braces, because the cost of being wrong is a hang.\n */\nfunction compilePattern(ctx: Ctx, raw: string, config: Record<string, unknown>): RegExp {\n const flags = typeof config.flags === \"string\" ? config.flags.replace(/[gy]/g, \"\") : \"\";\n try {\n return config.mode === \"regex\"\n ? new RegExp(raw, flags)\n : new RegExp(raw.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"), flags);\n } catch (e) {\n // Named as an INVALID PATTERN. A bad regex thrown raw reads as a crash in\n // the engine rather than as a typo in one node's config.\n return fail(ctx, `terminal_await has an invalid regex: ${e instanceof Error ? e.message : String(e)}`);\n }\n}\n\n/**\n * `terminal_run` — send a command, wait for it to finish, report its exit code.\n *\n * Shell-only, and it says so on the node: a TUI never returns to a prompt, so\n * there is nothing for the marker to ride on. Use send + await there.\n */\nexport const terminalRunExecutor: NodeExecutor = async (ctx) => {\n const config = configOf(ctx.node);\n const command = text(config, \"command\").trim();\n if (!command) fail(ctx, \"terminal_run has no command configured\");\n\n const terminal = requireTerminal(ctx);\n const session = await terminal.session();\n const transcript = await terminal.transcript();\n\n const { token, pattern } = exitMarker(newNonce());\n const timeoutMs = millis(config, \"timeoutMs\", DEFAULT_TIMEOUT_MS);\n\n // Everything the shell said before this command is somebody else's output.\n // Carrying it into this node's result would attribute the previous command's\n // text — and, worse, let a marker-shaped string from earlier satisfy the wait.\n transcript.clear();\n\n await session.write(`${command}; printf '${token}:%s\\\\n' \"$?\"${ENTER}`);\n\n const result = await transcript.waitFor(pattern, { timeoutMs, exited: session.exited });\n\n if (result.status === \"exited\") {\n fail(\n ctx,\n `The terminal exited (code ${result.exitCode}${result.signal ? `, signal ${result.signal}` : \"\"}) while `\n + `running \"${command}\". The lane's session is gone, so every later node in this lane would fail too.`,\n );\n }\n\n if (result.status === \"timeout\") {\n fail(\n ctx,\n `\"${command}\" did not finish within ${timeoutMs}ms. Raise the node's timeout if it is genuinely slow — `\n + \"but a command that waits for input never finishes at all, and needs terminal_send + terminal_await.\",\n );\n }\n\n const exitCode = Number(result.match[1]);\n const output = withoutMarker(result.text, token);\n\n const failOnNonZero = config.failOnNonZero !== false;\n if (failOnNonZero && exitCode !== 0) {\n // Aborting is the default because the alternative is the failure this whole\n // estate keeps finding: a step that failed, a run that reports success, and\n // nothing anywhere that says the two disagree.\n ctx.abort(`\"${command}\" exited ${exitCode}.\\n${output}`);\n }\n\n return { output, exitCode, command };\n};\n\n/**\n * `terminal_send` — type at the process and move on.\n *\n * The node that makes a TUI usable. It does NOT wait, deliberately: what\n * counts as an answer is the author's decision, not ours, and pairing every\n * send with a hardcoded wait would make the common case (send, then await a\n * specific prompt) impossible to express.\n */\nexport const terminalSendExecutor: NodeExecutor = async (ctx) => {\n const config = configOf(ctx.node);\n const terminal = requireTerminal(ctx);\n const session = await terminal.session();\n\n const body = text(config, \"text\");\n // `submit !== false` — a send that does not press Enter leaves the text\n // sitting on the process's input line, which looks exactly like the process\n // ignoring it.\n const submit = config.submit !== false;\n\n if (config.clearFirst === true) {\n (await terminal.transcript()).clear();\n }\n\n await session.write(submit ? `${body}${ENTER}` : body);\n\n return { sent: body, submitted: submit };\n};\n\n/**\n * `terminal_await` — wait for the process to say something.\n *\n * The other half of driving a TUI. Without it a graph can type at Claude Code\n * and never learn that it has answered, so every downstream node runs against\n * whatever was on screen when the run started.\n *\n * Three ways it can end and all three are reported distinctly, because\n * collapsing them is how a wrong diagnosis gets shipped: a match, a timeout,\n * and the process EXITING — which without its own branch reads as \"timed out\",\n * sending whoever debugs it to lengthen a timeout on a process that is not\n * running.\n */\nexport const terminalAwaitExecutor: NodeExecutor = async (ctx) => {\n const config = configOf(ctx.node);\n const terminal = requireTerminal(ctx);\n const session = await terminal.session();\n const transcript = await terminal.transcript();\n\n const raw = text(config, \"pattern\").trim();\n if (!raw) fail(ctx, \"terminal_await has no pattern configured — there is nothing for it to wait for\");\n\n const pattern = compilePattern(ctx, raw, config);\n\n const timeoutMs = millis(config, \"timeoutMs\", DEFAULT_TIMEOUT_MS);\n const result: TranscriptWaitResult = await transcript.waitFor(pattern, {\n timeoutMs,\n exited: session.exited,\n });\n\n if (result.status === \"exited\") {\n fail(\n ctx,\n `The terminal exited (code ${result.exitCode}${result.signal ? `, signal ${result.signal}` : \"\"}) while `\n + `waiting for ${JSON.stringify(raw)}. It never appeared, and the lane's session is gone.`,\n );\n }\n\n if (result.status === \"timeout\") {\n // The default is to FAIL. An await that shrugs after a timeout lets the\n // next node type at a process that never became ready, and the run reports\n // success — so continuing has to be something the author asked for.\n if (config.onTimeout === \"continue\") {\n ctx.emit({\n type: \"log\",\n nodeId: ctx.node.id,\n level: \"warn\",\n message: `terminal_await: ${JSON.stringify(raw)} did not appear within ${timeoutMs}ms; continuing as configured.`,\n });\n return { matched: false, output: result.text, groups: [] };\n }\n\n fail(\n ctx,\n `${JSON.stringify(raw)} did not appear within ${timeoutMs}ms. Last output:\\n${result.text.slice(-2000)}`,\n );\n }\n\n return {\n matched: true,\n output: result.text,\n matchedText: result.match[0],\n // Capture groups are the reason to use regex mode at all — a prompt that\n // reports a session id or a file path is only useful if the value comes out.\n groups: result.match.slice(1),\n };\n};\n","import { registerBuiltinKindInternal } from \"./registry\";\nimport { humanFieldType, type HumanFieldType } from \"../components/FlowEditor/human-fields\";\nimport { llmRouterExecutor } from \"./llm-router\";\nimport { subflowExecutor, subflowPorts, DEFAULT_MAX_DEPTH } from \"./subflow\";\nimport {\n branchExecutor,\n forEachExecutor,\n logExecutor,\n manualTriggerExecutor,\n mergeExecutor,\n outputExecutor,\n switchCaseExecutor,\n transformExecutor,\n variableExecutor,\n} from \"./logic\";\nimport { terminalAwaitExecutor, terminalRunExecutor, terminalSendExecutor } from \"./terminal-nodes\";\nimport type { PortDescriptor } from \"../types\";\nimport type { ConfigField, NodeKindDefinition } from \"./types\";\n\n/**\n * Built-in agentic node kit — schema + UI for every kind, and an executor for\n * the ones that need nothing from the host.\n *\n * **MOST kinds ship no executor, not all of them.** This comment used to say\n * \"every kind ships with schema + UI but NO executor\", and that was false for\n * nine of the thirty-one — including `branch` and `transform`, which are\n * exactly the ones a host is most likely to hand-write after reading it. A\n * wrong comment on a library's front door is worse than no comment: it is\n * confidently actionable, and the action it prompts is wasted work.\n *\n * The fourteen that DO carry one are the ones needing nothing from the host:\n * `subflow`, `branch`, `for_each`, `merge`, `transform`, `llm_router`,\n * `terminal_run`, `terminal_send`, `terminal_await`, and — added once the\n * omission was noticed — `manual_trigger`, `output`, `log`, `variable` and\n * `switch_case`.\n *\n * The rest are left to the host because they need a decision only the host can\n * make: where memory, data, network and AI calls actually go. That is a choice\n * this runtime makes for being a BROWSER library rather than a property of the\n * contract — the PHP and Python twins ship ~25 and take those decisions by\n * injection instead (`ExecutorDeps` carries the notifier, store, llm, http).\n *\n * `wait`, `user_input` and `human_approval` stay host-wired even though they\n * look pure. Each HALTS a run, and how a run halts — a durable pause, a sleep,\n * a queue re-drive — is the host's architecture, not a default anyone can pick\n * on its behalf.\n */\n\n/**\n * What each `user_input` control actually resolves to, in the vocabulary\n * `OutputField.type` uses.\n *\n * Date / time controls are strings deliberately — the form resolves the input's\n * `value`, which is an ISO-ish string, not a `Date`. Claiming otherwise here\n * would make the picker lie in the other direction.\n */\nconst HUMAN_FIELD_OUTPUT_TYPE: Record<HumanFieldType, \"string\" | \"number\" | \"boolean\"> = {\n text: \"string\",\n textarea: \"string\",\n select: \"string\",\n date: \"string\",\n datetime: \"string\",\n time: \"string\",\n email: \"string\",\n url: \"string\",\n tel: \"string\",\n password: \"string\",\n number: \"number\",\n switch: \"boolean\",\n};\n\n/**\n * Ports for `switch_case`, derived from its `cases` map (match value → port).\n *\n * Several match values may route to the same port, so ports are de-duplicated\n * and labelled with every value that reaches them (\"a|c\"). `default` is always\n * present — unmatched input has to land somewhere.\n */\nfunction casePorts(cases: unknown): PortDescriptor[] {\n const byPort = new Map<string, string[]>();\n if (cases && typeof cases === \"object\" && !Array.isArray(cases)) {\n for (const [match, port] of Object.entries(cases as Record<string, unknown>)) {\n if (typeof port !== \"string\" || port === \"\" || port === \"default\") continue;\n const matches = byPort.get(port) ?? [];\n matches.push(match);\n byPort.set(port, matches);\n }\n }\n const ports: PortDescriptor[] = [...byPort].map(([id, matches]) => ({\n id,\n label: matches.join(\"|\"),\n }));\n return [...ports, { id: \"default\", label: \"default\" }];\n}\n\n/**\n * Ports for `llm_branch`, derived from its `routes` list. Blank and duplicate\n * port names are dropped so a half-typed route can't collide with a real one.\n */\nfunction routePorts(routes: unknown, fallback?: unknown): PortDescriptor[] {\n const ports: PortDescriptor[] = [];\n const seen = new Set<string>();\n if (Array.isArray(routes)) {\n for (const route of routes) {\n const id = (route as any)?.port;\n if (typeof id !== \"string\" || id.trim() === \"\" || seen.has(id)) continue;\n seen.add(id);\n ports.push({ id, label: id });\n }\n }\n if (fallback !== false && !seen.has(\"fallback\")) {\n ports.push({ id: \"fallback\", label: \"fallback\" });\n }\n if (ports.length === 0) ports.push({ id: \"out\" });\n return ports;\n}\n\nconst HTTP_METHODS: ConfigField[] = [\n { type: \"select\", key: \"method\", label: \"Method\", options: [\n { value: \"GET\", label: \"GET\" },\n { value: \"POST\", label: \"POST\" },\n { value: \"PUT\", label: \"PUT\" },\n { value: \"PATCH\", label: \"PATCH\" },\n { value: \"DELETE\", label: \"DELETE\" },\n ], default: \"GET\", required: true },\n];\n\nconst KINDS: NodeKindDefinition[] = [\n // ───────────── Triggers ─────────────\n {\n name: \"@particle-academy/manual_trigger\",\n executor: manualTriggerExecutor,\n // Returns the raw inputs MAP, not the `in` port -- flat at an entry\n // point, port-keyed the moment the node has an inbound edge.\n emits: \"input-map-merged\",\n aliases: [\"manual_trigger\", \"@fancy/manual_trigger\"],\n category: \"trigger\",\n label: \"Manual\",\n description: \"Entry point fired when the user clicks Run.\",\n icon: \"⚡\",\n inputs: [],\n outputs: [{ id: \"out\" }],\n },\n {\n name: \"@particle-academy/webhook_trigger\",\n aliases: [\"webhook_trigger\", \"@fancy/webhook_trigger\"],\n category: \"trigger\",\n label: \"Webhook\",\n description: \"Triggered by an inbound HTTP request to a host-provided URL.\",\n icon: \"📡\",\n inputs: [],\n outputs: [{ id: \"out\", label: \"payload\" }],\n configSchema: [\n { type: \"text\", key: \"path\", label: \"Path\", placeholder: \"/hooks/my-flow\", required: true },\n { type: \"select\", key: \"method\", label: \"Method\", options: [\n { value: \"POST\", label: \"POST\" }, { value: \"GET\", label: \"GET\" },\n ], default: \"POST\" },\n { type: \"credential\", key: \"secret\", label: \"Verifying secret\", credentialType: \"webhook_secret\" },\n ],\n },\n {\n name: \"@particle-academy/schedule_trigger\",\n outputShape: [\n { path: \"cron\", type: \"string\" as const, description: \"The cron expression that fired.\" },\n { path: \"timezone\", type: \"string\" as const, description: \"The timezone it was evaluated in.\" },\n ],\n // Merges $ctx->inputs ITSELF beside cron/timezone -- the MAP, whose\n // shape depends on position, not each port's payload the way `merge` does.\n emits: \"input-map-merged\",\n aliases: [\"schedule_trigger\", \"@fancy/schedule_trigger\"],\n category: \"trigger\",\n label: \"Schedule\",\n description: \"Fires on a cron schedule (host-implemented).\",\n icon: \"⏱\",\n inputs: [],\n outputs: [{ id: \"out\" }],\n configSchema: [\n { type: \"text\", key: \"cron\", label: \"Cron\", placeholder: \"*/5 * * * *\", required: true,\n description: \"Standard 5-field cron expression.\" },\n { type: \"text\", key: \"timezone\", label: \"Timezone\", placeholder: \"UTC\", default: \"UTC\" },\n ],\n },\n {\n name: \"@particle-academy/user_input\",\n // The keys an author declared on THIS node — the case a static list cannot\n // express, and the one issue #5 named.\n //\n // The TYPE comes from the same normalizer the form renders with, so the\n // variable picker agrees with what the run actually resolves. It used to say\n // `string` for every field, which was wrong the moment a field was a number\n // or a switch — the picker told an author `{{ $json.age }}` was text while\n // the form handed the next node a number.\n outputShape: (config: { fields?: Array<{ key?: string; label?: string; type?: unknown }> }) =>\n (config.fields ?? [])\n .filter((f) => typeof f.key === \"string\" && f.key !== \"\")\n .map((f) => ({\n path: f.key as string,\n type: HUMAN_FIELD_OUTPUT_TYPE[humanFieldType(f.type)],\n description: f.label,\n })),\n aliases: [\"user_input\", \"@fancy/user_input\"],\n pausesForHuman: \"input\",\n category: \"human\",\n label: \"User Input\",\n description: \"Pause the flow until the user submits the configured form.\",\n icon: \"✎\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"out\", label: \"values\" }],\n configSchema: [\n { type: \"text\", key: \"title\", label: \"Form title\", default: \"Need your input\" },\n {\n type: \"repeater\",\n key: \"fields\",\n label: \"Fields\",\n description: \"The form the run pauses on.\",\n titleKey: \"label\",\n addLabel: \"Add field\",\n minItems: 1,\n fields: [\n { type: \"text\", key: \"key\", label: \"Key\", required: true, placeholder: \"answer\" },\n { type: \"text\", key: \"label\", label: \"Label\", required: true, placeholder: \"Your answer\" },\n {\n type: \"select\", key: \"type\", label: \"Type\", default: \"text\",\n // Every control `HumanPrompt` can render. A type the form supports\n // but the panel cannot select is reachable only by hand-editing the\n // workflow JSON — which is the audience this panel exists for.\n options: [\n { value: \"text\", label: \"Text\" },\n { value: \"textarea\", label: \"Long text\" },\n { value: \"number\", label: \"Number\" },\n { value: \"select\", label: \"Select\" },\n { value: \"switch\", label: \"Switch (yes / no)\" },\n { value: \"date\", label: \"Date\" },\n { value: \"datetime\", label: \"Date + time\" },\n { value: \"time\", label: \"Time\" },\n { value: \"email\", label: \"Email\" },\n { value: \"url\", label: \"URL\" },\n { value: \"tel\", label: \"Phone\" },\n { value: \"password\", label: \"Password\" },\n ],\n },\n {\n // Without this a panel-authored select had nothing to choose from,\n // so it rendered an empty dropdown — the type was declarable and\n // unusable in the same breath.\n type: \"keyvalue\",\n key: \"options\",\n label: \"Choices\",\n description: \"Select fields only. Left is the value the flow receives, right is what the person sees.\",\n keyLabel: \"Value\",\n valueLabel: \"Label\",\n keyPlaceholder: \"small\",\n valuePlaceholder: \"Small\",\n addLabel: \"Add choice\",\n },\n { type: \"switch\", key: \"required\", label: \"Required\", default: false },\n ],\n default: [{ key: \"answer\", label: \"Your answer\", type: \"textarea\", required: true }],\n },\n ],\n },\n\n {\n name: \"@particle-academy/rich_user_input\",\n aliases: [\"rich_user_input\", \"@fancy/rich_user_input\"],\n pausesForHuman: \"input\",\n category: \"human\",\n label: \"Rich User Input\",\n description: \"Pause the flow on a fully authored page — content, required reading, multi-section forms.\",\n icon: \"▤\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"out\", label: \"values\" }],\n configSchema: [\n { type: \"text\", key: \"title\", label: \"Step title\", default: \"Please review\" },\n {\n type: \"document\",\n key: \"document\",\n label: \"Page content\",\n documentType: \"stages\",\n description: \"Authored with the host's document editor (fancy-cms Stages).\",\n },\n { type: \"switch\", key: \"requireConfirm\", label: \"Require explicit confirmation\", default: true },\n { type: \"text\", key: \"submitLabel\", label: \"Submit button\", default: \"Continue\" },\n ],\n },\n\n {\n name: \"@particle-academy/subflow\",\n aliases: [\"subflow\", \"@fancy/subflow\"],\n category: \"logic\",\n label: \"SubFlow\",\n description: \"Run another workflow and bring its result — or its live progress — back into this one.\",\n icon: \"⧉\",\n inputs: [{ id: \"in\" }],\n // The stream port only exists when something actually streams.\n outputs: (config: any) => subflowPorts(config ?? {}),\n // Core, not marketplace: it runs a child graph through this same engine and\n // needs nothing from outside except where workflows live.\n executor: subflowExecutor,\n configSchema: [\n { type: \"text\", key: \"workflow\", label: \"Workflow\", required: true,\n placeholder: \"onboarding-v2\",\n description: \"Reference resolved by the host's registerWorkflowResolver().\" },\n { type: \"number\", key: \"version\", label: \"Pin to version\",\n description: \"Optional. Leave blank to always run the child's current version. Pinning fails the run loudly if the child has moved on — without it, someone edits the child and this flow silently runs different logic.\" },\n {\n type: \"select\", key: \"mode\", label: \"Return\", default: \"output\",\n options: [\n { value: \"output\", label: \"Output when it finishes\" },\n { value: \"stream\", label: \"Stream progress as it runs\" },\n { value: \"both\", label: \"Both — stream, then output\" },\n ],\n description: \"Streaming adds a second port so a parent can show progress instead of a spinner.\",\n },\n { type: \"keyvalue\", key: \"inputs\", label: \"Input mapping\",\n description: \"Values handed to the child's entry points. Omit to pass this node's inputs straight through.\",\n keyLabel: \"Name\", valueLabel: \"Value\", addLabel: \"Add input\" },\n { type: \"number\", key: \"maxDepth\", label: \"Max nesting depth\", default: DEFAULT_MAX_DEPTH, min: 1, max: 32,\n description: \"Guards against a workflow referencing itself.\" },\n ],\n },\n\n // ───────────── Logic ─────────────\n {\n name: \"@particle-academy/branch\",\n // returns its input on the chosen port\n emits: \"input\",\n aliases: [\"branch\", \"@fancy/branch\"],\n // Pure logic: no I/O to choose, so a default is safe. A host\n // executor still wins -- pickExecutor consults the registry first.\n executor: branchExecutor,\n category: \"logic\",\n label: \"Branch\",\n description: \"Multi-way branch on a condition or value.\",\n icon: \"◇\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"true\", label: \"true\" }, { id: \"false\", label: \"false\" }],\n configSchema: [\n {\n type: \"select\", key: \"match\", label: \"Match\", default: \"all\",\n options: [\n { value: \"all\", label: \"All conditions (AND)\" },\n { value: \"any\", label: \"Any condition (OR)\" },\n ],\n },\n {\n type: \"repeater\",\n key: \"conditions\",\n label: \"Conditions\",\n description: \"Routes to `true` when these match, otherwise `false`.\",\n titleKey: \"left\",\n addLabel: \"Add condition\",\n minItems: 1,\n fields: [\n { type: \"expression\", key: \"left\", label: \"Value\", example: \"{{ $json.status }}\", required: true },\n {\n type: \"select\", key: \"operator\", label: \"Is\", default: \"eq\",\n options: [\n { value: \"eq\", label: \"equal to\" },\n { value: \"neq\", label: \"not equal to\" },\n { value: \"contains\", label: \"contains\" },\n { value: \"not_contains\", label: \"does not contain\" },\n { value: \"gt\", label: \"greater than\" },\n { value: \"gte\", label: \"greater than or equal to\" },\n { value: \"lt\", label: \"less than\" },\n { value: \"lte\", label: \"less than or equal to\" },\n { value: \"truthy\", label: \"true\" },\n { value: \"falsy\", label: \"false\" },\n { value: \"empty\", label: \"empty\" },\n { value: \"not_empty\", label: \"not empty\" },\n ],\n },\n { type: \"text\", key: \"right\", label: \"Compared to\", placeholder: \"active\" },\n ],\n default: [{ left: \"\", operator: \"eq\", right: \"\" }],\n },\n {\n type: \"expression\",\n key: \"condition\",\n label: \"Raw expression (advanced)\",\n example: \"{{ $json.active && $json.score > 10 }}\",\n description: \"Escape hatch for logic the builder can't express. Overrides the conditions above when set.\",\n },\n ],\n },\n {\n name: \"@particle-academy/switch_case\",\n executor: switchCaseExecutor,\n // returns its input on the chosen port\n emits: \"input\",\n aliases: [\"switch_case\", \"@fancy/switch_case\"],\n category: \"logic\",\n label: \"Switch\",\n description: \"Route to one of N labelled outputs based on a key.\",\n icon: \"⤳\",\n inputs: [{ id: \"in\" }],\n // Ports ARE the config: every distinct port a case routes to becomes an\n // output handle, plus the always-present `default`. Editing the cases map\n // moves the ports on the canvas and the ports the runtime activates.\n outputs: (config: any) => casePorts(config?.cases),\n configSchema: [\n { type: \"expression\", key: \"value\", label: \"Switch on\", example: \"{{ $json.kind }}\", required: true },\n {\n type: \"keyvalue\",\n key: \"cases\",\n label: \"Cases\",\n description: \"Match value → output port. Unmatched input takes `default`.\",\n keyLabel: \"When value is\",\n valueLabel: \"Route to port\",\n keyPlaceholder: \"a\",\n valuePlaceholder: \"case_a\",\n addLabel: \"Add case\",\n default: { a: \"case_a\", b: \"case_b\" },\n },\n ],\n },\n {\n name: \"@particle-academy/for_each\",\n outputShape: [\n { path: \"items\", type: \"array\" },\n { path: \"count\", type: \"number\" },\n ],\n aliases: [\"for_each\", \"@fancy/for_each\"],\n // Pure logic: no I/O to choose, so a default is safe. A host\n // executor still wins -- pickExecutor consults the registry first.\n executor: forEachExecutor,\n category: \"logic\",\n label: \"For Each\",\n description: \"Iterate over a list, emitting each item on `item`.\",\n icon: \"↻\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"item\", label: \"item\" }, { id: \"done\", label: \"done\" }],\n configSchema: [\n { type: \"expression\", key: \"source\", label: \"List\", example: \"{{ $json.users }}\", required: true },\n { type: \"number\", key: \"concurrency\", label: \"Concurrency\", default: 1, min: 1, max: 50 },\n ],\n },\n {\n name: \"@particle-academy/merge\",\n // `merge` mode unions every object input at the TOP level; `concat` builds\n // a list instead, whose elements are not addressable as fields. So concat\n // declares NOTHING rather than an empty list -- `[]` would claim \"emits no\n // fields\" of a kind that emits a list, which is false and refuses every\n // reference.\n emits: (config: { mode?: string }) =>\n (config?.mode ?? \"merge\") === \"concat\" ? null : (\"inputs-merged\" as const),\n aliases: [\"merge\", \"@fancy/merge\"],\n // Pure logic: no I/O to choose, so a default is safe. A host\n // executor still wins -- pickExecutor consults the registry first.\n executor: mergeExecutor,\n category: \"logic\",\n label: \"Merge\",\n description: \"Combine multiple inputs into one object or array.\",\n icon: \"⊕\",\n inputs: [{ id: \"a\" }, { id: \"b\" }],\n outputs: [{ id: \"out\" }],\n configSchema: [\n { type: \"select\", key: \"mode\", label: \"Mode\", default: \"merge\",\n options: [{ value: \"merge\", label: \"Object merge\" }, { value: \"concat\", label: \"Array concat\" }] },\n ],\n },\n {\n name: \"@particle-academy/wait\",\n outputShape: [\n { path: \"waited\", type: \"string\" as const, description: \"Which wait mode ran.\" },\n { path: \"duration\", type: \"number\" as const, description: \"How long it waited.\" },\n { path: \"input\", type: \"unknown\" as const, description: \"The value that arrived, carried forward.\" },\n ],\n aliases: [\"wait\", \"@fancy/wait\"],\n category: \"logic\",\n label: \"Wait\",\n description: \"Sleep or wait for an external event.\",\n icon: \"⏸\",\n configSchema: [\n { type: \"select\", key: \"mode\", label: \"Mode\", default: \"duration\",\n options: [{ value: \"duration\", label: \"Duration\" }, { value: \"until\", label: \"Until timestamp\" }, { value: \"event\", label: \"External event\" }] },\n { type: \"text\", key: \"duration\", label: \"Duration\", placeholder: \"5s, 10m, 1h\", description: \"Used when mode = duration.\" },\n ],\n },\n {\n name: \"@particle-academy/transform\",\n // Two behaviours: the input unchanged when no expression is configured,\n // else the shape that expression names. So the RELATION is config-dependent.\n emits: (config: { expression?: string }) =>\n (config?.expression ?? \"\") === \"\" ? (\"input\" as const) : (\"expression:expression\" as const),\n aliases: [\"transform\", \"@fancy/transform\"],\n // Pure logic: no I/O to choose, so a default is safe. A host\n // executor still wins -- pickExecutor consults the registry first.\n executor: transformExecutor,\n category: \"logic\",\n label: \"Transform\",\n description: \"Reshape data with an expression.\",\n icon: \"ƒ\",\n configSchema: [\n {\n type: \"select\", key: \"mode\", label: \"Build the output\", default: \"fields\",\n options: [\n { value: \"fields\", label: \"Field by field\" },\n { value: \"expression\", label: \"One expression\" },\n ],\n },\n {\n type: \"repeater\",\n key: \"fields\",\n label: \"Output fields\",\n description: \"Each row becomes a key on the result.\",\n titleKey: \"key\",\n addLabel: \"Add field\",\n fields: [\n { type: \"text\", key: \"key\", label: \"Key\", required: true, placeholder: \"name\" },\n { type: \"expression\", key: \"value\", label: \"Value\", example: \"{{ $json.first }}\", required: true },\n ],\n default: [{ key: \"\", value: \"\" }],\n },\n {\n type: \"expression\",\n key: \"expression\",\n label: \"Expression (advanced)\",\n example: \"{{ { id: $json.id, name: $json.first + ' ' + $json.last } }}\",\n description: \"Used when the mode above is set to one expression.\",\n },\n ],\n },\n\n // ───────────── Data ─────────────\n {\n name: \"@particle-academy/memory_store\",\n aliases: [\"memory_store\", \"@fancy/memory_store\"],\n category: \"data\",\n label: \"Memory Store\",\n description: \"Read or write per-conversation memory.\",\n icon: \"🧠\",\n configSchema: [\n { type: \"select\", key: \"operation\", label: \"Operation\", required: true, default: \"read\",\n options: [{ value: \"read\", label: \"Read\" }, { value: \"write\", label: \"Write\" }, { value: \"append\", label: \"Append\" }] },\n { type: \"text\", key: \"key\", label: \"Key\", placeholder: \"user.preferences\", required: true },\n { type: \"expression\", key: \"value\", label: \"Value (write/append only)\", example: \"{{ $json }}\" },\n { type: \"credential\", key: \"store\", label: \"Memory store\", credentialType: \"memory_store\" },\n ],\n },\n {\n name: \"@particle-academy/data_store\",\n aliases: [\"data_store\", \"@fancy/data_store\"],\n category: \"data\",\n label: \"Data Store\",\n description: \"Key-value or table read/write against a host store.\",\n icon: \"🗃\",\n configSchema: [\n { type: \"select\", key: \"operation\", label: \"Operation\", required: true, default: \"get\",\n options: [\n { value: \"get\", label: \"Get\" }, { value: \"set\", label: \"Set\" }, { value: \"delete\", label: \"Delete\" },\n { value: \"query\", label: \"Query\" }, { value: \"list\", label: \"List\" },\n ] },\n { type: \"text\", key: \"table\", label: \"Table / collection\", required: true },\n { type: \"text\", key: \"key\", label: \"Key\" },\n { type: \"keyvalue\", key: \"where\", label: \"Where\",\n description: \"Field/value pairs to match. For query and list operations.\",\n keyLabel: \"Field\", valueLabel: \"Equals\", addLabel: \"Add filter\" },\n { type: \"expression\", key: \"value\", label: \"Value (set only)\", example: \"{{ $json }}\" },\n { type: \"credential\", key: \"store\", label: \"Data store\", credentialType: \"data_store\" },\n ],\n },\n {\n name: \"@particle-academy/variable\",\n executor: variableExecutor,\n // evaluates the expression in config.value\n emits: \"expression:value\",\n aliases: [\"variable\", \"@fancy/variable\"],\n category: \"data\",\n label: \"Variable\",\n description: \"Workflow-scoped value used by other nodes.\",\n icon: \"𝓍\",\n configSchema: [\n { type: \"text\", key: \"name\", label: \"Name\", required: true },\n { type: \"expression\", key: \"value\", label: \"Value\", required: true },\n ],\n },\n\n // ───────────── AI ─────────────\n {\n name: \"@particle-academy/llm_call\",\n // LlmClient::complete() -> array{text:string,data?:mixed,usage?:array,raw?:mixed}\n //\n // A FUNCTION of config, because `data` exists only when this node was asked\n // for a schema. Declaring it statically would offer `{{ $json.data }}` on\n // every llm_call in the kit, including the ones that emit nothing of the\n // sort — and a suggestion that resolves to null at runtime is worse than no\n // suggestion, since the picker is exactly what gave the author confidence.\n outputShape: (config: { response_schema?: unknown }) => {\n const asked =\n config?.response_schema != null &&\n config.response_schema !== \"\" &&\n !(Array.isArray(config.response_schema) && config.response_schema.length === 0);\n\n return [\n { path: \"text\", type: \"string\" as const, description: \"The model's completion.\" },\n ...(asked\n ? [{ path: \"data\", type: \"unknown\" as const, description: \"The parsed, schema-checked result.\" }]\n : []),\n { path: \"usage\", type: \"object\" as const, description: \"Token counts, when the provider reports them.\" },\n { path: \"raw\", type: \"unknown\" as const, description: \"The provider's untouched response.\" },\n ];\n },\n aliases: [\"llm_call\", \"@fancy/llm_call\"],\n category: \"ai\",\n label: \"LLM Call\",\n description: \"Send a prompt + context to a model and receive a response.\",\n icon: \"✦\",\n configSchema: [\n { type: \"select\", key: \"provider\", label: \"Provider\", default: \"anthropic\",\n options: [\n { value: \"anthropic\", label: \"Anthropic\" },\n { value: \"openai\", label: \"OpenAI\" },\n { value: \"custom\", label: \"Custom\" },\n ] },\n { type: \"text\", key: \"model\", label: \"Model\", placeholder: \"claude-sonnet-4-5\", required: true },\n { type: \"textarea\", key: \"system\", label: \"System prompt\", rows: 4 },\n { type: \"expression\", key: \"prompt\", label: \"User prompt\", example: \"{{ $json.question }}\", required: true },\n { type: \"number\", key: \"temperature\", label: \"Temperature\", min: 0, max: 2, step: 0.1, default: 0.7 },\n { type: \"number\", key: \"max_tokens\", label: \"Max tokens\", min: 1, max: 8192, default: 1024 },\n {\n type: \"repeater\", key: \"tools\", label: \"Tools\",\n description: \"Tools the model may call.\",\n titleKey: \"name\", addLabel: \"Add tool\",\n fields: [\n { type: \"text\", key: \"name\", label: \"Name\", required: true, placeholder: \"search_index\" },\n { type: \"text\", key: \"description\", label: \"When to use it\" },\n { type: \"json\", key: \"input_schema\", label: \"Input schema\",\n description: \"JSON Schema for the tool's arguments.\" },\n ],\n },\n {\n type: \"json\", key: \"response_schema\", label: \"Response schema\",\n description:\n \"Optional JSON Schema. When set, the runtime asks the provider for schema-valid JSON \" +\n \"and the node emits the parsed value as `data` — reference it as {{ $json.data }}. \" +\n \"A response that cannot be parsed or does not match FAILS the node rather than \" +\n \"passing an empty value downstream.\",\n },\n { type: \"credential\", key: \"credential\", label: \"API credential\", credentialType: \"llm_credential\" },\n ],\n },\n {\n name: \"@particle-academy/llm_router\",\n outputShape: [\n { path: \"route\", type: \"string\" as const, description: \"The port the model chose.\" },\n { path: \"reason\", type: \"string\" as const, description: \"Why the model chose it.\" },\n { path: \"input\", type: \"unknown\" as const, description: \"The value that arrived, carried forward.\" },\n ],\n // Every id this node has ever shipped under keeps resolving — MOIC's saved\n // flows carry the bare `llm_branch`.\n aliases: [\"llm_router\", \"llm_branch\", \"@fancy/llm_branch\", \"@fancy/llm_router\"],\n category: \"ai\",\n label: \"LLM Router\",\n description: \"Let a model choose which route the flow takes.\",\n icon: \"✧\",\n inputs: [{ id: \"in\" }],\n // Each declared route is a port. The executor returns `{ __port: id }`\n // (or `Port.only(id)` on the PHP runtime) to pick one.\n outputs: (config: any) => routePorts(config?.routes, config?.fallback),\n // A shuttle, not an engine: it carries the routes out to whatever LLM\n // client the host registered and carries the choice back. No provider SDK\n // reaches core, so this stays a builtin without adding a dependency.\n executor: llmRouterExecutor,\n configSchema: [\n { type: \"textarea\", key: \"system\", label: \"System prompt\", rows: 3,\n description: \"Optional framing for the routing decision.\" },\n { type: \"expression\", key: \"prompt\", label: \"What to route on\",\n example: \"{{ $json.message }}\", required: true },\n {\n type: \"repeater\",\n key: \"routes\",\n label: \"Routes\",\n description: \"The model picks exactly one. Descriptions are what it chooses between — make them distinct.\",\n titleKey: \"port\",\n addLabel: \"Add route\",\n minItems: 2,\n fields: [\n { type: \"text\", key: \"port\", label: \"Port\", required: true, placeholder: \"billing\" },\n { type: \"text\", key: \"description\", label: \"When to choose it\", required: true,\n placeholder: \"The user is asking about an invoice, refund, or payment.\" },\n ],\n default: [\n { port: \"a\", description: \"Describe when the model should pick this route.\" },\n { port: \"b\", description: \"Describe when the model should pick this route.\" },\n ],\n },\n { type: \"select\", key: \"provider\", label: \"Provider\", default: \"anthropic\",\n options: [\n { value: \"anthropic\", label: \"Anthropic\" },\n { value: \"openai\", label: \"OpenAI\" },\n { value: \"custom\", label: \"Custom\" },\n ] },\n { type: \"text\", key: \"model\", label: \"Model\", placeholder: \"claude-sonnet-4-5\" },\n { type: \"switch\", key: \"fallback\", label: \"Add a `fallback` port\", default: true,\n description: \"Where the flow goes if the model returns no usable route.\" },\n { type: \"credential\", key: \"credential\", label: \"API credential\", credentialType: \"llm_credential\" },\n ],\n },\n {\n name: \"@particle-academy/tool_use\",\n aliases: [\"tool_use\", \"@fancy/tool_use\"],\n category: \"ai\",\n label: \"Tool Use\",\n description: \"Hand control to a host-registered tool by name.\",\n icon: \"🛠\",\n configSchema: [\n { type: \"text\", key: \"tool\", label: \"Tool name\", placeholder: \"search_index\", required: true },\n { type: \"expression\", key: \"args\", label: \"Arguments\", example: \"{{ { query: $json.q } }}\" },\n ],\n },\n {\n name: \"@particle-academy/embed_search\",\n outputShape: [\n { path: \"query\", type: \"string\" },\n { path: \"matches\", type: \"array\", description: \"Ranked results from the vector store.\" },\n ],\n aliases: [\"embed_search\", \"@fancy/embed_search\"],\n category: \"ai\",\n label: \"Embed & Search\",\n description: \"Embed a query and search a vector store.\",\n icon: \"✺\",\n configSchema: [\n { type: \"expression\", key: \"query\", label: \"Query\", required: true, example: \"{{ $json.question }}\" },\n { type: \"number\", key: \"topK\", label: \"Top K\", default: 5, min: 1, max: 50 },\n { type: \"credential\", key: \"vectorStore\", label: \"Vector store\", credentialType: \"vector_store\" },\n ],\n },\n\n // ───────────── IO ─────────────\n {\n name: \"@particle-academy/api_request\",\n // HttpClient::send() -> array{status:int,headers:array,body:mixed}\n outputShape: [\n { path: \"status\", type: \"number\", description: \"HTTP status code.\" },\n { path: \"headers\", type: \"object\" },\n { path: \"body\", type: \"unknown\", description: \"Decoded JSON when the response is JSON, otherwise the raw body.\" },\n ],\n aliases: [\"api_request\", \"@fancy/api_request\"],\n category: \"io\",\n label: \"API Request\",\n description: \"HTTP request to any URL.\",\n icon: \"↔\",\n configSchema: [\n ...HTTP_METHODS,\n { type: \"text\", key: \"url\", label: \"URL\", placeholder: \"https://api.example.com/...\", required: true },\n { type: \"keyvalue\", key: \"headers\", label: \"Headers\",\n keyLabel: \"Header\", valueLabel: \"Value\",\n keyPlaceholder: \"content-type\", valuePlaceholder: \"application/json\",\n addLabel: \"Add header\",\n default: { \"content-type\": \"application/json\" } },\n { type: \"json\", key: \"body\", label: \"Body\" },\n { type: \"credential\", key: \"auth\", label: \"Auth\", credentialType: \"api_credential\" },\n ],\n },\n {\n name: \"@particle-academy/webhook_out\",\n outputShape: [\n { path: \"sent\", type: \"boolean\" as const, description: \"True once the request was made.\" },\n { path: \"status\", type: \"number\" as const, description: \"HTTP status, when the transport reported one.\" },\n { path: \"response\", type: \"unknown\" as const, description: \"The response body, when there was one.\" },\n ],\n aliases: [\"webhook_out\", \"@fancy/webhook_out\"],\n category: \"io\",\n label: \"Send Webhook\",\n description: \"POST a payload to a configured URL.\",\n icon: \"↗\",\n configSchema: [\n { type: \"text\", key: \"url\", label: \"URL\", required: true },\n { type: \"keyvalue\", key: \"headers\", label: \"Headers\",\n keyLabel: \"Header\", valueLabel: \"Value\", addLabel: \"Add header\" },\n { type: \"expression\", key: \"payload\", label: \"Payload\", required: true, example: \"{{ $json }}\" },\n ],\n },\n\n // ───────────── Human ─────────────\n {\n name: \"@particle-academy/human_approval\",\n // returns its input on approved/denied\n emits: \"input\",\n aliases: [\"human_approval\", \"@fancy/human_approval\"],\n pausesForHuman: \"approval\",\n category: \"human\",\n label: \"Human Approval\",\n description: \"Pause until a human approves or denies.\",\n icon: \"✓\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"approved\", label: \"approved\" }, { id: \"denied\", label: \"denied\" }],\n configSchema: [\n { type: \"text\", key: \"title\", label: \"Approval title\", default: \"Approve action\" },\n { type: \"textarea\", key: \"description\", label: \"Description for approver\", rows: 3 },\n { type: \"credential\", key: \"channel\", label: \"Notify channel\", credentialType: \"notify_channel\" },\n ],\n },\n {\n name: \"@particle-academy/notify\",\n outputShape: [\n { path: \"sent\", type: \"boolean\" as const, description: \"True once the message was handed to the channel.\" },\n { path: \"channel\", type: \"string\" as const, description: \"The channel it went to.\" },\n { path: \"to\", type: \"string\" as const, description: \"The recipient.\" },\n { path: \"message\", type: \"string\" as const, description: \"The rendered message.\" },\n ],\n aliases: [\"notify\", \"@fancy/notify\"],\n category: \"human\",\n label: \"Notify\",\n description: \"Send a message via Slack / email / SMS / etc.\",\n icon: \"🔔\",\n configSchema: [\n { type: \"select\", key: \"channel\", label: \"Channel\", default: \"slack\",\n options: [\n { value: \"slack\", label: \"Slack\" }, { value: \"email\", label: \"Email\" },\n { value: \"sms\", label: \"SMS\" }, { value: \"discord\", label: \"Discord\" },\n ] },\n { type: \"text\", key: \"to\", label: \"To\", required: true },\n { type: \"expression\", key: \"message\", label: \"Message\", required: true, example: \"{{ $json.summary }}\" },\n ],\n },\n\n // ───────────── Output ─────────────\n {\n name: \"@particle-academy/output\",\n executor: outputExecutor,\n // returns its input unchanged\n emits: \"input\",\n aliases: [\"output\", \"@fancy/output\"],\n category: \"output\",\n label: \"Output\",\n description: \"Terminal node — captures the workflow's result.\",\n icon: \"●\",\n inputs: [{ id: \"in\" }],\n outputs: [],\n },\n {\n name: \"@particle-academy/log\",\n executor: logExecutor,\n outputShape: [\n { path: \"logged\", type: \"string\" as const, description: \"The message that was written.\" },\n { path: \"level\", type: \"string\" as const, description: \"The level it was written at.\" },\n ],\n aliases: [\"log\", \"@fancy/log\"],\n category: \"output\",\n label: \"Log\",\n description: \"Send to the run feed.\",\n icon: \"≡\",\n inputs: [{ id: \"in\" }],\n outputs: [],\n configSchema: [\n { type: \"select\", key: \"level\", label: \"Level\", default: \"info\",\n options: [{ value: \"info\", label: \"info\" }, { value: \"warn\", label: \"warn\" }, { value: \"error\", label: \"error\" }] },\n { type: \"expression\", key: \"message\", label: \"Message\", required: true, example: \"{{ $json }}\" },\n ],\n },\n {\n // Swimlane — a portless, resizable container. Child nodes are parented into\n // it; it never runs (the runtime skips the `layout` category). Uses its own\n // renderer (LaneNode) instead of the default card.\n name: \"@particle-academy/lane\",\n aliases: [\"lane\", \"@fancy/lane\"],\n category: \"layout\",\n label: \"Lane\",\n description: \"A resizable swimlane — drop nodes into it to group them.\",\n icon: \"▤\",\n inputs: [],\n outputs: [],\n configSchema: [\n { type: \"text\", key: \"title\", label: \"Title\", default: \"Lane\" },\n { type: \"select\", key: \"orientation\", label: \"Orientation\", default: \"horizontal\",\n options: [{ value: \"horizontal\", label: \"Row\" }, { value: \"vertical\", label: \"Column\" }] },\n ],\n defaultConfig: { title: \"Lane\", orientation: \"horizontal\" },\n resizable: { minWidth: 160, minHeight: 72 },\n },\n {\n // Terminal lane — a lane that OWNS a terminal for the length of the run.\n //\n // Visually a swimlane, and `layout` for the same reason the plain lane is:\n // a lane is not a step, so it never executes and never appears in topo\n // order. What is new is that it DECLARES a resource. The runtime opens its\n // terminal lazily, when the first terminal node inside it runs, and closes\n // it in the run's `finally` — so a graph that never reaches a terminal node\n // never spawns a process, and one that does gets exactly one session no\n // matter how many nodes use it.\n //\n // Membership is `parentId`, which already persists into the WorkflowSchema.\n // That is what lets a headless runtime resolve the same grouping the canvas\n // shows, without a second association to keep in sync.\n name: \"@particle-academy/terminal_lane\",\n aliases: [\"terminal_lane\", \"@fancy/terminal_lane\"],\n category: \"layout\",\n label: \"Terminal lane\",\n description: \"A lane that owns one terminal. Opens at the first terminal node, closes when the run ends.\",\n icon: \"▣\",\n inputs: [],\n outputs: [],\n configSchema: [\n { type: \"text\", key: \"title\", label: \"Title\", default: \"Terminal\" },\n {\n type: \"text\",\n key: \"command\",\n label: \"Command\",\n placeholder: \"Leave empty for the default shell\",\n },\n { type: \"text\", key: \"cwd\", label: \"Working directory\", placeholder: \"Host default\" },\n { type: \"keyvalue\", key: \"env\", label: \"Environment\" },\n {\n type: \"select\",\n key: \"orientation\",\n label: \"Orientation\",\n default: \"horizontal\",\n options: [\n { value: \"horizontal\", label: \"Row\" },\n { value: \"vertical\", label: \"Column\" },\n ],\n },\n ],\n defaultConfig: { title: \"Terminal\", orientation: \"horizontal\" },\n resizable: { minWidth: 220, minHeight: 120 },\n },\n {\n // Terminal nodes. All three live inside a terminal lane and talk to the\n // session that lane owns; outside one they abort by name rather than\n // opening a shell of their own.\n name: \"@particle-academy/terminal_run\",\n aliases: [\"terminal_run\", \"@fancy/terminal_run\"],\n category: \"io\",\n label: \"Run in terminal\",\n description: \"Run a shell command in the lane's terminal and wait for its exit code.\",\n icon: \"$\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"out\", label: \"output\" }],\n executor: terminalRunExecutor,\n configSchema: [\n {\n type: \"textarea\",\n key: \"command\",\n label: \"Command\",\n rows: 3,\n required: true,\n placeholder: \"npm test\",\n description:\n \"Runs in the lane's shell, so `cd` and exported variables persist between nodes. \"\n + \"SHELL ONLY — a TUI never returns to a prompt, so use Send + Await for one.\",\n },\n {\n type: \"number\",\n key: \"timeoutMs\",\n label: \"Timeout (ms)\",\n default: 120000,\n description: \"How long to wait for the command to finish before failing the run.\",\n },\n {\n type: \"switch\",\n key: \"failOnNonZero\",\n label: \"Fail the run on a non-zero exit\",\n default: true,\n description:\n \"On by default. Turning it off means a failed command lets the run report success — \"\n + \"read the exit code on the output port and branch on it instead.\",\n },\n ],\n defaultConfig: { command: \"\", timeoutMs: 120000, failOnNonZero: true },\n },\n\n {\n name: \"@particle-academy/terminal_send\",\n aliases: [\"terminal_send\", \"@fancy/terminal_send\"],\n category: \"io\",\n label: \"Send to terminal\",\n description: \"Type text at whatever is running in the lane's terminal, without waiting.\",\n icon: \"⌨\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"out\", label: \"sent\" }],\n executor: terminalSendExecutor,\n configSchema: [\n {\n type: \"textarea\",\n key: \"text\",\n label: \"Text\",\n rows: 4,\n placeholder: \"Summarise the failing test and propose a fix.\",\n description: \"What to type. This is how a graph prompts an agent TUI such as Claude Code or Codex.\",\n },\n {\n type: \"switch\",\n key: \"submit\",\n label: \"Press Enter\",\n default: true,\n description: \"Off leaves the text on the input line — useful for building one up across several nodes.\",\n },\n {\n type: \"switch\",\n key: \"clearFirst\",\n label: \"Forget earlier output first\",\n default: false,\n description:\n \"Discards anything the terminal said before this send, so a following Await cannot match \"\n + \"a prompt left over from the previous exchange.\",\n },\n ],\n defaultConfig: { text: \"\", submit: true, clearFirst: false },\n },\n\n {\n name: \"@particle-academy/terminal_await\",\n aliases: [\"terminal_await\", \"@fancy/terminal_await\"],\n category: \"io\",\n label: \"Await terminal output\",\n description: \"Wait until the lane's terminal prints something that matches.\",\n icon: \"⏱\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"out\", label: \"output\" }],\n executor: terminalAwaitExecutor,\n configSchema: [\n {\n type: \"text\",\n key: \"pattern\",\n label: \"Wait for\",\n required: true,\n placeholder: \"esc to interrupt\",\n description: \"Matched against the output with colour codes already stripped, so match what you SEE.\",\n },\n {\n type: \"select\",\n key: \"mode\",\n label: \"Match as\",\n default: \"text\",\n options: [\n { value: \"text\", label: \"Plain text\" },\n { value: \"regex\", label: \"Regular expression\" },\n ],\n description: \"Regex mode also returns capture groups, which is how a value gets out of a prompt.\",\n },\n {\n type: \"number\",\n key: \"timeoutMs\",\n label: \"Timeout (ms)\",\n default: 120000,\n },\n {\n type: \"select\",\n key: \"onTimeout\",\n label: \"If it never appears\",\n default: \"fail\",\n options: [\n { value: \"fail\", label: \"Fail the run\" },\n { value: \"continue\", label: \"Continue with matched: false\" },\n ],\n description:\n \"Failing is the default. Continuing lets the next node type at a process that never became \"\n + \"ready while the run still reports success, so it has to be asked for.\",\n },\n ],\n defaultConfig: { pattern: \"\", mode: \"text\", timeoutMs: 120000, onTimeout: \"fail\" },\n },\n\n {\n // Note — a sticky-note annotation. Portless + visual-only: the runtime skips\n // the `annotation` category, so a note's text NEVER reaches a runner — it\n // rides in the document purely for people, editors, and MCP tools. Uses its\n // own renderer (NoteNode); double-click on the canvas to edit in place.\n name: \"@particle-academy/note\",\n aliases: [\"note\", \"@fancy/note\"],\n category: \"annotation\",\n label: \"Note\",\n description: \"A sticky note that documents the canvas. Never runs — editor + agent only.\",\n icon: \"🗒\",\n inputs: [],\n outputs: [],\n configSchema: [\n { type: \"text\", key: \"title\", label: \"Title\", placeholder: \"Optional heading\" },\n { type: \"textarea\", key: \"text\", label: \"Note\", rows: 5, placeholder: \"What does this part of the flow do?\" },\n { type: \"select\", key: \"color\", label: \"Color\", default: \"amber\", options: [\n { value: \"amber\", label: \"Amber\" },\n { value: \"sky\", label: \"Sky\" },\n { value: \"violet\", label: \"Violet\" },\n { value: \"emerald\", label: \"Emerald\" },\n { value: \"rose\", label: \"Rose\" },\n { value: \"slate\", label: \"Slate\" },\n ] },\n ],\n defaultConfig: { text: \"\", color: \"amber\" },\n resizable: { minWidth: 140, minHeight: 80 },\n },\n];\n\n/**\n * Register every built-in kind AS DATA -- no renderers.\n *\n * This is what `registry.ts` self-populates with, so a headless consumer gets\n * the full vocabulary without React. `builtin.ts` re-registers the four kinds\n * that have renderers on top; `registerBuiltinKindInternal` replaces a BUILTIN\n * by name, so that upgrades them in place.\n *\n * Both go through that internal registrar rather than the public\n * `registerNodeKind`, so neither can overwrite a kind a HOST has claimed. See\n * 0.66.2: that used to happen on every call, silently.\n */\nexport function registerBuiltinKindData(): void {\n for (const k of KINDS) registerBuiltinKindInternal(k);\n}\n\n/** The raw table, renderer-free. `builtin.ts` exports the decorated one. */\nexport const BUILTIN_KIND_DATA: NodeKindDefinition[] = KINDS;\n","import type { ConfigField, NodeCategory, NodeKindDefinition } from \"./types\";\n// The DATA module, deliberately -- importing `./builtin` here is what put\n// React into `/engine` (#11). See that file for the whole story.\nimport { registerBuiltinKindData } from \"./builtin-kinds\";\n\nconst kinds = new Map<string, NodeKindDefinition<any, any, any>>();\n/** alias → canonical name. See `resolveKindId`. */\nconst aliases = new Map<string, string>();\nconst listeners = new Set<() => void>();\n/**\n * canonical name → presentation patch. See `overrideNodeKind`.\n *\n * Kept SEPARATE from `kinds` on purpose: an override has to survive its base\n * kind being re-registered (HMR, a later `registerBuiltinKinds()`, a package\n * upgrade). Merging into the definition would mean the next registration\n * silently reverts the consumer's naming.\n */\nconst overrides = new Map<string, NodeKindPresentation>();\n\n/**\n * Names a HOST registered, as opposed to names the builtin kit registered.\n *\n * Builtin registration is not a one-shot event: `registerBuiltinKinds()` is\n * exported, the four kinds with renderers are deliberately registered twice\n * (React-free table, then decorated), and since 0.66.1 the root barrel calls it\n * as an import side effect. So \"the builtins register again\" happens routinely\n * and at times no consumer can predict.\n *\n * Without this set, every one of those occasions silently reverted a host's\n * replacement of a builtin — the only mechanism we offer for extending one.\n * A consumer's field would vanish from the editor while their server kept\n * validating it, and whether it happened at all depended on which module their\n * bundler evaluated second.\n *\n * This is the same protection `overrides` already had, and for the same stated\n * reason. Presentation patches were kept safe from re-registration; behavioural\n * replacement was not, and nothing marked the asymmetry.\n */\nconst hostOwned = new Set<string>();\n\n/**\n * canonical name -> schema patch from a SERVER. See `applyKindSchemaOverlay`.\n *\n * Kept in its own map for the reason `overrides` is: a patch stored ON the kind\n * is reverted the next time that kind is registered, and builtin registration\n * is not a one-shot event. 0.66.2 was exactly that bug for behavioural\n * replacement; this is the same shape and gets the same protection rather than\n * waiting to learn it twice.\n */\nconst schemaOverlays = new Map<string, KindSchemaOverlay>();\n\n/**\n * The builtin definition for a name, kept even while a host owns the name.\n *\n * Without it, releasing a claim could only DELETE the entry — which is a worse\n * state than before the override, not a return to it: the palette loses the\n * node and the canvas renders raw kind ids where a label belongs.\n */\nconst builtinDefs = new Map<string, NodeKindDefinition<any, any, any>>();\n\nlet builtinsEnsured = false;\n\n/**\n * Put the builtin kit in the registry before anyone reads or writes it.\n *\n * Registration used to be a bare `registerBuiltinKinds()` in `src/index.ts`, so\n * it fired ONLY as an import side effect of that one entry. Every other route in\n * — the `/engine` and `/registry` subpaths, or a root import that TypeScript\n * erases because it only took types — got an empty registry, and an empty\n * registry is silent: `getNodeKind()` returns null, `FlowViewer` falls through\n * its title chain, and the canvas shows `@particle-academy/llm_call` where a\n * name belongs.\n *\n * Doing it here instead means correctness no longer depends on which entry a\n * consumer imported, or on a bundler agreeing to keep a top-level statement.\n *\n * The flag is set BEFORE the call so a listener that reads the registry from\n * inside `notify()` cannot recurse. `registerNodeKind` ensures too, so builtins\n * are always in place before a host registers over one of them.\n */\nexport function ensureBuiltinKinds(): void {\n if (builtinsEnsured) return;\n builtinsEnsured = true;\n registerBuiltinKindData();\n}\n\n/**\n * The presentation fields a consumer may override on someone else's node kind.\n *\n * Deliberately excludes everything behavioural — `executor`, `inputs`,\n * `outputs`, `configSchema`, `sideEffects`. An \"override\" that could change\n * those is not an override, it is a fork wearing a friendly name, and it would\n * desync the graph from the runtime that executes it.\n *\n * `category` IS included: which drawer a node appears in is presentation, and a\n * consumer regrouping their palette is the same kind of act as renaming.\n */\nexport type NodeKindPresentation = Partial<\n Pick<NodeKindDefinition, \"label\" | \"description\" | \"icon\" | \"accent\" | \"category\">\n>;\n\n/**\n * registerNodeKind — install a node kind in the global registry. Returns\n * an `unregister` function. Calling with the same name replaces the prior\n * registration (handy for HMR).\n *\n * A kind's `name` is its CANONICAL id and is what gets written into saved\n * documents. Publish namespaced (`@fancy/llm_branch`, `@acme/salesforce_upsert`)\n * and list any previous bare names in `aliases`, so graphs saved before the\n * rename keep resolving.\n */\nexport function registerNodeKind<TC = any, TI = any, TO = any>(\n definition: NodeKindDefinition<TC, TI, TO>,\n): () => void {\n ensureBuiltinKinds();\n // Claiming the name is what protects it: from here on the builtin kit will\n // not overwrite this entry, however many times it re-registers.\n hostOwned.add(definition.name);\n kinds.set(definition.name, definition as NodeKindDefinition<any, any, any>);\n for (const alias of definition.aliases ?? []) aliases.set(alias, definition.name);\n notify();\n return () => {\n if (kinds.get(definition.name) === (definition as any)) {\n kinds.delete(definition.name);\n hostOwned.delete(definition.name);\n for (const alias of definition.aliases ?? []) {\n if (aliases.get(alias) === definition.name) aliases.delete(alias);\n }\n notify();\n }\n };\n}\n\n/**\n * Register a kind AS PART OF THE BUILTIN KIT — never overwriting a host.\n *\n * The builtin modules use this instead of `registerNodeKind` so that repeated\n * builtin registration is safe. It still replaces builtins (the four kinds with\n * renderers are registered twice on purpose, plain table then decorated), but\n * it steps aside for any name a host has claimed.\n *\n * Internal: not re-exported from the package. A consumer wanting to install a\n * kind uses `registerNodeKind`, and gets ownership of the name by doing so.\n */\nexport function registerBuiltinKindInternal(\n definition: NodeKindDefinition<any, any, any>,\n): void {\n // Recorded BEFORE the ownership check: a host owning the name now is exactly\n // when we will later need the builtin to hand back.\n builtinDefs.set(definition.name, definition);\n\n if (hostOwned.has(definition.name)) return;\n\n kinds.set(definition.name, definition);\n for (const alias of definition.aliases ?? []) {\n if (!hostOwned.has(aliases.get(alias) ?? \"\")) aliases.set(alias, definition.name);\n }\n}\n\n/**\n * Release a host's claim on a name and restore the builtin behind it.\n *\n * The counterpart to `registerNodeKind` replacing a builtin. `registerNodeKind`\n * does return an unregister closure, but a consumer reading the export list\n * cannot find it, and one correctly concluded no such operation existed — so\n * this is the named form.\n *\n * **Test isolation is the reason it matters.** Before 0.66.2, calling\n * `registerBuiltinKinds()` restored the builtins over any override, and people\n * reasonably used that to reset between tests. Since 0.66.2 it correctly\n * refuses to overwrite a host's registration, so that reset silently stopped\n * resetting — and it does not fail where it broke, it fails as a wrong\n * assertion in a later, unrelated test. Use this instead.\n *\n * Returns whether anything was actually released, so a typo'd name is visible\n * rather than a silent no-op — a reset helper that quietly stops resetting is\n * the failure this exists to prevent.\n */\nexport function unregisterNodeKind(name: string): boolean {\n const canonical = resolveKindId(name) ?? name;\n\n const released = hostOwned.delete(canonical);\n if (!released && !kinds.has(canonical)) return false;\n\n const builtin = builtinDefs.get(canonical);\n if (builtin) {\n kinds.set(canonical, builtin);\n for (const alias of builtin.aliases ?? []) aliases.set(alias, canonical);\n } else {\n const previous = kinds.get(canonical);\n kinds.delete(canonical);\n for (const alias of previous?.aliases ?? []) {\n if (aliases.get(alias) === canonical) aliases.delete(alias);\n }\n }\n\n notify();\n\n return released;\n}\n\n/**\n * Empty the registry completely, builtins included.\n *\n * For tests that need a clean slate — in particular any test asserting how host\n * and builtin registration interact, which cannot be written against a registry\n * still holding the previous test's kinds. Production code has no reason to\n * call it: a registry that can be emptied at runtime is a registry that can be\n * emptied at the wrong moment.\n */\nexport function resetNodeKindsForTests(): void {\n kinds.clear();\n aliases.clear();\n overrides.clear();\n schemaOverlays.clear();\n hostOwned.clear();\n builtinDefs.clear();\n builtinsEnsured = false;\n notify();\n}\n\n/**\n * A schema patch for a kind, sourced from a host's SERVER-side registry.\n *\n * fancy-flow has two kind registries. The PHP one lets a host decorate a\n * builtin and that decoration reaches the runtime and validation; the editor,\n * built from the JS registry, never learned any of it. A consumer hit this as a\n * field that existed, ran, and had no control in the panel.\n *\n * **The server owns what a node is CONFIGURED with. The client keeps what a\n * node DOES.** Only the serialisable half is here on purpose: `executor`,\n * `component`, `renderBody` and `icon` cannot cross a wire, and neither can\n * ports — `PortSpec` may be a FUNCTION of config, and three builtins use that\n * form (`switch_case` groups match keys onto one port and joins their labels;\n * `subflow` branches on a derived mode and cares about order). Expressing those\n * as data needs a mini-language with grouping, conditionals and ordering, which\n * is a second implementation of logic that already exists.\n */\nexport type KindSchemaOverlay = {\n /** Canonical id or alias — resolved either way. */\n kind: string;\n /**\n * REPLACES the kind's schema. Never merges.\n *\n * The motivating case is *drop seven fields and add one*, and a merge cannot\n * express a removal. A `remove: string[]` beside a merge would be two\n * mechanisms for one job, and their interaction would be the next bug. The\n * server sends the schema it wants; that is the point of it owning one.\n */\n configSchema?: ConfigField[];\n label?: string;\n description?: string;\n category?: NodeCategory;\n};\n\nexport type KindSchemaOverlayResult = {\n /** Canonical ids that matched a registered kind. */\n applied: string[];\n /**\n * Ids that matched NOTHING, reported rather than dropped.\n *\n * A server lists many kinds and a client will not have registered all of\n * them. Applying what matches and staying quiet about the rest is how a\n * field goes missing with no error anywhere — which is the defect this whole\n * mechanism exists to end, so it must not be reintroduced by the fix.\n */\n unknown: string[];\n unapply: () => void;\n};\n\n/**\n * Apply server-sourced schema patches to kinds this client already has.\n *\n * It does NOT register kinds. A kind must exist locally for its executor,\n * ports and renderer; the overlay corrects its schema, it does not conjure one.\n */\nexport function applyKindSchemaOverlay(\n overlays: readonly KindSchemaOverlay[],\n): KindSchemaOverlayResult {\n ensureBuiltinKinds();\n\n const applied: string[] = [];\n const unknown: string[] = [];\n const previous = new Map<string, KindSchemaOverlay | undefined>();\n\n for (const overlay of overlays) {\n const canonical = resolveKindId(overlay.kind);\n if (!canonical) {\n unknown.push(overlay.kind);\n continue;\n }\n\n if (!previous.has(canonical)) previous.set(canonical, schemaOverlays.get(canonical));\n schemaOverlays.set(canonical, { ...overlay, kind: canonical });\n applied.push(canonical);\n }\n\n if (applied.length > 0) notify();\n\n return {\n applied,\n unknown,\n unapply: () => {\n for (const [canonical, before] of previous) {\n if (before) {\n schemaOverlays.set(canonical, before);\n } else {\n schemaOverlays.delete(canonical);\n }\n }\n notify();\n },\n };\n}\n\n/** Drop every server-sourced schema patch. Mostly for tests. */\nexport function clearKindSchemaOverlays(): void {\n if (schemaOverlays.size === 0) return;\n schemaOverlays.clear();\n notify();\n}\n\n/**\n * Resolve any id — canonical or alias — to the canonical one, or null.\n *\n * `kind` is persisted inside every saved graph, so a bare name that two\n * packages could both claim is unfixable after the fact: the ambiguous string\n * is already in the document. Canonical ids are namespaced; aliases exist so\n * documents written before namespacing keep opening.\n */\nexport function resolveKindId(id: string): string | null {\n ensureBuiltinKinds();\n if (kinds.has(id)) return id;\n const canonical = aliases.get(id);\n return canonical && kinds.has(canonical) ? canonical : null;\n}\n\n/**\n * Rename or re-describe a kind you did not author.\n *\n * Before this existed the only way to relabel a builtin was `registerNodeKind`\n * with a full definition — which REPLACES the kind, so a consumer wanting\n * \"Call an API\" instead of \"HTTP Request\" had to re-declare that node's\n * configSchema, ports, executor and renderer, and silently forfeited whatever\n * the builtin gained in the next release. In practice nobody renamed a node,\n * and the palette could not be localised at all.\n *\n * ```ts\n * const undo = overrideNodeKind(\"@particle-academy/api_request\", {\n * label: \"Call an API\",\n * description: \"Fetch or post JSON to a URL\",\n * });\n * ```\n *\n * Applies at `getNodeKind()` and `listNodeKinds()`, so one call reaches the\n * palette, the node cards on the canvas, `FlowViewer`, and anything else that\n * reads the registry. Returns an unsubscribe, matching `registerNodeKind`.\n *\n * Patching an unregistered id is allowed and takes effect if that kind is\n * registered later — order of module side effects is not something a consumer\n * should have to reason about.\n */\nexport function overrideNodeKind(name: string, patch: NodeKindPresentation): () => void {\n const canonical = resolveKindId(name) ?? name;\n const previous = overrides.get(canonical);\n\n overrides.set(canonical, { ...previous, ...patch });\n notify();\n\n return () => {\n if (previous) {\n overrides.set(canonical, previous);\n } else {\n overrides.delete(canonical);\n }\n notify();\n };\n}\n\n/** Remove every presentation override. Mostly for tests. */\nexport function clearNodeKindOverrides(): void {\n if (overrides.size === 0) return;\n overrides.clear();\n notify();\n}\n\nfunction withOverride(kind: NodeKindDefinition | undefined): NodeKindDefinition | null {\n if (!kind) return null;\n\n // base -> SERVER schema -> LOCAL presentation override.\n //\n // The local override wins, and the order is pinned by a test because it is\n // invisible until the two disagree: `overrideNodeKind` is the app author's\n // explicit choice about naming, which is more specific than a server default.\n const overlay = schemaOverlays.get(kind.name);\n const patch = overrides.get(kind.name);\n if (!overlay && !patch) return kind;\n\n const withSchema = overlay\n ? ({\n ...kind,\n ...(overlay.configSchema !== undefined ? { configSchema: overlay.configSchema } : {}),\n ...(overlay.label !== undefined ? { label: overlay.label } : {}),\n ...(overlay.description !== undefined ? { description: overlay.description } : {}),\n ...(overlay.category !== undefined ? { category: overlay.category } : {}),\n } as NodeKindDefinition)\n : kind;\n\n return patch ? ({ ...withSchema, ...patch } as NodeKindDefinition) : withSchema;\n}\n\n/** Get a single kind by canonical id or alias, or null. */\nexport function getNodeKind(name: string): NodeKindDefinition | null {\n const canonical = resolveKindId(name);\n return canonical ? withOverride(kinds.get(canonical) as NodeKindDefinition) : null;\n}\n\n/** Every id a kind answers to — canonical first. Used to key node-type maps. */\nexport function kindIds(kind: NodeKindDefinition): string[] {\n return [kind.name, ...(kind.aliases ?? [])];\n}\n\n/** List every registered kind, optionally filtered by category. */\nexport function listNodeKinds(category?: string): NodeKindDefinition[] {\n ensureBuiltinKinds();\n const all = Array.from(kinds.values()).map((k) =>\n withOverride(k as NodeKindDefinition),\n ) as NodeKindDefinition[];\n // Filter AFTER applying overrides, so an override that moves a node to a\n // different category actually moves it in the palette rather than leaving it\n // filed under the old one with a new name.\n return category ? all.filter((k) => k.category === category) : all;\n}\n\n/** Subscribe to registry changes. Returns an unsubscribe function. */\nexport function onNodeKindsChanged(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n\nfunction notify(): void {\n for (const l of listeners) l();\n}\n\n/** Fill in defaults from a kind's configSchema for newly-created nodes. */\nexport function defaultConfigFor(kind: NodeKindDefinition): Record<string, unknown> {\n const fromKind = kind.defaultConfig ? { ...(kind.defaultConfig as Record<string, unknown>) } : {};\n for (const field of kind.configSchema ?? []) {\n if (fromKind[field.key] !== undefined) continue;\n if (\"default\" in field && (field as any).default !== undefined) {\n fromKind[field.key] = (field as any).default;\n }\n }\n return fromKind;\n}\n\n/**\n * Validate a config object against a kind's schema. Returns an array of\n * issues (empty = valid). Validation is intentionally light — type\n * coercion + required-field checks. Hosts can layer Zod / Ajv on top.\n */\nexport function validateConfig(\n kind: NodeKindDefinition,\n config: Record<string, unknown>,\n): Array<{ key: string; message: string }> {\n const issues: Array<{ key: string; message: string }> = [];\n for (const field of kind.configSchema ?? []) {\n const value = config[field.key];\n if (field.required && (value === undefined || value === null || value === \"\")) {\n issues.push({ key: field.key, message: `${field.label} is required` });\n continue;\n }\n if (value === undefined || value === null) continue;\n const issue = validateField(field, value);\n if (issue) issues.push({ key: field.key, message: issue });\n }\n return issues;\n}\n\nfunction validateField(field: ConfigField, value: unknown): string | null {\n switch (field.type) {\n case \"text\":\n case \"textarea\":\n case \"expression\":\n case \"credential\":\n return typeof value === \"string\" ? null : `${field.label} must be a string`;\n case \"number\": {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return `${field.label} must be a number`;\n if (field.min !== undefined && value < field.min) return `${field.label} must be >= ${field.min}`;\n if (field.max !== undefined && value > field.max) return `${field.label} must be <= ${field.max}`;\n return null;\n }\n case \"switch\":\n return typeof value === \"boolean\" ? null : `${field.label} must be a boolean`;\n case \"select\": {\n const allowed = field.options.map((o) => o.value);\n return allowed.includes(String(value)) ? null : `${field.label} must be one of ${allowed.join(\", \")}`;\n }\n case \"json\":\n return null; // permissive — just JSON-shaped\n case \"repeater\": {\n if (!Array.isArray(value)) return `${field.label} must be a list`;\n if (field.minItems !== undefined && value.length < field.minItems) {\n return `${field.label} needs at least ${field.minItems}`;\n }\n if (field.maxItems !== undefined && value.length > field.maxItems) {\n return `${field.label} allows at most ${field.maxItems}`;\n }\n // Surface the first offending row so the author knows WHICH one.\n for (let i = 0; i < value.length; i++) {\n const row = value[i];\n if (!row || typeof row !== \"object\" || Array.isArray(row)) {\n return `${field.label} item ${i + 1} must be an object`;\n }\n for (const sub of field.fields) {\n const cell = (row as Record<string, unknown>)[sub.key];\n if (sub.required && (cell === undefined || cell === null || cell === \"\")) {\n return `${field.label} item ${i + 1}: ${sub.label} is required`;\n }\n if (cell === undefined || cell === null) continue;\n const issue = validateField(sub, cell);\n if (issue) return `${field.label} item ${i + 1}: ${issue}`;\n }\n }\n return null;\n }\n case \"keyvalue\": {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return `${field.label} must be a key/value map`;\n }\n const allowed = field.valueOptions?.map((o) => o.value);\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (typeof v !== \"string\") return `${field.label}: \"${k}\" must be a string`;\n if (allowed && !allowed.includes(v)) {\n return `${field.label}: \"${k}\" must be one of ${allowed.join(\", \")}`;\n }\n }\n return null;\n }\n case \"document\":\n return null; // opaque to fancy-flow — the host's editor owns its shape\n default:\n return null;\n }\n}\n\n/** Default accents per category. */\nexport function categoryAccent(category: string): string {\n switch (category) {\n case \"trigger\": return \"#10b981\";\n case \"logic\": return \"#f59e0b\";\n case \"data\": return \"#0ea5e9\";\n case \"ai\": return \"#8b5cf6\";\n case \"io\": return \"#3b82f6\";\n case \"human\": return \"#ec4899\";\n case \"output\": return \"#a855f7\";\n case \"layout\": return \"#64748b\";\n case \"annotation\": return \"#eab308\";\n default: return \"#71717a\";\n }\n}\n","import { getNodeKind, kindIds } from \"../registry/registry\";\nimport type { FlowGraph, FlowNode } from \"../types\";\nimport type { ImportIssue } from \"../schema/workflow-schema\";\n\n/**\n * Refuse a graph whose nodes cannot take part in the workflow's dataflow.\n *\n * Two shapes, both of which import cleanly and then quietly do nothing. Neither\n * FAILS — which is what makes them worth refusing at authoring time, because a\n * run that reports success is the worst way for a workflow to be wrong. Both\n * were measured against the PHP twin's engine before this was written, and both\n * behave the same way here:\n *\n * ## 1. A FLOATING node — no inbound and no outbound edge\n *\n * It is NOT skipped. A node with no incoming edge is a root, so the topo sort\n * runs it: a three-node graph with one floating `log` executed `t,lonely,o`. It\n * runs disconnected — receiving nothing from the graph and reaching nobody in\n * it — which is precisely the state an author cannot see on a canvas.\n *\n * ## 2. An edge leaving a TERMINATOR\n *\n * A terminal kind — `output`, `log` — declares an EMPTY output port list. It\n * ends a chain. Measured: `t -> output -> log` imported clean and the `log` DID\n * run, with `{{ input }}` resolving to `\"\"`. `collectInputs` binds a payload\n * only when `\"<sourceId>:<handle>\"` exists, and a node publishing no ports never\n * creates that key — so the edge does not fail, it delivers nothing, and the\n * node downstream operates on a hole.\n *\n * That is the same silent-nothing the undelivered-edge diagnostic reports at run\n * time, but this one is decidable FROM THE DOCUMENT ALONE.\n *\n * ## What may float\n *\n * See {@link mayFloat}. Not only `note`: any `annotation` or `layout` kind (a\n * swimlane is never wired to anything — that is what a lane IS), and any kind\n * the registry does not know.\n */\nexport function checkGraphConnectivity(graph: FlowGraph): ImportIssue[] {\n const { nodes, edges } = graph;\n const issues: ImportIssue[] = [];\n\n const hasIncoming = new Set<string>();\n const hasOutgoing = new Set<string>();\n for (const edge of edges) {\n hasIncoming.add(edge.target);\n hasOutgoing.add(edge.source);\n }\n\n // A single-node graph is not \"floating\" — it is a graph with one step, which\n // is a legitimate (if small) workflow and what every graph looks like on the\n // way to a bigger one. Refusing it would make the editor unusable from the\n // first node placed.\n const single = nodes.length === 1;\n\n for (const node of nodes) {\n if (single || mayFloat(node)) continue;\n\n if (!hasIncoming.has(node.id) && !hasOutgoing.has(node.id)) {\n issues.push({\n level: \"error\",\n nodeId: node.id,\n message:\n `Node \"${node.id}\" is connected to nothing — no inbound edge and no outbound edge. ` +\n `It still RUNS (a node with no inbound edge is a root), but it receives nothing from ` +\n `the graph and reaches nobody in it, so it is either unwired or left behind by a ` +\n `deletion. Only a note, an annotation or a lane may float.`,\n });\n }\n }\n\n const byId = new Map(nodes.map((n) => [n.id, n]));\n\n for (const edge of edges) {\n const source = byId.get(edge.source);\n if (!source || !isTerminator(source)) continue;\n\n issues.push({\n level: \"error\",\n edgeId: edge.id,\n message:\n `Edge \"${edge.id}\" reads from \"${edge.source}\", which is a TERMINAL node and publishes ` +\n `no output ports at all. Nothing can ever travel this edge: it does not fail at run ` +\n `time, it delivers nothing, and \"${edge.target}\" runs anyway with an empty input.`,\n });\n }\n\n return issues;\n}\n\n/**\n * Which nodes are allowed to sit unconnected.\n *\n * Three answers, and the third is the one that took a second pass — it was\n * missed in the PHP twin's first release and shipped as 0.48.1:\n *\n * 1. **`note`**, across every id the kind answers to, so a graph saved with the\n * canonical `@particle-academy/note` stays an annotation rather than becoming\n * an unwireable node.\n * 2. **Any `annotation` or `layout` kind.** A host may register its own note,\n * and `@particle-academy/lane` is a swimlane the engine walks straight past.\n * Neither is a step and neither is ever wired.\n * 3. **A kind the registry has never heard of.** Not a loophole — the honest\n * answer. An unknown kind already produces its own issue, and we cannot know\n * whether it is a step, an annotation or a lane. Claiming it must be wired\n * would assert something unverifiable, and it lands hardest on the graphs\n * that deserve it least: a laned graph loaded by a runtime without `lane`\n * registered would report every swimlane twice, the second time wrongly.\n *\n * The note/annotation/layout half matches the test `run-flow` uses to skip a\n * node. The unknown-kind half deliberately does NOT — see the closing comment in\n * this file for why the two must not become one helper.\n */\nexport function mayFloat(node: FlowNode): boolean {\n const type = node.type;\n if (!type) return false;\n if (type === \"note\") return true;\n\n const kind = getNodeKind(type);\n if (!kind) return true;\n\n return kindIds(kind).includes(\"note\") || kind.category === \"annotation\" || kind.category === \"layout\";\n}\n\n/**\n * A kind that declares an EMPTY output list ends a chain.\n *\n * `[]` and `undefined` are different answers and only the first means this.\n * `undefined` is \"nobody declared what this publishes\", which resolves to `out`\n * and is most nodes in most graphs; `[]` is an explicit claim that there is\n * nothing to connect from. Reading them alike would refuse nearly every\n * workflow ever written.\n */\nfunction isTerminator(node: FlowNode): boolean {\n // A node carrying its own ports overrides its kind — the engine reads these\n // first, so an author who has said what this node publishes is believed.\n // (The PHP twin's importer DROPS node-level ports, so this branch is reachable\n // there only for a hand-built graph. Noted rather than smoothed over: the two\n // importers genuinely differ here.)\n const own = (node.data as { outputs?: unknown[] } | undefined)?.outputs;\n if (Array.isArray(own)) return own.length === 0;\n\n const kind = node.type ? getNodeKind(node.type) : null;\n\n // An unregistered kind falls back to `out` in the engine, so it is not a\n // terminator. Refusing here would break a host mid-registration, and would\n // use \"I do not know\" as evidence.\n if (!kind) return false;\n\n return Array.isArray(kind.outputs) && kind.outputs.length === 0;\n}\n\n/**\n * NOT shared with `frontier`'s / `run-flow`'s annotation test, deliberately.\n *\n * The two predicates look identical and have OPPOSITE safe defaults, which is\n * exactly how a shared helper becomes a bug:\n *\n * - **Here** an unknown kind may float. Being permissive costs nothing — the\n * unknown-kind issue already fires, and we would otherwise assert something\n * unverifiable.\n * - **In the engine** an unknown kind must NOT be treated as an annotation.\n * Being permissive there means SKIPPING a node the host meant to run, which\n * is silent and unrecoverable.\n *\n * So the note/annotation/layout half is the same question and the unknown half\n * is a different one. Collapsing them into one function would read as tidier and\n * would make a host's unregistered kind stop executing.\n */\n","import type { FlowEdge, FlowGraph, FlowNode, PortDescriptor, WorkflowInput } from \"../types\";\nimport { checkGraphConnectivity } from \"../analysis/graph-connectivity\";\nimport { defaultConfigFor, getNodeKind, validateConfig } from \"../registry/registry\";\nimport { resolveNodePorts } from \"../registry/ports\";\n\n/** Schema version. Bump on breaking shape changes; add migrations as needed. */\nexport const WORKFLOW_SCHEMA_VERSION = 1 as const;\nexport const WORKFLOW_SCHEMA_URL = \"https://particle.academy/schemas/workflow/v1.json\";\n\nexport type WorkflowSchema = {\n $schema: typeof WORKFLOW_SCHEMA_URL;\n version: typeof WORKFLOW_SCHEMA_VERSION;\n metadata?: WorkflowMetadata;\n /**\n * What this workflow accepts at run start, passed BY NAME.\n *\n * Lives beside `graph` rather than inside it because it describes the\n * workflow's CONTRACT, not its topology: a caller reads this to know what to\n * pass, and reading it should not mean walking nodes looking for a trigger.\n *\n * Omitted entirely when a workflow takes none, so every existing saved\n * document is unchanged byte for byte.\n */\n inputs?: WorkflowInput[];\n graph: {\n nodes: WorkflowSchemaNode[];\n edges: WorkflowSchemaEdge[];\n };\n view?: {\n viewport?: { x: number; y: number; zoom: number };\n };\n};\n\nexport type WorkflowMetadata = {\n id?: string;\n name?: string;\n description?: string;\n createdAt?: number;\n updatedAt?: number;\n author?: string;\n tags?: string[];\n};\n\nexport type WorkflowSchemaNode = {\n id: string;\n /** Registry kind name (e.g. \"memory_store\"). */\n kind: string;\n position: { x: number; y: number };\n label?: string;\n description?: string;\n /**\n * Announced to a person just before / just after this node runs. Omitted\n * entirely when unset, so a graph of ordinary plumbing nodes does not carry\n * a pair of empty keys per node and every diff of a saved graph stays\n * readable.\n */\n startingMsg?: string;\n stoppingMsg?: string;\n config?: Record<string, unknown>;\n /**\n * Resolved ports, written on export.\n *\n * A kind may derive its ports from config (`switch_case` cases,\n * `llm_branch` routes), and that derivation is a JavaScript function — a\n * runtime in another language cannot execute it. Without the resolved ports\n * in the document, the PHP twin sees no declared outputs and falls back to a\n * single `out`, so every branch edge in an exported flow silently stops\n * firing. Serializing them keeps the schema self-describing and preserves\n * the cross-runtime guarantee: same JSON in, same routing out.\n *\n * Optional and additive — a hand-written schema may omit them, and each\n * runtime then falls back to its own kind registry.\n */\n inputs?: PortDescriptor[];\n outputs?: PortDescriptor[];\n /**\n * Node grouping and visual layout — additive + optional. `parentId`/`extent`\n * say which container a node sits in (swimlanes); `width`/`height` carry an\n * explicit (resized) size; `style` carries inline presentation.\n *\n * **`parentId` is NOT decoration, and a runtime that drops it is wrong.** It\n * decides which terminal a node talks to — a terminal lane owns one session\n * and membership is this field, deliberately, so there is no second copy of\n * the grouping in each node's config to drift from what the canvas shows.\n *\n * This comment used to say these fields exist \"purely for the canvas\", so a\n * runtime that only walks edges and ports could ignore all of them. The\n * Python twin read that literally and carried none of them: a graph loaded\n * there and saved back lost every grouping a person had drawn, silently. The\n * sentence was true when it was written and became false without being\n * revisited, which is the more common way a comment does harm.\n *\n * An older reader that does not know these fields still drops them — that is\n * forward-compatibility, not permission.\n */\n parentId?: string;\n extent?: \"parent\" | [[number, number], [number, number]];\n width?: number;\n height?: number;\n style?: Record<string, unknown>;\n};\n\nexport type WorkflowSchemaEdge = {\n id: string;\n source: string;\n target: string;\n sourceHandle?: string;\n targetHandle?: string;\n label?: string;\n};\n\nexport type ImportIssue = {\n level: \"error\" | \"warning\";\n nodeId?: string;\n edgeId?: string;\n message: string;\n};\n\nexport type ImportResult = {\n graph: FlowGraph;\n issues: ImportIssue[];\n /** True when the import produced a usable graph (errors may have been\n * rewritten to warnings via `lenient: true`, except an unsupported schema\n * version, which is always an error). */\n ok: boolean;\n};\n\n/** Snapshot the in-memory graph as a portable WorkflowSchema. */\nexport function exportWorkflow(\n graph: FlowGraph,\n metadata?: WorkflowMetadata,\n view?: WorkflowSchema[\"view\"],\n): WorkflowSchema {\n return {\n $schema: WORKFLOW_SCHEMA_URL,\n version: WORKFLOW_SCHEMA_VERSION,\n metadata: metadata ? { ...metadata, updatedAt: Date.now() } : undefined,\n // Round-trips, or a saved workflow silently forgets its own contract and\n // every caller's props become \"unknown input\" on the next load.\n ...(graph.inputs && graph.inputs.length > 0 ? { inputs: graph.inputs } : {}),\n graph: {\n nodes: graph.nodes.map(toSchemaNode),\n edges: graph.edges.map(toSchemaEdge),\n },\n view,\n };\n}\n\nfunction toSchemaNode(n: FlowNode): WorkflowSchemaNode {\n const data: any = n.data ?? {};\n const kindName = data.kind ?? n.type ?? \"custom\";\n // Resolve through the same helper the canvas and runtime use, so a\n // config-driven kind writes its ACTUAL ports into the document instead of\n // leaving another language's runtime to guess at them.\n const ports = resolveNodePorts(n, getNodeKind(kindName) ?? undefined);\n const node = n as any;\n return {\n id: n.id,\n kind: kindName,\n position: { x: n.position.x, y: n.position.y },\n label: data.label,\n description: data.description,\n ...(typeof data.startingMsg === \"string\" && data.startingMsg !== \"\" ? { startingMsg: data.startingMsg } : {}),\n ...(typeof data.stoppingMsg === \"string\" && data.stoppingMsg !== \"\" ? { stoppingMsg: data.stoppingMsg } : {}),\n config: data.config,\n inputs: ports.inputs,\n outputs: ports.outputs,\n // Visual layout — only when explicitly set (never persist auto-`measured`\n // dimensions, which are derived, not authored).\n ...(node.parentId ? { parentId: node.parentId } : {}),\n ...(node.extent ? { extent: node.extent } : {}),\n ...(typeof node.width === \"number\" ? { width: node.width } : {}),\n ...(typeof node.height === \"number\" ? { height: node.height } : {}),\n ...(node.style ? { style: node.style } : {}),\n };\n}\n\nfunction toSchemaEdge(e: FlowEdge): WorkflowSchemaEdge {\n return {\n id: e.id,\n source: e.source,\n target: e.target,\n sourceHandle: e.sourceHandle ?? undefined,\n targetHandle: e.targetHandle ?? undefined,\n label: typeof e.label === \"string\" ? e.label : undefined,\n };\n}\n\nexport type ImportOptions = {\n /** When true, unknown kinds become warnings + a \"custom\" placeholder\n * instead of errors. Default false. It never softens the schema version:\n * a document that is not `version: 1` (after migration) is refused either\n * way, because no runtime can honour a format it does not know. */\n lenient?: boolean;\n};\n\n/** A migration step: takes a version-N document to version N+1. */\nexport type MigrationStep = (schema: Record<string, unknown>) => Record<string, unknown>;\n\n/**\n * Every migration step, keyed by the version it upgrades FROM.\n *\n * Empty today because v1 is current — when a BREAKING bump lands, add the step\n * here and every stored document upgrades on read, in this runtime and its\n * PHP and Python twins.\n */\nexport const MIGRATIONS: Record<number, MigrationStep> = {};\n\n/**\n * Migrate a raw schema object up to the current version, as far as it can go.\n *\n * Additive changes need no migration — an older document simply lacks the newer\n * optional fields. This is the seam for a future BREAKING bump, and\n * `importWorkflow` runs it before validating the version.\n *\n * ## The three rules, each with a reason\n *\n * - **A PAST version migrates forward**, step by step, to the current one.\n * - **A FUTURE version is left ALONE.** We cannot know what a later schema\n * means, and migrating downward would be guessing. Untouched hands it to the\n * version check, which reports it honestly.\n * - **A GAP in the table is left alone too.** A missing step is not a licence\n * to guess.\n *\n * ## Why `steps` is a parameter\n *\n * With only v1 in existence there is no old document to migrate, so a seam\n * tested against the built-in (empty) table is a check that CANNOT fail — it\n * would pass identically against a function that returned its input untouched,\n * which is what this was until the twins needed the same seam.\n *\n * The PHP and Python runtimes carry the identical shape. That mattered more\n * than it sounds: they had no migration at all and errored on any version\n * mismatch, so a v2 bump would have made every stored Op unreadable on exactly\n * the runtimes where durable runs resume.\n */\nexport function migrateSchema(\n schema: unknown,\n steps: Record<number, MigrationStep> = MIGRATIONS,\n): unknown {\n if (!schema || typeof schema !== \"object\") return schema;\n\n const doc = schema as Record<string, unknown>;\n let version = doc.version;\n\n if (typeof version !== \"number\" || !Number.isInteger(version) || version >= WORKFLOW_SCHEMA_VERSION) {\n return schema;\n }\n\n let out = doc;\n while (version < WORKFLOW_SCHEMA_VERSION) {\n const step = steps[version];\n if (!step) return out;\n\n out = step(out);\n version += 1;\n out.version = version;\n }\n\n return out;\n}\n\n/**\n * Hydrate a schema into runtime FlowGraph + validate kinds/configs against\n * the registry. Reports issues for unknown kinds, missing required config,\n * and dangling edges.\n */\nexport function importWorkflow(schema: unknown, options: ImportOptions = {}): ImportResult {\n const issues: ImportIssue[] = [];\n const lenient = options.lenient === true;\n schema = migrateSchema(schema);\n\n if (!schema || typeof schema !== \"object\") {\n return { ok: false, graph: { nodes: [], edges: [] }, issues: [{ level: \"error\", message: \"Schema is not an object.\" }] };\n }\n const s = schema as Partial<WorkflowSchema>;\n // NEVER softened by `lenient`. That flag is about unknown VOCABULARY (a kind\n // this host has not registered); a version is the format itself, and a\n // runtime cannot honour a format it does not know. It used to become a\n // warning, and fancy-flow-php imports leniently on every run(), so one\n // versionless document ran in Laravel and was refused by a default (strict)\n // import here. Past versions were migrated above, so anything still unequal\n // is refused.\n if (s.version !== WORKFLOW_SCHEMA_VERSION) {\n issues.push({\n level: \"error\",\n message: `Unsupported workflow schema version: ${s.version} (expected ${WORKFLOW_SCHEMA_VERSION})`,\n });\n return { ok: false, graph: { nodes: [], edges: [] }, issues };\n }\n\n const rawNodes = s.graph?.nodes ?? [];\n const rawEdges = s.graph?.edges ?? [];\n\n const nodes: FlowNode[] = rawNodes.map((n) => {\n const kind = getNodeKind(n.kind);\n if (!kind) {\n issues.push({\n level: lenient ? \"warning\" : \"error\",\n nodeId: n.id,\n message: `Unknown kind \"${n.kind}\" — register it before importing.`,\n });\n }\n const config = n.config ?? (kind ? defaultConfigFor(kind) : {});\n if (kind) {\n for (const iss of validateConfig(kind, config)) {\n issues.push({ level: \"warning\", nodeId: n.id, message: `${iss.key}: ${iss.message}` });\n }\n }\n // Canonicalise on the way in: a document may carry a pre-namespace id, and\n // rewriting it here means the graph converges on the canonical id the next\n // time it is saved, rather than carrying the ambiguous name forever.\n const kindId = kind?.name ?? n.kind;\n return {\n id: n.id,\n type: kindId,\n position: { x: n.position?.x ?? 0, y: n.position?.y ?? 0 },\n // Rehydrate visual layout onto the node's top level (where xyflow reads it).\n ...(n.parentId ? { parentId: n.parentId } : {}),\n ...(n.extent ? { extent: n.extent } : {}),\n ...(typeof n.width === \"number\" ? { width: n.width } : {}),\n ...(typeof n.height === \"number\" ? { height: n.height } : {}),\n ...(n.style ? { style: n.style } : {}),\n data: {\n kind: kindId,\n label: n.label ?? kind?.label ?? n.kind,\n description: n.description,\n ...(n.startingMsg ? { startingMsg: n.startingMsg } : {}),\n ...(n.stoppingMsg ? { stoppingMsg: n.stoppingMsg } : {}),\n config,\n // Carry serialized ports back onto the node so a round-trip is stable\n // and an unknown kind still routes the way the document described.\n ...(n.inputs ? { inputs: n.inputs } : {}),\n ...(n.outputs ? { outputs: n.outputs } : {}),\n } as any,\n };\n });\n\n const nodeIds = new Set(nodes.map((n) => n.id));\n const edges: FlowEdge[] = rawEdges\n .map((e) => {\n if (!nodeIds.has(e.source)) {\n issues.push({ level: \"warning\", edgeId: e.id, message: `Edge source \"${e.source}\" not found.` });\n return null;\n }\n if (!nodeIds.has(e.target)) {\n issues.push({ level: \"warning\", edgeId: e.id, message: `Edge target \"${e.target}\" not found.` });\n return null;\n }\n return {\n id: e.id,\n source: e.source,\n target: e.target,\n sourceHandle: e.sourceHandle,\n targetHandle: e.targetHandle,\n label: e.label,\n } as FlowEdge;\n })\n .filter((e): e is FlowEdge => e !== null);\n\n // WIRING, not merely dataflow: a node no edge reaches and that reaches no\n // edge, and an edge reading from a node that publishes nothing.\n //\n // Deliberately AFTER the edge loop, so it sees the same edges the engine will\n // -- a dangling edge is dropped with a warning above, and running this first\n // would let a dropped edge count as a connection.\n //\n // Deliberately NOT gated on `lenient`. That flag is about unknown VOCABULARY\n // (a kind this host has not registered), never about wiring.\n issues.push(...checkGraphConnectivity({ nodes, edges }));\n\n const ok = issues.every((i) => i.level !== \"error\");\n // The declaration comes back with the graph. Dropping it on import would be\n // the worse half of losing it on export: the document still says what it\n // accepts, the loaded graph does not, and every prop a caller passes becomes\n // \"unknown input\" — an error pointing at the caller for a bug in the loader.\n const declaredInputs = Array.isArray(s.inputs)\n ? (s.inputs as WorkflowInput[]).filter(\n (input): input is WorkflowInput =>\n input !== null && typeof input === \"object\" && typeof (input as WorkflowInput).name === \"string\",\n )\n : undefined;\n\n return {\n ok,\n graph: {\n nodes,\n edges,\n ...(declaredInputs && declaredInputs.length > 0 ? { inputs: declaredInputs } : {}),\n },\n issues,\n };\n}\n\n/** Convenience: serialize a schema as a downloadable JSON Blob. */\nexport function workflowToBlob(schema: WorkflowSchema): Blob {\n return new Blob([JSON.stringify(schema, null, 2)], { type: \"application/json\" });\n}\n"]}
1
+ {"version":3,"sources":["../src/components/FlowEditor/human-fields.ts","../src/registry/capabilities.ts","../src/registry/llm-router.ts","../src/registry/ports.ts","../src/runtime/run-identity.ts","../src/runtime/terminal-transcript.ts","../src/runtime/terminal-sessions.ts","../src/expressions/variables.ts","../src/runtime/undelivered-edges.ts","../src/runtime/workflow-props.ts","../src/runtime/run-flow.ts","../src/registry/subflow.ts","../src/expressions/expr.ts","../src/registry/logic.ts","../src/registry/terminal-nodes.ts","../src/registry/builtin-kinds.ts","../src/registry/registry.ts","../src/analysis/graph-connectivity.ts","../src/schema/workflow-schema.ts"],"names":["resolve","text","configOf"],"mappings":"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","file":"schema.cjs","sourcesContent":["/**\n * The field vocabulary a `user_input` node declares, and the normalizer that\n * turns whatever was actually written into something renderable.\n *\n * ## Why this is a separate module from `HumanPrompt.tsx`\n *\n * `src/registry/builtin.ts` needs `humanFieldType` for the `user_input` kind's\n * `outputShape`, and `builtin.ts` is in the import graph of the `/engine`\n * entry — the one `tests/core-nodes.test.ts` guards as React-free so a queue\n * worker or a CLI can register kinds without dragging React in. Importing the\n * modal's `.tsx` from there put a React module on that path and left the guard\n * standing only because treeshaking happened to drop it.\n *\n * Pure functions over plain data, in a `.ts` file, so the headless path cannot\n * regress on a future edit to the component.\n */\n\n/**\n * The control a field renders as, after {@link humanInputFields} has resolved\n * whatever the author, a peer runtime or an agent actually wrote.\n *\n * These are the CANONICAL names. The vocabulary an author may write is wider —\n * see {@link HUMAN_FIELD_TYPE_ALIASES} — because a `fields` array arrives from\n * three places (the config panel, a hand-written workflow JSON, and the PHP /\n * Python runtimes) and each has its own habits for spelling \"boolean\".\n */\nexport type HumanFieldType =\n | \"text\"\n | \"textarea\"\n | \"number\"\n | \"select\"\n | \"switch\"\n | \"date\"\n | \"datetime\"\n | \"time\"\n | \"email\"\n | \"url\"\n | \"tel\"\n | \"password\";\n\n/** One choice in a `select` field, after normalization. */\nexport type HumanFieldOption = { value: string; label: string };\n\n/** A field the input modal renders. Mirrors a `user_input` `fields` row. */\nexport type HumanField = {\n key: string;\n label?: string;\n type?: HumanFieldType;\n required?: boolean;\n placeholder?: string;\n options?: HumanFieldOption[];\n default?: unknown;\n};\n\n/**\n * Every spelling of a field type this accepts, mapped onto its canonical\n * control.\n *\n * The bug this table exists to fix: the old normalizer accepted exactly five\n * literal names and coerced everything else to `text`, so `boolean`, `date`,\n * `email` and `enum` — the words a person reaches for first, and the words the\n * peer runtimes' own docs use — all arrived at the form as a plain text box.\n * The person then typed a date into a text field and the run resumed with a\n * string where a date was declared, which nothing downstream could detect.\n *\n * Aliases rather than a stricter schema because the declaration is DATA. It is\n * written by hand and emitted by agents, and rejecting `boolean` on a spelling\n * technicality would be a worse failure than accepting it.\n */\nexport const HUMAN_FIELD_TYPE_ALIASES: Readonly<Record<string, HumanFieldType>> = {\n text: \"text\",\n string: \"text\",\n str: \"text\",\n input: \"text\",\n\n textarea: \"textarea\",\n long_text: \"textarea\",\n longtext: \"textarea\",\n \"long-text\": \"textarea\",\n multiline: \"textarea\",\n paragraph: \"textarea\",\n markdown: \"textarea\",\n\n number: \"number\",\n numeric: \"number\",\n integer: \"number\",\n int: \"number\",\n float: \"number\",\n decimal: \"number\",\n\n select: \"select\",\n enum: \"select\",\n choice: \"select\",\n choices: \"select\",\n dropdown: \"select\",\n options: \"select\",\n radio: \"select\",\n\n switch: \"switch\",\n bool: \"switch\",\n boolean: \"switch\",\n checkbox: \"switch\",\n toggle: \"switch\",\n\n date: \"date\",\n\n datetime: \"datetime\",\n \"datetime-local\": \"datetime\",\n datetimelocal: \"datetime\",\n timestamp: \"datetime\",\n\n time: \"time\",\n\n email: \"email\",\n \"e-mail\": \"email\",\n\n url: \"url\",\n uri: \"url\",\n link: \"url\",\n\n tel: \"tel\",\n phone: \"tel\",\n telephone: \"tel\",\n\n password: \"password\",\n secret: \"password\",\n};\n\n/**\n * Resolve a declared type name to a control.\n *\n * An unrecognised name becomes `text` — never a crash and never a dropped\n * field. A field the form refuses to render is a value the run will never\n * receive, which is strictly worse than rendering it as free text.\n */\nexport function humanFieldType(raw: unknown): HumanFieldType {\n if (typeof raw !== \"string\") return \"text\";\n return HUMAN_FIELD_TYPE_ALIASES[raw.trim().toLowerCase()] ?? \"text\";\n}\n\n/**\n * Normalize whatever an author wrote for a select's choices.\n *\n * Accepts the three shapes that actually turn up:\n *\n * - `[\"small\", \"large\"]` — bare strings, the shorthand `TextConfigField.choices`\n * already accepts elsewhere in this package.\n * - `[{ value: \"s\", label: \"Small\" }]` — the explicit form.\n * - `{ s: \"Small\", l: \"Large\" }` — what the config panel's `keyvalue` control\n * stores, which is how choices are authored on the `user_input` node.\n *\n * A missing `label` falls back to the value rather than rendering an empty\n * option — the old code read `o.label` off a bare string and put `undefined`\n * into both the value and the text, so a shorthand list rendered as a dropdown\n * of blank rows.\n */\nexport function humanFieldOptions(raw: unknown): HumanFieldOption[] | undefined {\n const entries: HumanFieldOption[] = [];\n\n if (Array.isArray(raw)) {\n for (const item of raw) {\n if (typeof item === \"string\" || typeof item === \"number\") {\n const value = String(item);\n if (value !== \"\") entries.push({ value, label: value });\n continue;\n }\n if (item && typeof item === \"object\") {\n const value = (item as { value?: unknown }).value;\n if (value === undefined || value === null || value === \"\") continue;\n const label = (item as { label?: unknown }).label;\n entries.push({\n value: String(value),\n label: typeof label === \"string\" && label !== \"\" ? label : String(value),\n });\n }\n }\n } else if (raw && typeof raw === \"object\") {\n for (const [value, label] of Object.entries(raw as Record<string, unknown>)) {\n if (value === \"\") continue;\n entries.push({ value, label: typeof label === \"string\" && label !== \"\" ? label : value });\n }\n }\n\n return entries.length ? entries : undefined;\n}\n\n/**\n * Normalize a `user_input` node's `fields` config into renderable fields. Falls\n * back to a single text field so even an unconfigured User Input node still\n * collects something rather than silently returning nothing.\n */\nexport function humanInputFields(config: Record<string, unknown>): HumanField[] {\n const raw = Array.isArray((config as any)?.fields) ? ((config as any).fields as any[]) : [];\n const fields: HumanField[] = raw\n .filter((f) => f && typeof f === \"object\" && typeof (f as any).key === \"string\" && (f as any).key)\n .map((f: any) => ({\n key: f.key,\n label: typeof f.label === \"string\" && f.label ? f.label : f.key,\n type: humanFieldType(f.type),\n required: !!f.required,\n placeholder: typeof f.placeholder === \"string\" ? f.placeholder : undefined,\n options: humanFieldOptions(f.options ?? f.choices),\n default: f.default,\n }));\n if (fields.length) return fields;\n const title = typeof (config as any)?.title === \"string\" && (config as any).title ? (config as any).title : \"Your answer\";\n return [{ key: \"value\", label: title, type: \"textarea\", required: true }];\n}\n\n","import type { FlowGraph } from \"../types\";\n\n/**\n * Host capabilities — the services core nodes need but must never depend on.\n *\n * A node that imports a provider SDK forces every consumer to install it: a\n * workflow app that never calls a model should not inherit an LLM dependency.\n * So core declares the CONTRACT and the host supplies the implementation, the\n * same arrangement `renderDocumentField` already uses for documents.\n *\n * That keeps opinionated nodes in core without their opinions: `llm_branch`\n * ships the routing semantics, port derivation and config UI, while whichever\n * client the host registers — Prism, an OpenAI SDK, a local model, a fake in a\n * test — decides how the question actually gets asked.\n *\n * Registration is deliberately explicit and typed per capability rather than a\n * stringly-keyed bag, so a missing one is a clear error at the seam instead of\n * an undefined somewhere downstream.\n */\n\n// ── LLM ─────────────────────────────────────────────────────────────────────\n\nexport type LlmRoute = { port: string; description?: string };\n\nexport type LlmRouteRequest = {\n /** Optional framing for the decision. */\n system?: string;\n /** What the model is deciding about. */\n prompt: string;\n /** The ports it must choose between. */\n routes: LlmRoute[];\n provider?: string;\n model?: string;\n /** Host-resolved credential reference, never a raw key. */\n credential?: string;\n};\n\nexport type LlmRouteChoice = {\n /** Must be one of the requested route ports. */\n port: string;\n /** Why — carried down the chosen port so a run is explainable afterwards. */\n reason?: string;\n};\n\n/**\n * The only thing core asks of an LLM: given routes, pick one.\n *\n * Deliberately not a general chat interface. A narrow contract is one a host\n * can satisfy in a few lines over any SDK, and it keeps the choice\n * machine-checkable — an implementation should constrain the model to the\n * declared ports (structured output / enum) rather than parsing prose.\n */\nexport type LlmClient = {\n chooseRoute: (request: LlmRouteRequest) => Promise<LlmRouteChoice> | LlmRouteChoice;\n};\n\nlet llmClient: LlmClient | null = null;\n\n/** Install the host's LLM client. Returns an unregister function. */\nexport function registerLlmClient(client: LlmClient): () => void {\n llmClient = client;\n return () => {\n if (llmClient === client) llmClient = null;\n };\n}\n\nexport function getLlmClient(): LlmClient | null {\n return llmClient;\n}\n\n// ── Terminal ────────────────────────────────────────────────────────────────\n\n/** What to launch. Omit `command` for the host's default shell. */\nexport type TerminalSessionSpec = {\n command?: string;\n args?: string[];\n cwd?: string;\n env?: Record<string, string>;\n cols?: number;\n rows?: number;\n};\n\nexport type TerminalExit = { exitCode: number; signal?: string };\n\n/**\n * One live terminal, owned by the host for as long as the run needs it.\n *\n * Output arrives by SUBSCRIPTION rather than a `read()` the engine calls. A TUI\n * emits continuously and on its own schedule — repainting, streaming a reply,\n * redrawing a spinner — so a polled read either misses bytes between calls or\n * has to buffer them anyway, and every host would invent that buffer\n * differently.\n */\nexport type TerminalSession = {\n id: string;\n write: (data: string) => void | Promise<void>;\n /** Subscribe to output. Returns an unsubscribe. */\n onData: (listener: (chunk: string) => void) => () => void;\n /**\n * Resolves when the process exits.\n *\n * A promise rather than an `exited` flag the engine polls, so \"the agent\n * quit\" and \"the agent has not answered yet\" are distinguishable while\n * waiting. Without it a node awaiting output cannot tell a slow reply from a\n * dead process, and waits out its timeout either way.\n */\n exited: Promise<TerminalExit>;\n close: () => void | Promise<void>;\n};\n\n/**\n * The only thing core asks of a terminal: open one.\n *\n * ## Why the contract stops at the PTY\n *\n * There is deliberately no `waitForOutput(pattern)` here, though every terminal\n * node needs one. Matching is derivable from `onData`, so putting it in the\n * contract would mean every host implements it — and two implementations of one\n * agreed rule is precisely how a week of registry defects happened: both sides\n * agreed output matching should work, and would have disagreed on whether a\n * pattern spans chunk boundaries, whether ANSI escapes are stripped first, and\n * what a timeout returns.\n *\n * So core owns the matching and the host owns the process. A host satisfies\n * this in a few lines over `node-pty`; nothing about how a run interprets the\n * bytes is up to it.\n *\n * ## Why this exists at all\n *\n * A terminal cannot live in the engine. `node-pty` is a native addon, so\n * importing it would break every browser build of this package and force the\n * dependency on consumers who never run a terminal node — the same reason the\n * LLM client is a contract rather than an SDK import. The desktop app that CAN\n * spawn a PTY registers one; everyone else never notices the capability exists.\n */\nexport type TerminalHost = {\n open: (spec: TerminalSessionSpec) => Promise<TerminalSession> | TerminalSession;\n};\n\nlet terminalHost: TerminalHost | null = null;\n\n/** Install the host's terminal. Returns an unregister function. */\nexport function registerTerminalHost(host: TerminalHost): () => void {\n terminalHost = host;\n return () => {\n if (terminalHost === host) terminalHost = null;\n };\n}\n\nexport function getTerminalHost(): TerminalHost | null {\n return terminalHost;\n}\n\n// ── Workflow resolution ─────────────────────────────────────────────────────\n\n/**\n * Why a workflow reference could not be resolved.\n *\n * `missing` and `version-mismatch` are deliberately distinct. Collapsing them\n * into a bare null makes \"no such workflow\" indistinguishable from \"that\n * workflow exists, but it is not the one you pinned\" — and the second wants an\n * error naming both versions, because it is the interesting failure.\n */\nexport type WorkflowResolutionFailure = {\n reason: \"missing\" | \"version-mismatch\";\n /** The version the host actually holds, when it holds one. */\n available?: number;\n message?: string;\n};\n\nexport type WorkflowResolution = FlowGraph | WorkflowResolutionFailure | null;\n\n/**\n * Resolve a workflow reference to a runnable graph.\n *\n * `subflow` names another workflow rather than embedding it, so the host owns\n * where workflows live — a database, a file, an API.\n *\n * ## Why `version` is here\n *\n * A workflow another workflow depends on is an INTERFACE, and interfaces need\n * pins. Without a version, a parent goes on calling `invoice-triage`, someone\n * edits that child, and the parent now runs different logic having reported\n * success the whole time — correct-looking, no error, wrong behaviour. The same\n * failure family as the 0.9.0 routing divergence.\n *\n * The parameter lives on the resolver rather than being encoded into the ref\n * string (`invoice-triage@3`) because a stringly-typed protocol is one every\n * host invents differently — the \"three vocabularies for one node\" problem.\n *\n * Raised by the MOIC Suite consumer, whose `workflow_ref` pins versions and\n * fails loudly on mismatch. Their point: a host COULD NOT implement pinning\n * before this, because the node had no way to ask and the resolver no way to\n * receive.\n *\n * Returning `null` still means \"no such workflow\". Return a\n * {@link WorkflowResolutionFailure} to distinguish a version mismatch.\n */\nexport type WorkflowResolver = (\n ref: string,\n version?: number,\n) => Promise<WorkflowResolution> | WorkflowResolution;\n\n/** Narrow a resolver's return value to an explicit failure. */\nexport function isResolutionFailure(value: WorkflowResolution): value is WorkflowResolutionFailure {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"reason\" in value &&\n (value as WorkflowResolutionFailure).reason !== undefined\n );\n}\n\nlet workflowResolver: WorkflowResolver | null = null;\n\n/** Install the host's workflow resolver. Returns an unregister function. */\nexport function registerWorkflowResolver(resolver: WorkflowResolver): () => void {\n workflowResolver = resolver;\n return () => {\n if (workflowResolver === resolver) workflowResolver = null;\n };\n}\n\nexport function getWorkflowResolver(): WorkflowResolver | null {\n return workflowResolver;\n}\n\n// ── Introspection ───────────────────────────────────────────────────────────\n\nexport type CapabilityId = \"llm\" | \"workflow_resolver\" | \"document\" | \"terminal\";\n\n/**\n * Which capabilities are currently satisfied.\n *\n * Exists so a host (or the CLI, or an agent over MCP) can answer \"what does\n * this graph need that I haven't wired?\" BEFORE a run fails halfway through.\n */\nexport function capabilityStatus(): Record<CapabilityId, boolean> {\n // Imported lazily to avoid dragging the React-dependent rich-input module\n // into the headless engine.\n let documentReady = false;\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires, no-undef\n documentReady = Boolean((globalThis as any).__fancyFlowDocumentAdapter);\n } catch {\n documentReady = false;\n }\n return {\n llm: llmClient !== null,\n workflow_resolver: workflowResolver !== null,\n document: documentReady,\n // Listed here for the reason this function exists at all. A graph with a\n // terminal lane and no host registered fails PART WAY THROUGH — after the\n // nodes before it have already run and possibly written somewhere — and the\n // whole point of asking up front is to learn that before starting. Leaving\n // it out would have made the one check designed to catch this report\n // all-clear for exactly the case it was built for.\n terminal: terminalHost !== null,\n };\n}\n","import { getLlmClient, type LlmRoute } from \"./capabilities\";\nimport type { NodeExecutor } from \"../types\";\n\n/**\n * `@fancy/llm_branch` — a SHUTTLE, not an engine.\n *\n * It carries the declared routes and the decision prompt out to whatever LLM\n * client the host registered, and carries the chosen port back down the graph.\n * It contains no provider SDK, no prompt engineering, no response parsing and\n * no retry policy — all of that belongs to the host's client, which is what\n * lets this node live in core without every consumer inheriting an LLM\n * dependency.\n *\n * The one thing it does own is graph integrity, because that is a workflow\n * concern rather than an AI one: a port the model invents must never route.\n */\n\n/** Read the node's declared routes out of config. */\nexport function declaredRoutes(config: Record<string, unknown>): LlmRoute[] {\n const raw = config.routes;\n if (!Array.isArray(raw)) return [];\n return raw\n .map((r) => ({ port: String((r as any)?.port ?? \"\").trim(), description: (r as any)?.description }))\n .filter((r) => r.port !== \"\");\n}\n\n/**\n * Where a run goes when the model returns a port that was never offered.\n *\n * Emitting on a port with no edge silently ends the branch — the worst failure\n * mode in a workflow engine, because the run reports success having done\n * nothing. So: the `fallback` port when it exists, else the first declared\n * route, and always loudly.\n */\nexport function resolveFallbackPort(routes: LlmRoute[], fallbackEnabled: boolean): string {\n if (fallbackEnabled) return \"fallback\";\n // Callers only reach this with at least one declared route (a node with none\n // aborts earlier), so there is always somewhere safe to land.\n return routes[0]?.port ?? \"out\";\n}\n\nexport const llmRouterExecutor: NodeExecutor = async (ctx) => {\n const config = ((ctx.node.data as any)?.config ?? {}) as Record<string, unknown>;\n const routes = declaredRoutes(config);\n\n if (routes.length === 0) {\n ctx.abort(\"llm_router has no routes configured\");\n }\n\n const client = getLlmClient();\n if (!client) {\n // Fail loudly rather than guessing a branch. A silent default here would\n // look like the model made a choice.\n ctx.abort(\n \"No LLM client registered. Call registerLlmClient() with your provider adapter — fancy-flow ships the routing, not the model call.\",\n );\n }\n\n const fallbackEnabled = config.fallback !== false;\n\n const choice = await client!.chooseRoute({\n system: typeof config.system === \"string\" ? config.system : undefined,\n prompt: String(config.prompt ?? ctx.inputs ?? \"\"),\n routes,\n provider: typeof config.provider === \"string\" ? config.provider : undefined,\n model: typeof config.model === \"string\" ? config.model : undefined,\n credential: typeof config.credential === \"string\" ? config.credential : undefined,\n });\n\n const offered = new Set(routes.map((r) => r.port));\n let port = choice?.port ?? \"\";\n let reason = choice?.reason;\n\n if (!offered.has(port)) {\n const safe = resolveFallbackPort(routes, fallbackEnabled);\n ctx.emit({\n type: \"log\",\n nodeId: ctx.node.id,\n level: \"warn\",\n message: `llm_router: model returned \"${port || \"(nothing)\"}\", which is not a declared route. Routing to \"${safe}\".`,\n });\n reason = reason ?? `unrecognised route \"${port}\"`;\n port = safe;\n }\n\n // The reason travels WITH the value, so a completed run explains itself\n // without needing the model call replayed.\n return { __port: port, value: { route: port, reason, input: ctx.inputs } };\n};\n","import type { FlowNode, PortDescriptor } from \"../types\";\nimport type { NodeKindDefinition, PortSpec } from \"./types\";\n\n/**\n * Port resolution — the single place a node's ports are derived, shared by\n * the canvas renderer and the headless runtime.\n *\n * This module is deliberately React-free: `runFlow` (the `/engine` entry)\n * imports it, and the engine bundle must stay free of React.\n *\n * ## Why this is centralized\n *\n * Ports used to be read in two places that disagreed — the canvas consulted\n * `data.outputs ?? kind.outputs`, while the runtime consulted `data.outputs`\n * ONLY and fell back to a single `out` port. A kind that declared branch ports\n * therefore drew correctly and then routed as if it had one output, unless the\n * host remembered to mirror the ports onto every node's `data`. Both callers\n * now go through `resolveNodePorts`, so declared ports and executed ports\n * cannot drift apart.\n */\n\n/**\n * Resolve a `PortSpec` against a config object.\n *\n * A config-driven spec is author-supplied and runs on every render, so a throw\n * is contained: it degrades to \"undeclared\" (letting the caller fall back)\n * rather than taking out the canvas or aborting a run mid-flight.\n */\nexport function resolvePortSpec<TConfig>(\n spec: PortSpec<TConfig> | undefined,\n config: TConfig,\n): PortDescriptor[] | undefined {\n if (spec === undefined) return undefined;\n if (typeof spec !== \"function\") return spec;\n try {\n const resolved = (spec as (c: TConfig) => PortDescriptor[])(config);\n return Array.isArray(resolved) ? resolved : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** Read the config bag off a node, tolerating the FlowNodeData union. */\nexport function nodeConfig(node: Pick<FlowNode, \"data\">): Record<string, unknown> {\n return ((node.data as any)?.config ?? {}) as Record<string, unknown>;\n}\n\n/**\n * Resolve a node's effective ports.\n *\n * Precedence: explicit `data.inputs`/`data.outputs` (a per-node host override)\n * beats the kind's declaration. `undefined` means \"nothing declared\" — the\n * caller applies its own category default.\n */\nexport function resolveNodePorts(\n node: Pick<FlowNode, \"data\">,\n kind?: Pick<NodeKindDefinition<any>, \"inputs\" | \"outputs\">,\n): { inputs?: PortDescriptor[]; outputs?: PortDescriptor[] } {\n const config = nodeConfig(node);\n const data = node.data as any;\n return {\n inputs: data?.inputs ?? resolvePortSpec(kind?.inputs, config),\n outputs: data?.outputs ?? resolvePortSpec(kind?.outputs, config),\n };\n}\n","/**\n * Who is running, which step this is, and how many times it has been tried.\n *\n * ## Why an engine needs this at all\n *\n * A node that WRITES to somebody else's system — charge a card, send a message,\n * open a pull request — can only survive a retry if the retry carries the same\n * idempotency key the first attempt did. Otherwise the provider treats the\n * second call as a new request and the customer is charged twice.\n *\n * Until this existed the executor context was `{ node, inputs, emit, abort }`,\n * which is not enough to derive one. Both obvious fallbacks are worse than\n * sending no key at all:\n *\n * - **the node id alone** is stable across retries, and also across RUNS — two\n * legitimate payments share a key and the provider silently collapses the\n * second into the first. A payment that never happened, reported as success;\n * - **a fresh random value** is unique per run, and also per ATTEMPT — a retry\n * creates a second charge, which is the thing being avoided.\n *\n * ## What actually identifies a step\n *\n * Not `(run, node)`. A node legitimately executes more than once inside one\n * run: once per subflow invocation, once per iteration of a loop an executor\n * drives itself. `(run, node)` would give every one of those the same key, and\n * a provider would honour exactly one of them.\n *\n * So a step is identified by the **path of invocations that led to it**, plus\n * an optional **occurrence** for repetition at the same level:\n *\n * ```text\n * runKey \":\" segment (\"/\" segment)* segment := escape(id) [\"#\" occurrence]\n * ```\n *\n * And the part that is easy to get backwards: **`attempt` is NOT in the key.**\n * It is carried here for logging and for {@link RunIdentity.isReplaySafe}, and\n * putting it in the key would restore the exact bug the key exists to prevent.\n *\n * Pinned cross-runtime by `shared/flow-run-identity` in\n * `@particle-academy/fancy-conformance`.\n */\n\n/** The wire shape — what a queue job payload carries. */\nexport type RunIdentityJson = {\n runKey: string;\n path?: string[];\n attempt?: number;\n firstAttemptAt?: string;\n};\n\n/**\n * Escape one segment so the composition is injective.\n *\n * `%` FIRST, or the escaping is not reversible: escaping `/` before `%` turns a\n * literal `a%2Fb` into the same text as the escaped form of `a/b`, which is the\n * collision this exists to prevent, reintroduced by its own fix.\n */\nexport function escapeSegment(value: string): string {\n // Not `replaceAll` — the package targets ES2020, and this must produce the\n // identical string on every runtime that reads the conformance table.\n return value.replace(/%/g, \"%25\").replace(/\\//g, \"%2F\").replace(/#/g, \"%23\");\n}\n\nfunction renderSegment(value: string, occurrence?: number | null): string {\n const escaped = escapeSegment(value);\n // `occurrence === 0` is a real occurrence. A truthiness check here silently\n // collapses iteration 0 into the un-iterated key.\n return occurrence === undefined || occurrence === null ? escaped : `${escaped}#${occurrence}`;\n}\n\nfunction instant(value: string): number {\n const ms = Date.parse(value);\n if (Number.isNaN(ms)) {\n throw new Error(\n `RunIdentity: firstAttemptAt is not a parseable timestamp: ${JSON.stringify(value)}`,\n );\n }\n return ms;\n}\n\n/**\n * A run, a position inside it, and how many times this position has been tried.\n *\n * Immutable. {@link descend} returns a new identity rather than mutating, so an\n * executor cannot change what its siblings see.\n */\nexport class RunIdentity {\n /** Stable for the whole run: same across retries, resumes, workers and hosts. */\n readonly runKey: string;\n\n /**\n * Enclosing invocation segments, outermost first, ALREADY RENDERED.\n *\n * Empty at the top level. A subflow pushes the invoking node's id; an\n * executor that loops pushes `id#i`.\n */\n readonly path: readonly string[];\n\n /**\n * 1-based attempt of THIS logical step. Never part of the key.\n *\n * The durable driver sets it from the node's claim row, which is exact. A\n * plain in-process `runFlow` gets whatever the host passed, which is\n * run-scoped and therefore conservative — see `isReplaySafe`.\n */\n readonly attempt: number;\n\n /** ISO-8601 UTC instant of attempt 1 of this step. */\n readonly firstAttemptAt: string;\n\n constructor(\n runKey: string,\n path: readonly string[] = [],\n attempt = 1,\n firstAttemptAt: string = new Date().toISOString(),\n ) {\n if (!runKey || runKey.trim() === \"\") {\n throw new Error(\"RunIdentity: runKey must be a non-empty string.\");\n }\n this.runKey = runKey;\n this.path = Object.freeze([...path]);\n this.attempt = Math.max(1, Math.trunc(attempt));\n this.firstAttemptAt = firstAttemptAt;\n Object.freeze(this);\n }\n\n /**\n * The identity of one execution of one node — stable across retries of that\n * execution, distinct from every other execution of the same node.\n *\n * Pass `occurrence` when an executor runs the same node more than once at the\n * same level (a loop body, one item of a fan-out it drives itself).\n */\n stepKey(nodeId: string, occurrence?: number | null): string {\n return `${this.runKey}:${[...this.path, renderSegment(nodeId, occurrence)].join(\"/\")}`;\n }\n\n /**\n * A child identity for work nested inside this step.\n *\n * `subflow` pushes the invoking node's id, so a node inside the child graph\n * cannot collide with a same-named node in the parent. Attempt and\n * `firstAttemptAt` are carried down unchanged: the nested work happens inside\n * this step's attempt, and shares its clock.\n */\n descend(segment: string, occurrence?: number | null): RunIdentity {\n return new RunIdentity(\n this.runKey,\n [...this.path, renderSegment(segment, occurrence)],\n this.attempt,\n this.firstAttemptAt,\n );\n }\n\n /** A copy on a different attempt, first-attempt clock preserved. */\n withAttempt(attempt: number, firstAttemptAt?: string): RunIdentity {\n return new RunIdentity(\n this.runKey,\n this.path,\n attempt,\n firstAttemptAt ?? this.firstAttemptAt,\n );\n }\n\n /**\n * May this attempt reuse the step key and still be deduplicated?\n *\n * Providers forget idempotency keys — Stripe after 24 hours. Past that\n * window, resending the key creates a second charge and sending a fresh one\n * creates a second charge, so **the caller must refuse rather than pick\n * between them**: a loud stuck run beats a silent double write.\n *\n * `true` on attempt 1 whatever the elapsed time — nothing was sent on an\n * earlier attempt, so there is nothing for the provider to have forgotten.\n * That is what lets a run park on a human gate for a week and then write.\n *\n * `windowSeconds: null` means the provider does not expire keys. `0` means\n * it does not dedupe at all, so no retry may reuse a key — it is a real\n * window, not an absent one, and the two must not be conflated: reading `0`\n * as `null` turns \"this provider does not dedupe\" into \"this provider\n * dedupes forever\", which is the more dangerous of the two by a distance.\n */\n isReplaySafe(windowSeconds: number | null | undefined, now: Date | string = new Date()): boolean {\n if (this.attempt <= 1) return true;\n if (windowSeconds === null || windowSeconds === undefined) return true;\n if (windowSeconds <= 0) return false;\n\n const nowMs = typeof now === \"string\" ? instant(now) : now.getTime();\n // Clock skew between two workers must not turn a legitimate retry into a\n // refusal, so a negative elapsed clamps to zero.\n const elapsedSeconds = Math.max(0, (nowMs - instant(this.firstAttemptAt)) / 1000);\n\n // Inclusive: a key written at T is remembered THROUGH T + window.\n return elapsedSeconds <= windowSeconds;\n }\n\n toJSON(): Required<RunIdentityJson> {\n return {\n runKey: this.runKey,\n path: [...this.path],\n attempt: this.attempt,\n firstAttemptAt: this.firstAttemptAt,\n };\n }\n\n /** Rebuild from a queue payload. */\n static from(value: RunIdentity | RunIdentityJson | string): RunIdentity {\n if (value instanceof RunIdentity) return value;\n if (typeof value === \"string\") return new RunIdentity(value);\n return new RunIdentity(\n value.runKey,\n value.path ?? [],\n value.attempt ?? 1,\n value.firstAttemptAt ?? new Date().toISOString(),\n );\n }\n}\n","/**\n * What a terminal has said, in a form a node can wait on.\n *\n * A raw `onData` stream is not something a workflow can match against, for\n * three reasons that all fail the same way — intermittently, and usually only\n * once there is real output moving:\n *\n * 1. **Chunks are arbitrary.** A PTY splits wherever it splits, so `Ready >`\n * can arrive as `Rea` + `dy >`. Testing each chunk on its own finds the\n * pattern when output is small enough to land in one write and misses it\n * when it is not. So matching runs against an ACCUMULATED buffer, never a\n * chunk.\n *\n * 2. **Output arrives before anyone is listening.** A node that types at a\n * process and a node that waits for its reply are two steps, and anything\n * printed between them is gone if the buffer starts when the wait does.\n * So the transcript is attached when the SESSION opens, and a wait reads\n * what has already accumulated before it subscribes to anything new.\n *\n * 3. **Escape sequences are everywhere and they also straddle.** An agent TUI\n * writes `Ready` as `ESC[32m Ready ESC[0m`, so matching raw bytes fails on\n * text a person can plainly read. Stripping per chunk reintroduces problem\n * 1 in a second guise — `ESC[3` + `2mReady` strips to `ESC[32mReady` with\n * the escape now INSIDE the text. So an incomplete trailing sequence is\n * held back until the rest of it arrives.\n *\n * Text is consumed through a match, so two waits for the same pattern do not\n * both resolve on the first occurrence — which would let a loop appear to make\n * progress while reading one old line forever.\n */\n\n/**\n * The control characters, by code point rather than as literals.\n *\n * A raw ESC byte sitting in a `.ts` file survives most tools and not all of\n * them, and the failure is the quiet kind: strip one out and the pattern below\n * still parses, still looks right in review, and matches nothing — so every\n * wait fails on coloured output while the code reads as correct. It happened\n * twice while this file was being written, which is the argument.\n */\nconst ESC = String.fromCharCode(0x1b);\nconst CSI = String.fromCharCode(0x9b);\nconst BEL = String.fromCharCode(0x07);\n\n/**\n * CSI (`ESC [ ... final`), OSC (`ESC ] ... BEL|ST`), and the two-character\n * escapes. Written out rather than taken from a dependency: it is a regex, and\n * the suite's rule is that third-party code is a liability carried for years.\n */\nconst ANSI = new RegExp(\n `[${ESC}${CSI}](?:\\\\[[0-?]*[ -/]*[@-~]|\\\\][^${BEL}${ESC}]*(?:${BEL}|${ESC}\\\\\\\\)|[@-Z\\\\\\\\-_])`,\n \"g\",\n);\n\n/**\n * How much unterminated escape to hold back before giving up on it.\n *\n * An OSC sequence carrying a window title is legitimately long, but a lone\n * `ESC` that never terminates is just a byte — holding the rest of the stream\n * hostage behind it would stall a wait forever, which is a worse failure than\n * one stray character in the output.\n */\nconst MAX_PENDING_ESCAPE = 1024;\n\n/**\n * Cap on retained text. A chatty process across a long run would otherwise grow\n * this without limit. Dropping from the FRONT keeps the recent output — which\n * is what a wait is about to match — and a pattern spanning a megabyte of\n * output is not a pattern anybody wrote.\n */\nconst MAX_BUFFER = 1_000_000;\n\nexport type TranscriptWaitResult =\n | { status: \"matched\"; text: string; match: RegExpMatchArray }\n | { status: \"timeout\"; text: string }\n | { status: \"exited\"; text: string; exitCode: number; signal?: string };\n\nexport class TerminalTranscript {\n /** Stripped, complete text not yet consumed by a wait. */\n private text = \"\";\n\n /** Raw bytes held back because they may be the start of an escape sequence. */\n private tail = \"\";\n\n private readonly waiters = new Set<() => void>();\n\n /** Feed raw terminal output in. Safe to call with any chunking. */\n append(chunk: string): void {\n this.tail += chunk;\n\n const safe = this.safeLength();\n if (safe > 0) {\n this.text += this.tail.slice(0, safe).replace(ANSI, \"\");\n this.tail = this.tail.slice(safe);\n }\n\n if (this.text.length > MAX_BUFFER) {\n this.text = this.text.slice(this.text.length - MAX_BUFFER);\n }\n\n for (const wake of [...this.waiters]) wake();\n }\n\n /**\n * How much of `tail` can be stripped now.\n *\n * Everything, unless the final `ESC` has not yet been terminated — in which\n * case processing stops there and resumes when the rest arrives.\n */\n private safeLength(): number {\n const lastEsc = Math.max(this.tail.lastIndexOf(ESC), this.tail.lastIndexOf(CSI));\n if (lastEsc === -1) return this.tail.length;\n\n // A complete sequence starting there means nothing is pending.\n ANSI.lastIndex = lastEsc;\n const match = ANSI.exec(this.tail);\n ANSI.lastIndex = 0;\n if (match && match.index === lastEsc) return this.tail.length;\n\n // Unterminated, but long enough that it is not really an escape.\n if (this.tail.length - lastEsc > MAX_PENDING_ESCAPE) return this.tail.length;\n\n return lastEsc;\n }\n\n /** Unconsumed output, escape sequences removed. */\n peek(): string {\n return this.text;\n }\n\n /** Drop everything currently buffered — used before typing a new command. */\n clear(): void {\n this.text = \"\";\n this.tail = \"\";\n }\n\n /**\n * Wait until `pattern` matches the unconsumed text.\n *\n * Checks what has ALREADY arrived before subscribing, because the common case\n * is that the process answered while the previous node was still finishing.\n *\n * `exited` is raced deliberately. Without it, a shell that dies reports as\n * \"timed out waiting for X\" — sending whoever reads it to lengthen a timeout\n * for a process that is not running. Naming the exit is the difference\n * between a diagnosis and a wrong lead.\n */\n waitFor(\n pattern: RegExp,\n options: { timeoutMs: number; exited?: Promise<{ exitCode: number; signal?: string }> },\n ): Promise<TranscriptWaitResult> {\n return new Promise<TranscriptWaitResult>((resolve) => {\n let settled = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const finish = (result: TranscriptWaitResult) => {\n if (settled) return;\n settled = true;\n this.waiters.delete(check);\n if (timer) clearTimeout(timer);\n resolve(result);\n };\n\n const check = () => {\n // A global or sticky pattern carries `lastIndex` between calls, so it\n // would start each attempt part-way through a buffer it has not read.\n pattern.lastIndex = 0;\n const match = pattern.exec(this.text);\n if (!match) return;\n\n // `|| 1` so a pattern that can match empty still makes progress rather\n // than consuming nothing and matching the same position forever.\n const through = match.index + (match[0].length || 1);\n const text = this.text.slice(0, through);\n this.text = this.text.slice(through);\n finish({ status: \"matched\", text, match });\n };\n\n this.waiters.add(check);\n check();\n if (settled) return;\n\n if (options.timeoutMs > 0) {\n timer = setTimeout(() => {\n const text = this.text;\n this.text = \"\";\n finish({ status: \"timeout\", text });\n }, options.timeoutMs);\n // Never hold a Node process open just to time out a wait nobody wants.\n (timer as unknown as { unref?: () => void }).unref?.();\n }\n\n options.exited?.then(\n (exit) => {\n // No re-check here, deliberately. `append` wakes every waiter the\n // instant data lands, so a process that prints its answer and then\n // exits has already matched by the time this runs — `settled` is\n // true and this returns. A re-check looked like it was guarding that\n // race and was in fact unreachable, which is worse than absent: it\n // read as a guarantee while the actual guarantee lived elsewhere.\n if (settled) return;\n const text = this.text;\n this.text = \"\";\n finish({ status: \"exited\", text, exitCode: exit.exitCode, signal: exit.signal });\n },\n () => {},\n );\n });\n }\n}\n","import { getTerminalHost, type TerminalSession, type TerminalSessionSpec } from \"../registry/capabilities\";\nimport { TerminalTranscript } from \"./terminal-transcript\";\nimport type { FlowGraph, FlowNode } from \"../types\";\n\n/**\n * One terminal per terminal lane, for the length of a run.\n *\n * ## The lifetime, and why it is not per-node\n *\n * A terminal node is only useful if the process it talks to is the SAME one the\n * last node talked to. `cd` has to persist; an agent TUI has to still be\n * running with its conversation intact. A session opened per node would give\n * every node a fresh shell and quietly turn a sequence of steps into a series\n * of unrelated ones — each individually correct, the whole thing meaningless.\n *\n * So the session is keyed on the LANE, opened lazily by the first node inside\n * it, and closed once when the run ends. A graph that never reaches a terminal\n * node spawns no process at all, which is what makes it safe for the lane to\n * exist on a canvas that mostly does other things.\n *\n * ## Why membership is `parentId`\n *\n * It is what the canvas already means by \"inside\", and it already persists into\n * the WorkflowSchema — so a headless runtime resolves exactly the grouping a\n * person drew, with no second association to keep in step. The alternative, a\n * lane id typed into each node's config, is the same fact in two places and\n * would drift the first time somebody dragged a node out of a lane.\n *\n * Nesting is followed to the nearest terminal lane, so an ordinary lane inside\n * a terminal lane still resolves — grouping for looks should not change which\n * terminal a node talks to.\n */\nexport class TerminalSessions {\n private readonly open = new Map<string, Promise<TerminalSession>>();\n\n private readonly laneOf = new Map<string, string | null>();\n\n private readonly transcripts = new Map<string, TerminalTranscript>();\n\n private readonly listening = new Map<string, () => void>();\n\n constructor(private readonly graph: FlowGraph) {}\n\n /**\n * The terminal lane a node belongs to, or null.\n *\n * Walks up `parentId` rather than checking only the immediate parent, and\n * caches per node id — a graph is walked once per run, and the answer cannot\n * change while it runs.\n */\n laneFor(nodeId: string, isTerminalLane: (node: FlowNode) => boolean): string | null {\n const cached = this.laneOf.get(nodeId);\n if (cached !== undefined) return cached;\n\n const byId = new Map(this.graph.nodes.map((n) => [n.id, n]));\n const seen = new Set<string>();\n\n let current = byId.get(nodeId);\n let answer: string | null = null;\n\n while (current) {\n // A cycle in `parentId` is malformed rather than impossible — a dragged\n // node with a stale parent can produce one — and walking it forever would\n // hang the run rather than fail it.\n if (seen.has(current.id)) break;\n seen.add(current.id);\n\n if (current.id !== nodeId && isTerminalLane(current)) {\n answer = current.id;\n break;\n }\n\n const parentId = (current as unknown as { parentId?: string }).parentId;\n current = parentId ? byId.get(parentId) : undefined;\n }\n\n this.laneOf.set(nodeId, answer);\n return answer;\n }\n\n /**\n * The session for a lane, opening it on first use.\n *\n * The PROMISE is cached, not the resolved session. Two nodes cannot run\n * concurrently in the current engine, but a caller that awaits a\n * half-finished open would otherwise start a second process — and two shells\n * where a graph says one is the failure this class exists to prevent, arriving\n * only under concurrency and therefore only sometimes.\n */\n session(laneId: string, spec: TerminalSessionSpec): Promise<TerminalSession> {\n const existing = this.open.get(laneId);\n if (existing) return existing;\n\n const host = getTerminalHost();\n\n if (!host) {\n // Named as a MISSING HOST rather than a failed open. A node in a terminal\n // lane with no host registered is a configuration problem — the desktop\n // app did not install one — and reporting it as \"the terminal failed\"\n // sends someone to debug a process that was never started.\n const failed = Promise.reject(\n new Error(\n \"No terminal host is registered. A terminal lane needs one — call registerTerminalHost() \"\n + \"from the desktop app, or install @particle-academy/fancy-flow/terminal/fancy-term-host.\",\n ),\n );\n // Cached so every node in the lane fails the same way rather than the\n // first one failing and the rest re-asking a question already answered.\n this.open.set(laneId, failed);\n // Nothing awaits this until a node does; keep node from warning meanwhile.\n failed.catch(() => {});\n return failed;\n }\n\n // Subscribed the moment the session resolves, not when a node first waits.\n //\n // A process answers on its own schedule, and the node that types at it and\n // the node that reads the reply are two separate steps. Anything printed in\n // between is unrecoverable if the buffer starts when the WAIT does — so a\n // fast process would be missed and a slow one caught, which is the same bug\n // presenting as flakiness rather than as a bug.\n const opening = Promise.resolve(host.open(spec)).then((session) => {\n const transcript = this.transcriptFor(laneId);\n this.listening.set(laneId, session.onData((chunk) => transcript.append(chunk)));\n return session;\n });\n\n this.open.set(laneId, opening);\n opening.catch(() => {});\n return opening;\n }\n\n /**\n * The accumulated output for a lane.\n *\n * Created on demand and kept for the run, so it exists before the session\n * resolves and survives every node that reads it. Consuming is the reader's\n * job — see `TerminalTranscript.waitFor`.\n */\n transcriptFor(laneId: string): TerminalTranscript {\n const existing = this.transcripts.get(laneId);\n if (existing) return existing;\n\n const created = new TerminalTranscript();\n this.transcripts.set(laneId, created);\n return created;\n }\n\n /** True once a lane has a session — used to avoid opening one during teardown. */\n isOpen(laneId: string): boolean {\n return this.open.has(laneId);\n }\n\n /**\n * Close every session this run opened.\n *\n * Every close is attempted even if one throws: a host that fails to close one\n * PTY must not strand the others, which would leave processes alive after the\n * run reported that it had finished. Errors are returned rather than thrown,\n * because teardown runs in a `finally` and throwing there would replace the\n * run's real error with a cleanup error.\n */\n async closeAll(): Promise<Error[]> {\n const errors: Error[] = [];\n\n for (const [laneId, pending] of this.open) {\n try {\n // Unsubscribe BEFORE closing. A host that emits a final chunk while\n // shutting down would otherwise append to a transcript nobody will read\n // again, and a listener outliving its session is how a closed terminal\n // keeps a run's objects alive.\n this.listening.get(laneId)?.();\n this.listening.delete(laneId);\n\n const session = await pending;\n await session.close();\n } catch (e) {\n errors.push(e instanceof Error ? e : new Error(`${laneId}: ${String(e)}`));\n }\n }\n\n this.open.clear();\n this.listening.clear();\n this.transcripts.clear();\n return errors;\n }\n}\n\n/** The spec a terminal lane node declares. */\nexport function specForLane(lane: FlowNode): TerminalSessionSpec {\n const config = ((lane.data as { config?: Record<string, unknown> } | undefined)?.config ?? {}) as Record<\n string,\n unknown\n >;\n\n const text = (key: string): string | undefined => {\n const value = config[key];\n return typeof value === \"string\" && value !== \"\" ? value : undefined;\n };\n\n const env = config.env;\n\n return {\n command: text(\"command\"),\n cwd: text(\"cwd\"),\n env:\n env && typeof env === \"object\" && !Array.isArray(env)\n ? Object.fromEntries(\n Object.entries(env as Record<string, unknown>).map(([k, v]) => [k, String(v)]),\n )\n : undefined,\n };\n}\n","import { getNodeKind } from \"../registry/registry\";\nimport type { FlowGraph, FlowNode } from \"../types\";\n\n/**\n * What a node emits, described well enough for an author to reference it.\n *\n * This is deliberately NOT `outputs` — that is a `PortSpec`, which describes\n * WIRES (port ids and labels). Nothing in the registry described the DATA on\n * those wires, so \"what can I write in this field\" had no answer to derive\n * from. Hence a second, small declaration.\n */\nexport type OutputField = {\n /** Dot-path relative to the emitted value: `text`, `user.email`. */\n path: string;\n type?: \"string\" | \"number\" | \"boolean\" | \"object\" | \"array\" | \"unknown\";\n description?: string;\n};\n\n/**\n * A kind's output shape — static, or computed from the node's config.\n *\n * The function form is the important one. A `user_input` step emits exactly the\n * field keys its author defined, and a `transform` emits the keys it was told\n * to build; no static list can know either. A static list would have forced\n * every dynamic kind to declare nothing, which is the case an author most needs\n * help with.\n */\nexport type OutputShape<TConfig = Record<string, unknown>> =\n | OutputField[]\n | ((config: TConfig) => OutputField[]);\n\n/** One entry in the variable picker. */\nexport type AvailableVariable = {\n /** Exactly what gets inserted, including the braces. */\n expression: string;\n /** The bare path, for display: `$json.text`. */\n path: string;\n type?: OutputField[\"type\"];\n description?: string;\n /** Label of the upstream node this came from, for disambiguation. */\n source?: string;\n};\n\n/**\n * `$json` and `$input` both alias the `in` port value in the PHP resolver\n * (`Expr::resolvePath`). We suggest ONE of them so the picker does not present\n * the same variable twice under two names; `$json` is the spelling every\n * builtin kind's `example` already uses.\n */\nconst ROOT = \"$json\";\n\nfunction expr(path: string): string {\n return `{{ ${path} }}`;\n}\n\n/** Resolve a kind's output shape for a specific node. */\nexport function outputFieldsFor(node: FlowNode): OutputField[] {\n const kindName = (node.data as { kind?: string } | undefined)?.kind ?? node.type;\n if (!kindName) return [];\n\n const kind = getNodeKind(kindName) as { outputShape?: OutputShape } | undefined;\n const shape = kind?.outputShape;\n if (!shape) return [];\n\n if (typeof shape === \"function\") {\n // A kind computes this from author-supplied config, which is exactly where\n // a throw would be easiest to write and worst to ship — a malformed config\n // would take the whole panel down rather than showing one short list.\n try {\n const config = (node.data as { config?: Record<string, unknown> } | undefined)?.config ?? {};\n return shape(config) ?? [];\n } catch {\n return [];\n }\n }\n return shape;\n}\n\n/**\n * The variables an author can reference from `nodeId`, in this graph.\n *\n * Only the DIRECT predecessors are consulted, because `in` is the value on the\n * incoming wire. Walking further would offer a grandparent's fields, which\n * resolve to `null` at runtime — a suggestion that silently produces nothing is\n * worse than no suggestion, since the author has no reason to doubt it.\n *\n * Always includes the whole input. That one exists no matter what upstream\n * declared, and it is the escape hatch when a kind has no `outputShape` yet.\n */\nexport function baseVariables(): AvailableVariable[] {\n return [\n { expression: expr(ROOT), path: ROOT, type: \"unknown\", description: \"The whole incoming value.\" },\n ];\n}\n\nexport function availableVariables(graph: FlowGraph, nodeId: string): AvailableVariable[] {\n const out: AvailableVariable[] = baseVariables();\n const seen = new Set<string>([ROOT]);\n\n const byId = new Map(graph.nodes.map((n) => [n.id, n]));\n const upstreamIds = graph.edges.filter((e) => e.target === nodeId).map((e) => e.source);\n\n for (const id of upstreamIds) {\n if (id === nodeId) continue; // a self-edge is not an input shape\n const upstream = byId.get(id);\n if (!upstream) continue;\n\n const kindName = (upstream.data as { kind?: string } | undefined)?.kind ?? upstream.type;\n const label =\n (upstream.data as { label?: string } | undefined)?.label ??\n (kindName ? getNodeKind(kindName)?.label : undefined);\n\n for (const field of outputFieldsFor(upstream)) {\n const path = `${ROOT}.${field.path}`;\n if (seen.has(path)) continue;\n seen.add(path);\n out.push({\n expression: expr(path),\n path,\n type: field.type,\n description: field.description,\n source: label,\n });\n }\n }\n\n return out;\n}\n\n/** One documented form of the expression grammar. */\nexport type ExpressionForm = { syntax: string; meaning: string };\n\nexport type ExpressionGrammarHelp = {\n forms: ExpressionForm[];\n note: string;\n};\n\n/**\n * The reference help shown beside an expression field.\n *\n * Every form here is one `Expr::resolvePath` implements — a dot-path and\n * nothing else. It is tempting to document `{{ a && b }}` or `{{ a + b }}`\n * because they look like expressions; the resolver would return `null` for\n * both, and an author following the help would have no way to tell why.\n */\nexport function describeExpressionGrammar(): ExpressionGrammarHelp {\n return {\n forms: [\n { syntax: \"{{ $json }}\", meaning: \"The whole value arriving on this node's input.\" },\n { syntax: \"{{ $json.field }}\", meaning: \"One key of that value. Dot-paths nest: $json.user.email.\" },\n { syntax: \"{{ $input.field }}\", meaning: \"An alias for $json — the same value, either spelling.\" },\n { syntax: \"{{ in }}\", meaning: \"The input by its context key, rather than through the alias.\" },\n ],\n note:\n \"Dot-paths only — no arithmetic, comparisons or function calls; anything else resolves to nothing. \" +\n \"A field that is exactly one expression keeps the resolved value's type; mixed text interpolates as a string. \" +\n \"fancy-flow's own runFlow does not interpolate: it hands config to your executor verbatim, and the \" +\n \"fancy-flow-php runtime is what resolves these.\",\n };\n}\n","/**\n * AN EDGE THAT DELIVERS NOTHING MUST SAY SO — the one implementation of that\n * check, shared by every path that can reach it.\n *\n * `runFlow` asks it of each node it reaches. The durable `Coordinator` asks it\n * of each node its frontier SKIPS, because a skipped node never gets a job and\n * so never replays to ask it for itself. Two copies of this check would agree\n * for a while and then disagree on one handle — which is exactly the kind of\n * divergence the warning exists to report — so there is one, and it EMITS\n * nothing. It returns the events and each caller decides where they go.\n *\n * Kept React-free on purpose: `run-flow.ts` imports it, and the `/engine` entry\n * must not reach React.\n */\nimport type { FlowEdge, FlowNode, RunEvent } from \"../types\";\n// React-free modules, imported directly rather than via the `registry` barrel,\n// which re-exports the RegistryNode component.\nimport { defaultConfigFor, getNodeKind } from \"../registry/registry\";\nimport { nodeConfig, resolvePortSpec } from \"../registry/ports\";\nimport { outputFieldsFor } from \"../expressions/variables\";\n\n/**\n * The `log` / `warn` events for every inbound edge of `target` that delivers\n * nothing and never could.\n *\n * Asked BEFORE the activity gate, because the two outcomes are both silent and\n * only one reaches `collectInputs`. If the bad edge is the node's only inbound\n * one the node is SKIPPED; if it has another live edge it RUNS with that port\n * simply missing -- and then a downstream template that is entirely correct\n * renders empty, because the payload never arrived to have a field in it.\n *\n * Keyed on the source having COMPLETED and on the handle being a port the source\n * could NEVER publish. A branch that was not taken is ordinary and must never\n * warn; a source that finished and cannot publish this port is a\n * misconfiguration that delivers nothing on any run. A warning that fires on\n * ordinary branching is noise, and noise is how a real warning stops being read.\n * PHP has always said this; this runtime ran the same graph and said nothing\n * (fancy-flow#17). Pinned by `flow/run-diagnostics`.\n *\n * - `incoming` — the target's inbound edges, in graph order.\n * - `portValues` — keyed `\"<nodeId>:<portId>\"`, one key per port a node\n * published, in publication order. Only the KEYS are read: which ports\n * published, never what they carried.\n * - `completed` — the ids of nodes that ran to an output. A source that did not\n * complete is never judged (row 0014).\n * - `nodesById` — every node of the graph, to resolve a source's ports and\n * output fields.\n */\nexport function undeliveredEdgeWarnings(\n target: FlowNode,\n incoming: readonly FlowEdge[],\n portValues: ReadonlyMap<string, unknown>,\n completed: ReadonlySet<string>,\n nodesById: ReadonlyMap<string, FlowNode>,\n): RunEvent[] {\n const events: RunEvent[] = [];\n\n for (const e of incoming) {\n const handle = e.sourceHandle ?? \"out\";\n if (portValues.has(`${e.source}:${handle}`) || !completed.has(e.source)) continue;\n if (possiblePortIds(nodesById.get(e.source)).includes(handle)) continue;\n\n events.push({\n type: \"log\",\n nodeId: target.id,\n level: \"warn\",\n message: undeliveredEdgeMessage(e, target, portValues, nodesById),\n detail: { edge: e.id, source: e.source, sourceHandle: handle },\n });\n }\n\n return events;\n}\n\n/**\n * Every port this node COULD publish — not the ones it did.\n *\n * The distinction that keeps the undelivered-edge warning honest. A `branch`\n * that took `true` publishes no `false`, and the edge leaving `false` binds\n * nothing: that is ORDINARY BRANCHING. A handle that is not a port of the node\n * at all can never bind on any run. \"Did it publish?\" cannot tell those apart —\n * both are absent — so this asks what is POSSIBLE.\n *\n * The rule is the PHP twin's `PortResolution::possible`, precedence and all,\n * because a warning one runtime raises and another does not is a parity failure:\n *\n * 1. the node's own declared `outputs`;\n * 2. the kind's CONFIG-DERIVED ports, when the config declares any;\n * 3. the kind's declared ports;\n * 4. `out`.\n *\n * It differs from `resolveNodePorts` in exactly one place, on purpose. A kind\n * whose ports come from config — `switch_case`, `llm_router` — and whose config\n * declares none yet answers with its DEFAULT-config shape (`case_a`, `case_b`,\n * `default`), which is what PHP's static declaration for that kind is.\n * `resolveNodePorts` answers with what that empty config yields (`default`\n * alone), which is right for the canvas and for `activatedPorts`, so it is left\n * alone: this only decides whether to warn, never what routes.\n */\nfunction possiblePortIds(node: FlowNode | undefined): string[] {\n if (!node) return [\"out\"];\n\n const own = (node.data as { outputs?: unknown } | undefined)?.outputs;\n if (Array.isArray(own)) return own.map((p: { id: string }) => p.id);\n\n // An unregistered kind is not ambiguous: `activatedPorts` falls back to\n // exactly `out` for a kind it cannot resolve, so that is all it publishes.\n const kind = getNodeKind((node.data as any)?.kind ?? node.type ?? \"\");\n if (!kind) return [\"out\"];\n\n const config = nodeConfig(node);\n const representative = typeof kind.outputs === \"function\" && !configDeclaresPorts(kind.name, config);\n const ids = (resolvePortSpec(kind.outputs, representative ? defaultConfigFor(kind) : config) ?? [])\n .map((p) => p.id);\n\n return ids.length > 0 ? ids : [\"out\"];\n}\n\n/**\n * Whether a config-driven kind's config declares any ports of its own — PHP's\n * `configDerived` returning non-empty. Matched on the BARE kind name, as there:\n * graphs carry both `switch_case` and `@particle-academy/switch_case`.\n */\nfunction configDeclaresPorts(kindName: string, config: Record<string, unknown>): boolean {\n const bare = kindName.startsWith(\"@\") ? kindName.slice(kindName.lastIndexOf(\"/\") + 1) : kindName;\n\n if (bare === \"switch_case\") {\n // `cases` maps VALUE => PORT, so the ports are its values.\n const cases = config.cases;\n return !!cases && typeof cases === \"object\"\n && Object.values(cases).some((port) => typeof port === \"string\" && port !== \"\");\n }\n\n if (bare === \"llm_router\") {\n const routes = config.routes;\n return Array.isArray(routes)\n && routes.some((route) => (route as { port?: unknown } | null)?.port != null && (route as { port: unknown }).port !== \"\");\n }\n\n return true;\n}\n\n/**\n * The message for an edge whose source port publishes nothing.\n *\n * The PHP twin's wording, byte for byte, and each part earns its place:\n *\n * 1. THE EDGE ID FIRST — the thing the author, looking at a graph, can act on.\n * 2. THE CONSEQUENCE, IN RUNTIME TERMS. Without \"nothing would reach X\" this\n * reads as a schema nit, and a handle string feels cosmetic.\n * 3. THE AVAILABLE PORTS — what the source ACTUALLY published on this run, in\n * publication order, so a config-driven kind reports its real ports.\n * 4. THE REMEDY FOR THE COMMON CASE. Nearly every occurrence is an agent\n * ADDING a handle that should not be there, so \"leave sourceHandle off\" —\n * offered only when there is a handle to leave off.\n *\n * Plus the part only the engine can supply: when the handle names a FIELD of\n * the source kind's output shape, say so. That is the actual confusion — a field\n * name where a port belongs — and naming it turns a correction into an\n * explanation.\n */\nfunction undeliveredEdgeMessage(\n edge: FlowEdge,\n target: FlowNode,\n portValues: ReadonlyMap<string, unknown>,\n nodesById: ReadonlyMap<string, FlowNode>,\n): string {\n const handle = edge.sourceHandle ?? \"out\";\n\n const prefix = `${edge.source}:`;\n const available: string[] = [];\n for (const key of portValues.keys()) {\n if (key.startsWith(prefix)) available.push(key.slice(prefix.length));\n }\n\n let message =\n `Edge ${edge.id} reads port \"${handle}\" from node ${edge.source}, which never publishes it — ` +\n `nothing would reach ${target.id} at run time.`;\n\n if (available.length > 0) message += ` Available: ${available.join(\", \")}.`;\n\n // The near-miss: a FIELD of that name, where a PORT was expected.\n const source = nodesById.get(edge.source);\n if (source && outputFieldsFor(source).some((field) => field?.path === handle)) {\n message +=\n ` Note: \"${handle}\" is a FIELD this node emits, not a port — read it downstream as ` +\n `{{ in.${handle} }} rather than naming it as a source handle.`;\n }\n\n if (edge.sourceHandle != null) message += \" Leave sourceHandle off to read the node's output.\";\n\n return message;\n}\n","import type { WorkflowInput } from \"../types\";\n\n/**\n * Resolving what a caller passed against what a workflow declared.\n *\n * Kept in its own module, and deliberately a pure function over two plain\n * objects, because the PHP and Python runtimes implement the same rules and\n * `suites/flow/workflow-props` in `@particle-academy/fancy-conformance` is the\n * table all three run. A rule that lives inside a runner is a rule each runtime\n * re-derives; a rule that is a function over maps is one they can share a\n * fixture for.\n *\n * ## Every branch here exists to make a mistake LOUD\n *\n * The failure this replaces was silence. `initialInputs` was keyed by node id,\n * so a caller passed `{ t: { topic: \"otters\" } }` and had to know the trigger\n * was named `t`; and nothing declared what a workflow accepted, so a\n * misspelled key was not an error — the value sat unread, the node saw\n * nothing, and the run reported success with output that was quietly wrong.\n *\n * So: an unknown key fails, a missing required value fails, and a wrong type\n * fails. None of those is a warning. A warning on a queue worker is a line in a\n * log nobody opens.\n */\n\n/**\n * Why a resolution failed, in a vocabulary that is the same in every runtime.\n *\n * The MESSAGE is English prose and each runtime words it slightly differently,\n * which is fine for a human and useless for a shared fixture table. The CODE is\n * what `suites/flow/workflow-props` asserts, so parity is pinned on the\n * decision rather than on the phrasing — otherwise the three implementations\n * would be held to a translation instead of a behaviour.\n */\nexport type PropsErrorCode = \"unknown_input\" | \"missing_required\" | \"type_mismatch\";\n\n/** The outcome of checking a caller's props against a declaration. */\nexport type PropsResolution =\n | { ok: true; props: Record<string, unknown> }\n | { ok: false; code: PropsErrorCode; error: string };\n\n/**\n * The runtime type of a value, in the vocabulary a declaration uses.\n *\n * Arrays are checked before objects because `typeof []` is `\"object\"` and a\n * declaration that says `array` means a list — accepting `{}` there would be\n * the check passing while meaning nothing.\n */\nfunction typeOf(value: unknown): string {\n if (value === null) return \"null\";\n if (Array.isArray(value)) return \"array\";\n return typeof value;\n}\n\n/**\n * Check and fill a caller's props.\n *\n * Returns the resolved map — declared defaults filled in, nothing else added —\n * or the first error. One error rather than a list, because a run stops at the\n * first one anyway and a caller fixing a call wants the thing to fix, not a\n * report.\n */\nexport function resolveWorkflowProps(\n declared: WorkflowInput[] | undefined,\n passed: Record<string, unknown> | undefined,\n): PropsResolution {\n const inputs = declared ?? [];\n const given = passed ?? {};\n const byName = new Map(inputs.map((input) => [input.name, input]));\n\n // UNKNOWN KEYS FIRST, and this is the check the whole feature is for.\n //\n // A caller who misspells `topic` as `topik` has configured nothing, and\n // before this the run went ahead and looked fine. Checking it before\n // anything else means the error names what they typed rather than\n // complaining that the thing they thought they passed is missing.\n for (const name of Object.keys(given)) {\n if (!byName.has(name)) {\n const known = inputs.map((input) => input.name);\n const suffix = known.length === 0\n ? \"this workflow declares no inputs\"\n : `known inputs: ${known.join(\", \")}`;\n\n return {\n ok: false,\n code: \"unknown_input\",\n error: `Unknown workflow input \"${name}\" — ${suffix}.`,\n };\n }\n }\n\n const resolved: Record<string, unknown> = {};\n\n for (const input of inputs) {\n // `hasOwnProperty`, not a truthiness or `??` check. `0`, `false` and `\"\"`\n // are real values a caller meant to pass, and a default applied over them\n // is a silent override — a limit of 0 quietly becoming 10 is not an error\n // anybody sees.\n const supplied = Object.prototype.hasOwnProperty.call(given, input.name);\n const hasDefault = Object.prototype.hasOwnProperty.call(input, \"default\");\n\n if (!supplied) {\n if (hasDefault) {\n resolved[input.name] = input.default;\n continue;\n }\n\n if (input.required) {\n return {\n ok: false,\n code: \"missing_required\",\n error: `Missing required workflow input \"${input.name}\"${\n input.type ? ` (${input.type})` : \"\"\n }.`,\n };\n }\n\n // Not supplied, no default, not required — absent rather than\n // `undefined`, so `{{ $props.x }}` resolves to null on both runtimes\n // instead of one of them inventing a key.\n continue;\n }\n\n const value = given[input.name];\n\n // An undeclared type accepts anything. \"I am not asserting a shape\" must\n // not degrade into \"nothing is allowed\".\n if (input.type !== undefined) {\n const actual = typeOf(value);\n if (actual !== input.type) {\n return {\n ok: false,\n code: \"type_mismatch\",\n error: `Workflow input \"${input.name}\" expects ${input.type}, got ${actual}.`,\n };\n }\n }\n\n resolved[input.name] = value;\n }\n\n return { ok: true, props: resolved };\n}\n","import type {\n ExecutorRegistry,\n FlowEdge,\n FlowGraph,\n FlowNode,\n NodeExecutor,\n RunEvent,\n} from \"../types\";\n// Both modules are React-free by design — the `/engine` entry must not pull in\n// React. Import them directly rather than via the `registry` barrel, which\n// re-exports the RegistryNode component.\nimport { getNodeKind, kindIds } from \"../registry/registry\";\nimport { resolveNodePorts } from \"../registry/ports\";\nimport { RunIdentity, type RunIdentityJson } from \"./run-identity\";\nimport { TerminalSessions, specForLane } from \"./terminal-sessions\";\nimport { undeliveredEdgeWarnings } from \"./undelivered-edges\";\nimport { resolveWorkflowProps } from \"./workflow-props\";\n\nexport type RunOptions = {\n /** Stop the run after this many ms. Default: no timeout. */\n timeoutMs?: number;\n /** Abort signal — host can cancel the run. */\n signal?: AbortSignal;\n /** Initial inputs supplied to entry-point nodes (no incoming edges). */\n initialInputs?: Record<string, Record<string, unknown>>;\n /**\n * Values for the inputs the graph DECLARES, passed by name.\n *\n * The flat, node-id-free way to configure a run. `initialInputs` is keyed by\n * node id, so a caller had to know the trigger was called `t` and a rename\n * broke every caller while the graph stayed valid. Props are checked against\n * `graph.inputs`, so a misspelling fails the run instead of sitting unread.\n */\n props?: Record<string, unknown>;\n /**\n * Which ENTRY POINTS are live — the ids of nodes with NO incoming edges this\n * run should start from. Omit it and every entry point runs, exactly as\n * before the option existed.\n *\n * A graph may hold more than one trigger — a `manual_trigger` for\n * hand-testing beside the event trigger that runs it for real — and a trigger\n * has no inbound edges, which IS the readiness rule. So without this, every\n * trigger's branch runs on every run, whichever one fired. The triggers\n * themselves are harmless; everything DOWNSTREAM of the ones that did not\n * fire is not. A `user_input` stranded on the manual branch parks an\n * event-driven run to ask a person for data the event already supplied,\n * which from outside looks like the event trigger being ignored.\n *\n * Naming the live entry points makes the others INACTIVE, and the existing\n * \"at least one active inbound edge\" rule then skips everything reachable\n * only from them. No new routing logic.\n *\n * Three edges, each pinned by `flow/entry-points` in\n * `@particle-academy/fancy-conformance`:\n * - `undefined` is NOT `[]`. Unset runs every entry point; an empty array\n * says none is live and runs nothing.\n * - A node reachable from SEVERAL entry points still runs when any one of\n * them fires — one active inbound edge is enough, as always.\n * - Naming a node that HAS inbound edges names no entry point, so every real\n * entry is inactive and nothing runs. That falls out of the rule rather\n * than being special-cased; validate your ids if you want a typo to be\n * loud, because the runtime cannot tell one from a deliberate empty\n * selection.\n */\n entryNodes?: string[];\n /** Nesting depth — set by `subflow` when it runs a child graph. */\n depth?: number;\n /**\n * Who is running, so a writing node can derive a stable idempotency key.\n *\n * A bare string is taken as the run key. **Deliberately not defaulted:** a\n * minted-per-call key would change on every whole-run retry, which is exactly\n * the failure an idempotency key exists to prevent — so a host that has not\n * supplied one gets `ctx.run === undefined` and a connector that declines to\n * write blind, rather than a plausible-looking key that double-charges.\n */\n run?: RunIdentity | RunIdentityJson | string;\n /**\n * Outputs already checkpointed for this run, keyed by node id.\n *\n * A node present here is **republished, not re-executed** — its stored value\n * goes back onto the same ports, so downstream routing reproduces exactly\n * what it did the first time. This is what makes a per-node durable driver\n * possible without a second copy of the routing rules, and it is how the PHP\n * and Python runtimes have always resumed.\n */\n resumeOutputs?: Record<string, unknown>;\n /**\n * Executors bound to ONE node id each, matched against `node.id` and nothing\n * else. They outrank every entry of the executor registry.\n *\n * The registry cannot say this. It is one flat object, and `executorLookupIds`\n * tries a key as the node's id AND as its kind, so a key that is both is both:\n * binding `host_kind` to pin the node CALLED `host_kind` also rebinds every\n * node whose kind is `host_kind`. That is the registry's contract (pinned by\n * `flow/executor-resolution`) and it stays. This is the separate channel for a\n * binding that must not leak into the kind namespace -- the PHP twin's\n * `bindNode`, which has always been kept apart from `bind`.\n *\n * The durable replay fences every node but its target through this. Through\n * the registry, a node whose id matched a kind fenced every node of that kind,\n * and the durable run reported success having run nothing.\n *\n * NOT handed down to a nested run. Node ids belong to one graph: a `subflow`\n * child's `t` is not its parent's `t`, so `ctx.executors` stays the registry\n * alone.\n */\n nodeExecutors?: Record<string, NodeExecutor>;\n};\n\nexport type RunResult = {\n ok: boolean;\n /** Outputs collected per node, keyed by node id. */\n outputs: Record<string, unknown>;\n /** Error captured if any node threw. */\n error?: string;\n};\n\n/**\n * runFlow — topological execution of a FlowGraph against an ExecutorRegistry.\n *\n * Each node runs once, when all upstream nodes have produced outputs on the\n * connected ports. Decision nodes (or any executor that returns `{ branch:\n * 'true' }`) can short-circuit specific output ports — only edges leaving\n * an \"active\" port propagate to downstream nodes.\n *\n * Cycles are detected and abort the run with an error.\n *\n * The `onEvent` callback receives a stream of `RunEvent`s — wire it to a\n * status feed, log panel, or store.\n */\nexport async function runFlow(\n graph: FlowGraph,\n executors: ExecutorRegistry,\n onEvent: (event: RunEvent) => void = () => {},\n options: RunOptions = {},\n): Promise<RunResult> {\n const { signal, initialInputs = {}, timeoutMs, depth = 0, resumeOutputs = {}, entryNodes, nodeExecutors } = options;\n const run = options.run === undefined ? undefined : RunIdentity.from(options.run);\n const outputs: Record<string, unknown> = {};\n const portValues = new Map<string, unknown>(); // key: `${nodeId}:${portId}`\n const completed = new Set<string>();\n const errors: string[] = [];\n\n // Topological order via Kahn's algorithm. We allow nodes to run as soon\n // as their incoming edges' source ports have produced values, so the\n // order here is just a deterministic baseline used for cycle detection.\n const order = topoSort(graph);\n if (order === null) {\n const msg = \"Cycle detected in flow graph — aborting.\";\n onEvent({ type: \"run-error\", error: msg });\n return { ok: false, outputs, error: msg };\n }\n\n // Props are checked BEFORE anything runs, and a failure aborts the run.\n //\n // Before a node executes, not after: a workflow whose third node needed a\n // value the caller misspelled would otherwise do two nodes' worth of real\n // work — sending, writing, charging — and only then discover the call was\n // malformed. Validation that happens after a side effect is not validation.\n const propsCheck = resolveWorkflowProps(graph.inputs, options.props);\n if (!propsCheck.ok) {\n onEvent({ type: \"run-error\", error: propsCheck.error });\n return { ok: false, outputs, error: propsCheck.error };\n }\n const props = propsCheck.props;\n const declaresProps = (graph.inputs?.length ?? 0) > 0;\n\n const incomingByNode = indexIncoming(graph.edges);\n // Built ONCE. Used only to explain an undelivered edge, but building it per\n // node would make a diagnostic quietly O(n^2) on the hot path.\n const nodesById = new Map(graph.nodes.map((n) => [n.id, n]));\n\n // Terminal lanes. Constructed unconditionally and costing nothing until a\n // node inside one actually runs — a graph with no terminal lane never asks\n // for a host, so nothing spawns and nothing needs one registered.\n const sessions = new TerminalSessions(graph);\n const isTerminalLane = (candidate: FlowNode): boolean =>\n getNodeKind(candidate.type ?? \"\")?.name === \"@particle-academy/terminal_lane\";\n\n const terminalAccessorFor = (node: FlowNode) => {\n const laneId = sessions.laneFor(node.id, isTerminalLane);\n if (laneId === null) return undefined;\n\n const lane = graph.nodes.find((n) => n.id === laneId);\n if (!lane) return undefined;\n\n // Returned as a FUNCTION rather than an open session, so the terminal opens\n // on first USE rather than when a node in the lane starts. A node that\n // never touches its terminal never spawns one, which is what makes the\n // lane safe to draw around nodes that mostly do other things.\n return {\n session: () => sessions.session(laneId, specForLane(lane)),\n // Awaits the session first on purpose. A transcript handed out before\n // anything is feeding it would look perfectly healthy and match nothing,\n // and \"waited and nothing came\" is the hardest failure here to tell apart\n // from a process that is simply slow.\n transcript: async () => {\n await sessions.session(laneId, specForLane(lane));\n return sessions.transcriptFor(laneId);\n },\n };\n };\n\n const timer = timeoutMs ? setTimeout(() => errors.push(`Run timed out after ${timeoutMs}ms`), timeoutMs) : null;\n\n onEvent({ type: \"run-start\" });\n\n try {\n for (const node of order) {\n if (signal?.aborted) throw new Error(\"aborted\");\n if (errors.length) break;\n\n // A checkpointed node is republished, never re-executed. Publishing the\n // stored value back onto its own ports is what makes the resume exact:\n // the branch it took, the ports it lit and the inputs its successors\n // collect are all reproduced by the engine's own rules rather than by a\n // driver's recollection of them.\n if (Object.prototype.hasOwnProperty.call(resumeOutputs, node.id)) {\n const stored = resumeOutputs[node.id];\n outputs[node.id] = stored;\n const activated = activatedPorts(node, stored);\n for (const portId of activated.ports) {\n const value = portValueOf(activated, portId);\n portValues.set(`${node.id}:${portId}`, value);\n onEvent({ type: \"node-output\", nodeId: node.id, portId, value });\n }\n completed.add(node.id);\n onEvent({ type: \"node-status\", nodeId: node.id, status: \"done\", text: \"resumed\" });\n continue;\n }\n\n const incoming = incomingByNode.get(node.id) ?? [];\n\n // An ENTRY POINT this run did not start from is inactive.\n //\n // A node with no inbound edges is unconditionally ready -- that IS the\n // readiness rule -- so a graph with two triggers ran both branches on\n // every run, whichever trigger actually fired. Marking the unnamed ones\n // inactive here lets the \"at least one active inbound edge\" test below\n // skip everything reachable only from them, with no new routing logic.\n //\n // Gates only nodes with NO incoming edges: a node further down the graph\n // is not an entry point, and its readiness is still decided by its edges.\n if (incoming.length === 0 && entryNodes !== undefined && !entryNodes.includes(node.id)) {\n onEvent({ type: \"node-status\", nodeId: node.id, status: \"idle\", text: \"skipped\" });\n continue;\n }\n\n // AN EDGE THAT DELIVERS NOTHING MUST SAY SO.\n //\n // Checked HERE, before the activity gate, because the two outcomes are\n // both silent and only one reaches `collectInputs`: a node whose only\n // inbound edge is bad is SKIPPED, and one with another live edge RUNS with\n // that port missing. The rule itself lives in `undeliveredEdgeWarnings`,\n // which the durable coordinator also asks at its skip decision -- one\n // implementation, so the two paths cannot disagree about a handle.\n for (const warning of undeliveredEdgeWarnings(node, incoming, portValues, completed, nodesById)) {\n onEvent(warning);\n }\n\n // Run a node once any upstream branch reaches it. We iterate in\n // topological order, so by the time we reach this node every upstream\n // node has been processed — each incoming edge is therefore *settled*\n // (active or dead, never still-pending). Requiring ALL incoming edges to\n // be active wrongly skipped MERGE POINTS: when a Decision routes down one\n // branch, the other branch's edge stays dead forever, so an `every` check\n // skipped the shared continuation node and halted the run after the first\n // branch (#1). Run when AT LEAST ONE incoming edge is active —\n // collectInputs() only reads from the active ones. A genuine parallel\n // join still works: in topo order both of its inputs are already active.\n if (incoming.length > 0) {\n const anyActive = incoming.some((e) => portValues.has(`${e.source}:${e.sourceHandle ?? \"out\"}`));\n if (!anyActive) {\n onEvent({ type: \"node-status\", nodeId: node.id, status: \"idle\", text: \"skipped\" });\n continue;\n }\n }\n\n // Notes/annotations + layout (lane/pool) nodes are visual only — never\n // executed and never fed to runners. Their config (a note's text, a lane's\n // title) stays in the document for editors + MCP tools, but the engine\n // walks straight past them. Edges cross lanes freely, so grouping never\n // affects topology.\n const visualKind = getNodeKind(node.type ?? \"\");\n const isLayout = visualKind?.category === \"layout\";\n const isAnnotation = node.type === \"note\" || visualKind?.category === \"annotation\";\n if (isLayout || isAnnotation) {\n onEvent({\n type: \"node-status\",\n nodeId: node.id,\n status: \"idle\",\n text: isLayout ? \"lane\" : \"annotation\",\n });\n continue;\n }\n\n onEvent({ type: \"node-status\", nodeId: node.id, status: \"running\" });\n announce(onEvent, node, \"start\");\n\n const inputs = collectInputs(node, incoming, portValues, initialInputs, props, declaresProps);\n const exec = pickExecutor(executors, node, nodeExecutors);\n if (!exec) {\n // Name what was LOOKED FOR, not just what the node calls itself.\n //\n // This said `kind=${node.type}` — so a registry keyed under one of the\n // kind's other ids produced \"kind=manual_trigger is missing\" about a\n // kind that exists AND is registered, just under a different key. The\n // consumer who reported it reasonably read that as the kind being\n // absent and went looking for a missing package.\n // The wildcard is part of `executorLookupIds` now, so it is already in\n // the list — appending \"and the wildcard\" as well made the message name\n // it twice, and the test that reads the ids back out of the message\n // parsed the prose between the two quoted stars as an id.\n const tried = executorLookupIds(node);\n const msg = `No executor registered for kind=${node.type}`\n + ` — tried ${tried.map((id) => `\"${id}\"`).join(\", \")}`\n + `. Key your registry by one of those.`;\n errors.push(msg);\n onEvent({ type: \"node-status\", nodeId: node.id, status: \"error\", text: msg });\n onEvent({ type: \"log\", nodeId: node.id, level: \"error\", message: msg });\n break;\n }\n\n try {\n const result = await Promise.resolve(\n exec({\n node,\n inputs,\n abort: (reason) => { throw new Error(reason ?? \"aborted\"); },\n emit: onEvent,\n executors,\n depth,\n run,\n terminal: terminalAccessorFor(node),\n }),\n );\n outputs[node.id] = result;\n\n // Decide which output ports were activated. Three conventions:\n // 1) If result is `{ __port: \"out\", value: x }`, only that port emits.\n // 2) If result has `branch: <portId>`, only that port emits (decision sugar).\n // 3) If result has `__ports`, exactly those emit — a list shares one\n // payload, a map gives each its own.\n // 4) Otherwise, the value is published on every declared output port.\n const activated = activatedPorts(node, result);\n for (const portId of activated.ports) {\n const value = portValueOf(activated, portId);\n portValues.set(`${node.id}:${portId}`, value);\n onEvent({ type: \"node-output\", nodeId: node.id, portId, value });\n }\n completed.add(node.id);\n onEvent({ type: \"node-status\", nodeId: node.id, status: \"done\" });\n // Only on the success path, and deliberately so: a `stoppingMsg` of\n // \"Analysis complete\" emitted after a throw tells a human the opposite\n // of what happened, in the part of the UI they trust most. A failure\n // reports through node-status/log, which is what those exist for.\n announce(onEvent, node, \"end\");\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n errors.push(msg);\n onEvent({ type: \"node-status\", nodeId: node.id, status: \"error\", text: msg });\n onEvent({ type: \"log\", nodeId: node.id, level: \"error\", message: msg });\n break;\n }\n }\n } finally {\n if (timer) clearTimeout(timer);\n\n // Terminals close HERE, in the same `finally` that clears the timer, so\n // they go away on the error and abort paths too — not only when a run ends\n // tidily. A PTY that outlives its run is a process nobody is watching and\n // nothing will close.\n //\n // Failures are reported and swallowed rather than thrown: this is the\n // teardown path, and throwing would replace the run's real error with a\n // cleanup error, hiding what actually went wrong behind the consequence.\n for (const error of await sessions.closeAll()) {\n onEvent({ type: \"log\", level: \"warn\", message: `terminal close failed: ${error.message}` });\n }\n }\n\n const ok = errors.length === 0;\n onEvent({ type: \"run-end\", ok });\n return ok ? { ok, outputs } : { ok, outputs, error: errors[0] };\n}\n\nfunction indexIncoming(edges: FlowEdge[]): Map<string, FlowEdge[]> {\n const map = new Map<string, FlowEdge[]>();\n for (const e of edges) {\n const list = map.get(e.target) ?? [];\n list.push(e);\n map.set(e.target, list);\n }\n return map;\n}\n\nfunction topoSort(graph: FlowGraph): FlowNode[] | null {\n const inDegree = new Map<string, number>();\n for (const n of graph.nodes) inDegree.set(n.id, 0);\n for (const e of graph.edges) inDegree.set(e.target, (inDegree.get(e.target) ?? 0) + 1);\n const queue: string[] = [];\n for (const [id, d] of inDegree) if (d === 0) queue.push(id);\n const ordered: string[] = [];\n while (queue.length) {\n const id = queue.shift()!;\n ordered.push(id);\n for (const e of graph.edges) {\n if (e.source !== id) continue;\n const next = (inDegree.get(e.target) ?? 0) - 1;\n inDegree.set(e.target, next);\n if (next === 0) queue.push(e.target);\n }\n }\n if (ordered.length !== graph.nodes.length) return null;\n const byId = new Map(graph.nodes.map((n) => [n.id, n]));\n return ordered.map((id) => byId.get(id)!).filter(Boolean);\n}\n\nfunction collectInputs(\n node: FlowNode,\n incoming: FlowEdge[],\n portValues: Map<string, unknown>,\n initial: Record<string, Record<string, unknown>>,\n props: Record<string, unknown>,\n declaresProps: boolean,\n): Record<string, unknown> {\n const inputs: Record<string, unknown> = { ...(initial[node.id] ?? {}) };\n\n // ENTRY POINTS are seeded with the props by their bare names.\n //\n // This is what lets an existing graph keep working unchanged. A trigger that\n // reads `{{ topic }}` was fed by `initialInputs[triggerId].topic`; a caller\n // moving to props passes `{ topic }` and the node sees exactly what it saw\n // before. Only entry points, because a node in the middle of a graph reading\n // a bare `topic` would be shadowing whatever its upstream edge is called.\n //\n // Never clobbers: a value already seeded by the host is the host's.\n if (incoming.length === 0) {\n for (const [name, value] of Object.entries(props)) {\n if (!(name in inputs)) inputs[name] = value;\n }\n }\n for (const e of incoming) {\n const portId = e.targetHandle ?? \"in\";\n const key = `${e.source}:${e.sourceHandle ?? \"out\"}`;\n // A branch that never fired has no entry in portValues. Assigning its\n // `undefined` would CLOBBER the value the branch that DID fire already\n // contributed on this same handle — emptying every merge point downstream\n // of a decision, silently, with the run still reporting success.\n //\n // This is the other half of the merge-point bug above: that fix stopped the\n // shared continuation node being skipped, but it still arrived with nothing\n // whenever a later inactive edge happened to be last in `incoming`.\n if (!portValues.has(key)) continue;\n inputs[portId] = portValues.get(key);\n\n // ALSO address it by the SOURCE NODE'S ID, when the edge named no handle.\n //\n // Authors reach for node ids -- every graph tool addresses nodes that way,\n // so `{{ n2.text }}` is the first thing written, by people and far more\n // often by assistants generating graphs. That resolved to nothing, and\n // NOTHING FAILED: an unresolvable path yields \"\", so the node ran, the run\n // reported success, and the damage was output that was quietly wrong. A\n // consumer shipped a file named `document.md` containing the literal text\n // of its own template, on a green run (fancy-flow-php#8).\n //\n // `targetHandle` already covers this and stays the right mechanism for\n // reading something other than the immediate predecessor -- but it is set\n // on the EDGE, which is not where an author is looking while writing a\n // node's config. The model was not wrong; the obvious spelling meant\n // nothing.\n //\n // Only for edges that declared NO handle: an edge that named one said what\n // it meant, and a second key under the source id would quietly widen a\n // deliberate contract. `??=` so nothing already seeded -- by the host's\n // initialInputs or an earlier edge -- is ever clobbered.\n if (e.targetHandle == null && !(e.source in inputs)) {\n inputs[e.source] = portValues.get(key);\n }\n }\n\n // EVERY node gets `$props` — but ONLY when the workflow declares inputs.\n //\n // The first half is what makes props usable at depth. Seeding entry points\n // alone would mean a node six hops downstream had the value threaded through\n // every edge in between, and every hop is somewhere it can be dropped. It\n // costs nothing to resolve because `$props` is an ORDINARY KEY in the inputs\n // object: `resolvePath` already walks dot-paths against it, so\n // `{{ $props.topic }}` works with no change to any expression resolver in any\n // of the three runtimes.\n //\n // The second half is a CORRECTION, and the golden parity fixtures caught it.\n // An earlier draft wrote `$props` unconditionally, justified as \"so\n // `{{ $props.x }}` resolves to null rather than throwing\" — which is not\n // true. `resolvePath` returns null for any unresolvable path, so on a graph\n // declaring nothing the key changes no behaviour at all. What it DOES do is\n // add a key to every executor's inputs, on every graph, forever — which\n // showed up instantly as a diff in every stored golden.\n //\n // `ConnectorFacet::from` states the same rule for the same reason: a payload\n // gaining a key on every entry is a wire change for no gain, and the ABSENCE\n // of a key is already the honest way to say \"this one takes no props\".\n //\n // Keyed on the DECLARATION rather than on whether a value arrived: a workflow\n // whose inputs are all optional and all omitted still declared a contract, so\n // `$props` is present and empty.\n if (declaresProps) inputs.$props = props;\n\n return inputs;\n}\n\n/**\n * Every key a node's executor may legitimately be registered under, in\n * precedence order. **This is the resolution rule** — `pickExecutor` walks this\n * list and takes the first hit, and the failure message lists the same ids.\n *\n * That sharing is the point, and it used to be a claim rather than a fact: this\n * docblock already said \"shared by the lookup and by its failure message\" while\n * `pickExecutor` re-implemented the walk beside it. The two agreed until the\n * precedence changed, and then the message listed an id the lookup no longer\n * tried — sending a reader to check something that never happened, which the\n * comment correctly named as worse than listing nothing. **Prose next to a check\n * is not the check.** One list now, walked by both, so they cannot drift.\n *\n * The order, and why:\n *\n * 1. `node.id` — the per-node override. First so a graph can pin ONE node to a\n * stub without unbinding that kind for every other node using it.\n * 2. `node.type`, then every id its kind answers to — **if `node.type` names a\n * registered kind, it is authoritative and `data.kind` is not consulted at\n * all.** A node that says it is an `llm_call` must never quietly run another\n * kind's code; it fails closed instead.\n * 3. Otherwise `data.kind` and its kind's ids. A `node.type` naming no\n * registered kind is not a claim about behaviour — usually it is an xyflow\n * RENDERER type (`\"fancyNode\"`), which is ordinary practice, and then\n * `data.kind` is the only real answer. This branch also covers `type` absent.\n * 4. `\"*\"` — the wildcard, last, and a sentinel rather than a kind: it is never\n * expanded through the alias machinery, or every unmatched node would bind to\n * whatever a kind literally named `*` aliased to.\n *\n * Pinned as `flow/executor-resolution` in `@particle-academy/fancy-conformance`.\n */\nfunction executorLookupIds(node: FlowNode): string[] {\n const ids: string[] = [node.id];\n if (node.type) ids.push(node.type);\n\n const typeKind = node.type ? getNodeKind(node.type) : null;\n\n if (typeKind) {\n for (const id of kindIds(typeKind)) ids.push(id);\n } else {\n const declared = (node.data as { kind?: unknown } | undefined)?.kind;\n const kindName = typeof declared === \"string\" && declared !== \"\" ? declared : null;\n\n if (kindName) {\n ids.push(kindName);\n const dataKind = getNodeKind(kindName);\n if (dataKind) {\n for (const id of kindIds(dataKind)) ids.push(id);\n }\n }\n }\n\n ids.push(\"*\");\n\n return [...new Set(ids)];\n}\n\nfunction pickExecutor(\n executors: ExecutorRegistry,\n node: FlowNode,\n nodeExecutors?: Record<string, NodeExecutor>,\n): NodeExecutor | undefined {\n // A node-only binding is looked up by the node's id and NO other key, which\n // is the whole reason it is not an entry in `executors` (see\n // `RunOptions.nodeExecutors`). Own properties only: a node called\n // `constructor` must not find `Object`.\n const pinned = nodeExecutors && Object.prototype.hasOwnProperty.call(nodeExecutors, node.id)\n ? nodeExecutors[node.id]\n : undefined;\n if (pinned) return pinned;\n\n // The whole rule lives in `executorLookupIds` -- see its docblock. Walking\n // that one list is what keeps the resolution and the failure message from\n // ever disagreeing about which keys were tried.\n //\n // The HOST registry is consulted first, and that order is the contract: a\n // kind ships an executor as a default, and a host that registers its own\n // takes over. Reversing it would make a builtin unoverridable.\n for (const id of executorLookupIds(node)) {\n if (executors[id]) return executors[id];\n }\n\n // Then the kind's own, for the kinds that ship one.\n //\n // This fallback did not exist, and `NodeKindDefinition.executor` was\n // therefore a field nothing read. `subflow` and `llm_router` have both\n // declared one since they were written, and both were unreachable through\n // `runFlow`: a consumer who called `registerBuiltinKinds()` and ran a graph\n // containing a subflow node got \"No executor registered for kind=subflow\"\n // about a kind that ships its executor in the same object as its schema.\n //\n // It survived because the two are unit-tested by calling the executor\n // directly — which proves the executor works and says nothing about whether\n // anything can reach it. A declared capability with no reader is the shape\n // this estate keeps finding, and the only reliable way to catch it is a test\n // that goes through the front door.\n return getNodeKind(node.type ?? \"\")?.executor;\n}\n\nfunction activatedPorts(node: FlowNode, result: unknown): { ports: string[]; value: unknown; values?: Record<string, unknown> } {\n if (result && typeof result === \"object\") {\n const r = result as Record<string, unknown>;\n if (typeof r.__port === \"string\") {\n return { ports: [r.__port], value: r.value };\n }\n // A CHOSEN SUBSET (fancy-flow-php#18): a list lights those ports with one\n // payload, a map gives each lit port its own. Before this a node could light\n // one port or all of them, so a router that matched two of five had to drop\n // work or wake lanes nobody asked for.\n //\n // An empty list lights NOTHING, deliberately — the same rule an explicitly\n // empty `outputs` array follows below. `values` is read per port, so a\n // payload that is present and null stays null rather than falling back to\n // the whole result, which is the trap `branch` already had to learn.\n if (Array.isArray(r.__ports)) {\n return { ports: r.__ports.filter((p): p is string => typeof p === \"string\"), value: r.value };\n }\n if (r.__ports && typeof r.__ports === \"object\") {\n const values = r.__ports as Record<string, unknown>;\n return { ports: Object.keys(values), value: r.value, values };\n }\n if (typeof r.branch === \"string\") {\n // `Object.hasOwn`, NOT `??`. The two are different questions:\n // no `value` key at all -> the whole result IS the payload (the case\n // this fallback exists for)\n // `value` present, null -> the payload is null; pass null on\n // `r.value ?? r` cannot tell them apart, so a branch whose payload was\n // null leaked the WRAPPER downstream -- every following node received\n // `{ branch, value }`, two fields no kind declares, while the fields it\n // does declare were absent. The reachable path is an upstream `transform`\n // whose dot-path did not resolve, which is exactly the silent-null case.\n // `Port.only`'s `?? null` never had it. All four runtimes shared this,\n // identically -- so no parity table could catch it; they agreed on being\n // wrong.\n return { ports: [r.branch], value: Object.prototype.hasOwnProperty.call(r, \"value\") ? r.value : r };\n }\n }\n // Resolve through the shared helper so the ports the runtime activates are\n // the same ones the canvas drew — including config-driven ports, which the\n // node's `data` does not carry. Falls back to a lone `out` when a node\n // declares nothing.\n const kind = getNodeKind((node.data as any)?.kind ?? node.type ?? \"\") ?? undefined;\n const declared = resolveNodePorts(node, kind).outputs?.map((p) => p.id);\n return { ports: declared?.length ? declared : [\"out\"], value: result };\n}\n\n/**\n * What one lit port carries: its own entry when the result named ports\n * individually, otherwise the single payload every lit port shares.\n *\n * `hasOwnProperty`, not `??`: a per-port payload that is present and null is a\n * payload. `values[portId] ?? value` would quietly hand that port the shared\n * value instead — the same confusion `branch` had between \"no key\" and \"null\".\n */\nfunction portValueOf(activated: { value: unknown; values?: Record<string, unknown> }, portId: string): unknown {\n return activated.values && Object.prototype.hasOwnProperty.call(activated.values, portId)\n ? activated.values[portId]\n : activated.value;\n}\n\n/**\n * Emit a node's own status message for one phase of its execution, if it\n * declared one.\n *\n * Opt-in by absence: a node with no `startingMsg` / `stoppingMsg` says nothing,\n * because most nodes in a real graph are plumbing and narrating all of them\n * buries the two or three steps a person actually wants to follow.\n *\n * A message must be a non-empty string after trimming. An empty string is the\n * shape a cleared editor field takes, and a blank line in a progress feed is\n * indistinguishable from a real message that happens to render as nothing —\n * so it is treated as \"not set\" rather than as \"announce nothing visible\".\n */\nfunction announce(\n onEvent: (event: RunEvent) => void,\n node: FlowNode,\n phase: \"start\" | \"end\",\n): void {\n const data = node.data as { startingMsg?: unknown; stoppingMsg?: unknown } | undefined;\n const raw = phase === \"start\" ? data?.startingMsg : data?.stoppingMsg;\n if (typeof raw !== \"string\") return;\n\n const message = raw.trim();\n if (message === \"\") return;\n\n onEvent({ type: \"node-message\", nodeId: node.id, phase, message });\n}\n","import { getWorkflowResolver, isResolutionFailure } from \"./capabilities\";\nimport { runFlow } from \"../runtime/run-flow\";\nimport type { FlowGraph, NodeExecutor, RunEvent } from \"../types\";\n\n/**\n * `@fancy/subflow` — run another workflow and bring its result home.\n *\n * Core, not marketplace: it introduces no third-party dependency. It runs a\n * child graph through the very same engine, so the only thing it needs from the\n * host is where workflows live (`registerWorkflowResolver`).\n *\n * Three output modes, because both halves are genuinely useful:\n *\n * - `output` — the child's outputs arrive on `out` when it finishes.\n * - `stream` — the child's events are forwarded live on `stream` as they\n * happen, so a parent can show progress instead of a spinner.\n * - `both` — stream while running AND deliver the final outputs.\n *\n * Recursion is guarded by depth. A workflow that references itself (directly or\n * through a chain) would otherwise recurse until the stack dies, which surfaces\n * as an opaque crash rather than \"you built a loop\".\n */\n\nexport const DEFAULT_MAX_DEPTH = 8;\n\nexport type SubflowMode = \"output\" | \"stream\" | \"both\";\n\nexport function subflowMode(config: Record<string, unknown>): SubflowMode {\n const mode = config.mode;\n return mode === \"stream\" || mode === \"both\" ? mode : \"output\";\n}\n\n/** Ports follow the mode — `stream` only exists when something streams. */\nexport function subflowPorts(config: Record<string, unknown>) {\n const mode = subflowMode(config);\n const ports = [{ id: \"out\", label: \"result\" }];\n if (mode === \"stream\" || mode === \"both\") ports.unshift({ id: \"stream\", label: \"stream\" });\n return ports;\n}\n\n/**\n * Entry-point inputs for the child run: the node's explicit `inputs` mapping,\n * or — absent or empty — the parent's inputs handed to every entry node (a node\n * with no incoming edge), so the simple case needs no configuration at all.\n *\n * The same rule as the PHP and Python engines. This used to seed\n * `{ __parent: inputs }`: `initialInputs` is keyed by node id and nothing is\n * called `__parent`, so the child ran with no inputs and nothing said so.\n */\nexport function childInputs(\n config: Record<string, unknown>,\n child: FlowGraph,\n inputs: Record<string, unknown>,\n): Record<string, Record<string, unknown>> {\n const mapping = config.inputs;\n\n if (mapping && typeof mapping === \"object\" && !Array.isArray(mapping) && Object.keys(mapping).length > 0) {\n return mapping as Record<string, Record<string, unknown>>;\n }\n\n const hasIncoming = new Set(child.edges.map((edge) => edge.target));\n const seeded: Record<string, Record<string, unknown>> = {};\n\n for (const node of child.nodes) {\n if (!hasIncoming.has(node.id)) seeded[node.id] = inputs;\n }\n\n return seeded;\n}\n\nexport const subflowExecutor: NodeExecutor = async (ctx) => {\n const config = ((ctx.node.data as any)?.config ?? {}) as Record<string, unknown>;\n const ref = String(config.workflow ?? \"\").trim();\n if (!ref) ctx.abort(\"subflow has no workflow reference configured\");\n\n const resolver = getWorkflowResolver();\n if (!resolver) {\n ctx.abort(\n \"No workflow resolver registered. Call registerWorkflowResolver() so subflow can find the workflow it references.\",\n );\n }\n\n const maxDepth = Number.isFinite(config.maxDepth) ? Number(config.maxDepth) : DEFAULT_MAX_DEPTH;\n const depth = ctx.depth ?? 0;\n if (depth + 1 > maxDepth) {\n // Name the cause. \"Maximum call stack exceeded\" tells an author nothing\n // about the workflow they wired into itself.\n ctx.abort(\n `subflow depth limit reached (${maxDepth}) at \"${ref}\" — a workflow is referencing itself, directly or through a chain.`,\n );\n }\n\n // An optional pin. A workflow another workflow depends on is an interface:\n // without a pin, someone edits the child and the parent silently runs\n // different logic while still reporting success.\n const pinned = config.version === undefined || config.version === \"\" ? undefined : Number(config.version);\n if (pinned !== undefined && !Number.isInteger(pinned)) {\n ctx.abort(`subflow \"${ref}\" has a non-integer version pin (${String(config.version)}).`);\n }\n\n const resolved = await resolver!(ref, pinned);\n\n // A mismatch names BOTH versions. Reporting it as \"not found\" would send an\n // author looking for a workflow that is sitting right there — which is why\n // the resolver can say which of the two failures it hit.\n const child = isResolutionFailure(resolved)\n ? ctx.abort(\n resolved.reason === \"version-mismatch\"\n ? (resolved.message ??\n `subflow \"${ref}\" is pinned to version ${pinned}, but the host has ${resolved.available ?? \"a different version\"}.`)\n : (resolved.message ?? `subflow could not resolve workflow \"${ref}\"`),\n )\n : resolved;\n\n if (!child) ctx.abort(`subflow could not resolve workflow \"${ref}\"`);\n\n const mode = subflowMode(config);\n const streaming = mode === \"stream\" || mode === \"both\";\n\n const forward = (event: RunEvent) => {\n if (!streaming) return;\n // Surface the child's progress on the PARENT's feed as a log line against\n // this node. Re-emitting the child's raw events would collide with the\n // parent's own node ids — a child's \"node-status\" for its `output` node is\n // not a status for anything in the parent graph.\n const detail =\n event.type === \"node-status\"\n ? `${event.nodeId} ${event.status}`\n : event.type === \"run-end\"\n ? `finished (${event.ok ? \"ok\" : \"failed\"})`\n : event.type;\n ctx.emit({\n type: \"log\",\n nodeId: ctx.node.id,\n level: \"info\",\n message: `[${ref}] ${detail}`,\n });\n };\n\n const result = await runFlow(\n child!,\n // Inherit the parent's registry, then let the graph layer its own on top.\n // The inherited half is the fix; the layered half keeps a graph that\n // deliberately hands its child extra or different executors working.\n { ...(ctx.executors ?? {}), ...((config.executors as Record<string, unknown>) ?? {}) } as never,\n forward,\n {\n initialInputs: childInputs(config, child!, ctx.inputs as Record<string, unknown>),\n depth: depth + 1,\n // Push THIS node onto the identity path, so a node inside the child graph\n // cannot share an idempotency key with a same-named node in the parent —\n // or with the same child graph invoked from a different parent node.\n // Attempt and the first-attempt clock ride down unchanged: the child's\n // work happens inside this node's attempt.\n run: ctx.run?.descend(ctx.node.id),\n },\n );\n\n if (!result.ok) {\n ctx.abort(`subflow \"${ref}\" failed: ${result.error ?? \"unknown error\"}`);\n }\n\n // `stream` alone still emits a final value on `stream` so downstream nodes\n // have something to run on; `both` publishes on every declared port.\n if (mode === \"stream\") {\n return { __port: \"stream\", value: result.outputs };\n }\n if (mode === \"both\") {\n return result.outputs;\n }\n return { __port: \"out\", value: result.outputs };\n};\n","/**\n * `{{ }}` resolution — the TypeScript twin of `FancyFlow\\Nodes\\Support\\Expr`.\n *\n * ## Why this is opt-in and not wired into `runFlow`\n *\n * The PHP runtime resolves expressions inside its batteries-included executors.\n * The JS runtime never has: `runFlow` hands `node.data.config` to your executor\n * verbatim, so every host that uses `{{ }}` today already resolves it itself.\n * Turning resolution on inside `runFlow` would interpolate a second time over\n * values those hosts had already substituted — silently, and only for graphs\n * that happen to contain `{{` in their DATA.\n *\n * So this exports the semantics and changes no behaviour. Call it yourself:\n *\n * ```ts\n * const url = evaluateExpression(node.data.config.url, inputs);\n * ```\n *\n * ## The semantics are the PHP file's, deliberately\n *\n * This is not a general expression language and must not grow into one. It\n * resolves a dot-path against a context and nothing else — no arithmetic, no\n * comparisons, no calls. Hosts that want real expressions override the executor\n * (the PHP docblock points at symfony/expression-language for the same reason).\n *\n * Divergence here is a correctness bug rather than a style difference: the same\n * graph is authored once and may run on either runtime. `suites/shared/expr`\n * in `@particle-academy/fancy-conformance` is the fixture table both sides run,\n * so parity is a test result instead of a claim.\n */\n\n/** Anything a context or a resolved value can be. */\nexport type ExprValue = unknown;\n\n/** The context an expression resolves against — the executor's `inputs`. */\nexport type ExprContext = Record<string, ExprValue>;\n\n/**\n * `{{ … }}` is parsed by SCANNING, not by a regular expression.\n *\n * Two CodeQL `js/polynomial-redos` alerts (#2, #3) came out of the regex\n * version, and the second survived the obvious fix — which is the useful part.\n * Dropping the ambiguous `\\s*` around the capture killed one witness\n * (`'{{{{' + ' '.repeat(n)`) and CodeQL immediately produced another\n * (`'{{{{a'` repeated). That is not a pattern bug: a GLOBAL lazy scan for a\n * delimiter that never arrives is quadratic by construction — O(n) starts, each\n * scanning O(n) forward — and no amount of tuning the pattern removes it.\n *\n * `indexOf` has no backtracking at all. Each character is visited a bounded\n * number of times, so this is linear by construction rather than by careful\n * pattern-writing, and there is no next witness to find.\n *\n * The behaviour matches the PHP twin's regexes, and `shared/expr` is what holds\n * the two together.\n */\n\n/**\n * The inner text of a template that is EXACTLY one expression, else `null`.\n *\n * Starting with `{{` and ending with `}}` is not enough: the inner text may\n * contain neither `}}` nor `{{`. Without that check `{{ in.text }} --- {{\n * user.transcript }}` was ONE path, `in.text }} --- {{ user.transcript`, that\n * resolves to nothing, so the template returned null (fancy-flow-php#16). That\n * corner came from PHP's end-anchored pattern, whose lazy capture grew to reach\n * the end; it was documented here as deliberate and mirrored in every runtime,\n * so no parity table could see it. A template with several references now\n * interpolates each, and `{{a}}{{b}}` is two references.\n */\nfunction wholeExpression(trimmed: string): string | null {\n if (trimmed.length < 4) return null;\n if (!trimmed.startsWith(\"{{\") || !trimmed.endsWith(\"}}\")) return null;\n const inner = trimmed.slice(2, -2);\n if (inner.includes(\"}}\") || inner.includes(\"{{\")) return null;\n return inner;\n}\n\n/**\n * Replace every `{{ … }}` run, left to right, in a single pass.\n *\n * An unterminated `{{` is literal text — the same thing the regex did by simply\n * not matching, and the case an author hits constantly while typing.\n */\nfunction interpolate(template: string, resolve: (path: string) => string): string {\n let out = \"\";\n let i = 0;\n\n for (;;) {\n const open = template.indexOf(\"{{\", i);\n if (open === -1) return out + template.slice(i);\n\n const close = template.indexOf(\"}}\", open + 2);\n if (close === -1) return out + template.slice(i);\n\n out += template.slice(i, open) + resolve(template.slice(open + 2, close));\n i = close + 2;\n }\n}\n\n/**\n * Strings PHP's `Expr::truthy` treats as false.\n *\n * `\"0\"` and `\"false\"` are the ones that matter: a branch condition arriving as\n * text from a form or a JSON body would otherwise be truthy for every non-empty\n * string, and `\"false\"` taking the true branch is the kind of bug that looks\n * like the engine is broken.\n */\nconst FALSY_STRINGS = new Set([\"\", \"0\", \"false\", \"no\", \"off\", \"null\"]);\n\n/**\n * What a resolution attempt ANSWERS — did the path resolve, and to what.\n *\n * `resolvePath` cannot express this, and that is the defect it exists to fix:\n * it returns `null` both for \"this path does not exist\" and for \"this path\n * exists and holds null\". One value standing for two states.\n *\n * At the interpolation layer the collapse is worse, because `null` stringifies\n * to `\"\"`. A consumer put it exactly:\n *\n * > \"An unresolvable path yields `''`, so a wrong field is indistinguishable\n * > from an empty one at runtime.\"\n *\n * A misspelled field renders as an empty string, which looks precisely like a\n * field that is legitimately empty. The graph runs, the node succeeds, and the\n * output is quietly missing a value nobody is told about — worst on\n * LLM-authored graphs, where the field name was guessed in the first place.\n *\n * Same shape as the four `??` collapses fixed across all four runtimes on\n * 2026-08-26 (absent vs null), one layer up: **presence is the only correct\n * test, and a return value that cannot express presence cannot be tested for\n * it.** Hence a second return channel rather than a cleverer sentinel — every\n * sentinel is a legal value for somebody.\n */\nexport interface Resolution {\n /** Whether the path resolved at all. `false` means it does not exist. */\n resolved: boolean;\n /** The value, when `resolved`. `null` when not — do not read it blind. */\n value: ExprValue;\n}\n\n/** Thrown by the `\"throw\"` policy when a path does not resolve. */\nexport class UnresolvedPathError extends Error {\n constructor(readonly path: string) {\n super(\n `Expression path \"${path}\" did not resolve. ` +\n `Under the \"throw\" policy an unresolvable path is an error rather than an empty string.`,\n );\n this.name = \"UnresolvedPathError\";\n }\n}\n\n/**\n * What evaluation does with a path that does not resolve.\n *\n * - `\"empty\"` — today's behaviour, and the DEFAULT. Interpolates to `\"\"`; a\n * whole expression yields `null`. Unchanged so that widening this API breaks\n * nobody: 40 call sites across the runtimes assume it.\n * - `\"keep\"` — leave the `{{ … }}` text in place. The failure becomes VISIBLE\n * in the output without stopping the run, which is what you want for\n * human-reviewed content: a rendered `{{ in.recipient_naem }}` is self-\n * diagnosing in a way an absence never is.\n * - `\"throw\"` — refuse. For hosts that would rather fail a run than deliver a\n * silently incomplete result.\n *\n * Opt-in before default at the request of the consumer who reported it — the\n * host with the most LLM-authored graphs, and so both the biggest beneficiary\n * and the right place for it to break first if it is going to.\n */\nexport type UnresolvedPolicy = \"empty\" | \"keep\" | \"throw\";\n\n/** Options for {@link evaluateExpression} / {@link evaluateConfig}. */\nexport interface EvaluateOptions {\n /** What to do with a path that does not resolve. Default `\"empty\"`. */\n onUnresolved?: UnresolvedPolicy;\n}\n\n/**\n * Resolve a dot-path, reporting WHETHER it resolved.\n *\n * The same walk as `resolvePath` — deliberately, so the two can never disagree\n * about what resolves; `resolvePath` is defined in terms of this one below.\n *\n * A note on JS having two absent values: a key present with the value\n * `undefined` reports `resolved: false`, matching `resolvePath`'s long-standing\n * behaviour. It cannot arise from graph data (JSON has no `undefined`), and\n * changing it would make the two functions disagree for no reachable gain.\n */\nexport function tryResolvePath(path: string, context: ExprContext): Resolution {\n const unresolved: Resolution = { resolved: false, value: null };\n\n const trimmed = path.trim();\n if (trimmed === \"\") return unresolved;\n\n const segments = trimmed.split(\".\");\n let cursor: ExprValue;\n\n const head = segments[0];\n if (head === \"$json\" || head === \"$input\") {\n cursor = context !== null && typeof context === \"object\" && \"in\" in context ? context.in : context;\n segments.shift();\n } else {\n cursor = context;\n }\n\n for (const segment of segments) {\n if (cursor === null || cursor === undefined) return unresolved;\n if (typeof cursor !== \"object\") return unresolved;\n // Arrays are indexed by their numeric keys, matching PHP's list access.\n const next = (cursor as Record<string, ExprValue>)[segment];\n if (next === undefined) return unresolved;\n cursor = next;\n }\n\n return { resolved: true, value: cursor === undefined ? null : cursor };\n}\n\n/**\n * Resolve a dot-path against the context, honouring the `$json` / `$input`\n * alias.\n *\n * Both aliases point at the `in` port value when the context has one, and at\n * the whole context otherwise — the same fallback the PHP does, which is what\n * makes `{{ $json.x }}` work on a trigger node that has no upstream input.\n *\n * A path that does not resolve returns `null`, never `undefined`: PHP has one\n * absent value and JS has two, and letting the difference leak would make the\n * two runtimes disagree about `{{ missing }}` for no useful reason.\n */\nexport function resolvePath(path: string, context: ExprContext): ExprValue {\n // Defined in terms of `tryResolvePath` rather than repeating the walk. Two\n // copies of a traversal agree right up until someone edits one of them, and\n // nothing anywhere reports that -- the same reason the shared conformance\n // tables exist instead of hand-copied fixture rows.\n return tryResolvePath(path, context).value;\n}\n\n/**\n * Evaluate a template against a context.\n *\n * A string that is EXACTLY one expression returns the resolved value with its\n * type intact — `{{ $json.count }}` gives you a number, not `\"3\"`. Anything\n * else interpolates each run as text. That distinction is load-bearing: it is\n * what lets a config field carry either a value or a sentence.\n *\n * Non-string templates pass through untouched, so this is safe to map over a\n * whole config object.\n */\nexport function evaluateExpression(\n template: ExprValue,\n context: ExprContext,\n options: EvaluateOptions = {},\n): ExprValue {\n if (typeof template !== \"string\") return template;\n\n const policy = options.onUnresolved ?? \"empty\";\n\n const whole = wholeExpression(template.trim());\n if (whole !== null) {\n const r = tryResolvePath(whole, context);\n if (r.resolved) return r.value;\n\n // The whole-expression branch returns `null` under `\"empty\"`, not `\"\"` --\n // that is what it has always done, and the asymmetry is deliberate: this\n // branch preserves TYPE, so its absent value is the typed one.\n if (policy === \"throw\") throw new UnresolvedPathError(whole);\n return policy === \"keep\" ? template : null;\n }\n\n return interpolate(template, (path) => {\n const r = tryResolvePath(path, context);\n if (r.resolved) return stringify(r.value);\n if (policy === \"throw\") throw new UnresolvedPathError(path);\n return policy === \"keep\" ? `{{${path}}}` : \"\";\n });\n}\n\n/**\n * Truthiness for branch / switch decisions.\n *\n * Mirrors PHP's rules rather than JavaScript's, because the graph is authored\n * once and may run on either side. The two disagree in exactly the places a\n * workflow hits: `\"0\"` and `\"false\"` are truthy in JS and falsy here, and an\n * empty array is truthy in JS and falsy here.\n */\nexport function truthy(value: ExprValue): boolean {\n if (typeof value === \"boolean\") return value;\n if (value === null || value === undefined) return false;\n if (typeof value === \"string\") return !FALSY_STRINGS.has(value.trim().toLowerCase());\n if (Array.isArray(value)) return value.length > 0;\n if (typeof value === \"number\") return value !== 0;\n return Boolean(value);\n}\n\n/** Coerce a value to text the way interpolation does. */\nexport function text(value: ExprValue): string {\n return stringify(value);\n}\n\nfunction stringify(value: ExprValue): string {\n if (typeof value === \"string\") return value;\n if (typeof value === \"boolean\") return value ? \"true\" : \"false\";\n if (value === null || value === undefined) return \"\";\n if (typeof value === \"number\" || typeof value === \"bigint\") return String(value);\n try {\n return JSON.stringify(value) ?? \"\";\n } catch {\n return \"\";\n }\n}\n\n/**\n * Resolve every string in a config object, one level of nesting at a time.\n *\n * The convenience most hosts actually want, and the shape their hand-rolled\n * version usually takes. Opt-in like the rest of this module.\n */\nexport function evaluateConfig<T extends Record<string, ExprValue>>(\n config: T,\n context: ExprContext,\n options: EvaluateOptions = {},\n): T {\n const out: Record<string, ExprValue> = {};\n for (const [key, value] of Object.entries(config)) {\n out[key] = Array.isArray(value)\n ? value.map((v) => evaluateExpression(v, context, options))\n : value !== null && typeof value === \"object\"\n ? evaluateConfig(value as Record<string, ExprValue>, context, options)\n : evaluateExpression(value, context, options);\n }\n return out as T;\n}\n","import { evaluateExpression, truthy, text, tryResolvePath } from \"../expressions/expr\";\nimport type { NodeExecutor } from \"../types\";\n\n/**\n * Default executors for the four PURE-LOGIC builtins.\n *\n * ## Why these four ship one and `api_request` does not\n *\n * The kit's rule is that a kind ships schema + UI and the HOST wires the\n * executor, so it controls where memory, network and model calls actually go.\n * That reasoning is exactly right for `api_request`, `llm_call`, `memory_store`\n * — anything that touches the outside world, where a default would be a\n * decision made on the host's behalf about its own infrastructure.\n *\n * It is much weaker for `transform`, which does no I/O at all. `branch`,\n * `transform`, `merge` and `for_each` are pure functions of their inputs and\n * their config: there is exactly one correct answer and no infrastructure to\n * choose. Leaving them out meant every host reimplemented the same four, from\n * a schema, with no reference implementation to check against — and a consumer\n * asked whether that was deliberate (#13), which is a fair question to have to\n * ask.\n *\n * Host executors still take precedence: `pickExecutor` consults the host\n * registry first and falls back to the kind's own. Anyone who already wrote\n * these keeps theirs, unchanged.\n *\n * ## They implement the TypeScript schema, which is wider than the twin's\n *\n * `branch` and `transform` each have TWO authoring paths: a builder\n * (`conditions[]` / `fields[]`), which is what the editor produces by default,\n * and a raw-expression escape hatch (`condition` / `expression`). The Python\n * twin implements only the escape hatches. See the note in `docs/` — a graph\n * drawn the default way and run there routes or reshapes wrongly, silently.\n * These implement BOTH, so the TypeScript side is the complete one.\n */\n\ntype Config = Record<string, unknown>;\n\nfunction configOf(node: unknown): Config {\n return (((node as { data?: { config?: Config } })?.data?.config) ?? {}) as Config;\n}\n\n/** The expression context every one of these resolves against. */\nfunction contextOf(inputs: Record<string, unknown>): Record<string, unknown> {\n return inputs as Record<string, unknown>;\n}\n\n/** `{{ }}`-aware resolve. A non-string config value is already a value. */\nfunction resolve(value: unknown, inputs: Record<string, unknown>): unknown {\n if (typeof value !== \"string\") return value;\n return evaluateExpression(value, contextOf(inputs) as never);\n}\n\n/**\n * Warn when a routing decision was made on a path that DID NOT RESOLVE.\n *\n * `branch` asks `truthy()` of its resolved condition. An unresolvable path\n * yields `null`, `null` is falsy, and the run takes `false` — silently, and for\n * a reason that has nothing to do with the data. `switch_case` has the same\n * shape one step over: a `value` that does not resolve matches no case and\n * falls to `default`. From outside, both look exactly like a legitimate answer,\n * and half the graph then never runs on a run that reports success.\n *\n * Routing is deliberately UNCHANGED. Re-routing would silently change graphs\n * that have been running for months; the warning supplies the missing part,\n * which is the reason. A host that would rather fail can register its own\n * executor resolving with `evaluateExpression(…, { onUnresolved: \"throw\" })`.\n *\n * Only for a WHOLE `{{ path }}`. A condition mixing text with expressions is\n * being used as a string, and an unresolved fragment there is interpolation,\n * not routing. Absent is not null: a key holding `null` RESOLVED, and is silent.\n *\n * Ported from the PHP twin's `RoutingDiagnostics::warnIfUnresolved`, message and\n * detail verbatim — pinned by `flow/run-diagnostics` (fancy-flow#17). Found by\n * `flabs`: a triage graph whose urgency check named a field that did not\n * resolve routed every request, total payment failure included, as non-urgent.\n */\nfunction warnIfUnresolved(\n ctx: Parameters<NodeExecutor>[0],\n condition: unknown,\n tookPort: string,\n configKey = \"condition\",\n): void {\n if (typeof condition !== \"string\") return;\n\n const trimmed = condition.trim();\n if (trimmed.length < 4 || !trimmed.startsWith(\"{{\") || !trimmed.endsWith(\"}}\")) return;\n\n const path = trimmed.slice(2, -2).trim();\n\n // `{{ a }}{{ b }}` would otherwise read as one \"path\" spanning `}}{{` — a\n // template of two references rather than a missing field, and reporting it\n // as a missing field sends the reader somewhere useless.\n if (path === \"\" || path.includes(\"}}\")) return;\n\n if (tryResolvePath(path, ctx.inputs as never).resolved) return;\n\n const nodeId = ctx.node.id;\n ctx.emit({\n type: \"log\",\n nodeId,\n level: \"warn\",\n message:\n `Node ${nodeId} took the \"${tookPort}\" port because \\`${configKey}\\` resolved to NOTHING — ` +\n `the path ${path} names no field on this node's inputs. That is not the same as a false ` +\n `condition: the route was decided by an absent value rather than by the data.`,\n detail: { node: nodeId, configKey, path, tookPort },\n });\n}\n\n/**\n * One row of the `conditions` repeater.\n *\n * `left` is an expression; `right` is plain text in the schema but is resolved\n * too, because an author who types `{{ $json.threshold }}` there means it.\n */\nfunction conditionHolds(row: Config, inputs: Record<string, unknown>): boolean {\n const left = resolve(row.left, inputs);\n const right = resolve(row.right, inputs);\n const operator = typeof row.operator === \"string\" ? row.operator : \"eq\";\n\n const asText = (v: unknown) => text(v as never);\n const asNumber = (v: unknown) => {\n const n = typeof v === \"number\" ? v : Number(asText(v));\n return Number.isFinite(n) ? n : NaN;\n };\n // A number comparison against something unparseable is FALSE rather than a\n // throw: an author comparing a missing field to 10 wants the branch not to\n // take, not the run to die.\n const numeric = (fn: (a: number, b: number) => boolean) => {\n const a = asNumber(left);\n const b = asNumber(right);\n return Number.isFinite(a) && Number.isFinite(b) ? fn(a, b) : false;\n };\n const isEmpty = (v: unknown) =>\n v === null\n || v === undefined\n || v === \"\"\n || (Array.isArray(v) && v.length === 0)\n || (typeof v === \"object\" && !Array.isArray(v) && Object.keys(v as object).length === 0);\n\n switch (operator) {\n // Compared as TEXT, deliberately. `right` is a text field in the schema, so\n // `status == \"2\"` must match the number 2 an upstream node produced —\n // strict equality there would fail on a difference the author cannot see.\n case \"eq\": return asText(left) === asText(right);\n case \"neq\": return asText(left) !== asText(right);\n case \"contains\": return asText(left).includes(asText(right));\n case \"not_contains\": return !asText(left).includes(asText(right));\n case \"gt\": return numeric((a, b) => a > b);\n case \"gte\": return numeric((a, b) => a >= b);\n case \"lt\": return numeric((a, b) => a < b);\n case \"lte\": return numeric((a, b) => a <= b);\n case \"truthy\": return truthy(left as never);\n case \"falsy\": return !truthy(left as never);\n case \"empty\": return isEmpty(left);\n case \"not_empty\": return !isEmpty(left);\n default:\n // An operator the schema does not declare is a config error, not a\n // silent false — false would look exactly like a condition that did not\n // match, which is the answer an author would then try to debug.\n return false;\n }\n}\n\n/**\n * `branch` — two ports, exactly one taken.\n *\n * The raw `condition` WINS when set, because its own schema description says so\n * (\"Overrides the conditions above when set\"). The input passes through\n * unchanged down whichever side is taken and the other edge stays dead.\n */\nexport const branchExecutor: NodeExecutor = (ctx) => {\n const config = configOf(ctx.node);\n const inputs = ctx.inputs as Record<string, unknown>;\n\n let taken: boolean;\n\n const raw = config.condition;\n if (typeof raw === \"string\" && raw.trim() !== \"\") {\n taken = truthy(resolve(raw, inputs) as never);\n // A condition that did not RESOLVE is falsy, so the run takes `false`\n // silently and for the wrong reason. Routing is unchanged; the reason is\n // now visible.\n warnIfUnresolved(ctx, raw, taken ? \"true\" : \"false\");\n } else {\n const rows = Array.isArray(config.conditions) ? (config.conditions as Config[]) : [];\n // No conditions at all is FALSE, not true. An empty `all` is vacuously\n // true in logic, and that would send an unconfigured branch down the\n // success path — the one place a half-built graph should not go.\n if (rows.length === 0) {\n taken = false;\n } else {\n const results = rows.map((row) => conditionHolds(row, inputs));\n taken = config.match === \"any\" ? results.some(Boolean) : results.every(Boolean);\n }\n }\n\n return { __port: taken ? \"true\" : \"false\", value: ctx.inputs.in ?? ctx.inputs };\n};\n\n/**\n * `transform` — reshape in place. One `out` port, always active.\n *\n * `mode` decides which authoring path is read, defaulting to `fields` exactly\n * as the schema does.\n */\nexport const transformExecutor: NodeExecutor = (ctx) => {\n const config = configOf(ctx.node);\n const inputs = ctx.inputs as Record<string, unknown>;\n const passthrough = ctx.inputs.in ?? ctx.inputs;\n\n if (config.mode === \"expression\") {\n const expression = config.expression;\n if (typeof expression !== \"string\" || expression.trim() === \"\") return passthrough;\n return resolve(expression, inputs);\n }\n\n const rows = Array.isArray(config.fields) ? (config.fields as Config[]) : [];\n // Nothing configured passes the input through untouched rather than\n // returning `{}`. A half-built transform that silently empties the payload\n // breaks every node downstream of it with no clue where the data went.\n if (rows.length === 0) return passthrough;\n\n const out: Record<string, unknown> = {};\n let wrote = false;\n for (const row of rows) {\n const key = typeof row.key === \"string\" ? row.key.trim() : \"\";\n if (key === \"\") continue;\n out[key] = resolve(row.value, inputs);\n wrote = true;\n }\n return wrote ? out : passthrough;\n};\n\n/**\n * `merge` — several inputs, one value.\n *\n * `merge` combines into one object: a plain object is spread in by key,\n * anything else is keyed by its PORT id. `concat` flattens into one list.\n *\n * `null`/`undefined` inputs are skipped, and dead edges never reach the\n * executor at all — so a merge downstream of a branch receives only the side\n * that actually ran, which is what makes it a merge point rather than a join.\n */\nexport const mergeExecutor: NodeExecutor = (ctx) => {\n const entries = Object.entries(ctx.inputs as Record<string, unknown>);\n\n if (configOf(ctx.node).mode === \"concat\") {\n const out: unknown[] = [];\n for (const [, value] of entries) {\n if (value === null || value === undefined) continue;\n if (Array.isArray(value)) out.push(...value);\n else out.push(value);\n }\n return out;\n }\n\n const merged: Record<string, unknown> = {};\n for (const [port, value] of entries) {\n if (value === null || value === undefined) continue;\n if (typeof value === \"object\" && !Array.isArray(value)) Object.assign(merged, value);\n else merged[port] = value;\n }\n return merged;\n};\n\n/**\n * `for_each` — fan-out as DATA, not as jobs.\n *\n * Publishes the resolved collection and its size. It does NOT spawn one job per\n * item, and that is deliberate rather than unfinished: on a durable run a\n * `for_each` over 10,000 rows is one node, one claim, one checkpoint — not\n * 10,000. A host that wants true per-item iteration overrides this, which is\n * exactly what the executor seam is for.\n *\n * Matches the Python twin, including `concurrency` being carried for a host\n * that does iterate rather than acted on here.\n */\nexport const forEachExecutor: NodeExecutor = (ctx) => {\n const source = resolve(configOf(ctx.node).source, ctx.inputs as Record<string, unknown>);\n\n let items: unknown[];\n if (Array.isArray(source)) items = source;\n else if (source === null || source === undefined) items = [];\n else if (typeof source === \"object\") items = Object.values(source as object);\n else items = [source];\n\n return { items, count: items.length };\n};\n\n/*\n * ---------------------------------------------------------------------------\n * The DEPS-FREE remainder.\n *\n * The four above shipped because \"the host decides where I/O goes\" does not\n * apply to a pure function. The same argument covers five more, and leaving\n * them out was omission rather than a decision: `manual_trigger`, `output`,\n * `log`, `variable` and `switch_case` need no notifier, no store, no client and\n * no network. The PHP and Python twins ship all five, and they are four lines\n * each there.\n *\n * The cost of the gap was measured rather than guessed. A connector lab running\n * one WorkflowSchema on three engines had to hand-write `manual_trigger` and\n * `output` for its Node lane while PHP and Python got them from the engine, and\n * left a comment above them saying so — because a future parity failure on\n * those two kinds would otherwise be misattributed to this package. Every host\n * writes the same one-liners, slightly differently, and a parity suite cannot\n * tell \"the runtimes disagree\" from \"the two hosts disagree\".\n *\n * Ported from the PHP twin line for line, because parity is the contract: same\n * WorkflowSchema in, same `RunResult.outputs` out. A \"better\" implementation\n * here would be a divergence.\n *\n * `wait`, `user_input` and `human_approval` stay out. They look pure and are\n * not: each halts a run, and how a run halts is the host's decision (a durable\n * pause, a sleep, a queue re-drive) rather than a default anyone can pick.\n * ---------------------------------------------------------------------------\n */\n\n/**\n * `manual_trigger` — the entry point, publishing whatever started the run.\n *\n * Returns `ctx.inputs` whole. On a trigger those inputs ARE the run's initial\n * inputs, so this is what makes `{{ trigger.field }}` resolve downstream.\n */\nexport const manualTriggerExecutor: NodeExecutor = (ctx) => ctx.inputs;\n\n/**\n * `output` — the terminal node, publishing what reached it.\n *\n * `in ?? inputs`, not `inputs`: a node wired through its declared `in` port\n * publishes that port's value UNWRAPPED, which is what makes the terminal entry\n * in `RunResult.outputs` the plain result rather than a port map. Falling back\n * to the whole input map keeps a node with no inbound edge meaningful.\n */\nexport const outputExecutor: NodeExecutor = (ctx) => {\n const inputs = ctx.inputs as Record<string, unknown>;\n\n return inputs.in ?? inputs;\n};\n\n/**\n * `variable` — resolve an expression and publish it.\n *\n * The value is returned bare, not under a key. `{{ }}`-resolution is the whole\n * behaviour; a non-string config value is already a value and passes through.\n */\nexport const variableExecutor: NodeExecutor = (ctx) =>\n resolve(configOf(ctx.node).value, ctx.inputs as Record<string, unknown>);\n\n/**\n * `log` — emit a log event, and say what was logged.\n *\n * The message is emitted through `ctx.emit`, never written to a console: where\n * a host's logs GO is a host decision, and a `console.log` here would be this\n * package choosing one. The return value records what was emitted so a\n * downstream node can read it, matching the twins.\n */\nexport const logExecutor: NodeExecutor = (ctx) => {\n const config = configOf(ctx.node);\n const inputs = ctx.inputs as Record<string, unknown>;\n\n const level = (config.level as \"info\" | \"warn\" | \"error\") ?? \"info\";\n const message = text(resolve(config.message ?? \"\", inputs) as never);\n\n ctx.emit({ type: \"log\", nodeId: ctx.node.id, level, message });\n\n return { logged: message, level };\n};\n\n/**\n * `switch_case` — route to the port its resolved value names.\n *\n * An unmatched value falls to `default`, which is the same silent mis-route\n * `branch` has one step over: an expression that does not resolve becomes `\"\"`,\n * matches no case, and takes `default` — indistinguishable from a value that\n * genuinely matched nothing.\n *\n * So it warns when the value did not RESOLVE, and only then. This used to warn\n * on ANY unmatched value that came from an expression, including one that\n * resolved to a real value no case names — which is what `default` is FOR, and\n * a warning on a node's intended behaviour is noise that trains people to\n * ignore the one that matters. The twin warns on the unresolved path alone.\n */\nexport const switchCaseExecutor: NodeExecutor = (ctx) => {\n const config = configOf(ctx.node);\n const inputs = ctx.inputs as Record<string, unknown>;\n\n const expression = config.value;\n const value = text(resolve(expression, inputs) as never);\n const cases = (config.cases ?? {}) as Record<string, unknown>;\n\n const matched = Object.prototype.hasOwnProperty.call(cases, value);\n const port = matched ? String(cases[value]) : \"default\";\n\n warnIfUnresolved(ctx, expression, port, \"value\");\n\n return { __port: port, value: inputs.in ?? inputs };\n};\n","import type { NodeExecutor } from \"../types\";\nimport type { TranscriptWaitResult } from \"../runtime/terminal-transcript\";\n\n/**\n * The three terminal primitives.\n *\n * They are core rather than marketplace for the same reason `subflow` is: they\n * introduce no third-party dependency. The PTY lives behind\n * `registerTerminalHost`, so this file imports nothing that a browser build\n * would choke on.\n *\n * ## Why three, and not one\n *\n * A terminal is two different things depending on what is running in it, and\n * one node cannot serve both:\n *\n * - **A shell** answers a question and finishes, so the useful unit is\n * \"run this, tell me what it said and whether it worked\" — `terminal_run`.\n * - **A TUI** (Claude Code, Codex, a REPL, an installer asking a question)\n * never finishes. There is no exit code to wait for and no prompt to return\n * to; there is only text going in and text coming out. That is\n * `terminal_send` + `terminal_await`, and it is the pair that makes an agent\n * TUI drivable at all.\n *\n * Collapsing them into one node would mean guessing which mode the author\n * meant, and guessing wrong on a TUI means hanging until a timeout.\n */\n\nconst DEFAULT_TIMEOUT_MS = 120_000;\n\n/** Enter, in a PTY, is a carriage return. */\nconst ENTER = \"\\r\";\n\nfunction configOf(node: unknown): Record<string, unknown> {\n return (((node as { data?: { config?: Record<string, unknown> } })?.data?.config) ?? {}) as Record<\n string,\n unknown\n >;\n}\n\nfunction text(config: Record<string, unknown>, key: string): string {\n const value = config[key];\n return typeof value === \"string\" ? value : \"\";\n}\n\nfunction millis(config: Record<string, unknown>, key: string, fallback: number): number {\n const value = Number(config[key]);\n return Number.isFinite(value) && value >= 0 ? value : fallback;\n}\n\n/**\n * The marker `terminal_run` appends so it can tell when a command finished and\n * what it returned.\n *\n * A persistent shell has no completion channel — output just stops arriving,\n * and \"stopped arriving\" is indistinguishable from \"still thinking\". So the\n * command is followed by an echo of its own exit status, and THAT is what the\n * node waits for.\n *\n * The nonce matters: without it, a command whose own output happened to contain\n * the marker would end the wait early, and a run that left a stale marker in\n * the buffer would satisfy the NEXT command instantly. One per execution.\n */\nexport function exitMarker(nonce: string): { token: string; pattern: RegExp } {\n const token = `__fancy_flow_exit_${nonce}__`;\n return {\n token,\n // The expanded status is required to be digits. The shell ECHOES the typed\n // command back first, and that echo contains the marker with `$?`\n // unexpanded — so requiring digits is what stops the node matching its own\n // command line and reporting success before anything has run.\n pattern: new RegExp(`${token}:(\\\\d+)`),\n };\n}\n\nlet counter = 0;\n\nfunction newNonce(): string {\n counter += 1;\n return `${Date.now().toString(36)}${counter.toString(36)}${Math.random().toString(36).slice(2, 8)}`;\n}\n\n/**\n * Drop every line carrying the marker.\n *\n * Two of them exist in a normal run — the shell's echo of the command that was\n * typed, and the marker line itself — and neither is output the author asked\n * for. Filtering by line rather than slicing by index survives an echo that is\n * wrapped, disabled, or reordered, none of which is under our control.\n */\nfunction withoutMarker(output: string, token: string): string {\n return output\n .split(\"\\n\")\n .filter((line) => !line.includes(token))\n .join(\"\\n\")\n .trim();\n}\n\ntype Ctx = Parameters<NodeExecutor>[0];\n\n/**\n * Abort, in a shape the compiler believes.\n *\n * `ctx.abort` is declared `=> never`, but TypeScript only narrows control flow\n * through a never-returning call when the callee is a plain function name — not\n * a mutable property on a parameter. So calling `ctx.abort` directly left every\n * later line thinking the run might have continued, and the code had to be\n * written as if a value could still be `undefined` after it had been rejected.\n *\n * That is not a cosmetic complaint: the workaround is a non-null assertion, and\n * a `!` on a line that \"cannot be reached\" is indistinguishable from a `!` on a\n * line that can.\n */\nfunction fail(ctx: Ctx, message: string): never {\n ctx.abort(message);\n // Unreachable — `abort` throws. Present so this function's own return type is\n // honest without depending on the narrowing that is missing above.\n throw new Error(message);\n}\n\n/** Shared: resolve the lane's terminal, or abort naming the real problem. */\nfunction requireTerminal(ctx: Ctx): NonNullable<Ctx[\"terminal\"]> {\n if (!ctx.terminal) {\n fail(\n ctx,\n `\"${String(ctx.node.data?.label ?? ctx.node.id)}\" is a terminal node but is not inside a terminal lane. `\n + \"Drag it into one — a terminal node outside a lane has no session to talk to, and opening a private \"\n + \"shell for it would defeat the point of the lane.\",\n );\n }\n return ctx.terminal;\n}\n\n/**\n * The pattern a `terminal_await` waits for.\n *\n * Plain text is the default and is ESCAPED, so a prompt like `? (y/n)` matches\n * itself instead of being read as a regex and either failing to compile or —\n * worse — matching something else entirely while looking like it works.\n *\n * `g` and `y` are stripped from author-supplied flags. Both make a regex carry\n * `lastIndex` between calls, so the same pattern would resume part-way through\n * a buffer it had never read, and a wait would miss a match sitting in plain\n * view. The transcript resets `lastIndex` too; this is the belt to that\n * braces, because the cost of being wrong is a hang.\n */\nfunction compilePattern(ctx: Ctx, raw: string, config: Record<string, unknown>): RegExp {\n const flags = typeof config.flags === \"string\" ? config.flags.replace(/[gy]/g, \"\") : \"\";\n try {\n return config.mode === \"regex\"\n ? new RegExp(raw, flags)\n : new RegExp(raw.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"), flags);\n } catch (e) {\n // Named as an INVALID PATTERN. A bad regex thrown raw reads as a crash in\n // the engine rather than as a typo in one node's config.\n return fail(ctx, `terminal_await has an invalid regex: ${e instanceof Error ? e.message : String(e)}`);\n }\n}\n\n/**\n * `terminal_run` — send a command, wait for it to finish, report its exit code.\n *\n * Shell-only, and it says so on the node: a TUI never returns to a prompt, so\n * there is nothing for the marker to ride on. Use send + await there.\n */\nexport const terminalRunExecutor: NodeExecutor = async (ctx) => {\n const config = configOf(ctx.node);\n const command = text(config, \"command\").trim();\n if (!command) fail(ctx, \"terminal_run has no command configured\");\n\n const terminal = requireTerminal(ctx);\n const session = await terminal.session();\n const transcript = await terminal.transcript();\n\n const { token, pattern } = exitMarker(newNonce());\n const timeoutMs = millis(config, \"timeoutMs\", DEFAULT_TIMEOUT_MS);\n\n // Everything the shell said before this command is somebody else's output.\n // Carrying it into this node's result would attribute the previous command's\n // text — and, worse, let a marker-shaped string from earlier satisfy the wait.\n transcript.clear();\n\n await session.write(`${command}; printf '${token}:%s\\\\n' \"$?\"${ENTER}`);\n\n const result = await transcript.waitFor(pattern, { timeoutMs, exited: session.exited });\n\n if (result.status === \"exited\") {\n fail(\n ctx,\n `The terminal exited (code ${result.exitCode}${result.signal ? `, signal ${result.signal}` : \"\"}) while `\n + `running \"${command}\". The lane's session is gone, so every later node in this lane would fail too.`,\n );\n }\n\n if (result.status === \"timeout\") {\n fail(\n ctx,\n `\"${command}\" did not finish within ${timeoutMs}ms. Raise the node's timeout if it is genuinely slow — `\n + \"but a command that waits for input never finishes at all, and needs terminal_send + terminal_await.\",\n );\n }\n\n const exitCode = Number(result.match[1]);\n const output = withoutMarker(result.text, token);\n\n const failOnNonZero = config.failOnNonZero !== false;\n if (failOnNonZero && exitCode !== 0) {\n // Aborting is the default because the alternative is the failure this whole\n // estate keeps finding: a step that failed, a run that reports success, and\n // nothing anywhere that says the two disagree.\n ctx.abort(`\"${command}\" exited ${exitCode}.\\n${output}`);\n }\n\n return { output, exitCode, command };\n};\n\n/**\n * `terminal_send` — type at the process and move on.\n *\n * The node that makes a TUI usable. It does NOT wait, deliberately: what\n * counts as an answer is the author's decision, not ours, and pairing every\n * send with a hardcoded wait would make the common case (send, then await a\n * specific prompt) impossible to express.\n */\nexport const terminalSendExecutor: NodeExecutor = async (ctx) => {\n const config = configOf(ctx.node);\n const terminal = requireTerminal(ctx);\n const session = await terminal.session();\n\n const body = text(config, \"text\");\n // `submit !== false` — a send that does not press Enter leaves the text\n // sitting on the process's input line, which looks exactly like the process\n // ignoring it.\n const submit = config.submit !== false;\n\n if (config.clearFirst === true) {\n (await terminal.transcript()).clear();\n }\n\n await session.write(submit ? `${body}${ENTER}` : body);\n\n return { sent: body, submitted: submit };\n};\n\n/**\n * `terminal_await` — wait for the process to say something.\n *\n * The other half of driving a TUI. Without it a graph can type at Claude Code\n * and never learn that it has answered, so every downstream node runs against\n * whatever was on screen when the run started.\n *\n * Three ways it can end and all three are reported distinctly, because\n * collapsing them is how a wrong diagnosis gets shipped: a match, a timeout,\n * and the process EXITING — which without its own branch reads as \"timed out\",\n * sending whoever debugs it to lengthen a timeout on a process that is not\n * running.\n */\nexport const terminalAwaitExecutor: NodeExecutor = async (ctx) => {\n const config = configOf(ctx.node);\n const terminal = requireTerminal(ctx);\n const session = await terminal.session();\n const transcript = await terminal.transcript();\n\n const raw = text(config, \"pattern\").trim();\n if (!raw) fail(ctx, \"terminal_await has no pattern configured — there is nothing for it to wait for\");\n\n const pattern = compilePattern(ctx, raw, config);\n\n const timeoutMs = millis(config, \"timeoutMs\", DEFAULT_TIMEOUT_MS);\n const result: TranscriptWaitResult = await transcript.waitFor(pattern, {\n timeoutMs,\n exited: session.exited,\n });\n\n if (result.status === \"exited\") {\n fail(\n ctx,\n `The terminal exited (code ${result.exitCode}${result.signal ? `, signal ${result.signal}` : \"\"}) while `\n + `waiting for ${JSON.stringify(raw)}. It never appeared, and the lane's session is gone.`,\n );\n }\n\n if (result.status === \"timeout\") {\n // The default is to FAIL. An await that shrugs after a timeout lets the\n // next node type at a process that never became ready, and the run reports\n // success — so continuing has to be something the author asked for.\n if (config.onTimeout === \"continue\") {\n ctx.emit({\n type: \"log\",\n nodeId: ctx.node.id,\n level: \"warn\",\n message: `terminal_await: ${JSON.stringify(raw)} did not appear within ${timeoutMs}ms; continuing as configured.`,\n });\n return { matched: false, output: result.text, groups: [] };\n }\n\n fail(\n ctx,\n `${JSON.stringify(raw)} did not appear within ${timeoutMs}ms. Last output:\\n${result.text.slice(-2000)}`,\n );\n }\n\n return {\n matched: true,\n output: result.text,\n matchedText: result.match[0],\n // Capture groups are the reason to use regex mode at all — a prompt that\n // reports a session id or a file path is only useful if the value comes out.\n groups: result.match.slice(1),\n };\n};\n","import { registerBuiltinKindInternal } from \"./registry\";\nimport { humanFieldType, type HumanFieldType } from \"../components/FlowEditor/human-fields\";\nimport { llmRouterExecutor } from \"./llm-router\";\nimport { subflowExecutor, subflowPorts, DEFAULT_MAX_DEPTH } from \"./subflow\";\nimport {\n branchExecutor,\n forEachExecutor,\n logExecutor,\n manualTriggerExecutor,\n mergeExecutor,\n outputExecutor,\n switchCaseExecutor,\n transformExecutor,\n variableExecutor,\n} from \"./logic\";\nimport { terminalAwaitExecutor, terminalRunExecutor, terminalSendExecutor } from \"./terminal-nodes\";\nimport type { PortDescriptor } from \"../types\";\nimport type { ConfigField, NodeKindDefinition } from \"./types\";\n\n/**\n * Built-in agentic node kit — schema + UI for every kind, and an executor for\n * the ones that need nothing from the host.\n *\n * **MOST kinds ship no executor, not all of them.** This comment used to say\n * \"every kind ships with schema + UI but NO executor\", and that was false for\n * nine of the thirty-one — including `branch` and `transform`, which are\n * exactly the ones a host is most likely to hand-write after reading it. A\n * wrong comment on a library's front door is worse than no comment: it is\n * confidently actionable, and the action it prompts is wasted work.\n *\n * The fourteen that DO carry one are the ones needing nothing from the host:\n * `subflow`, `branch`, `for_each`, `merge`, `transform`, `llm_router`,\n * `terminal_run`, `terminal_send`, `terminal_await`, and — added once the\n * omission was noticed — `manual_trigger`, `output`, `log`, `variable` and\n * `switch_case`.\n *\n * The rest are left to the host because they need a decision only the host can\n * make: where memory, data, network and AI calls actually go. That is a choice\n * this runtime makes for being a BROWSER library rather than a property of the\n * contract — the PHP and Python twins ship ~25 and take those decisions by\n * injection instead (`ExecutorDeps` carries the notifier, store, llm, http).\n *\n * `wait`, `user_input` and `human_approval` stay host-wired even though they\n * look pure. Each HALTS a run, and how a run halts — a durable pause, a sleep,\n * a queue re-drive — is the host's architecture, not a default anyone can pick\n * on its behalf.\n */\n\n/**\n * What each `user_input` control actually resolves to, in the vocabulary\n * `OutputField.type` uses.\n *\n * Date / time controls are strings deliberately — the form resolves the input's\n * `value`, which is an ISO-ish string, not a `Date`. Claiming otherwise here\n * would make the picker lie in the other direction.\n */\nconst HUMAN_FIELD_OUTPUT_TYPE: Record<HumanFieldType, \"string\" | \"number\" | \"boolean\"> = {\n text: \"string\",\n textarea: \"string\",\n select: \"string\",\n date: \"string\",\n datetime: \"string\",\n time: \"string\",\n email: \"string\",\n url: \"string\",\n tel: \"string\",\n password: \"string\",\n number: \"number\",\n switch: \"boolean\",\n};\n\n/**\n * Ports for `switch_case`, derived from its `cases` map (match value → port).\n *\n * Several match values may route to the same port, so ports are de-duplicated\n * and labelled with every value that reaches them (\"a|c\"). `default` is always\n * present — unmatched input has to land somewhere.\n */\nfunction casePorts(cases: unknown): PortDescriptor[] {\n const byPort = new Map<string, string[]>();\n if (cases && typeof cases === \"object\" && !Array.isArray(cases)) {\n for (const [match, port] of Object.entries(cases as Record<string, unknown>)) {\n if (typeof port !== \"string\" || port === \"\" || port === \"default\") continue;\n const matches = byPort.get(port) ?? [];\n matches.push(match);\n byPort.set(port, matches);\n }\n }\n const ports: PortDescriptor[] = [...byPort].map(([id, matches]) => ({\n id,\n label: matches.join(\"|\"),\n }));\n return [...ports, { id: \"default\", label: \"default\" }];\n}\n\n/**\n * Ports for `llm_branch`, derived from its `routes` list. Blank and duplicate\n * port names are dropped so a half-typed route can't collide with a real one.\n */\nfunction routePorts(routes: unknown, fallback?: unknown): PortDescriptor[] {\n const ports: PortDescriptor[] = [];\n const seen = new Set<string>();\n if (Array.isArray(routes)) {\n for (const route of routes) {\n const id = (route as any)?.port;\n if (typeof id !== \"string\" || id.trim() === \"\" || seen.has(id)) continue;\n seen.add(id);\n ports.push({ id, label: id });\n }\n }\n if (fallback !== false && !seen.has(\"fallback\")) {\n ports.push({ id: \"fallback\", label: \"fallback\" });\n }\n if (ports.length === 0) ports.push({ id: \"out\" });\n return ports;\n}\n\nconst HTTP_METHODS: ConfigField[] = [\n { type: \"select\", key: \"method\", label: \"Method\", options: [\n { value: \"GET\", label: \"GET\" },\n { value: \"POST\", label: \"POST\" },\n { value: \"PUT\", label: \"PUT\" },\n { value: \"PATCH\", label: \"PATCH\" },\n { value: \"DELETE\", label: \"DELETE\" },\n ], default: \"GET\", required: true },\n];\n\nconst KINDS: NodeKindDefinition[] = [\n // ───────────── Triggers ─────────────\n {\n name: \"@particle-academy/manual_trigger\",\n executor: manualTriggerExecutor,\n // Returns the raw inputs MAP, not the `in` port -- flat at an entry\n // point, port-keyed the moment the node has an inbound edge.\n emits: \"input-map-merged\",\n aliases: [\"manual_trigger\", \"@fancy/manual_trigger\"],\n category: \"trigger\",\n label: \"Manual\",\n description: \"Entry point fired when the user clicks Run.\",\n icon: \"⚡\",\n inputs: [],\n outputs: [{ id: \"out\" }],\n },\n {\n name: \"@particle-academy/webhook_trigger\",\n aliases: [\"webhook_trigger\", \"@fancy/webhook_trigger\"],\n category: \"trigger\",\n label: \"Webhook\",\n description: \"Triggered by an inbound HTTP request to a host-provided URL.\",\n icon: \"📡\",\n inputs: [],\n outputs: [{ id: \"out\", label: \"payload\" }],\n configSchema: [\n { type: \"text\", key: \"path\", label: \"Path\", placeholder: \"/hooks/my-flow\", required: true },\n { type: \"select\", key: \"method\", label: \"Method\", options: [\n { value: \"POST\", label: \"POST\" }, { value: \"GET\", label: \"GET\" },\n ], default: \"POST\" },\n { type: \"credential\", key: \"secret\", label: \"Verifying secret\", credentialType: \"webhook_secret\" },\n ],\n },\n {\n name: \"@particle-academy/schedule_trigger\",\n outputShape: [\n { path: \"cron\", type: \"string\" as const, description: \"The cron expression that fired.\" },\n { path: \"timezone\", type: \"string\" as const, description: \"The timezone it was evaluated in.\" },\n ],\n // Merges $ctx->inputs ITSELF beside cron/timezone -- the MAP, whose\n // shape depends on position, not each port's payload the way `merge` does.\n emits: \"input-map-merged\",\n aliases: [\"schedule_trigger\", \"@fancy/schedule_trigger\"],\n category: \"trigger\",\n label: \"Schedule\",\n description: \"Fires on a cron schedule (host-implemented).\",\n icon: \"⏱\",\n inputs: [],\n outputs: [{ id: \"out\" }],\n configSchema: [\n { type: \"text\", key: \"cron\", label: \"Cron\", placeholder: \"*/5 * * * *\", required: true,\n description: \"Standard 5-field cron expression.\" },\n { type: \"text\", key: \"timezone\", label: \"Timezone\", placeholder: \"UTC\", default: \"UTC\" },\n ],\n },\n {\n name: \"@particle-academy/user_input\",\n // The keys an author declared on THIS node — the case a static list cannot\n // express, and the one issue #5 named.\n //\n // The TYPE comes from the same normalizer the form renders with, so the\n // variable picker agrees with what the run actually resolves. It used to say\n // `string` for every field, which was wrong the moment a field was a number\n // or a switch — the picker told an author `{{ $json.age }}` was text while\n // the form handed the next node a number.\n outputShape: (config: { fields?: Array<{ key?: string; label?: string; type?: unknown }> }) =>\n (config.fields ?? [])\n .filter((f) => typeof f.key === \"string\" && f.key !== \"\")\n .map((f) => ({\n path: f.key as string,\n type: HUMAN_FIELD_OUTPUT_TYPE[humanFieldType(f.type)],\n description: f.label,\n })),\n aliases: [\"user_input\", \"@fancy/user_input\"],\n pausesForHuman: \"input\",\n category: \"human\",\n label: \"User Input\",\n description: \"Pause the flow until the user submits the configured form.\",\n icon: \"✎\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"out\", label: \"values\" }],\n configSchema: [\n { type: \"text\", key: \"title\", label: \"Form title\", default: \"Need your input\" },\n {\n type: \"repeater\",\n key: \"fields\",\n label: \"Fields\",\n description: \"The form the run pauses on.\",\n titleKey: \"label\",\n addLabel: \"Add field\",\n minItems: 1,\n fields: [\n { type: \"text\", key: \"key\", label: \"Key\", required: true, placeholder: \"answer\" },\n { type: \"text\", key: \"label\", label: \"Label\", required: true, placeholder: \"Your answer\" },\n {\n type: \"select\", key: \"type\", label: \"Type\", default: \"text\",\n // Every control `HumanPrompt` can render. A type the form supports\n // but the panel cannot select is reachable only by hand-editing the\n // workflow JSON — which is the audience this panel exists for.\n options: [\n { value: \"text\", label: \"Text\" },\n { value: \"textarea\", label: \"Long text\" },\n { value: \"number\", label: \"Number\" },\n { value: \"select\", label: \"Select\" },\n { value: \"switch\", label: \"Switch (yes / no)\" },\n { value: \"date\", label: \"Date\" },\n { value: \"datetime\", label: \"Date + time\" },\n { value: \"time\", label: \"Time\" },\n { value: \"email\", label: \"Email\" },\n { value: \"url\", label: \"URL\" },\n { value: \"tel\", label: \"Phone\" },\n { value: \"password\", label: \"Password\" },\n ],\n },\n {\n // Without this a panel-authored select had nothing to choose from,\n // so it rendered an empty dropdown — the type was declarable and\n // unusable in the same breath.\n type: \"keyvalue\",\n key: \"options\",\n label: \"Choices\",\n description: \"Select fields only. Left is the value the flow receives, right is what the person sees.\",\n keyLabel: \"Value\",\n valueLabel: \"Label\",\n keyPlaceholder: \"small\",\n valuePlaceholder: \"Small\",\n addLabel: \"Add choice\",\n },\n { type: \"switch\", key: \"required\", label: \"Required\", default: false },\n ],\n default: [{ key: \"answer\", label: \"Your answer\", type: \"textarea\", required: true }],\n },\n ],\n },\n\n {\n name: \"@particle-academy/rich_user_input\",\n aliases: [\"rich_user_input\", \"@fancy/rich_user_input\"],\n pausesForHuman: \"input\",\n category: \"human\",\n label: \"Rich User Input\",\n description: \"Pause the flow on a fully authored page — content, required reading, multi-section forms.\",\n icon: \"▤\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"out\", label: \"values\" }],\n configSchema: [\n { type: \"text\", key: \"title\", label: \"Step title\", default: \"Please review\" },\n {\n type: \"document\",\n key: \"document\",\n label: \"Page content\",\n documentType: \"stages\",\n description: \"Authored with the host's document editor (fancy-cms Stages).\",\n },\n { type: \"switch\", key: \"requireConfirm\", label: \"Require explicit confirmation\", default: true },\n { type: \"text\", key: \"submitLabel\", label: \"Submit button\", default: \"Continue\" },\n ],\n },\n\n {\n name: \"@particle-academy/subflow\",\n aliases: [\"subflow\", \"@fancy/subflow\"],\n category: \"logic\",\n label: \"SubFlow\",\n description: \"Run another workflow and bring its result — or its live progress — back into this one.\",\n icon: \"⧉\",\n inputs: [{ id: \"in\" }],\n // The stream port only exists when something actually streams.\n outputs: (config: any) => subflowPorts(config ?? {}),\n // Core, not marketplace: it runs a child graph through this same engine and\n // needs nothing from outside except where workflows live.\n executor: subflowExecutor,\n configSchema: [\n { type: \"text\", key: \"workflow\", label: \"Workflow\", required: true,\n placeholder: \"onboarding-v2\",\n description: \"Reference resolved by the host's registerWorkflowResolver().\" },\n { type: \"number\", key: \"version\", label: \"Pin to version\",\n description: \"Optional. Leave blank to always run the child's current version. Pinning fails the run loudly if the child has moved on — without it, someone edits the child and this flow silently runs different logic.\" },\n {\n type: \"select\", key: \"mode\", label: \"Return\", default: \"output\",\n options: [\n { value: \"output\", label: \"Output when it finishes\" },\n { value: \"stream\", label: \"Stream progress as it runs\" },\n { value: \"both\", label: \"Both — stream, then output\" },\n ],\n description: \"Streaming adds a second port so a parent can show progress instead of a spinner.\",\n },\n { type: \"keyvalue\", key: \"inputs\", label: \"Input mapping\",\n description: \"Values handed to the child's entry points. Omit to pass this node's inputs straight through.\",\n keyLabel: \"Name\", valueLabel: \"Value\", addLabel: \"Add input\" },\n { type: \"number\", key: \"maxDepth\", label: \"Max nesting depth\", default: DEFAULT_MAX_DEPTH, min: 1, max: 32,\n description: \"Guards against a workflow referencing itself.\" },\n ],\n },\n\n // ───────────── Logic ─────────────\n {\n name: \"@particle-academy/branch\",\n // returns its input on the chosen port\n emits: \"input\",\n aliases: [\"branch\", \"@fancy/branch\"],\n // Pure logic: no I/O to choose, so a default is safe. A host\n // executor still wins -- pickExecutor consults the registry first.\n executor: branchExecutor,\n category: \"logic\",\n label: \"Branch\",\n description: \"Multi-way branch on a condition or value.\",\n icon: \"◇\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"true\", label: \"true\" }, { id: \"false\", label: \"false\" }],\n configSchema: [\n {\n type: \"select\", key: \"match\", label: \"Match\", default: \"all\",\n options: [\n { value: \"all\", label: \"All conditions (AND)\" },\n { value: \"any\", label: \"Any condition (OR)\" },\n ],\n },\n {\n type: \"repeater\",\n key: \"conditions\",\n label: \"Conditions\",\n description: \"Routes to `true` when these match, otherwise `false`.\",\n titleKey: \"left\",\n addLabel: \"Add condition\",\n minItems: 1,\n fields: [\n { type: \"expression\", key: \"left\", label: \"Value\", example: \"{{ $json.status }}\", required: true },\n {\n type: \"select\", key: \"operator\", label: \"Is\", default: \"eq\",\n options: [\n { value: \"eq\", label: \"equal to\" },\n { value: \"neq\", label: \"not equal to\" },\n { value: \"contains\", label: \"contains\" },\n { value: \"not_contains\", label: \"does not contain\" },\n { value: \"gt\", label: \"greater than\" },\n { value: \"gte\", label: \"greater than or equal to\" },\n { value: \"lt\", label: \"less than\" },\n { value: \"lte\", label: \"less than or equal to\" },\n { value: \"truthy\", label: \"true\" },\n { value: \"falsy\", label: \"false\" },\n { value: \"empty\", label: \"empty\" },\n { value: \"not_empty\", label: \"not empty\" },\n ],\n },\n { type: \"text\", key: \"right\", label: \"Compared to\", placeholder: \"active\" },\n ],\n default: [{ left: \"\", operator: \"eq\", right: \"\" }],\n },\n {\n type: \"expression\",\n key: \"condition\",\n label: \"Raw expression (advanced)\",\n example: \"{{ $json.active && $json.score > 10 }}\",\n description: \"Escape hatch for logic the builder can't express. Overrides the conditions above when set.\",\n },\n ],\n },\n {\n name: \"@particle-academy/switch_case\",\n executor: switchCaseExecutor,\n // returns its input on the chosen port\n emits: \"input\",\n aliases: [\"switch_case\", \"@fancy/switch_case\"],\n category: \"logic\",\n label: \"Switch\",\n description: \"Route to one of N labelled outputs based on a key.\",\n icon: \"⤳\",\n inputs: [{ id: \"in\" }],\n // Ports ARE the config: every distinct port a case routes to becomes an\n // output handle, plus the always-present `default`. Editing the cases map\n // moves the ports on the canvas and the ports the runtime activates.\n outputs: (config: any) => casePorts(config?.cases),\n configSchema: [\n { type: \"expression\", key: \"value\", label: \"Switch on\", example: \"{{ $json.kind }}\", required: true },\n {\n type: \"keyvalue\",\n key: \"cases\",\n label: \"Cases\",\n description: \"Match value → output port. Unmatched input takes `default`.\",\n keyLabel: \"When value is\",\n valueLabel: \"Route to port\",\n keyPlaceholder: \"a\",\n valuePlaceholder: \"case_a\",\n addLabel: \"Add case\",\n default: { a: \"case_a\", b: \"case_b\" },\n },\n ],\n },\n {\n name: \"@particle-academy/for_each\",\n outputShape: [\n { path: \"items\", type: \"array\" },\n { path: \"count\", type: \"number\" },\n ],\n aliases: [\"for_each\", \"@fancy/for_each\"],\n // Pure logic: no I/O to choose, so a default is safe. A host\n // executor still wins -- pickExecutor consults the registry first.\n executor: forEachExecutor,\n category: \"logic\",\n label: \"For Each\",\n description: \"Iterate over a list, emitting each item on `item`.\",\n icon: \"↻\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"item\", label: \"item\" }, { id: \"done\", label: \"done\" }],\n configSchema: [\n { type: \"expression\", key: \"source\", label: \"List\", example: \"{{ $json.users }}\", required: true },\n { type: \"number\", key: \"concurrency\", label: \"Concurrency\", default: 1, min: 1, max: 50 },\n ],\n },\n {\n name: \"@particle-academy/merge\",\n // `merge` mode unions every object input at the TOP level; `concat` builds\n // a list instead, whose elements are not addressable as fields. So concat\n // declares NOTHING rather than an empty list -- `[]` would claim \"emits no\n // fields\" of a kind that emits a list, which is false and refuses every\n // reference.\n emits: (config: { mode?: string }) =>\n (config?.mode ?? \"merge\") === \"concat\" ? null : (\"inputs-merged\" as const),\n aliases: [\"merge\", \"@fancy/merge\"],\n // Pure logic: no I/O to choose, so a default is safe. A host\n // executor still wins -- pickExecutor consults the registry first.\n executor: mergeExecutor,\n category: \"logic\",\n label: \"Merge\",\n description: \"Combine multiple inputs into one object or array.\",\n icon: \"⊕\",\n inputs: [{ id: \"a\" }, { id: \"b\" }],\n outputs: [{ id: \"out\" }],\n configSchema: [\n { type: \"select\", key: \"mode\", label: \"Mode\", default: \"merge\",\n options: [{ value: \"merge\", label: \"Object merge\" }, { value: \"concat\", label: \"Array concat\" }] },\n ],\n },\n {\n name: \"@particle-academy/wait\",\n outputShape: [\n { path: \"waited\", type: \"string\" as const, description: \"Which wait mode ran.\" },\n { path: \"duration\", type: \"number\" as const, description: \"How long it waited.\" },\n { path: \"input\", type: \"unknown\" as const, description: \"The value that arrived, carried forward.\" },\n ],\n aliases: [\"wait\", \"@fancy/wait\"],\n category: \"logic\",\n label: \"Wait\",\n description: \"Sleep or wait for an external event.\",\n icon: \"⏸\",\n configSchema: [\n { type: \"select\", key: \"mode\", label: \"Mode\", default: \"duration\",\n options: [{ value: \"duration\", label: \"Duration\" }, { value: \"until\", label: \"Until timestamp\" }, { value: \"event\", label: \"External event\" }] },\n { type: \"text\", key: \"duration\", label: \"Duration\", placeholder: \"5s, 10m, 1h\", description: \"Used when mode = duration.\" },\n ],\n },\n {\n name: \"@particle-academy/transform\",\n // Two behaviours: the input unchanged when no expression is configured,\n // else the shape that expression names. So the RELATION is config-dependent.\n emits: (config: { expression?: string }) =>\n (config?.expression ?? \"\") === \"\" ? (\"input\" as const) : (\"expression:expression\" as const),\n aliases: [\"transform\", \"@fancy/transform\"],\n // Pure logic: no I/O to choose, so a default is safe. A host\n // executor still wins -- pickExecutor consults the registry first.\n executor: transformExecutor,\n category: \"logic\",\n label: \"Transform\",\n description: \"Reshape data with an expression.\",\n icon: \"ƒ\",\n configSchema: [\n {\n type: \"select\", key: \"mode\", label: \"Build the output\", default: \"fields\",\n options: [\n { value: \"fields\", label: \"Field by field\" },\n { value: \"expression\", label: \"One expression\" },\n ],\n },\n {\n type: \"repeater\",\n key: \"fields\",\n label: \"Output fields\",\n description: \"Each row becomes a key on the result.\",\n titleKey: \"key\",\n addLabel: \"Add field\",\n fields: [\n { type: \"text\", key: \"key\", label: \"Key\", required: true, placeholder: \"name\" },\n { type: \"expression\", key: \"value\", label: \"Value\", example: \"{{ $json.first }}\", required: true },\n ],\n default: [{ key: \"\", value: \"\" }],\n },\n {\n type: \"expression\",\n key: \"expression\",\n label: \"Expression (advanced)\",\n example: \"{{ { id: $json.id, name: $json.first + ' ' + $json.last } }}\",\n description: \"Used when the mode above is set to one expression.\",\n },\n ],\n },\n\n // ───────────── Data ─────────────\n {\n name: \"@particle-academy/memory_store\",\n aliases: [\"memory_store\", \"@fancy/memory_store\"],\n category: \"data\",\n label: \"Memory Store\",\n description: \"Read or write per-conversation memory.\",\n icon: \"🧠\",\n configSchema: [\n { type: \"select\", key: \"operation\", label: \"Operation\", required: true, default: \"read\",\n options: [{ value: \"read\", label: \"Read\" }, { value: \"write\", label: \"Write\" }, { value: \"append\", label: \"Append\" }] },\n { type: \"text\", key: \"key\", label: \"Key\", placeholder: \"user.preferences\", required: true },\n { type: \"expression\", key: \"value\", label: \"Value (write/append only)\", example: \"{{ $json }}\" },\n { type: \"credential\", key: \"store\", label: \"Memory store\", credentialType: \"memory_store\" },\n ],\n },\n {\n name: \"@particle-academy/data_store\",\n aliases: [\"data_store\", \"@fancy/data_store\"],\n category: \"data\",\n label: \"Data Store\",\n description: \"Key-value or table read/write against a host store.\",\n icon: \"🗃\",\n configSchema: [\n { type: \"select\", key: \"operation\", label: \"Operation\", required: true, default: \"get\",\n options: [\n { value: \"get\", label: \"Get\" }, { value: \"set\", label: \"Set\" }, { value: \"delete\", label: \"Delete\" },\n { value: \"query\", label: \"Query\" }, { value: \"list\", label: \"List\" },\n ] },\n { type: \"text\", key: \"table\", label: \"Table / collection\", required: true },\n { type: \"text\", key: \"key\", label: \"Key\" },\n { type: \"keyvalue\", key: \"where\", label: \"Where\",\n description: \"Field/value pairs to match. For query and list operations.\",\n keyLabel: \"Field\", valueLabel: \"Equals\", addLabel: \"Add filter\" },\n { type: \"expression\", key: \"value\", label: \"Value (set only)\", example: \"{{ $json }}\" },\n { type: \"credential\", key: \"store\", label: \"Data store\", credentialType: \"data_store\" },\n ],\n },\n {\n name: \"@particle-academy/variable\",\n executor: variableExecutor,\n // evaluates the expression in config.value\n emits: \"expression:value\",\n aliases: [\"variable\", \"@fancy/variable\"],\n category: \"data\",\n label: \"Variable\",\n description: \"Workflow-scoped value used by other nodes.\",\n icon: \"𝓍\",\n configSchema: [\n { type: \"text\", key: \"name\", label: \"Name\", required: true },\n { type: \"expression\", key: \"value\", label: \"Value\", required: true },\n ],\n },\n\n // ───────────── AI ─────────────\n {\n name: \"@particle-academy/llm_call\",\n // LlmClient::complete() -> array{text:string,data?:mixed,usage?:array,raw?:mixed}\n //\n // A FUNCTION of config, because `data` exists only when this node was asked\n // for a schema. Declaring it statically would offer `{{ $json.data }}` on\n // every llm_call in the kit, including the ones that emit nothing of the\n // sort — and a suggestion that resolves to null at runtime is worse than no\n // suggestion, since the picker is exactly what gave the author confidence.\n outputShape: (config: { response_schema?: unknown }) => {\n const asked =\n config?.response_schema != null &&\n config.response_schema !== \"\" &&\n !(Array.isArray(config.response_schema) && config.response_schema.length === 0);\n\n return [\n { path: \"text\", type: \"string\" as const, description: \"The model's completion.\" },\n ...(asked\n ? [{ path: \"data\", type: \"unknown\" as const, description: \"The parsed, schema-checked result.\" }]\n : []),\n { path: \"usage\", type: \"object\" as const, description: \"Token counts, when the provider reports them.\" },\n { path: \"raw\", type: \"unknown\" as const, description: \"The provider's untouched response.\" },\n ];\n },\n aliases: [\"llm_call\", \"@fancy/llm_call\"],\n category: \"ai\",\n label: \"LLM Call\",\n description: \"Send a prompt + context to a model and receive a response.\",\n icon: \"✦\",\n configSchema: [\n { type: \"select\", key: \"provider\", label: \"Provider\", default: \"anthropic\",\n options: [\n { value: \"anthropic\", label: \"Anthropic\" },\n { value: \"openai\", label: \"OpenAI\" },\n { value: \"custom\", label: \"Custom\" },\n ] },\n { type: \"text\", key: \"model\", label: \"Model\", placeholder: \"claude-sonnet-4-5\", required: true },\n { type: \"textarea\", key: \"system\", label: \"System prompt\", rows: 4 },\n { type: \"expression\", key: \"prompt\", label: \"User prompt\", example: \"{{ $json.question }}\", required: true },\n { type: \"number\", key: \"temperature\", label: \"Temperature\", min: 0, max: 2, step: 0.1, default: 0.7 },\n { type: \"number\", key: \"max_tokens\", label: \"Max tokens\", min: 1, max: 8192, default: 1024 },\n {\n type: \"repeater\", key: \"tools\", label: \"Tools\",\n description: \"Tools the model may call.\",\n titleKey: \"name\", addLabel: \"Add tool\",\n fields: [\n { type: \"text\", key: \"name\", label: \"Name\", required: true, placeholder: \"search_index\" },\n { type: \"text\", key: \"description\", label: \"When to use it\" },\n { type: \"json\", key: \"input_schema\", label: \"Input schema\",\n description: \"JSON Schema for the tool's arguments.\" },\n ],\n },\n {\n type: \"json\", key: \"response_schema\", label: \"Response schema\",\n description:\n \"Optional JSON Schema. When set, the runtime asks the provider for schema-valid JSON \" +\n \"and the node emits the parsed value as `data` — reference it as {{ $json.data }}. \" +\n \"A response that cannot be parsed or does not match FAILS the node rather than \" +\n \"passing an empty value downstream.\",\n },\n { type: \"credential\", key: \"credential\", label: \"API credential\", credentialType: \"llm_credential\" },\n ],\n },\n {\n name: \"@particle-academy/llm_router\",\n outputShape: [\n { path: \"route\", type: \"string\" as const, description: \"The port the model chose.\" },\n { path: \"reason\", type: \"string\" as const, description: \"Why the model chose it.\" },\n { path: \"input\", type: \"unknown\" as const, description: \"The value that arrived, carried forward.\" },\n ],\n // Every id this node has ever shipped under keeps resolving — MOIC's saved\n // flows carry the bare `llm_branch`.\n aliases: [\"llm_router\", \"llm_branch\", \"@fancy/llm_branch\", \"@fancy/llm_router\"],\n category: \"ai\",\n label: \"LLM Router\",\n description: \"Let a model choose which route the flow takes.\",\n icon: \"✧\",\n inputs: [{ id: \"in\" }],\n // Each declared route is a port. The executor returns `{ __port: id }`\n // (or `Port.only(id)` on the PHP runtime) to pick one.\n outputs: (config: any) => routePorts(config?.routes, config?.fallback),\n // A shuttle, not an engine: it carries the routes out to whatever LLM\n // client the host registered and carries the choice back. No provider SDK\n // reaches core, so this stays a builtin without adding a dependency.\n executor: llmRouterExecutor,\n configSchema: [\n { type: \"textarea\", key: \"system\", label: \"System prompt\", rows: 3,\n description: \"Optional framing for the routing decision.\" },\n { type: \"expression\", key: \"prompt\", label: \"What to route on\",\n example: \"{{ $json.message }}\", required: true },\n {\n type: \"repeater\",\n key: \"routes\",\n label: \"Routes\",\n description: \"The model picks exactly one. Descriptions are what it chooses between — make them distinct.\",\n titleKey: \"port\",\n addLabel: \"Add route\",\n minItems: 2,\n fields: [\n { type: \"text\", key: \"port\", label: \"Port\", required: true, placeholder: \"billing\" },\n { type: \"text\", key: \"description\", label: \"When to choose it\", required: true,\n placeholder: \"The user is asking about an invoice, refund, or payment.\" },\n ],\n default: [\n { port: \"a\", description: \"Describe when the model should pick this route.\" },\n { port: \"b\", description: \"Describe when the model should pick this route.\" },\n ],\n },\n { type: \"select\", key: \"provider\", label: \"Provider\", default: \"anthropic\",\n options: [\n { value: \"anthropic\", label: \"Anthropic\" },\n { value: \"openai\", label: \"OpenAI\" },\n { value: \"custom\", label: \"Custom\" },\n ] },\n { type: \"text\", key: \"model\", label: \"Model\", placeholder: \"claude-sonnet-4-5\" },\n { type: \"switch\", key: \"fallback\", label: \"Add a `fallback` port\", default: true,\n description: \"Where the flow goes if the model returns no usable route.\" },\n { type: \"credential\", key: \"credential\", label: \"API credential\", credentialType: \"llm_credential\" },\n ],\n },\n {\n name: \"@particle-academy/tool_use\",\n aliases: [\"tool_use\", \"@fancy/tool_use\"],\n category: \"ai\",\n label: \"Tool Use\",\n description: \"Hand control to a host-registered tool by name.\",\n icon: \"🛠\",\n configSchema: [\n { type: \"text\", key: \"tool\", label: \"Tool name\", placeholder: \"search_index\", required: true },\n { type: \"expression\", key: \"args\", label: \"Arguments\", example: \"{{ { query: $json.q } }}\" },\n ],\n },\n {\n name: \"@particle-academy/embed_search\",\n outputShape: [\n { path: \"query\", type: \"string\" },\n { path: \"matches\", type: \"array\", description: \"Ranked results from the vector store.\" },\n ],\n aliases: [\"embed_search\", \"@fancy/embed_search\"],\n category: \"ai\",\n label: \"Embed & Search\",\n description: \"Embed a query and search a vector store.\",\n icon: \"✺\",\n configSchema: [\n { type: \"expression\", key: \"query\", label: \"Query\", required: true, example: \"{{ $json.question }}\" },\n { type: \"number\", key: \"topK\", label: \"Top K\", default: 5, min: 1, max: 50 },\n { type: \"credential\", key: \"vectorStore\", label: \"Vector store\", credentialType: \"vector_store\" },\n ],\n },\n\n // ───────────── IO ─────────────\n {\n name: \"@particle-academy/api_request\",\n // HttpClient::send() -> array{status:int,headers:array,body:mixed}\n outputShape: [\n { path: \"status\", type: \"number\", description: \"HTTP status code.\" },\n { path: \"headers\", type: \"object\" },\n { path: \"body\", type: \"unknown\", description: \"Decoded JSON when the response is JSON, otherwise the raw body.\" },\n ],\n aliases: [\"api_request\", \"@fancy/api_request\"],\n category: \"io\",\n label: \"API Request\",\n description: \"HTTP request to any URL.\",\n icon: \"↔\",\n configSchema: [\n ...HTTP_METHODS,\n { type: \"text\", key: \"url\", label: \"URL\", placeholder: \"https://api.example.com/...\", required: true },\n { type: \"keyvalue\", key: \"headers\", label: \"Headers\",\n keyLabel: \"Header\", valueLabel: \"Value\",\n keyPlaceholder: \"content-type\", valuePlaceholder: \"application/json\",\n addLabel: \"Add header\",\n default: { \"content-type\": \"application/json\" } },\n { type: \"json\", key: \"body\", label: \"Body\" },\n { type: \"credential\", key: \"auth\", label: \"Auth\", credentialType: \"api_credential\" },\n ],\n },\n {\n name: \"@particle-academy/webhook_out\",\n outputShape: [\n { path: \"sent\", type: \"boolean\" as const, description: \"True once the request was made.\" },\n { path: \"status\", type: \"number\" as const, description: \"HTTP status, when the transport reported one.\" },\n { path: \"response\", type: \"unknown\" as const, description: \"The response body, when there was one.\" },\n ],\n aliases: [\"webhook_out\", \"@fancy/webhook_out\"],\n category: \"io\",\n label: \"Send Webhook\",\n description: \"POST a payload to a configured URL.\",\n icon: \"↗\",\n configSchema: [\n { type: \"text\", key: \"url\", label: \"URL\", required: true },\n { type: \"keyvalue\", key: \"headers\", label: \"Headers\",\n keyLabel: \"Header\", valueLabel: \"Value\", addLabel: \"Add header\" },\n { type: \"expression\", key: \"payload\", label: \"Payload\", required: true, example: \"{{ $json }}\" },\n ],\n },\n\n // ───────────── Human ─────────────\n {\n name: \"@particle-academy/human_approval\",\n // returns its input on approved/denied\n emits: \"input\",\n aliases: [\"human_approval\", \"@fancy/human_approval\"],\n pausesForHuman: \"approval\",\n category: \"human\",\n label: \"Human Approval\",\n description: \"Pause until a human approves or denies.\",\n icon: \"✓\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"approved\", label: \"approved\" }, { id: \"denied\", label: \"denied\" }],\n configSchema: [\n { type: \"text\", key: \"title\", label: \"Approval title\", default: \"Approve action\" },\n { type: \"textarea\", key: \"description\", label: \"Description for approver\", rows: 3 },\n { type: \"credential\", key: \"channel\", label: \"Notify channel\", credentialType: \"notify_channel\" },\n ],\n },\n {\n name: \"@particle-academy/notify\",\n outputShape: [\n { path: \"sent\", type: \"boolean\" as const, description: \"True once the message was handed to the channel.\" },\n { path: \"channel\", type: \"string\" as const, description: \"The channel it went to.\" },\n { path: \"to\", type: \"string\" as const, description: \"The recipient.\" },\n { path: \"message\", type: \"string\" as const, description: \"The rendered message.\" },\n ],\n aliases: [\"notify\", \"@fancy/notify\"],\n category: \"human\",\n label: \"Notify\",\n description: \"Send a message via Slack / email / SMS / etc.\",\n icon: \"🔔\",\n configSchema: [\n { type: \"select\", key: \"channel\", label: \"Channel\", default: \"slack\",\n options: [\n { value: \"slack\", label: \"Slack\" }, { value: \"email\", label: \"Email\" },\n { value: \"sms\", label: \"SMS\" }, { value: \"discord\", label: \"Discord\" },\n ] },\n { type: \"text\", key: \"to\", label: \"To\", required: true },\n { type: \"expression\", key: \"message\", label: \"Message\", required: true, example: \"{{ $json.summary }}\" },\n ],\n },\n\n // ───────────── Output ─────────────\n {\n name: \"@particle-academy/output\",\n executor: outputExecutor,\n // returns its input unchanged\n emits: \"input\",\n aliases: [\"output\", \"@fancy/output\"],\n category: \"output\",\n label: \"Output\",\n description: \"Terminal node — captures the workflow's result.\",\n icon: \"●\",\n inputs: [{ id: \"in\" }],\n outputs: [],\n },\n {\n name: \"@particle-academy/log\",\n executor: logExecutor,\n outputShape: [\n { path: \"logged\", type: \"string\" as const, description: \"The message that was written.\" },\n { path: \"level\", type: \"string\" as const, description: \"The level it was written at.\" },\n ],\n aliases: [\"log\", \"@fancy/log\"],\n category: \"output\",\n label: \"Log\",\n description: \"Send to the run feed.\",\n icon: \"≡\",\n inputs: [{ id: \"in\" }],\n outputs: [],\n configSchema: [\n { type: \"select\", key: \"level\", label: \"Level\", default: \"info\",\n options: [{ value: \"info\", label: \"info\" }, { value: \"warn\", label: \"warn\" }, { value: \"error\", label: \"error\" }] },\n { type: \"expression\", key: \"message\", label: \"Message\", required: true, example: \"{{ $json }}\" },\n ],\n },\n {\n // Swimlane — a portless, resizable container. Child nodes are parented into\n // it; it never runs (the runtime skips the `layout` category). Uses its own\n // renderer (LaneNode) instead of the default card.\n name: \"@particle-academy/lane\",\n aliases: [\"lane\", \"@fancy/lane\"],\n category: \"layout\",\n label: \"Lane\",\n description: \"A resizable swimlane — drop nodes into it to group them.\",\n icon: \"▤\",\n inputs: [],\n outputs: [],\n configSchema: [\n { type: \"text\", key: \"title\", label: \"Title\", default: \"Lane\" },\n { type: \"select\", key: \"orientation\", label: \"Orientation\", default: \"horizontal\",\n options: [{ value: \"horizontal\", label: \"Row\" }, { value: \"vertical\", label: \"Column\" }] },\n ],\n defaultConfig: { title: \"Lane\", orientation: \"horizontal\" },\n resizable: { minWidth: 160, minHeight: 72 },\n },\n {\n // Terminal lane — a lane that OWNS a terminal for the length of the run.\n //\n // Visually a swimlane, and `layout` for the same reason the plain lane is:\n // a lane is not a step, so it never executes and never appears in topo\n // order. What is new is that it DECLARES a resource. The runtime opens its\n // terminal lazily, when the first terminal node inside it runs, and closes\n // it in the run's `finally` — so a graph that never reaches a terminal node\n // never spawns a process, and one that does gets exactly one session no\n // matter how many nodes use it.\n //\n // Membership is `parentId`, which already persists into the WorkflowSchema.\n // That is what lets a headless runtime resolve the same grouping the canvas\n // shows, without a second association to keep in sync.\n name: \"@particle-academy/terminal_lane\",\n aliases: [\"terminal_lane\", \"@fancy/terminal_lane\"],\n category: \"layout\",\n label: \"Terminal lane\",\n description: \"A lane that owns one terminal. Opens at the first terminal node, closes when the run ends.\",\n icon: \"▣\",\n inputs: [],\n outputs: [],\n configSchema: [\n { type: \"text\", key: \"title\", label: \"Title\", default: \"Terminal\" },\n {\n type: \"text\",\n key: \"command\",\n label: \"Command\",\n placeholder: \"Leave empty for the default shell\",\n },\n { type: \"text\", key: \"cwd\", label: \"Working directory\", placeholder: \"Host default\" },\n { type: \"keyvalue\", key: \"env\", label: \"Environment\" },\n {\n type: \"select\",\n key: \"orientation\",\n label: \"Orientation\",\n default: \"horizontal\",\n options: [\n { value: \"horizontal\", label: \"Row\" },\n { value: \"vertical\", label: \"Column\" },\n ],\n },\n ],\n defaultConfig: { title: \"Terminal\", orientation: \"horizontal\" },\n resizable: { minWidth: 220, minHeight: 120 },\n },\n {\n // Terminal nodes. All three live inside a terminal lane and talk to the\n // session that lane owns; outside one they abort by name rather than\n // opening a shell of their own.\n name: \"@particle-academy/terminal_run\",\n aliases: [\"terminal_run\", \"@fancy/terminal_run\"],\n category: \"io\",\n label: \"Run in terminal\",\n description: \"Run a shell command in the lane's terminal and wait for its exit code.\",\n icon: \"$\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"out\", label: \"output\" }],\n executor: terminalRunExecutor,\n configSchema: [\n {\n type: \"textarea\",\n key: \"command\",\n label: \"Command\",\n rows: 3,\n required: true,\n placeholder: \"npm test\",\n description:\n \"Runs in the lane's shell, so `cd` and exported variables persist between nodes. \"\n + \"SHELL ONLY — a TUI never returns to a prompt, so use Send + Await for one.\",\n },\n {\n type: \"number\",\n key: \"timeoutMs\",\n label: \"Timeout (ms)\",\n default: 120000,\n description: \"How long to wait for the command to finish before failing the run.\",\n },\n {\n type: \"switch\",\n key: \"failOnNonZero\",\n label: \"Fail the run on a non-zero exit\",\n default: true,\n description:\n \"On by default. Turning it off means a failed command lets the run report success — \"\n + \"read the exit code on the output port and branch on it instead.\",\n },\n ],\n defaultConfig: { command: \"\", timeoutMs: 120000, failOnNonZero: true },\n },\n\n {\n name: \"@particle-academy/terminal_send\",\n aliases: [\"terminal_send\", \"@fancy/terminal_send\"],\n category: \"io\",\n label: \"Send to terminal\",\n description: \"Type text at whatever is running in the lane's terminal, without waiting.\",\n icon: \"⌨\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"out\", label: \"sent\" }],\n executor: terminalSendExecutor,\n configSchema: [\n {\n type: \"textarea\",\n key: \"text\",\n label: \"Text\",\n rows: 4,\n placeholder: \"Summarise the failing test and propose a fix.\",\n description: \"What to type. This is how a graph prompts an agent TUI such as Claude Code or Codex.\",\n },\n {\n type: \"switch\",\n key: \"submit\",\n label: \"Press Enter\",\n default: true,\n description: \"Off leaves the text on the input line — useful for building one up across several nodes.\",\n },\n {\n type: \"switch\",\n key: \"clearFirst\",\n label: \"Forget earlier output first\",\n default: false,\n description:\n \"Discards anything the terminal said before this send, so a following Await cannot match \"\n + \"a prompt left over from the previous exchange.\",\n },\n ],\n defaultConfig: { text: \"\", submit: true, clearFirst: false },\n },\n\n {\n name: \"@particle-academy/terminal_await\",\n aliases: [\"terminal_await\", \"@fancy/terminal_await\"],\n category: \"io\",\n label: \"Await terminal output\",\n description: \"Wait until the lane's terminal prints something that matches.\",\n icon: \"⏱\",\n inputs: [{ id: \"in\" }],\n outputs: [{ id: \"out\", label: \"output\" }],\n executor: terminalAwaitExecutor,\n configSchema: [\n {\n type: \"text\",\n key: \"pattern\",\n label: \"Wait for\",\n required: true,\n placeholder: \"esc to interrupt\",\n description: \"Matched against the output with colour codes already stripped, so match what you SEE.\",\n },\n {\n type: \"select\",\n key: \"mode\",\n label: \"Match as\",\n default: \"text\",\n options: [\n { value: \"text\", label: \"Plain text\" },\n { value: \"regex\", label: \"Regular expression\" },\n ],\n description: \"Regex mode also returns capture groups, which is how a value gets out of a prompt.\",\n },\n {\n type: \"number\",\n key: \"timeoutMs\",\n label: \"Timeout (ms)\",\n default: 120000,\n },\n {\n type: \"select\",\n key: \"onTimeout\",\n label: \"If it never appears\",\n default: \"fail\",\n options: [\n { value: \"fail\", label: \"Fail the run\" },\n { value: \"continue\", label: \"Continue with matched: false\" },\n ],\n description:\n \"Failing is the default. Continuing lets the next node type at a process that never became \"\n + \"ready while the run still reports success, so it has to be asked for.\",\n },\n ],\n defaultConfig: { pattern: \"\", mode: \"text\", timeoutMs: 120000, onTimeout: \"fail\" },\n },\n\n {\n // Note — a sticky-note annotation. Portless + visual-only: the runtime skips\n // the `annotation` category, so a note's text NEVER reaches a runner — it\n // rides in the document purely for people, editors, and MCP tools. Uses its\n // own renderer (NoteNode); double-click on the canvas to edit in place.\n name: \"@particle-academy/note\",\n aliases: [\"note\", \"@fancy/note\"],\n category: \"annotation\",\n label: \"Note\",\n description: \"A sticky note that documents the canvas. Never runs — editor + agent only.\",\n icon: \"🗒\",\n inputs: [],\n outputs: [],\n configSchema: [\n { type: \"text\", key: \"title\", label: \"Title\", placeholder: \"Optional heading\" },\n { type: \"textarea\", key: \"text\", label: \"Note\", rows: 5, placeholder: \"What does this part of the flow do?\" },\n { type: \"select\", key: \"color\", label: \"Color\", default: \"amber\", options: [\n { value: \"amber\", label: \"Amber\" },\n { value: \"sky\", label: \"Sky\" },\n { value: \"violet\", label: \"Violet\" },\n { value: \"emerald\", label: \"Emerald\" },\n { value: \"rose\", label: \"Rose\" },\n { value: \"slate\", label: \"Slate\" },\n ] },\n ],\n defaultConfig: { text: \"\", color: \"amber\" },\n resizable: { minWidth: 140, minHeight: 80 },\n },\n];\n\n/**\n * Register every built-in kind AS DATA -- no renderers.\n *\n * This is what `registry.ts` self-populates with, so a headless consumer gets\n * the full vocabulary without React. `builtin.ts` re-registers the four kinds\n * that have renderers on top; `registerBuiltinKindInternal` replaces a BUILTIN\n * by name, so that upgrades them in place.\n *\n * Both go through that internal registrar rather than the public\n * `registerNodeKind`, so neither can overwrite a kind a HOST has claimed. See\n * 0.66.2: that used to happen on every call, silently.\n */\nexport function registerBuiltinKindData(): void {\n for (const k of KINDS) registerBuiltinKindInternal(k);\n}\n\n/** The raw table, renderer-free. `builtin.ts` exports the decorated one. */\nexport const BUILTIN_KIND_DATA: NodeKindDefinition[] = KINDS;\n","import type { ConfigField, NodeCategory, NodeKindDefinition } from \"./types\";\n// The DATA module, deliberately -- importing `./builtin` here is what put\n// React into `/engine` (#11). See that file for the whole story.\nimport { registerBuiltinKindData } from \"./builtin-kinds\";\n\nconst kinds = new Map<string, NodeKindDefinition<any, any, any>>();\n/** alias → canonical name. See `resolveKindId`. */\nconst aliases = new Map<string, string>();\nconst listeners = new Set<() => void>();\n/**\n * canonical name → presentation patch. See `overrideNodeKind`.\n *\n * Kept SEPARATE from `kinds` on purpose: an override has to survive its base\n * kind being re-registered (HMR, a later `registerBuiltinKinds()`, a package\n * upgrade). Merging into the definition would mean the next registration\n * silently reverts the consumer's naming.\n */\nconst overrides = new Map<string, NodeKindPresentation>();\n\n/**\n * Names a HOST registered, as opposed to names the builtin kit registered.\n *\n * Builtin registration is not a one-shot event: `registerBuiltinKinds()` is\n * exported, the four kinds with renderers are deliberately registered twice\n * (React-free table, then decorated), and since 0.66.1 the root barrel calls it\n * as an import side effect. So \"the builtins register again\" happens routinely\n * and at times no consumer can predict.\n *\n * Without this set, every one of those occasions silently reverted a host's\n * replacement of a builtin — the only mechanism we offer for extending one.\n * A consumer's field would vanish from the editor while their server kept\n * validating it, and whether it happened at all depended on which module their\n * bundler evaluated second.\n *\n * This is the same protection `overrides` already had, and for the same stated\n * reason. Presentation patches were kept safe from re-registration; behavioural\n * replacement was not, and nothing marked the asymmetry.\n */\nconst hostOwned = new Set<string>();\n\n/**\n * canonical name -> schema patch from a SERVER. See `applyKindSchemaOverlay`.\n *\n * Kept in its own map for the reason `overrides` is: a patch stored ON the kind\n * is reverted the next time that kind is registered, and builtin registration\n * is not a one-shot event. 0.66.2 was exactly that bug for behavioural\n * replacement; this is the same shape and gets the same protection rather than\n * waiting to learn it twice.\n */\nconst schemaOverlays = new Map<string, KindSchemaOverlay>();\n\n/**\n * The builtin definition for a name, kept even while a host owns the name.\n *\n * Without it, releasing a claim could only DELETE the entry — which is a worse\n * state than before the override, not a return to it: the palette loses the\n * node and the canvas renders raw kind ids where a label belongs.\n */\nconst builtinDefs = new Map<string, NodeKindDefinition<any, any, any>>();\n\nlet builtinsEnsured = false;\n\n/**\n * Put the builtin kit in the registry before anyone reads or writes it.\n *\n * Registration used to be a bare `registerBuiltinKinds()` in `src/index.ts`, so\n * it fired ONLY as an import side effect of that one entry. Every other route in\n * — the `/engine` and `/registry` subpaths, or a root import that TypeScript\n * erases because it only took types — got an empty registry, and an empty\n * registry is silent: `getNodeKind()` returns null, `FlowViewer` falls through\n * its title chain, and the canvas shows `@particle-academy/llm_call` where a\n * name belongs.\n *\n * Doing it here instead means correctness no longer depends on which entry a\n * consumer imported, or on a bundler agreeing to keep a top-level statement.\n *\n * The flag is set BEFORE the call so a listener that reads the registry from\n * inside `notify()` cannot recurse. `registerNodeKind` ensures too, so builtins\n * are always in place before a host registers over one of them.\n */\nexport function ensureBuiltinKinds(): void {\n if (builtinsEnsured) return;\n builtinsEnsured = true;\n registerBuiltinKindData();\n}\n\n/**\n * The presentation fields a consumer may override on someone else's node kind.\n *\n * Deliberately excludes everything behavioural — `executor`, `inputs`,\n * `outputs`, `configSchema`, `sideEffects`. An \"override\" that could change\n * those is not an override, it is a fork wearing a friendly name, and it would\n * desync the graph from the runtime that executes it.\n *\n * `category` IS included: which drawer a node appears in is presentation, and a\n * consumer regrouping their palette is the same kind of act as renaming.\n */\nexport type NodeKindPresentation = Partial<\n Pick<NodeKindDefinition, \"label\" | \"description\" | \"icon\" | \"accent\" | \"category\">\n>;\n\n/**\n * registerNodeKind — install a node kind in the global registry. Returns\n * an `unregister` function. Calling with the same name replaces the prior\n * registration (handy for HMR).\n *\n * A kind's `name` is its CANONICAL id and is what gets written into saved\n * documents. Publish namespaced (`@fancy/llm_branch`, `@acme/salesforce_upsert`)\n * and list any previous bare names in `aliases`, so graphs saved before the\n * rename keep resolving.\n */\nexport function registerNodeKind<TC = any, TI = any, TO = any>(\n definition: NodeKindDefinition<TC, TI, TO>,\n): () => void {\n ensureBuiltinKinds();\n // Claiming the name is what protects it: from here on the builtin kit will\n // not overwrite this entry, however many times it re-registers.\n hostOwned.add(definition.name);\n kinds.set(definition.name, definition as NodeKindDefinition<any, any, any>);\n for (const alias of definition.aliases ?? []) aliases.set(alias, definition.name);\n notify();\n return () => {\n if (kinds.get(definition.name) === (definition as any)) {\n kinds.delete(definition.name);\n hostOwned.delete(definition.name);\n for (const alias of definition.aliases ?? []) {\n if (aliases.get(alias) === definition.name) aliases.delete(alias);\n }\n notify();\n }\n };\n}\n\n/**\n * Register a kind AS PART OF THE BUILTIN KIT — never overwriting a host.\n *\n * The builtin modules use this instead of `registerNodeKind` so that repeated\n * builtin registration is safe. It still replaces builtins (the four kinds with\n * renderers are registered twice on purpose, plain table then decorated), but\n * it steps aside for any name a host has claimed.\n *\n * Internal: not re-exported from the package. A consumer wanting to install a\n * kind uses `registerNodeKind`, and gets ownership of the name by doing so.\n */\nexport function registerBuiltinKindInternal(\n definition: NodeKindDefinition<any, any, any>,\n): void {\n // Recorded BEFORE the ownership check: a host owning the name now is exactly\n // when we will later need the builtin to hand back.\n builtinDefs.set(definition.name, definition);\n\n if (hostOwned.has(definition.name)) return;\n\n kinds.set(definition.name, definition);\n for (const alias of definition.aliases ?? []) {\n if (!hostOwned.has(aliases.get(alias) ?? \"\")) aliases.set(alias, definition.name);\n }\n}\n\n/**\n * Release a host's claim on a name and restore the builtin behind it.\n *\n * The counterpart to `registerNodeKind` replacing a builtin. `registerNodeKind`\n * does return an unregister closure, but a consumer reading the export list\n * cannot find it, and one correctly concluded no such operation existed — so\n * this is the named form.\n *\n * **Test isolation is the reason it matters.** Before 0.66.2, calling\n * `registerBuiltinKinds()` restored the builtins over any override, and people\n * reasonably used that to reset between tests. Since 0.66.2 it correctly\n * refuses to overwrite a host's registration, so that reset silently stopped\n * resetting — and it does not fail where it broke, it fails as a wrong\n * assertion in a later, unrelated test. Use this instead.\n *\n * Returns whether anything was actually released, so a typo'd name is visible\n * rather than a silent no-op — a reset helper that quietly stops resetting is\n * the failure this exists to prevent.\n */\nexport function unregisterNodeKind(name: string): boolean {\n const canonical = resolveKindId(name) ?? name;\n\n const released = hostOwned.delete(canonical);\n if (!released && !kinds.has(canonical)) return false;\n\n const builtin = builtinDefs.get(canonical);\n if (builtin) {\n kinds.set(canonical, builtin);\n for (const alias of builtin.aliases ?? []) aliases.set(alias, canonical);\n } else {\n const previous = kinds.get(canonical);\n kinds.delete(canonical);\n for (const alias of previous?.aliases ?? []) {\n if (aliases.get(alias) === canonical) aliases.delete(alias);\n }\n }\n\n notify();\n\n return released;\n}\n\n/**\n * Empty the registry completely, builtins included.\n *\n * For tests that need a clean slate — in particular any test asserting how host\n * and builtin registration interact, which cannot be written against a registry\n * still holding the previous test's kinds. Production code has no reason to\n * call it: a registry that can be emptied at runtime is a registry that can be\n * emptied at the wrong moment.\n */\nexport function resetNodeKindsForTests(): void {\n kinds.clear();\n aliases.clear();\n overrides.clear();\n schemaOverlays.clear();\n hostOwned.clear();\n builtinDefs.clear();\n builtinsEnsured = false;\n notify();\n}\n\n/**\n * A schema patch for a kind, sourced from a host's SERVER-side registry.\n *\n * fancy-flow has two kind registries. The PHP one lets a host decorate a\n * builtin and that decoration reaches the runtime and validation; the editor,\n * built from the JS registry, never learned any of it. A consumer hit this as a\n * field that existed, ran, and had no control in the panel.\n *\n * **The server owns what a node is CONFIGURED with. The client keeps what a\n * node DOES.** Only the serialisable half is here on purpose: `executor`,\n * `component`, `renderBody` and `icon` cannot cross a wire, and neither can\n * ports — `PortSpec` may be a FUNCTION of config, and three builtins use that\n * form (`switch_case` groups match keys onto one port and joins their labels;\n * `subflow` branches on a derived mode and cares about order). Expressing those\n * as data needs a mini-language with grouping, conditionals and ordering, which\n * is a second implementation of logic that already exists.\n */\nexport type KindSchemaOverlay = {\n /** Canonical id or alias — resolved either way. */\n kind: string;\n /**\n * REPLACES the kind's schema. Never merges.\n *\n * The motivating case is *drop seven fields and add one*, and a merge cannot\n * express a removal. A `remove: string[]` beside a merge would be two\n * mechanisms for one job, and their interaction would be the next bug. The\n * server sends the schema it wants; that is the point of it owning one.\n */\n configSchema?: ConfigField[];\n label?: string;\n description?: string;\n category?: NodeCategory;\n};\n\nexport type KindSchemaOverlayResult = {\n /** Canonical ids that matched a registered kind. */\n applied: string[];\n /**\n * Ids that matched NOTHING, reported rather than dropped.\n *\n * A server lists many kinds and a client will not have registered all of\n * them. Applying what matches and staying quiet about the rest is how a\n * field goes missing with no error anywhere — which is the defect this whole\n * mechanism exists to end, so it must not be reintroduced by the fix.\n */\n unknown: string[];\n unapply: () => void;\n};\n\n/**\n * Apply server-sourced schema patches to kinds this client already has.\n *\n * It does NOT register kinds. A kind must exist locally for its executor,\n * ports and renderer; the overlay corrects its schema, it does not conjure one.\n */\nexport function applyKindSchemaOverlay(\n overlays: readonly KindSchemaOverlay[],\n): KindSchemaOverlayResult {\n ensureBuiltinKinds();\n\n const applied: string[] = [];\n const unknown: string[] = [];\n const previous = new Map<string, KindSchemaOverlay | undefined>();\n\n for (const overlay of overlays) {\n const canonical = resolveKindId(overlay.kind);\n if (!canonical) {\n unknown.push(overlay.kind);\n continue;\n }\n\n if (!previous.has(canonical)) previous.set(canonical, schemaOverlays.get(canonical));\n schemaOverlays.set(canonical, { ...overlay, kind: canonical });\n applied.push(canonical);\n }\n\n if (applied.length > 0) notify();\n\n return {\n applied,\n unknown,\n unapply: () => {\n for (const [canonical, before] of previous) {\n if (before) {\n schemaOverlays.set(canonical, before);\n } else {\n schemaOverlays.delete(canonical);\n }\n }\n notify();\n },\n };\n}\n\n/** Drop every server-sourced schema patch. Mostly for tests. */\nexport function clearKindSchemaOverlays(): void {\n if (schemaOverlays.size === 0) return;\n schemaOverlays.clear();\n notify();\n}\n\n/**\n * Resolve any id — canonical or alias — to the canonical one, or null.\n *\n * `kind` is persisted inside every saved graph, so a bare name that two\n * packages could both claim is unfixable after the fact: the ambiguous string\n * is already in the document. Canonical ids are namespaced; aliases exist so\n * documents written before namespacing keep opening.\n */\nexport function resolveKindId(id: string): string | null {\n ensureBuiltinKinds();\n if (kinds.has(id)) return id;\n const canonical = aliases.get(id);\n return canonical && kinds.has(canonical) ? canonical : null;\n}\n\n/**\n * Rename or re-describe a kind you did not author.\n *\n * Before this existed the only way to relabel a builtin was `registerNodeKind`\n * with a full definition — which REPLACES the kind, so a consumer wanting\n * \"Call an API\" instead of \"HTTP Request\" had to re-declare that node's\n * configSchema, ports, executor and renderer, and silently forfeited whatever\n * the builtin gained in the next release. In practice nobody renamed a node,\n * and the palette could not be localised at all.\n *\n * ```ts\n * const undo = overrideNodeKind(\"@particle-academy/api_request\", {\n * label: \"Call an API\",\n * description: \"Fetch or post JSON to a URL\",\n * });\n * ```\n *\n * Applies at `getNodeKind()` and `listNodeKinds()`, so one call reaches the\n * palette, the node cards on the canvas, `FlowViewer`, and anything else that\n * reads the registry. Returns an unsubscribe, matching `registerNodeKind`.\n *\n * Patching an unregistered id is allowed and takes effect if that kind is\n * registered later — order of module side effects is not something a consumer\n * should have to reason about.\n */\nexport function overrideNodeKind(name: string, patch: NodeKindPresentation): () => void {\n const canonical = resolveKindId(name) ?? name;\n const previous = overrides.get(canonical);\n\n overrides.set(canonical, { ...previous, ...patch });\n notify();\n\n return () => {\n if (previous) {\n overrides.set(canonical, previous);\n } else {\n overrides.delete(canonical);\n }\n notify();\n };\n}\n\n/** Remove every presentation override. Mostly for tests. */\nexport function clearNodeKindOverrides(): void {\n if (overrides.size === 0) return;\n overrides.clear();\n notify();\n}\n\nfunction withOverride(kind: NodeKindDefinition | undefined): NodeKindDefinition | null {\n if (!kind) return null;\n\n // base -> SERVER schema -> LOCAL presentation override.\n //\n // The local override wins, and the order is pinned by a test because it is\n // invisible until the two disagree: `overrideNodeKind` is the app author's\n // explicit choice about naming, which is more specific than a server default.\n const overlay = schemaOverlays.get(kind.name);\n const patch = overrides.get(kind.name);\n if (!overlay && !patch) return kind;\n\n const withSchema = overlay\n ? ({\n ...kind,\n ...(overlay.configSchema !== undefined ? { configSchema: overlay.configSchema } : {}),\n ...(overlay.label !== undefined ? { label: overlay.label } : {}),\n ...(overlay.description !== undefined ? { description: overlay.description } : {}),\n ...(overlay.category !== undefined ? { category: overlay.category } : {}),\n } as NodeKindDefinition)\n : kind;\n\n return patch ? ({ ...withSchema, ...patch } as NodeKindDefinition) : withSchema;\n}\n\n/** Get a single kind by canonical id or alias, or null. */\nexport function getNodeKind(name: string): NodeKindDefinition | null {\n const canonical = resolveKindId(name);\n return canonical ? withOverride(kinds.get(canonical) as NodeKindDefinition) : null;\n}\n\n/** Every id a kind answers to — canonical first. Used to key node-type maps. */\nexport function kindIds(kind: NodeKindDefinition): string[] {\n return [kind.name, ...(kind.aliases ?? [])];\n}\n\n/** List every registered kind, optionally filtered by category. */\nexport function listNodeKinds(category?: string): NodeKindDefinition[] {\n ensureBuiltinKinds();\n const all = Array.from(kinds.values()).map((k) =>\n withOverride(k as NodeKindDefinition),\n ) as NodeKindDefinition[];\n // Filter AFTER applying overrides, so an override that moves a node to a\n // different category actually moves it in the palette rather than leaving it\n // filed under the old one with a new name.\n return category ? all.filter((k) => k.category === category) : all;\n}\n\n/** Subscribe to registry changes. Returns an unsubscribe function. */\nexport function onNodeKindsChanged(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n\nfunction notify(): void {\n for (const l of listeners) l();\n}\n\n/** Fill in defaults from a kind's configSchema for newly-created nodes. */\nexport function defaultConfigFor(kind: NodeKindDefinition): Record<string, unknown> {\n const fromKind = kind.defaultConfig ? { ...(kind.defaultConfig as Record<string, unknown>) } : {};\n for (const field of kind.configSchema ?? []) {\n if (fromKind[field.key] !== undefined) continue;\n if (\"default\" in field && (field as any).default !== undefined) {\n fromKind[field.key] = (field as any).default;\n }\n }\n return fromKind;\n}\n\n/**\n * Validate a config object against a kind's schema. Returns an array of\n * issues (empty = valid). Validation is intentionally light — type\n * coercion + required-field checks. Hosts can layer Zod / Ajv on top.\n */\nexport function validateConfig(\n kind: NodeKindDefinition,\n config: Record<string, unknown>,\n): Array<{ key: string; message: string }> {\n const issues: Array<{ key: string; message: string }> = [];\n for (const field of kind.configSchema ?? []) {\n const value = config[field.key];\n if (field.required && (value === undefined || value === null || value === \"\")) {\n issues.push({ key: field.key, message: `${field.label} is required` });\n continue;\n }\n if (value === undefined || value === null) continue;\n const issue = validateField(field, value);\n if (issue) issues.push({ key: field.key, message: issue });\n }\n return issues;\n}\n\nfunction validateField(field: ConfigField, value: unknown): string | null {\n switch (field.type) {\n case \"text\":\n case \"textarea\":\n case \"expression\":\n case \"credential\":\n return typeof value === \"string\" ? null : `${field.label} must be a string`;\n case \"number\": {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return `${field.label} must be a number`;\n if (field.min !== undefined && value < field.min) return `${field.label} must be >= ${field.min}`;\n if (field.max !== undefined && value > field.max) return `${field.label} must be <= ${field.max}`;\n return null;\n }\n case \"switch\":\n return typeof value === \"boolean\" ? null : `${field.label} must be a boolean`;\n case \"select\": {\n const allowed = field.options.map((o) => o.value);\n return allowed.includes(String(value)) ? null : `${field.label} must be one of ${allowed.join(\", \")}`;\n }\n case \"json\":\n return null; // permissive — just JSON-shaped\n case \"repeater\": {\n if (!Array.isArray(value)) return `${field.label} must be a list`;\n if (field.minItems !== undefined && value.length < field.minItems) {\n return `${field.label} needs at least ${field.minItems}`;\n }\n if (field.maxItems !== undefined && value.length > field.maxItems) {\n return `${field.label} allows at most ${field.maxItems}`;\n }\n // Surface the first offending row so the author knows WHICH one.\n for (let i = 0; i < value.length; i++) {\n const row = value[i];\n if (!row || typeof row !== \"object\" || Array.isArray(row)) {\n return `${field.label} item ${i + 1} must be an object`;\n }\n for (const sub of field.fields) {\n const cell = (row as Record<string, unknown>)[sub.key];\n if (sub.required && (cell === undefined || cell === null || cell === \"\")) {\n return `${field.label} item ${i + 1}: ${sub.label} is required`;\n }\n if (cell === undefined || cell === null) continue;\n const issue = validateField(sub, cell);\n if (issue) return `${field.label} item ${i + 1}: ${issue}`;\n }\n }\n return null;\n }\n case \"keyvalue\": {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return `${field.label} must be a key/value map`;\n }\n const allowed = field.valueOptions?.map((o) => o.value);\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (typeof v !== \"string\") return `${field.label}: \"${k}\" must be a string`;\n if (allowed && !allowed.includes(v)) {\n return `${field.label}: \"${k}\" must be one of ${allowed.join(\", \")}`;\n }\n }\n return null;\n }\n case \"document\":\n return null; // opaque to fancy-flow — the host's editor owns its shape\n default:\n return null;\n }\n}\n\n/** Default accents per category. */\nexport function categoryAccent(category: string): string {\n switch (category) {\n case \"trigger\": return \"#10b981\";\n case \"logic\": return \"#f59e0b\";\n case \"data\": return \"#0ea5e9\";\n case \"ai\": return \"#8b5cf6\";\n case \"io\": return \"#3b82f6\";\n case \"human\": return \"#ec4899\";\n case \"output\": return \"#a855f7\";\n case \"layout\": return \"#64748b\";\n case \"annotation\": return \"#eab308\";\n default: return \"#71717a\";\n }\n}\n","import { getNodeKind, kindIds } from \"../registry/registry\";\nimport type { FlowGraph, FlowNode } from \"../types\";\nimport type { ImportIssue } from \"../schema/workflow-schema\";\n\n/**\n * Refuse a graph whose nodes cannot take part in the workflow's dataflow.\n *\n * Two shapes, both of which import cleanly and then quietly do nothing. Neither\n * FAILS — which is what makes them worth refusing at authoring time, because a\n * run that reports success is the worst way for a workflow to be wrong. Both\n * were measured against the PHP twin's engine before this was written, and both\n * behave the same way here:\n *\n * ## 1. A FLOATING node — no inbound and no outbound edge\n *\n * It is NOT skipped. A node with no incoming edge is a root, so the topo sort\n * runs it: a three-node graph with one floating `log` executed `t,lonely,o`. It\n * runs disconnected — receiving nothing from the graph and reaching nobody in\n * it — which is precisely the state an author cannot see on a canvas.\n *\n * ## 2. An edge leaving a TERMINATOR\n *\n * A terminal kind — `output`, `log` — declares an EMPTY output port list. It\n * ends a chain. Measured: `t -> output -> log` imported clean and the `log` DID\n * run, with `{{ input }}` resolving to `\"\"`. `collectInputs` binds a payload\n * only when `\"<sourceId>:<handle>\"` exists, and a node publishing no ports never\n * creates that key — so the edge does not fail, it delivers nothing, and the\n * node downstream operates on a hole.\n *\n * That is the same silent-nothing the undelivered-edge diagnostic reports at run\n * time, but this one is decidable FROM THE DOCUMENT ALONE.\n *\n * ## What may float\n *\n * See {@link mayFloat}. Not only `note`: any `annotation` or `layout` kind (a\n * swimlane is never wired to anything — that is what a lane IS), and any kind\n * the registry does not know.\n */\nexport function checkGraphConnectivity(graph: FlowGraph): ImportIssue[] {\n const { nodes, edges } = graph;\n const issues: ImportIssue[] = [];\n\n const hasIncoming = new Set<string>();\n const hasOutgoing = new Set<string>();\n for (const edge of edges) {\n hasIncoming.add(edge.target);\n hasOutgoing.add(edge.source);\n }\n\n // A single-node graph is not \"floating\" — it is a graph with one step, which\n // is a legitimate (if small) workflow and what every graph looks like on the\n // way to a bigger one. Refusing it would make the editor unusable from the\n // first node placed.\n const single = nodes.length === 1;\n\n for (const node of nodes) {\n if (single || mayFloat(node)) continue;\n\n if (!hasIncoming.has(node.id) && !hasOutgoing.has(node.id)) {\n issues.push({\n level: \"error\",\n nodeId: node.id,\n message:\n `Node \"${node.id}\" is connected to nothing — no inbound edge and no outbound edge. ` +\n `It still RUNS (a node with no inbound edge is a root), but it receives nothing from ` +\n `the graph and reaches nobody in it, so it is either unwired or left behind by a ` +\n `deletion. Only a note, an annotation or a lane may float.`,\n });\n }\n }\n\n const byId = new Map(nodes.map((n) => [n.id, n]));\n\n for (const edge of edges) {\n const source = byId.get(edge.source);\n if (!source || !isTerminator(source)) continue;\n\n issues.push({\n level: \"error\",\n edgeId: edge.id,\n message:\n `Edge \"${edge.id}\" reads from \"${edge.source}\", which is a TERMINAL node and publishes ` +\n `no output ports at all. Nothing can ever travel this edge: it does not fail at run ` +\n `time, it delivers nothing, and \"${edge.target}\" runs anyway with an empty input.`,\n });\n }\n\n return issues;\n}\n\n/**\n * Which nodes are allowed to sit unconnected.\n *\n * Three answers, and the third is the one that took a second pass — it was\n * missed in the PHP twin's first release and shipped as 0.48.1:\n *\n * 1. **`note`**, across every id the kind answers to, so a graph saved with the\n * canonical `@particle-academy/note` stays an annotation rather than becoming\n * an unwireable node.\n * 2. **Any `annotation` or `layout` kind.** A host may register its own note,\n * and `@particle-academy/lane` is a swimlane the engine walks straight past.\n * Neither is a step and neither is ever wired.\n * 3. **A kind the registry has never heard of.** Not a loophole — the honest\n * answer. An unknown kind already produces its own issue, and we cannot know\n * whether it is a step, an annotation or a lane. Claiming it must be wired\n * would assert something unverifiable, and it lands hardest on the graphs\n * that deserve it least: a laned graph loaded by a runtime without `lane`\n * registered would report every swimlane twice, the second time wrongly.\n *\n * The note/annotation/layout half matches the test `run-flow` uses to skip a\n * node. The unknown-kind half deliberately does NOT — see the closing comment in\n * this file for why the two must not become one helper.\n */\nexport function mayFloat(node: FlowNode): boolean {\n const type = node.type;\n if (!type) return false;\n if (type === \"note\") return true;\n\n const kind = getNodeKind(type);\n if (!kind) return true;\n\n return kindIds(kind).includes(\"note\") || kind.category === \"annotation\" || kind.category === \"layout\";\n}\n\n/**\n * A kind that declares an EMPTY output list ends a chain.\n *\n * `[]` and `undefined` are different answers and only the first means this.\n * `undefined` is \"nobody declared what this publishes\", which resolves to `out`\n * and is most nodes in most graphs; `[]` is an explicit claim that there is\n * nothing to connect from. Reading them alike would refuse nearly every\n * workflow ever written.\n */\nfunction isTerminator(node: FlowNode): boolean {\n // A node carrying its own ports overrides its kind — the engine reads these\n // first, so an author who has said what this node publishes is believed.\n // (The PHP twin's importer DROPS node-level ports, so this branch is reachable\n // there only for a hand-built graph. Noted rather than smoothed over: the two\n // importers genuinely differ here.)\n const own = (node.data as { outputs?: unknown[] } | undefined)?.outputs;\n if (Array.isArray(own)) return own.length === 0;\n\n const kind = node.type ? getNodeKind(node.type) : null;\n\n // An unregistered kind falls back to `out` in the engine, so it is not a\n // terminator. Refusing here would break a host mid-registration, and would\n // use \"I do not know\" as evidence.\n if (!kind) return false;\n\n return Array.isArray(kind.outputs) && kind.outputs.length === 0;\n}\n\n/**\n * NOT shared with `frontier`'s / `run-flow`'s annotation test, deliberately.\n *\n * The two predicates look identical and have OPPOSITE safe defaults, which is\n * exactly how a shared helper becomes a bug:\n *\n * - **Here** an unknown kind may float. Being permissive costs nothing — the\n * unknown-kind issue already fires, and we would otherwise assert something\n * unverifiable.\n * - **In the engine** an unknown kind must NOT be treated as an annotation.\n * Being permissive there means SKIPPING a node the host meant to run, which\n * is silent and unrecoverable.\n *\n * So the note/annotation/layout half is the same question and the unknown half\n * is a different one. Collapsing them into one function would read as tidier and\n * would make a host's unregistered kind stop executing.\n */\n","import type { FlowEdge, FlowGraph, FlowNode, PortDescriptor, WorkflowInput } from \"../types\";\nimport { checkGraphConnectivity } from \"../analysis/graph-connectivity\";\nimport { defaultConfigFor, getNodeKind, validateConfig } from \"../registry/registry\";\nimport { resolveNodePorts } from \"../registry/ports\";\n\n/** Schema version. Bump on breaking shape changes; add migrations as needed. */\nexport const WORKFLOW_SCHEMA_VERSION = 1 as const;\nexport const WORKFLOW_SCHEMA_URL = \"https://particle.academy/schemas/workflow/v1.json\";\n\nexport type WorkflowSchema = {\n $schema: typeof WORKFLOW_SCHEMA_URL;\n version: typeof WORKFLOW_SCHEMA_VERSION;\n metadata?: WorkflowMetadata;\n /**\n * What this workflow accepts at run start, passed BY NAME.\n *\n * Lives beside `graph` rather than inside it because it describes the\n * workflow's CONTRACT, not its topology: a caller reads this to know what to\n * pass, and reading it should not mean walking nodes looking for a trigger.\n *\n * Omitted entirely when a workflow takes none, so every existing saved\n * document is unchanged byte for byte.\n */\n inputs?: WorkflowInput[];\n graph: {\n nodes: WorkflowSchemaNode[];\n edges: WorkflowSchemaEdge[];\n };\n view?: {\n viewport?: { x: number; y: number; zoom: number };\n };\n};\n\nexport type WorkflowMetadata = {\n id?: string;\n name?: string;\n description?: string;\n createdAt?: number;\n updatedAt?: number;\n author?: string;\n tags?: string[];\n};\n\nexport type WorkflowSchemaNode = {\n id: string;\n /** Registry kind name (e.g. \"memory_store\"). */\n kind: string;\n position: { x: number; y: number };\n label?: string;\n description?: string;\n /**\n * Announced to a person just before / just after this node runs. Omitted\n * entirely when unset, so a graph of ordinary plumbing nodes does not carry\n * a pair of empty keys per node and every diff of a saved graph stays\n * readable.\n */\n startingMsg?: string;\n stoppingMsg?: string;\n config?: Record<string, unknown>;\n /**\n * Resolved ports, written on export.\n *\n * A kind may derive its ports from config (`switch_case` cases,\n * `llm_branch` routes), and that derivation is a JavaScript function — a\n * runtime in another language cannot execute it. Without the resolved ports\n * in the document, the PHP twin sees no declared outputs and falls back to a\n * single `out`, so every branch edge in an exported flow silently stops\n * firing. Serializing them keeps the schema self-describing and preserves\n * the cross-runtime guarantee: same JSON in, same routing out.\n *\n * Optional and additive — a hand-written schema may omit them, and each\n * runtime then falls back to its own kind registry.\n */\n inputs?: PortDescriptor[];\n outputs?: PortDescriptor[];\n /**\n * Node grouping and visual layout — additive + optional. `parentId`/`extent`\n * say which container a node sits in (swimlanes); `width`/`height` carry an\n * explicit (resized) size; `style` carries inline presentation.\n *\n * **`parentId` is NOT decoration, and a runtime that drops it is wrong.** It\n * decides which terminal a node talks to — a terminal lane owns one session\n * and membership is this field, deliberately, so there is no second copy of\n * the grouping in each node's config to drift from what the canvas shows.\n *\n * This comment used to say these fields exist \"purely for the canvas\", so a\n * runtime that only walks edges and ports could ignore all of them. The\n * Python twin read that literally and carried none of them: a graph loaded\n * there and saved back lost every grouping a person had drawn, silently. The\n * sentence was true when it was written and became false without being\n * revisited, which is the more common way a comment does harm.\n *\n * An older reader that does not know these fields still drops them — that is\n * forward-compatibility, not permission.\n */\n parentId?: string;\n extent?: \"parent\" | [[number, number], [number, number]];\n width?: number;\n height?: number;\n style?: Record<string, unknown>;\n};\n\nexport type WorkflowSchemaEdge = {\n id: string;\n source: string;\n target: string;\n sourceHandle?: string;\n targetHandle?: string;\n label?: string;\n};\n\nexport type ImportIssue = {\n level: \"error\" | \"warning\";\n nodeId?: string;\n edgeId?: string;\n message: string;\n};\n\nexport type ImportResult = {\n graph: FlowGraph;\n issues: ImportIssue[];\n /** True when the import produced a usable graph (errors may have been\n * rewritten to warnings via `lenient: true`, except an unsupported schema\n * version, which is always an error). */\n ok: boolean;\n};\n\n/** Snapshot the in-memory graph as a portable WorkflowSchema. */\nexport function exportWorkflow(\n graph: FlowGraph,\n metadata?: WorkflowMetadata,\n view?: WorkflowSchema[\"view\"],\n): WorkflowSchema {\n return {\n $schema: WORKFLOW_SCHEMA_URL,\n version: WORKFLOW_SCHEMA_VERSION,\n metadata: metadata ? { ...metadata, updatedAt: Date.now() } : undefined,\n // Round-trips, or a saved workflow silently forgets its own contract and\n // every caller's props become \"unknown input\" on the next load.\n ...(graph.inputs && graph.inputs.length > 0 ? { inputs: graph.inputs } : {}),\n graph: {\n nodes: graph.nodes.map(toSchemaNode),\n edges: graph.edges.map(toSchemaEdge),\n },\n view,\n };\n}\n\nfunction toSchemaNode(n: FlowNode): WorkflowSchemaNode {\n const data: any = n.data ?? {};\n const kindName = data.kind ?? n.type ?? \"custom\";\n // Resolve through the same helper the canvas and runtime use, so a\n // config-driven kind writes its ACTUAL ports into the document instead of\n // leaving another language's runtime to guess at them.\n const ports = resolveNodePorts(n, getNodeKind(kindName) ?? undefined);\n const node = n as any;\n return {\n id: n.id,\n kind: kindName,\n position: { x: n.position.x, y: n.position.y },\n label: data.label,\n description: data.description,\n ...(typeof data.startingMsg === \"string\" && data.startingMsg !== \"\" ? { startingMsg: data.startingMsg } : {}),\n ...(typeof data.stoppingMsg === \"string\" && data.stoppingMsg !== \"\" ? { stoppingMsg: data.stoppingMsg } : {}),\n config: data.config,\n inputs: ports.inputs,\n outputs: ports.outputs,\n // Visual layout — only when explicitly set (never persist auto-`measured`\n // dimensions, which are derived, not authored).\n ...(node.parentId ? { parentId: node.parentId } : {}),\n ...(node.extent ? { extent: node.extent } : {}),\n ...(typeof node.width === \"number\" ? { width: node.width } : {}),\n ...(typeof node.height === \"number\" ? { height: node.height } : {}),\n ...(node.style ? { style: node.style } : {}),\n };\n}\n\nfunction toSchemaEdge(e: FlowEdge): WorkflowSchemaEdge {\n return {\n id: e.id,\n source: e.source,\n target: e.target,\n sourceHandle: e.sourceHandle ?? undefined,\n targetHandle: e.targetHandle ?? undefined,\n label: typeof e.label === \"string\" ? e.label : undefined,\n };\n}\n\nexport type ImportOptions = {\n /** When true, unknown kinds become warnings + a \"custom\" placeholder\n * instead of errors. Default false. It never softens the schema version:\n * a document that is not `version: 1` (after migration) is refused either\n * way, because no runtime can honour a format it does not know. */\n lenient?: boolean;\n};\n\n/** A migration step: takes a version-N document to version N+1. */\nexport type MigrationStep = (schema: Record<string, unknown>) => Record<string, unknown>;\n\n/**\n * Every migration step, keyed by the version it upgrades FROM.\n *\n * Empty today because v1 is current — when a BREAKING bump lands, add the step\n * here and every stored document upgrades on read, in this runtime and its\n * PHP and Python twins.\n */\nexport const MIGRATIONS: Record<number, MigrationStep> = {};\n\n/**\n * Migrate a raw schema object up to the current version, as far as it can go.\n *\n * Additive changes need no migration — an older document simply lacks the newer\n * optional fields. This is the seam for a future BREAKING bump, and\n * `importWorkflow` runs it before validating the version.\n *\n * ## The three rules, each with a reason\n *\n * - **A PAST version migrates forward**, step by step, to the current one.\n * - **A FUTURE version is left ALONE.** We cannot know what a later schema\n * means, and migrating downward would be guessing. Untouched hands it to the\n * version check, which reports it honestly.\n * - **A GAP in the table is left alone too.** A missing step is not a licence\n * to guess.\n *\n * ## Why `steps` is a parameter\n *\n * With only v1 in existence there is no old document to migrate, so a seam\n * tested against the built-in (empty) table is a check that CANNOT fail — it\n * would pass identically against a function that returned its input untouched,\n * which is what this was until the twins needed the same seam.\n *\n * The PHP and Python runtimes carry the identical shape. That mattered more\n * than it sounds: they had no migration at all and errored on any version\n * mismatch, so a v2 bump would have made every stored Op unreadable on exactly\n * the runtimes where durable runs resume.\n */\nexport function migrateSchema(\n schema: unknown,\n steps: Record<number, MigrationStep> = MIGRATIONS,\n): unknown {\n if (!schema || typeof schema !== \"object\") return schema;\n\n const doc = schema as Record<string, unknown>;\n let version = doc.version;\n\n if (typeof version !== \"number\" || !Number.isInteger(version) || version >= WORKFLOW_SCHEMA_VERSION) {\n return schema;\n }\n\n let out = doc;\n while (version < WORKFLOW_SCHEMA_VERSION) {\n const step = steps[version];\n if (!step) return out;\n\n out = step(out);\n version += 1;\n out.version = version;\n }\n\n return out;\n}\n\n/**\n * Hydrate a schema into runtime FlowGraph + validate kinds/configs against\n * the registry. Reports issues for unknown kinds, missing required config,\n * and dangling edges.\n */\nexport function importWorkflow(schema: unknown, options: ImportOptions = {}): ImportResult {\n const issues: ImportIssue[] = [];\n const lenient = options.lenient === true;\n schema = migrateSchema(schema);\n\n if (!schema || typeof schema !== \"object\") {\n return { ok: false, graph: { nodes: [], edges: [] }, issues: [{ level: \"error\", message: \"Schema is not an object.\" }] };\n }\n const s = schema as Partial<WorkflowSchema>;\n // NEVER softened by `lenient`. That flag is about unknown VOCABULARY (a kind\n // this host has not registered); a version is the format itself, and a\n // runtime cannot honour a format it does not know. It used to become a\n // warning, and fancy-flow-php imports leniently on every run(), so one\n // versionless document ran in Laravel and was refused by a default (strict)\n // import here. Past versions were migrated above, so anything still unequal\n // is refused.\n if (s.version !== WORKFLOW_SCHEMA_VERSION) {\n issues.push({\n level: \"error\",\n message: `Unsupported workflow schema version: ${s.version} (expected ${WORKFLOW_SCHEMA_VERSION})`,\n });\n return { ok: false, graph: { nodes: [], edges: [] }, issues };\n }\n\n const rawNodes = s.graph?.nodes ?? [];\n const rawEdges = s.graph?.edges ?? [];\n\n const nodes: FlowNode[] = rawNodes.map((n) => {\n const kind = getNodeKind(n.kind);\n if (!kind) {\n issues.push({\n level: lenient ? \"warning\" : \"error\",\n nodeId: n.id,\n message: `Unknown kind \"${n.kind}\" — register it before importing.`,\n });\n }\n const config = n.config ?? (kind ? defaultConfigFor(kind) : {});\n if (kind) {\n for (const iss of validateConfig(kind, config)) {\n issues.push({ level: \"warning\", nodeId: n.id, message: `${iss.key}: ${iss.message}` });\n }\n }\n // Canonicalise on the way in: a document may carry a pre-namespace id, and\n // rewriting it here means the graph converges on the canonical id the next\n // time it is saved, rather than carrying the ambiguous name forever.\n const kindId = kind?.name ?? n.kind;\n return {\n id: n.id,\n type: kindId,\n position: { x: n.position?.x ?? 0, y: n.position?.y ?? 0 },\n // Rehydrate visual layout onto the node's top level (where xyflow reads it).\n ...(n.parentId ? { parentId: n.parentId } : {}),\n ...(n.extent ? { extent: n.extent } : {}),\n ...(typeof n.width === \"number\" ? { width: n.width } : {}),\n ...(typeof n.height === \"number\" ? { height: n.height } : {}),\n ...(n.style ? { style: n.style } : {}),\n data: {\n kind: kindId,\n label: n.label ?? kind?.label ?? n.kind,\n description: n.description,\n ...(n.startingMsg ? { startingMsg: n.startingMsg } : {}),\n ...(n.stoppingMsg ? { stoppingMsg: n.stoppingMsg } : {}),\n config,\n // Carry serialized ports back onto the node so a round-trip is stable\n // and an unknown kind still routes the way the document described.\n ...(n.inputs ? { inputs: n.inputs } : {}),\n ...(n.outputs ? { outputs: n.outputs } : {}),\n } as any,\n };\n });\n\n const nodeIds = new Set(nodes.map((n) => n.id));\n const edges: FlowEdge[] = rawEdges\n .map((e) => {\n if (!nodeIds.has(e.source)) {\n issues.push({ level: \"warning\", edgeId: e.id, message: `Edge source \"${e.source}\" not found.` });\n return null;\n }\n if (!nodeIds.has(e.target)) {\n issues.push({ level: \"warning\", edgeId: e.id, message: `Edge target \"${e.target}\" not found.` });\n return null;\n }\n return {\n id: e.id,\n source: e.source,\n target: e.target,\n sourceHandle: e.sourceHandle,\n targetHandle: e.targetHandle,\n label: e.label,\n } as FlowEdge;\n })\n .filter((e): e is FlowEdge => e !== null);\n\n // WIRING, not merely dataflow: a node no edge reaches and that reaches no\n // edge, and an edge reading from a node that publishes nothing.\n //\n // Deliberately AFTER the edge loop, so it sees the same edges the engine will\n // -- a dangling edge is dropped with a warning above, and running this first\n // would let a dropped edge count as a connection.\n //\n // Deliberately NOT gated on `lenient`. That flag is about unknown VOCABULARY\n // (a kind this host has not registered), never about wiring.\n issues.push(...checkGraphConnectivity({ nodes, edges }));\n\n const ok = issues.every((i) => i.level !== \"error\");\n // The declaration comes back with the graph. Dropping it on import would be\n // the worse half of losing it on export: the document still says what it\n // accepts, the loaded graph does not, and every prop a caller passes becomes\n // \"unknown input\" — an error pointing at the caller for a bug in the loader.\n const declaredInputs = Array.isArray(s.inputs)\n ? (s.inputs as WorkflowInput[]).filter(\n (input): input is WorkflowInput =>\n input !== null && typeof input === \"object\" && typeof (input as WorkflowInput).name === \"string\",\n )\n : undefined;\n\n return {\n ok,\n graph: {\n nodes,\n edges,\n ...(declaredInputs && declaredInputs.length > 0 ? { inputs: declaredInputs } : {}),\n },\n issues,\n };\n}\n\n/** Convenience: serialize a schema as a downloadable JSON Blob. */\nexport function workflowToBlob(schema: WorkflowSchema): Blob {\n return new Blob([JSON.stringify(schema, null, 2)], { type: \"application/json\" });\n}\n"]}