@pipelex/mthds-ui 0.14.0 → 0.15.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.
- package/dist/{chunk-V4FKGLKA.js → chunk-O62372BD.js} +7 -4
- package/dist/chunk-O62372BD.js.map +1 -0
- package/dist/chunk-QD5YDMWV.js +1 -0
- package/dist/{chunk-GS2KODND.js → chunk-YC7TW3BW.js} +16 -2
- package/dist/chunk-YC7TW3BW.js.map +1 -0
- package/dist/graph/index.d.ts +3 -2
- package/dist/graph/index.js +7 -3
- package/dist/graph/react/index.d.ts +2 -2
- package/dist/graph/react/index.js +3 -3
- package/dist/graph/react/index.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +7 -3
- package/dist/pipeRefs-BQJO5nh5.d.ts +19 -0
- package/dist/standalone/graph-standalone.html +9 -9
- package/dist/standalone/graph-viewer.js +9 -9
- package/dist/static-graph/index.d.ts +16 -2
- package/dist/static-graph/index.js +31 -13
- package/dist/static-graph/index.js.map +1 -1
- package/dist/{types-CIH1Ae16.d.ts → types-DFIZ_rx6.d.ts} +9 -5
- package/package.json +1 -1
- package/dist/chunk-GS2KODND.js.map +0 -1
- package/dist/chunk-LJQS5ZNA.js +0 -1
- package/dist/chunk-V4FKGLKA.js.map +0 -1
- /package/dist/{chunk-LJQS5ZNA.js.map → chunk-QD5YDMWV.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/static-graph/types.ts","../../src/static-graph/conceptRefs.ts","../../src/static-graph/parseMthdsBundle.ts","../../src/static-graph/normalizePipe.ts","../../src/static-graph/mergeBundles.ts","../../src/static-graph/buildStaticGraphSpec.ts","../../src/static-graph/validationIssues.ts"],"sourcesContent":["// ─── Static method-graph module: domain types ───────────────────────────────\n// Pure TypeScript, no React. This module parses raw `.mthds` TOML text into\n// blueprint-shaped bundles, reusing the `Pipe*Blueprint` registry types from\n// `@graph/types` so the parsed entries can feed a GraphSpec `pipe_registry`\n// directly. Parsing is lenient: half-written bundles produce partial results\n// plus non-fatal diagnostics, never exceptions.\n\nimport type { ConceptInfo, PipeBlueprintUnion } from \"@graph/types\";\n\n// ─── Diagnostics ─────────────────────────────────────────────────────────────\n\nexport type DiagnosticSeverity = \"error\" | \"warning\";\n\nexport type DiagnosticCode =\n | \"toml-parse-error\"\n | \"missing-domain\"\n | \"invalid-bundle-shape\"\n | \"invalid-concept-entry\"\n | \"invalid-pipe-entry\"\n | \"unknown-pipe-type\"\n | \"invalid-concept-ref\"\n | \"missing-pipe-output\"\n | \"invalid-sub-pipe\"\n | \"incomplete-batch-spec\"\n | \"duplicate-concept\"\n | \"duplicate-pipe\"\n | \"unresolved-pipe-ref\"\n | \"cyclic-pipe-ref\"\n | \"missing-main-pipe\"\n | \"no-entry-pipe\"\n | \"conflicting-input-concept\";\n\n/**\n * A non-fatal note collected while parsing or merging. `error` means a whole\n * unit could not be interpreted (unparseable TOML, a skipped pipe); `warning`\n * means something was tolerated with a fallback (missing output, bad ref).\n */\nexport interface Diagnostic {\n severity: DiagnosticSeverity;\n code: DiagnosticCode;\n message: string;\n /** TOML-style locator for the offending entry, e.g. `pipe.analyze_candidate.output`. */\n path?: string;\n}\n\n// ─── Parsed bundle ───────────────────────────────────────────────────────────\n\n/**\n * One `.mthds` file, parsed and normalized. Pipes are narrowed to the same\n * `PipeBlueprintUnion` shapes the pipelex runtime serializes into GraphSpec\n * `pipe_registry`, and concepts to `ConceptInfo` — no parallel type universe.\n * Field names mirror the TOML bundle header keys.\n */\nexport interface ParsedBundle {\n domain: string | null;\n description: string | null;\n main_pipe: string | null;\n system_prompt: string | null;\n /** Concepts declared in this bundle, keyed by bare concept code. */\n concepts: Record<string, ConceptInfo>;\n /** Pipes declared in this bundle, keyed by bare pipe code. */\n pipes: Record<string, PipeBlueprintUnion>;\n}\n\nexport interface ParseMthdsBundleResult {\n bundle: ParsedBundle;\n diagnostics: Diagnostic[];\n}\n\n// ─── Merged method set ───────────────────────────────────────────────────────\n\n/** Namespace of one domain after merging bundles: concepts and pipes by bare code. */\nexport interface DomainNamespace {\n domain: string;\n concepts: Record<string, ConceptInfo>;\n pipes: Record<string, PipeBlueprintUnion>;\n}\n\n/**\n * The merged namespace of a method package: every parsed bundle grouped by\n * domain, with duplicate codes resolved keep-first (plus a diagnostic).\n * `mainDomain` / `mainPipe` come as a pair from the first bundle declaring\n * `main_pipe` (falling back to the first domained bundle when none does) —\n * the walk entry point for the static graph builder. `description` comes from\n * the first bundle that declares it.\n */\nexport interface MergedMethodSet {\n domains: Record<string, DomainNamespace>;\n mainDomain: string | null;\n mainPipe: string | null;\n description: string | null;\n diagnostics: Diagnostic[];\n}\n\n/** Namespace used for bundles that declare no `domain` (a legal WIP state). */\nexport const UNKNOWN_DOMAIN = \"unknown\";\n\n// ─── Narrowing helpers (shared by the parsing modules) ───────────────────────\n\n/**\n * True for plain tables only — rejects arrays, class instances and dates\n * (smol-toml emits `TomlDate` objects for TOML datetime values).\n */\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\nexport function strOrNull(value: unknown): string | null {\n return typeof value === \"string\" && value.length > 0 ? value : null;\n}\n\nexport function intOrNull(value: unknown): number | null {\n return typeof value === \"number\" && Number.isInteger(value) ? value : null;\n}\n\nexport function boolOrNull(value: unknown): boolean | null {\n return typeof value === \"boolean\" ? value : null;\n}\n","// ─── Concept reference parsing and resolution ────────────────────────────────\n// A concept ref in MTHDS TOML is `Code`, `domain.Code`, optionally suffixed\n// with a multiplicity marker: `Code[]` (many) or `Code[N]` (exactly N).\n// Resolution follows the spec's namespace rules: bare refs resolve in the\n// current bundle first, then the native domain; qualified refs name their\n// domain explicitly. Anything unresolved becomes a best-effort stub — this\n// module never throws on content.\n\nimport type { ConceptInfo, StuffSpecInfo } from \"@graph/types\";\n\nexport const NATIVE_DOMAIN = \"native\";\n\n/**\n * The native concept catalog (mirrors pipelex `NativeConceptCode`). Descriptions\n * are display-only stand-ins — the runtime's exact wording is not part of the\n * contract. Structure class names follow the runtime's `<Code>Content` rule.\n */\nconst NATIVE_CONCEPT_DESCRIPTIONS: Record<string, string> = {\n Dynamic: \"Dynamically typed content\",\n Text: \"A text\",\n Image: \"An image\",\n Document: \"A document\",\n Html: \"HTML content\",\n TextAndImages: \"A text with images\",\n Number: \"A number\",\n Page: \"The content of a page of a document\",\n JSON: \"JSON content\",\n SearchResult: \"A search result\",\n Anything: \"Anything\",\n Composite: \"A named composition of multiple contents\",\n};\n\nexport const NATIVE_CONCEPT_CODES: ReadonlySet<string> = new Set(\n Object.keys(NATIVE_CONCEPT_DESCRIPTIONS),\n);\n\n// ─── Ref parsing ─────────────────────────────────────────────────────────────\n\nexport interface ConceptRefParts {\n /** Explicit domain qualifier (`recruitment` in `recruitment.Profile`), or null for bare refs. */\n domain: string | null;\n code: string;\n /** `[]` → true (many), `[N]` → N, no suffix → null (single). */\n multiplicity: number | boolean | null;\n}\n\nconst CONCEPT_REF_RE = /^(?:([A-Za-z0-9_][A-Za-z0-9_.]*)\\.)?([A-Za-z0-9_]+)(?:\\[(\\d*)\\])?$/;\n\n/** Parse a concept ref string into its parts. Returns null when the ref is not interpretable. */\nexport function parseConceptRef(raw: unknown): ConceptRefParts | null {\n if (typeof raw !== \"string\") return null;\n const match = CONCEPT_REF_RE.exec(raw.trim());\n if (!match) return null;\n const [, domain, code, multiplicity] = match;\n return {\n domain: domain ?? null,\n code,\n multiplicity:\n multiplicity === undefined\n ? null\n : multiplicity === \"\"\n ? true\n : Number.parseInt(multiplicity, 10),\n };\n}\n\n// ─── Resolution to ConceptInfo ───────────────────────────────────────────────\n\n/**\n * Synthetic structure class name for a non-native concept, mirroring the\n * runtime's `make_qualified_structure_class_name`: dots in hierarchical\n * domain codes are replaced with interpuncts (·) to keep the name a valid,\n * collision-free identifier (`a.b` → `a·b`, distinct from `a_b`).\n */\nexport function qualifiedStructureClassName(domain: string, code: string): string {\n return `${domain.replaceAll(\".\", \"·\")}__${code}`;\n}\n\nexport function nativeConceptInfo(code: string): ConceptInfo {\n return {\n code,\n domain_code: NATIVE_DOMAIN,\n description: NATIVE_CONCEPT_DESCRIPTIONS[code] ?? code,\n structure_class_name: `${code}Content`,\n refines: null,\n };\n}\n\n/**\n * Best-effort info for a concept that is referenced but not declared in the\n * material at hand — an implicit concept, a WIP ref, or a cross-bundle ref\n * that `mergeBundles` may still enrich later.\n */\nfunction stubConceptInfo(code: string, domain: string): ConceptInfo {\n return {\n code,\n domain_code: domain,\n description: \"\",\n structure_class_name: qualifiedStructureClassName(domain, code),\n refines: null,\n };\n}\n\n/**\n * Resolve parsed ref parts against the current bundle. `localConcepts` holds\n * the bundle's declared concepts keyed by bare code.\n */\nexport function resolveConceptInfo(\n parts: ConceptRefParts,\n currentDomain: string,\n localConcepts: Record<string, ConceptInfo>,\n): ConceptInfo {\n if (parts.domain === NATIVE_DOMAIN) {\n return NATIVE_CONCEPT_CODES.has(parts.code)\n ? nativeConceptInfo(parts.code)\n : stubConceptInfo(parts.code, NATIVE_DOMAIN);\n }\n if (parts.domain !== null && parts.domain !== currentDomain) {\n return stubConceptInfo(parts.code, parts.domain);\n }\n const local = localConcepts[parts.code];\n if (local) return local;\n if (parts.domain === null && NATIVE_CONCEPT_CODES.has(parts.code)) {\n return nativeConceptInfo(parts.code);\n }\n return stubConceptInfo(parts.code, currentDomain);\n}\n\n/** Resolve a raw concept ref string straight to a `StuffSpecInfo`, or null when unparseable. */\nexport function resolveStuffSpec(\n raw: unknown,\n currentDomain: string,\n localConcepts: Record<string, ConceptInfo>,\n): StuffSpecInfo | null {\n const parts = parseConceptRef(raw);\n if (parts === null) return null;\n return {\n concept: resolveConceptInfo(parts, currentDomain, localConcepts),\n multiplicity: parts.multiplicity,\n };\n}\n","// ─── parseMthdsBundle: `.mthds` TOML text → ParsedBundle ─────────────────────\n// The single entry point for turning one raw `.mthds` string into a\n// blueprint-shaped bundle. Lenient in the `validateGraphSpec` house style but\n// inverted: instead of failing loudly on contract violations, it tolerates\n// missing or partial sections, skips what it cannot interpret, and records\n// non-fatal diagnostics — the whole point is rendering methods while they are\n// being written. It never throws on content; even unparseable TOML becomes an\n// `error` diagnostic with an empty bundle.\n\nimport { parse as parseToml } from \"smol-toml\";\n\nimport type { ConceptInfo, PipeBlueprintUnion } from \"@graph/types\";\n\nimport {\n NATIVE_CONCEPT_CODES,\n NATIVE_DOMAIN,\n parseConceptRef,\n qualifiedStructureClassName,\n} from \"./conceptRefs\";\nimport { normalizePipe } from \"./normalizePipe\";\nimport type { Diagnostic, ParseMthdsBundleResult, ParsedBundle } from \"./types\";\nimport { isPlainObject, strOrNull, UNKNOWN_DOMAIN } from \"./types\";\n\n// ─── Concept structure → JSON schema (display-only, best-effort) ─────────────\n\nconst FIELD_TYPE_TO_JSON: Record<string, Record<string, unknown>> = {\n text: { type: \"string\" },\n integer: { type: \"integer\" },\n number: { type: \"number\" },\n boolean: { type: \"boolean\" },\n date: { type: \"string\", format: \"date-time\" },\n list: { type: \"array\" },\n dict: { type: \"object\" },\n concept: { type: \"object\" },\n};\n\nfunction fieldSchema(spec: Record<string, unknown>): Record<string, unknown> {\n const typeName = strOrNull(spec.type) ?? \"text\";\n const schema: Record<string, unknown> = {\n ...(FIELD_TYPE_TO_JSON[typeName] ?? { type: \"string\" }),\n };\n const description = strOrNull(spec.description);\n if (description !== null) schema.description = description;\n if (typeName === \"list\") {\n const itemType = strOrNull(spec.item_type);\n schema.items = itemType !== null ? { ...(FIELD_TYPE_TO_JSON[itemType] ?? {}) } : {};\n }\n if (Array.isArray(spec.choices)) {\n schema.enum = spec.choices.filter((choice) => typeof choice === \"string\");\n }\n if (spec.default_value !== undefined && spec.default_value !== null) {\n schema.default = spec.default_value;\n }\n return schema;\n}\n\n/**\n * Derive a lightweight JSON schema from a `[concept.X.structure]` table so\n * concept detail panels have fields to show. Deliberately simpler than the\n * pydantic-generated schema the runtime emits (no anyOf-null wrapping, no\n * per-field titles) — this is presentation data, not a contract.\n */\nfunction deriveJsonSchema(\n structure: unknown,\n title: string,\n description: string,\n): Record<string, unknown> | undefined {\n if (!isPlainObject(structure)) return undefined;\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n for (const [name, spec] of Object.entries(structure)) {\n if (typeof spec === \"string\") {\n properties[name] = { type: \"string\", description: spec };\n continue;\n }\n if (!isPlainObject(spec)) continue;\n properties[name] = fieldSchema(spec);\n if (spec.required === true) required.push(name);\n }\n return {\n title,\n type: \"object\",\n description,\n properties,\n ...(required.length > 0 ? { required } : {}),\n };\n}\n\n// ─── Concept table parsing ───────────────────────────────────────────────────\n\n/** Qualify a `refines` ref the way the runtime registry does (`Text` → `native.Text`). */\nfunction qualifyRefines(\n raw: unknown,\n domain: string,\n declaredCodes: ReadonlySet<string>,\n): string | null {\n const parts = parseConceptRef(raw);\n if (parts === null) return null;\n if (parts.domain !== null) return `${parts.domain}.${parts.code}`;\n if (!declaredCodes.has(parts.code) && NATIVE_CONCEPT_CODES.has(parts.code)) {\n return `${NATIVE_DOMAIN}.${parts.code}`;\n }\n return `${domain}.${parts.code}`;\n}\n\nfunction parseConcepts(\n raw: unknown,\n domain: string,\n diagnostics: Diagnostic[],\n): Record<string, ConceptInfo> {\n const concepts: Record<string, ConceptInfo> = {};\n if (raw === undefined) return concepts;\n if (!isPlainObject(raw)) {\n diagnostics.push({\n severity: \"warning\",\n code: \"invalid-bundle-shape\",\n message: \"concept section is not a table — ignored\",\n path: \"concept\",\n });\n return concepts;\n }\n const declaredCodes: ReadonlySet<string> = new Set(Object.keys(raw));\n for (const [code, entry] of Object.entries(raw)) {\n if (typeof entry === \"string\") {\n // Shorthand form: `Concept = \"description\"`.\n concepts[code] = {\n code,\n domain_code: domain,\n description: entry,\n structure_class_name: qualifiedStructureClassName(domain, code),\n refines: null,\n };\n continue;\n }\n if (!isPlainObject(entry)) {\n diagnostics.push({\n severity: \"warning\",\n code: \"invalid-concept-entry\",\n message: `concept \"${code}\" is neither a table nor a description string — skipped`,\n path: `concept.${code}`,\n });\n continue;\n }\n const description = strOrNull(entry.description) ?? \"\";\n // A `structure = \"ClassName\"` string names an existing structure class;\n // the table form gets the runtime's `<domain>__<Code>` synthetic name.\n const structureClassName =\n strOrNull(entry.structure) ?? qualifiedStructureClassName(domain, code);\n concepts[code] = {\n code,\n domain_code: domain,\n description,\n structure_class_name: structureClassName,\n refines: qualifyRefines(entry.refines, domain, declaredCodes),\n json_schema: deriveJsonSchema(entry.structure, structureClassName, description),\n };\n }\n return concepts;\n}\n\n// ─── Bundle parsing ──────────────────────────────────────────────────────────\n\nfunction emptyBundle(): ParsedBundle {\n return {\n domain: null,\n description: null,\n main_pipe: null,\n system_prompt: null,\n concepts: {},\n pipes: {},\n };\n}\n\n/**\n * Parse one `.mthds` TOML string. Returns whatever could be interpreted plus\n * the diagnostics collected along the way — never throws.\n */\nexport function parseMthdsBundle(tomlText: string): ParseMthdsBundleResult {\n const diagnostics: Diagnostic[] = [];\n let root: Record<string, unknown>;\n try {\n root = parseToml(tomlText);\n } catch (error) {\n diagnostics.push({\n severity: \"error\",\n code: \"toml-parse-error\",\n message: error instanceof Error ? error.message : String(error),\n });\n return { bundle: emptyBundle(), diagnostics };\n }\n\n const bundle = emptyBundle();\n bundle.domain = strOrNull(root.domain);\n bundle.description = strOrNull(root.description);\n bundle.main_pipe = strOrNull(root.main_pipe);\n bundle.system_prompt = strOrNull(root.system_prompt);\n if (bundle.domain === null) {\n diagnostics.push({\n severity: \"warning\",\n code: \"missing-domain\",\n message: `bundle declares no domain — using \"${UNKNOWN_DOMAIN}\"`,\n path: \"domain\",\n });\n }\n const domain = bundle.domain ?? UNKNOWN_DOMAIN;\n\n bundle.concepts = parseConcepts(root.concept, domain, diagnostics);\n\n const pipeTable = root.pipe;\n if (pipeTable !== undefined) {\n if (!isPlainObject(pipeTable)) {\n diagnostics.push({\n severity: \"warning\",\n code: \"invalid-bundle-shape\",\n message: \"pipe section is not a table — ignored\",\n path: \"pipe\",\n });\n } else {\n const ctx = { domain, concepts: bundle.concepts, diagnostics };\n for (const [code, entry] of Object.entries(pipeTable)) {\n if (!isPlainObject(entry)) {\n diagnostics.push({\n severity: \"error\",\n code: \"invalid-pipe-entry\",\n message: `pipe \"${code}\" is not a table — skipped`,\n path: `pipe.${code}`,\n });\n continue;\n }\n const pipe: PipeBlueprintUnion | null = normalizePipe(code, entry, ctx);\n if (pipe !== null) bundle.pipes[code] = pipe;\n }\n }\n }\n\n return { bundle, diagnostics };\n}\n","// ─── Pipe normalization: authored TOML shape → registry blueprint shape ─────\n// The authoring surface (mthds_schema.json, checked in under data/schema/)\n// and the runtime-serialized registry shape (`PipeBlueprintUnion` in\n// `@graph/types`) name things differently: `steps` vs `sequential_sub_pipes`,\n// `model` vs `llm_choices`, `prompt` vs `prompt_blueprint`, … This module maps\n// the former to the latter, leniently: uninterpretable pieces are skipped with\n// a diagnostic, and only a pipe without a usable `type` is dropped entirely.\n\nimport type {\n ConceptInfo,\n PipeBlueprintUnion,\n PipeComposeConstructBlueprint,\n PipeComposeConstructField,\n PipeType,\n StuffSpecInfo,\n SubPipeSpec,\n TemplateBlueprint,\n} from \"@graph/types\";\nimport { KNOWN_PIPE_TYPES } from \"@graph/types\";\n\nimport { NATIVE_DOMAIN, nativeConceptInfo, resolveStuffSpec } from \"./conceptRefs\";\nimport type { Diagnostic } from \"./types\";\nimport { boolOrNull, intOrNull, isPlainObject, strOrNull } from \"./types\";\n\nexport interface NormalizePipeContext {\n domain: string;\n /** The bundle's declared concepts, keyed by bare code. */\n concepts: Record<string, ConceptInfo>;\n diagnostics: Diagnostic[];\n}\n\n// ─── Small shared builders ───────────────────────────────────────────────────\n\nfunction makeTemplate(template: string, category: string): TemplateBlueprint {\n return { template, templating_style: null, category, extra_context: null };\n}\n\n/**\n * Extract a display string from a model choice, which the authoring surface\n * allows as a plain handle (`\"gpt-5\"`), an inline setting (`{ model = … }`),\n * or a model reference (`{ name = … }`).\n */\nfunction modelToString(value: unknown): string | null {\n if (typeof value === \"string\") return strOrNull(value);\n if (isPlainObject(value)) {\n return strOrNull(value.model) ?? strOrNull(value.raw) ?? strOrNull(value.name);\n }\n return null;\n}\n\nfunction stringArrayOrNull(value: unknown): string[] | null {\n if (!Array.isArray(value)) return null;\n return value.filter((item): item is string => typeof item === \"string\");\n}\n\n// ─── IO normalization ────────────────────────────────────────────────────────\n\nfunction normalizeInputs(\n raw: unknown,\n pipeCode: string,\n ctx: NormalizePipeContext,\n): Record<string, StuffSpecInfo> {\n const inputs: Record<string, StuffSpecInfo> = {};\n if (raw === undefined || raw === null) return inputs;\n if (!isPlainObject(raw)) {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"invalid-pipe-entry\",\n message: `pipe \"${pipeCode}\": inputs is not a table — ignored`,\n path: `pipe.${pipeCode}.inputs`,\n });\n return inputs;\n }\n for (const [name, ref] of Object.entries(raw)) {\n const spec = resolveStuffSpec(ref, ctx.domain, ctx.concepts);\n if (spec === null) {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"invalid-concept-ref\",\n message: `pipe \"${pipeCode}\": input \"${name}\" has an uninterpretable concept ref — skipped`,\n path: `pipe.${pipeCode}.inputs.${name}`,\n });\n continue;\n }\n inputs[name] = spec;\n }\n return inputs;\n}\n\nfunction normalizeOutput(raw: unknown, pipeCode: string, ctx: NormalizePipeContext): StuffSpecInfo {\n const spec = resolveStuffSpec(raw, ctx.domain, ctx.concepts);\n if (spec !== null) return spec;\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"missing-pipe-output\",\n message: `pipe \"${pipeCode}\": missing or uninterpretable output — assuming native.Anything`,\n path: `pipe.${pipeCode}.output`,\n });\n return { concept: nativeConceptInfo(\"Anything\"), multiplicity: null };\n}\n\n// ─── Sub-pipe normalization (sequence steps, parallel branches) ──────────────\n\nfunction normalizeSubPipe(\n raw: unknown,\n pipeCode: string,\n path: string,\n ctx: NormalizePipeContext,\n): SubPipeSpec | null {\n if (!isPlainObject(raw) || strOrNull(raw.pipe) === null) {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"invalid-sub-pipe\",\n message: `pipe \"${pipeCode}\": sub-pipe entry without a \"pipe\" ref — skipped`,\n path,\n });\n return null;\n }\n const batchOver = strOrNull(raw.batch_over);\n const batchAs = strOrNull(raw.batch_as);\n let batchParams: SubPipeSpec[\"batch_params\"] = null;\n if (batchOver !== null && batchAs !== null) {\n batchParams = { input_list_stuff_name: batchOver, input_item_stuff_name: batchAs };\n } else if (batchOver !== null || batchAs !== null) {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"incomplete-batch-spec\",\n message:\n `pipe \"${pipeCode}\": sub-pipe \"${raw.pipe as string}\" sets only one of ` +\n `batch_over/batch_as — batching ignored`,\n path,\n });\n }\n // Mirrors the runtime SubPipeFactory: explicit nb_output wins, then\n // multiple_output, and a batched step is implicitly multiple.\n let outputMultiplicity: SubPipeSpec[\"output_multiplicity\"] =\n intOrNull(raw.nb_output) ?? (raw.multiple_output === true ? true : null);\n if (batchParams !== null && outputMultiplicity === null) outputMultiplicity = true;\n return {\n pipe_code: raw.pipe as string,\n output_name: strOrNull(raw.result),\n output_multiplicity: outputMultiplicity,\n batch_params: batchParams,\n };\n}\n\nfunction normalizeSubPipeList(\n raw: unknown,\n pipeCode: string,\n key: string,\n ctx: NormalizePipeContext,\n): SubPipeSpec[] {\n if (!Array.isArray(raw)) {\n if (raw !== undefined) {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"invalid-pipe-entry\",\n message: `pipe \"${pipeCode}\": ${key} is not an array — treated as empty`,\n path: `pipe.${pipeCode}.${key}`,\n });\n }\n return [];\n }\n return raw\n .map((entry, index) =>\n normalizeSubPipe(entry, pipeCode, `pipe.${pipeCode}.${key}[${index}]`, ctx),\n )\n .filter((entry): entry is SubPipeSpec => entry !== null);\n}\n\n// ─── Compose construct normalization ─────────────────────────────────────────\n\nfunction normalizeConstructField(value: unknown): PipeComposeConstructField | null {\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\" ||\n Array.isArray(value)\n ) {\n return { method: \"fixed\", fixed_value: value };\n }\n if (isPlainObject(value)) {\n if (typeof value.from === \"string\") {\n return {\n method: \"from_var\",\n from_path: value.from,\n list_to_dict_keyed_by: strOrNull(value.list_to_dict_keyed_by),\n };\n }\n if (typeof value.template === \"string\") {\n return { method: \"template\", template: value.template };\n }\n const nested = normalizeConstruct(value);\n if (nested !== null) return { method: \"nested\", nested };\n }\n return null;\n}\n\nfunction normalizeConstruct(raw: unknown): PipeComposeConstructBlueprint | null {\n if (!isPlainObject(raw)) return null;\n const fields: Record<string, PipeComposeConstructField> = {};\n for (const [name, value] of Object.entries(raw)) {\n const field = normalizeConstructField(value);\n if (field !== null) fields[name] = field;\n }\n return Object.keys(fields).length > 0 ? { fields } : null;\n}\n\n// ─── Per-type normalization ──────────────────────────────────────────────────\n\n/**\n * Normalize one `[pipe.<code>]` table to its registry blueprint shape.\n * Returns null (with a diagnostic) only when the `type` is missing or not a\n * known pipe class — everything else degrades field-by-field.\n */\nexport function normalizePipe(\n code: string,\n raw: Record<string, unknown>,\n ctx: NormalizePipeContext,\n): PipeBlueprintUnion | null {\n const typeValue = raw.type;\n if (typeof typeValue !== \"string\" || !KNOWN_PIPE_TYPES.has(typeValue)) {\n ctx.diagnostics.push({\n severity: \"error\",\n code: \"unknown-pipe-type\",\n message: `pipe \"${code}\": unknown pipe type ${JSON.stringify(typeValue)} — pipe skipped`,\n path: `pipe.${code}.type`,\n });\n return null;\n }\n const type = typeValue as PipeType;\n const base = {\n code,\n domain_code: ctx.domain,\n description: strOrNull(raw.description) ?? \"\",\n inputs: normalizeInputs(raw.inputs, code, ctx),\n output: normalizeOutput(raw.output, code, ctx),\n };\n\n switch (type) {\n case \"PipeSequence\":\n return {\n ...base,\n type,\n pipe_category: \"PipeController\",\n sequential_sub_pipes: normalizeSubPipeList(raw.steps, code, \"steps\", ctx),\n };\n case \"PipeParallel\":\n return {\n ...base,\n type,\n pipe_category: \"PipeController\",\n parallel_sub_pipes: normalizeSubPipeList(raw.branches, code, \"branches\", ctx),\n add_each_output: raw.add_each_output === true,\n combined_output: strOrNull(raw.combined_output),\n };\n case \"PipeCondition\": {\n const outcomeMap: Record<string, string> = {};\n if (isPlainObject(raw.outcomes)) {\n for (const [outcome, pipeRef] of Object.entries(raw.outcomes)) {\n if (typeof pipeRef === \"string\" && pipeRef.length > 0) {\n outcomeMap[outcome] = pipeRef;\n } else {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"invalid-pipe-entry\",\n message: `pipe \"${code}\": outcome \"${outcome}\" is not a pipe ref — skipped`,\n path: `pipe.${code}.outcomes.${outcome}`,\n });\n }\n }\n }\n return {\n ...base,\n type,\n pipe_category: \"PipeController\",\n expression: strOrNull(raw.expression) ?? strOrNull(raw.expression_template) ?? \"\",\n outcome_map: outcomeMap,\n default_outcome: strOrNull(raw.default_outcome) ?? \"\",\n add_alias_from_expression_to: strOrNull(raw.add_alias_from_expression_to),\n };\n }\n case \"PipeBatch\": {\n const branchPipeCode = strOrNull(raw.branch_pipe_code);\n if (branchPipeCode === null) {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"invalid-pipe-entry\",\n message: `pipe \"${code}\": PipeBatch without branch_pipe_code`,\n path: `pipe.${code}.branch_pipe_code`,\n });\n }\n return {\n ...base,\n type,\n pipe_category: \"PipeController\",\n branch_pipe_code: branchPipeCode ?? \"\",\n batch_params: {\n input_list_stuff_name: strOrNull(raw.input_list_name) ?? \"\",\n input_item_stuff_name: strOrNull(raw.input_item_name) ?? \"\",\n },\n };\n }\n case \"PipeLLM\": {\n const systemPrompt = strOrNull(raw.system_prompt);\n const prompt = strOrNull(raw.prompt);\n return {\n ...base,\n type,\n pipe_category: \"PipeOperator\",\n llm_prompt_spec: {\n templating_style: null,\n system_prompt_blueprint:\n systemPrompt === null ? null : makeTemplate(systemPrompt, \"llm_prompt\"),\n prompt_blueprint: prompt === null ? null : makeTemplate(prompt, \"llm_prompt\"),\n user_image_references: null,\n user_document_references: null,\n system_image_references: null,\n system_document_references: null,\n },\n llm_choices: {\n for_text: modelToString(raw.model),\n for_object: modelToString(raw.model_to_structure),\n },\n structuring_method: strOrNull(raw.structuring_method),\n output_multiplicity: null,\n };\n }\n case \"PipeStructure\": {\n const inputNames = Object.keys(base.inputs);\n const llmChoice = isPlainObject(raw.model) ? raw.model : strOrNull(raw.model);\n return {\n ...base,\n type,\n pipe_category: \"PipeOperator\",\n llm_choice: llmChoice,\n text_input_name: inputNames[0] ?? \"text\",\n output_multiplicity: null,\n };\n }\n case \"PipeExtract\": {\n // Mirrors the runtime PipeExtractFactory: the (single) input is either\n // image-like or document-like, and exactly one of the two stuff names is\n // set. Statically, \"compatible with native.Image\" approximates to the\n // concept being Image or refining it; anything else counts as a document.\n const isImageLike = (spec: StuffSpecInfo): boolean =>\n (spec.concept.domain_code === NATIVE_DOMAIN && spec.concept.code === \"Image\") ||\n spec.concept.refines === `${NATIVE_DOMAIN}.Image`;\n const inputEntries = Object.entries(base.inputs);\n const imageInput = inputEntries.find(([, spec]) => isImageLike(spec));\n const documentInput = imageInput === undefined ? inputEntries[0] : undefined;\n return {\n ...base,\n type,\n pipe_category: \"PipeOperator\",\n extract_choice: modelToString(raw.model),\n should_caption_images: raw.page_image_captions === true,\n max_page_images: intOrNull(raw.max_page_images),\n should_include_page_views: raw.page_views === true,\n page_views_dpi: intOrNull(raw.page_views_dpi),\n render_js: boolOrNull(raw.render_js),\n include_raw_html: boolOrNull(raw.include_raw_html),\n image_stuff_name: imageInput?.[0] ?? null,\n document_stuff_name: documentInput?.[0] ?? null,\n };\n }\n case \"PipeSearch\":\n return {\n ...base,\n type,\n pipe_category: \"PipeOperator\",\n search_choice: modelToString(raw.model),\n prompt_blueprint: makeTemplate(strOrNull(raw.prompt) ?? \"\", \"basic\"),\n include_images_override: boolOrNull(raw.include_images),\n max_results_override: intOrNull(raw.max_results),\n from_date: strOrNull(raw.from_date),\n to_date: strOrNull(raw.to_date),\n include_domains: stringArrayOrNull(raw.include_domains),\n exclude_domains: stringArrayOrNull(raw.exclude_domains),\n is_structured_output: false,\n };\n case \"PipeImgGen\": {\n const prompt = strOrNull(raw.prompt);\n const negativePrompt = strOrNull(raw.negative_prompt);\n const seed = intOrNull(raw.seed) ?? (raw.seed === \"auto\" ? \"auto\" : null);\n return {\n ...base,\n type,\n pipe_category: \"PipeOperator\",\n img_gen_prompt_blueprint: {\n prompt_blueprint: prompt === null ? null : makeTemplate(prompt, \"img_gen_prompt\"),\n negative_prompt_blueprint:\n negativePrompt === null ? null : makeTemplate(negativePrompt, \"img_gen_prompt\"),\n image_references: null,\n },\n img_gen_choice: modelToString(raw.model),\n aspect_ratio: strOrNull(raw.aspect_ratio),\n is_raw: boolOrNull(raw.is_raw),\n seed,\n background: strOrNull(raw.background),\n output_format: strOrNull(raw.output_format),\n output_multiplicity:\n typeof base.output.multiplicity === \"number\" ? base.output.multiplicity : 1,\n };\n }\n case \"PipeCompose\": {\n const rawTemplate = raw.template;\n let template: string | null = null;\n let templatingStyle: string | null = null;\n let category = \"basic\";\n let extraContext: Record<string, unknown> | null = null;\n if (typeof rawTemplate === \"string\") {\n template = rawTemplate;\n } else if (isPlainObject(rawTemplate)) {\n template = strOrNull(rawTemplate.template);\n templatingStyle = strOrNull(rawTemplate.templating_style);\n category = strOrNull(rawTemplate.category) ?? category;\n extraContext = isPlainObject(rawTemplate.extra_context) ? rawTemplate.extra_context : null;\n }\n return {\n ...base,\n type,\n pipe_category: \"PipeOperator\",\n template,\n templating_style: templatingStyle,\n category,\n extra_context: extraContext,\n construct_blueprint: normalizeConstruct(raw.construct),\n };\n }\n case \"PipeFunc\":\n return { ...base, type, pipe_category: \"PipeOperator\" };\n case \"PipeSignature\": {\n const signatureFor = strOrNull(raw.signature_for);\n return {\n ...base,\n type,\n pipe_category: null,\n signature_for:\n signatureFor !== null && KNOWN_PIPE_TYPES.has(signatureFor)\n ? (signatureFor as PipeType)\n : null,\n };\n }\n default: {\n const _exhaustive: never = type;\n return _exhaustive;\n }\n }\n}\n","// ─── mergeBundles: ParsedBundle[] → MergedMethodSet ──────────────────────────\n// A method package may span several `.mthds` files; files sharing a domain\n// merge into one namespace. Duplicate codes keep the first declaration and\n// record a diagnostic. After merging, io concept stubs are re-pointed at the\n// declarations that other files contributed (a pipe in file A can reference a\n// concept declared in file B).\n\nimport type { PipeBlueprintUnion, StuffSpecInfo } from \"@graph/types\";\n\nimport type { Diagnostic, DomainNamespace, MergedMethodSet, ParsedBundle } from \"./types\";\nimport { UNKNOWN_DOMAIN } from \"./types\";\n\nfunction enrichPipeConcepts(\n pipe: PipeBlueprintUnion,\n domains: Record<string, DomainNamespace>,\n): PipeBlueprintUnion {\n const enrichSpec = (spec: StuffSpecInfo): StuffSpecInfo => {\n const declared = domains[spec.concept.domain_code]?.concepts[spec.concept.code];\n return declared !== undefined && declared !== spec.concept\n ? { ...spec, concept: declared }\n : spec;\n };\n const inputs: Record<string, StuffSpecInfo> = {};\n for (const [name, spec] of Object.entries(pipe.inputs)) {\n inputs[name] = enrichSpec(spec);\n }\n return { ...pipe, inputs, output: enrichSpec(pipe.output) };\n}\n\n/**\n * Merge parsed bundles into one namespace per domain. Order matters: on\n * duplicate codes the first bundle wins. `mainDomain` and `mainPipe` are taken\n * together from the first bundle declaring `main_pipe`, so a bare entry ref\n * always resolves in its declaring bundle's namespace; when no bundle declares\n * one, `mainDomain` falls back to the first domained bundle. `description`\n * comes from the first bundle that declares it.\n */\nexport function mergeBundles(bundles: ParsedBundle[]): MergedMethodSet {\n const diagnostics: Diagnostic[] = [];\n const domains: Record<string, DomainNamespace> = {};\n let mainDomain: string | null = null;\n let mainPipe: string | null = null;\n let description: string | null = null;\n\n for (const bundle of bundles) {\n const domain = bundle.domain ?? UNKNOWN_DOMAIN;\n const namespace = (domains[domain] ??= { domain, concepts: {}, pipes: {} });\n if (mainDomain === null && bundle.domain !== null) mainDomain = bundle.domain;\n if (mainPipe === null && bundle.main_pipe !== null) {\n mainPipe = bundle.main_pipe;\n // A bare main_pipe must resolve in the namespace of the bundle declaring\n // it, not whichever bundle happened to come first.\n mainDomain = domain;\n }\n if (description === null && bundle.description !== null) description = bundle.description;\n\n for (const [code, concept] of Object.entries(bundle.concepts)) {\n if (code in namespace.concepts) {\n diagnostics.push({\n severity: \"warning\",\n code: \"duplicate-concept\",\n message: `concept \"${domain}.${code}\" declared more than once — keeping the first declaration`,\n path: `concept.${code}`,\n });\n continue;\n }\n namespace.concepts[code] = concept;\n }\n for (const [code, pipe] of Object.entries(bundle.pipes)) {\n if (code in namespace.pipes) {\n diagnostics.push({\n severity: \"warning\",\n code: \"duplicate-pipe\",\n message: `pipe \"${domain}.${code}\" declared more than once — keeping the first declaration`,\n path: `pipe.${code}`,\n });\n continue;\n }\n namespace.pipes[code] = pipe;\n }\n }\n\n for (const namespace of Object.values(domains)) {\n for (const [code, pipe] of Object.entries(namespace.pipes)) {\n namespace.pipes[code] = enrichPipeConcepts(pipe, domains);\n }\n }\n\n return { domains, mainDomain, mainPipe, description, diagnostics };\n}\n","// ─── Static graph builder: MergedMethodSet → GraphSpec ──────────────────────\n// The static walk from the design doc (wip/static-graph-design.md): walk pipe\n// *invocations* starting at the entry pipe, maintaining a scope (the static\n// mirror of working memory), and emit a GraphSpec with `meta.mode: \"static\"`\n// that the existing GraphViewer renders unchanged.\n//\n// Identity is deterministic: node ids are invocation paths\n// (`screening.process_cv/step_2/...`) and stuff digests are the raw strings\n// `<producer_node_id>:<name>` (external inputs: `input:<name>`). The UI treats\n// digests as opaque unique keys, so the raw string — collision-free by\n// construction and readable in snapshots — is preferred over a hash.\n//\n// Everything is best-effort: unresolvable refs skip the child, cycles render\n// as leaves, dependency-alias refs (`alias->pipe`) render as opaque leaf\n// cards. This module never throws on content.\n\nimport type {\n ConceptInfo,\n GraphSpec,\n GraphSpecEdge,\n GraphSpecEdgeKind,\n GraphSpecNode,\n GraphSpecNodeIoItem,\n PipeBatchBlueprint,\n PipeBlueprintUnion,\n PipeConditionBlueprint,\n PipeParallelBlueprint,\n PipeSequenceBlueprint,\n PipeType,\n SubPipeSpec,\n} from \"@graph/types\";\n\nimport { nativeConceptInfo } from \"./conceptRefs\";\nimport { mergeBundles } from \"./mergeBundles\";\nimport { parseMthdsBundle } from \"./parseMthdsBundle\";\nimport type { Diagnostic, DomainNamespace, MergedMethodSet } from \"./types\";\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\nexport interface StaticGraphOptions {\n /**\n * Pipe ref to walk from (`code` or `domain.code`). Defaults to the merged\n * set's `main_pipe`, falling back to a root heuristic (first pipe no other\n * pipe references) when none is declared.\n */\n entryPipe?: string;\n}\n\nexport interface StaticGraphResult {\n spec: GraphSpec;\n diagnostics: Diagnostic[];\n}\n\n/** Build a static GraphSpec from an already-parsed, merged method set. */\nexport function buildStaticGraphSpec(\n set: MergedMethodSet,\n options: StaticGraphOptions = {},\n): StaticGraphResult {\n const diagnostics: Diagnostic[] = [];\n const ctx: WalkCtx = {\n set,\n nodes: [],\n edges: [],\n pipeRegistry: {},\n conceptRegistry: {},\n stuffByDigest: new Map(),\n diagnostics,\n stack: [],\n edgeSeq: 0,\n };\n\n // Registries carry every parsed entry (the dry-run path often ships them\n // empty — populating them is what makes detail panels rich). Registered\n // before the walk so synthetic entries minted during it never clobber a\n // declared one.\n for (const namespace of Object.values(set.domains)) {\n for (const concept of Object.values(namespace.concepts)) registerConcept(ctx, concept);\n for (const pipe of Object.values(namespace.pipes)) {\n ctx.pipeRegistry[`${pipe.domain_code}.${pipe.code}`] = pipe;\n for (const spec of Object.values(pipe.inputs)) registerConcept(ctx, spec.concept);\n registerConcept(ctx, pipe.output.concept);\n }\n }\n\n const entry = pickEntryPipe(set, options.entryPipe ?? null, diagnostics);\n if (entry !== null) {\n walkPipe(ctx, entry.code, entry.domain, `${entry.domain}.${entry.code}`, null, new Map(), {\n resultName: null,\n outputMultiplicity: null,\n });\n }\n\n const spec: GraphSpec = {\n nodes: ctx.nodes,\n edges: ctx.edges,\n meta: { format: \"mthds\", mode: \"static\" },\n pipe_registry: ctx.pipeRegistry,\n concept_registry: ctx.conceptRegistry,\n };\n if (entry !== null) {\n spec.pipeline_ref = { domain: entry.domain, main_pipe: entry.code };\n }\n return { spec, diagnostics };\n}\n\n/**\n * Convenience wrapper: parse one or more `.mthds` TOML strings, merge them,\n * and build the static GraphSpec. Diagnostics from all three stages are\n * concatenated in order (parse, merge, build).\n */\nexport function buildStaticGraphSpecFromToml(\n tomlTexts: string | string[],\n options: StaticGraphOptions = {},\n): StaticGraphResult {\n const texts = Array.isArray(tomlTexts) ? tomlTexts : [tomlTexts];\n const parsed = texts.map((text) => parseMthdsBundle(text));\n const merged = mergeBundles(parsed.map((result) => result.bundle));\n const built = buildStaticGraphSpec(merged, options);\n return {\n spec: built.spec,\n diagnostics: [\n ...parsed.flatMap((result) => result.diagnostics),\n ...merged.diagnostics,\n ...built.diagnostics,\n ],\n };\n}\n\n// ─── Walk state ──────────────────────────────────────────────────────────────\n\n/** A scope entry — the static mirror of a working-memory stuff. */\ninterface StuffRecord {\n digest: string;\n name: string;\n concept: ConceptInfo;\n multiplicity: number | boolean | null;\n}\n\ntype Scope = Map<string, StuffRecord>;\n\ninterface WalkCtx {\n set: MergedMethodSet;\n nodes: GraphSpecNode[];\n edges: GraphSpecEdge[];\n pipeRegistry: Record<string, PipeBlueprintUnion>;\n conceptRegistry: Record<string, ConceptInfo>;\n stuffByDigest: Map<string, StuffRecord>;\n diagnostics: Diagnostic[];\n /** Qualified refs (`domain.code`) on the recursion stack — the cycle guard. */\n stack: string[];\n edgeSeq: number;\n}\n\n/** How a pipe is being invoked — the step/branch/outcome context. */\ninterface Invocation {\n /** The enclosing step's `result` name — names the operator's output stuff. */\n resultName: string | null;\n /** The enclosing step's `nb_output`/`multiple_output` override. */\n outputMultiplicity: SubPipeSpec[\"output_multiplicity\"];\n /** Set on condition children: the outcome value that routes here. */\n outcomeValue?: string;\n}\n\ninterface WalkResult {\n nodeId: string;\n /** Primary output stuff — what a sequence step's `result` binds to. */\n output: StuffRecord | null;\n /** Extra bindings a parallel with `add_each_output` exposes to the enclosing scope. */\n eachOutputs: [string, StuffRecord][];\n}\n\n// ─── Entry pipe selection ────────────────────────────────────────────────────\n\ntype PipeResolution =\n | { kind: \"resolved\"; blueprint: PipeBlueprintUnion; domain: string; code: string }\n | { kind: \"opaque\" }\n | { kind: \"unresolved\" };\n\n/**\n * Resolve a pipe ref against the merged set: bare refs in the current domain\n * (same-domain files are already merged into one namespace), `domain.code`\n * refs in the named domain. `alias->…` dependency refs are opaque in phase 1.\n */\nfunction resolvePipeRef(set: MergedMethodSet, ref: string, currentDomain: string): PipeResolution {\n if (ref.includes(\"->\")) return { kind: \"opaque\" };\n const dot = ref.lastIndexOf(\".\");\n const domain = dot === -1 ? currentDomain : ref.slice(0, dot);\n const code = dot === -1 ? ref : ref.slice(dot + 1);\n const blueprint = set.domains[domain]?.pipes[code];\n if (blueprint === undefined) return { kind: \"unresolved\" };\n return { kind: \"resolved\", blueprint, domain, code };\n}\n\n/** Sub-pipe refs appearing anywhere in a namespace — used by the root heuristic. */\nfunction referencedPipeCodes(namespace: DomainNamespace): Set<string> {\n const refs = new Set<string>();\n // Refs are authored strings: bare (`helper`) or qualified (`domain.helper`).\n // Reduce them to bare codes in this namespace, mirroring resolvePipeRef —\n // cross-domain and `alias->` refs can't name a pipe here, so they're dropped.\n const add = (ref: string): void => {\n if (ref === \"\" || ref.includes(\"->\")) return;\n const dot = ref.lastIndexOf(\".\");\n if (dot === -1) refs.add(ref);\n else if (ref.slice(0, dot) === namespace.domain) refs.add(ref.slice(dot + 1));\n };\n for (const pipe of Object.values(namespace.pipes)) {\n switch (pipe.type) {\n case \"PipeSequence\":\n for (const sub of pipe.sequential_sub_pipes) add(sub.pipe_code);\n break;\n case \"PipeParallel\":\n for (const sub of pipe.parallel_sub_pipes) add(sub.pipe_code);\n break;\n case \"PipeCondition\":\n for (const target of Object.values(pipe.outcome_map)) add(target);\n add(pipe.default_outcome);\n break;\n case \"PipeBatch\":\n add(pipe.branch_pipe_code);\n break;\n default:\n break;\n }\n }\n return refs;\n}\n\nfunction pickEntryPipe(\n set: MergedMethodSet,\n explicitRef: string | null,\n diagnostics: Diagnostic[],\n): { domain: string; code: string } | null {\n const domainsInOrder = Object.keys(set.domains);\n const fallbackDomain = set.mainDomain ?? domainsInOrder[0];\n if (fallbackDomain === undefined) {\n diagnostics.push({\n severity: \"error\",\n code: \"no-entry-pipe\",\n message: \"no bundles to build a graph from\",\n });\n return null;\n }\n\n const resolveEntry = (ref: string): { domain: string; code: string } | null => {\n const resolution = resolvePipeRef(set, ref, fallbackDomain);\n return resolution.kind === \"resolved\"\n ? { domain: resolution.domain, code: resolution.code }\n : null;\n };\n\n if (explicitRef !== null) {\n const entry = resolveEntry(explicitRef);\n if (entry === null) {\n diagnostics.push({\n severity: \"error\",\n code: \"unresolved-pipe-ref\",\n message: `entry pipe \"${explicitRef}\" not found in the method set`,\n });\n }\n return entry;\n }\n\n if (set.mainPipe !== null) {\n const entry = resolveEntry(set.mainPipe);\n if (entry !== null) return entry;\n diagnostics.push({\n severity: \"warning\",\n code: \"unresolved-pipe-ref\",\n message: `main_pipe \"${set.mainPipe}\" not found — falling back to a root heuristic`,\n });\n } else {\n diagnostics.push({\n severity: \"warning\",\n code: \"missing-main-pipe\",\n message: \"no main_pipe declared — falling back to a root heuristic\",\n });\n }\n\n // Root heuristic: the first pipe (declaration order) that no other pipe in\n // its domain references; else the first pipe. Keeps half-written bundles\n // rendering something sensible.\n const domainWithPipes = [fallbackDomain, ...domainsInOrder].find(\n (domain) => Object.keys(set.domains[domain]?.pipes ?? {}).length > 0,\n );\n if (domainWithPipes === undefined) {\n diagnostics.push({\n severity: \"error\",\n code: \"no-entry-pipe\",\n message: \"no pipes found in any bundle\",\n });\n return null;\n }\n const namespace = set.domains[domainWithPipes];\n const referenced = referencedPipeCodes(namespace);\n const codes = Object.keys(namespace.pipes);\n const root = codes.find((code) => !referenced.has(code)) ?? codes[0];\n return { domain: domainWithPipes, code: root };\n}\n\n// ─── Small helpers ───────────────────────────────────────────────────────────\n\n/** `CamelCase` concept code → `snake_case` stuff name (the runtime's fallback naming). */\nfunction snakeCase(code: string): string {\n return code\n .replace(/([A-Z]+)([A-Z][a-z0-9])/g, \"$1_$2\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1_$2\")\n .toLowerCase();\n}\n\nfunction registerConcept(ctx: WalkCtx, concept: ConceptInfo): void {\n ctx.conceptRegistry[`${concept.domain_code}.${concept.code}`] ??= concept;\n}\n\n/**\n * Mint (or return the already-minted) stuff for a digest. First mint wins —\n * matching how the UI's stuff registry keeps the first occurrence per digest.\n */\nfunction mintStuff(\n ctx: WalkCtx,\n digest: string,\n name: string,\n concept: ConceptInfo,\n multiplicity: number | boolean | null,\n): StuffRecord {\n const existing = ctx.stuffByDigest.get(digest);\n if (existing !== undefined) return existing;\n const record: StuffRecord = { digest, name, concept, multiplicity };\n ctx.stuffByDigest.set(digest, record);\n registerConcept(ctx, concept);\n return record;\n}\n\n/**\n * An io item for `stuff`, optionally exposed under a *slot name* — the name\n * the invoking step binds it to (`result = \"x\"`). The runtime names a\n * controller's transparent output by its slot, while the producing operator\n * keeps the local name; the UI's stuff registry is first-occurrence-wins and\n * controllers are emitted before their children, so the slot name is what\n * renders (verified against the dry fixtures).\n */\nfunction ioItem(stuff: StuffRecord, slotName?: string | null): GraphSpecNodeIoItem {\n return { name: slotName ?? stuff.name, digest: stuff.digest, concept: stuff.concept.code };\n}\n\nfunction addEdge(\n ctx: WalkCtx,\n kind: GraphSpecEdgeKind,\n source: string,\n target: string,\n extras?: { label?: string; sourceStuff?: string; targetStuff?: string },\n): void {\n // Namespaced ids: the rendering pipeline synthesizes its own dataflow edges\n // named `edge_<n>` (graphBuilders.ts), so bare `edge_<n>` here would collide\n // in the ReactFlow key space.\n const edge: GraphSpecEdge = { id: `static:edge_${ctx.edgeSeq++}`, source, target, kind };\n if (extras?.label !== undefined) edge.label = extras.label;\n if (extras?.sourceStuff !== undefined) edge.source_stuff_digest = extras.sourceStuff;\n if (extras?.targetStuff !== undefined) edge.target_stuff_digest = extras.targetStuff;\n ctx.edges.push(edge);\n}\n\nfunction addNodeTag(node: GraphSpecNode, key: string, value: string): void {\n node.tags = { ...(node.tags ?? {}), [key]: value };\n}\n\nfunction formatBatchMultiplicity(multiplicity: number | boolean | null | undefined): string {\n if (typeof multiplicity === \"number\") return `x${multiplicity}`;\n if (multiplicity === true) return \"xmany\";\n return \"x?\";\n}\n\n/**\n * Working-memory name matching: exact name first, then dotted-prefix — an\n * input `a.b` is satisfied by a binding for `a`.\n */\nfunction lookupScope(scope: Scope, name: string): StuffRecord | undefined {\n let candidate = name;\n for (;;) {\n const found = scope.get(candidate);\n if (found !== undefined) return found;\n const dot = candidate.lastIndexOf(\".\");\n if (dot <= 0) return undefined;\n candidate = candidate.slice(0, dot);\n }\n}\n\nfunction conceptKey(concept: ConceptInfo): string {\n return `${concept.domain_code}.${concept.code}`;\n}\n\n/**\n * Bind the invoked pipe's declared inputs from the caller's scope. A name the\n * scope cannot satisfy is a *dangling* input: mint an input stuff\n * (`input:<name>`) with the declared concept — at the method root these are\n * exactly the method's external inputs, and the UI classifies producer-less\n * stuff as role `input`. The `input:` digest namespace is method-global on\n * purpose: an unbound name means the same missing working-memory entry\n * wherever it is read, so all its consumers share one stuff. When two\n * consumers declare *different* concepts for that shared name, the first\n * mint wins and a diagnostic surfaces the authoring inconsistency.\n *\n * Minted dangling inputs are written into `scope`: working memory is one flat\n * namespace shared down the walk (see the scope model note on `walkPipe`), so\n * later readers of the same name bind the same record.\n */\nfunction bindInputs(\n ctx: WalkCtx,\n blueprint: PipeBlueprintUnion,\n scope: Scope,\n): GraphSpecNodeIoItem[] {\n const ioInputs: GraphSpecNodeIoItem[] = [];\n for (const [name, spec] of Object.entries(blueprint.inputs)) {\n let bound = lookupScope(scope, name);\n if (bound === undefined) {\n bound = mintStuff(ctx, `input:${name}`, name, spec.concept, spec.multiplicity);\n scope.set(name, bound);\n if (conceptKey(bound.concept) !== conceptKey(spec.concept)) {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"conflicting-input-concept\",\n message:\n `pipe \"${blueprint.code}\": dangling input \"${name}\" is declared as ` +\n `${conceptKey(spec.concept)} here but was first seen as ` +\n `${conceptKey(bound.concept)} — keeping the first`,\n path: `pipe.${blueprint.code}.inputs.${name}`,\n });\n }\n }\n ioInputs.push(ioItem(bound));\n }\n return ioInputs;\n}\n\nfunction emitNode(\n ctx: WalkCtx,\n args: {\n id: string;\n kind: \"controller\" | \"operator\";\n pipeCode: string;\n pipeType: PipeType;\n description: string;\n domainCode: string;\n ioInputs: GraphSpecNodeIoItem[];\n parentId: string | null;\n inv: Invocation;\n },\n): GraphSpecNode {\n const node: GraphSpecNode = {\n id: args.id,\n kind: args.kind,\n pipe_code: args.pipeCode,\n pipe_type: args.pipeType,\n // validateGraphSpec requires a non-empty description; WIP pipes may lack one.\n description: args.description.length > 0 ? args.description : args.pipeCode,\n domain_code: args.domainCode,\n status: \"scheduled\",\n io: { inputs: args.ioInputs, outputs: [] },\n };\n if (args.inv.outcomeValue !== undefined) node.tags = { outcome: args.inv.outcomeValue };\n ctx.nodes.push(node);\n if (args.parentId !== null) {\n addEdge(\n ctx,\n \"contains\",\n args.parentId,\n args.id,\n args.inv.outcomeValue !== undefined ? { label: args.inv.outcomeValue } : undefined,\n );\n }\n return node;\n}\n\n// ─── The walk ────────────────────────────────────────────────────────────────\n\n/**\n * Walk one pipe *invocation*: resolve the ref, emit the node (and its\n * `contains` edge), bind inputs from the caller's scope, recurse per\n * controller type, and report the invocation's output stuff.\n *\n * Scope model — the static mirror of the runtime's working memory, which is\n * ONE flat namespace shared across the whole run (verified against the dry\n * fixtures: a result produced inside a nested sub-sequence is consumed by a\n * later step of an ancestor sequence). So: sequence steps see and mutate the\n * caller's scope *object*; parallel/batch branches and condition outcome\n * children each get a *copy* — branches because the runtime forks memory per\n * branch and merges back only the declared outputs, condition outcomes\n * because they are mutually exclusive alternatives (only one runs, so no\n * branch's writes may be visible to its siblings or, beyond the condition's\n * representative output, to the caller).\n */\nfunction walkPipe(\n ctx: WalkCtx,\n ref: string,\n currentDomain: string,\n nodeId: string,\n parentId: string | null,\n scope: Scope,\n inv: Invocation,\n): WalkResult | null {\n const resolution = resolvePipeRef(ctx.set, ref, currentDomain);\n if (resolution.kind === \"unresolved\") {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"unresolved-pipe-ref\",\n message: `pipe ref \"${ref}\" cannot be resolved — node skipped`,\n path: nodeId,\n });\n return null;\n }\n if (resolution.kind === \"opaque\") {\n return emitOpaqueLeaf(ctx, ref, currentDomain, nodeId, parentId, inv);\n }\n\n const { blueprint, domain, code } = resolution;\n const qualified = `${domain}.${code}`;\n const ioInputs = bindInputs(ctx, blueprint, scope);\n const node = emitNode(ctx, {\n id: nodeId,\n kind: blueprint.pipe_category === \"PipeController\" ? \"controller\" : \"operator\",\n pipeCode: code,\n pipeType: blueprint.type,\n description: blueprint.description,\n domainCode: blueprint.domain_code,\n ioInputs,\n parentId,\n inv,\n });\n\n if (ctx.stack.includes(qualified)) {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"cyclic-pipe-ref\",\n message: `pipe \"${qualified}\" is invoked recursively — rendered as a leaf`,\n path: nodeId,\n });\n return finishLeaf(ctx, node, blueprint, nodeId, inv);\n }\n\n ctx.stack.push(qualified);\n try {\n switch (blueprint.type) {\n case \"PipeSequence\":\n return finishSequence(ctx, node, blueprint, nodeId, scope, inv);\n case \"PipeParallel\":\n return finishParallel(ctx, node, blueprint, nodeId, scope, inv);\n case \"PipeCondition\":\n return finishCondition(ctx, node, blueprint, nodeId, scope, inv);\n case \"PipeBatch\":\n return finishBatch(ctx, node, blueprint, nodeId, scope, inv);\n default:\n return finishLeaf(ctx, node, blueprint, nodeId, inv);\n }\n } finally {\n ctx.stack.pop();\n }\n}\n\n/**\n * A step (or branch) invocation: a step carrying inline `batch_over`/`batch_as`\n * becomes a synthetic PipeBatch node wrapping the invoked pipe — mirroring the\n * runtime, which materializes `<pipe>_batch` controllers for inline batching.\n */\nfunction walkSubPipe(\n ctx: WalkCtx,\n sub: SubPipeSpec,\n domain: string,\n nodeId: string,\n parentId: string,\n scope: Scope,\n): WalkResult | null {\n if (sub.batch_params !== null) {\n return walkInlineBatch(ctx, sub, domain, nodeId, parentId, scope);\n }\n return walkPipe(ctx, sub.pipe_code, domain, nodeId, parentId, scope, {\n resultName: sub.output_name,\n outputMultiplicity: sub.output_multiplicity,\n });\n}\n\n// ─── Leaf (operators, signatures, cyclic refs) ───────────────────────────────\n\nfunction finishLeaf(\n ctx: WalkCtx,\n node: GraphSpecNode,\n blueprint: PipeBlueprintUnion,\n nodeId: string,\n inv: Invocation,\n): WalkResult {\n const name = inv.resultName ?? snakeCase(blueprint.output.concept.code);\n const multiplicity =\n typeof inv.outputMultiplicity === \"number\" || inv.outputMultiplicity === true\n ? inv.outputMultiplicity\n : blueprint.output.multiplicity;\n const output = mintStuff(ctx, `${nodeId}:${name}`, name, blueprint.output.concept, multiplicity);\n node.io.outputs = [ioItem(output)];\n return { nodeId, output, eachOutputs: [] };\n}\n\n/** Phase-1 policy for `alias->…` dependency refs: an opaque leaf card. */\nfunction emitOpaqueLeaf(\n ctx: WalkCtx,\n ref: string,\n currentDomain: string,\n nodeId: string,\n parentId: string | null,\n inv: Invocation,\n): WalkResult {\n const alias = ref.slice(0, ref.indexOf(\"->\"));\n const tail = ref.slice(ref.lastIndexOf(\"->\") + 2);\n const codeTail = tail.slice(tail.lastIndexOf(\".\") + 1);\n const node = emitNode(ctx, {\n id: nodeId,\n kind: \"operator\",\n pipeCode: codeTail.length > 0 ? codeTail : ref,\n pipeType: \"PipeSignature\",\n description: `External pipe from dependency \"${alias}\"`,\n domainCode: alias.length > 0 ? alias : currentDomain,\n ioInputs: [],\n parentId,\n inv,\n });\n const name = inv.resultName ?? \"output\";\n const output = mintStuff(ctx, `${nodeId}:${name}`, name, nativeConceptInfo(\"Anything\"), null);\n node.io.outputs = [ioItem(output)];\n return { nodeId, output, eachOutputs: [] };\n}\n\n// ─── Controllers ─────────────────────────────────────────────────────────────\n\nfunction finishSequence(\n ctx: WalkCtx,\n node: GraphSpecNode,\n blueprint: PipeSequenceBlueprint,\n nodeId: string,\n scope: Scope,\n inv: Invocation,\n): WalkResult {\n let lastOutput: StuffRecord | null = null;\n blueprint.sequential_sub_pipes.forEach((sub, index) => {\n const result = walkSubPipe(\n ctx,\n sub,\n blueprint.domain_code,\n `${nodeId}/step_${index + 1}`,\n nodeId,\n scope,\n );\n if (result === null) return;\n if (result.output !== null) {\n if (sub.output_name !== null) scope.set(sub.output_name, result.output);\n lastOutput = result.output;\n }\n for (const [name, stuff] of result.eachOutputs) scope.set(name, stuff);\n });\n // Controller transparency: the sequence's output IS its last producing\n // step's stuff — same digest, so downstream consumers wire to the real\n // producer (the UI only takes producers from non-controller nodes).\n node.io.outputs = lastOutput === null ? [] : [ioItem(lastOutput, inv.resultName)];\n return { nodeId, output: lastOutput, eachOutputs: [] };\n}\n\nfunction finishParallel(\n ctx: WalkCtx,\n node: GraphSpecNode,\n blueprint: PipeParallelBlueprint,\n nodeId: string,\n scope: Scope,\n inv: Invocation,\n): WalkResult {\n const branchResults: { sub: SubPipeSpec; result: WalkResult }[] = [];\n blueprint.parallel_sub_pipes.forEach((sub, index) => {\n // Branches are independent: each gets its own copy of the inherited scope.\n const result = walkSubPipe(\n ctx,\n sub,\n blueprint.domain_code,\n `${nodeId}/branch_${index + 1}`,\n nodeId,\n new Map(scope),\n );\n if (result !== null) branchResults.push({ sub, result });\n });\n\n const eachOutputs: [string, StuffRecord][] = [];\n if (blueprint.add_each_output) {\n for (const { sub, result } of branchResults) {\n if (sub.output_name !== null && result.output !== null) {\n eachOutputs.push([sub.output_name, result.output]);\n }\n }\n }\n\n const combinedName =\n blueprint.combined_output ?? inv.resultName ?? snakeCase(blueprint.output.concept.code);\n const combined = mintStuff(\n ctx,\n `${nodeId}:${combinedName}`,\n combinedName,\n blueprint.output.concept,\n blueprint.output.multiplicity,\n );\n for (const { result } of branchResults) {\n if (result.output !== null) {\n addEdge(ctx, \"parallel_combine\", result.nodeId, nodeId, {\n sourceStuff: result.output.digest,\n targetStuff: combined.digest,\n });\n }\n }\n node.io.outputs = [ioItem(combined, inv.resultName)];\n return { nodeId, output: combined, eachOutputs };\n}\n\nfunction finishCondition(\n ctx: WalkCtx,\n node: GraphSpecNode,\n blueprint: PipeConditionBlueprint,\n nodeId: string,\n scope: Scope,\n inv: Invocation,\n): WalkResult {\n const conditionScope: Scope = new Map(scope);\n if (blueprint.add_alias_from_expression_to !== null) {\n const alias = blueprint.add_alias_from_expression_to;\n // The alias points at whatever the expression evaluates to at run time —\n // statically typed as native.Dynamic.\n conditionScope.set(\n alias,\n mintStuff(ctx, `${nodeId}:${alias}`, alias, nativeConceptInfo(\"Dynamic\"), null),\n );\n }\n\n // One child node per distinct *target pipe*, not per outcome value —\n // mirroring the runtime tracer. Outcomes routing to the same pipe (often\n // one value plus `default_outcome`) merge into a single child carrying all\n // its routing values. `fail` / `continue` are outcome actions, not refs.\n // The default route is tracked as a flag, never as a value string — an\n // *authored* outcome value literally named \"default\" must not collide with\n // the synthetic default sentinel (node ids and primary selection key on it).\n interface RouteEntry {\n values: string[];\n ref: string;\n viaDefault: boolean;\n }\n const targets: RouteEntry[] = [];\n const byRef = new Map<string, RouteEntry>();\n const addRoute = (value: string, ref: string, isDefault: boolean): void => {\n if (ref === \"\" || ref === \"fail\" || ref === \"continue\") return;\n const existing = byRef.get(ref);\n if (existing !== undefined) {\n existing.values.push(value);\n existing.viaDefault ||= isDefault;\n return;\n }\n const entry = { values: [value], ref, viaDefault: isDefault };\n byRef.set(ref, entry);\n targets.push(entry);\n };\n for (const [value, target] of Object.entries(blueprint.outcome_map)) {\n addRoute(value, target, false);\n }\n addRoute(\"default\", blueprint.default_outcome, true);\n\n const results: { entry: RouteEntry; result: WalkResult }[] = [];\n for (const entry of targets) {\n const idSegment =\n entry.viaDefault && entry.values.length === 1 ? \"default\" : `outcome_${entry.values[0]}`;\n const result = walkPipe(\n ctx,\n entry.ref,\n blueprint.domain_code,\n `${nodeId}/${idSegment}`,\n nodeId,\n new Map(conditionScope),\n {\n // The runtime stores whichever branch runs under the condition's own\n // slot name, so every branch's output carries it (dry-run parity).\n resultName: inv.resultName,\n outputMultiplicity: null,\n outcomeValue: entry.values.join(\" | \"),\n },\n );\n if (result !== null) results.push({ entry, result });\n }\n\n // Statically all outcomes exist; pick one representative output for the\n // controller (the default route when present, else the first producing\n // outcome) so downstream consumers wire to a real producer.\n const primary =\n results.find(({ entry, result }) => entry.viaDefault && result.output !== null)?.result\n .output ??\n results.find(({ result }) => result.output !== null)?.result.output ??\n null;\n node.io.outputs = primary === null ? [] : [ioItem(primary, inv.resultName)];\n return { nodeId, output: primary, eachOutputs: [] };\n}\n\nfunction finishBatch(\n ctx: WalkCtx,\n node: GraphSpecNode,\n blueprint: PipeBatchBlueprint,\n nodeId: string,\n scope: Scope,\n inv: Invocation,\n): WalkResult {\n const params = blueprint.batch_params;\n\n let listStuff: StuffRecord | null = null;\n if (params.input_list_stuff_name !== \"\") {\n const bound = lookupScope(scope, params.input_list_stuff_name);\n if (bound !== undefined) {\n listStuff = bound;\n } else {\n // The list name is not among the declared inputs (sloppy but legal WIP\n // state): mint it as a dangling input and surface it on the node's io.\n listStuff = mintStuff(\n ctx,\n `input:${params.input_list_stuff_name}`,\n params.input_list_stuff_name,\n nativeConceptInfo(\"Anything\"),\n true,\n );\n node.io.inputs.push(ioItem(listStuff));\n }\n }\n\n let itemStuff: StuffRecord | null = null;\n const branchScope: Scope = new Map(scope);\n if (params.input_item_stuff_name !== \"\" && listStuff !== null) {\n // The item is one element of the list: same concept, single multiplicity.\n itemStuff = mintStuff(\n ctx,\n `${nodeId}:${params.input_item_stuff_name}`,\n params.input_item_stuff_name,\n listStuff.concept,\n null,\n );\n branchScope.set(params.input_item_stuff_name, itemStuff);\n }\n\n const batchMultiplicity = formatBatchMultiplicity(listStuff?.multiplicity);\n addNodeTag(node, \"batch_multiplicity\", batchMultiplicity);\n\n // One representative branch, not N — this is a method view, not a run trace.\n let branchResult: WalkResult | null = null;\n if (blueprint.branch_pipe_code !== \"\") {\n branchResult = walkPipe(\n ctx,\n blueprint.branch_pipe_code,\n blueprint.domain_code,\n `${nodeId}/batch_branch`,\n nodeId,\n branchScope,\n { resultName: null, outputMultiplicity: null },\n );\n const branchNode = ctx.nodes.find((candidate) => candidate.id === branchResult?.nodeId);\n if (branchNode !== undefined) {\n addNodeTag(branchNode, \"batch_multiplicity\", batchMultiplicity);\n }\n }\n\n const aggConcept = branchResult?.output?.concept ?? blueprint.output.concept;\n const aggName = inv.resultName ?? snakeCase(aggConcept.code);\n const aggregate = mintStuff(ctx, `${nodeId}:${aggName}`, aggName, aggConcept, true);\n\n if (branchResult !== null && listStuff !== null && itemStuff !== null) {\n addEdge(ctx, \"batch_item\", nodeId, branchResult.nodeId, {\n sourceStuff: listStuff.digest,\n targetStuff: itemStuff.digest,\n });\n }\n if (branchResult?.output != null) {\n addEdge(ctx, \"batch_aggregate\", branchResult.nodeId, nodeId, {\n sourceStuff: branchResult.output.digest,\n targetStuff: aggregate.digest,\n });\n }\n\n node.io.outputs = [ioItem(aggregate)];\n return { nodeId, output: aggregate, eachOutputs: [] };\n}\n\n/** Synthesize the PipeBatch node the runtime materializes for an inline `batch_over` step. */\nfunction walkInlineBatch(\n ctx: WalkCtx,\n sub: SubPipeSpec,\n domain: string,\n nodeId: string,\n parentId: string,\n scope: Scope,\n): WalkResult {\n const params = sub.batch_params as NonNullable<SubPipeSpec[\"batch_params\"]>;\n // Bare code of the branch ref: strip a dependency alias (`helpers->clean`)\n // and a domain qualifier (`lib.clean`) so the synthetic code reads cleanly.\n const aliasIdx = sub.pipe_code.lastIndexOf(\"->\");\n const refTail = aliasIdx === -1 ? sub.pipe_code : sub.pipe_code.slice(aliasIdx + 2);\n const branchTail = refTail.slice(refTail.lastIndexOf(\".\") + 1);\n const branchResolution = resolvePipeRef(ctx.set, sub.pipe_code, domain);\n const branchBlueprint = branchResolution.kind === \"resolved\" ? branchResolution.blueprint : null;\n\n const listBinding = lookupScope(scope, params.input_list_stuff_name);\n const listConcept =\n listBinding?.concept ??\n branchBlueprint?.inputs[params.input_item_stuff_name]?.concept ??\n nativeConceptInfo(\"Anything\");\n const outputSpec = branchBlueprint?.output ?? {\n concept: nativeConceptInfo(\"Anything\"),\n multiplicity: null,\n };\n\n // Registry key: the detail panel resolves blueprints by `domain.pipe_code`,\n // so every distinct inline batch needs its own entry. Reuse the code only\n // when it already points at this exact batch (same branch, same params);\n // otherwise disambiguate with a numeric suffix (`x_batch`, `x_batch_2`, …).\n const baseCode = `${branchTail}_batch`;\n let code = baseCode;\n for (let suffix = 2; ; suffix++) {\n const existing = ctx.pipeRegistry[`${domain}.${code}`];\n if (\n existing === undefined ||\n (existing.type === \"PipeBatch\" &&\n existing.branch_pipe_code === sub.pipe_code &&\n existing.batch_params.input_list_stuff_name === params.input_list_stuff_name &&\n existing.batch_params.input_item_stuff_name === params.input_item_stuff_name)\n ) {\n break;\n }\n code = `${baseCode}_${suffix}`;\n }\n const blueprint: PipeBatchBlueprint = {\n type: \"PipeBatch\",\n pipe_category: \"PipeController\",\n code,\n domain_code: domain,\n description: `Batch processing for ${branchTail}`,\n inputs: { [params.input_list_stuff_name]: { concept: listConcept, multiplicity: null } },\n output: { concept: outputSpec.concept, multiplicity: null },\n branch_pipe_code: sub.pipe_code,\n batch_params: params,\n };\n ctx.pipeRegistry[`${domain}.${code}`] ??= blueprint;\n\n const ioInputs = bindInputs(ctx, blueprint, scope);\n const inv: Invocation = {\n resultName: sub.output_name,\n outputMultiplicity: sub.output_multiplicity,\n };\n const node = emitNode(ctx, {\n id: nodeId,\n kind: \"controller\",\n pipeCode: code,\n pipeType: \"PipeBatch\",\n description: blueprint.description,\n domainCode: domain,\n ioInputs,\n parentId,\n inv,\n });\n return finishBatch(ctx, node, blueprint, nodeId, scope, inv);\n}\n","// Bridge from static-analysis diagnostics to the viewer's validation panel.\n\nimport type { ValidationIssue } from \"@graph/types\";\nimport type { Diagnostic } from \"./types\";\n\n/**\n * Derive the viewer targeting fields from a diagnostic's TOML-style `path`.\n *\n * - A walk-phase path is a GraphSpec node id and contains `/` (e.g.\n * `demo.main_flow/step_2`) → `nodeId`. Checked first: node ids embed the\n * domain, so a prefix test alone could misread them.\n * - A declaration path `pipe.<code>[...]` → `pipeCode`.\n * - Everything else (concept paths, bare section paths like `pipe`, root\n * entry-pipe ids without `/`, missing paths) has no graph target — those\n * issues stay panel-only.\n */\nfunction targetFromPath(path: string | undefined): Pick<ValidationIssue, \"pipeCode\" | \"nodeId\"> {\n if (!path) return {};\n if (path.includes(\"/\")) return { nodeId: path };\n if (path.startsWith(\"pipe.\")) {\n const code = path.split(\".\")[1];\n if (code) return { pipeCode: code };\n }\n return {};\n}\n\n/**\n * Project static-graph {@link Diagnostic}s onto the viewer's presentation shape\n * so a host can feed them straight into `GraphViewer`'s `validationIssues`.\n * The TOML-style `path` becomes the locator chip; `origin: \"static\"` lets the\n * panel (and the host's issue policy) distinguish them from validator verdicts.\n * When the path identifies a pipe declaration or a precise invocation, the\n * targeting fields (`pipeCode` / `nodeId`) are filled so the viewer can\n * decorate the affected graph nodes.\n */\nexport function staticDiagnosticsToValidationIssues(diagnostics: Diagnostic[]): ValidationIssue[] {\n return diagnostics.map((diagnostic) => ({\n severity: diagnostic.severity,\n message: diagnostic.message,\n context: diagnostic.path,\n origin: \"static\",\n ...targetFromPath(diagnostic.path),\n }));\n}\n"],"mappings":"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","names":["spec","_a","_b"]}
|
|
1
|
+
{"version":3,"sources":["../../src/static-graph/types.ts","../../src/static-graph/conceptRefs.ts","../../src/static-graph/parseMthdsBundle.ts","../../src/static-graph/normalizePipe.ts","../../src/static-graph/mergeBundles.ts","../../src/static-graph/buildStaticGraphSpec.ts","../../src/static-graph/validationIssues.ts"],"sourcesContent":["// ─── Static method-graph module: domain types ───────────────────────────────\n// Pure TypeScript, no React. This module parses raw `.mthds` TOML text into\n// blueprint-shaped bundles, reusing the `Pipe*Blueprint` registry types from\n// `@graph/types` so the parsed entries can feed a GraphSpec `pipe_registry`\n// directly. Parsing is lenient: half-written bundles produce partial results\n// plus non-fatal diagnostics, never exceptions.\n\nimport type { ConceptInfo, PipeBlueprintUnion } from \"@graph/types\";\n\n// ─── Diagnostics ─────────────────────────────────────────────────────────────\n\nexport type DiagnosticSeverity = \"error\" | \"warning\";\n\nexport type DiagnosticCode =\n | \"toml-parse-error\"\n | \"missing-domain\"\n | \"invalid-bundle-shape\"\n | \"invalid-concept-entry\"\n | \"invalid-pipe-entry\"\n | \"unknown-pipe-type\"\n | \"invalid-concept-ref\"\n | \"missing-pipe-output\"\n | \"invalid-sub-pipe\"\n | \"incomplete-batch-spec\"\n | \"duplicate-concept\"\n | \"duplicate-pipe\"\n | \"unresolved-pipe-ref\"\n | \"cyclic-pipe-ref\"\n | \"missing-main-pipe\"\n | \"no-entry-pipe\"\n | \"conflicting-input-concept\";\n\n/**\n * A non-fatal note collected while parsing or merging. `error` means a whole\n * unit could not be interpreted (unparseable TOML, a skipped pipe); `warning`\n * means something was tolerated with a fallback (missing output, bad ref).\n */\nexport interface Diagnostic {\n severity: DiagnosticSeverity;\n code: DiagnosticCode;\n message: string;\n /** TOML-style locator for the offending entry, e.g. `pipe.analyze_candidate.output`. */\n path?: string;\n /**\n * Domain of the bundle namespace the diagnostic belongs to — the declaring-file\n * identity a host needs to qualify a `pipe.<code>` locator into a full pipe ref\n * (`domain_code.pipe_code`). Stamped wherever the owning namespace is known:\n * per-file diagnostics get their bundle's domain ({@link UNKNOWN_DOMAIN} when\n * the bundle declares none), merge/walk diagnostics the namespace being\n * processed, and entry selection stamps the diagnostics it can attribute (a\n * missing or unresolvable `main_pipe` names its declaring domain). Absent only\n * when no owning bundle can be resolved: unparseable TOML, or entry selection\n * with no resolvable owner (no bundles, no pipes anywhere, or a host-supplied\n * entry ref that matches nothing).\n */\n domain_code?: string;\n}\n\n// ─── Parsed bundle ───────────────────────────────────────────────────────────\n\n/**\n * One `.mthds` file, parsed and normalized. Pipes are narrowed to the same\n * `PipeBlueprintUnion` shapes the pipelex runtime serializes into GraphSpec\n * `pipe_registry`, and concepts to `ConceptInfo` — no parallel type universe.\n * Field names mirror the TOML bundle header keys.\n */\nexport interface ParsedBundle {\n domain: string | null;\n description: string | null;\n main_pipe: string | null;\n system_prompt: string | null;\n /** Concepts declared in this bundle, keyed by bare concept code. */\n concepts: Record<string, ConceptInfo>;\n /** Pipes declared in this bundle, keyed by bare pipe code. */\n pipes: Record<string, PipeBlueprintUnion>;\n}\n\nexport interface ParseMthdsBundleResult {\n bundle: ParsedBundle;\n diagnostics: Diagnostic[];\n}\n\n// ─── Merged method set ───────────────────────────────────────────────────────\n\n/** Namespace of one domain after merging bundles: concepts and pipes by bare code. */\nexport interface DomainNamespace {\n domain: string;\n concepts: Record<string, ConceptInfo>;\n pipes: Record<string, PipeBlueprintUnion>;\n}\n\n/**\n * The merged namespace of a method package: every parsed bundle grouped by\n * domain, with duplicate codes resolved keep-first (plus a diagnostic).\n * `mainDomain` / `mainPipe` come as a pair from the first bundle declaring\n * `main_pipe` (falling back to the first domained bundle when none does) —\n * the walk entry point for the static graph builder. `description` comes from\n * the first bundle that declares it.\n */\nexport interface MergedMethodSet {\n domains: Record<string, DomainNamespace>;\n mainDomain: string | null;\n mainPipe: string | null;\n description: string | null;\n diagnostics: Diagnostic[];\n}\n\n/** Namespace used for bundles that declare no `domain` (a legal WIP state). */\nexport const UNKNOWN_DOMAIN = \"unknown\";\n\n// ─── Narrowing helpers (shared by the parsing modules) ───────────────────────\n\n/**\n * True for plain tables only — rejects arrays, class instances and dates\n * (smol-toml emits `TomlDate` objects for TOML datetime values).\n */\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\nexport function strOrNull(value: unknown): string | null {\n return typeof value === \"string\" && value.length > 0 ? value : null;\n}\n\nexport function intOrNull(value: unknown): number | null {\n return typeof value === \"number\" && Number.isInteger(value) ? value : null;\n}\n\nexport function boolOrNull(value: unknown): boolean | null {\n return typeof value === \"boolean\" ? value : null;\n}\n","// ─── Concept reference parsing and resolution ────────────────────────────────\n// A concept ref in MTHDS TOML is `Code`, `domain.Code`, optionally suffixed\n// with a multiplicity marker: `Code[]` (many) or `Code[N]` (exactly N).\n// Resolution follows the spec's namespace rules: bare refs resolve in the\n// current bundle first, then the native domain; qualified refs name their\n// domain explicitly. Anything unresolved becomes a best-effort stub — this\n// module never throws on content.\n\nimport type { ConceptInfo, StuffSpecInfo } from \"@graph/types\";\n\nexport const NATIVE_DOMAIN = \"native\";\n\n/**\n * The native concept catalog (mirrors pipelex `NativeConceptCode`). Descriptions\n * are display-only stand-ins — the runtime's exact wording is not part of the\n * contract. Structure class names follow the runtime's `<Code>Content` rule.\n */\nconst NATIVE_CONCEPT_DESCRIPTIONS: Record<string, string> = {\n Dynamic: \"Dynamically typed content\",\n Text: \"A text\",\n Image: \"An image\",\n Document: \"A document\",\n Html: \"HTML content\",\n TextAndImages: \"A text with images\",\n Number: \"A number\",\n Page: \"The content of a page of a document\",\n JSON: \"JSON content\",\n SearchResult: \"A search result\",\n Anything: \"Anything\",\n Composite: \"A named composition of multiple contents\",\n};\n\nexport const NATIVE_CONCEPT_CODES: ReadonlySet<string> = new Set(\n Object.keys(NATIVE_CONCEPT_DESCRIPTIONS),\n);\n\n// ─── Ref parsing ─────────────────────────────────────────────────────────────\n\nexport interface ConceptRefParts {\n /** Explicit domain qualifier (`recruitment` in `recruitment.Profile`), or null for bare refs. */\n domain: string | null;\n code: string;\n /** `[]` → true (many), `[N]` → N, no suffix → null (single). */\n multiplicity: number | boolean | null;\n}\n\nconst CONCEPT_REF_RE = /^(?:([A-Za-z0-9_][A-Za-z0-9_.]*)\\.)?([A-Za-z0-9_]+)(?:\\[(\\d*)\\])?$/;\n\n/** Parse a concept ref string into its parts. Returns null when the ref is not interpretable. */\nexport function parseConceptRef(raw: unknown): ConceptRefParts | null {\n if (typeof raw !== \"string\") return null;\n const match = CONCEPT_REF_RE.exec(raw.trim());\n if (!match) return null;\n const [, domain, code, multiplicity] = match;\n return {\n domain: domain ?? null,\n code,\n multiplicity:\n multiplicity === undefined\n ? null\n : multiplicity === \"\"\n ? true\n : Number.parseInt(multiplicity, 10),\n };\n}\n\n// ─── Resolution to ConceptInfo ───────────────────────────────────────────────\n\n/**\n * Synthetic structure class name for a non-native concept, mirroring the\n * runtime's `make_qualified_structure_class_name`: dots in hierarchical\n * domain codes are replaced with interpuncts (·) to keep the name a valid,\n * collision-free identifier (`a.b` → `a·b`, distinct from `a_b`).\n */\nexport function qualifiedStructureClassName(domain: string, code: string): string {\n return `${domain.replaceAll(\".\", \"·\")}__${code}`;\n}\n\nexport function nativeConceptInfo(code: string): ConceptInfo {\n return {\n code,\n domain_code: NATIVE_DOMAIN,\n description: NATIVE_CONCEPT_DESCRIPTIONS[code] ?? code,\n structure_class_name: `${code}Content`,\n refines: null,\n };\n}\n\n/**\n * Best-effort info for a concept that is referenced but not declared in the\n * material at hand — an implicit concept, a WIP ref, or a cross-bundle ref\n * that `mergeBundles` may still enrich later.\n */\nfunction stubConceptInfo(code: string, domain: string): ConceptInfo {\n return {\n code,\n domain_code: domain,\n description: \"\",\n structure_class_name: qualifiedStructureClassName(domain, code),\n refines: null,\n };\n}\n\n/**\n * Resolve parsed ref parts against the current bundle. `localConcepts` holds\n * the bundle's declared concepts keyed by bare code.\n */\nexport function resolveConceptInfo(\n parts: ConceptRefParts,\n currentDomain: string,\n localConcepts: Record<string, ConceptInfo>,\n): ConceptInfo {\n if (parts.domain === NATIVE_DOMAIN) {\n return NATIVE_CONCEPT_CODES.has(parts.code)\n ? nativeConceptInfo(parts.code)\n : stubConceptInfo(parts.code, NATIVE_DOMAIN);\n }\n if (parts.domain !== null && parts.domain !== currentDomain) {\n return stubConceptInfo(parts.code, parts.domain);\n }\n const local = localConcepts[parts.code];\n if (local) return local;\n if (parts.domain === null && NATIVE_CONCEPT_CODES.has(parts.code)) {\n return nativeConceptInfo(parts.code);\n }\n return stubConceptInfo(parts.code, currentDomain);\n}\n\n/** Resolve a raw concept ref string straight to a `StuffSpecInfo`, or null when unparseable. */\nexport function resolveStuffSpec(\n raw: unknown,\n currentDomain: string,\n localConcepts: Record<string, ConceptInfo>,\n): StuffSpecInfo | null {\n const parts = parseConceptRef(raw);\n if (parts === null) return null;\n return {\n concept: resolveConceptInfo(parts, currentDomain, localConcepts),\n multiplicity: parts.multiplicity,\n };\n}\n","// ─── parseMthdsBundle: `.mthds` TOML text → ParsedBundle ─────────────────────\n// The single entry point for turning one raw `.mthds` string into a\n// blueprint-shaped bundle. Lenient in the `validateGraphSpec` house style but\n// inverted: instead of failing loudly on contract violations, it tolerates\n// missing or partial sections, skips what it cannot interpret, and records\n// non-fatal diagnostics — the whole point is rendering methods while they are\n// being written. It never throws on content; even unparseable TOML becomes an\n// `error` diagnostic with an empty bundle.\n\nimport { parse as parseToml } from \"smol-toml\";\n\nimport type { ConceptInfo, PipeBlueprintUnion } from \"@graph/types\";\n\nimport {\n NATIVE_CONCEPT_CODES,\n NATIVE_DOMAIN,\n parseConceptRef,\n qualifiedStructureClassName,\n} from \"./conceptRefs\";\nimport { normalizePipe } from \"./normalizePipe\";\nimport type { Diagnostic, ParseMthdsBundleResult, ParsedBundle } from \"./types\";\nimport { isPlainObject, strOrNull, UNKNOWN_DOMAIN } from \"./types\";\n\n// ─── Concept structure → JSON schema (display-only, best-effort) ─────────────\n\nconst FIELD_TYPE_TO_JSON: Record<string, Record<string, unknown>> = {\n text: { type: \"string\" },\n integer: { type: \"integer\" },\n number: { type: \"number\" },\n boolean: { type: \"boolean\" },\n date: { type: \"string\", format: \"date-time\" },\n list: { type: \"array\" },\n dict: { type: \"object\" },\n concept: { type: \"object\" },\n};\n\nfunction fieldSchema(spec: Record<string, unknown>): Record<string, unknown> {\n const typeName = strOrNull(spec.type) ?? \"text\";\n const schema: Record<string, unknown> = {\n ...(FIELD_TYPE_TO_JSON[typeName] ?? { type: \"string\" }),\n };\n const description = strOrNull(spec.description);\n if (description !== null) schema.description = description;\n if (typeName === \"list\") {\n const itemType = strOrNull(spec.item_type);\n schema.items = itemType !== null ? { ...(FIELD_TYPE_TO_JSON[itemType] ?? {}) } : {};\n }\n if (Array.isArray(spec.choices)) {\n schema.enum = spec.choices.filter((choice) => typeof choice === \"string\");\n }\n if (spec.default_value !== undefined && spec.default_value !== null) {\n schema.default = spec.default_value;\n }\n return schema;\n}\n\n/**\n * Derive a lightweight JSON schema from a `[concept.X.structure]` table so\n * concept detail panels have fields to show. Deliberately simpler than the\n * pydantic-generated schema the runtime emits (no anyOf-null wrapping, no\n * per-field titles) — this is presentation data, not a contract.\n */\nfunction deriveJsonSchema(\n structure: unknown,\n title: string,\n description: string,\n): Record<string, unknown> | undefined {\n if (!isPlainObject(structure)) return undefined;\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n for (const [name, spec] of Object.entries(structure)) {\n if (typeof spec === \"string\") {\n properties[name] = { type: \"string\", description: spec };\n continue;\n }\n if (!isPlainObject(spec)) continue;\n properties[name] = fieldSchema(spec);\n if (spec.required === true) required.push(name);\n }\n return {\n title,\n type: \"object\",\n description,\n properties,\n ...(required.length > 0 ? { required } : {}),\n };\n}\n\n// ─── Concept table parsing ───────────────────────────────────────────────────\n\n/** Qualify a `refines` ref the way the runtime registry does (`Text` → `native.Text`). */\nfunction qualifyRefines(\n raw: unknown,\n domain: string,\n declaredCodes: ReadonlySet<string>,\n): string | null {\n const parts = parseConceptRef(raw);\n if (parts === null) return null;\n if (parts.domain !== null) return `${parts.domain}.${parts.code}`;\n if (!declaredCodes.has(parts.code) && NATIVE_CONCEPT_CODES.has(parts.code)) {\n return `${NATIVE_DOMAIN}.${parts.code}`;\n }\n return `${domain}.${parts.code}`;\n}\n\nfunction parseConcepts(\n raw: unknown,\n domain: string,\n diagnostics: Diagnostic[],\n): Record<string, ConceptInfo> {\n const concepts: Record<string, ConceptInfo> = {};\n if (raw === undefined) return concepts;\n if (!isPlainObject(raw)) {\n diagnostics.push({\n severity: \"warning\",\n code: \"invalid-bundle-shape\",\n message: \"concept section is not a table — ignored\",\n path: \"concept\",\n });\n return concepts;\n }\n const declaredCodes: ReadonlySet<string> = new Set(Object.keys(raw));\n for (const [code, entry] of Object.entries(raw)) {\n if (typeof entry === \"string\") {\n // Shorthand form: `Concept = \"description\"`.\n concepts[code] = {\n code,\n domain_code: domain,\n description: entry,\n structure_class_name: qualifiedStructureClassName(domain, code),\n refines: null,\n };\n continue;\n }\n if (!isPlainObject(entry)) {\n diagnostics.push({\n severity: \"warning\",\n code: \"invalid-concept-entry\",\n message: `concept \"${code}\" is neither a table nor a description string — skipped`,\n path: `concept.${code}`,\n });\n continue;\n }\n const description = strOrNull(entry.description) ?? \"\";\n // A `structure = \"ClassName\"` string names an existing structure class;\n // the table form gets the runtime's `<domain>__<Code>` synthetic name.\n const structureClassName =\n strOrNull(entry.structure) ?? qualifiedStructureClassName(domain, code);\n concepts[code] = {\n code,\n domain_code: domain,\n description,\n structure_class_name: structureClassName,\n refines: qualifyRefines(entry.refines, domain, declaredCodes),\n json_schema: deriveJsonSchema(entry.structure, structureClassName, description),\n };\n }\n return concepts;\n}\n\n// ─── Bundle parsing ──────────────────────────────────────────────────────────\n\nfunction emptyBundle(): ParsedBundle {\n return {\n domain: null,\n description: null,\n main_pipe: null,\n system_prompt: null,\n concepts: {},\n pipes: {},\n };\n}\n\n/**\n * Parse one `.mthds` TOML string. Returns whatever could be interpreted plus\n * the diagnostics collected along the way — never throws.\n */\nexport function parseMthdsBundle(tomlText: string): ParseMthdsBundleResult {\n const diagnostics: Diagnostic[] = [];\n let root: Record<string, unknown>;\n try {\n root = parseToml(tomlText);\n } catch (error) {\n diagnostics.push({\n severity: \"error\",\n code: \"toml-parse-error\",\n message: error instanceof Error ? error.message : String(error),\n });\n return { bundle: emptyBundle(), diagnostics };\n }\n\n const bundle = emptyBundle();\n bundle.domain = strOrNull(root.domain);\n bundle.description = strOrNull(root.description);\n bundle.main_pipe = strOrNull(root.main_pipe);\n bundle.system_prompt = strOrNull(root.system_prompt);\n if (bundle.domain === null) {\n diagnostics.push({\n severity: \"warning\",\n code: \"missing-domain\",\n message: `bundle declares no domain — using \"${UNKNOWN_DOMAIN}\"`,\n path: \"domain\",\n });\n }\n const domain = bundle.domain ?? UNKNOWN_DOMAIN;\n\n bundle.concepts = parseConcepts(root.concept, domain, diagnostics);\n\n const pipeTable = root.pipe;\n if (pipeTable !== undefined) {\n if (!isPlainObject(pipeTable)) {\n diagnostics.push({\n severity: \"warning\",\n code: \"invalid-bundle-shape\",\n message: \"pipe section is not a table — ignored\",\n path: \"pipe\",\n });\n } else {\n const ctx = { domain, concepts: bundle.concepts, diagnostics };\n for (const [code, entry] of Object.entries(pipeTable)) {\n if (!isPlainObject(entry)) {\n diagnostics.push({\n severity: \"error\",\n code: \"invalid-pipe-entry\",\n message: `pipe \"${code}\" is not a table — skipped`,\n path: `pipe.${code}`,\n });\n continue;\n }\n const pipe: PipeBlueprintUnion | null = normalizePipe(code, entry, ctx);\n if (pipe !== null) bundle.pipes[code] = pipe;\n }\n }\n }\n\n // Stamp every diagnostic with the file's namespace domain — the declaring-file\n // identity hosts need to qualify `pipe.<code>` locators into full pipe refs.\n // (The toml-parse-error path returns above, before any domain exists.)\n for (const diagnostic of diagnostics) {\n diagnostic.domain_code ??= domain;\n }\n\n return { bundle, diagnostics };\n}\n","// ─── Pipe normalization: authored TOML shape → registry blueprint shape ─────\n// The authoring surface (mthds_schema.json, checked in under data/schema/)\n// and the runtime-serialized registry shape (`PipeBlueprintUnion` in\n// `@graph/types`) name things differently: `steps` vs `sequential_sub_pipes`,\n// `model` vs `llm_choices`, `prompt` vs `prompt_blueprint`, … This module maps\n// the former to the latter, leniently: uninterpretable pieces are skipped with\n// a diagnostic, and only a pipe without a usable `type` is dropped entirely.\n\nimport type {\n ConceptInfo,\n PipeBlueprintUnion,\n PipeComposeConstructBlueprint,\n PipeComposeConstructField,\n PipeType,\n StuffSpecInfo,\n SubPipeSpec,\n TemplateBlueprint,\n} from \"@graph/types\";\nimport { KNOWN_PIPE_TYPES } from \"@graph/types\";\n\nimport { NATIVE_DOMAIN, nativeConceptInfo, resolveStuffSpec } from \"./conceptRefs\";\nimport type { Diagnostic } from \"./types\";\nimport { boolOrNull, intOrNull, isPlainObject, strOrNull } from \"./types\";\n\nexport interface NormalizePipeContext {\n domain: string;\n /** The bundle's declared concepts, keyed by bare code. */\n concepts: Record<string, ConceptInfo>;\n diagnostics: Diagnostic[];\n}\n\n// ─── Small shared builders ───────────────────────────────────────────────────\n\nfunction makeTemplate(template: string, category: string): TemplateBlueprint {\n return { template, templating_style: null, category, extra_context: null };\n}\n\n/**\n * Extract a display string from a model choice, which the authoring surface\n * allows as a plain handle (`\"gpt-5\"`), an inline setting (`{ model = … }`),\n * or a model reference (`{ name = … }`).\n */\nfunction modelToString(value: unknown): string | null {\n if (typeof value === \"string\") return strOrNull(value);\n if (isPlainObject(value)) {\n return strOrNull(value.model) ?? strOrNull(value.raw) ?? strOrNull(value.name);\n }\n return null;\n}\n\nfunction stringArrayOrNull(value: unknown): string[] | null {\n if (!Array.isArray(value)) return null;\n return value.filter((item): item is string => typeof item === \"string\");\n}\n\n// ─── IO normalization ────────────────────────────────────────────────────────\n\nfunction normalizeInputs(\n raw: unknown,\n pipeCode: string,\n ctx: NormalizePipeContext,\n): Record<string, StuffSpecInfo> {\n const inputs: Record<string, StuffSpecInfo> = {};\n if (raw === undefined || raw === null) return inputs;\n if (!isPlainObject(raw)) {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"invalid-pipe-entry\",\n message: `pipe \"${pipeCode}\": inputs is not a table — ignored`,\n path: `pipe.${pipeCode}.inputs`,\n });\n return inputs;\n }\n for (const [name, ref] of Object.entries(raw)) {\n const spec = resolveStuffSpec(ref, ctx.domain, ctx.concepts);\n if (spec === null) {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"invalid-concept-ref\",\n message: `pipe \"${pipeCode}\": input \"${name}\" has an uninterpretable concept ref — skipped`,\n path: `pipe.${pipeCode}.inputs.${name}`,\n });\n continue;\n }\n inputs[name] = spec;\n }\n return inputs;\n}\n\nfunction normalizeOutput(raw: unknown, pipeCode: string, ctx: NormalizePipeContext): StuffSpecInfo {\n const spec = resolveStuffSpec(raw, ctx.domain, ctx.concepts);\n if (spec !== null) return spec;\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"missing-pipe-output\",\n message: `pipe \"${pipeCode}\": missing or uninterpretable output — assuming native.Anything`,\n path: `pipe.${pipeCode}.output`,\n });\n return { concept: nativeConceptInfo(\"Anything\"), multiplicity: null };\n}\n\n// ─── Sub-pipe normalization (sequence steps, parallel branches) ──────────────\n\nfunction normalizeSubPipe(\n raw: unknown,\n pipeCode: string,\n path: string,\n ctx: NormalizePipeContext,\n): SubPipeSpec | null {\n if (!isPlainObject(raw) || strOrNull(raw.pipe) === null) {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"invalid-sub-pipe\",\n message: `pipe \"${pipeCode}\": sub-pipe entry without a \"pipe\" ref — skipped`,\n path,\n });\n return null;\n }\n const batchOver = strOrNull(raw.batch_over);\n const batchAs = strOrNull(raw.batch_as);\n let batchParams: SubPipeSpec[\"batch_params\"] = null;\n if (batchOver !== null && batchAs !== null) {\n batchParams = { input_list_stuff_name: batchOver, input_item_stuff_name: batchAs };\n } else if (batchOver !== null || batchAs !== null) {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"incomplete-batch-spec\",\n message:\n `pipe \"${pipeCode}\": sub-pipe \"${raw.pipe as string}\" sets only one of ` +\n `batch_over/batch_as — batching ignored`,\n path,\n });\n }\n // Mirrors the runtime SubPipeFactory: explicit nb_output wins, then\n // multiple_output, and a batched step is implicitly multiple.\n let outputMultiplicity: SubPipeSpec[\"output_multiplicity\"] =\n intOrNull(raw.nb_output) ?? (raw.multiple_output === true ? true : null);\n if (batchParams !== null && outputMultiplicity === null) outputMultiplicity = true;\n return {\n pipe_code: raw.pipe as string,\n output_name: strOrNull(raw.result),\n output_multiplicity: outputMultiplicity,\n batch_params: batchParams,\n };\n}\n\nfunction normalizeSubPipeList(\n raw: unknown,\n pipeCode: string,\n key: string,\n ctx: NormalizePipeContext,\n): SubPipeSpec[] {\n if (!Array.isArray(raw)) {\n if (raw !== undefined) {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"invalid-pipe-entry\",\n message: `pipe \"${pipeCode}\": ${key} is not an array — treated as empty`,\n path: `pipe.${pipeCode}.${key}`,\n });\n }\n return [];\n }\n return raw\n .map((entry, index) =>\n normalizeSubPipe(entry, pipeCode, `pipe.${pipeCode}.${key}[${index}]`, ctx),\n )\n .filter((entry): entry is SubPipeSpec => entry !== null);\n}\n\n// ─── Compose construct normalization ─────────────────────────────────────────\n\nfunction normalizeConstructField(value: unknown): PipeComposeConstructField | null {\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\" ||\n Array.isArray(value)\n ) {\n return { method: \"fixed\", fixed_value: value };\n }\n if (isPlainObject(value)) {\n if (typeof value.from === \"string\") {\n return {\n method: \"from_var\",\n from_path: value.from,\n list_to_dict_keyed_by: strOrNull(value.list_to_dict_keyed_by),\n };\n }\n if (typeof value.template === \"string\") {\n return { method: \"template\", template: value.template };\n }\n const nested = normalizeConstruct(value);\n if (nested !== null) return { method: \"nested\", nested };\n }\n return null;\n}\n\nfunction normalizeConstruct(raw: unknown): PipeComposeConstructBlueprint | null {\n if (!isPlainObject(raw)) return null;\n const fields: Record<string, PipeComposeConstructField> = {};\n for (const [name, value] of Object.entries(raw)) {\n const field = normalizeConstructField(value);\n if (field !== null) fields[name] = field;\n }\n return Object.keys(fields).length > 0 ? { fields } : null;\n}\n\n// ─── Per-type normalization ──────────────────────────────────────────────────\n\n/**\n * Normalize one `[pipe.<code>]` table to its registry blueprint shape.\n * Returns null (with a diagnostic) only when the `type` is missing or not a\n * known pipe class — everything else degrades field-by-field.\n */\nexport function normalizePipe(\n code: string,\n raw: Record<string, unknown>,\n ctx: NormalizePipeContext,\n): PipeBlueprintUnion | null {\n const typeValue = raw.type;\n if (typeof typeValue !== \"string\" || !KNOWN_PIPE_TYPES.has(typeValue)) {\n ctx.diagnostics.push({\n severity: \"error\",\n code: \"unknown-pipe-type\",\n message: `pipe \"${code}\": unknown pipe type ${JSON.stringify(typeValue)} — pipe skipped`,\n path: `pipe.${code}.type`,\n });\n return null;\n }\n const type = typeValue as PipeType;\n const base = {\n code,\n domain_code: ctx.domain,\n description: strOrNull(raw.description) ?? \"\",\n inputs: normalizeInputs(raw.inputs, code, ctx),\n output: normalizeOutput(raw.output, code, ctx),\n };\n\n switch (type) {\n case \"PipeSequence\":\n return {\n ...base,\n type,\n pipe_category: \"PipeController\",\n sequential_sub_pipes: normalizeSubPipeList(raw.steps, code, \"steps\", ctx),\n };\n case \"PipeParallel\":\n return {\n ...base,\n type,\n pipe_category: \"PipeController\",\n parallel_sub_pipes: normalizeSubPipeList(raw.branches, code, \"branches\", ctx),\n add_each_output: raw.add_each_output === true,\n combined_output: strOrNull(raw.combined_output),\n };\n case \"PipeCondition\": {\n const outcomeMap: Record<string, string> = {};\n if (isPlainObject(raw.outcomes)) {\n for (const [outcome, pipeRef] of Object.entries(raw.outcomes)) {\n if (typeof pipeRef === \"string\" && pipeRef.length > 0) {\n outcomeMap[outcome] = pipeRef;\n } else {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"invalid-pipe-entry\",\n message: `pipe \"${code}\": outcome \"${outcome}\" is not a pipe ref — skipped`,\n path: `pipe.${code}.outcomes.${outcome}`,\n });\n }\n }\n }\n return {\n ...base,\n type,\n pipe_category: \"PipeController\",\n expression: strOrNull(raw.expression) ?? strOrNull(raw.expression_template) ?? \"\",\n outcome_map: outcomeMap,\n default_outcome: strOrNull(raw.default_outcome) ?? \"\",\n add_alias_from_expression_to: strOrNull(raw.add_alias_from_expression_to),\n };\n }\n case \"PipeBatch\": {\n const branchPipeCode = strOrNull(raw.branch_pipe_code);\n if (branchPipeCode === null) {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"invalid-pipe-entry\",\n message: `pipe \"${code}\": PipeBatch without branch_pipe_code`,\n path: `pipe.${code}.branch_pipe_code`,\n });\n }\n return {\n ...base,\n type,\n pipe_category: \"PipeController\",\n branch_pipe_code: branchPipeCode ?? \"\",\n batch_params: {\n input_list_stuff_name: strOrNull(raw.input_list_name) ?? \"\",\n input_item_stuff_name: strOrNull(raw.input_item_name) ?? \"\",\n },\n };\n }\n case \"PipeLLM\": {\n const systemPrompt = strOrNull(raw.system_prompt);\n const prompt = strOrNull(raw.prompt);\n return {\n ...base,\n type,\n pipe_category: \"PipeOperator\",\n llm_prompt_spec: {\n templating_style: null,\n system_prompt_blueprint:\n systemPrompt === null ? null : makeTemplate(systemPrompt, \"llm_prompt\"),\n prompt_blueprint: prompt === null ? null : makeTemplate(prompt, \"llm_prompt\"),\n user_image_references: null,\n user_document_references: null,\n system_image_references: null,\n system_document_references: null,\n },\n llm_choices: {\n for_text: modelToString(raw.model),\n for_object: modelToString(raw.model_to_structure),\n },\n structuring_method: strOrNull(raw.structuring_method),\n output_multiplicity: null,\n };\n }\n case \"PipeStructure\": {\n const inputNames = Object.keys(base.inputs);\n const llmChoice = isPlainObject(raw.model) ? raw.model : strOrNull(raw.model);\n return {\n ...base,\n type,\n pipe_category: \"PipeOperator\",\n llm_choice: llmChoice,\n text_input_name: inputNames[0] ?? \"text\",\n output_multiplicity: null,\n };\n }\n case \"PipeExtract\": {\n // Mirrors the runtime PipeExtractFactory: the (single) input is either\n // image-like or document-like, and exactly one of the two stuff names is\n // set. Statically, \"compatible with native.Image\" approximates to the\n // concept being Image or refining it; anything else counts as a document.\n const isImageLike = (spec: StuffSpecInfo): boolean =>\n (spec.concept.domain_code === NATIVE_DOMAIN && spec.concept.code === \"Image\") ||\n spec.concept.refines === `${NATIVE_DOMAIN}.Image`;\n const inputEntries = Object.entries(base.inputs);\n const imageInput = inputEntries.find(([, spec]) => isImageLike(spec));\n const documentInput = imageInput === undefined ? inputEntries[0] : undefined;\n return {\n ...base,\n type,\n pipe_category: \"PipeOperator\",\n extract_choice: modelToString(raw.model),\n should_caption_images: raw.page_image_captions === true,\n max_page_images: intOrNull(raw.max_page_images),\n should_include_page_views: raw.page_views === true,\n page_views_dpi: intOrNull(raw.page_views_dpi),\n render_js: boolOrNull(raw.render_js),\n include_raw_html: boolOrNull(raw.include_raw_html),\n image_stuff_name: imageInput?.[0] ?? null,\n document_stuff_name: documentInput?.[0] ?? null,\n };\n }\n case \"PipeSearch\":\n return {\n ...base,\n type,\n pipe_category: \"PipeOperator\",\n search_choice: modelToString(raw.model),\n prompt_blueprint: makeTemplate(strOrNull(raw.prompt) ?? \"\", \"basic\"),\n include_images_override: boolOrNull(raw.include_images),\n max_results_override: intOrNull(raw.max_results),\n from_date: strOrNull(raw.from_date),\n to_date: strOrNull(raw.to_date),\n include_domains: stringArrayOrNull(raw.include_domains),\n exclude_domains: stringArrayOrNull(raw.exclude_domains),\n is_structured_output: false,\n };\n case \"PipeImgGen\": {\n const prompt = strOrNull(raw.prompt);\n const negativePrompt = strOrNull(raw.negative_prompt);\n const seed = intOrNull(raw.seed) ?? (raw.seed === \"auto\" ? \"auto\" : null);\n return {\n ...base,\n type,\n pipe_category: \"PipeOperator\",\n img_gen_prompt_blueprint: {\n prompt_blueprint: prompt === null ? null : makeTemplate(prompt, \"img_gen_prompt\"),\n negative_prompt_blueprint:\n negativePrompt === null ? null : makeTemplate(negativePrompt, \"img_gen_prompt\"),\n image_references: null,\n },\n img_gen_choice: modelToString(raw.model),\n aspect_ratio: strOrNull(raw.aspect_ratio),\n is_raw: boolOrNull(raw.is_raw),\n seed,\n background: strOrNull(raw.background),\n output_format: strOrNull(raw.output_format),\n output_multiplicity:\n typeof base.output.multiplicity === \"number\" ? base.output.multiplicity : 1,\n };\n }\n case \"PipeCompose\": {\n const rawTemplate = raw.template;\n let template: string | null = null;\n let templatingStyle: string | null = null;\n let category = \"basic\";\n let extraContext: Record<string, unknown> | null = null;\n if (typeof rawTemplate === \"string\") {\n template = rawTemplate;\n } else if (isPlainObject(rawTemplate)) {\n template = strOrNull(rawTemplate.template);\n templatingStyle = strOrNull(rawTemplate.templating_style);\n category = strOrNull(rawTemplate.category) ?? category;\n extraContext = isPlainObject(rawTemplate.extra_context) ? rawTemplate.extra_context : null;\n }\n return {\n ...base,\n type,\n pipe_category: \"PipeOperator\",\n template,\n templating_style: templatingStyle,\n category,\n extra_context: extraContext,\n construct_blueprint: normalizeConstruct(raw.construct),\n };\n }\n case \"PipeFunc\":\n return { ...base, type, pipe_category: \"PipeOperator\" };\n case \"PipeSignature\": {\n const signatureFor = strOrNull(raw.signature_for);\n return {\n ...base,\n type,\n pipe_category: null,\n signature_for:\n signatureFor !== null && KNOWN_PIPE_TYPES.has(signatureFor)\n ? (signatureFor as PipeType)\n : null,\n };\n }\n default: {\n const _exhaustive: never = type;\n return _exhaustive;\n }\n }\n}\n","// ─── mergeBundles: ParsedBundle[] → MergedMethodSet ──────────────────────────\n// A method package may span several `.mthds` files; files sharing a domain\n// merge into one namespace. Duplicate codes keep the first declaration and\n// record a diagnostic. After merging, io concept stubs are re-pointed at the\n// declarations that other files contributed (a pipe in file A can reference a\n// concept declared in file B).\n\nimport type { PipeBlueprintUnion, StuffSpecInfo } from \"@graph/types\";\n\nimport type { Diagnostic, DomainNamespace, MergedMethodSet, ParsedBundle } from \"./types\";\nimport { UNKNOWN_DOMAIN } from \"./types\";\n\nfunction enrichPipeConcepts(\n pipe: PipeBlueprintUnion,\n domains: Record<string, DomainNamespace>,\n): PipeBlueprintUnion {\n const enrichSpec = (spec: StuffSpecInfo): StuffSpecInfo => {\n const declared = domains[spec.concept.domain_code]?.concepts[spec.concept.code];\n return declared !== undefined && declared !== spec.concept\n ? { ...spec, concept: declared }\n : spec;\n };\n const inputs: Record<string, StuffSpecInfo> = {};\n for (const [name, spec] of Object.entries(pipe.inputs)) {\n inputs[name] = enrichSpec(spec);\n }\n return { ...pipe, inputs, output: enrichSpec(pipe.output) };\n}\n\n/**\n * Merge parsed bundles into one namespace per domain. Order matters: on\n * duplicate codes the first bundle wins. `mainDomain` and `mainPipe` are taken\n * together from the first bundle declaring `main_pipe`, so a bare entry ref\n * always resolves in its declaring bundle's namespace; when no bundle declares\n * one, `mainDomain` falls back to the first domained bundle. `description`\n * comes from the first bundle that declares it.\n */\nexport function mergeBundles(bundles: ParsedBundle[]): MergedMethodSet {\n const diagnostics: Diagnostic[] = [];\n const domains: Record<string, DomainNamespace> = {};\n let mainDomain: string | null = null;\n let mainPipe: string | null = null;\n let description: string | null = null;\n\n for (const bundle of bundles) {\n const domain = bundle.domain ?? UNKNOWN_DOMAIN;\n const namespace = (domains[domain] ??= { domain, concepts: {}, pipes: {} });\n if (mainDomain === null && bundle.domain !== null) mainDomain = bundle.domain;\n if (mainPipe === null && bundle.main_pipe !== null) {\n mainPipe = bundle.main_pipe;\n // A bare main_pipe must resolve in the namespace of the bundle declaring\n // it, not whichever bundle happened to come first.\n mainDomain = domain;\n }\n if (description === null && bundle.description !== null) description = bundle.description;\n\n for (const [code, concept] of Object.entries(bundle.concepts)) {\n if (code in namespace.concepts) {\n diagnostics.push({\n severity: \"warning\",\n code: \"duplicate-concept\",\n message: `concept \"${domain}.${code}\" declared more than once — keeping the first declaration`,\n path: `concept.${code}`,\n domain_code: domain,\n });\n continue;\n }\n namespace.concepts[code] = concept;\n }\n for (const [code, pipe] of Object.entries(bundle.pipes)) {\n if (code in namespace.pipes) {\n diagnostics.push({\n severity: \"warning\",\n code: \"duplicate-pipe\",\n message: `pipe \"${domain}.${code}\" declared more than once — keeping the first declaration`,\n path: `pipe.${code}`,\n domain_code: domain,\n });\n continue;\n }\n namespace.pipes[code] = pipe;\n }\n }\n\n for (const namespace of Object.values(domains)) {\n for (const [code, pipe] of Object.entries(namespace.pipes)) {\n namespace.pipes[code] = enrichPipeConcepts(pipe, domains);\n }\n }\n\n return { domains, mainDomain, mainPipe, description, diagnostics };\n}\n","// ─── Static graph builder: MergedMethodSet → GraphSpec ──────────────────────\n// The static walk from the design doc (wip/static-graph-design.md): walk pipe\n// *invocations* starting at the entry pipe, maintaining a scope (the static\n// mirror of working memory), and emit a GraphSpec with `meta.mode: \"static\"`\n// that the existing GraphViewer renders unchanged.\n//\n// Identity is deterministic: node ids are invocation paths\n// (`screening.process_cv/step_2/...`) and stuff digests are the raw strings\n// `<producer_node_id>:<name>` (external inputs: `input:<name>`). The UI treats\n// digests as opaque unique keys, so the raw string — collision-free by\n// construction and readable in snapshots — is preferred over a hash.\n//\n// Everything is best-effort: unresolvable refs skip the child, cycles render\n// as leaves, dependency-alias refs (`alias->pipe`) render as opaque leaf\n// cards. This module never throws on content.\n\nimport type {\n ConceptInfo,\n GraphSpec,\n GraphSpecEdge,\n GraphSpecEdgeKind,\n GraphSpecNode,\n GraphSpecNodeIoItem,\n PipeBatchBlueprint,\n PipeBlueprintUnion,\n PipeConditionBlueprint,\n PipeParallelBlueprint,\n PipeSequenceBlueprint,\n PipeType,\n SubPipeSpec,\n} from \"@graph/types\";\n\nimport { nativeConceptInfo } from \"./conceptRefs\";\nimport { mergeBundles } from \"./mergeBundles\";\nimport { parseMthdsBundle } from \"./parseMthdsBundle\";\nimport type { Diagnostic, DomainNamespace, MergedMethodSet } from \"./types\";\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\nexport interface StaticGraphOptions {\n /**\n * Pipe ref to walk from (`code` or `domain.code`). Defaults to the merged\n * set's `main_pipe`, falling back to a root heuristic (first pipe no other\n * pipe references) when none is declared.\n */\n entryPipe?: string;\n}\n\nexport interface StaticGraphResult {\n spec: GraphSpec;\n diagnostics: Diagnostic[];\n}\n\n/** Build a static GraphSpec from an already-parsed, merged method set. */\nexport function buildStaticGraphSpec(\n set: MergedMethodSet,\n options: StaticGraphOptions = {},\n): StaticGraphResult {\n const diagnostics: Diagnostic[] = [];\n const ctx: WalkCtx = {\n set,\n nodes: [],\n edges: [],\n pipeRegistry: {},\n conceptRegistry: {},\n stuffByDigest: new Map(),\n diagnostics,\n stack: [],\n edgeSeq: 0,\n };\n\n // Registries carry every parsed entry (the dry-run path often ships them\n // empty — populating them is what makes detail panels rich). Registered\n // before the walk so synthetic entries minted during it never clobber a\n // declared one.\n for (const namespace of Object.values(set.domains)) {\n for (const concept of Object.values(namespace.concepts)) registerConcept(ctx, concept);\n for (const pipe of Object.values(namespace.pipes)) {\n ctx.pipeRegistry[`${pipe.domain_code}.${pipe.code}`] = pipe;\n for (const spec of Object.values(pipe.inputs)) registerConcept(ctx, spec.concept);\n registerConcept(ctx, pipe.output.concept);\n }\n }\n\n const entry = pickEntryPipe(set, options.entryPipe ?? null, diagnostics);\n if (entry !== null) {\n walkPipe(ctx, entry.code, entry.domain, `${entry.domain}.${entry.code}`, null, new Map(), {\n resultName: null,\n outputMultiplicity: null,\n });\n }\n\n const spec: GraphSpec = {\n nodes: ctx.nodes,\n edges: ctx.edges,\n meta: { format: \"mthds\", mode: \"static\" },\n pipe_registry: ctx.pipeRegistry,\n concept_registry: ctx.conceptRegistry,\n };\n if (entry !== null) {\n spec.pipeline_ref = { domain: entry.domain, main_pipe: entry.code };\n }\n return { spec, diagnostics };\n}\n\n/**\n * Convenience wrapper: parse one or more `.mthds` TOML strings, merge them,\n * and build the static GraphSpec. Diagnostics from all three stages are\n * concatenated in order (parse, merge, build).\n */\nexport function buildStaticGraphSpecFromToml(\n tomlTexts: string | string[],\n options: StaticGraphOptions = {},\n): StaticGraphResult {\n const texts = Array.isArray(tomlTexts) ? tomlTexts : [tomlTexts];\n const parsed = texts.map((text) => parseMthdsBundle(text));\n const merged = mergeBundles(parsed.map((result) => result.bundle));\n const built = buildStaticGraphSpec(merged, options);\n return {\n spec: built.spec,\n diagnostics: [\n ...parsed.flatMap((result) => result.diagnostics),\n ...merged.diagnostics,\n ...built.diagnostics,\n ],\n };\n}\n\n// ─── Walk state ──────────────────────────────────────────────────────────────\n\n/** A scope entry — the static mirror of a working-memory stuff. */\ninterface StuffRecord {\n digest: string;\n name: string;\n concept: ConceptInfo;\n multiplicity: number | boolean | null;\n}\n\ntype Scope = Map<string, StuffRecord>;\n\ninterface WalkCtx {\n set: MergedMethodSet;\n nodes: GraphSpecNode[];\n edges: GraphSpecEdge[];\n pipeRegistry: Record<string, PipeBlueprintUnion>;\n conceptRegistry: Record<string, ConceptInfo>;\n stuffByDigest: Map<string, StuffRecord>;\n diagnostics: Diagnostic[];\n /** Qualified refs (`domain.code`) on the recursion stack — the cycle guard. */\n stack: string[];\n edgeSeq: number;\n}\n\n/** How a pipe is being invoked — the step/branch/outcome context. */\ninterface Invocation {\n /** The enclosing step's `result` name — names the operator's output stuff. */\n resultName: string | null;\n /** The enclosing step's `nb_output`/`multiple_output` override. */\n outputMultiplicity: SubPipeSpec[\"output_multiplicity\"];\n /** Set on condition children: the outcome value that routes here. */\n outcomeValue?: string;\n}\n\ninterface WalkResult {\n nodeId: string;\n /** Primary output stuff — what a sequence step's `result` binds to. */\n output: StuffRecord | null;\n /** Extra bindings a parallel with `add_each_output` exposes to the enclosing scope. */\n eachOutputs: [string, StuffRecord][];\n}\n\n// ─── Entry pipe selection ────────────────────────────────────────────────────\n\ntype PipeResolution =\n | { kind: \"resolved\"; blueprint: PipeBlueprintUnion; domain: string; code: string }\n | { kind: \"opaque\" }\n | { kind: \"unresolved\" };\n\n/**\n * Resolve a pipe ref against the merged set: bare refs in the current domain\n * (same-domain files are already merged into one namespace), `domain.code`\n * refs in the named domain. `alias->…` dependency refs are opaque in phase 1.\n */\nfunction resolvePipeRef(set: MergedMethodSet, ref: string, currentDomain: string): PipeResolution {\n if (ref.includes(\"->\")) return { kind: \"opaque\" };\n const dot = ref.lastIndexOf(\".\");\n const domain = dot === -1 ? currentDomain : ref.slice(0, dot);\n const code = dot === -1 ? ref : ref.slice(dot + 1);\n const blueprint = set.domains[domain]?.pipes[code];\n if (blueprint === undefined) return { kind: \"unresolved\" };\n return { kind: \"resolved\", blueprint, domain, code };\n}\n\n/** Sub-pipe refs appearing anywhere in a namespace — used by the root heuristic. */\nfunction referencedPipeCodes(namespace: DomainNamespace): Set<string> {\n const refs = new Set<string>();\n // Refs are authored strings: bare (`helper`) or qualified (`domain.helper`).\n // Reduce them to bare codes in this namespace, mirroring resolvePipeRef —\n // cross-domain and `alias->` refs can't name a pipe here, so they're dropped.\n const add = (ref: string): void => {\n if (ref === \"\" || ref.includes(\"->\")) return;\n const dot = ref.lastIndexOf(\".\");\n if (dot === -1) refs.add(ref);\n else if (ref.slice(0, dot) === namespace.domain) refs.add(ref.slice(dot + 1));\n };\n for (const pipe of Object.values(namespace.pipes)) {\n switch (pipe.type) {\n case \"PipeSequence\":\n for (const sub of pipe.sequential_sub_pipes) add(sub.pipe_code);\n break;\n case \"PipeParallel\":\n for (const sub of pipe.parallel_sub_pipes) add(sub.pipe_code);\n break;\n case \"PipeCondition\":\n for (const target of Object.values(pipe.outcome_map)) add(target);\n add(pipe.default_outcome);\n break;\n case \"PipeBatch\":\n add(pipe.branch_pipe_code);\n break;\n default:\n break;\n }\n }\n return refs;\n}\n\nfunction pickEntryPipe(\n set: MergedMethodSet,\n explicitRef: string | null,\n diagnostics: Diagnostic[],\n): { domain: string; code: string } | null {\n const domainsInOrder = Object.keys(set.domains);\n const fallbackDomain = set.mainDomain ?? domainsInOrder[0];\n if (fallbackDomain === undefined) {\n diagnostics.push({\n severity: \"error\",\n code: \"no-entry-pipe\",\n message: \"no bundles to build a graph from\",\n });\n return null;\n }\n\n const resolveEntry = (ref: string): { domain: string; code: string } | null => {\n const resolution = resolvePipeRef(set, ref, fallbackDomain);\n return resolution.kind === \"resolved\"\n ? { domain: resolution.domain, code: resolution.code }\n : null;\n };\n\n if (explicitRef !== null) {\n const entry = resolveEntry(explicitRef);\n if (entry === null) {\n diagnostics.push({\n severity: \"error\",\n code: \"unresolved-pipe-ref\",\n message: `entry pipe \"${explicitRef}\" not found in the method set`,\n });\n }\n return entry;\n }\n\n if (set.mainPipe !== null) {\n const entry = resolveEntry(set.mainPipe);\n if (entry !== null) return entry;\n diagnostics.push({\n severity: \"warning\",\n code: \"unresolved-pipe-ref\",\n message: `main_pipe \"${set.mainPipe}\" not found — falling back to a root heuristic`,\n // The owning bundle is known (the namespace that declares this main_pipe),\n // so stamp it — this is not an ownerless diagnostic.\n domain_code: fallbackDomain,\n });\n } else {\n diagnostics.push({\n severity: \"warning\",\n code: \"missing-main-pipe\",\n message: \"no main_pipe declared — falling back to a root heuristic\",\n domain_code: fallbackDomain,\n });\n }\n\n // Root heuristic: the first pipe (declaration order) that no other pipe in\n // its domain references; else the first pipe. Keeps half-written bundles\n // rendering something sensible.\n const domainWithPipes = [fallbackDomain, ...domainsInOrder].find(\n (domain) => Object.keys(set.domains[domain]?.pipes ?? {}).length > 0,\n );\n if (domainWithPipes === undefined) {\n diagnostics.push({\n severity: \"error\",\n code: \"no-entry-pipe\",\n message: \"no pipes found in any bundle\",\n });\n return null;\n }\n const namespace = set.domains[domainWithPipes];\n const referenced = referencedPipeCodes(namespace);\n const codes = Object.keys(namespace.pipes);\n const root = codes.find((code) => !referenced.has(code)) ?? codes[0];\n return { domain: domainWithPipes, code: root };\n}\n\n// ─── Small helpers ───────────────────────────────────────────────────────────\n\n/** `CamelCase` concept code → `snake_case` stuff name (the runtime's fallback naming). */\nfunction snakeCase(code: string): string {\n return code\n .replace(/([A-Z]+)([A-Z][a-z0-9])/g, \"$1_$2\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1_$2\")\n .toLowerCase();\n}\n\nfunction registerConcept(ctx: WalkCtx, concept: ConceptInfo): void {\n ctx.conceptRegistry[`${concept.domain_code}.${concept.code}`] ??= concept;\n}\n\n/**\n * Mint (or return the already-minted) stuff for a digest. First mint wins —\n * matching how the UI's stuff registry keeps the first occurrence per digest.\n */\nfunction mintStuff(\n ctx: WalkCtx,\n digest: string,\n name: string,\n concept: ConceptInfo,\n multiplicity: number | boolean | null,\n): StuffRecord {\n const existing = ctx.stuffByDigest.get(digest);\n if (existing !== undefined) return existing;\n const record: StuffRecord = { digest, name, concept, multiplicity };\n ctx.stuffByDigest.set(digest, record);\n registerConcept(ctx, concept);\n return record;\n}\n\n/**\n * An io item for `stuff`, optionally exposed under a *slot name* — the name\n * the invoking step binds it to (`result = \"x\"`). The runtime names a\n * controller's transparent output by its slot, while the producing operator\n * keeps the local name; the UI's stuff registry is first-occurrence-wins and\n * controllers are emitted before their children, so the slot name is what\n * renders (verified against the dry fixtures).\n */\nfunction ioItem(stuff: StuffRecord, slotName?: string | null): GraphSpecNodeIoItem {\n return { name: slotName ?? stuff.name, digest: stuff.digest, concept: stuff.concept.code };\n}\n\nfunction addEdge(\n ctx: WalkCtx,\n kind: GraphSpecEdgeKind,\n source: string,\n target: string,\n extras?: { label?: string; sourceStuff?: string; targetStuff?: string },\n): void {\n // Namespaced ids: the rendering pipeline synthesizes its own dataflow edges\n // named `edge_<n>` (graphBuilders.ts), so bare `edge_<n>` here would collide\n // in the ReactFlow key space.\n const edge: GraphSpecEdge = { id: `static:edge_${ctx.edgeSeq++}`, source, target, kind };\n if (extras?.label !== undefined) edge.label = extras.label;\n if (extras?.sourceStuff !== undefined) edge.source_stuff_digest = extras.sourceStuff;\n if (extras?.targetStuff !== undefined) edge.target_stuff_digest = extras.targetStuff;\n ctx.edges.push(edge);\n}\n\nfunction addNodeTag(node: GraphSpecNode, key: string, value: string): void {\n node.tags = { ...(node.tags ?? {}), [key]: value };\n}\n\nfunction formatBatchMultiplicity(multiplicity: number | boolean | null | undefined): string {\n if (typeof multiplicity === \"number\") return `x${multiplicity}`;\n if (multiplicity === true) return \"xmany\";\n return \"x?\";\n}\n\n/**\n * Working-memory name matching: exact name first, then dotted-prefix — an\n * input `a.b` is satisfied by a binding for `a`.\n */\nfunction lookupScope(scope: Scope, name: string): StuffRecord | undefined {\n let candidate = name;\n for (;;) {\n const found = scope.get(candidate);\n if (found !== undefined) return found;\n const dot = candidate.lastIndexOf(\".\");\n if (dot <= 0) return undefined;\n candidate = candidate.slice(0, dot);\n }\n}\n\nfunction conceptKey(concept: ConceptInfo): string {\n return `${concept.domain_code}.${concept.code}`;\n}\n\n/**\n * Bind the invoked pipe's declared inputs from the caller's scope. A name the\n * scope cannot satisfy is a *dangling* input: mint an input stuff\n * (`input:<name>`) with the declared concept — at the method root these are\n * exactly the method's external inputs, and the UI classifies producer-less\n * stuff as role `input`. The `input:` digest namespace is method-global on\n * purpose: an unbound name means the same missing working-memory entry\n * wherever it is read, so all its consumers share one stuff. When two\n * consumers declare *different* concepts for that shared name, the first\n * mint wins and a diagnostic surfaces the authoring inconsistency.\n *\n * Minted dangling inputs are written into `scope`: working memory is one flat\n * namespace shared down the walk (see the scope model note on `walkPipe`), so\n * later readers of the same name bind the same record.\n */\nfunction bindInputs(\n ctx: WalkCtx,\n blueprint: PipeBlueprintUnion,\n scope: Scope,\n): GraphSpecNodeIoItem[] {\n const ioInputs: GraphSpecNodeIoItem[] = [];\n for (const [name, spec] of Object.entries(blueprint.inputs)) {\n let bound = lookupScope(scope, name);\n if (bound === undefined) {\n bound = mintStuff(ctx, `input:${name}`, name, spec.concept, spec.multiplicity);\n scope.set(name, bound);\n if (conceptKey(bound.concept) !== conceptKey(spec.concept)) {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"conflicting-input-concept\",\n message:\n `pipe \"${blueprint.code}\": dangling input \"${name}\" is declared as ` +\n `${conceptKey(spec.concept)} here but was first seen as ` +\n `${conceptKey(bound.concept)} — keeping the first`,\n path: `pipe.${blueprint.code}.inputs.${name}`,\n domain_code: blueprint.domain_code,\n });\n }\n }\n ioInputs.push(ioItem(bound));\n }\n return ioInputs;\n}\n\nfunction emitNode(\n ctx: WalkCtx,\n args: {\n id: string;\n kind: \"controller\" | \"operator\";\n pipeCode: string;\n pipeType: PipeType;\n description: string;\n domainCode: string;\n ioInputs: GraphSpecNodeIoItem[];\n parentId: string | null;\n inv: Invocation;\n },\n): GraphSpecNode {\n const node: GraphSpecNode = {\n id: args.id,\n kind: args.kind,\n pipe_code: args.pipeCode,\n pipe_type: args.pipeType,\n // validateGraphSpec requires a non-empty description; WIP pipes may lack one.\n description: args.description.length > 0 ? args.description : args.pipeCode,\n domain_code: args.domainCode,\n status: \"scheduled\",\n io: { inputs: args.ioInputs, outputs: [] },\n };\n if (args.inv.outcomeValue !== undefined) node.tags = { outcome: args.inv.outcomeValue };\n ctx.nodes.push(node);\n if (args.parentId !== null) {\n addEdge(\n ctx,\n \"contains\",\n args.parentId,\n args.id,\n args.inv.outcomeValue !== undefined ? { label: args.inv.outcomeValue } : undefined,\n );\n }\n return node;\n}\n\n// ─── The walk ────────────────────────────────────────────────────────────────\n\n/**\n * Walk one pipe *invocation*: resolve the ref, emit the node (and its\n * `contains` edge), bind inputs from the caller's scope, recurse per\n * controller type, and report the invocation's output stuff.\n *\n * Scope model — the static mirror of the runtime's working memory, which is\n * ONE flat namespace shared across the whole run (verified against the dry\n * fixtures: a result produced inside a nested sub-sequence is consumed by a\n * later step of an ancestor sequence). So: sequence steps see and mutate the\n * caller's scope *object*; parallel/batch branches and condition outcome\n * children each get a *copy* — branches because the runtime forks memory per\n * branch and merges back only the declared outputs, condition outcomes\n * because they are mutually exclusive alternatives (only one runs, so no\n * branch's writes may be visible to its siblings or, beyond the condition's\n * representative output, to the caller).\n */\nfunction walkPipe(\n ctx: WalkCtx,\n ref: string,\n currentDomain: string,\n nodeId: string,\n parentId: string | null,\n scope: Scope,\n inv: Invocation,\n): WalkResult | null {\n const resolution = resolvePipeRef(ctx.set, ref, currentDomain);\n if (resolution.kind === \"unresolved\") {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"unresolved-pipe-ref\",\n message: `pipe ref \"${ref}\" cannot be resolved — node skipped`,\n path: nodeId,\n // The uttering file's domain: a bare ref belongs to the namespace that\n // wrote it, mirroring the runtime's `_qualify_pipe_ref` inference.\n domain_code: currentDomain,\n });\n return null;\n }\n if (resolution.kind === \"opaque\") {\n return emitOpaqueLeaf(ctx, ref, currentDomain, nodeId, parentId, inv);\n }\n\n const { blueprint, domain, code } = resolution;\n const qualified = `${domain}.${code}`;\n const ioInputs = bindInputs(ctx, blueprint, scope);\n const node = emitNode(ctx, {\n id: nodeId,\n kind: blueprint.pipe_category === \"PipeController\" ? \"controller\" : \"operator\",\n pipeCode: code,\n pipeType: blueprint.type,\n description: blueprint.description,\n domainCode: blueprint.domain_code,\n ioInputs,\n parentId,\n inv,\n });\n\n if (ctx.stack.includes(qualified)) {\n ctx.diagnostics.push({\n severity: \"warning\",\n code: \"cyclic-pipe-ref\",\n message: `pipe \"${qualified}\" is invoked recursively — rendered as a leaf`,\n path: nodeId,\n domain_code: domain,\n });\n return finishLeaf(ctx, node, blueprint, nodeId, inv);\n }\n\n ctx.stack.push(qualified);\n try {\n switch (blueprint.type) {\n case \"PipeSequence\":\n return finishSequence(ctx, node, blueprint, nodeId, scope, inv);\n case \"PipeParallel\":\n return finishParallel(ctx, node, blueprint, nodeId, scope, inv);\n case \"PipeCondition\":\n return finishCondition(ctx, node, blueprint, nodeId, scope, inv);\n case \"PipeBatch\":\n return finishBatch(ctx, node, blueprint, nodeId, scope, inv);\n default:\n return finishLeaf(ctx, node, blueprint, nodeId, inv);\n }\n } finally {\n ctx.stack.pop();\n }\n}\n\n/**\n * A step (or branch) invocation: a step carrying inline `batch_over`/`batch_as`\n * becomes a synthetic PipeBatch node wrapping the invoked pipe — mirroring the\n * runtime, which materializes `<pipe>_batch` controllers for inline batching.\n */\nfunction walkSubPipe(\n ctx: WalkCtx,\n sub: SubPipeSpec,\n domain: string,\n nodeId: string,\n parentId: string,\n scope: Scope,\n): WalkResult | null {\n if (sub.batch_params !== null) {\n return walkInlineBatch(ctx, sub, domain, nodeId, parentId, scope);\n }\n return walkPipe(ctx, sub.pipe_code, domain, nodeId, parentId, scope, {\n resultName: sub.output_name,\n outputMultiplicity: sub.output_multiplicity,\n });\n}\n\n// ─── Leaf (operators, signatures, cyclic refs) ───────────────────────────────\n\nfunction finishLeaf(\n ctx: WalkCtx,\n node: GraphSpecNode,\n blueprint: PipeBlueprintUnion,\n nodeId: string,\n inv: Invocation,\n): WalkResult {\n const name = inv.resultName ?? snakeCase(blueprint.output.concept.code);\n const multiplicity =\n typeof inv.outputMultiplicity === \"number\" || inv.outputMultiplicity === true\n ? inv.outputMultiplicity\n : blueprint.output.multiplicity;\n const output = mintStuff(ctx, `${nodeId}:${name}`, name, blueprint.output.concept, multiplicity);\n node.io.outputs = [ioItem(output)];\n return { nodeId, output, eachOutputs: [] };\n}\n\n/** Phase-1 policy for `alias->…` dependency refs: an opaque leaf card. */\nfunction emitOpaqueLeaf(\n ctx: WalkCtx,\n ref: string,\n currentDomain: string,\n nodeId: string,\n parentId: string | null,\n inv: Invocation,\n): WalkResult {\n const alias = ref.slice(0, ref.indexOf(\"->\"));\n const tail = ref.slice(ref.lastIndexOf(\"->\") + 2);\n const codeTail = tail.slice(tail.lastIndexOf(\".\") + 1);\n const node = emitNode(ctx, {\n id: nodeId,\n kind: \"operator\",\n pipeCode: codeTail.length > 0 ? codeTail : ref,\n pipeType: \"PipeSignature\",\n description: `External pipe from dependency \"${alias}\"`,\n domainCode: alias.length > 0 ? alias : currentDomain,\n ioInputs: [],\n parentId,\n inv,\n });\n const name = inv.resultName ?? \"output\";\n const output = mintStuff(ctx, `${nodeId}:${name}`, name, nativeConceptInfo(\"Anything\"), null);\n node.io.outputs = [ioItem(output)];\n return { nodeId, output, eachOutputs: [] };\n}\n\n// ─── Controllers ─────────────────────────────────────────────────────────────\n\nfunction finishSequence(\n ctx: WalkCtx,\n node: GraphSpecNode,\n blueprint: PipeSequenceBlueprint,\n nodeId: string,\n scope: Scope,\n inv: Invocation,\n): WalkResult {\n let lastOutput: StuffRecord | null = null;\n blueprint.sequential_sub_pipes.forEach((sub, index) => {\n const result = walkSubPipe(\n ctx,\n sub,\n blueprint.domain_code,\n `${nodeId}/step_${index + 1}`,\n nodeId,\n scope,\n );\n if (result === null) return;\n if (result.output !== null) {\n if (sub.output_name !== null) scope.set(sub.output_name, result.output);\n lastOutput = result.output;\n }\n for (const [name, stuff] of result.eachOutputs) scope.set(name, stuff);\n });\n // Controller transparency: the sequence's output IS its last producing\n // step's stuff — same digest, so downstream consumers wire to the real\n // producer (the UI only takes producers from non-controller nodes).\n node.io.outputs = lastOutput === null ? [] : [ioItem(lastOutput, inv.resultName)];\n return { nodeId, output: lastOutput, eachOutputs: [] };\n}\n\nfunction finishParallel(\n ctx: WalkCtx,\n node: GraphSpecNode,\n blueprint: PipeParallelBlueprint,\n nodeId: string,\n scope: Scope,\n inv: Invocation,\n): WalkResult {\n const branchResults: { sub: SubPipeSpec; result: WalkResult }[] = [];\n blueprint.parallel_sub_pipes.forEach((sub, index) => {\n // Branches are independent: each gets its own copy of the inherited scope.\n const result = walkSubPipe(\n ctx,\n sub,\n blueprint.domain_code,\n `${nodeId}/branch_${index + 1}`,\n nodeId,\n new Map(scope),\n );\n if (result !== null) branchResults.push({ sub, result });\n });\n\n const eachOutputs: [string, StuffRecord][] = [];\n if (blueprint.add_each_output) {\n for (const { sub, result } of branchResults) {\n if (sub.output_name !== null && result.output !== null) {\n eachOutputs.push([sub.output_name, result.output]);\n }\n }\n }\n\n const combinedName =\n blueprint.combined_output ?? inv.resultName ?? snakeCase(blueprint.output.concept.code);\n const combined = mintStuff(\n ctx,\n `${nodeId}:${combinedName}`,\n combinedName,\n blueprint.output.concept,\n blueprint.output.multiplicity,\n );\n for (const { result } of branchResults) {\n if (result.output !== null) {\n addEdge(ctx, \"parallel_combine\", result.nodeId, nodeId, {\n sourceStuff: result.output.digest,\n targetStuff: combined.digest,\n });\n }\n }\n node.io.outputs = [ioItem(combined, inv.resultName)];\n return { nodeId, output: combined, eachOutputs };\n}\n\nfunction finishCondition(\n ctx: WalkCtx,\n node: GraphSpecNode,\n blueprint: PipeConditionBlueprint,\n nodeId: string,\n scope: Scope,\n inv: Invocation,\n): WalkResult {\n const conditionScope: Scope = new Map(scope);\n if (blueprint.add_alias_from_expression_to !== null) {\n const alias = blueprint.add_alias_from_expression_to;\n // The alias points at whatever the expression evaluates to at run time —\n // statically typed as native.Dynamic.\n conditionScope.set(\n alias,\n mintStuff(ctx, `${nodeId}:${alias}`, alias, nativeConceptInfo(\"Dynamic\"), null),\n );\n }\n\n // One child node per distinct *target pipe*, not per outcome value —\n // mirroring the runtime tracer. Outcomes routing to the same pipe (often\n // one value plus `default_outcome`) merge into a single child carrying all\n // its routing values. `fail` / `continue` are outcome actions, not refs.\n // The default route is tracked as a flag, never as a value string — an\n // *authored* outcome value literally named \"default\" must not collide with\n // the synthetic default sentinel (node ids and primary selection key on it).\n interface RouteEntry {\n values: string[];\n ref: string;\n viaDefault: boolean;\n }\n const targets: RouteEntry[] = [];\n const byRef = new Map<string, RouteEntry>();\n const addRoute = (value: string, ref: string, isDefault: boolean): void => {\n if (ref === \"\" || ref === \"fail\" || ref === \"continue\") return;\n const existing = byRef.get(ref);\n if (existing !== undefined) {\n existing.values.push(value);\n existing.viaDefault ||= isDefault;\n return;\n }\n const entry = { values: [value], ref, viaDefault: isDefault };\n byRef.set(ref, entry);\n targets.push(entry);\n };\n for (const [value, target] of Object.entries(blueprint.outcome_map)) {\n addRoute(value, target, false);\n }\n addRoute(\"default\", blueprint.default_outcome, true);\n\n const results: { entry: RouteEntry; result: WalkResult }[] = [];\n for (const entry of targets) {\n const idSegment =\n entry.viaDefault && entry.values.length === 1 ? \"default\" : `outcome_${entry.values[0]}`;\n const result = walkPipe(\n ctx,\n entry.ref,\n blueprint.domain_code,\n `${nodeId}/${idSegment}`,\n nodeId,\n new Map(conditionScope),\n {\n // The runtime stores whichever branch runs under the condition's own\n // slot name, so every branch's output carries it (dry-run parity).\n resultName: inv.resultName,\n outputMultiplicity: null,\n outcomeValue: entry.values.join(\" | \"),\n },\n );\n if (result !== null) results.push({ entry, result });\n }\n\n // Statically all outcomes exist; pick one representative output for the\n // controller (the default route when present, else the first producing\n // outcome) so downstream consumers wire to a real producer.\n const primary =\n results.find(({ entry, result }) => entry.viaDefault && result.output !== null)?.result\n .output ??\n results.find(({ result }) => result.output !== null)?.result.output ??\n null;\n node.io.outputs = primary === null ? [] : [ioItem(primary, inv.resultName)];\n return { nodeId, output: primary, eachOutputs: [] };\n}\n\nfunction finishBatch(\n ctx: WalkCtx,\n node: GraphSpecNode,\n blueprint: PipeBatchBlueprint,\n nodeId: string,\n scope: Scope,\n inv: Invocation,\n): WalkResult {\n const params = blueprint.batch_params;\n\n let listStuff: StuffRecord | null = null;\n if (params.input_list_stuff_name !== \"\") {\n const bound = lookupScope(scope, params.input_list_stuff_name);\n if (bound !== undefined) {\n listStuff = bound;\n } else {\n // The list name is not among the declared inputs (sloppy but legal WIP\n // state): mint it as a dangling input and surface it on the node's io.\n listStuff = mintStuff(\n ctx,\n `input:${params.input_list_stuff_name}`,\n params.input_list_stuff_name,\n nativeConceptInfo(\"Anything\"),\n true,\n );\n node.io.inputs.push(ioItem(listStuff));\n }\n }\n\n let itemStuff: StuffRecord | null = null;\n const branchScope: Scope = new Map(scope);\n if (params.input_item_stuff_name !== \"\" && listStuff !== null) {\n // The item is one element of the list: same concept, single multiplicity.\n itemStuff = mintStuff(\n ctx,\n `${nodeId}:${params.input_item_stuff_name}`,\n params.input_item_stuff_name,\n listStuff.concept,\n null,\n );\n branchScope.set(params.input_item_stuff_name, itemStuff);\n }\n\n const batchMultiplicity = formatBatchMultiplicity(listStuff?.multiplicity);\n addNodeTag(node, \"batch_multiplicity\", batchMultiplicity);\n\n // One representative branch, not N — this is a method view, not a run trace.\n let branchResult: WalkResult | null = null;\n if (blueprint.branch_pipe_code !== \"\") {\n branchResult = walkPipe(\n ctx,\n blueprint.branch_pipe_code,\n blueprint.domain_code,\n `${nodeId}/batch_branch`,\n nodeId,\n branchScope,\n { resultName: null, outputMultiplicity: null },\n );\n const branchNode = ctx.nodes.find((candidate) => candidate.id === branchResult?.nodeId);\n if (branchNode !== undefined) {\n addNodeTag(branchNode, \"batch_multiplicity\", batchMultiplicity);\n }\n }\n\n const aggConcept = branchResult?.output?.concept ?? blueprint.output.concept;\n const aggName = inv.resultName ?? snakeCase(aggConcept.code);\n const aggregate = mintStuff(ctx, `${nodeId}:${aggName}`, aggName, aggConcept, true);\n\n if (branchResult !== null && listStuff !== null && itemStuff !== null) {\n addEdge(ctx, \"batch_item\", nodeId, branchResult.nodeId, {\n sourceStuff: listStuff.digest,\n targetStuff: itemStuff.digest,\n });\n }\n if (branchResult?.output != null) {\n addEdge(ctx, \"batch_aggregate\", branchResult.nodeId, nodeId, {\n sourceStuff: branchResult.output.digest,\n targetStuff: aggregate.digest,\n });\n }\n\n node.io.outputs = [ioItem(aggregate)];\n return { nodeId, output: aggregate, eachOutputs: [] };\n}\n\n/** Synthesize the PipeBatch node the runtime materializes for an inline `batch_over` step. */\nfunction walkInlineBatch(\n ctx: WalkCtx,\n sub: SubPipeSpec,\n domain: string,\n nodeId: string,\n parentId: string,\n scope: Scope,\n): WalkResult {\n const params = sub.batch_params as NonNullable<SubPipeSpec[\"batch_params\"]>;\n // Bare code of the branch ref: strip a dependency alias (`helpers->clean`)\n // and a domain qualifier (`lib.clean`) so the synthetic code reads cleanly.\n const aliasIdx = sub.pipe_code.lastIndexOf(\"->\");\n const refTail = aliasIdx === -1 ? sub.pipe_code : sub.pipe_code.slice(aliasIdx + 2);\n const branchTail = refTail.slice(refTail.lastIndexOf(\".\") + 1);\n const branchResolution = resolvePipeRef(ctx.set, sub.pipe_code, domain);\n const branchBlueprint = branchResolution.kind === \"resolved\" ? branchResolution.blueprint : null;\n\n const listBinding = lookupScope(scope, params.input_list_stuff_name);\n const listConcept =\n listBinding?.concept ??\n branchBlueprint?.inputs[params.input_item_stuff_name]?.concept ??\n nativeConceptInfo(\"Anything\");\n const outputSpec = branchBlueprint?.output ?? {\n concept: nativeConceptInfo(\"Anything\"),\n multiplicity: null,\n };\n\n // Registry key: the detail panel resolves blueprints by `domain.pipe_code`,\n // so every distinct inline batch needs its own entry. Reuse the code only\n // when it already points at this exact batch (same branch, same params);\n // otherwise disambiguate with a numeric suffix (`x_batch`, `x_batch_2`, …).\n const baseCode = `${branchTail}_batch`;\n let code = baseCode;\n for (let suffix = 2; ; suffix++) {\n const existing = ctx.pipeRegistry[`${domain}.${code}`];\n if (\n existing === undefined ||\n (existing.type === \"PipeBatch\" &&\n existing.branch_pipe_code === sub.pipe_code &&\n existing.batch_params.input_list_stuff_name === params.input_list_stuff_name &&\n existing.batch_params.input_item_stuff_name === params.input_item_stuff_name)\n ) {\n break;\n }\n code = `${baseCode}_${suffix}`;\n }\n const blueprint: PipeBatchBlueprint = {\n type: \"PipeBatch\",\n pipe_category: \"PipeController\",\n code,\n domain_code: domain,\n description: `Batch processing for ${branchTail}`,\n inputs: { [params.input_list_stuff_name]: { concept: listConcept, multiplicity: null } },\n output: { concept: outputSpec.concept, multiplicity: null },\n branch_pipe_code: sub.pipe_code,\n batch_params: params,\n };\n ctx.pipeRegistry[`${domain}.${code}`] ??= blueprint;\n\n const ioInputs = bindInputs(ctx, blueprint, scope);\n const inv: Invocation = {\n resultName: sub.output_name,\n outputMultiplicity: sub.output_multiplicity,\n };\n const node = emitNode(ctx, {\n id: nodeId,\n kind: \"controller\",\n pipeCode: code,\n pipeType: \"PipeBatch\",\n description: blueprint.description,\n domainCode: domain,\n ioInputs,\n parentId,\n inv,\n });\n return finishBatch(ctx, node, blueprint, nodeId, scope, inv);\n}\n","// Bridge from static-analysis diagnostics to the viewer's validation panel.\n\nimport type { ValidationIssue } from \"@graph/types\";\nimport { makePipeRef } from \"@graph/pipeRefs\";\nimport type { Diagnostic } from \"./types\";\n\n/**\n * Derive the viewer targeting fields from a diagnostic's TOML-style `path`\n * plus its declaring-namespace `domain_code`.\n *\n * - A walk-phase path is a GraphSpec node id and contains `/` (e.g.\n * `demo.main_flow/step_2`) → `nodeId`. Checked first: node ids embed the\n * domain, so a prefix test alone could misread them.\n * - A declaration path `pipe.<code>[...]` qualified by the diagnostic's\n * `domain_code` → `pipeRef` (`domain_code.pipe_code`). A diagnostic without\n * `domain_code` cannot be qualified and stays panel-only — decorating on a\n * bare code would ring every same-code node across domains.\n * - Everything else (concept paths, bare section paths like `pipe`, root\n * entry-pipe ids without `/`, missing paths) has no graph target — those\n * issues stay panel-only.\n */\nfunction targetFromPath(\n path: string | undefined,\n domainCode: string | undefined,\n): Pick<ValidationIssue, \"pipeRef\" | \"nodeId\"> {\n if (!path) return {};\n if (path.includes(\"/\")) return { nodeId: path };\n if (path.startsWith(\"pipe.\")) {\n const code = path.split(\".\")[1];\n if (code && domainCode) return { pipeRef: makePipeRef(domainCode, code) };\n }\n return {};\n}\n\n/**\n * Project static-graph {@link Diagnostic}s onto the viewer's presentation shape\n * so a host can feed them straight into `GraphViewer`'s `validationIssues`.\n * The TOML-style `path` becomes the locator chip; `origin: \"static\"` lets the\n * panel (and the host's issue policy) distinguish them from validator verdicts.\n * When the path identifies a pipe declaration or a precise invocation, the\n * targeting fields (`pipeRef` / `nodeId`) are filled so the viewer can\n * decorate the affected graph nodes.\n */\nexport function staticDiagnosticsToValidationIssues(diagnostics: Diagnostic[]): ValidationIssue[] {\n return diagnostics.map((diagnostic) => ({\n severity: diagnostic.severity,\n message: diagnostic.message,\n context: diagnostic.path,\n origin: \"static\",\n ...targetFromPath(diagnostic.path, diagnostic.domain_code),\n }));\n}\n"],"mappings":"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","names":["spec","_a","_b"]}
|
|
@@ -432,7 +432,7 @@ type ValidationState = (typeof VALIDATION_STATE)[keyof typeof VALIDATION_STATE];
|
|
|
432
432
|
* which issues to show for each state (its validator's errors, the static
|
|
433
433
|
* analyzer's diagnostics, or a mix) and handles navigation on row click. The
|
|
434
434
|
* only fields the viewer interprets are the optional targeting fields
|
|
435
|
-
* (`
|
|
435
|
+
* (`pipeRef` / `nodeId`), which drive node decorations on the graph.
|
|
436
436
|
*/
|
|
437
437
|
interface ValidationIssue {
|
|
438
438
|
severity: "error" | "warning";
|
|
@@ -446,13 +446,17 @@ interface ValidationIssue {
|
|
|
446
446
|
/** Which analyzer produced the issue: the host's validator or the static parser. */
|
|
447
447
|
origin?: "validator" | "static";
|
|
448
448
|
/**
|
|
449
|
-
*
|
|
450
|
-
*
|
|
449
|
+
* Fully-qualified pipe ref (`domain_code.pipe_code`, see `makePipeRef`) this
|
|
450
|
+
* issue targets — decorates every rendered node invoking that pipe (a pipe
|
|
451
|
+
* can be invoked from several places in the graph). Always qualified, never a
|
|
452
|
+
* bare code: two domains may declare the same pipe code, and a bare match
|
|
453
|
+
* would ring every same-code node. An emitter that cannot qualify must leave
|
|
454
|
+
* the issue untargeted (panel-only) rather than decorate by guess.
|
|
451
455
|
*/
|
|
452
|
-
|
|
456
|
+
pipeRef?: string;
|
|
453
457
|
/**
|
|
454
458
|
* Precise invocation this issue targets — a GraphSpec node id (e.g.
|
|
455
|
-
* `demo.main_flow/step_2`). Takes precedence over `
|
|
459
|
+
* `demo.main_flow/step_2`). Takes precedence over `pipeRef` when both are
|
|
456
460
|
* set. Issues with neither targeting field stay panel-only.
|
|
457
461
|
*/
|
|
458
462
|
nodeId?: string;
|