@styx-api/core 0.2.0 → 0.4.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/index.cjs +521 -107
- package/dist/index.d.cts +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +521 -107
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/frontend/detect-format.ts +10 -1
- package/src/frontend/mrtrix/index.ts +1 -0
- package/src/frontend/mrtrix/parser.ts +455 -0
- package/src/index.ts +4 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["findDeepName","isObject","isString","isNumber","isArray","isObject","isString","isArray","description","mapType","renderAccess","isExpr","resultToStmt","appendLines","toStringExpr","pathArg","rootFieldDefault","readAccess","accessOf","renderAccess","collectDefaults","loopVarCounter","buildArgs","walk","walkTerminal","walkSequence","walkOptional","walkRepeat","walkAlternative","emitImports","emitMetadata","mapType","emitTypeDeclarations","emitBuildCargs","buildArgs","resultToStmt","emitWrapperFunction","emitSigParams","emitParamsFactory","emitKwargWrapper","emitValidate","emitRoot","raise","expectedType","emitField","emitValue","str","emitUnion","emitLiteralMembership","checkType","emitRange","emitListLength","plural","mapType","outputTypeExpr","streamFieldIds","rootFieldDefault","collectDefaults","loopCounter","renderWrapperOpen","bindingAccess","presentCondition","renderAccess","renderPathExpr","renderToken","renderRefValue","emitOneOutput","emitBuildOutputs","needsStripExtensionsHelper","emitStripExtensionsHelper","computePublicNames","buildEmitModel","mapType","needsStripExtensionsHelper","streamFieldIds","appModuleName","appEntrypoint","emitPackageDispatch","buildEmitModel","rootFieldDefault","collectDefaults","walk"],"sources":["../src/frontend/argdump/parser.ts","../src/ir/meta.ts","../src/frontend/boutiques/destruct-template.ts","../src/frontend/boutiques/split-command.ts","../src/frontend/boutiques/parser.ts","../src/ir/builders.ts","../src/backend/string-case.ts","../src/frontend/workbench/parser.ts","../src/frontend/detect-format.ts","../src/backend/find-doc.ts","../src/backend/resolve-field-binding.ts","../src/backend/find-struct-node.ts","../src/backend/collect-field-info.ts","../src/bindings/binding.ts","../src/bindings/output-gate.ts","../src/bindings/format.ts","../src/backend/resolve-output-tokens.ts","../src/backend/scope.ts","../src/backend/boutiques/boutiques.ts","../src/backend/code-builder.ts","../src/backend/type-keys.ts","../src/backend/collect-named-types.ts","../src/backend/styxdefs-compat.ts","../src/backend/python/packaging.ts","../src/backend/sig-entries.ts","../src/backend/union-variants.ts","../src/backend/python/typemap.ts","../src/backend/python/arg-builder.ts","../src/backend/python/emit.ts","../src/backend/validate-walk.ts","../src/backend/python/validate-emit.ts","../src/backend/collect-output-fields.ts","../src/backend/python/outputs-emit.ts","../src/backend/python/python.ts","../src/backend/snippet-core.ts","../src/backend/python/snippet.ts","../src/backend/schema/jsonschema.ts","../src/backend/typescript/typemap.ts","../src/backend/typescript/packaging.ts","../src/backend/typescript/arg-builder.ts","../src/backend/typescript/emit.ts","../src/backend/typescript/validate-emit.ts","../src/backend/typescript/outputs-emit.ts","../src/backend/typescript/typescript.ts","../src/backend/typescript/snippet.ts","../src/ir/format.ts","../src/ir/node.ts","../src/ir/passes/pass.ts","../src/ir/passes/canonicalize.ts","../src/ir/passes/flatten.ts","../src/ir/passes/remove-empty.ts","../src/ir/passes/simplify.ts","../src/ir/passes/pipeline.ts","../src/manifest/context.ts","../src/solver/resolve-outputs.ts","../src/solver/assign-access.ts","../src/solver/solver.ts","../src/index.ts"],"sourcesContent":["import type { AppMeta, NodeMeta } from \"../../ir/meta.js\";\nimport type {\n Alternative,\n Expr,\n Float,\n Int,\n Literal,\n Optional,\n Path,\n Repeat,\n Sequence,\n Str,\n} from \"../../ir/node.js\";\nimport type {\n Frontend,\n ParseError,\n ParseResult,\n ParseWarning,\n SourceLocation,\n} from \"../frontend.js\";\n\n// Find the deepest existing name in a subtree, mirroring solver semantics.\n// Used by the mutex code so the synthesized inner name matches the binding\n// name the solver will produce for the same subtree.\nfunction findDeepName(node: Expr): string | undefined {\n if (node.meta?.name) return node.meta.name;\n if (node.kind === \"optional\" || node.kind === \"repeat\") {\n return findDeepName(node.attrs.node);\n }\n if (node.kind === \"sequence\") {\n for (const child of node.attrs.nodes) {\n if (child.kind === \"literal\") continue;\n const name = findDeepName(child);\n if (name) return name;\n }\n }\n return undefined;\n}\n\n// Type guards\n\nfunction isObject(x: unknown): x is Record<string, unknown> {\n return typeof x === \"object\" && x !== null && !Array.isArray(x);\n}\n\nfunction isString(x: unknown): x is string {\n return typeof x === \"string\";\n}\n\nfunction isNumber(x: unknown): x is number {\n return typeof x === \"number\";\n}\n\nfunction isArray(x: unknown): x is unknown[] {\n return Array.isArray(x);\n}\n\n// Argdump types\n\ntype AdAction = Record<string, unknown>;\ntype AdDescriptor = Record<string, unknown>;\n\ninterface ArgparseMarker {\n __argparse__: string;\n}\n\nfunction isArgparseMarker(x: unknown): x is ArgparseMarker {\n return isObject(x) && isString(x.__argparse__);\n}\n\nfunction isSuppressed(x: unknown): boolean {\n return isArgparseMarker(x) && x.__argparse__ === \"SUPPRESS\";\n}\n\n// Parser\n\nexport class ArgdumpParser implements Frontend {\n readonly name = \"argdump\";\n readonly extensions = [\"json\"];\n\n private errors: ParseError[] = [];\n private warnings: ParseWarning[] = [];\n\n private reset(): void {\n this.errors = [];\n this.warnings = [];\n }\n\n private error(message: string, location?: SourceLocation): void {\n this.errors.push({ message, location });\n }\n\n private warn(message: string, location?: SourceLocation): void {\n this.warnings.push({ message, location });\n }\n\n // JSON parsing\n\n private parseJSON(source: string): AdDescriptor | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(source);\n } catch (e) {\n this.error(e instanceof SyntaxError ? e.message : \"Invalid JSON\");\n return null;\n }\n\n if (!isObject(parsed)) {\n this.error(\"JSON source is not an object\");\n return null;\n }\n\n return parsed;\n }\n\n // Metadata building\n\n private buildAppMeta(descriptor: AdDescriptor): AppMeta | undefined {\n const prog = descriptor.prog;\n if (!isString(prog)) return undefined;\n\n // Use prog as id, fall back to first word of description\n let id = prog || undefined;\n if (!id) {\n const desc = descriptor.description;\n if (isString(desc)) {\n // Extract tool name: first word, strip trailing punctuation\n const match = desc.match(/^(\\S+)/);\n if (match) id = match[1]!.replace(/[:;,]+$/, \"\") || undefined;\n }\n }\n if (!id) return undefined;\n\n const description = descriptor.description;\n const epilog = descriptor.epilog;\n // Try to extract version from a version action\n let versionStr: string | undefined;\n const actions = descriptor.actions;\n if (isArray(actions)) {\n for (const action of actions) {\n if (isObject(action) && action.action_type === \"version\" && isString(action.version)) {\n // Strip %(prog)s prefix if present\n versionStr = action.version.replace(/%%?\\(prog\\)s\\s*/g, \"\").trim();\n if (!versionStr) versionStr = undefined;\n break;\n }\n }\n }\n\n return {\n id,\n ...(versionStr && { version: versionStr }),\n ...((isString(description) || isString(epilog)) && {\n doc: {\n ...(isString(description) && { description }),\n ...(isString(epilog) && { comment: epilog }),\n },\n }),\n };\n }\n\n // Terminal node building\n\n private resolveTerminal(action: AdAction): Expr | null {\n const typeInfo = action.type_info;\n const fileTypeInfo = action.file_type_info;\n const choices = action.choices;\n\n // Choices -> enum alternative\n if (isArray(choices) && choices.length > 0) {\n const alts: Literal[] = [];\n for (const choice of choices) {\n if (isString(choice) || isNumber(choice)) {\n alts.push({ kind: \"literal\", attrs: { str: String(choice) } });\n } else {\n this.warn(`Ignoring non-string/number choice: ${JSON.stringify(choice)}`);\n }\n }\n if (alts.length === 0) return null;\n return { kind: \"alternative\", attrs: { alts } };\n }\n\n // FileType -> path\n if (isObject(fileTypeInfo)) {\n return { kind: \"path\", attrs: {} } satisfies Path;\n }\n\n // type_info-based resolution\n if (isObject(typeInfo)) {\n const name = typeInfo.name;\n\n if (!isString(name)) {\n return this.inferFromSamples(action) ?? ({ kind: \"str\", attrs: {} } satisfies Str);\n }\n\n // Non-serializable type -> infer from samples, else str + warning\n if (typeInfo.serializable === false) {\n const inferred = this.inferFromSamples(action);\n const fallback = inferred ? inferred.kind : \"string\";\n this.warn(`Non-serializable type '${name}' for '${action.dest}', treating as ${fallback}`);\n return inferred ?? ({ kind: \"str\", attrs: {} } satisfies Str);\n }\n\n switch (name) {\n case \"int\":\n return { kind: \"int\", attrs: {} } satisfies Int;\n case \"float\":\n return { kind: \"float\", attrs: {} } satisfies Float;\n case \"Path\":\n case \"PosixPath\":\n case \"WindowsPath\":\n return { kind: \"path\", attrs: {} } satisfies Path;\n default: {\n const moduleHit = this.resolveByModule(typeInfo.module);\n if (moduleHit) return moduleHit;\n // Unknown type -> infer from samples, else str\n const inferred = this.inferFromSamples(action);\n if (name !== \"str\") {\n const fallback = inferred ? inferred.kind : \"string\";\n this.warn(`Unknown type '${name}' for '${action.dest}', treating as ${fallback}`);\n }\n return inferred ?? ({ kind: \"str\", attrs: {} } satisfies Str);\n }\n }\n }\n\n // No type_info -> infer from samples, else str (argparse default)\n return this.inferFromSamples(action) ?? ({ kind: \"str\", attrs: {} } satisfies Str);\n }\n\n private resolveByModule(mod: unknown): Path | Float | null {\n if (!isString(mod)) return null;\n if (mod === \"pathlib\" || mod === \"os.path\" || mod.includes(\"path\")) {\n return { kind: \"path\", attrs: {} } satisfies Path;\n }\n if (mod === \"decimal\" || mod === \"fractions\") {\n return { kind: \"float\", attrs: {} } satisfies Float;\n }\n return null;\n }\n\n /** Infer numeric type from sample values: default (incl. list elements) or const. */\n private inferFromSamples(action: AdAction): Int | Float | null {\n const samples: unknown[] = [];\n const def = action.default;\n if (isArray(def)) samples.push(...def);\n else samples.push(def);\n samples.push(action.const);\n\n let sawNumber = false;\n let sawNonInteger = false;\n for (const s of samples) {\n if (typeof s !== \"number\" || !Number.isFinite(s)) continue;\n sawNumber = true;\n if (!Number.isInteger(s)) sawNonInteger = true;\n }\n if (!sawNumber) return null;\n return sawNonInteger\n ? ({ kind: \"float\", attrs: {} } satisfies Float)\n : ({ kind: \"int\", attrs: {} } satisfies Int);\n }\n\n // Nargs wrapping\n\n private wrapWithNargs(node: Expr, nargs: unknown): Expr {\n if (nargs === null || nargs === undefined) {\n // No nargs -> bare value\n return node;\n }\n\n if (isArgparseMarker(nargs)) {\n if (nargs.__argparse__ === \"REMAINDER\") {\n // REMAINDER -> rep(str())\n const rep: Repeat = {\n kind: \"repeat\",\n attrs: { node: { kind: \"str\", attrs: {} }, countMin: 0 },\n };\n return rep;\n }\n if (nargs.__argparse__ === \"SUPPRESS\") {\n return node;\n }\n }\n\n if (nargs === \"?\") {\n const opt: Optional = { kind: \"optional\", attrs: { node } };\n return opt;\n }\n\n if (nargs === \"*\") {\n const rep: Repeat = { kind: \"repeat\", attrs: { node, countMin: 0 } };\n return rep;\n }\n\n if (nargs === \"+\") {\n const rep: Repeat = { kind: \"repeat\", attrs: { node, countMin: 1 } };\n return rep;\n }\n\n if (isNumber(nargs) && Number.isInteger(nargs) && nargs >= 0) {\n if (nargs === 1) return node;\n const rep: Repeat = {\n kind: \"repeat\",\n attrs: { node, countMin: nargs, countMax: nargs },\n };\n return rep;\n }\n\n return node;\n }\n\n // Action building\n\n private buildNodeMeta(action: AdAction): NodeMeta | undefined {\n const dest = action.dest;\n const help = action.help;\n const defaultVal = action.default;\n const name = this.preferredName(action) ?? (isString(dest) ? dest : undefined);\n\n const hasName = name !== undefined;\n const hasHelp = isString(help) && !isSuppressed(help);\n const hasDefault =\n (isString(defaultVal) || isNumber(defaultVal) || typeof defaultVal === \"boolean\") &&\n !isSuppressed(defaultVal);\n\n if (!hasName && !hasHelp && !hasDefault) return undefined;\n\n return {\n ...(hasName && { name }),\n ...(hasHelp && { doc: { description: help } }),\n ...(hasDefault && { defaultValue: defaultVal }),\n };\n }\n\n private getOptionFlag(action: AdAction): string | null {\n const optionStrings = action.option_strings;\n if (!isArray(optionStrings) || optionStrings.length === 0) return null;\n\n // Prefer long option, fallback to first\n for (const opt of optionStrings) {\n if (isString(opt) && opt.startsWith(\"--\")) return opt;\n }\n const first = optionStrings[0];\n return isString(first) ? first : null;\n }\n\n /** Prefer the first --long flag (without leading dashes) over dest. */\n private preferredName(action: AdAction): string | undefined {\n const optionStrings = action.option_strings;\n if (!isArray(optionStrings)) return undefined;\n for (const opt of optionStrings) {\n if (isString(opt) && opt.startsWith(\"--\") && opt.length > 2) {\n return opt.slice(2);\n }\n }\n return undefined;\n }\n\n private isPositional(action: AdAction): boolean {\n const optionStrings = action.option_strings;\n return !isArray(optionStrings) || optionStrings.length === 0;\n }\n\n private buildAction(action: AdAction): Expr | null {\n const actionType = action.action_type ?? \"store\";\n\n switch (actionType) {\n case \"store\":\n return this.buildStore(action);\n case \"store_true\":\n return this.buildStoreTrue(action);\n case \"store_false\":\n return this.buildStoreFalse(action);\n case \"store_const\":\n return this.buildStoreConst(action);\n case \"boolean_optional\":\n return this.buildBooleanOptional(action);\n case \"count\":\n return this.buildCount(action);\n case \"append\":\n case \"extend\":\n return this.buildAppendExtend(action);\n case \"append_const\":\n return this.buildAppendConst(action);\n case \"parsers\":\n return this.buildSubparsers(action);\n case \"help\":\n case \"version\":\n // Skip help/version actions - not part of the tool interface\n return null;\n case \"unknown\":\n this.warn(\n `Unknown action type for '${action.dest}'` +\n (isString(action.custom_action_class)\n ? ` (custom class: ${action.custom_action_class})`\n : \"\") +\n \", treating as store\",\n );\n return this.buildStore(action);\n default:\n this.warn(`Unrecognized action_type '${actionType}' for '${action.dest}', skipping`);\n return null;\n }\n }\n\n private buildStore(action: AdAction): Expr | null {\n const terminal = this.resolveTerminal(action);\n if (!terminal) return null;\n\n const meta = this.buildNodeMeta(action);\n if (meta) terminal.meta = meta;\n\n const node: Expr = this.wrapWithNargs(terminal, action.nargs);\n\n if (this.isPositional(action)) {\n // Hoist metadata from terminal to outermost wrapper\n if (node !== terminal && terminal.meta) {\n const { name, ...rest } = terminal.meta;\n if (Object.keys(rest).length > 0) {\n node.meta = { ...node.meta, ...rest };\n terminal.meta = name ? { name } : undefined;\n }\n }\n return node;\n }\n\n // Optional argument: seq(lit(flag), value)\n const flag = this.getOptionFlag(action);\n if (!flag) {\n this.error(`Optional argument '${action.dest}' has no option strings`);\n return null;\n }\n\n const flagLit: Literal = { kind: \"literal\", attrs: { str: flag } };\n const seq: Sequence = { kind: \"sequence\", attrs: { nodes: [flagLit, node] } };\n\n // Wrap in optional unless explicitly required\n const isRequired = action.required === true;\n let result: Expr;\n if (isRequired) {\n result = seq;\n } else {\n const opt: Optional = { kind: \"optional\", attrs: { node: seq } };\n result = opt;\n }\n\n // Hoist metadata to outermost node\n if (terminal.meta) {\n const { name, ...rest } = terminal.meta;\n if (Object.keys(rest).length > 0) {\n result.meta = { ...result.meta, ...rest };\n terminal.meta = name ? { name } : undefined;\n }\n }\n\n return result;\n }\n\n private buildStoreTrue(action: AdAction): Expr | null {\n const flag = this.getOptionFlag(action);\n if (!flag) {\n this.error(`store_true action '${action.dest}' has no option strings`);\n return null;\n }\n\n const literal: Literal = { kind: \"literal\", attrs: { str: flag } };\n const opt: Optional = { kind: \"optional\", attrs: { node: literal } };\n\n const meta = this.buildNodeMeta(action);\n const flagMeta = meta ?? {};\n if (flagMeta.defaultValue === undefined) flagMeta.defaultValue = false;\n opt.meta = flagMeta;\n\n return opt;\n }\n\n private buildStoreFalse(action: AdAction): Expr | null {\n const flag = this.getOptionFlag(action);\n if (!flag) {\n this.error(`store_false action '${action.dest}' has no option strings`);\n return null;\n }\n\n const literal: Literal = { kind: \"literal\", attrs: { str: flag } };\n const opt: Optional = { kind: \"optional\", attrs: { node: literal } };\n\n const meta = this.buildNodeMeta(action);\n const flagMeta = meta ?? {};\n if (flagMeta.defaultValue === undefined) flagMeta.defaultValue = true;\n opt.meta = flagMeta;\n\n return opt;\n }\n\n private buildStoreConst(action: AdAction): Expr | null {\n const flag = this.getOptionFlag(action);\n if (!flag) {\n this.error(`store_const action '${action.dest}' has no option strings`);\n return null;\n }\n\n const literal: Literal = { kind: \"literal\", attrs: { str: flag } };\n const opt: Optional = { kind: \"optional\", attrs: { node: literal } };\n\n const meta = this.buildNodeMeta(action);\n if (meta) opt.meta = meta;\n\n return opt;\n }\n\n private buildBooleanOptional(action: AdAction): Expr | null {\n const optionStrings = action.option_strings;\n if (!isArray(optionStrings) || optionStrings.length === 0) {\n this.error(`boolean_optional action '${action.dest}' has no option strings`);\n return null;\n }\n\n // Find --flag and --no-flag forms\n let posFlag: string | null = null;\n let negFlag: string | null = null;\n\n for (const opt of optionStrings) {\n if (!isString(opt)) continue;\n if (opt.startsWith(\"--no-\")) {\n negFlag = opt;\n } else if (opt.startsWith(\"--\")) {\n posFlag = opt;\n }\n }\n\n if (!posFlag) {\n // Fallback: use first two option strings\n posFlag = isString(optionStrings[0]) ? optionStrings[0] : null;\n negFlag = isString(optionStrings[1]) ? optionStrings[1] : null;\n }\n\n if (!posFlag) {\n this.error(`boolean_optional action '${action.dest}' has no valid option strings`);\n return null;\n }\n\n const posLit: Literal = { kind: \"literal\", attrs: { str: posFlag } };\n\n let innerNode: Expr;\n if (negFlag) {\n const negLit: Literal = { kind: \"literal\", attrs: { str: negFlag } };\n const alt: Alternative = { kind: \"alternative\", attrs: { alts: [posLit, negLit] } };\n innerNode = alt;\n } else {\n innerNode = posLit;\n }\n\n const opt: Optional = { kind: \"optional\", attrs: { node: innerNode } };\n\n const meta = this.buildNodeMeta(action);\n const flagMeta = meta ?? {};\n if (flagMeta.defaultValue === undefined) flagMeta.defaultValue = false;\n opt.meta = flagMeta;\n\n return opt;\n }\n\n private buildCount(action: AdAction): Expr | null {\n const flag = this.getOptionFlag(action);\n if (!flag) {\n this.error(`count action '${action.dest}' has no option strings`);\n return null;\n }\n\n const literal: Literal = { kind: \"literal\", attrs: { str: flag } };\n const rep: Repeat = { kind: \"repeat\", attrs: { node: literal, countMin: 0 } };\n\n const meta = this.buildNodeMeta(action);\n if (meta) rep.meta = meta;\n\n return rep;\n }\n\n private buildAppendExtend(action: AdAction): Expr | null {\n const terminal = this.resolveTerminal(action);\n if (!terminal) return null;\n\n const meta = this.buildNodeMeta(action);\n if (meta) terminal.meta = meta;\n\n // Inner value may have nargs\n const nargsWrapped: Expr = this.wrapWithNargs(terminal, action.nargs);\n\n // Always wrap in repeat (append/extend accumulates)\n const inner: Expr =\n nargsWrapped.kind === \"repeat\"\n ? nargsWrapped\n : ({ kind: \"repeat\", attrs: { node: nargsWrapped, countMin: 0 } } satisfies Repeat);\n\n if (this.isPositional(action)) {\n // Hoist metadata\n if (inner !== terminal && terminal.meta) {\n const { name, ...rest } = terminal.meta;\n if (Object.keys(rest).length > 0) {\n inner.meta = { ...inner.meta, ...rest };\n terminal.meta = name ? { name } : undefined;\n }\n }\n return inner;\n }\n\n // Optional argument with flag\n const flag = this.getOptionFlag(action);\n if (!flag) {\n this.error(`append/extend action '${action.dest}' has no option strings`);\n return null;\n }\n\n // For append with flag: rep(seq(lit(flag), value))\n // Unwrap the repeat we just added\n const valueNode = inner.kind === \"repeat\" ? inner.attrs.node : inner;\n const flagLit: Literal = { kind: \"literal\", attrs: { str: flag } };\n const flagSeq: Sequence = { kind: \"sequence\", attrs: { nodes: [flagLit, valueNode] } };\n const outerRep: Repeat = { kind: \"repeat\", attrs: { node: flagSeq, countMin: 0 } };\n\n // Hoist metadata\n if (terminal.meta) {\n const { name, ...rest } = terminal.meta;\n if (Object.keys(rest).length > 0) {\n outerRep.meta = { ...outerRep.meta, ...rest };\n terminal.meta = name ? { name } : undefined;\n }\n }\n\n return outerRep;\n }\n\n private buildAppendConst(action: AdAction): Expr | null {\n const flag = this.getOptionFlag(action);\n if (!flag) {\n this.error(`append_const action '${action.dest}' has no option strings`);\n return null;\n }\n\n // Similar to count - repeated flag\n const literal: Literal = { kind: \"literal\", attrs: { str: flag } };\n const rep: Repeat = { kind: \"repeat\", attrs: { node: literal, countMin: 0 } };\n\n const meta = this.buildNodeMeta(action);\n if (meta) rep.meta = meta;\n\n return rep;\n }\n\n private buildSubparsers(action: AdAction): Expr | null {\n const subparsers = action.subparsers;\n if (!isObject(subparsers)) {\n this.error(`parsers action '${action.dest}' has no subparsers`);\n return null;\n }\n\n const aliases = isObject(action.subparsers_aliases) ? action.subparsers_aliases : {};\n const alts: Expr[] = [];\n\n for (const [name, parserInfo] of Object.entries(subparsers)) {\n if (!isObject(parserInfo)) {\n this.warn(`Skipping non-object subparser '${name}'`);\n continue;\n }\n\n const subExpr = this.parseParserInfo(parserInfo);\n if (!subExpr) continue;\n\n // Prepend subcommand literal\n const cmdLit: Literal = { kind: \"literal\", attrs: { str: name } };\n const seq: Sequence = {\n kind: \"sequence\",\n attrs: { nodes: [cmdLit, ...subExpr.attrs.nodes] },\n };\n\n // Attach name and aliases as doc\n const subAliases = aliases[name];\n const aliasDoc =\n isArray(subAliases) && subAliases.length > 0\n ? ` (aliases: ${subAliases.filter(isString).join(\", \")})`\n : \"\";\n\n const description = isString(parserInfo.description) ? parserInfo.description : undefined;\n const docStr = description\n ? description + aliasDoc\n : aliasDoc\n ? aliasDoc.slice(1) // Remove leading space\n : undefined;\n\n seq.meta = {\n name,\n ...(docStr && { doc: { description: docStr } }),\n };\n\n alts.push(seq);\n }\n\n if (alts.length === 0) {\n this.error(`No valid subparsers for '${action.dest}'`);\n return null;\n }\n\n if (alts.length === 1) {\n return alts[0]!;\n }\n\n const alt: Alternative = { kind: \"alternative\", attrs: { alts } };\n\n const isRequired = action.subparsers_required === true || action.required === true;\n if (!isRequired) {\n const opt: Optional = { kind: \"optional\", attrs: { node: alt } };\n\n const meta = this.buildNodeMeta(action);\n if (meta) opt.meta = meta;\n\n return opt;\n }\n\n const meta = this.buildNodeMeta(action);\n if (meta) alt.meta = meta;\n\n return alt;\n }\n\n // Mutual exclusion\n\n private applyMutualExclusion(\n actionsByDest: Map<string, AdAction>,\n groups: unknown[],\n nodes: Expr[],\n nodesByDest: Map<string, Expr>,\n ): Expr[] {\n const excluded = new Set<string>();\n\n for (const group of groups) {\n if (!isObject(group)) continue;\n const groupActions = group.actions;\n if (!isArray(groupActions)) continue;\n\n const memberDests: string[] = [];\n for (const dest of groupActions) {\n if (isString(dest) && nodesByDest.has(dest)) {\n memberDests.push(dest);\n }\n }\n\n if (memberDests.length < 2) continue;\n\n // Build alt from member nodes. Unwrapping the optional drops its meta\n // (doc/default), so merge it onto the inner node and tag the inner\n // with the dest so backends can derive a per-variant name.\n const altMembers: Expr[] = [];\n for (const dest of memberDests) {\n const node = nodesByDest.get(dest)!;\n let inner: Expr;\n let outerMeta: NodeMeta | undefined;\n if (node.kind === \"optional\") {\n inner = node.attrs.node;\n outerMeta = node.meta;\n } else {\n inner = node;\n }\n inner.meta = {\n ...outerMeta,\n ...inner.meta,\n // Prefer the deepest existing name in the subtree so the synthesized\n // name matches the binding the solver derives for the same node.\n // Otherwise findDeepName short-circuits on the inner's new name and\n // the variant struct's field key drifts from the binding name.\n name: inner.meta?.name ?? findDeepName(inner) ?? dest,\n };\n altMembers.push(inner);\n excluded.add(dest);\n }\n\n const alt: Alternative = { kind: \"alternative\", attrs: { alts: altMembers } };\n\n const isRequired = group.required === true;\n let groupNode: Expr;\n if (isRequired) {\n groupNode = alt;\n } else {\n groupNode = { kind: \"optional\", attrs: { node: alt } } satisfies Optional;\n }\n\n // Synthesize a name so backends can derive a meaningful id instead of\n // a Scope-generated placeholder. Prefer an explicit title if surfaced\n // by argdump, otherwise concat dests for 2-member groups, fall back\n // to a \"_choice\" suffix for larger groups.\n const title = isString(group.title) ? group.title : undefined;\n const groupName =\n title ??\n (memberDests.length === 2\n ? `${memberDests[0]}_or_${memberDests[1]}`\n : `${memberDests[0]}_choice`);\n groupNode.meta = { ...groupNode.meta, name: groupName };\n\n // Insert at position of first member\n const firstDest = memberDests[0]!;\n const firstIdx = nodes.findIndex((n) => n === nodesByDest.get(firstDest));\n if (firstIdx >= 0) {\n nodes.splice(firstIdx, 0, groupNode);\n } else {\n nodes.push(groupNode);\n }\n }\n\n // Remove excluded nodes\n return nodes.filter((n) => {\n // Find which dest this node corresponds to\n for (const [dest, node] of nodesByDest) {\n if (node === n && excluded.has(dest)) return false;\n }\n return true;\n });\n }\n\n // Main parser\n\n private parseParserInfo(descriptor: AdDescriptor): Sequence | null {\n const actions = descriptor.actions;\n if (!isArray(actions)) {\n return { kind: \"sequence\", attrs: { nodes: [] } };\n }\n\n const positionals: Expr[] = [];\n const optionals: Expr[] = [];\n const actionsByDest = new Map<string, AdAction>();\n const nodesByDest = new Map<string, Expr>();\n\n for (const rawAction of actions) {\n if (!isObject(rawAction)) continue;\n\n const node = this.buildAction(rawAction);\n if (!node) continue;\n\n const dest = rawAction.dest;\n if (isString(dest)) {\n actionsByDest.set(dest, rawAction);\n nodesByDest.set(dest, node);\n }\n\n if (this.isPositional(rawAction) && rawAction.action_type !== \"parsers\") {\n positionals.push(node);\n } else {\n optionals.push(node);\n }\n }\n\n // Assemble: positionals first, then optionals\n let allNodes = [...positionals, ...optionals];\n\n // Apply mutual exclusion groups\n const mutexGroups = descriptor.mutually_exclusive_groups;\n if (isArray(mutexGroups) && mutexGroups.length > 0) {\n allNodes = this.applyMutualExclusion(actionsByDest, mutexGroups, allNodes, nodesByDest);\n }\n\n return { kind: \"sequence\", attrs: { nodes: allNodes } };\n }\n\n // Public API\n\n parse(source: string, _filename?: string): ParseResult {\n this.reset();\n\n const descriptor = this.parseJSON(source);\n if (descriptor === null) {\n return {\n expr: { kind: \"sequence\", attrs: { nodes: [] } },\n errors: this.errors,\n warnings: this.warnings,\n };\n }\n\n const meta = this.buildAppMeta(descriptor);\n if (!meta) {\n this.error(\"Descriptor is missing prog\");\n return {\n expr: { kind: \"sequence\", attrs: { nodes: [] } },\n errors: this.errors,\n warnings: this.warnings,\n };\n }\n\n const expr = this.parseParserInfo(descriptor);\n if (expr === null) {\n this.error(\"Failed to parse argument structure\");\n return {\n expr: { kind: \"sequence\", attrs: { nodes: [] } },\n errors: this.errors,\n warnings: this.warnings,\n };\n }\n\n // Prepend prog as command literal (like Boutiques' command-line prefix)\n const prog = descriptor.prog;\n if (isString(prog) && prog) {\n expr.attrs.nodes.unshift({ kind: \"literal\", attrs: { str: prog } });\n }\n\n // Set root struct name\n if (!expr.meta?.name && meta.id) {\n expr.meta = { ...expr.meta, name: meta.id };\n }\n\n return {\n meta,\n expr,\n errors: this.errors,\n warnings: this.warnings,\n };\n }\n}\n","import type { Documentation, MediaTypeIdentifier } from \"./types.js\";\n\n/**\n * Opaque, name-based reference to an IR node by its `NodeMeta.name`.\n *\n * Resolved post-solve against the binding registry, not within IR passes.\n * Names survive optimization (pointers don't), so token refs stay valid even\n * after passes rewrite the tree. See `memory/design_outputs.md`.\n */\nexport interface NodeRef {\n kind: \"node-ref\";\n name: string;\n}\n\n/** Construct a NodeRef from a node name. */\nexport function nodeRef(name: string): NodeRef {\n return { kind: \"node-ref\", name };\n}\n\n/** Output token: literal text or a parameter reference. */\nexport type OutputToken =\n | { kind: \"literal\"; value: string }\n | {\n kind: \"ref\";\n target: NodeRef;\n stripExtensions?: string[];\n fallback?: string;\n };\n\n/**\n * Specification for a file the tool produces. Lives on `NodeMeta.outputs` of\n * the struct node (root sequence or subcommand sequence) that declared it.\n * Per-output gating is derived downstream from the scope's binding gate and\n * each ref binding's gate, so no host node or `optional` flag is stored.\n */\nexport interface Output {\n name?: string;\n doc?: Documentation;\n tokens: OutputToken[];\n mediaTypes?: MediaTypeIdentifier[];\n}\n\n/** Metadata attached to any IR node. */\nexport interface NodeMeta {\n /** Name identifier for this node (used by solver for binding names). */\n name?: string;\n /**\n * The discriminator (`@type`) tag for this node when it is a union arm (a\n * Boutiques sub-command). Kept separate from `name`: a single-field\n * sub-command collapses onto its inner field, whose `name` then wins, so the\n * tag would otherwise become the inner field's id - e.g. two distinct\n * sub-commands `VariousString`/`VariousFile` both wrapping an `obj` field\n * would collide on `@type: \"obj\"` (and the second arm would be unreachable).\n * `mergeMeta` preserves this through the collapse and the solver prefers it\n * for the variant tag, so distinct sub-commands keep distinct, reachable\n * `@type`s.\n */\n variantTag?: string;\n doc?: Documentation;\n defaultValue?: string | number | boolean;\n /** Files produced when this node is active. See `Output`. */\n outputs?: Output[];\n}\n\n/** Application-level metadata for the root node. */\nexport interface AppMeta {\n id?: string;\n version?: string;\n doc?: Documentation;\n container?: {\n image: string;\n type?: \"docker\" | \"singularity\";\n };\n stdout?: StreamOutput;\n stderr?: StreamOutput;\n}\n\nexport interface StreamOutput {\n name: string;\n doc?: Documentation;\n}\n\n/**\n * Produce a usable name for an Output. Frontends may leave `Output.name`\n * unset; downstream code (resolver, validator, backends) needs a stable\n * identifier for diagnostics and field naming. Falls back to `output_<index>`\n * keyed by the output's position in tree-walk order.\n */\nexport function effectiveOutputName(output: Output, index: number): string {\n return output.name ?? `output_${index}`;\n}\n","/**\n * Destruct a template string to a list of strings and replacements.\n *\n * This is used to safely destruct boutiques `command-line` as well as `path-template` strings.\n *\n * @example\n * destructTemplate(\"hello x, I am y\", { x: 12, y: 34 })\n * // => [\"hello \", 12, \", I am \", 34]\n */\nexport function destructTemplate<T>(template: string, lookup: Record<string, T>): (string | T)[] {\n const destructed: (string | T)[] = [];\n const stack: (string | T)[] = [template];\n\n while (stack.length > 0) {\n // biome-ignore lint/style/noNonNullAssertion: length check guarantees element exists\n const x = stack.shift()!;\n\n if (typeof x !== \"string\") {\n destructed.push(x);\n continue;\n }\n\n let didSplit = false;\n\n for (const [alias, replacement] of Object.entries(lookup)) {\n const idx = x.indexOf(alias);\n if (idx !== -1) {\n const left = x.slice(0, idx);\n const right = x.slice(idx + alias.length);\n\n if (right.length > 0) {\n stack.unshift(right);\n }\n stack.unshift(replacement);\n if (left.length > 0) {\n stack.unshift(left);\n }\n\n didSplit = true;\n break;\n }\n }\n\n if (!didSplit) {\n destructed.push(x);\n }\n }\n\n return destructed;\n}\n","/**\n * Split a Boutiques command into a list of arguments.\n *\n * @param command - The Boutiques command.\n * @returns The list of arguments.\n * @throws {Error} If command is null or undefined.\n */\nexport function boutiquesSplitCommand(command: string): string[] {\n if (command == null) {\n throw new Error(\"Command cannot be null or undefined\");\n }\n\n const args: string[] = [];\n let current = \"\";\n let inSingleQuote = false;\n let inDoubleQuote = false;\n let escaped = false;\n\n for (const char of command) {\n if (escaped) {\n // In double quotes, only certain escapes are meaningful\n if (inDoubleQuote && ![\"\\\\\", '\"', \"$\", \"`\", \"\\n\"].includes(char)) {\n current += \"\\\\\";\n }\n current += char;\n escaped = false;\n continue;\n }\n\n if (char === \"\\\\\" && !inSingleQuote) {\n escaped = true;\n continue;\n }\n\n if (char === \"'\" && !inDoubleQuote) {\n inSingleQuote = !inSingleQuote;\n continue;\n }\n\n if (char === '\"' && !inSingleQuote) {\n inDoubleQuote = !inDoubleQuote;\n continue;\n }\n\n if (/\\s/.test(char) && !inSingleQuote && !inDoubleQuote) {\n if (current) {\n args.push(current);\n current = \"\";\n }\n continue;\n }\n\n current += char;\n }\n\n if (inSingleQuote || inDoubleQuote) {\n throw new Error(\"Unclosed quote in command string\");\n }\n\n if (escaped) {\n throw new Error(\"Trailing backslash in command string\");\n }\n\n if (current) {\n args.push(current);\n }\n\n return args;\n}\n","import { nodeRef } from \"../../ir/meta.js\";\nimport type { AppMeta, NodeMeta, NodeRef, Output, OutputToken } from \"../../ir/meta.js\";\nimport type { Documentation } from \"../../ir/types.js\";\nimport type {\n Alternative,\n Expr,\n Float,\n Int,\n Literal,\n Optional,\n Path,\n Repeat,\n Sequence,\n Str,\n} from \"../../ir/node.js\";\nimport type {\n Frontend,\n ParseError,\n ParseResult,\n ParseWarning,\n SourceLocation,\n} from \"../frontend.js\";\nimport { destructTemplate } from \"./destruct-template.js\";\nimport { boutiquesSplitCommand } from \"./split-command.js\";\n\n// Type guards\n\nfunction isObject(x: unknown): x is Record<string, unknown> {\n return typeof x === \"object\" && x !== null && !Array.isArray(x);\n}\n\nfunction isString(x: unknown): x is string {\n return typeof x === \"string\";\n}\n\nfunction isNumber(x: unknown): x is number {\n return typeof x === \"number\";\n}\n\nfunction isArray(x: unknown): x is unknown[] {\n return Array.isArray(x);\n}\n\n// Outputs attach to the rootSeq of the descriptor they were declared in\n// (root or a subcommand's sequence). Per-ref gating is computed downstream\n// from each referenced binding's `gate`.\n\n// Boutiques types\n\ntype BtInput = Record<string, unknown>;\ntype BtDescriptor = Record<string, unknown>;\n\nenum InputTypePrimitive {\n String = \"String\",\n Float = \"Float\",\n Integer = \"Integer\",\n File = \"File\",\n Flag = \"Flag\",\n SubCommand = \"SubCommand\",\n SubCommandUnion = \"SubCommandUnion\",\n}\n\ninterface InputType {\n primitive: InputTypePrimitive;\n isList: boolean;\n isOptional: boolean;\n isEnum: boolean;\n}\n\n// Parser\n\nexport class BoutiquesParser implements Frontend {\n readonly name = \"boutiques\";\n readonly extensions = [\"json\"];\n\n private errors: ParseError[] = [];\n private warnings: ParseWarning[] = [];\n\n private reset(): void {\n this.errors = [];\n this.warnings = [];\n }\n\n private error(message: string, location?: SourceLocation): void {\n this.errors.push({ message, location });\n }\n\n private warn(message: string, location?: SourceLocation): void {\n this.warnings.push({ message, location });\n }\n\n // JSON parsing\n\n private parseJSON(source: string): BtDescriptor | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(source);\n } catch (e) {\n this.error(e instanceof SyntaxError ? e.message : \"Invalid JSON\");\n return null;\n }\n\n if (!isObject(parsed)) {\n this.error(\"JSON source is not an object\");\n return null;\n }\n\n return parsed;\n }\n\n // Input type detection\n\n private getInputTypePrimitive(btInput: BtInput): InputTypePrimitive | null {\n const btType = btInput.type;\n\n if (btType === undefined) {\n this.error(`type is missing for input: '${btInput.id}'`);\n return null;\n }\n\n if (isObject(btType)) return InputTypePrimitive.SubCommand;\n if (isArray(btType)) return InputTypePrimitive.SubCommandUnion;\n\n const typeName = isString(btType) ? btType : String(btType);\n\n switch (typeName) {\n case \"String\":\n return InputTypePrimitive.String;\n case \"File\":\n return InputTypePrimitive.File;\n case \"Flag\":\n return InputTypePrimitive.Flag;\n case \"Number\":\n return btInput.integer ? InputTypePrimitive.Integer : InputTypePrimitive.Float;\n default:\n this.error(`Unknown input type: '${typeName}'`);\n return null;\n }\n }\n\n private getInputType(btInput: BtInput): InputType | null {\n const primitive = this.getInputTypePrimitive(btInput);\n if (primitive === null) return null;\n\n if (primitive === InputTypePrimitive.Flag) {\n return { primitive, isList: false, isOptional: true, isEnum: false };\n }\n\n const isList = btInput.list === true;\n const isOptional = btInput.optional === true;\n const isEnum = btInput[\"value-choices\"] !== undefined;\n\n if (primitive === InputTypePrimitive.File && isEnum) {\n this.error(`File input '${btInput.id}' cannot have value-choices`);\n return null;\n }\n\n return { primitive, isList, isOptional, isEnum };\n }\n\n // Metadata building\n\n private buildNodeMeta(btInput: BtInput): NodeMeta | undefined {\n const name = btInput.id;\n const title = btInput.name;\n const description = btInput.description;\n const defaultValue = btInput[\"default-value\"];\n\n const hasDefault =\n isString(defaultValue) || isNumber(defaultValue) || typeof defaultValue === \"boolean\";\n\n if (!isString(name) && !isString(title) && !isString(description) && !hasDefault) {\n return undefined;\n }\n\n return {\n ...(isString(name) && { name }),\n ...((isString(title) || isString(description)) && {\n doc: {\n ...(isString(title) && { title }),\n ...(isString(description) && { description }),\n },\n }),\n ...(hasDefault && { defaultValue }),\n };\n }\n\n private buildStreamMeta(\n bt: Record<string, unknown>,\n ): { name: string; doc?: { title?: string; description?: string } } | undefined {\n const id = bt.id;\n if (!isString(id)) return undefined;\n\n const name = bt.name;\n const description = bt.description;\n\n return {\n name: id,\n ...((isString(name) || isString(description)) && {\n doc: {\n ...(isString(name) && { title: name }),\n ...(isString(description) && { description }),\n },\n }),\n };\n }\n\n private buildOutput(\n out: BtInput,\n lookup: Record<string, NodeRef>,\n idOptional: Set<string>,\n ): { output: Output } | null {\n const id = out.id;\n if (!isString(id)) {\n this.error(\"output-files entry missing id\");\n return null;\n }\n\n const template = out[\"path-template\"];\n if (!isString(template)) {\n this.error(`output-files entry '${id}' missing path-template`);\n return null;\n }\n\n const stripRaw = out[\"path-template-stripped-extensions\"];\n const stripExtensions =\n isArray(stripRaw) && stripRaw.every(isString) && stripRaw.length > 0\n ? (stripRaw as string[])\n : undefined;\n\n const parts = destructTemplate<NodeRef>(template, lookup);\n\n const tokens: OutputToken[] = parts.map((part) => {\n if (typeof part === \"string\") return { kind: \"literal\" as const, value: part };\n return {\n kind: \"ref\" as const,\n target: part,\n ...(stripExtensions && { stripExtensions }),\n // Boutiques substitutes an unset optional input with the empty string.\n ...(idOptional.has(part.name) && { fallback: \"\" }),\n };\n });\n\n const title = out.name;\n const description = out.description;\n const output: Output = { name: id, tokens };\n if (isString(title) || isString(description)) {\n output.doc = {\n ...(isString(title) && { title }),\n ...(isString(description) && { description }),\n };\n }\n // Boutiques' `optional: bool` on output-files is a tool-author hint and is\n // re-derived at emit time from the refs' bindings - we don't store it.\n\n return { output };\n }\n\n /**\n * Attach `output-files` entries to the descriptor's rootSeq. Per-output\n * gating (which refs are optional, which arm we're inside) is recovered\n * downstream from each ref binding's `gate`.\n */\n private attachOutputs(rootSeq: Sequence, bt: BtDescriptor): void {\n const outputFiles = bt[\"output-files\"];\n if (!isArray(outputFiles)) return;\n\n const lookup: Record<string, NodeRef> = {};\n const idOptional = new Set<string>();\n const inputs = bt[\"inputs\"];\n if (isArray(inputs)) {\n for (const input of inputs) {\n if (isObject(input) && isString(input[\"value-key\"]) && isString(input.id)) {\n lookup[input[\"value-key\"]] = nodeRef(input.id);\n if (input.optional === true) idOptional.add(input.id);\n }\n }\n }\n\n for (const out of outputFiles) {\n if (!isObject(out)) {\n this.warn(\"Skipping non-object output-files entry\");\n continue;\n }\n const built = this.buildOutput(out, lookup, idOptional);\n if (!built) continue;\n\n if (!rootSeq.meta) rootSeq.meta = {};\n rootSeq.meta.outputs = [...(rootSeq.meta.outputs ?? []), built.output];\n }\n }\n\n private buildAppMeta(bt: BtDescriptor): AppMeta | undefined {\n const id = bt.id ?? bt.name;\n if (!isString(id)) return undefined;\n\n const name = bt.name;\n const description = bt.description;\n const version = bt[\"tool-version\"];\n const author = bt.author;\n const url = bt.url;\n const container = bt[\"container-image\"];\n const stdout = bt[\"stdout-output\"];\n const stderr = bt[\"stderr-output\"];\n\n const doc: Documentation = {\n ...(isString(name) && { title: name }),\n ...(isString(description) && { description }),\n ...(isString(author) && { authors: [author] }),\n ...(isString(url) && { urls: [url] }),\n };\n\n return {\n id,\n ...(isString(version) && { version }),\n ...(Object.keys(doc).length > 0 && { doc }),\n ...(isObject(container) &&\n isString(container.image) && {\n container: {\n image: container.image,\n ...(isString(container.type) && {\n type: container.type as \"docker\" | \"singularity\",\n }),\n },\n }),\n ...(isObject(stdout) && { stdout: this.buildStreamMeta(stdout) }),\n ...(isObject(stderr) && { stderr: this.buildStreamMeta(stderr) }),\n };\n }\n\n // Terminal node building\n\n private buildEnumAlternative(choices: unknown[], meta?: NodeMeta): Alternative | null {\n const alts: Literal[] = [];\n\n for (const choice of choices) {\n if (isString(choice)) {\n alts.push({ kind: \"literal\", attrs: { str: choice } });\n } else if (isNumber(choice)) {\n alts.push({ kind: \"literal\", attrs: { str: String(choice) } });\n } else {\n this.warn(`Ignoring non-string/number enum choice: ${JSON.stringify(choice)}`);\n }\n }\n\n if (alts.length === 0) return null;\n\n const node: Alternative = { kind: \"alternative\", attrs: { alts } };\n if (meta) node.meta = meta;\n return node;\n }\n\n private buildTerminal(btInput: BtInput, inputType: InputType): Expr | null {\n const meta = this.buildNodeMeta(btInput);\n\n if (inputType.isEnum) {\n const choices = btInput[\"value-choices\"];\n if (!isArray(choices)) {\n this.error(`Invalid value-choices for '${btInput.id}'`);\n return null;\n }\n return this.buildEnumAlternative(choices, meta);\n }\n\n switch (inputType.primitive) {\n case InputTypePrimitive.String: {\n const node: Str = { kind: \"str\", attrs: {} };\n if (meta) node.meta = meta;\n return node;\n }\n\n case InputTypePrimitive.Integer: {\n const node: Int = { kind: \"int\", attrs: {} };\n if (isNumber(btInput.minimum)) {\n node.attrs.minValue = Math.floor(btInput.minimum);\n if (btInput[\"exclusive-minimum\"] === true) node.attrs.minValue += 1;\n }\n if (isNumber(btInput.maximum)) {\n node.attrs.maxValue = Math.floor(btInput.maximum);\n if (btInput[\"exclusive-maximum\"] === true) node.attrs.maxValue -= 1;\n }\n if (meta) node.meta = meta;\n return node;\n }\n\n case InputTypePrimitive.Float: {\n const node: Float = { kind: \"float\", attrs: {} };\n if (isNumber(btInput.minimum)) node.attrs.minValue = btInput.minimum;\n if (isNumber(btInput.maximum)) node.attrs.maxValue = btInput.maximum;\n if (meta) node.meta = meta;\n return node;\n }\n\n case InputTypePrimitive.File: {\n const node: Path = {\n kind: \"path\",\n attrs: {\n ...(btInput[\"resolve-parent\"] === true && { resolveParent: true }),\n ...(btInput.mutable === true && { mutable: true }),\n },\n };\n if (meta) node.meta = meta;\n return node;\n }\n\n case InputTypePrimitive.Flag: {\n const flag = btInput[\"command-line-flag\"];\n if (!isString(flag)) {\n this.error(`Flag input '${btInput.id}' missing command-line-flag`);\n return null;\n }\n const literal: Literal = { kind: \"literal\", attrs: { str: flag } };\n const node: Optional = { kind: \"optional\", attrs: { node: literal } };\n const flagMeta = meta ?? {};\n if (flagMeta.defaultValue === undefined) flagMeta.defaultValue = false;\n node.meta = flagMeta;\n return node;\n }\n\n case InputTypePrimitive.SubCommand: {\n const nested = btInput.type;\n if (!isObject(nested)) {\n this.error(`Invalid subcommand type for '${btInput.id}'`);\n return null;\n }\n const node = this.parseDescriptor(nested);\n if (node && meta) node.meta = meta;\n return node;\n }\n\n case InputTypePrimitive.SubCommandUnion: {\n const alts = btInput.type;\n if (!isArray(alts)) {\n this.error(`Invalid subcommand union type for '${btInput.id}'`);\n return null;\n }\n const parsedAlts: Expr[] = [];\n // A discriminated union dispatches on a unique `@type` (the subcommand\n // id), recorded as `variantTag` so it survives a single-field\n // sub-command collapsing onto its inner field. Two genuinely-duplicate\n // ids (c3d c2d/c3d/c4d declare two byte-identical sub-commands) are\n // dodged to a unique tag so both arms stay addressable rather than the\n // second being an unreachable, codegen-breaking duplicate (the backend\n // rejects duplicate `@type`s outright).\n const usedTags = new Set<string>();\n for (const alt of alts) {\n if (!isObject(alt)) {\n this.warn(\"Skipping non-object subcommand alternative\");\n continue;\n }\n const parsed = this.parseDescriptor(alt);\n if (parsed) {\n // Tag the arm from the subcommand descriptor's id.\n const altMeta = this.buildAppMeta(alt);\n if (altMeta?.id) {\n let tag = altMeta.id;\n if (usedTags.has(tag)) {\n let n = 2;\n while (usedTags.has(`${altMeta.id}_${n}`)) n++;\n tag = `${altMeta.id}_${n}`;\n this.warn(\n `Duplicate subcommand id '${altMeta.id}' in union '${btInput.id}'; ` +\n `renamed variant to '${tag}' to keep the @type discriminator unique.`,\n );\n }\n usedTags.add(tag);\n // `variantTag` is the discriminator (survives collapse); `name`\n // gives a unique binding/type name for non-collapsing (multi-field)\n // arms - it is clobbered by the inner field's name when the arm\n // collapses, which is why the tag needs its own channel.\n parsed.meta = { ...parsed.meta, name: tag, variantTag: tag };\n }\n parsedAlts.push(parsed);\n }\n }\n if (parsedAlts.length === 0) {\n this.error(`No valid alternatives for subcommand union '${btInput.id}'`);\n return null;\n }\n if (parsedAlts.length === 1) {\n const node = parsedAlts[0]!;\n if (meta) node.meta = { ...node.meta, ...meta };\n return node;\n }\n const node: Alternative = { kind: \"alternative\", attrs: { alts: parsedAlts } };\n if (meta) node.meta = meta;\n return node;\n }\n\n default:\n return null;\n }\n }\n\n // Node wrapping (repeat, flag, optional)\n\n private wrapWithRepeat(node: Expr, btInput: BtInput): Repeat {\n return {\n kind: \"repeat\",\n attrs: {\n node,\n ...(isString(btInput[\"list-separator\"]) && { join: btInput[\"list-separator\"] }),\n ...(isNumber(btInput[\"min-list-entries\"]) && { countMin: btInput[\"min-list-entries\"] }),\n ...(isNumber(btInput[\"max-list-entries\"]) && { countMax: btInput[\"max-list-entries\"] }),\n },\n };\n }\n\n private wrapWithFlag(node: Expr, btInput: BtInput): Expr {\n const flag = btInput[\"command-line-flag\"];\n if (!isString(flag)) return node;\n\n const flagSep = btInput[\"command-line-flag-separator\"];\n const prefix: Literal = {\n kind: \"literal\",\n attrs: { str: flag + (flagSep ?? \"\") },\n };\n\n return { kind: \"sequence\", attrs: { nodes: [prefix, node] } };\n }\n\n private wrapWithOptional(node: Expr): Optional {\n return { kind: \"optional\", attrs: { node } };\n }\n\n private wrapNode(node: Expr, btInput: BtInput, inputType: InputType): Expr {\n // Flags handle their own optional wrapping\n if (inputType.primitive === InputTypePrimitive.Flag) {\n return node;\n }\n\n const inner = node;\n\n // Order: repeat -> flag -> optional\n // This produces: optional(sequence(flag, repeat(value)))\n\n if (inputType.isList) {\n node = this.wrapWithRepeat(node, btInput);\n }\n\n node = this.wrapWithFlag(node, btInput);\n\n if (inputType.isOptional) {\n node = this.wrapWithOptional(node);\n }\n\n // Hoist metadata (doc, default) to outermost wrapper so backends find it\n // on the binding node. Keep name on inner for solver's findDeepName.\n if (node !== inner && inner.meta) {\n const { name, ...rest } = inner.meta;\n if (Object.keys(rest).length > 0) {\n node.meta = { ...node.meta, ...rest };\n inner.meta = name ? { name } : undefined;\n }\n }\n\n return node;\n }\n\n // Command line parsing\n\n private parseCommandLineTemplate(\n template: string,\n inputsLookup: Map<string, BtInput>,\n ): Array<Array<string | BtInput>> {\n let args: string[];\n try {\n args = boutiquesSplitCommand(template);\n } catch (e) {\n this.error(`Failed to parse command-line: ${e instanceof Error ? e.message : String(e)}`);\n return [];\n }\n\n const lookupObj = Object.fromEntries(inputsLookup);\n return args.map((arg) => destructTemplate(arg, lookupObj));\n }\n\n private parseDescriptor(bt: BtDescriptor): Sequence | null {\n // Build inputs lookup\n const inputs = bt[\"inputs\"];\n const inputsLookup = new Map<string, BtInput>();\n\n if (isArray(inputs)) {\n for (const input of inputs) {\n if (isObject(input) && isString(input[\"value-key\"])) {\n inputsLookup.set(input[\"value-key\"], input);\n }\n }\n }\n\n // Parse command line template\n const commandLine = bt[\"command-line\"];\n const segments = isString(commandLine)\n ? this.parseCommandLineTemplate(commandLine, inputsLookup)\n : [];\n\n // Build IR\n const rootSeq: Sequence = { kind: \"sequence\", attrs: { nodes: [] } };\n\n for (const segment of segments) {\n const seq: Sequence = { kind: \"sequence\", attrs: { nodes: [], join: \"\" } };\n\n for (const elem of segment) {\n if (isObject(elem)) {\n const inputType = this.getInputType(elem);\n if (inputType === null) continue;\n\n let node = this.buildTerminal(elem, inputType);\n if (node === null) continue;\n\n node = this.wrapNode(node, elem, inputType);\n seq.attrs.nodes.push(node);\n } else {\n seq.attrs.nodes.push({ kind: \"literal\", attrs: { str: elem } });\n }\n }\n\n // Flatten single-node sequences\n if (seq.attrs.nodes.length === 1) {\n rootSeq.attrs.nodes.push(seq.attrs.nodes[0]!);\n } else if (seq.attrs.nodes.length > 1) {\n rootSeq.attrs.nodes.push(seq);\n }\n }\n\n this.attachOutputs(rootSeq, bt);\n return rootSeq;\n }\n\n // Public API\n\n parse(source: string, _filename?: string): ParseResult {\n this.reset();\n\n const bt = this.parseJSON(source);\n if (bt === null) {\n return {\n expr: { kind: \"sequence\", attrs: { nodes: [] } },\n errors: this.errors,\n warnings: this.warnings,\n };\n }\n\n const baseMeta = this.buildAppMeta(bt);\n if (!baseMeta) {\n this.error(\"Descriptor is missing id/name\");\n return {\n expr: { kind: \"sequence\", attrs: { nodes: [] } },\n errors: this.errors,\n warnings: this.warnings,\n };\n }\n\n const expr = this.parseDescriptor(bt);\n if (expr === null) {\n this.error(\"Failed to parse command structure\");\n return {\n expr: { kind: \"sequence\", attrs: { nodes: [] } },\n errors: this.errors,\n warnings: this.warnings,\n };\n }\n\n // Set root struct name from descriptor id if not already set\n if (!expr.meta?.name && baseMeta?.id) {\n expr.meta = { ...expr.meta, name: baseMeta.id };\n }\n\n return {\n meta: baseMeta,\n expr,\n errors: this.errors,\n warnings: this.warnings,\n };\n }\n}\n","import type { NodeMeta } from \"./meta.js\";\nimport type {\n Alternative,\n Expr,\n Float,\n Int,\n Literal,\n Optional,\n Path,\n Repeat,\n Sequence,\n Str,\n} from \"./node.js\";\n\n// -- Terminals --\n\nexport function lit(str: string): Literal {\n return { kind: \"literal\", attrs: { str } };\n}\n\nexport function str(meta?: NodeMeta | string): Str {\n return { kind: \"str\", attrs: {}, meta: normalizeMeta(meta) };\n}\n\nexport function int(meta?: NodeMeta | string): Int {\n return { kind: \"int\", attrs: {}, meta: normalizeMeta(meta) };\n}\n\nexport function float(meta?: NodeMeta | string): Float {\n return { kind: \"float\", attrs: {}, meta: normalizeMeta(meta) };\n}\n\nexport function path(meta?: NodeMeta | string): Path {\n return { kind: \"path\", attrs: {}, meta: normalizeMeta(meta) };\n}\n\n// -- Structural --\n\nexport function seq(...nodes: Expr[]): Sequence {\n return { kind: \"sequence\", attrs: { nodes } };\n}\n\nexport function seqJoin(join: string, ...nodes: Expr[]): Sequence {\n return { kind: \"sequence\", attrs: { nodes, join } };\n}\n\nexport function opt(node: Expr, meta?: NodeMeta | string): Optional {\n return { kind: \"optional\", attrs: { node }, meta: normalizeMeta(meta) };\n}\n\nexport function rep(node: Expr, meta?: NodeMeta | string): Repeat {\n return { kind: \"repeat\", attrs: { node }, meta: normalizeMeta(meta) };\n}\n\nexport function repJoin(join: string, node: Expr, meta?: NodeMeta | string): Repeat {\n return { kind: \"repeat\", attrs: { node, join }, meta: normalizeMeta(meta) };\n}\n\nexport function alt(...alts: Expr[]): Alternative {\n return { kind: \"alternative\", attrs: { alts } };\n}\n\n// -- Helpers --\n\nfunction normalizeMeta(meta: NodeMeta | string | undefined): NodeMeta | undefined {\n if (meta === undefined) return undefined;\n if (typeof meta === \"string\") return { name: meta };\n return meta;\n}\n","/** Split a string into lowercase word tokens for case conversion. */\nfunction tokenize(s: string): string[] {\n return s\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\") // camelCase boundary\n .replace(/([A-Z]+)([A-Z][a-z])/g, \"$1 $2\") // consecutive uppercase -> keep runs\n .replace(/[^a-zA-Z0-9]+/g, \" \")\n .trim()\n .toLowerCase()\n .split(/\\s+/)\n .filter(Boolean);\n}\n\nexport function snakeCase(s: string): string {\n return tokenize(s).join(\"_\");\n}\n\nexport function screamingSnakeCase(s: string): string {\n return tokenize(s).join(\"_\").toUpperCase();\n}\n\nexport function pascalCase(s: string): string {\n return tokenize(s)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(\"\");\n}\n\nexport function camelCase(s: string): string {\n const pascal = pascalCase(s);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n}\n","import { lit, opt, rep, seq, str, int, float, alt } from \"../../ir/builders.js\";\nimport { nodeRef } from \"../../ir/meta.js\";\nimport type { AppMeta, NodeMeta, Output } from \"../../ir/meta.js\";\nimport type { Documentation } from \"../../ir/types.js\";\nimport type { Expr, Path, Sequence } from \"../../ir/node.js\";\nimport { snakeCase } from \"../../backend/string-case.js\";\nimport type {\n Frontend,\n ParseError,\n ParseResult,\n ParseWarning,\n SourceLocation,\n} from \"../frontend.js\";\n\n// Type guards\n\nfunction isObject(x: unknown): x is Record<string, unknown> {\n return typeof x === \"object\" && x !== null && !Array.isArray(x);\n}\n\nfunction isString(x: unknown): x is string {\n return typeof x === \"string\";\n}\n\nfunction isArray(x: unknown): x is unknown[] {\n return Array.isArray(x);\n}\n\n// Workbench scalar/file type strings. See the v1 loader's model.py.\nconst TYPE_STRING = \"String\";\nconst TYPE_FLOATING_POINT = \"Floating Point\";\nconst TYPE_INTEGER = \"Integer\";\nconst TYPE_BOOLEAN = \"Boolean\";\n\nconst FILE_TYPES = new Set<string>([\n \"Surface File\",\n \"Border File\",\n \"Metric File\",\n \"Annotation File\",\n \"Cifti File\",\n \"Volume File\",\n \"Label File\",\n \"Foci File\",\n]);\n\n/** A fresh empty root sequence for error returns (IR passes mutate in place,\n * so callers must not share a single instance). */\nfunction emptyExpr(): Sequence {\n return { kind: \"sequence\", attrs: { nodes: [] } };\n}\n\n/**\n * Parser for Connectome Workbench command definitions (`workbench.json`).\n *\n * The format is recursive but flat in expressivity: positional `params`,\n * positional `outputs`, optional `options`, and `repeatable_options`, where an\n * option may nest its own options/repeatable_options arbitrarily deep. There\n * are no unions, constraints, or conditionals. We lower it onto the same `Expr`\n * shapes the Boutiques parser already emits for flagged sub-sequences:\n *\n * wb_command <command> <positionals...> [option ...] ...\n *\n * - param -> typed terminal (required)\n * - output -> str terminal (the user-supplied filename) + an Output\n * entry on the enclosing struct's meta, referencing it\n * - option -> opt(seq(lit(switch), ...)) (or opt(lit(switch)) flag)\n * - repeatable_option-> rep(seq(lit(switch), ...)) (or rep(lit(switch)) count)\n *\n * v1 reference: ../niwrap/tooling/src/wrap/apps/build/loaders/workbench/.\n */\nexport class WorkbenchParser implements Frontend {\n readonly name = \"workbench\";\n readonly extensions = [\"json\"];\n\n private errors: ParseError[] = [];\n private warnings: ParseWarning[] = [];\n\n private reset(): void {\n this.errors = [];\n this.warnings = [];\n }\n\n private error(message: string, location?: SourceLocation): void {\n this.errors.push({ message, location });\n }\n\n private warn(message: string, location?: SourceLocation): void {\n this.warnings.push({ message, location });\n }\n\n private parseJSON(source: string): Record<string, unknown> | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(source);\n } catch (e) {\n this.error(e instanceof SyntaxError ? e.message : \"Invalid JSON\");\n return null;\n }\n if (!isObject(parsed)) {\n this.error(\"JSON source is not an object\");\n return null;\n }\n return parsed;\n }\n\n // -- Metadata --\n\n private docFrom(description: unknown): Documentation | undefined {\n return isString(description) && description.length > 0 ? { description } : undefined;\n }\n\n private buildAppMeta(cmd: Record<string, unknown>): AppMeta | undefined {\n const command = cmd.command;\n if (!isString(command)) {\n this.error(\"Workbench descriptor missing required 'command' string\");\n return undefined;\n }\n\n const id = normalizeName(command);\n const title = cmd.short_description;\n const description = cmd.help_text;\n const doc: Documentation = {\n ...(isString(title) && { title }),\n ...(isString(description) && { description }),\n };\n\n const version = extractVersion(cmd.version_info);\n return {\n id,\n ...(version && { version }),\n ...(Object.keys(doc).length > 0 && { doc }),\n };\n }\n\n // -- Terminals --\n\n /** Map a workbench scalar/file type string to an IR terminal node. */\n private buildTerminal(type: string, meta: NodeMeta, ctx: string): Expr | null {\n switch (type) {\n case TYPE_STRING:\n return str(meta);\n case TYPE_INTEGER:\n return int(meta);\n case TYPE_FLOATING_POINT:\n return float(meta);\n case TYPE_BOOLEAN: {\n // A positional boolean emits the literal token \"true\" or \"false\". The\n // idiomatic styx2 representation is a two-literal choice (v1 used a\n // value_true/value_false Bool, which produces the same tokens).\n const node = alt(lit(\"true\"), lit(\"false\"));\n node.meta = meta;\n return node;\n }\n default: {\n if (FILE_TYPES.has(type)) {\n const node: Path = {\n kind: \"path\",\n attrs: { mediaTypes: [`workbench/${type}`] },\n meta,\n };\n return node;\n }\n this.error(`Unknown workbench type '${type}' for '${ctx}'`);\n return null;\n }\n }\n }\n\n // -- Params / outputs --\n\n /** Positional parameter -> required typed terminal. */\n private buildParam(param: unknown): Expr | null {\n if (!isObject(param)) {\n this.warn(\"Skipping non-object param\");\n return null;\n }\n const shortName = param.short_name;\n const type = param.type;\n if (!isString(shortName) || !isString(type)) {\n this.error(\"Workbench param missing 'short_name'/'type'\");\n return null;\n }\n const doc = this.docFrom(param.description);\n const meta: NodeMeta = { name: snakeCase(shortName), ...(doc && { doc }) };\n return this.buildTerminal(type, meta, shortName);\n }\n\n /**\n * Positional/option output -> a `str` terminal (the user-supplied output\n * filename) plus an `Output` declaration referencing it by name. Mirrors v1's\n * `_load_output`, which emits both a String param and an OutputParamReference.\n */\n private buildOutput(output: unknown): { node: Expr; output: Output } | null {\n if (!isObject(output)) {\n this.warn(\"Skipping non-object output\");\n return null;\n }\n const shortName = output.short_name;\n const type = output.type;\n if (!isString(shortName) || !isString(type)) {\n this.error(\"Workbench output missing 'short_name'/'type'\");\n return null;\n }\n if (!FILE_TYPES.has(type)) {\n this.error(`Workbench output '${shortName}' has non-file type '${type}'`);\n return null;\n }\n const name = snakeCase(shortName);\n const doc = this.docFrom(output.description);\n const node = str({ name, ...(doc && { doc }) });\n const out: Output = {\n name,\n ...(doc && { doc }),\n tokens: [{ kind: \"ref\", target: nodeRef(name) }],\n mediaTypes: [`workbench/${type}`],\n };\n return { node, output: out };\n }\n\n // -- Options --\n\n /**\n * An option/repeatable_option -> an optional (or repeated) switch group.\n *\n * With no sub-content it collapses to a bare flag (`opt(lit(switch))` ->\n * bool, `rep(lit(switch))` -> count). With content it is a struct sequence\n * `seq(lit(switch), ...)`; the struct's name + any outputs live on that\n * sequence's meta, the option's doc on the optional/repeat wrapper (matching\n * the Boutiques metadata-hoisting convention).\n */\n private buildOption(option: unknown, repeatable: boolean): Expr | null {\n if (!isObject(option)) {\n this.warn(\"Skipping non-object option\");\n return null;\n }\n const sw = option.option_switch;\n if (!isString(sw)) {\n this.error(\"Workbench option missing 'option_switch'\");\n return null;\n }\n const name = normalizeName(sw);\n const doc = this.docFrom(option.description);\n\n const inner: Expr[] = [lit(sw)];\n const outputs: Output[] = [];\n\n for (const p of asArray(option.params)) {\n const node = this.buildParam(p);\n if (node) inner.push(node);\n }\n for (const o of asArray(option.outputs)) {\n const built = this.buildOutput(o);\n if (built) {\n inner.push(built.node);\n outputs.push(built.output);\n }\n }\n for (const o of asArray(option.options)) {\n const node = this.buildOption(o, false);\n if (node) inner.push(node);\n }\n for (const o of asArray(option.repeatable_options)) {\n const node = this.buildOption(o, true);\n if (node) inner.push(node);\n }\n\n const wrapperMeta: NodeMeta = { ...(doc && { doc }) };\n\n if (inner.length === 1) {\n // Pure flag: no parameters or sub-options.\n const flagMeta: NodeMeta = { name, ...wrapperMeta };\n if (!repeatable) flagMeta.defaultValue = false;\n return repeatable ? rep(lit(sw), flagMeta) : opt(lit(sw), flagMeta);\n }\n\n const structSeq = seq(...inner);\n structSeq.meta = { name, ...(outputs.length > 0 && { outputs }) };\n return repeatable ? rep(structSeq, wrapperMeta) : opt(structSeq, wrapperMeta);\n }\n\n // -- Public API --\n\n parse(source: string, _filename?: string): ParseResult {\n this.reset();\n\n const cmd = this.parseJSON(source);\n if (!cmd) {\n return { expr: emptyExpr(), errors: this.errors, warnings: this.warnings };\n }\n\n const meta = this.buildAppMeta(cmd);\n if (!meta || !isString(cmd.command)) {\n return { expr: emptyExpr(), errors: this.errors, warnings: this.warnings };\n }\n\n const nodes: Expr[] = [lit(\"wb_command\"), lit(cmd.command)];\n const rootOutputs: Output[] = [];\n\n for (const p of asArray(cmd.params)) {\n const node = this.buildParam(p);\n if (node) nodes.push(node);\n }\n for (const o of asArray(cmd.outputs)) {\n const built = this.buildOutput(o);\n if (built) {\n nodes.push(built.node);\n rootOutputs.push(built.output);\n }\n }\n for (const o of asArray(cmd.options)) {\n const node = this.buildOption(o, false);\n if (node) nodes.push(node);\n }\n for (const o of asArray(cmd.repeatable_options)) {\n const node = this.buildOption(o, true);\n if (node) nodes.push(node);\n }\n\n const rootSeq = seq(...nodes);\n rootSeq.meta = { name: meta.id, ...(rootOutputs.length > 0 && { outputs: rootOutputs }) };\n\n return { meta, expr: rootSeq, errors: this.errors, warnings: this.warnings };\n }\n}\n\n// -- Helpers --\n\n/** Strip a leading dash from a switch/command and snake_case it. */\nfunction normalizeName(name: string): string {\n return snakeCase(name.replace(/^-+/, \"\"));\n}\n\n/** Coerce a possibly-missing list field to an array. */\nfunction asArray(x: unknown): unknown[] {\n return isArray(x) ? x : [];\n}\n\n/**\n * Pull a clean version out of workbench's noisy `version_info` lines\n * (e.g. \"Version: 2.1.0\"). Returns undefined if none is present.\n */\nfunction extractVersion(versionInfo: unknown): string | undefined {\n if (!isArray(versionInfo)) return undefined;\n for (const line of versionInfo) {\n if (isString(line)) {\n const m = /^Version:\\s*(.+)$/.exec(line.trim());\n if (m && m[1]) return m[1].trim();\n }\n }\n return undefined;\n}\n","export type FormatName = \"boutiques\" | \"argdump\" | \"workbench\";\n\n/**\n * Auto-detect the format of a JSON descriptor source string.\n * Returns null if the format cannot be determined.\n */\nexport function detectFormat(source: string): FormatName | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(source);\n } catch {\n return null;\n }\n\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n return null;\n }\n\n const obj = parsed as Record<string, unknown>;\n\n // Check $schema for argdump\n if (typeof obj.$schema === \"string\" && obj.$schema.includes(\"argdump\")) {\n return \"argdump\";\n }\n\n // Workbench: has a \"command\" switch plus \"short_description\"\n if (typeof obj.command === \"string\" && typeof obj.short_description === \"string\") {\n return \"workbench\";\n }\n\n // Boutiques: has \"command-line\" or \"inputs\" array\n if (\"command-line\" in obj || (Array.isArray(obj.inputs) && \"name\" in obj)) {\n return \"boutiques\";\n }\n\n // Argdump: has \"actions\" array + \"prog\"\n if (Array.isArray(obj.actions) && \"prog\" in obj) {\n return \"argdump\";\n }\n\n return null;\n}\n","import type { BoundType } from \"../bindings/index.js\";\nimport type { Expr } from \"../ir/index.js\";\n\n/**\n * Find a description from an IR node, traversing through wrapper nodes.\n *\n * The parser's `wrapNode` hoists doc metadata to the outermost wrapper node,\n * but the solver's simplify pass can collapse sequences, burying descriptions\n * deeper in the tree.\n *\n * This traversal is type-aware: it only enters sequences when the corresponding\n * BoundType is not a struct. Struct sequences have their own field collection\n * call, so entering them would steal nested struct children's descriptions.\n *\n * @param node - The IR node to search for a description.\n * @param fieldType - The BoundType of the field, used to determine traversal boundaries.\n */\nexport function findDoc(node: Expr, fieldType: BoundType): string | undefined {\n if (node.meta?.doc?.description) return node.meta.doc.description;\n switch (node.kind) {\n case \"optional\":\n return findDoc(node.attrs.node, fieldType.kind === \"optional\" ? fieldType.inner : fieldType);\n case \"repeat\":\n return findDoc(node.attrs.node, fieldType.kind === \"list\" ? fieldType.item : fieldType);\n case \"sequence\": {\n // Only traverse into sequences that were collapsed (non-struct field types).\n // Struct sequences have their own collectFieldInfo call for their children.\n if (fieldType.kind === \"struct\") return undefined;\n for (const child of node.attrs.nodes) {\n const doc = findDoc(child, fieldType);\n if (doc) return doc;\n }\n return undefined;\n }\n default:\n return undefined;\n }\n}\n","import type { Binding, BoundType } from \"../bindings/index.js\";\nimport type { Expr } from \"../ir/index.js\";\nimport type { CodegenContext } from \"../manifest/index.js\";\n\n/**\n * Resolve a struct child node to its field binding, handling collapsed sequences.\n *\n * When the solver's simplify pass collapses `seq(lit(\"--flag\"), terminal)` into\n * just the terminal, the binding ends up on the inner node while metadata (doc,\n * defaultValue) may remain on the outermost wrapper. This function recursively\n * descends through collapsed sequences to find the binding, tracking the outermost\n * node for metadata recovery.\n *\n * Uses type identity (`===`) to verify the binding matches the struct's field type,\n * preventing cross-nesting name collisions where an inner struct has a field with\n * the same name as the outer struct.\n */\nexport function resolveFieldBinding(\n node: Expr,\n ctx: CodegenContext,\n structType: Extract<BoundType, { kind: \"struct\" }>,\n outermost?: Expr,\n): { binding: Binding; wrapperNode: Expr } | undefined {\n const wrapper = outermost ?? node;\n const binding = ctx.resolve(node);\n if (\n binding &&\n binding.name in structType.fields &&\n binding.type === structType.fields[binding.name]\n ) {\n return { binding, wrapperNode: wrapper };\n }\n // Recurse into collapsed sequences to find the binding deeper\n if (node.kind === \"sequence\") {\n for (const inner of node.attrs.nodes) {\n const result = resolveFieldBinding(inner, ctx, structType, wrapper);\n if (result) return result;\n }\n }\n return undefined;\n}\n","import type { BoundType } from \"../bindings/index.js\";\nimport type { Expr } from \"../ir/index.js\";\nimport type { CodegenContext } from \"../manifest/index.js\";\nimport { resolveFieldBinding } from \"./resolve-field-binding.js\";\n\n/**\n * Find the sequence node whose child bindings match a struct type's fields.\n *\n * Traverses through optional, repeat, and alternative wrappers to find the\n * sequence that directly contains the struct's field bindings. This is necessary\n * because the solver may collapse `seq(lit(\"--flag\"), terminal)` into the terminal,\n * burying bindings deeper in the tree.\n *\n * Uses a two-phase check for sequences:\n * 1. Direct binding check (`ctx.resolve`) - matches when bindings are on immediate children\n * 2. Recursive binding check (`resolveFieldBinding`) - matches when solver collapsed\n * a seq(lit, terminal) and the binding is buried deeper\n *\n * Phase 1 is tried first to avoid falsely matching an outer sequence when an inner\n * sequence is the actual struct owner (e.g. `seq(lit(\"--flag\"), seq(field1, field2))`).\n */\nexport function findStructNode(\n node: Expr,\n ctx: CodegenContext,\n structType: Extract<BoundType, { kind: \"struct\" }>,\n): Extract<Expr, { kind: \"sequence\" }> | undefined {\n switch (node.kind) {\n case \"sequence\": {\n // Phase 1: Check if any direct child has a binding matching a struct field\n for (const child of node.attrs.nodes) {\n const binding = ctx.resolve(child);\n if (\n binding &&\n binding.name in structType.fields &&\n binding.type === structType.fields[binding.name]\n ) {\n return node;\n }\n }\n // Recurse into child nodes first (prefer deeper matches)\n for (const child of node.attrs.nodes) {\n const result = findStructNode(child, ctx, structType);\n if (result) return result;\n }\n // Phase 2: Check via resolveFieldBinding for collapsed sequences\n // where bindings are buried inside collapsed seq(lit, terminal)\n for (const child of node.attrs.nodes) {\n if (resolveFieldBinding(child, ctx, structType)) return node;\n }\n return undefined;\n }\n case \"optional\":\n return findStructNode(node.attrs.node, ctx, structType);\n case \"repeat\":\n return findStructNode(node.attrs.node, ctx, structType);\n case \"alternative\": {\n for (const alt of node.attrs.alts) {\n const result = findStructNode(alt, ctx, structType);\n if (result) return result;\n }\n return undefined;\n }\n default:\n return undefined;\n }\n}\n","import type { BoundType } from \"../bindings/index.js\";\nimport type { CodegenContext } from \"../manifest/index.js\";\nimport { findDoc } from \"./find-doc.js\";\nimport { findStructNode } from \"./find-struct-node.js\";\nimport { resolveFieldBinding } from \"./resolve-field-binding.js\";\n\n/**\n * Metadata extracted for each field of a struct type.\n *\n * `doc` is the field's description, recovered from wrapper nodes via `findDoc`.\n * `defaultValue` is pulled from the wrapper or binding node's metadata.\n */\nexport interface FieldInfo {\n doc?: string;\n defaultValue?: string | number | boolean;\n}\n\n/**\n * Collect field metadata (doc, defaultValue) for each field of a struct type.\n *\n * Walks the IR tree to find the sequence node containing the struct's fields,\n * then resolves each child to its field binding. Metadata is recovered from both\n * the wrapper node (where the parser hoists doc) and the binding node (where the\n * solver places the binding after sequence collapse).\n */\nexport function collectFieldInfo(\n ctx: CodegenContext,\n structType: Extract<BoundType, { kind: \"struct\" }>,\n): Map<string, FieldInfo> {\n const info = new Map<string, FieldInfo>();\n\n const structNode = findStructNode(ctx.expr, ctx, structType);\n if (!structNode) return info;\n\n for (const child of structNode.attrs.nodes) {\n const match = resolveFieldBinding(child, ctx, structType);\n if (!match) continue;\n const { binding, wrapperNode } = match;\n const fieldInfo: FieldInfo = {};\n const fieldType = structType.fields[binding.name]!;\n // Check wrapper node first (doc may be hoisted there), then binding node\n const doc = findDoc(wrapperNode, fieldType) ?? findDoc(binding.node, fieldType);\n if (doc) fieldInfo.doc = doc;\n const defaultValue = wrapperNode.meta?.defaultValue ?? binding.node.meta?.defaultValue;\n if (defaultValue !== undefined) fieldInfo.defaultValue = defaultValue;\n info.set(binding.name, fieldInfo);\n }\n\n return info;\n}\n","import type { Expr } from \"../ir/index.js\";\nimport type { GateAtom } from \"./resolved-output.js\";\nimport type { BoundType } from \"./types.js\";\n\nexport type BindingId = string;\n\n/**\n * One step in a binding's access path relative to top-level `params`.\n *\n * - `field`: descend into a named field of the enclosing struct scope. Renders\n * as `params.name` (TS) / `params[\"name\"]` (Python).\n * - `iter`: the access base resets to the per-element loop variable bound to\n * `binding` (a `repeat`-of-list). The renderer substitutes the active loop\n * variable at emit time (from the `iter` gate atom's loop, or the\n * arg-builder's local loop), so segments after an `iter` build off the\n * element rather than off `params`.\n *\n * There is deliberately no `variant` or `directValue` segment: complex-union\n * variant fields are plain `field` segments off the union's own path (the\n * `@type` discriminant lives in `GateAtom`, not the access path), and the\n * solver's wrapper collapses (`optional<scalar>`, scalar lists) are expressed\n * by a binding simply inheriting its parent wrapper's path.\n */\nexport type AccessSegment = { kind: \"field\"; name: string } | { kind: \"iter\"; binding: BindingId };\n\n/**\n * A binding's location relative to top-level `params`, as a structured segment\n * sequence. Computed once by the solver (`assignAccessPaths`) and rendered by\n * each backend's `renderAccess`, so the arg-builder and outputs emitter share\n * one source of truth instead of each re-deriving paths.\n */\nexport type AccessPath = AccessSegment[];\n\nexport interface Binding {\n id: BindingId;\n node: Expr;\n name: string;\n type: BoundType;\n /**\n * Wrapper layers on the path from the root to this binding, root-to-leaf.\n * Captures the optional/repeat/alternative ancestors as `present`/`iter`/\n * `variant` atoms. Backends nest wrappers in array order; \"is this binding\n * conditionally active?\" reduces to `gate.length > 0`.\n */\n gate: GateAtom[];\n /**\n * Access path relative to top-level `params`, assigned by the solver's\n * `assignAccessPaths` pass after types settle. Backends render it via\n * `renderAccess` rather than re-walking the IR to recompute where this\n * binding lives.\n */\n access: AccessPath;\n}\n\nexport type BindingRegistry = Map<BindingId, Binding>;\n\nexport type OutputDiagnosticLevel = \"error\" | \"warning\";\n\nexport interface OutputDiagnostic {\n output: string;\n message: string;\n level: OutputDiagnosticLevel;\n}\n\nexport interface OutputValidationResult {\n errors: OutputDiagnostic[];\n warnings: OutputDiagnostic[];\n}\n\nexport interface SolveResult {\n bindings: BindingRegistry;\n resolve: (node: Expr) => Binding | undefined;\n}\n\nexport function createRegistry(): BindingRegistry {\n return new Map();\n}\n","import type { BindingRegistry } from \"./binding.js\";\nimport type { GateAtom, ResolvedOutput } from \"./resolved-output.js\";\n\n/**\n * The unified wrapper sequence for a single output: the scope's gate, then for\n * each ref token both the ref binding's path-gate and (if its type is itself\n * \"thick\" - nullable or iterable) a self-atom on the ref binding. Atoms are\n * deduped while preserving first-occurrence order.\n *\n * The self-atom encodes facts derivable from `Binding.type` alone:\n * - `optional`, `bool`, `count` -> `present(binding)` (value may be absent)\n * - `list` -> `iter(binding)` (iterate per element)\n *\n * `scopeGate` is the gate of the scope's struct binding (often `[]` at the\n * root). Backends nest wrappers in array order; the atom kind decides whether\n * it renders as a guard (`present` / `variant`) or a loop (`iter`).\n */\nexport function outputGate(\n scopeGate: GateAtom[],\n output: ResolvedOutput,\n bindings: BindingRegistry,\n): GateAtom[] {\n const seen = new Set<string>();\n const result: GateAtom[] = [];\n const push = (atom: GateAtom): void => {\n const key = atomKey(atom);\n if (seen.has(key)) return;\n seen.add(key);\n result.push(atom);\n };\n for (const atom of scopeGate) push(atom);\n for (const token of output.tokens) {\n if (token.kind !== \"ref\") continue;\n const refBinding = bindings.get(token.binding);\n if (!refBinding) continue;\n for (const atom of refBinding.gate) push(atom);\n const kind = refBinding.type.kind;\n if (kind === \"optional\" || kind === \"bool\" || kind === \"count\") {\n push({ kind: \"present\", binding: refBinding.id });\n } else if (kind === \"list\") {\n push({ kind: \"iter\", binding: refBinding.id });\n }\n }\n return result;\n}\n\nexport function atomKey(atom: GateAtom): string {\n if (atom.kind === \"variant\") return `v:${atom.binding}:${atom.variant}`;\n return `${atom.kind[0]}:${atom.binding}`;\n}\n","import type { Expr } from \"../ir/node.js\";\nimport type { AccessPath, BindingRegistry, OutputValidationResult } from \"./binding.js\";\nimport type { SolveResult } from \"./index.js\";\nimport { outputGate } from \"./output-gate.js\";\nimport type { GateAtom, OutputScope, ResolvedOutput, ResolvedToken } from \"./resolved-output.js\";\nimport type { BoundType } from \"./types.js\";\n\nexport interface FormatExtras {\n scopes?: OutputScope[];\n diagnostics?: OutputValidationResult;\n}\n\nexport function formatSolveResult(result: SolveResult, expr: Expr, extras?: FormatExtras): string {\n const binding = result.resolve(expr);\n const rootLine = binding ? `${binding.name}: ${formatType(binding.type)}` : \"(no binding)\";\n\n const sections = [rootLine];\n\n const gatedBindings = [...result.bindings.values()].filter(\n (b) => b.gate.length > 0 && b !== binding,\n );\n if (gatedBindings.length > 0) {\n sections.push(\"\", \"gates:\");\n for (const b of gatedBindings) {\n sections.push(` ${b.name}: ${formatGate(b.gate, result.bindings)}`);\n }\n }\n\n const accessBindings = [...result.bindings.values()].filter((b) => b.access.length > 0);\n if (accessBindings.length > 0) {\n sections.push(\"\", \"access:\");\n for (const b of accessBindings) {\n sections.push(` ${b.name}: ${formatAccess(b.access, result.bindings)}`);\n }\n }\n\n if (extras?.scopes?.length) {\n sections.push(\"\", \"outputs:\");\n for (const scope of extras.scopes) {\n const scopeBinding = result.bindings.get(scope.scope);\n const header = scopeBinding ? ` on ${scopeBinding.name}:` : \" on <unbound>:\";\n sections.push(header);\n const scopeGate = scopeBinding?.gate ?? [];\n for (const out of scope.outputs) {\n sections.push(formatResolvedOutput(out, scopeGate, result.bindings, 2));\n }\n }\n }\n\n const diags = [...(extras?.diagnostics?.errors ?? []), ...(extras?.diagnostics?.warnings ?? [])];\n if (diags.length > 0) {\n sections.push(\"\", \"diagnostics:\");\n for (const d of diags) sections.push(` [${d.level}] ${d.output}: ${d.message}`);\n }\n\n return sections.join(\"\\n\");\n}\n\nfunction formatResolvedOutput(\n out: ResolvedOutput,\n scopeGate: GateAtom[],\n bindings: BindingRegistry,\n indent: number,\n): string {\n const pad = \" \".repeat(indent);\n const media = out.mediaTypes?.length ? ` (${out.mediaTypes.join(\", \")})` : \"\";\n const tokens = out.tokens.map((t) => formatResolvedToken(t, bindings)).join(\" + \") || `\"\"`;\n const gateAtoms = outputGate(scopeGate, out, bindings);\n const optional = gateAtoms.some((a) => a.kind === \"present\" || a.kind === \"variant\");\n const optTag = optional ? \" [optional]\" : \"\";\n const gate =\n gateAtoms.length > 0\n ? ` when (${gateAtoms.map((a) => formatGateAtom(a, bindings)).join(\" AND \")})`\n : \"\";\n return `${pad}${out.name}${optTag}${media}: ${tokens}${gate}`;\n}\n\nfunction bindingName(bindings: BindingRegistry, id: string): string {\n return bindings.get(id)?.name ?? `<${id}>`;\n}\n\nexport function formatResolvedToken(token: ResolvedToken, bindings: BindingRegistry): string {\n if (token.kind === \"literal\") return JSON.stringify(token.value);\n const flags = [\n token.stripExtensions?.length && `strip=${JSON.stringify(token.stripExtensions)}`,\n token.fallback !== undefined && `fallback=${JSON.stringify(token.fallback)}`,\n ].filter(Boolean);\n const suffix = flags.length > 0 ? ` {${flags.join(\", \")}}` : \"\";\n return `ref(${bindingName(bindings, token.binding)})${suffix}`;\n}\n\nexport function formatGateAtom(atom: GateAtom, bindings: BindingRegistry): string {\n switch (atom.kind) {\n case \"present\":\n return `present(${bindingName(bindings, atom.binding)})`;\n case \"variant\":\n return `${bindingName(bindings, atom.binding)}=${atom.variant}`;\n case \"iter\":\n return `iter(${bindingName(bindings, atom.binding)})`;\n }\n}\n\nexport function formatGate(gate: GateAtom[], bindings: BindingRegistry): string {\n if (gate.length === 0) return \"(unconditional)\";\n return gate.map((a) => formatGateAtom(a, bindings)).join(\" / \");\n}\n\n/**\n * Render a binding's access path for debugging, e.g. `params.sub.x` or\n * `<iter:things>.file`. An `iter` segment shows the repeat it loops, since the\n * concrete loop variable is a backend emit-time detail.\n */\nexport function formatAccess(access: AccessPath, bindings: BindingRegistry): string {\n let out = \"params\";\n for (const seg of access) {\n out =\n seg.kind === \"field\" ? `${out}.${seg.name}` : `<iter:${bindingName(bindings, seg.binding)}>`;\n }\n return out;\n}\n\nfunction formatType(type: BoundType, indent = 0): string {\n const pad = \" \".repeat(indent);\n const inner = (t: BoundType) => formatType(t, indent + 1);\n\n switch (type.kind) {\n case \"scalar\":\n return type.scalar;\n case \"bool\":\n return \"bool\";\n case \"count\":\n return \"count\";\n case \"literal\":\n return typeof type.value === \"number\" ? String(type.value) : `\"${type.value}\"`;\n case \"optional\":\n return `optional<${inner(type.inner)}>`;\n case \"list\":\n return `list<${inner(type.item)}>`;\n\n case \"struct\": {\n const entries = Object.entries(type.fields);\n if (entries.length === 0) return \"struct {}\";\n if (entries.length === 1) {\n const [name, t] = entries[0]!;\n return `struct { ${name}: ${formatType(t)} }`;\n }\n const fields = entries.map(([name, t]) => `${pad} ${name}: ${inner(t)}`).join(\"\\n\");\n return `struct {\\n${fields}\\n${pad}}`;\n }\n\n case \"union\": {\n if (type.variants.length === 0) return \"union {}\";\n\n // If all variants are literals, display inline\n const allLiterals = type.variants.every((v) => v.type.kind === \"literal\");\n if (allLiterals) {\n return type.variants\n .map((v) =>\n v.type.kind === \"literal\"\n ? typeof v.type.value === \"number\"\n ? String(v.type.value)\n : `\"${v.type.value}\"`\n : \"?\",\n )\n .join(\" | \");\n }\n\n // Otherwise multi-line union\n const variants = type.variants.map((v) => `${pad} | ${v.name}: ${inner(v.type)}`).join(\"\\n\");\n return `union {\\n${variants}\\n${pad}}`;\n }\n\n default:\n return ((_x: never) => \"unknown\")(type);\n }\n}\n","import type {\n BindingRegistry,\n GateAtom,\n OutputScope,\n ResolvedOutput,\n ResolvedToken,\n} from \"../bindings/index.js\";\nimport { outputGate } from \"../bindings/index.js\";\n\n// Re-export the core helper so backends have a single entry point.\nexport { outputGate };\n\n/**\n * Compact consecutive literal tokens. Backends that emit string concatenation\n * benefit from a shorter token stream; backends that template each token\n * individually can ignore this and use `output.tokens` directly.\n */\nexport function compactTokens(tokens: ResolvedToken[]): ResolvedToken[] {\n const out: ResolvedToken[] = [];\n for (const tok of tokens) {\n const last = out[out.length - 1];\n if (tok.kind === \"literal\" && last && last.kind === \"literal\") {\n out[out.length - 1] = { kind: \"literal\", value: last.value + tok.value };\n } else {\n out.push(tok);\n }\n }\n return out;\n}\n\n/**\n * One output ready for codegen. `gate` is the wrapper sequence (outermost\n * first); the backend renders each atom as the appropriate scope-introducing\n * statement, then emits the path expression inside the innermost layer.\n */\nexport interface OutputEmitPlan {\n name: string;\n gate: GateAtom[];\n tokens: ResolvedToken[];\n resolved: ResolvedOutput;\n}\n\nexport function planOutput(\n scopeGate: GateAtom[],\n output: ResolvedOutput,\n bindings: BindingRegistry,\n): OutputEmitPlan {\n return {\n name: output.name,\n gate: outputGate(scopeGate, output, bindings),\n tokens: compactTokens(output.tokens),\n resolved: output,\n };\n}\n\n/**\n * Does the output have any conditional wrapper? Equivalent to \"is at least one\n * atom a `present` or `variant`?\". `iter` alone means the output emits a list\n * and is not conditionally absent.\n */\nexport function isGated(plan: OutputEmitPlan): boolean {\n return plan.gate.some((a) => a.kind === \"present\" || a.kind === \"variant\");\n}\n\n/** Does the output iterate (emit zero-or-more values)? */\nexport function isIterated(plan: OutputEmitPlan): boolean {\n return plan.gate.some((a) => a.kind === \"iter\");\n}\n\n/**\n * Convenience for backends emitting all outputs of a scope at once. The caller\n * provides the scope's gate (typically `bindings.get(scope.scope)?.gate ?? []`).\n */\nexport function planScope(\n scope: OutputScope,\n scopeGate: GateAtom[],\n bindings: BindingRegistry,\n): OutputEmitPlan[] {\n return scope.outputs.map((output) => planOutput(scopeGate, output, bindings));\n}\n","/** Symbol collision avoidance for code generation. */\nexport class Scope {\n private readonly reserved: ReadonlySet<string>;\n private readonly used: Set<string>;\n private readonly parent?: Scope;\n\n constructor(reserved: Iterable<string> = [], parent?: Scope) {\n this.reserved = new Set(reserved);\n this.used = new Set();\n this.parent = parent;\n }\n\n /** Check if a symbol is already taken (in this scope or any parent). */\n has(symbol: string): boolean {\n return (\n this.reserved.has(symbol) || this.used.has(symbol) || (this.parent?.has(symbol) ?? false)\n );\n }\n\n /**\n * Add a symbol, appending a numeric suffix to avoid collisions. Returns the\n * safe name.\n *\n * When a `recase` transform is given, a disambiguated candidate is routed back\n * through it so the suffix is absorbed into the identifier's casing - e.g.\n * `pascalCase` folds `Config_2` into `Config2` - rather than leaving a\n * mixed-case `Config_2`. Uniqueness is always checked on the final emitted\n * form, so two hints that case-collide still get distinct names. Defaults to\n * identity (the bare `<name>_<n>` suffix) for callers that don't case-normalize.\n */\n add(candidate: string, recase: (s: string) => string = (s) => s): string {\n if (!this.has(candidate)) {\n this.used.add(candidate);\n return candidate;\n }\n let suffix = 2;\n let safe = recase(`${candidate}_${suffix}`);\n while (this.has(safe)) {\n suffix++;\n safe = recase(`${candidate}_${suffix}`);\n }\n this.used.add(safe);\n return safe;\n }\n\n /** Create a child scope that inherits this scope's restrictions. */\n child(reserved: Iterable<string> = []): Scope {\n return new Scope(reserved, this);\n }\n}\n","import type {\n Binding,\n BindingId,\n BoundType,\n BoundVariant,\n GateAtom,\n OutputScope,\n ResolvedOutput,\n} from \"../../bindings/index.js\";\nimport type { Expr, ScalarKind } from \"../../ir/index.js\";\nimport type { AppMeta } from \"../../ir/meta.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport type { Backend, EmittedApp, EmitWarning } from \"../backend.js\";\nimport { collectFieldInfo } from \"../collect-field-info.js\";\nimport { findDoc } from \"../find-doc.js\";\nimport { findStructNode } from \"../find-struct-node.js\";\nimport { outputGate } from \"../resolve-output-tokens.js\";\nimport { resolveFieldBinding } from \"../resolve-field-binding.js\";\nimport { Scope } from \"../scope.js\";\nimport { screamingSnakeCase } from \"../string-case.js\";\n\n// Boutiques descriptor types (output format)\n\ninterface BtDescriptor {\n name?: string;\n id?: string;\n description?: string;\n \"schema-version\"?: string;\n \"tool-version\"?: string;\n author?: string;\n url?: string;\n \"container-image\"?: { image: string; type?: string };\n \"command-line\"?: string;\n inputs?: BtInput[];\n \"stdout-output\"?: { id: string; name?: string; description?: string };\n \"stderr-output\"?: { id: string; name?: string; description?: string };\n \"output-files\"?: BtOutputFile[];\n}\n\ninterface BtOutputFile {\n id: string;\n name?: string;\n description?: string;\n \"path-template\": string;\n optional?: boolean;\n list?: boolean;\n \"path-template-stripped-extensions\"?: string[];\n}\n\ninterface BtInput {\n id: string;\n name?: string;\n description?: string;\n type: string | BtDescriptor | BtDescriptor[];\n \"value-key\": string;\n optional?: boolean;\n list?: boolean;\n \"list-separator\"?: string;\n \"min-list-entries\"?: number;\n \"max-list-entries\"?: number;\n \"command-line-flag\"?: string;\n \"command-line-flag-separator\"?: string;\n \"value-choices\"?: (string | number)[];\n \"default-value\"?: string | number | boolean;\n minimum?: number;\n maximum?: number;\n integer?: boolean;\n \"resolve-parent\"?: boolean;\n mutable?: boolean;\n}\n\n// Wrapper peeling result\n\ninterface PeeledInput {\n isOptional: boolean;\n isList: boolean;\n listSeparator?: string;\n minListEntries?: number;\n maxListEntries?: number;\n flag?: string;\n flagSeparator?: string;\n}\n\nclass BoutiquesEmitter {\n private warnings: EmitWarning[] = [];\n // Scope binding id -> outputs declared on that struct. The solver forces a\n // binding on every output-carrying sequence, so this is a one-liner.\n private outputsByScope = new Map<BindingId, OutputScope>();\n\n constructor(private ctx: CodegenContext) {\n for (const scope of ctx.outputScopes) this.outputsByScope.set(scope.scope, scope);\n }\n\n private warn(message: string): void {\n this.warnings.push({ message });\n }\n\n emit(): { descriptor: BtDescriptor; warnings: EmitWarning[] } {\n const descriptor = this.buildRootDescriptor();\n return { descriptor, warnings: this.warnings };\n }\n\n private buildRootDescriptor(): BtDescriptor {\n const bt: BtDescriptor = { \"schema-version\": \"0.5+styx\" };\n\n // Map AppMeta to root descriptor fields\n const app = this.ctx.app;\n if (app) {\n this.applyAppMeta(bt, app);\n }\n\n // Resolve root binding\n const rootBinding = this.ctx.resolve(this.ctx.expr);\n if (!rootBinding) {\n // No root binding - the solver collapsed single-field sequences.\n // Walk the expression tree directly to synthesize the descriptor.\n this.buildFromUnboundSequence(bt, this.ctx.expr);\n return bt;\n }\n\n this.buildDescriptorBody(bt, rootBinding, this.ctx.expr);\n return bt;\n }\n\n private applyAppMeta(bt: BtDescriptor, app: AppMeta): void {\n // Boutiques requires `name` at root and disallows `id` there.\n const rootName = app.doc?.title ?? app.id;\n if (rootName) bt.name = rootName;\n if (app.doc?.description) bt.description = app.doc.description;\n if (app.version) bt[\"tool-version\"] = app.version;\n if (app.doc?.authors?.[0]) bt.author = app.doc.authors[0];\n if (app.doc?.urls?.[0]) bt.url = app.doc.urls[0];\n if (app.container) {\n bt[\"container-image\"] = {\n image: app.container.image,\n ...(app.container.type && { type: app.container.type }),\n };\n }\n if (app.stdout) {\n bt[\"stdout-output\"] = {\n id: app.stdout.name,\n ...(app.stdout.doc?.title && { name: app.stdout.doc.title }),\n ...(app.stdout.doc?.description && { description: app.stdout.doc.description }),\n };\n }\n if (app.stderr) {\n bt[\"stderr-output\"] = {\n id: app.stderr.name,\n ...(app.stderr.doc?.title && { name: app.stderr.doc.title }),\n ...(app.stderr.doc?.description && { description: app.stderr.doc.description }),\n };\n }\n }\n\n private buildDescriptorBody(bt: BtDescriptor, binding: Binding, expr: Expr): void {\n const type = binding.type;\n\n if (type.kind === \"struct\") {\n this.buildFromStruct(bt, type, expr);\n } else {\n // Root is not a struct (e.g. simplified to a literal) - just build command line\n bt[\"command-line\"] = this.buildCommandLineFromExpr(expr);\n }\n }\n\n // Handle sequences where the solver collapsed single-field structs.\n // Walk children, emitting literals as command-line text and bound nodes as inputs.\n private buildFromUnboundSequence(bt: BtDescriptor, expr: Expr): void {\n if (expr.kind !== \"sequence\") {\n bt[\"command-line\"] = this.buildCommandLineFromExpr(expr);\n return;\n }\n\n const scope = new Scope();\n const idScope = new Scope();\n const commandParts: string[] = [];\n const inputs: BtInput[] = [];\n const valueKeyByBinding = new Map<BindingId, string>();\n\n for (const child of expr.attrs.nodes) {\n if (child.kind === \"literal\") {\n commandParts.push(child.attrs.str);\n continue;\n }\n\n const binding = this.ctx.resolve(child);\n if (binding) {\n // Direct binding on this child\n const id = idScope.add(this.sanitizeId(binding.name));\n const valueKey = scope.add(screamingSnakeCase(id));\n const valueKeyStr = `[${valueKey}]`;\n valueKeyByBinding.set(binding.id, valueKeyStr);\n const peeled = this.peelNode(child, binding.type);\n if (this.isBool(binding.type) && !peeled.flag) {\n const flagStr = this.extractBoolFlag(child);\n if (flagStr) peeled.flag = flagStr;\n }\n const input = this.buildInputFromBinding(binding, id, valueKeyStr, peeled, child);\n commandParts.push(valueKeyStr);\n inputs.push(input);\n } else {\n // No direct binding - might be a nested sequence (subcommand).\n // Try to find bindings deeper inside.\n const deepBinding = this.findDeepBinding(child);\n if (deepBinding) {\n const rawName = child.meta?.name ?? deepBinding.name;\n const id = idScope.add(this.sanitizeId(rawName));\n const valueKey = scope.add(screamingSnakeCase(id));\n const valueKeyStr = `[${valueKey}]`;\n const subBt = this.buildSubCommandFromUnbound(child);\n const input: BtInput = {\n id,\n type: subBt,\n \"value-key\": valueKeyStr,\n };\n this.finalizeInput(input);\n commandParts.push(valueKeyStr);\n inputs.push(input);\n } else {\n commandParts.push(this.buildCommandLineFromExpr(child));\n }\n }\n }\n\n bt[\"command-line\"] = commandParts.join(\" \");\n bt.inputs = inputs;\n this.emitOutputFiles(bt, expr, valueKeyByBinding, idScope);\n }\n\n // Build a subcommand descriptor from an unbound sequence node\n private buildSubCommandFromUnbound(node: Expr): BtDescriptor {\n const bt: BtDescriptor = {};\n if (node.meta?.name) {\n bt.name = node.meta.name;\n bt.id = this.sanitizeId(node.meta.name);\n }\n this.buildFromUnboundSequence(bt, node);\n return bt;\n }\n\n // Find any binding in a subtree\n private findDeepBinding(node: Expr): Binding | undefined {\n const binding = this.ctx.resolve(node);\n if (binding) return binding;\n\n switch (node.kind) {\n case \"sequence\":\n for (const child of node.attrs.nodes) {\n const found = this.findDeepBinding(child);\n if (found) return found;\n }\n return undefined;\n case \"optional\":\n return this.findDeepBinding(node.attrs.node);\n case \"repeat\":\n return this.findDeepBinding(node.attrs.node);\n case \"alternative\":\n for (const alt of node.attrs.alts) {\n const found = this.findDeepBinding(alt);\n if (found) return found;\n }\n return undefined;\n default:\n return undefined;\n }\n }\n\n // Build an input from a binding directly (without struct context)\n private buildInputFromBinding(\n binding: Binding,\n id: string,\n valueKey: string,\n peeled: PeeledInput,\n wrapperNode: Expr,\n ): BtInput {\n const innerType = this.unwrapType(binding.type);\n const mapped = this.mapType(innerType, wrapperNode);\n\n const input: BtInput = {\n id,\n type: mapped.type,\n \"value-key\": valueKey,\n };\n\n if (binding.node.meta?.doc?.title) input.name = binding.node.meta.doc.title;\n if (binding.node.meta?.doc?.description) input.description = binding.node.meta.doc.description;\n\n if (peeled.isOptional || mapped.optional) input.optional = true;\n const isList = peeled.isList || mapped.list === true;\n if (isList) {\n input.list = true;\n const listSep = peeled.listSeparator ?? mapped.listSeparator;\n const minEntries = peeled.minListEntries ?? mapped.minListEntries;\n if (listSep !== undefined) input[\"list-separator\"] = listSep;\n if (minEntries !== undefined) input[\"min-list-entries\"] = minEntries;\n if (peeled.maxListEntries !== undefined) input[\"max-list-entries\"] = peeled.maxListEntries;\n }\n if (peeled.flag) {\n input[\"command-line-flag\"] = peeled.flag;\n if (peeled.flagSeparator) input[\"command-line-flag-separator\"] = peeled.flagSeparator;\n }\n if (mapped.integer) input.integer = true;\n if (mapped.minimum !== undefined) input.minimum = mapped.minimum;\n if (mapped.maximum !== undefined) input.maximum = mapped.maximum;\n if (mapped.valueChoices) input[\"value-choices\"] = mapped.valueChoices;\n if (mapped.resolveParent) input[\"resolve-parent\"] = true;\n if (mapped.mutable) input[\"mutable\"] = true;\n\n if (innerType.kind !== \"count\") {\n const defaultValue = binding.node.meta?.defaultValue;\n if (defaultValue !== undefined) input[\"default-value\"] = defaultValue;\n }\n\n this.finalizeInput(input);\n return input;\n }\n\n // Boutiques' default-value substitutes when the user omits the input;\n // argparse's default is the parser's internal fallback, not a CLI value\n // to materialize. Surface it in the description instead.\n private mergeDefaultIntoDescription(input: BtInput): void {\n const dv = input[\"default-value\"];\n if (dv === undefined) return;\n delete input[\"default-value\"];\n if (input.type === \"Flag\") return;\n const formatted = typeof dv === \"string\" ? JSON.stringify(dv) : String(dv);\n const suffix = `Default: ${formatted}`;\n const desc = input.description;\n input.description = desc ? `${desc.replace(/\\s+$/, \"\")} (${suffix})` : suffix;\n }\n\n private buildFromStruct(\n bt: BtDescriptor,\n structType: Extract<BoundType, { kind: \"struct\" }>,\n expr: Expr,\n ): void {\n const structNode = findStructNode(expr, this.ctx, structType);\n if (!structNode) {\n bt[\"command-line\"] = \"\";\n bt.inputs = [];\n return;\n }\n\n // `findStructNode` may descend below `expr` to the sequence whose direct\n // children are the struct's fields (e.g. when a single-field inner sequence\n // was preserved by flatten to keep its doc, then collapsed). Any command\n // literals on the path from `expr` down to that node would otherwise be\n // dropped - including the tool's own command name. Recover them as a prefix.\n const prefixLiterals =\n structNode === expr ? [] : (commandPrefixLiterals(expr, structNode) ?? []);\n\n const scope = new Scope();\n const idScope = new Scope();\n const commandParts: string[] = [...prefixLiterals];\n const inputs: BtInput[] = [];\n const valueKeyByBinding = new Map<BindingId, string>();\n const fieldInfo = collectFieldInfo(this.ctx, structType);\n\n for (const child of structNode.attrs.nodes) {\n // Literal nodes -> command-line text\n if (child.kind === \"literal\") {\n commandParts.push(child.attrs.str);\n continue;\n }\n\n // Try to resolve to a field binding\n const match = resolveFieldBinding(child, this.ctx, structType);\n if (!match) {\n // Unbound non-literal node - no command-line text we can emit.\n continue;\n }\n\n const { binding, wrapperNode } = match;\n const fieldType = structType.fields[binding.name];\n if (!fieldType) continue;\n\n // Skip literal fields (union discriminators, not user-facing)\n if (fieldType.kind === \"literal\") continue;\n\n const id = idScope.add(this.sanitizeId(binding.name));\n const valueKey = scope.add(screamingSnakeCase(id));\n const valueKeyStr = `[${valueKey}]`;\n valueKeyByBinding.set(binding.id, valueKeyStr);\n\n // Peel wrapper layers from the IR node\n const peeled = this.peelNode(wrapperNode, fieldType);\n\n // Bool IR pattern: optional(literal(\"-v\")) - the literal IS the flag.\n if (this.isBool(fieldType) && !peeled.flag) {\n const flagStr = this.extractBoolFlag(wrapperNode);\n if (flagStr) peeled.flag = flagStr;\n }\n\n const input = this.buildInput(\n binding,\n id,\n fieldType,\n valueKeyStr,\n peeled,\n fieldInfo,\n wrapperNode,\n );\n\n // Add flag to command line if present, then value-key\n if (peeled.flag) {\n if (\n fieldType.kind === \"bool\" ||\n (fieldType.kind === \"optional\" && this.isBool(fieldType))\n ) {\n // Bool flags: the value-key IS the flag\n commandParts.push(valueKeyStr);\n } else {\n // Value flags: flag then value-key as separate args\n commandParts.push(valueKeyStr);\n }\n } else {\n commandParts.push(valueKeyStr);\n }\n\n inputs.push(input);\n }\n\n bt[\"command-line\"] = commandParts.join(\" \");\n bt.inputs = inputs;\n this.emitOutputFiles(bt, expr, valueKeyByBinding, idScope);\n }\n\n // Emit `output-files` entries declared on this struct binding. `optional`\n // and `list` are derived from the unified gate (scope binding's gate plus\n // each ref's binding gate plus type-derived atoms). Refs that point to\n // bindings outside the scope are dropped with a warning; output ids share\n // the input id scope so they cannot collide.\n private emitOutputFiles(\n bt: BtDescriptor,\n scopeNode: Expr,\n valueKeys: Map<BindingId, string>,\n idScope: Scope,\n ): void {\n const scopeBinding = this.ctx.resolve(scopeNode);\n if (!scopeBinding) return;\n const scope = this.outputsByScope.get(scopeBinding.id);\n if (!scope || scope.outputs.length === 0) return;\n\n const files: BtOutputFile[] = [];\n for (const output of scope.outputs) {\n const file = this.buildOutputFile(scopeBinding.gate, output, valueKeys, idScope);\n if (file) files.push(file);\n }\n if (files.length > 0) bt[\"output-files\"] = files;\n }\n\n private buildOutputFile(\n scopeGate: GateAtom[],\n output: ResolvedOutput,\n valueKeys: Map<BindingId, string>,\n idScope: Scope,\n ): BtOutputFile | null {\n let template = \"\";\n let stripExtensions: string[] | undefined;\n let droppedRef = false;\n\n for (const token of output.tokens) {\n if (token.kind === \"literal\") {\n template += token.value;\n continue;\n }\n const key = valueKeys.get(token.binding);\n if (!key) {\n const bindingName = this.ctx.bindings.get(token.binding)?.name ?? \"<unknown>\";\n this.warn(\n `Output '${output.name}' references binding '${bindingName}' that is not in the same descriptor scope`,\n );\n droppedRef = true;\n continue;\n }\n template += key;\n // The parser applies the same stripped-extensions list to every ref in\n // an output, so taking the first non-empty list round-trips cleanly.\n if (token.stripExtensions && !stripExtensions) stripExtensions = token.stripExtensions;\n }\n\n // If we couldn't resolve any refs and the template is empty, drop the\n // output entirely. (A literal-only template stays.)\n if (droppedRef && template === \"\") return null;\n\n const gate = outputGate(scopeGate, output, this.ctx.bindings);\n const isOptional = gate.some((a) => a.kind === \"present\" || a.kind === \"variant\");\n const isList = gate.some((a) => a.kind === \"iter\");\n\n const id = idScope.add(this.sanitizeId(output.name));\n const file: BtOutputFile = { id, \"path-template\": template };\n if (output.doc?.title) file.name = output.doc.title;\n if (output.doc?.description) file.description = output.doc.description;\n if (isOptional) file.optional = true;\n if (isList) file.list = true;\n if (stripExtensions) file[\"path-template-stripped-extensions\"] = stripExtensions;\n return file;\n }\n\n // Extract flag literal from a bool IR pattern: optional(literal(\"-v\"))\n private extractBoolFlag(node: Expr): string | undefined {\n if (node.kind === \"optional\") return this.extractBoolFlag(node.attrs.node);\n if (node.kind === \"literal\") return node.attrs.str;\n return undefined;\n }\n\n private buildInput(\n binding: Binding,\n id: string,\n fieldType: BoundType,\n valueKey: string,\n peeled: PeeledInput,\n fieldInfo: Map<string, { doc?: string; defaultValue?: string | number | boolean }>,\n wrapperNode: Expr,\n ): BtInput {\n const info = fieldInfo.get(binding.name);\n const innerType = this.unwrapType(fieldType);\n const mapped = this.mapType(innerType, wrapperNode);\n\n const input: BtInput = {\n id,\n type: mapped.type,\n \"value-key\": valueKey,\n };\n\n // Name (short label) - only from explicit title, not description\n const title = binding.node.meta?.doc?.title;\n if (title) input.name = title;\n\n // Description (longer help text)\n const description =\n info?.doc ?? binding.node.meta?.doc?.description ?? findDoc(binding.node, fieldType);\n if (description) input.description = description;\n\n if (peeled.isOptional || mapped.optional) input.optional = true;\n\n const isList = peeled.isList || mapped.list === true;\n if (isList) {\n input.list = true;\n const listSep = peeled.listSeparator ?? mapped.listSeparator;\n const minEntries = peeled.minListEntries ?? mapped.minListEntries;\n if (listSep !== undefined) input[\"list-separator\"] = listSep;\n if (minEntries !== undefined) input[\"min-list-entries\"] = minEntries;\n if (peeled.maxListEntries !== undefined) input[\"max-list-entries\"] = peeled.maxListEntries;\n }\n\n // Flag\n if (peeled.flag) {\n input[\"command-line-flag\"] = peeled.flag;\n if (peeled.flagSeparator) input[\"command-line-flag-separator\"] = peeled.flagSeparator;\n }\n\n // Constraints from mapped type\n if (mapped.integer) input.integer = true;\n if (mapped.minimum !== undefined) input.minimum = mapped.minimum;\n if (mapped.maximum !== undefined) input.maximum = mapped.maximum;\n if (mapped.valueChoices) input[\"value-choices\"] = mapped.valueChoices;\n if (mapped.resolveParent) input[\"resolve-parent\"] = true;\n if (mapped.mutable) input[\"mutable\"] = true;\n\n // count's \"default\" is implicit via min-list-entries:0; skip emitting it.\n if (innerType.kind !== \"count\") {\n const defaultValue = info?.defaultValue ?? binding.node.meta?.defaultValue;\n if (defaultValue !== undefined) input[\"default-value\"] = defaultValue;\n }\n\n this.finalizeInput(input);\n return input;\n }\n\n // Normalize an input so the descriptor is valid even when upstream types\n // are dynamic (functools.partial, custom action classes) and the parser\n // had to fall back to String.\n private finalizeInput(input: BtInput): void {\n if (input.name === undefined) input.name = input.id;\n\n // A String with a bool default and no choices is really a Flag.\n if (\n input.type === \"String\" &&\n typeof input[\"default-value\"] === \"boolean\" &&\n input[\"value-choices\"] === undefined\n ) {\n input.type = \"Flag\";\n }\n\n if (input.type === \"Flag\") {\n delete input[\"default-value\"];\n delete input[\"value-choices\"];\n delete input.list;\n delete input[\"list-separator\"];\n delete input[\"min-list-entries\"];\n delete input[\"max-list-entries\"];\n } else if (input.type === \"String\") {\n const dv = input[\"default-value\"];\n if (dv !== undefined && typeof dv !== \"string\") {\n input[\"default-value\"] = String(dv);\n }\n const choices = input[\"value-choices\"];\n if (Array.isArray(choices)) {\n input[\"value-choices\"] = choices.map((c) => (typeof c === \"string\" ? c : String(c)));\n }\n } else if (input.type === \"Number\") {\n const dv = input[\"default-value\"];\n if (dv !== undefined && typeof dv !== \"number\") {\n const num = Number(dv);\n if (Number.isFinite(num)) input[\"default-value\"] = num;\n else delete input[\"default-value\"];\n }\n }\n\n // Default must be one of the choices, or dropped.\n const choices = input[\"value-choices\"];\n const dv = input[\"default-value\"];\n if (Array.isArray(choices) && dv !== undefined && !choices.some((c) => c === dv)) {\n delete input[\"default-value\"];\n }\n\n this.mergeDefaultIntoDescription(input);\n }\n\n // Peel wrapper layers from an IR node to extract Boutiques input properties.\n // Walks from outermost to innermost, detecting optional/repeat/flag patterns.\n private peelNode(node: Expr, type: BoundType): PeeledInput {\n const result: PeeledInput = { isOptional: false, isList: false };\n this.peelNodeInner(node, type, result);\n return result;\n }\n\n private peelNodeInner(node: Expr, type: BoundType, result: PeeledInput): void {\n switch (node.kind) {\n case \"optional\":\n result.isOptional = true;\n this.peelNodeInner(node.attrs.node, type.kind === \"optional\" ? type.inner : type, result);\n break;\n\n case \"repeat\":\n // count's Repeat is the count, not a list - mapType handles it.\n if (this.isCount(type)) {\n break;\n }\n result.isList = true;\n if (node.attrs.join !== undefined) result.listSeparator = node.attrs.join;\n if (node.attrs.countMin !== undefined) result.minListEntries = node.attrs.countMin;\n if (node.attrs.countMax !== undefined) result.maxListEntries = node.attrs.countMax;\n this.peelNodeInner(node.attrs.node, type.kind === \"list\" ? type.item : type, result);\n break;\n\n case \"sequence\": {\n // Detect flag pattern: seq(lit(flag), inner)\n const nodes = node.attrs.nodes;\n if (nodes.length === 2 && nodes[0]!.kind === \"literal\") {\n const flagLit = nodes[0]!.attrs.str;\n const { flag, separator } = this.splitFlagLiteral(flagLit);\n result.flag = flag;\n if (separator) result.flagSeparator = separator;\n this.peelNodeInner(nodes[1]!, type, result);\n }\n // Otherwise don't peel further (it's a struct sequence or similar)\n break;\n }\n\n default:\n // Terminal or other node - nothing more to peel\n break;\n }\n }\n\n // Split a flag literal like \"-f \" or \"--flag=\" into flag + separator.\n // The parser merges flag + separator into one literal: `flag + (flagSep ?? \"\")`\n private splitFlagLiteral(str: string): { flag: string; separator: string } {\n // If it ends with \"=\", split there\n if (str.endsWith(\"=\")) {\n return { flag: str.slice(0, -1), separator: \"=\" };\n }\n // If it ends with whitespace, strip it\n const trimmed = str.trimEnd();\n if (trimmed.length < str.length) {\n return { flag: trimmed, separator: str.slice(trimmed.length) };\n }\n // No separator\n return { flag: str, separator: \"\" };\n }\n\n // Unwrap optional/list layers to get the \"core\" type for mapping\n private unwrapType(type: BoundType): BoundType {\n if (type.kind === \"optional\") return this.unwrapType(type.inner);\n if (type.kind === \"list\") return this.unwrapType(type.item);\n return type;\n }\n\n // Returned list/optional fields override peeled values (for `count`, whose\n // IR Repeat does not correspond to a Boutiques list).\n private mapType(\n type: BoundType,\n node: Expr,\n ): {\n type: string | BtDescriptor | BtDescriptor[];\n integer?: boolean;\n minimum?: number;\n maximum?: number;\n valueChoices?: (string | number)[];\n resolveParent?: boolean;\n mutable?: boolean;\n list?: boolean;\n listSeparator?: string;\n minListEntries?: number;\n optional?: boolean;\n } {\n switch (type.kind) {\n case \"scalar\":\n return this.mapScalar(type.scalar, node);\n\n case \"bool\":\n return { type: \"Flag\" };\n\n case \"count\":\n return this.mapCount(node);\n\n case \"literal\":\n // Single literal - emit as String with value-choices\n return {\n type: \"String\",\n valueChoices: [type.value],\n };\n\n case \"struct\":\n return { type: this.buildSubCommand(type, node) };\n\n case \"union\":\n return this.mapUnion(type, node);\n\n // optional/list should have been unwrapped already\n case \"optional\":\n return this.mapType(type.inner, node);\n case \"list\":\n return this.mapType(type.item, node);\n }\n }\n\n private mapScalar(\n scalar: ScalarKind,\n node: Expr,\n ): {\n type: string;\n integer?: boolean;\n minimum?: number;\n maximum?: number;\n resolveParent?: boolean;\n mutable?: boolean;\n } {\n const terminal = this.findTerminal(node);\n\n switch (scalar) {\n case \"int\": {\n const result: { type: string; integer: true; minimum?: number; maximum?: number } = {\n type: \"Number\",\n integer: true,\n };\n if (terminal?.kind === \"int\") {\n if (terminal.attrs.minValue !== undefined) result.minimum = terminal.attrs.minValue;\n if (terminal.attrs.maxValue !== undefined) result.maximum = terminal.attrs.maxValue;\n }\n return result;\n }\n\n case \"float\": {\n const result: { type: string; minimum?: number; maximum?: number } = { type: \"Number\" };\n if (terminal?.kind === \"float\") {\n if (terminal.attrs.minValue !== undefined) result.minimum = terminal.attrs.minValue;\n if (terminal.attrs.maxValue !== undefined) result.maximum = terminal.attrs.maxValue;\n }\n return result;\n }\n\n case \"str\":\n return { type: \"String\" };\n\n case \"path\": {\n const result: { type: string; resolveParent?: boolean; mutable?: boolean } = {\n type: \"File\",\n };\n if (terminal?.kind === \"path\") {\n if (terminal.attrs.resolveParent) result.resolveParent = true;\n if (terminal.attrs.mutable) result.mutable = true;\n }\n return result;\n }\n }\n }\n\n private mapUnion(\n type: Extract<BoundType, { kind: \"union\" }>,\n node: Expr,\n ): {\n type: string | BtDescriptor | BtDescriptor[];\n valueChoices?: (string | number)[];\n } {\n // All-literal union -> value-choices\n const allLiteral = type.variants.every((v: BoundVariant) => v.type.kind === \"literal\");\n if (allLiteral) {\n return {\n type: \"String\",\n valueChoices: type.variants.map((v: BoundVariant) =>\n v.type.kind === \"literal\" ? v.type.value : \"\",\n ),\n };\n }\n\n // All-struct union -> SubCommandUnion\n const allStruct = type.variants.every((v: BoundVariant) => v.type.kind === \"struct\");\n if (allStruct) {\n return { type: this.buildSubCommandUnion(type, node) };\n }\n\n // Mixed union -> wrap each variant as a SubCommand descriptor\n return { type: this.buildMixedUnionAsSubCommands(type, node) };\n }\n\n private buildSubCommand(type: Extract<BoundType, { kind: \"struct\" }>, node: Expr): BtDescriptor {\n const bt: BtDescriptor = {};\n const structNode = findStructNode(node, this.ctx, type);\n if (structNode) {\n // Recursively serialize as nested descriptor\n this.buildFromStruct(bt, type, node);\n }\n if (node.meta?.name) {\n bt.name = node.meta.name;\n bt.id = this.sanitizeId(node.meta.name);\n }\n return bt;\n }\n\n private buildSubCommandUnion(\n type: Extract<BoundType, { kind: \"union\" }>,\n node: Expr,\n ): BtDescriptor[] {\n const alts = node.kind === \"alternative\" ? node.attrs.alts : [node];\n\n return type.variants.map((variant: BoundVariant, i: number) => {\n const altNode = alts[i] ?? node;\n if (variant.type.kind === \"struct\") {\n const bt = this.buildSubCommand(variant.type, altNode);\n // The variant has its own name; the wrapperNode's name is the\n // parent (mutex group) name and would otherwise leak down.\n if (variant.name) {\n bt.name = variant.name;\n bt.id = this.sanitizeId(variant.name);\n }\n return bt;\n }\n return this.wrapAsDescriptor(variant, altNode);\n });\n }\n\n private buildMixedUnionAsSubCommands(\n type: Extract<BoundType, { kind: \"union\" }>,\n node: Expr,\n ): BtDescriptor[] {\n const alts = node.kind === \"alternative\" ? node.attrs.alts : [node];\n\n return type.variants.map((variant: BoundVariant, i: number) => {\n const altNode = alts[i] ?? node;\n if (variant.type.kind === \"struct\") {\n const bt = this.buildSubCommand(variant.type, altNode);\n // The variant has its own name; the wrapperNode's name is the\n // parent (mutex group) name and would otherwise leak down.\n if (variant.name) {\n bt.name = variant.name;\n bt.id = this.sanitizeId(variant.name);\n }\n return bt;\n }\n return this.wrapAsDescriptor(variant, altNode);\n });\n }\n\n // Wrap a non-struct variant as a trivial single-input descriptor\n private wrapAsDescriptor(variant: BoundVariant, node: Expr): BtDescriptor {\n const name = variant.name ?? \"value\";\n const id = this.sanitizeId(name);\n const mapped = this.mapType(variant.type, node);\n const input: BtInput = {\n id,\n type: mapped.type,\n \"value-key\": `[${screamingSnakeCase(id)}]`,\n };\n if (mapped.valueChoices) input[\"value-choices\"] = mapped.valueChoices;\n if (mapped.integer) input.integer = true;\n if (mapped.minimum !== undefined) input.minimum = mapped.minimum;\n if (mapped.maximum !== undefined) input.maximum = mapped.maximum;\n\n this.finalizeInput(input);\n\n return {\n name,\n id,\n \"command-line\": `[${screamingSnakeCase(id)}]`,\n inputs: [input],\n };\n }\n\n // Find terminal node through wrappers\n private findTerminal(node: Expr): Expr | undefined {\n switch (node.kind) {\n case \"optional\":\n return this.findTerminal(node.attrs.node);\n case \"repeat\":\n return this.findTerminal(node.attrs.node);\n case \"sequence\": {\n const nonLiteral = node.attrs.nodes.find((n) => n.kind !== \"literal\");\n return nonLiteral ? this.findTerminal(nonLiteral) : undefined;\n }\n default:\n return node;\n }\n }\n\n // Build a simple command-line string from literal nodes in an expression\n private buildCommandLineFromExpr(expr: Expr): string {\n if (expr.kind === \"literal\") return expr.attrs.str;\n if (expr.kind === \"sequence\") {\n return expr.attrs.nodes.map((n) => this.buildCommandLineFromExpr(n)).join(\" \");\n }\n return \"\";\n }\n\n private isBool(type: BoundType): boolean {\n if (type.kind === \"bool\") return true;\n if (type.kind === \"optional\") return this.isBool(type.inner);\n return false;\n }\n\n private isCount(type: BoundType): boolean {\n if (type.kind === \"count\") return true;\n if (type.kind === \"optional\") return this.isCount(type.inner);\n return false;\n }\n\n // Boutiques `id` must match /^[0-9A-Za-z_]+$/ (input ids, sub-descriptor\n // ids, value-keys after [ ] removal). Non-matching chars (e.g. argparse\n // subparser names with hyphens) become underscores.\n private sanitizeId(raw: string): string {\n const cleaned = raw.replace(/[^0-9A-Za-z_]/g, \"_\");\n return cleaned.length > 0 ? cleaned : \"id\";\n }\n\n private findCountRepeat(node: Expr): Extract<Expr, { kind: \"repeat\" }> | undefined {\n switch (node.kind) {\n case \"repeat\":\n return node;\n case \"optional\":\n return this.findCountRepeat(node.attrs.node);\n default:\n return undefined;\n }\n }\n\n // Bounded count -> String + enumerated value-choices.\n // Unbounded count -> SubCommand + list:true (no list-separator: each\n // occurrence must be a separate argv element for argparse to count it).\n private mapCount(node: Expr): {\n type: string | BtDescriptor;\n valueChoices?: string[];\n list?: boolean;\n listSeparator?: string;\n minListEntries?: number;\n optional?: boolean;\n } {\n const repeat = this.findCountRepeat(node);\n if (!repeat || repeat.attrs.node.kind !== \"literal\") {\n return { type: \"Flag\" };\n }\n const flag = repeat.attrs.node.attrs.str;\n const countMin = repeat.attrs.countMin ?? 0;\n const countMax = repeat.attrs.countMax;\n\n if (countMax !== undefined && countMax >= Math.max(countMin, 1)) {\n const choices: string[] = [];\n const start = Math.max(countMin, 1);\n for (let i = start; i <= countMax; i++) choices.push(flag.repeat(i));\n return {\n type: \"String\",\n valueChoices: choices,\n ...(countMin === 0 && { optional: true }),\n };\n }\n\n const dest = repeat.meta?.name;\n const subId = this.sanitizeId(dest ? `${dest}_token` : \"count_token\");\n const subBt: BtDescriptor = {\n name: subId,\n id: subId,\n \"command-line\": flag,\n inputs: [],\n };\n\n return {\n type: subBt,\n list: true,\n minListEntries: countMin,\n };\n }\n}\n\n/**\n * The ordered command literals on the path from `node` down to `target`,\n * descending only through sequences (the structure `findStructNode` follows to\n * reach a struct whose fields are direct children). Returns `null` when\n * `target` is not reachable that way - callers then emit no prefix. Literals\n * inside `target` itself are excluded; the caller walks those separately.\n */\nfunction commandPrefixLiterals(node: Expr, target: Expr): string[] | null {\n if (node === target) return [];\n if (node.kind !== \"sequence\") return null;\n const lits: string[] = [];\n for (const child of node.attrs.nodes) {\n if (child === target) return lits;\n if (child.kind === \"literal\") {\n lits.push(child.attrs.str);\n continue;\n }\n const deeper = commandPrefixLiterals(child, target);\n if (deeper !== null) return [...lits, ...deeper];\n }\n return null;\n}\n\nexport function generateBoutiques(ctx: CodegenContext): {\n descriptor: BtDescriptor;\n warnings: EmitWarning[];\n} {\n return new BoutiquesEmitter(ctx).emit();\n}\n\nexport class BoutiquesBackend implements Backend {\n readonly name = \"boutiques\";\n readonly target = \"boutiques\";\n\n emitApp(ctx: CodegenContext): EmittedApp {\n const { descriptor, warnings } = generateBoutiques(ctx);\n const json = JSON.stringify(descriptor, null, 2);\n return {\n meta: ctx.app,\n files: new Map([[\"descriptor.json\", json]]),\n errors: [],\n warnings,\n };\n }\n}\n","/** Line-buffer abstraction for code emission. */\nexport class CodeBuilder {\n private readonly lines: string[] = [];\n private depth = 0;\n private readonly indentStr: string;\n\n constructor(indent = \" \") {\n this.indentStr = indent;\n }\n\n /** Append a line at the current indentation level. */\n line(text: string): this {\n this.lines.push(this.indentStr.repeat(this.depth) + text);\n return this;\n }\n\n /** Append a blank line. */\n blank(): this {\n this.lines.push(\"\");\n return this;\n }\n\n /** Append a comment line. */\n comment(text: string, prefix = \"// \"): this {\n return this.line(`${prefix}${text}`);\n }\n\n /** Run a callback with increased indentation. */\n indent(fn: () => void): this {\n this.depth++;\n fn();\n this.depth--;\n return this;\n }\n\n /** Append all lines from another CodeBuilder at the current indentation level. */\n append(other: CodeBuilder): this {\n const prefix = this.indentStr.repeat(this.depth);\n for (const line of other.lines) {\n this.lines.push(line === \"\" ? \"\" : prefix + line);\n }\n return this;\n }\n\n /** Return the built code as a string. */\n toString(): string {\n return this.lines.join(\"\\n\");\n }\n}\n","import type { BoundType } from \"../bindings/index.js\";\n\n/**\n * Stable, fully structural identity key for any BoundType.\n *\n * Two types share a key iff they are structurally identical - same shape AND\n * same leaf types/literal values, recursively. This is what `collectNamedTypes`\n * dedups on: distinct nominal types must get distinct keys so each gets its own\n * generated name.\n *\n * Keying on field/variant *names* alone is too coarse: discriminated-union\n * variants that differ only by their `@type` literal (e.g. ANTs' `transform_*`\n * variants, all `{ \"@type\": <literal>, gradient_step: float }`) would collapse\n * to one identity, emitting `Transform = TransformRigid | TransformRigid | ...`\n * and breaking discriminated-union narrowing. Including the field types (and\n * thus the `@type` literal value) keeps them distinct.\n */\nexport function typeKey(type: BoundType): string {\n switch (type.kind) {\n case \"scalar\":\n return `scalar:${type.scalar}`;\n case \"bool\":\n return \"bool\";\n case \"count\":\n return \"count\";\n case \"literal\":\n // JSON.stringify disambiguates the value's type too (e.g. \"2\" vs 2).\n return `literal:${JSON.stringify(type.value)}`;\n case \"optional\":\n return `optional(${typeKey(type.inner)})`;\n case \"list\":\n return `list(${typeKey(type.item)})`;\n case \"struct\":\n return structKey(type);\n case \"union\":\n return unionKey(type);\n }\n}\n\n/** Stable identity key for a struct type (field names + field types). */\nexport function structKey(type: Extract<BoundType, { kind: \"struct\" }>): string {\n const fields = Object.entries(type.fields)\n .map(([name, fieldType]) => `${name}=${typeKey(fieldType)}`)\n .join(\",\");\n return `struct{${fields}}`;\n}\n\n/** Stable identity key for a union type (variant names + variant types). */\nexport function unionKey(type: Extract<BoundType, { kind: \"union\" }>): string {\n const variants = type.variants.map((v) => `${v.name ?? \"?\"}=${typeKey(v.type)}`).join(\"|\");\n return `union[${variants}]`;\n}\n","import type { BoundType } from \"../bindings/index.js\";\nimport { Scope } from \"./scope.js\";\nimport { structKey, unionKey } from \"./type-keys.js\";\n\n/** A named compound type (struct or union) discovered during type collection. */\nexport interface NamedType {\n name: string;\n type: BoundType;\n}\n\n/**\n * Recursively collect all struct/union types and assign unique names.\n *\n * Walks the BoundType tree depth-first, using structural keys (`structKey`,\n * `unionKey`) to deduplicate types that appear multiple times in the tree.\n * Each unique struct/union gets a name generated by applying `nameTransform`\n * to a hint string (derived from the root name or field/variant names).\n *\n * @param rootType - The root BoundType to walk.\n * @param rootName - The hint for the root type's name (already tool-qualified).\n * @param scope - Symbol scope for collision avoidance.\n * @param nameTransform - Converts a hint string to a type name (e.g. pascalCase, snake_case).\n * @param nestedPrefix - Prepended to every NON-root type name so a suite's flat\n * barrel (`export * from`/`from .x import *`) can't collide two tools' types\n * that share a local field/variant name (e.g. `Outputtype`). Pass the tool's\n * type prefix (its root name); defaults to \"\" for single-tool emission.\n * @returns `namedTypes` maps structural keys to assigned names, `typeDecls` lists declarations in order.\n */\nexport function collectNamedTypes(\n rootType: BoundType,\n rootName: string,\n scope: Scope,\n nameTransform: (hint: string) => string,\n nestedPrefix = \"\",\n): { namedTypes: Map<string, string>; typeDecls: NamedType[] } {\n const namedTypes = new Map<string, string>();\n const typeDecls: NamedType[] = [];\n\n function nameFor(hint: string, isRoot: boolean): string {\n const cased = isRoot ? nameTransform(hint) : nestedPrefix + nameTransform(hint);\n // Dedup in the cased (emitted) namespace, folding any disambiguation suffix\n // back through nameTransform so a collision yields e.g. `Config2`, not the\n // mixed-case `Config_2`. Uniqueness is still checked on the final form, so\n // two hints that case-collide get distinct names.\n return scope.add(cased, nameTransform);\n }\n\n function visit(type: BoundType, hint: string, isRoot: boolean): void {\n switch (type.kind) {\n case \"struct\": {\n const key = structKey(type);\n if (!namedTypes.has(key)) {\n const name = nameFor(hint, isRoot);\n namedTypes.set(key, name);\n typeDecls.push({ name, type });\n for (const [fieldName, fieldType] of Object.entries(type.fields)) {\n visit(fieldType, fieldName, false);\n }\n }\n break;\n }\n case \"union\": {\n const key = unionKey(type);\n if (!namedTypes.has(key)) {\n const name = nameFor(hint, isRoot);\n namedTypes.set(key, name);\n typeDecls.push({ name, type });\n for (const v of type.variants) {\n visit(v.type, v.name ?? hint, false);\n }\n }\n break;\n }\n // Wrappers are transparent: an optional/list at the root still names its\n // inner type as the root (no prefix), matching the pre-prefix behavior.\n case \"optional\":\n visit(type.inner, hint, isRoot);\n break;\n case \"list\":\n visit(type.item, hint, isRoot);\n break;\n default:\n break;\n }\n }\n\n visit(rootType, rootName, true);\n return { namedTypes, typeDecls };\n}\n\n/**\n * Create a type name resolver from a namedTypes map.\n * Returns a function that maps a BoundType to its assigned name (if any).\n */\nexport function resolveTypeName(\n namedTypes: Map<string, string>,\n): (type: BoundType) => string | undefined {\n return (type) => {\n if (type.kind === \"struct\") return namedTypes.get(structKey(type));\n if (type.kind === \"union\") return namedTypes.get(unionKey(type));\n return undefined;\n };\n}\n","/**\n * Runtime version floors baked into generated dependency metadata.\n *\n * styx2-generated code calls `mutable_copy` / `mutableCopy` (introduced in the\n * styxdefs 0.7.0 / styxdefs-js 0.2.0 release), so emitted packages genuinely\n * require that runtime floor. This is the single source of truth: bump here and\n * both the Python and TypeScript backends pick it up.\n */\nexport const STYXDEFS_COMPAT = {\n /** PEP 508 specifier for the Python `styxdefs` package. */\n python: \">=0.7.0,<0.8.0\",\n /** npm semver range for the `styxdefs` package. */\n npm: \"^0.2.0\",\n} as const;\n\n/**\n * Extra Python runtime packages the root distribution pulls in (container +\n * graph runners). Left unpinned - styxdefs's floor constrains them transitively\n * via their own inter-package pins.\n */\nexport const PYTHON_RUNNER_DEPS = [\"styxdocker\", \"styxsingularity\", \"styxgraph\"] as const;\n","import type { Documentation } from \"../../ir/index.js\";\nimport type { PackageMeta, ProjectMeta } from \"../../manifest/index.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport { PYTHON_RUNNER_DEPS, STYXDEFS_COMPAT } from \"../styxdefs-compat.js\";\n\nconst REQUIRES_PYTHON = \">=3.10\";\nconst BUILD_SYSTEM = `[build-system]\nrequires = [\"setuptools>=61\"]\nbuild-backend = \"setuptools.build_meta\"`;\n\n/** Escape a value for embedding in a TOML basic string. */\nfunction tomlStr(s: string): string {\n return (\n s\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\"/g, '\\\\\"')\n .replace(/[\\r\\n]+/g, \" \")\n // TOML basic strings forbid literal control chars (tab U+0009 is allowed);\n // strip the rest so scraped docs can't produce invalid TOML.\n // eslint-disable-next-line no-control-regex\n .replace(/[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f]/g, \"\")\n .trim()\n );\n}\n\n/** Suite directory / importable package name; matches the CLI's `pkgDir` fallback. */\nfunction pkgDir(pkg: PackageMeta): string {\n return pkg.name ?? \"package\";\n}\n\n/** Distribution (PyPI) name for a package: `<project>_<package>`, or just `<package>`. */\nexport function pyDistName(proj: ProjectMeta, pkg: PackageMeta): string {\n const name = pkgDir(pkg);\n return proj.name ? `${proj.name}_${name}` : name;\n}\n\n// pyproject's `[project] description` becomes the core-metadata `Summary` field,\n// which PyPI caps at 512 chars. The catalog's `doc.description` is often a full\n// paragraph (and is emitted in full into the README / long description anyway),\n// so the summary is clamped to fit.\nconst SUMMARY_MAX_LEN = 512;\n\n/**\n * Clamp a description to a <=512-char one-line summary. Prefer cutting at the\n * last complete sentence that fits (clean, no dangling fragment); if there is no\n * sentence boundary early enough, cut at a word boundary and mark the elision.\n */\nfunction clampSummary(s: string): string {\n if (s.length <= SUMMARY_MAX_LEN) return s;\n const window = s.slice(0, SUMMARY_MAX_LEN);\n const lastSentence = window.lastIndexOf(\". \");\n if (lastSentence >= 0) return s.slice(0, lastSentence + 1); // keep the period\n const ellipsis = \"...\";\n const body = window.slice(0, SUMMARY_MAX_LEN - ellipsis.length);\n const lastSpace = body.lastIndexOf(\" \");\n return (lastSpace > 0 ? body.slice(0, lastSpace) : body).replace(/[.,;:\\s]+$/, \"\") + ellipsis;\n}\n\nfunction description(doc: Documentation | undefined, fallbackName: string | undefined): string {\n const summary =\n doc?.description ?? `Styx generated wrappers for ${doc?.title ?? fallbackName ?? \"tools\"}.`;\n return clampSummary(summary);\n}\n\nfunction authorsField(doc: Documentation | undefined): string {\n const authors = doc?.authors?.length ? doc.authors : [\"unknown\"];\n return `[${authors.map((a) => `{ name = \"${tomlStr(a)}\" }`).join(\", \")}]`;\n}\n\nfunction licenseField(proj: ProjectMeta): string {\n return `{ text = \"${tomlStr(proj.license?.description ?? \"unknown\")}\" }`;\n}\n\n/**\n * Per-suite `pyproject.toml`. The flat layout (`python/<pkg>/bet.py`) makes the\n * directory itself the importable package, so setuptools' `package-dir` maps the\n * import name (`<pkg>`) onto the distribution's root directory. The styxdefs\n * floor is the only runtime dependency.\n *\n * Precondition: `pkg.name` must be a valid Python identifier - the flat layout's\n * relative imports (`from .bet import *`) already require this, and the CLI uses\n * it verbatim as the directory name, so this stays consistent with that.\n */\nexport function generateSubPyproject(proj: ProjectMeta, pkg: PackageMeta): string {\n const importName = pkgDir(pkg);\n const cb = new CodeBuilder(\" \");\n cb.line(\"[project]\");\n cb.line(`name = \"${tomlStr(pyDistName(proj, pkg))}\"`);\n // The wrapper distribution is released as part of the project, so it carries\n // the project (catalog) version - NOT the wrapped tool's version. This keeps\n // every niwrap_<pkg> in lockstep with the niwrap meta package, matching the\n // single-package TypeScript distribution and the v1 release scheme.\n cb.line(`version = \"${tomlStr(proj.version ?? \"0.0.0\")}\"`);\n cb.line(`description = \"${tomlStr(description(pkg.doc, pkg.name))}\"`);\n cb.line(`readme = \"README.md\"`);\n cb.line(`license = ${licenseField(proj)}`);\n cb.line(`authors = ${authorsField(pkg.doc ?? proj.doc)}`);\n cb.line(`requires-python = \"${REQUIRES_PYTHON}\"`);\n cb.line(\"dependencies = [\");\n cb.line(` \"styxdefs${STYXDEFS_COMPAT.python}\",`);\n cb.line(\"]\");\n cb.blank();\n cb.line(\"[tool.setuptools]\");\n cb.line(`packages = [\"${importName}\"]`);\n cb.line(`package-dir = { \"${importName}\" = \".\" }`);\n cb.blank();\n cb.line(\"[tool.setuptools.package-data]\");\n cb.line(`\"${importName}\" = [\"py.typed\"]`);\n cb.blank();\n cb.line(BUILD_SYSTEM);\n return cb.toString() + \"\\n\";\n}\n\n/**\n * Root `pyproject.toml`: a metapackage depending on each per-suite distribution\n * plus the container/graph runner packages. `packages = []` keeps setuptools\n * from sweeping the sibling suite directories into this distribution.\n */\nexport function generateRootPyproject(proj: ProjectMeta, distNames: string[]): string {\n const cb = new CodeBuilder(\" \");\n cb.line(\"[project]\");\n cb.line(`name = \"${tomlStr(proj.name ?? \"project\")}\"`);\n cb.line(`version = \"${tomlStr(proj.version ?? \"0.0.0\")}\"`);\n cb.line(`description = \"${tomlStr(description(proj.doc, proj.name))}\"`);\n cb.line(`readme = \"README.md\"`);\n cb.line(`license = ${licenseField(proj)}`);\n cb.line(`authors = ${authorsField(proj.doc)}`);\n cb.line(`requires-python = \"${REQUIRES_PYTHON}\"`);\n cb.line(\"dependencies = [\");\n for (const dep of PYTHON_RUNNER_DEPS) cb.line(` \"${dep}\",`);\n for (const dist of distNames) cb.line(` \"${tomlStr(dist)}\",`);\n cb.line(\"]\");\n cb.blank();\n cb.line(\"[tool.setuptools]\");\n cb.line(\"packages = []\");\n cb.blank();\n cb.line(BUILD_SYSTEM);\n return cb.toString() + \"\\n\";\n}\n\n/** Per-suite README crediting the upstream tool authors. */\nexport function generateSubReadme(proj: ProjectMeta, pkg: PackageMeta): string {\n const projectTitle = proj.doc?.title ?? proj.name ?? \"Styx\";\n const packageTitle = pkg.doc?.title ?? pkg.name ?? \"package\";\n const url = pkg.doc?.urls?.[0];\n const titleMd = url ? `[${packageTitle}](${url})` : packageTitle;\n const credits = pkg.doc?.authors?.length\n ? pkg.doc.authors.join(\", \")\n : (pkg.doc?.urls?.join(\", \") ?? \"unknown\");\n const desc = pkg.doc?.description ? `\\n\\n${pkg.doc.description}` : \"\";\n return (\n `# ${projectTitle} wrappers for ${titleMd}${desc}\\n\\n` +\n `${packageTitle} is made by ${credits}.\\n\\n` +\n `This package contains wrappers only and has no affiliation with the original authors.\\n`\n );\n}\n\n/** Root README listing the bundled per-suite distributions. */\nexport function generateRootReadme(proj: ProjectMeta, distNames: string[]): string {\n const title = proj.doc?.title ?? proj.name ?? \"Styx\";\n const desc = proj.doc?.description ? `\\n${proj.doc.description}\\n` : \"\";\n const list = distNames.map((d) => `- ${d}`).join(\"\\n\");\n return (\n `# ${title}\\n${desc}\\n` +\n `Auto-generated Styx wrappers. This project bundles the following packages:\\n\\n` +\n `${list}\\n`\n );\n}\n\n/** Local-install manifest: each suite directory first, then the root metapackage. */\nexport function generateRequirementsTxt(pkgDirs: string[]): string {\n return [...pkgDirs.map((d) => `./${d}`), \"./\"].join(\"\\n\") + \"\\n\";\n}\n","import type { BoundType } from \"../bindings/index.js\";\nimport type { FieldInfo } from \"./collect-field-info.js\";\n\n/**\n * One entry of a kwarg-style signature, shared across language backends. Each\n * entry describes a single user-facing parameter of the `_params()` factory\n * and the kwarg wrapper:\n * - `sigType`/`sigDefault` go directly into the function signature\n * - `isOptional`/`hasExplicitDefault` drive the dict-build branches (required\n * and explicitly-defaulted fields are always set; optional-no-default fields\n * are conditionally set when not None/null)\n * - `doc` is rendered into the per-param doc block (Args / @param)\n *\n * `name` is the scrubbed host identifier (used in the signature and function\n * body); `wireKey` is the Boutiques field name (used as the dict key /\n * TypedDict field key). They diverge when the wire key collides with a host\n * reserved word, is not a valid identifier, or shadows a local in the emitting\n * function (e.g. wire `float` -> host `float_`, wire `4d_input` -> host\n * `v_4d_input`).\n */\nexport interface SigEntry {\n /** Scrubbed host identifier - safe to use in signatures and as a local. */\n name: string;\n /** Boutiques field name - used as the dict key / TypedDict field key. */\n wireKey: string;\n sigType: string;\n /** Rendered default expression in the host language, or undefined for required-no-default. */\n sigDefault?: string;\n /** True iff the BoundType is `optional` (i.e. dict-build conditionally includes). */\n isOptional: boolean;\n /** True iff the field carries an explicit defaultValue in its FieldInfo. */\n hasExplicitDefault: boolean;\n doc?: string;\n}\n\n/** Per-backend rendering hooks for `buildSigEntries`. */\nexport interface SigOptions {\n /** Render a non-optional BoundType as a language-native type expression. */\n renderType: (t: BoundType) => string;\n /** Suffix appended to `renderType(inner)` for optional fields (e.g. ` | None`, ` | null`). */\n nullableSuffix: string;\n /** Default expression for optional-no-default fields (e.g. `None`, `null`). */\n nullableDefault: string;\n /** Render a JS scalar default as a host-language literal (e.g. `True`/`true`). */\n renderDefault: (v: string | number | boolean) => string;\n}\n\n/**\n * Build per-field signature entries for the kwarg wrapper and params factory.\n * Skips `@type` (the factory injects it as a constant). Required-no-default\n * entries are placed before defaulted ones so the resulting signature is\n * syntactically valid in both Python and TS.\n *\n * `registerLocal` is called once per field with the wire key; it must return\n * a scrubbed, unique host identifier (typically by combining a language-aware\n * scrub function with `Scope.add()`). The caller's scope should already have\n * the function's other locals (`params`, `runner`, ...) reserved so this\n * registration cannot collide with them.\n */\nexport function buildSigEntries(\n rootType: Extract<BoundType, { kind: \"struct\" }>,\n fieldInfo: Map<string, FieldInfo>,\n registerLocal: (wireKey: string) => string,\n opts: SigOptions,\n): SigEntry[] {\n const entries: SigEntry[] = [];\n for (const [fieldName, fieldType] of Object.entries(rootType.fields)) {\n if (fieldType.kind === \"literal\") continue;\n\n const fi = fieldInfo.get(fieldName);\n const isOptional = fieldType.kind === \"optional\";\n const inner = isOptional ? fieldType.inner : fieldType;\n let sigType = opts.renderType(inner);\n if (isOptional) sigType += opts.nullableSuffix;\n\n let sigDefault: string | undefined;\n const hasExplicitDefault = fi?.defaultValue !== undefined;\n if (hasExplicitDefault) {\n sigDefault = opts.renderDefault(fi!.defaultValue!);\n } else if (isOptional) {\n sigDefault = opts.nullableDefault;\n }\n\n entries.push({\n name: registerLocal(fieldName),\n wireKey: fieldName,\n sigType,\n sigDefault,\n isOptional,\n hasExplicitDefault,\n doc: fi?.doc,\n });\n }\n const required = entries.filter((e) => e.sigDefault === undefined);\n const defaulted = entries.filter((e) => e.sigDefault !== undefined);\n return [...required, ...defaulted];\n}\n","import type { BoundType, BoundVariant } from \"../bindings/index.js\";\n\n/** A union's struct variant paired with its index into the union's `variants`\n * array (which stays parallel to the IR `alts` and the per-arm results a caller\n * builds, so the index must be threaded through). */\nexport interface IndexedStructVariant {\n variant: BoundVariant;\n i: number;\n}\n\n/**\n * The struct variants of a union, each with its index into `variants`.\n *\n * A discriminated union dispatches on a unique `@type`, so two struct variants\n * sharing a tag are a malformed union: the second is unreachable at runtime and\n * emits a dead branch (a mypy `comparison-overlap` in the Python backend's\n * `if`/`elif` chain). Producing well-formed, unique-tagged unions is a frontend\n * responsibility - the Boutiques frontend dodges duplicate sub-command ids\n * (`orient` -> `orient_2`). This asserts that invariant at the backend boundary\n * and throws if it is violated, rather than silently emitting a dead branch.\n */\nexport function structVariants(\n unionType: Extract<BoundType, { kind: \"union\" }>,\n): IndexedStructVariant[] {\n const seen = new Set<string>();\n const out: IndexedStructVariant[] = [];\n unionType.variants.forEach((variant, i) => {\n if (variant.type.kind !== \"struct\") return;\n const tag = variant.name ?? \"\";\n if (seen.has(tag)) {\n throw new Error(\n `duplicate union variant @type ${JSON.stringify(tag)}: a discriminated ` +\n `union dispatches on a unique @type, so a second variant with the same ` +\n `tag is unreachable. Frontends must dodge duplicate variant tags before ` +\n `codegen (the Boutiques frontend renames duplicate sub-command ids).`,\n );\n }\n seen.add(tag);\n out.push({ variant, i });\n });\n return out;\n}\n","import type { AccessPath, BindingId, BoundType } from \"../../bindings/index.js\";\n\n/**\n * Map a BoundType to its Python type expression.\n *\n * `resolve` is the named-type resolver from `collectNamedTypes` - returns the\n * declared name for struct/union types so they can be referenced symbolically\n * rather than inlined.\n *\n * Python target: 3.10+ (uses `X | None`, `list[T]`, `int`/`str`/etc.).\n */\nexport function mapType(type: BoundType, resolve: (type: BoundType) => string | undefined): string {\n switch (type.kind) {\n case \"scalar\":\n return { int: \"int\", float: \"float\", str: \"str\", path: \"InputPathType\" }[type.scalar];\n case \"bool\":\n return \"bool\";\n case \"count\":\n return \"int\";\n case \"literal\":\n return typeof type.value === \"string\"\n ? `typing.Literal[${pyStr(type.value)}]`\n : `typing.Literal[${type.value}]`;\n case \"optional\":\n // The solver has no nullable type: `optional` means \"omittable\" (the key\n // may be absent), never \"the value may be None\". Omittability is expressed\n // structurally at the field level (`typing.NotRequired[...]`); the value\n // type itself is just the inner type. So in any value position (nested\n // list/union arm, validator messages) we render the inner type with no\n // `| None`.\n return mapType(type.inner, resolve);\n case \"list\":\n return `list[${mapType(type.item, resolve)}]`;\n case \"struct\": {\n const name = resolve(type);\n if (name) return name;\n // Fallback: inline as Mapping[str, object]. Real struct types should always\n // resolve to a declared TypedDict.\n return \"typing.Mapping[str, object]\";\n }\n case \"union\": {\n const name = resolve(type);\n if (name) return name;\n return type.variants.map((v) => mapType(v.type, resolve)).join(\" | \");\n }\n }\n}\n\n/** Render a JS default value as a Python literal (signatures, `.get(k, default)`). */\nexport function renderPyLiteral(value: string | number | boolean): string {\n if (typeof value === \"boolean\") return value ? \"True\" : \"False\";\n if (typeof value === \"number\") return Number.isFinite(value) ? String(value) : \"float('nan')\";\n return pyStr(value);\n}\n\n/** Python double-quoted string literal with minimal escaping. */\nexport function pyStr(value: string): string {\n // For any value containing control characters, JSON encoding produces a valid\n // Python double-quoted literal (with the same `\\n`/`\\t`/`\\uXXXX` escapes).\n // Otherwise we hand-escape backslashes and double quotes only.\n for (let i = 0; i < value.length; i++) {\n if (value.charCodeAt(i) < 0x20) return JSON.stringify(value);\n }\n return `\"${value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`;\n}\n\n/** Options controlling how `renderAccess` renders an access path. */\nexport interface RenderAccessOptions {\n /**\n * Render the LAST segment - if it is a `field` - as `base.get(key)` instead of\n * `base[key]`. Used when binding the value of an optional field to a narrowed\n * local: the params factory omits optional-without-default keys entirely (they\n * are `typing.NotRequired`), so a bare subscript would raise `KeyError`. `.get()`\n * yields `None` for an absent key, matching the present-and-None case. (Unlike\n * JS, where `obj[missing]` is `undefined`, Python subscript on a missing key\n * raises - so the structurally-mirrored TS walk needs this read in Python.)\n */\n finalFieldGet?: boolean;\n /**\n * Render the LAST segment - if it is a `field` - as `base.get(key, <default>)`,\n * supplying a fallback value for an absent key. Used for fields that carry a\n * Boutiques default and are read unconditionally (e.g. an output-basename like\n * `maskfile=\"img_bet\"`): the field is `NotRequired`, so a bare subscript would\n * raise `KeyError`, and a bare `.get()` would yield `None` (wrong - the default\n * must be substituted). The string is an already-rendered Python literal.\n * Takes precedence over `finalFieldGet`.\n */\n finalFieldDefault?: string;\n /**\n * Prefix substitutions: maps a rendered access prefix (e.g. `params[\"cfg\"]`) to\n * a local variable name. After each segment is appended, if the rendered prefix\n * so far matches a key, it is replaced by the local. This lets reads of an\n * optional field (and anything nested under it) resolve to the `.get()`-narrowed\n * local bound by the enclosing presence guard - one lookup, absent-safe, and\n * mypy can narrow it (a re-subscript or a fresh `.get()` cannot be narrowed).\n */\n subst?: ReadonlyMap<string, string>;\n}\n\n/**\n * Render a solver-assigned `AccessPath` to a Python expression. Starts from\n * `params`; each `field` segment subscripts a key, and each `iter` segment\n * resets the base to the loop variable bound to that repeat binding (resolved\n * via `lookupLoopVar`). Mirrors the TypeScript `renderAccess`.\n */\nexport function renderAccess(\n path: AccessPath,\n lookupLoopVar: (binding: BindingId) => string,\n options: RenderAccessOptions = {},\n): string {\n const { finalFieldGet = false, finalFieldDefault, subst } = options;\n let cur = \"params\";\n path.forEach((seg, i) => {\n if (seg.kind !== \"field\") {\n cur = lookupLoopVar(seg.binding);\n } else {\n const isLast = i === path.length - 1;\n if (isLast && finalFieldDefault !== undefined) {\n cur = `${cur}.get(${pyStr(seg.name)}, ${finalFieldDefault})`;\n } else if (isLast && finalFieldGet) {\n cur = `${cur}.get(${pyStr(seg.name)})`;\n } else {\n cur = `${cur}[${pyStr(seg.name)}]`;\n }\n }\n // Swap in a narrowed local if this prefix was bound by an enclosing guard.\n const sub = subst?.get(cur);\n if (sub !== undefined) cur = sub;\n });\n return cur;\n}\n","import type { Binding, BindingId, BoundType, BoundVariant } from \"../../bindings/index.js\";\nimport { collectFieldInfo } from \"../collect-field-info.js\";\nimport type { Expr } from \"../../ir/index.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport { structVariants } from \"../union-variants.js\";\nimport { pyStr, renderAccess, renderPyLiteral } from \"./typemap.js\";\n\n// -- Result types --\n\ninterface Expr_ {\n expr: string;\n}\ninterface Stmt {\n stmt: string;\n}\nexport type ArgResult = Expr_ | Stmt;\n\nfunction isExpr(r: ArgResult): r is Expr_ {\n return \"expr\" in r;\n}\n\nexport function resultToStmt(r: ArgResult): string {\n return isExpr(r) ? `cargs.append(${r.expr})` : r.stmt;\n}\n\nfunction appendLines(cb: CodeBuilder, code: string): void {\n for (const line of code.split(\"\\n\")) cb.line(line);\n}\n\n// -- Type helpers --\n\nfunction toStringExpr(node: Expr, type: BoundType, expr: string): string {\n if (type.kind === \"scalar\") {\n if (type.scalar === \"str\") return expr;\n if (type.scalar === \"path\") return pathArg(node, expr);\n }\n return `str(${expr})`;\n}\n\n/**\n * Command-line value for a path input via `execution.input_file`, threading the\n * path node's `resolve_parent` / `mutable` attrs as keyword args. `mutable=True`\n * tells the runner to stage a writable COPY (original untouched) and return the\n * copy's command-line path; the outputs builder surfaces that same copy's host\n * path via `execution.mutable_copy`.\n */\nfunction pathArg(node: Expr, expr: string): string {\n if (node.kind !== \"path\") return `execution.input_file(${expr})`;\n let extra = \"\";\n if (node.attrs.resolveParent) extra += \", resolve_parent=True\";\n if (node.attrs.mutable) extra += \", mutable=True\";\n return `execution.input_file(${expr}${extra})`;\n}\n\n// -- Context passed down through recursion --\n\ninterface ArgContext {\n /** Join nesting depth (controls ternary vs if-statement for optionals). */\n joinDepth: number;\n /**\n * Loop variables bound by enclosing `repeat`-of-list nodes, keyed by the\n * repeat binding's id. `renderAccess` consults this to resolve the `iter`\n * segments in a binding's solver-assigned access path.\n */\n loopVars: ReadonlyMap<BindingId, string>;\n /**\n * Prefix substitutions for optional fields narrowed by an enclosing presence\n * guard: maps a rendered access prefix to the `.get()`-narrowed local that\n * holds it. Threaded into `renderAccess` so inner reads use the local (one\n * lookup, absent-safe, mypy-narrowable) instead of re-subscripting.\n */\n valueSubst: ReadonlyMap<string, string>;\n /**\n * Rendered Python default literals for root-level NON-OPTIONAL fields that\n * carry a Boutiques default (e.g. `maskfile -> \"img_bet\"`), keyed by field\n * name. Such a field is `NotRequired` (a hand-authored config may omit it) yet\n * is read unconditionally - so every read of its value becomes\n * `.get(key, <default>)` to substitute the default instead of raising\n * `KeyError`. Optional fields are excluded: they are presence-guarded (their\n * default, if any, is supplied by the factory's kwarg signature), so reading\n * them with a default here would both be wrong and collide with `valueSubst`.\n */\n defaults: ReadonlyMap<string, string>;\n}\n\n/**\n * The rendered default for a binding iff it is a root-level NON-OPTIONAL field\n * carrying a Boutiques default. Restricted to single-segment (root) field access\n * so a nested field can never accidentally pick up a same-named root default.\n */\nfunction rootFieldDefault(\n binding: Binding,\n defaults: ReadonlyMap<string, string>,\n): string | undefined {\n const a = binding.access;\n if (a.length === 1 && a[0]?.kind === \"field\") return defaults.get(binding.name);\n return undefined;\n}\n\n/**\n * Render a binding's access for an UNCONDITIONAL value read (terminal, repeat\n * loop, alternative dispatch): substitutes the field's default via\n * `.get(key, default)` when it is a defaulted non-optional field, else the plain\n * access. Returns plain access for every non-defaulted field, so the emitted\n * code is byte-identical to before for the common case. Not used by\n * `walkOptional` (its bare access is the `valueSubst` key and its guard reads\n * via `.get()`).\n */\nfunction readAccess(binding: Binding, arg: ArgContext): string {\n const def = rootFieldDefault(binding, arg.defaults);\n return accessOf(binding, arg, def !== undefined ? { finalDefault: def } : {});\n}\n\ninterface AccessOpts {\n /** Render the final field segment as `.get(key)` (absent key -> None). */\n finalGet?: boolean;\n /** Render the final field segment as `.get(key, default)` (absent key -> default). */\n finalDefault?: string;\n}\n\n/**\n * Render a binding's solver-assigned access path in the current loop scope.\n * `finalGet` renders the final field segment as `.get(key)` (used when binding\n * an optional's value to a narrowed local); `finalDefault` renders it as\n * `.get(key, default)` (used for absent-safe reads of a defaulted field).\n */\nfunction accessOf(binding: Binding, arg: ArgContext, opts: AccessOpts = {}): string {\n return renderAccess(\n binding.access,\n (b) => {\n const v = arg.loopVars.get(b);\n if (v === undefined) throw new Error(`arg-builder: unbound loop variable for binding ${b}`);\n return v;\n },\n { finalFieldGet: opts.finalGet, finalFieldDefault: opts.finalDefault, subst: arg.valueSubst },\n );\n}\n\n/**\n * Build the field-name -> rendered-default map for a struct root (else empty).\n * Includes only non-optional defaulted fields (optional fields are\n * presence-guarded; their default comes from the factory's kwarg signature).\n */\nfunction collectDefaults(ctx: CodegenContext, rootType?: BoundType): Map<string, string> {\n const out = new Map<string, string>();\n if (rootType?.kind !== \"struct\") return out;\n for (const [name, fi] of collectFieldInfo(ctx, rootType)) {\n if (fi.defaultValue === undefined) continue;\n if (rootType.fields[name]?.kind === \"optional\") continue;\n out.set(name, renderPyLiteral(fi.defaultValue));\n }\n return out;\n}\n\n// -- Recursive descent --\n\nlet loopVarCounter = 0;\nlet optVarCounter = 0;\n\n/**\n * Build arg-building code for an IR tree via recursive descent.\n *\n * Mirrors the TypeScript backend's `walk` structurally so the emitted Python\n * has the same shape (and the same correctness story) as the TS output.\n */\nexport function buildArgs(rootExpr: Expr, ctx: CodegenContext, rootType?: BoundType): ArgResult {\n loopVarCounter = 0;\n optVarCounter = 0;\n const initialCtx: ArgContext = {\n joinDepth: 0,\n loopVars: new Map(),\n valueSubst: new Map(),\n defaults: collectDefaults(ctx, rootType),\n };\n return walk(rootExpr, ctx, initialCtx);\n}\n\nfunction walk(node: Expr, ctx: CodegenContext, arg: ArgContext): ArgResult {\n switch (node.kind) {\n case \"literal\":\n return { expr: pyStr(node.attrs.str) };\n\n case \"int\":\n case \"float\":\n case \"str\":\n case \"path\":\n return walkTerminal(node, ctx, arg);\n\n case \"sequence\":\n return walkSequence(node, ctx, arg);\n\n case \"optional\":\n return walkOptional(node, ctx, arg);\n\n case \"repeat\":\n return walkRepeat(node, ctx, arg);\n\n case \"alternative\":\n return walkAlternative(node, ctx, arg);\n }\n}\n\nfunction walkTerminal(node: Expr, ctx: CodegenContext, arg: ArgContext): ArgResult {\n const binding = ctx.resolve(node);\n if (!binding) throw new Error(`Missing binding for terminal node: ${node.kind}`);\n // A root-level defaulted field (e.g. an output basename `maskfile=\"img_bet\"`)\n // is read here unconditionally but is `NotRequired`, so `readAccess`\n // substitutes the default for an absent key via `.get(key, default)`.\n return { expr: toStringExpr(node, binding.type, readAccess(binding, arg)) };\n}\n\nfunction walkSequence(\n node: Extract<Expr, { kind: \"sequence\" }>,\n ctx: CodegenContext,\n arg: ArgContext,\n): ArgResult {\n // A non-join sequence inside an outer join must concatenate (rather than\n // push separate args) so it can stand in as a single Expr element of the\n // outer join. Boutiques produces this shape for `command-line-flag` inputs\n // nested under a parent join template (e.g. `[OUTPUT][FLAG]` -> seqJoin('')\n // around an opt(seq(lit(FLAG), value))).\n const join = node.attrs.join ?? (arg.joinDepth > 0 ? \"\" : undefined);\n\n // Struct scoping is already baked into each child's access path by the\n // solver; here we only thread join depth (a codegen concern).\n const childArg: ArgContext = join !== undefined ? { ...arg, joinDepth: arg.joinDepth + 1 } : arg;\n\n const parts = node.attrs.nodes.map((child) => walk(child, ctx, childArg));\n\n if (join !== undefined) {\n const exprs = parts.map((p) => (isExpr(p) ? p.expr : p.stmt));\n if (exprs.length === 1) return { expr: exprs[0]! };\n return { expr: `${pyStr(join)}.join([${exprs.join(\", \")}])` };\n }\n\n return { stmt: parts.map(resultToStmt).join(\"\\n\") };\n}\n\nfunction walkOptional(\n node: Extract<Expr, { kind: \"optional\" }>,\n ctx: CodegenContext,\n arg: ArgContext,\n): ArgResult {\n const binding = ctx.resolve(node);\n if (!binding) throw new Error(\"Missing binding for optional node\");\n const isOpt = binding.type.kind === \"optional\";\n const access = accessOf(binding, arg);\n\n // For a nullable optional, bind the value to a narrowed local read via `.get()`\n // (the key is `NotRequired` - the factory omits it when None, so a bare\n // subscript would KeyError). Inner reads of this access (and anything nested\n // under it) are redirected to the local via `valueSubst`: one lookup, absent-\n // safe, and mypy can narrow the local (it cannot narrow a re-subscript or a\n // fresh `.get()`). Bool-flag optionals are also `NotRequired` (default false),\n // so the truthy guard reads via `.get()` too (absent key -> None -> flag off).\n let childArg = arg;\n let local: string | undefined;\n let getAccess: string | undefined;\n if (isOpt) {\n local = `v_${optVarCounter++}`;\n getAccess = accessOf(binding, arg, { finalGet: true });\n childArg = { ...arg, valueSubst: new Map(arg.valueSubst).set(access, local) };\n }\n // Absent-safe truthy guard for the bool-flag case.\n const boolGuard = accessOf(binding, arg, { finalGet: true });\n\n // The inner node's access path is solver-assigned (it either inherits this\n // optional's path on a collapse, or scopes into it for a struct); we thread the\n // loop scope, join depth, and the optional's value substitution.\n const inner = walk(node.attrs.node, ctx, childArg);\n\n // Inside a join context, emit as ternary expression.\n if (arg.joinDepth > 0 && isExpr(inner)) {\n if (isOpt) {\n // Walrus binds the narrowed local inside the lazy ternary; the inner expr\n // (which references `local`) only evaluates when the key is present.\n return { expr: `(${inner.expr} if (${local} := ${getAccess}) is not None else \"\")` };\n }\n return { expr: `(${inner.expr} if ${boolGuard} else \"\")` };\n }\n\n const cb = new CodeBuilder(\" \");\n const innerStmt = resultToStmt(inner);\n if (isOpt) {\n cb.line(`${local} = ${getAccess}`);\n cb.line(`if ${local} is not None:`);\n cb.indent(() => appendLines(cb, innerStmt));\n } else {\n cb.line(`if ${boolGuard}:`);\n cb.indent(() => appendLines(cb, innerStmt));\n }\n return { stmt: cb.toString() };\n}\n\nfunction walkRepeat(\n node: Extract<Expr, { kind: \"repeat\" }>,\n ctx: CodegenContext,\n arg: ArgContext,\n): ArgResult {\n const binding = ctx.resolve(node);\n if (!binding) throw new Error(\"Missing binding for repeat node\");\n // A non-join repeat inside an outer join concatenates rather than pushing\n // separate args, mirroring walkSequence's handling of bare non-join seqs.\n const join = node.attrs.join ?? (arg.joinDepth > 0 ? \"\" : undefined);\n // Unconditional read (the count/list value) - `readAccess` substitutes a\n // defaulted non-optional field's default for an absent key.\n const access = readAccess(binding, arg);\n\n // Count repeat: emit a counted for-loop. Inside a join the for-loop would\n // be dropped into a list literal as raw text, so emit a comprehension.\n if (binding.type.kind === \"count\") {\n const inner = walk(node.attrs.node, ctx, arg);\n const v = `_i${loopVarCounter++}`;\n if (join !== undefined && isExpr(inner)) {\n return { expr: `${pyStr(join)}.join([${inner.expr} for ${v} in range(${access})])` };\n }\n const cb = new CodeBuilder(\" \");\n cb.line(`for ${v} in range(${access}):`);\n cb.indent(() => appendLines(cb, resultToStmt(inner)));\n return { stmt: cb.toString() };\n }\n\n // List repeat: emit a for-in loop or generator-join. The loop variable is\n // registered under this repeat's binding id so inner bindings' `iter`\n // segments resolve to it via `renderAccess`.\n const loopVar = `item${loopVarCounter++}`;\n const childArg: ArgContext = {\n ...arg,\n loopVars: new Map(arg.loopVars).set(binding.id, loopVar),\n };\n\n const inner = walk(node.attrs.node, ctx, childArg);\n\n if (join !== undefined && isExpr(inner)) {\n return {\n expr: `${pyStr(join)}.join([${inner.expr} for ${loopVar} in ${access}])`,\n };\n }\n\n const cb = new CodeBuilder(\" \");\n cb.line(`for ${loopVar} in ${access}:`);\n cb.indent(() => appendLines(cb, resultToStmt(inner)));\n return { stmt: cb.toString() };\n}\n\nfunction walkAlternative(\n node: Extract<Expr, { kind: \"alternative\" }>,\n ctx: CodegenContext,\n arg: ArgContext,\n): ArgResult {\n const binding = ctx.resolve(node);\n if (!binding) throw new Error(\"Missing binding for alternative node\");\n // Unconditional read (the enum value / bool guard / union discriminator) -\n // `readAccess` substitutes a defaulted non-optional field's default for an\n // absent key (e.g. a `value-choices` String with a default).\n const access = readAccess(binding, arg);\n\n // Complex-union variant fields already carry the union's path in their\n // solver-assigned access, so arms walk with the current context unchanged.\n const variants = node.attrs.alts.map((alt) => walk(alt, ctx, arg));\n\n if (\n binding.type.kind === \"union\" &&\n binding.type.variants.every((v: BoundVariant) => v.type.kind === \"literal\")\n ) {\n return { expr: `str(${access})` };\n }\n\n if (binding.type.kind === \"bool\") {\n // Inside a join, the alternative's output must be an expression, not a\n // statement: an `if/else` block dropped into a `\"\".join([...])` list\n // literal is not valid Python. Emit a ternary when both arms are exprs.\n if (arg.joinDepth > 0) {\n if (!variants[1]) {\n throw new Error(\n \"single-arm bool alternative inside a join: cannot produce an expression \" +\n \"without ambiguous semantics (omitting the entry vs emitting empty string)\",\n );\n }\n if (!variants.every(isExpr)) {\n throw new Error(\n \"bool alternative inside a join has statement-shaped variants; \" +\n \"expected all arms to fold to expressions\",\n );\n }\n const v0 = (variants[0] as Expr_).expr;\n const v1 = (variants[1] as Expr_).expr;\n return { expr: `(${v0} if ${access} else ${v1})` };\n }\n const cb = new CodeBuilder(\" \");\n cb.line(`if ${access}:`);\n cb.indent(() => appendLines(cb, resultToStmt(variants[0]!)));\n if (variants[1]) {\n cb.line(`else:`);\n cb.indent(() => appendLines(cb, resultToStmt(variants[1]!)));\n }\n return { stmt: cb.toString() };\n }\n\n if (binding.type.kind === \"union\") {\n const unionType = binding.type;\n // A union may be pure-discriminated (every variant a struct with `@type`) or\n // mixed (struct variants plus bare-literal variants, e.g. ants\n // `Interpolation = \"Linear\" | MultiLabel | ...`). Pure-enum unions returned\n // above. Dispatch struct variants on `@type`; a bare literal is its own value.\n // Struct variants with their indices; throws if two share an `@type` (a\n // duplicate-tagged variant is unreachable and a mypy `comparison-overlap` -\n // frontends must dodge duplicate tags before codegen).\n const structVars = structVariants(unionType);\n const hasLiteral = unionType.variants.some((v) => v.type.kind === \"literal\");\n\n // Inside a join: chained ternary, same reason as bool above.\n if (arg.joinDepth > 0) {\n if (!variants.every(isExpr)) {\n throw new Error(\n \"union alternative inside a join has statement-shaped variants; \" +\n \"expected all arms to fold to expressions\",\n );\n }\n let structExpr = pyStr(\"\");\n for (let k = structVars.length - 1; k >= 0; k--) {\n const { variant, i } = structVars[k]!;\n const v = (variants[i] as Expr_).expr;\n structExpr = `(${v} if ${access}[\"@type\"] == ${pyStr(variant.name ?? \"\")} else ${structExpr})`;\n }\n if (!hasLiteral) return { expr: structExpr };\n // Mixed: a dict value dispatches by `@type`; a bare literal is itself.\n return { expr: `(${structExpr} if isinstance(${access}, dict) else str(${access}))` };\n }\n\n const cb = new CodeBuilder(\" \");\n const emitStructDispatch = (): void => {\n structVars.forEach(({ variant, i }, k) => {\n const keyword = k === 0 ? \"if\" : \"elif\";\n cb.line(`${keyword} ${access}[\"@type\"] == ${pyStr(variant.name ?? \"\")}:`);\n cb.indent(() => appendLines(cb, resultToStmt(variants[i]!)));\n });\n };\n if (!hasLiteral) {\n emitStructDispatch();\n return { stmt: cb.toString() };\n }\n // Mixed union: branch on runtime shape (dict -> `@type` dispatch; else a\n // bare literal used directly), mirroring the validator.\n cb.line(`if isinstance(${access}, dict):`);\n cb.indent(emitStructDispatch);\n cb.line(`else:`);\n cb.indent(() => appendLines(cb, resultToStmt({ expr: `str(${access})` })));\n return { stmt: cb.toString() };\n }\n\n return { stmt: variants.map(resultToStmt).join(\"\\n\") };\n}\n","import type { BoundType } from \"../../bindings/index.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport type { SigEntry, SigOptions } from \"../sig-entries.js\";\nimport { snakeCase } from \"../string-case.js\";\nimport { structKey, unionKey } from \"../type-keys.js\";\nimport type { ArgResult } from \"./arg-builder.js\";\nimport { buildArgs, resultToStmt } from \"./arg-builder.js\";\nimport { mapType, pyStr, renderPyLiteral } from \"./typemap.js\";\nimport type { NamedType } from \"./types.js\";\nimport { collectFieldInfo, resolveTypeName } from \"./types.js\";\n\n/**\n * Emit a Python triple-quoted docstring. Single-line if short, multi-line for\n * longer text. Should be placed as the first statement inside a function/class\n * body or as a field doc immediately after the annotation.\n */\nexport function emitDocstring(cb: CodeBuilder, text?: string): void {\n if (!text) return;\n const lines = text.split(\"\\n\");\n if (lines.length === 1 && !lines[0]!.includes('\"')) {\n cb.line(`\"\"\"${lines[0]}\"\"\"`);\n return;\n }\n cb.line(`\"\"\"`);\n for (const line of lines) cb.line(line);\n cb.line(`\"\"\"`);\n}\n\nexport function emitImports(cb: CodeBuilder, emitOutputs: boolean): void {\n cb.line(\"import dataclasses\");\n cb.line(\"import pathlib\");\n cb.line(\"import typing\");\n cb.blank();\n const fromStyxdefs = [\"Execution\", \"InputPathType\", \"Metadata\", \"Runner\", \"StyxValidationError\"];\n if (emitOutputs) fromStyxdefs.push(\"OutputPathType\");\n cb.line(`from styxdefs import ${fromStyxdefs.join(\", \")}, get_global_runner`);\n}\n\nexport function emitMetadata(ctx: CodegenContext, metaConst: string, cb: CodeBuilder): void {\n const id = ctx.app?.id ?? \"unknown\";\n const name = ctx.app?.doc?.title ?? ctx.app?.id ?? \"unknown\";\n const pkg = ctx.package?.name ?? \"unknown\";\n\n cb.line(`${metaConst} = Metadata(`);\n cb.indent(() => {\n cb.line(`id=${pyStr(id)},`);\n cb.line(`name=${pyStr(name)},`);\n cb.line(`package=${pyStr(pkg)},`);\n if (ctx.app?.doc?.literature?.length) {\n cb.line(`citations=[${ctx.app.doc.literature.map(pyStr).join(\", \")}],`);\n }\n if (ctx.app?.container?.image) {\n cb.line(`container_image_tag=${pyStr(ctx.app.container.image)},`);\n }\n });\n cb.line(\")\");\n}\n\n/**\n * Python keywords that would cause a SyntaxError or silent miscompile if used\n * as a class-body annotation key (e.g. `lambda: float` parses as a lambda\n * expression statement, not a TypedDict field). The class-syntax check uses\n * this to force functional syntax for those fields. Builtins like `int`/`str`\n * are NOT in this set - those are valid class attribute names.\n */\nexport const PY_KEYWORDS = new Set([\n \"False\",\n \"None\",\n \"True\",\n \"and\",\n \"as\",\n \"assert\",\n \"async\",\n \"await\",\n \"break\",\n \"class\",\n \"continue\",\n \"def\",\n \"del\",\n \"elif\",\n \"else\",\n \"except\",\n \"finally\",\n \"for\",\n \"from\",\n \"global\",\n \"if\",\n \"import\",\n \"in\",\n \"is\",\n \"lambda\",\n \"nonlocal\",\n \"not\",\n \"or\",\n \"pass\",\n \"raise\",\n \"return\",\n \"try\",\n \"while\",\n \"with\",\n \"yield\",\n]);\n\n/** Can `s` be used as a class-attribute name in a TypedDict class body? */\nfunction isPyIdent(s: string): boolean {\n return /^[A-Za-z_][A-Za-z0-9_]*$/.test(s) && !PY_KEYWORDS.has(s);\n}\n\n/**\n * Emit the python source for one struct as a TypedDict. Uses functional syntax\n * if any field name is not a Python identifier (e.g. `@type` discriminators);\n * otherwise uses class syntax for readability.\n *\n * When `injectAtTypeTag` is given, an `@type: typing.Literal[<tag>]` entry is\n * prepended; used by the root struct of single-tool params, whose tag is\n * derived from `pkg/appId` rather than from the IR.\n */\nfunction emitStructTypedDict(\n name: string,\n type: Extract<BoundType, { kind: \"struct\" }>,\n ctx: CodegenContext,\n resolve: (t: BoundType) => string | undefined,\n cb: CodeBuilder,\n injectAtTypeTag?: string,\n): void {\n const fieldInfo = collectFieldInfo(ctx, type);\n const entries = Object.entries(type.fields);\n // @type literal fields are special: they're not user-provided regular fields\n // but discriminator values. Other literals are skipped (they have no runtime\n // representation in the dict).\n const hasInjectedAtType = injectAtTypeTag !== undefined;\n const hasNonIdentKey =\n hasInjectedAtType ||\n entries.some(([k, v]) => {\n if (v.kind === \"literal\") return k === \"@type\";\n return !isPyIdent(k);\n });\n\n // Compute the typed entry list (skipping non-discriminator literals).\n const typedEntries: Array<{ key: string; type: string; doc?: string }> = [];\n if (injectAtTypeTag !== undefined) {\n // NotRequired: the factory always sets @type and runtime dispatch tables\n // read it, but callers building a dict by hand shouldn't have to type it.\n // (Union variants further down keep their @type required - that one IS\n // load-bearing for discriminated-union narrowing.)\n typedEntries.push({\n key: \"@type\",\n type: `typing.NotRequired[typing.Literal[${pyStr(injectAtTypeTag)}]]`,\n });\n }\n for (const [fieldName, fieldType] of entries) {\n if (fieldType.kind === \"literal\") {\n if (fieldName === \"@type\") {\n const lit =\n typeof fieldType.value === \"string\"\n ? `typing.Literal[${pyStr(fieldType.value)}]`\n : `typing.Literal[${fieldType.value}]`;\n typedEntries.push({ key: fieldName, type: lit });\n }\n continue;\n }\n const fi = fieldInfo.get(fieldName);\n const hasDefault = fi?.defaultValue !== undefined;\n const isOptional = fieldType.kind === \"optional\";\n // The value type is the inner type, never `| None`: the solver has no\n // nullable, so a present value is never None. Omittability (the key may be\n // absent) is expressed structurally via `typing.NotRequired[...]`.\n const inner = isOptional ? fieldType.inner : fieldType;\n let typeExpr = mapType(inner, resolve);\n // A field is omittable iff it is `optional` or it carries a default (which\n // includes flags - `defaultValue` false). Mark omittable fields NotRequired:\n // optional-without-default fields are conditionally set by the factory, and\n // defaulted fields may legitimately be absent in a hand-authored config (the\n // absence-safe runtime reads apply the default). Required-without-default\n // fields stay bare - the factory always writes them.\n if (isOptional || hasDefault) {\n typeExpr = `typing.NotRequired[${typeExpr}]`;\n }\n typedEntries.push({ key: fieldName, type: typeExpr, doc: fi?.doc });\n }\n\n if (hasNonIdentKey) {\n cb.line(`${name} = typing.TypedDict(`);\n cb.indent(() => {\n cb.line(`${pyStr(name)},`);\n cb.line(`{`);\n cb.indent(() => {\n for (const { key, type } of typedEntries) {\n cb.line(`${pyStr(key)}: ${type},`);\n }\n });\n cb.line(`},`);\n });\n cb.line(`)`);\n } else {\n cb.line(`class ${name}(typing.TypedDict):`);\n cb.indent(() => {\n if (typedEntries.length === 0) {\n cb.line(\"pass\");\n return;\n }\n for (const { key, type, doc } of typedEntries) {\n cb.line(`${key}: ${type}`);\n if (doc) emitDocstring(cb, doc);\n }\n });\n }\n}\n\n/** Structural identity key for a NamedType (only structs/unions are collected). */\nfunction declKey(type: BoundType): string | undefined {\n if (type.kind === \"struct\") return structKey(type);\n if (type.kind === \"union\") return unionKey(type);\n return undefined;\n}\n\n/**\n * Collect the keys of every named struct/union directly referenced by `type`'s\n * emitted expression. Wrappers (optional/list) are transparent; a nested\n * struct/union is its own declaration, so we record its key and stop. This is\n * the dependency edge set used to order declarations.\n */\nfunction collectRefs(type: BoundType, namedTypes: Map<string, string>, out: Set<string>): void {\n switch (type.kind) {\n case \"optional\":\n collectRefs(type.inner, namedTypes, out);\n break;\n case \"list\":\n collectRefs(type.item, namedTypes, out);\n break;\n case \"struct\": {\n const k = structKey(type);\n if (namedTypes.has(k)) out.add(k);\n break;\n }\n case \"union\": {\n const k = unionKey(type);\n if (namedTypes.has(k)) out.add(k);\n break;\n }\n default:\n break;\n }\n}\n\n/** Direct named-type dependencies of one declaration (its field/variant types). */\nfunction declDeps(type: BoundType, namedTypes: Map<string, string>): Set<string> {\n const out = new Set<string>();\n if (type.kind === \"struct\") {\n for (const fieldType of Object.values(type.fields)) collectRefs(fieldType, namedTypes, out);\n } else if (type.kind === \"union\") {\n for (const v of type.variants) collectRefs(v.type, namedTypes, out);\n }\n return out;\n}\n\nexport function emitTypeDeclarations(\n typeDecls: NamedType[],\n namedTypes: Map<string, string>,\n ctx: CodegenContext,\n cb: CodeBuilder,\n rootName?: string,\n rootTypeTag?: string,\n): void {\n const resolve = resolveTypeName(namedTypes);\n\n // Python evaluates type expressions eagerly (no hoisting like TS): a name\n // must be defined before any declaration references it. The collector yields\n // types in forward-discovery order (parents before children); the old\n // emission just reversed that, but reverse-discovery breaks for shared types\n // in a DAG - e.g. a union arm discovered deep under the FIRST variant that is\n // also referenced by a LATER sibling arm ends up emitted after its user.\n // Instead, do a real topological sort over the dependency graph (post-order\n // DFS so a type is emitted only after every type it references). Back-edges\n // from a cycle are ignored - the recursion guard breaks them, and recursive\n // descriptor types don't occur in practice.\n const byKey = new Map<string, NamedType>();\n for (const decl of typeDecls) {\n const k = declKey(decl.type);\n if (k !== undefined) byKey.set(k, decl);\n }\n\n const ordered: NamedType[] = [];\n const visited = new Set<string>();\n const onStack = new Set<string>();\n function emitInOrder(key: string): void {\n if (visited.has(key)) return;\n const decl = byKey.get(key);\n if (decl === undefined) return;\n onStack.add(key);\n for (const dep of declDeps(decl.type, namedTypes)) {\n if (!onStack.has(dep)) emitInOrder(dep);\n }\n onStack.delete(key);\n visited.add(key);\n ordered.push(decl);\n }\n // Drive from the original discovery order so independent declarations keep a\n // stable, deterministic relative order.\n for (const decl of typeDecls) {\n const k = declKey(decl.type);\n if (k !== undefined) emitInOrder(k);\n }\n\n for (const { name, type } of ordered) {\n if (type.kind === \"struct\") {\n const inject = name === rootName ? rootTypeTag : undefined;\n emitStructTypedDict(name, type, ctx, resolve, cb, inject);\n cb.blank();\n } else if (type.kind === \"union\") {\n const parts = type.variants.map((v) => mapType(v.type, resolve));\n cb.line(`${name} = ${parts.join(\" | \")}`);\n cb.blank();\n }\n }\n}\n\nexport function emitBuildCargs(\n ctx: CodegenContext,\n rootType: BoundType,\n paramsType: string,\n funcName: string,\n cb: CodeBuilder,\n): void {\n let result: ArgResult;\n try {\n result = buildArgs(ctx.expr, ctx, rootType);\n } catch {\n cb.line(`def ${funcName}(params: ${paramsType}, execution: Execution) -> list[str]:`);\n cb.indent(() => {\n emitDocstring(cb, \"Build command-line arguments from parameters.\");\n cb.line(\"return []\");\n });\n return;\n }\n\n const argsCode = resultToStmt(result);\n\n cb.line(`def ${funcName}(params: ${paramsType}, execution: Execution) -> list[str]:`);\n cb.indent(() => {\n emitDocstring(cb, \"Build command-line arguments from parameters.\");\n cb.line(\"cargs: list[str] = []\");\n for (const line of argsCode.split(\"\\n\")) {\n if (line.trim()) cb.line(line);\n }\n cb.line(\"return cargs\");\n });\n}\n\nexport function emitWrapperFunction(\n ctx: CodegenContext,\n paramsType: string,\n funcName: string,\n metaConst: string,\n cargsFunc: string,\n outputsFunc: string | undefined,\n outputsType: string | undefined,\n validateFunc: string | undefined,\n streams: { stdout?: string; stderr?: string },\n cb: CodeBuilder,\n): void {\n const emitOutputs = outputsFunc !== undefined;\n const appDoc = ctx.app?.doc;\n const returnType = emitOutputs && outputsType ? outputsType : \"None\";\n\n cb.line(`def ${funcName}(params: ${paramsType}, runner: Runner | None = None) -> ${returnType}:`);\n cb.indent(() => {\n cb.line('\"\"\"');\n let hasContent = false;\n if (appDoc?.title) {\n cb.line(appDoc.title);\n hasContent = true;\n }\n if (appDoc?.description) {\n if (hasContent) cb.blank();\n cb.line(appDoc.description);\n hasContent = true;\n }\n if (appDoc?.authors?.length) {\n if (hasContent) cb.blank();\n cb.line(`Author: ${appDoc.authors.join(\", \")}`);\n hasContent = true;\n }\n if (appDoc?.urls?.length) {\n if (hasContent) cb.blank();\n cb.line(`URL: ${appDoc.urls[0]}`);\n hasContent = true;\n }\n if (hasContent) cb.blank();\n cb.line(\"Args:\");\n cb.line(\" params: The parameters.\");\n cb.line(\" runner: Command runner (defaults to global runner).\");\n cb.blank();\n cb.line(\"Returns:\");\n cb.line(emitOutputs ? \" Tool outputs (paths to files produced by the tool).\" : \" None.\");\n cb.line('\"\"\"');\n // Validate the params dict first (the kwarg wrapper delegates here, so it\n // gets validation transitively; the statically-typed kwargs don't need it).\n if (validateFunc) cb.line(`${validateFunc}(params)`);\n cb.line(\"runner = runner if runner is not None else get_global_runner()\");\n cb.line(`execution = runner.start_execution(${metaConst})`);\n cb.line(\"execution.params(params)\");\n // Local names `args`/`out` avoid colliding with the module-level `cargs`\n // and `outputs` functions when they share generic names.\n cb.line(`args = ${cargsFunc}(params, execution)`);\n if (emitOutputs) {\n cb.line(`out = ${outputsFunc}(params, execution)`);\n const handlers: string[] = [];\n if (streams.stdout) handlers.push(`handle_stdout=lambda s: out.${streams.stdout}.append(s)`);\n if (streams.stderr) handlers.push(`handle_stderr=lambda s: out.${streams.stderr}.append(s)`);\n cb.line(`execution.run(args${handlers.length ? \", \" + handlers.join(\", \") : \"\"})`);\n cb.line(\"return out\");\n } else {\n cb.line(\"execution.run(args)\");\n }\n });\n}\n\n/** Convenience: derive a snake_case function name from the app id. */\nexport function appFuncName(ctx: CodegenContext, fallback: string): string {\n return snakeCase(ctx.app?.id ?? fallback);\n}\n\n/**\n * SigOptions hooks for Python. The kwarg-signature sentinel for an optional\n * param is `T | None = None` - here `| None` is the *parameter* type (the\n * \"not provided\" sentinel a caller passes), not the dict field type, which is\n * just `typing.NotRequired[T]`. Keeping the sentinel preserves the ergonomic\n * `foo(x)` call where omitted optionals default to `None` and the factory then\n * drops them.\n */\nexport function pySigOptions(resolve: (t: BoundType) => string | undefined): SigOptions {\n return {\n renderType: (t) => mapType(t, resolve),\n nullableSuffix: \" | None\",\n nullableDefault: \"None\",\n renderDefault: renderPyLiteral,\n };\n}\n\n/**\n * Scrub a Boutiques wire name into a valid Python host identifier. Replaces\n * any non-`[A-Za-z0-9_]` character with `_`; prefixes `v_` if the result\n * starts with a digit; appends a single trailing underscore when the scrubbed\n * name matches a reserved word or shadowed built-in (matching v1 niwrap's\n * `float_:` style). The caller is responsible for further deduping the result\n * through a `Scope` so collisions with already-registered locals don't slip\n * through.\n */\nexport function pyScrubIdent(name: string, reserved: ReadonlySet<string>): string {\n let scrubbed = name.replace(/[^A-Za-z0-9_]/g, \"_\");\n if (/^[0-9]/.test(scrubbed)) scrubbed = \"v_\" + scrubbed;\n if (scrubbed === \"\") scrubbed = \"_\";\n if (reserved.has(scrubbed)) scrubbed = scrubbed + \"_\";\n return scrubbed;\n}\n\n/** Emit a sequence of `name: type [= default],` lines (one per entry) into `cb`. */\nfunction emitSigParams(entries: readonly SigEntry[], cb: CodeBuilder): void {\n for (const e of entries) {\n if (e.sigDefault !== undefined) {\n cb.line(`${e.name}: ${e.sigType} = ${e.sigDefault},`);\n } else {\n cb.line(`${e.name}: ${e.sigType},`);\n }\n }\n}\n\n/**\n * Word-wrap a Google-style \"Args:\" entry. Produces lines like\n * `name: description that continues...\\`\n * ` until it ends here.`\n * The first line is prefixed with `<indent><name>: `; continuations use\n * `<indent> ` (4 spaces deeper). Lines that exceed `lineWidth` end with a\n * `\\` continuation marker.\n */\nfunction wrapDocEntry(name: string, doc: string, indent: string, lineWidth = 80): string[] {\n const firstPrefix = `${indent}${name}: `;\n const contPrefix = `${indent} `;\n const words = doc.split(/\\s+/).filter((w) => w.length > 0);\n if (words.length === 0) return [`${firstPrefix.trimEnd()}`];\n\n const lines: string[] = [];\n let current = firstPrefix + words[0]!;\n for (let i = 1; i < words.length; i++) {\n const word = words[i]!;\n if (current.length + 1 + word.length + 1 > lineWidth) {\n lines.push(current + \"\\\\\");\n current = contPrefix + word;\n } else {\n current += \" \" + word;\n }\n }\n lines.push(current);\n return lines;\n}\n\n/** Emit the per-field `Args:` block for a docstring. Caller is already at the\n * correct indent (i.e. inside the function body). */\nfunction emitArgsBlock(entries: readonly { name: string; doc?: string }[], cb: CodeBuilder): void {\n cb.line(\"Args:\");\n for (const e of entries) {\n for (const ln of wrapDocEntry(e.name, e.doc ?? \"\", \" \")) cb.line(ln);\n }\n}\n\n/**\n * Emit the `_params(...)` factory: a kwarg-style function that builds and\n * returns the params dict (with `@type` injected). Non-optional fields (required,\n * and defaulted scalars whose default lives on the signature) are always set in\n * the literal. Every optional field is set conditionally when not None -\n * including optional-with-default ones: their value type is `T | None` (the omit\n * sentinel) but the dict field is the non-None `NotRequired[T]`, so a bare\n * literal assignment of a possibly-None value would not type-check. When the\n * caller omits the arg, the signature default (a concrete non-None value) flows\n * through the guard and is written.\n */\nexport function emitParamsFactory(\n entries: readonly SigEntry[],\n funcName: string,\n paramsType: string,\n typeTag: string | undefined,\n cb: CodeBuilder,\n): void {\n // Signature\n if (entries.length === 0) {\n cb.line(`def ${funcName}() -> ${paramsType}:`);\n } else {\n cb.line(`def ${funcName}(`);\n cb.indent(() => emitSigParams(entries, cb));\n cb.line(`) -> ${paramsType}:`);\n }\n\n cb.indent(() => {\n // Docstring\n cb.line('\"\"\"');\n cb.line(\"Build parameters.\");\n if (entries.length > 0) {\n cb.blank();\n emitArgsBlock(entries, cb);\n }\n cb.blank();\n cb.line(\"Returns:\");\n cb.line(\" Parameter dictionary.\");\n cb.line('\"\"\"');\n\n // Build dict: required and explicitly-defaulted fields go into the literal\n cb.line(`params: ${paramsType} = {`);\n cb.indent(() => {\n if (typeTag !== undefined) cb.line(`\"@type\": ${pyStr(typeTag)},`);\n for (const e of entries) {\n if (!e.isOptional) {\n cb.line(`${pyStr(e.wireKey)}: ${e.name},`);\n }\n }\n });\n cb.line(\"}\");\n\n // Conditional include for every optional field (its kwarg default supplies a\n // non-None value when the caller omits the arg).\n for (const e of entries) {\n if (e.isOptional) {\n cb.line(`if ${e.name} is not None:`);\n cb.indent(() => cb.line(`params[${pyStr(e.wireKey)}] = ${e.name}`));\n }\n }\n cb.line(\"return params\");\n });\n}\n\n/**\n * Emit the user-facing kwarg wrapper: takes the same kwargs as `_params()`\n * plus `runner`, builds the params dict, and delegates to the dict-style\n * execute function.\n */\nexport function emitKwargWrapper(\n ctx: CodegenContext,\n entries: readonly SigEntry[],\n funcName: string,\n paramsFnName: string,\n executeFnName: string,\n outputsType: string | undefined,\n cb: CodeBuilder,\n): void {\n // Signature: same as params factory + `runner` last\n cb.line(`def ${funcName}(`);\n cb.indent(() => {\n emitSigParams(entries, cb);\n cb.line(\"runner: Runner | None = None,\");\n });\n const returnType = outputsType ?? \"None\";\n cb.line(`) -> ${returnType}:`);\n\n cb.indent(() => {\n // Docstring: app title/description + per-field docs + runner + Returns.\n const appDoc = ctx.app?.doc;\n cb.line('\"\"\"');\n if (appDoc?.title) cb.line(appDoc.title);\n if (appDoc?.description) {\n if (appDoc?.title) cb.blank();\n cb.line(appDoc.description);\n }\n if (appDoc?.authors?.length) {\n cb.blank();\n cb.line(`Author: ${appDoc.authors.join(\", \")}`);\n }\n if (appDoc?.urls?.length) {\n cb.blank();\n cb.line(`URL: ${appDoc.urls[0]}`);\n }\n cb.blank();\n emitArgsBlock(\n [...entries, { name: \"runner\", doc: \"Command runner (defaults to global runner).\" }],\n cb,\n );\n cb.blank();\n cb.line(\"Returns:\");\n cb.line(outputsType ? \" Tool outputs (paths to files produced by the tool).\" : \" None.\");\n cb.line('\"\"\"');\n\n // Body: delegate to factory + execute\n if (entries.length === 0) {\n cb.line(`params = ${paramsFnName}()`);\n } else {\n cb.line(`params = ${paramsFnName}(`);\n cb.indent(() => {\n for (const e of entries) cb.line(`${e.name}=${e.name},`);\n });\n cb.line(\")\");\n }\n if (outputsType) {\n cb.line(`return ${executeFnName}(params, runner)`);\n } else {\n cb.line(`${executeFnName}(params, runner)`);\n }\n });\n}\n","import type { BoundType } from \"../bindings/index.js\";\nimport type { Expr, Float, Int, Repeat } from \"../ir/index.js\";\nimport type { CodegenContext } from \"../manifest/index.js\";\nimport { collectFieldInfo } from \"./collect-field-info.js\";\nimport { findStructNode } from \"./find-struct-node.js\";\nimport { resolveFieldBinding } from \"./resolve-field-binding.js\";\n\n/**\n * Shared, language-agnostic tree-walk helpers for validation emit.\n *\n * Validation walks the solved root `BoundType` for the data shape, but the\n * runtime constraints it checks (int/float range, list length) live on the\n * underlying IR nodes, not the `BoundType`. These helpers bridge the two: they\n * map a struct's fields to their IR binding nodes and locate the IR node that\n * carries a given constraint within a field's subtree.\n */\n\n/** A struct field paired with its BoundType and (when resolvable) its IR node. */\nexport interface FieldEntry {\n name: string;\n type: BoundType;\n /** The IR node the field's binding was solved from. `undefined` if it could\n * not be resolved (constraint lookups then degrade gracefully). */\n node: Expr | undefined;\n /**\n * Whether the field has a default value. Such fields (and flags) accept\n * `None`/`null` to mean \"use the default\", so validation gates them like\n * optionals rather than requiring presence - matching v1 niwrap.\n */\n hasDefault: boolean;\n}\n\n/**\n * Enumerate a struct type's fields in declaration order, each paired with the\n * IR node its binding resolved from. `searchRoot` is the IR subtree known to\n * contain the struct (the root expr for the top-level struct, or a field /\n * union-arm node for nested ones).\n */\nexport function structFields(\n ctx: CodegenContext,\n structType: Extract<BoundType, { kind: \"struct\" }>,\n searchRoot: Expr | undefined,\n): FieldEntry[] {\n const nodeByName = new Map<string, Expr>();\n if (searchRoot) {\n const structNode = findStructNode(searchRoot, ctx, structType);\n if (structNode) {\n for (const child of structNode.attrs.nodes) {\n const match = resolveFieldBinding(child, ctx, structType);\n if (match) nodeByName.set(match.binding.name, match.binding.node);\n }\n }\n }\n const fieldInfo = collectFieldInfo(ctx, structType);\n return Object.entries(structType.fields).map(([name, type]) => ({\n name,\n type,\n node: nodeByName.get(name),\n hasDefault: fieldInfo.get(name)?.defaultValue !== undefined,\n }));\n}\n\n/**\n * Depth-first search for the first node satisfying `pred`, descending through\n * the transparent structural wrappers the solver may bury a binding under\n * (sequence/optional/repeat/alternative).\n */\nexport function findNode(node: Expr | undefined, pred: (n: Expr) => boolean): Expr | undefined {\n if (!node) return undefined;\n if (pred(node)) return node;\n switch (node.kind) {\n case \"sequence\":\n for (const child of node.attrs.nodes) {\n const r = findNode(child, pred);\n if (r) return r;\n }\n return undefined;\n case \"optional\":\n return findNode(node.attrs.node, pred);\n case \"repeat\":\n return findNode(node.attrs.node, pred);\n case \"alternative\":\n for (const alt of node.attrs.alts) {\n const r = findNode(alt, pred);\n if (r) return r;\n }\n return undefined;\n default:\n return undefined;\n }\n}\n\n/** Locate the int/float node carrying a scalar field's numeric range. */\nexport function findRangeNode(node: Expr | undefined): Int | Float | undefined {\n const found = findNode(node, (n) => n.kind === \"int\" || n.kind === \"float\");\n return found as Int | Float | undefined;\n}\n\n/** Locate the repeat node carrying a list field's length bounds and item. */\nexport function findRepeatNode(node: Expr | undefined): Repeat | undefined {\n const found = findNode(node, (n) => n.kind === \"repeat\");\n return found as Repeat | undefined;\n}\n\n/** Locate the alternative node backing a union field, to map arms to variants. */\nexport function findAlternativeNode(\n node: Expr | undefined,\n): Extract<Expr, { kind: \"alternative\" }> | undefined {\n const found = findNode(node, (n) => n.kind === \"alternative\");\n return found as Extract<Expr, { kind: \"alternative\" }> | undefined;\n}\n","import type { BoundType } from \"../../bindings/index.js\";\nimport type { Expr } from \"../../ir/index.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport type { CodeBuilder } from \"../code-builder.js\";\nimport type { Scope } from \"../scope.js\";\nimport {\n findAlternativeNode,\n findRangeNode,\n findRepeatNode,\n structFields,\n} from \"../validate-walk.js\";\nimport { structVariants } from \"../union-variants.js\";\nimport { emitDocstring } from \"./emit.js\";\nimport { mapType, pyStr } from \"./typemap.js\";\n\n/**\n * Emit a `<tool>_validate(params)` function that walks the solved root\n * `BoundType` and raises `StyxValidationError` on invalid input. Mirrors the\n * runtime validation v1 niwrap emits, but as a single inlined function (the v2\n * backends inline `_cargs`/`_outputs` too, rather than v1's per-struct\n * dispatch).\n *\n * Constraints checked: presence (required fields), `isinstance`, int/float\n * range, list length, union `@type` membership + per-variant recursion, and\n * nested struct recursion.\n */\n\ntype Resolve = (t: BoundType) => string | undefined;\n\ninterface Emit {\n ctx: CodegenContext;\n resolve: Resolve;\n /** Per-function scope for generated locals (loop vars), reserving `params`. */\n scope: Scope;\n cb: CodeBuilder;\n}\n\nexport function emitValidate(\n ctx: CodegenContext,\n rootType: BoundType,\n rootNode: Expr,\n paramsType: string,\n funcName: string,\n resolve: Resolve,\n scope: Scope,\n cb: CodeBuilder,\n): void {\n const e: Emit = { ctx, resolve, scope: scope.child([\"params\"]), cb };\n // Untyped input: a boundary guard usable on a parsed dict / config blob, not\n // just an already-typed value (mirrors styx v1's `typing.Any` validator).\n cb.line(`def ${funcName}(params: typing.Any) -> None:`);\n cb.indent(() => {\n emitDocstring(\n cb,\n `Validate untrusted parameters. Raises StyxValidationError if \\`params\\` is not a valid ${paramsType}.`,\n );\n emitRoot(e, rootType, rootNode);\n });\n}\n\nfunction emitRoot(e: Emit, rootType: BoundType, rootNode: Expr): void {\n if (rootType.kind === \"struct\") {\n e.cb.line(\"if params is None or not isinstance(params, dict):\");\n e.cb.indent(() => raise(e, wrongObjectTypeMsg(\"params\")));\n for (const f of structFields(e.ctx, rootType, rootNode)) {\n emitField(e, f.name, f.type, f.node, f.hasDefault, \"params\");\n }\n } else if (rootType.kind === \"union\") {\n emitUnion(e, rootType, rootNode, \"params\", \"params\");\n } else {\n emitValue(e, rootType, rootNode, \"params\", \"params\", expectedType(e, rootType));\n }\n}\n\n/** Validate one struct field, handling required-presence vs optional gating. */\nfunction emitField(\n e: Emit,\n name: string,\n fieldType: BoundType,\n node: Expr | undefined,\n hasDefault: boolean,\n base: string,\n): void {\n // `@type` and other fixed literals have no user-supplied runtime value.\n if (fieldType.kind === \"literal\") return;\n\n const getExpr = `${base}.get(${pyStr(name)}, None)`;\n const idxExpr = `${base}[${pyStr(name)}]`;\n const expected = expectedType(e, fieldType);\n const valueType = fieldType.kind === \"optional\" ? fieldType.inner : fieldType;\n\n // Optionals and defaulted fields/flags accept None (None = \"use default\"), so\n // gate the body instead of requiring presence.\n if (fieldType.kind === \"optional\" || hasDefault) {\n e.cb.line(`if ${getExpr} is not None:`);\n e.cb.indent(() => emitValue(e, valueType, node, name, idxExpr, expected));\n } else {\n e.cb.line(`if ${getExpr} is None:`);\n e.cb.indent(() => raise(e, str(\"`\" + name + \"` must not be None\")));\n emitValue(e, valueType, node, name, idxExpr, expected);\n }\n}\n\n/** Validate a known-non-null value at `valueExpr` against `type`. */\nfunction emitValue(\n e: Emit,\n type: BoundType,\n node: Expr | undefined,\n wireKey: string,\n valueExpr: string,\n expected: string,\n): void {\n switch (type.kind) {\n case \"optional\":\n emitValue(e, type.inner, node, wireKey, valueExpr, expected);\n return;\n case \"literal\":\n return;\n case \"scalar\":\n switch (type.scalar) {\n case \"str\":\n checkType(e, valueExpr, \"str\", wireKey, expected);\n return;\n case \"int\":\n checkType(e, valueExpr, \"int\", wireKey, expected);\n emitRange(e, node, wireKey, valueExpr);\n return;\n case \"float\":\n checkType(e, valueExpr, \"(float, int)\", wireKey, expected);\n emitRange(e, node, wireKey, valueExpr);\n return;\n case \"path\":\n checkType(e, valueExpr, \"(pathlib.Path, str)\", wireKey, expected);\n return;\n }\n return;\n case \"bool\":\n checkType(e, valueExpr, \"bool\", wireKey, expected);\n return;\n case \"count\":\n checkType(e, valueExpr, \"int\", wireKey, expected);\n return;\n case \"list\": {\n checkType(e, valueExpr, \"list\", wireKey, expected);\n emitListLength(e, node, wireKey, valueExpr);\n const itemNode = findRepeatNode(node)?.attrs.node;\n const elem = e.scope.add(\"e\");\n e.cb.line(`for ${elem} in ${valueExpr}:`);\n e.cb.indent(() => emitValue(e, type.item, itemNode, wireKey, elem, expected));\n return;\n }\n case \"struct\": {\n e.cb.line(`if not isinstance(${valueExpr}, dict):`);\n e.cb.indent(() => raise(e, wrongObjectTypeMsg(valueExpr)));\n for (const f of structFields(e.ctx, type, node)) {\n emitField(e, f.name, f.type, f.node, f.hasDefault, valueExpr);\n }\n return;\n }\n case \"union\":\n emitUnion(e, type, node, wireKey, valueExpr);\n return;\n }\n}\n\nfunction emitUnion(\n e: Emit,\n unionType: Extract<BoundType, { kind: \"union\" }>,\n node: Expr | undefined,\n wireKey: string,\n valueExpr: string,\n): void {\n const litVariants = unionType.variants.filter((v) => v.type.kind === \"literal\");\n const hasStruct = unionType.variants.some((v) => v.type.kind === \"struct\");\n\n // Pure enum/choice: no struct variants, just literal values (no `@type`).\n if (!hasStruct) {\n const values = litVariants.map(\n (v) => (v.type as Extract<BoundType, { kind: \"literal\" }>).value,\n );\n const allStr = values.every((x) => typeof x === \"string\");\n checkType(e, valueExpr, allStr ? \"str\" : \"(float, int)\", wireKey, expectedType(e, unionType));\n emitLiteralMembership(e, values, wireKey, valueExpr);\n return;\n }\n\n const altNode = findAlternativeNode(node);\n // Struct variants with their indices; throws if two share an `@type` (a\n // duplicate-tagged variant is unreachable and a mypy `comparison-overlap` -\n // frontends must dodge duplicate tags before codegen). The index keeps each\n // arm aligned with the IR `alts`.\n const structVars = structVariants(unionType);\n const emitStructArm = (): void => {\n // `valueExpr` is known to be a dict here.\n e.cb.line(`if \"@type\" not in ${valueExpr}:`);\n e.cb.indent(() => raise(e, str(\"Params object is missing `@type`\")));\n const names = structVars\n .map(({ variant }) => variant.name)\n .filter((n): n is string => n !== undefined)\n .map((n) => pyStr(n))\n .join(\", \");\n e.cb.line(`if ${valueExpr}[\"@type\"] not in [${names}]:`);\n e.cb.indent(() =>\n raise(e, str(\"Parameter `\" + wireKey + \"`s `@type` must be one of [\" + names + \"]\")),\n );\n structVars.forEach(({ variant, i }, k) => {\n const vt = variant.type as Extract<BoundType, { kind: \"struct\" }>;\n const keyword = k === 0 ? \"if\" : \"elif\";\n e.cb.line(`${keyword} ${valueExpr}[\"@type\"] == ${pyStr(variant.name ?? \"\")}:`);\n e.cb.indent(() => {\n const fields = structFields(e.ctx, vt, altNode?.attrs.alts[i]).filter(\n (f) => f.type.kind !== \"literal\",\n );\n if (fields.length === 0) {\n e.cb.line(\"pass\");\n } else {\n for (const f of fields) emitField(e, f.name, f.type, f.node, f.hasDefault, valueExpr);\n }\n });\n });\n };\n\n // Pure discriminated union: every variant is a struct with an `@type`.\n if (litVariants.length === 0) {\n e.cb.line(`if not isinstance(${valueExpr}, dict):`);\n e.cb.indent(() => raise(e, wrongObjectTypeMsg(valueExpr)));\n emitStructArm();\n return;\n }\n\n // Mixed union: a value is either a struct (dict with `@type`) or a bare\n // literal. Branch on the runtime shape.\n e.cb.line(`if isinstance(${valueExpr}, dict):`);\n e.cb.indent(emitStructArm);\n e.cb.line(\"else:\");\n e.cb.indent(() => {\n const values = litVariants.map(\n (v) => (v.type as Extract<BoundType, { kind: \"literal\" }>).value,\n );\n emitLiteralMembership(e, values, wireKey, valueExpr);\n });\n}\n\n/** Emit a `not in [...]` membership check over literal values. */\nfunction emitLiteralMembership(\n e: Emit,\n values: (string | number)[],\n wireKey: string,\n valueExpr: string,\n): void {\n const rendered = values.map((x) => (typeof x === \"string\" ? pyStr(x) : pyNum(x))).join(\", \");\n e.cb.line(`if ${valueExpr} not in [${rendered}]:`);\n e.cb.indent(() => raise(e, str(\"Parameter `\" + wireKey + \"` must be one of [\" + rendered + \"]\")));\n}\n\nfunction checkType(\n e: Emit,\n valueExpr: string,\n pyType: string,\n wireKey: string,\n expected: string,\n): void {\n e.cb.line(`if not isinstance(${valueExpr}, ${pyType}):`);\n e.cb.indent(() => raise(e, wrongTypeMsg(wireKey, valueExpr, expected)));\n}\n\nfunction emitRange(e: Emit, node: Expr | undefined, wireKey: string, valueExpr: string): void {\n const term = findRangeNode(node);\n if (!term) return;\n const { minValue, maxValue } = term.attrs;\n if (minValue !== undefined && maxValue !== undefined) {\n e.cb.line(`if not (${pyNum(minValue)} <= ${valueExpr} <= ${pyNum(maxValue)}):`);\n e.cb.indent(() =>\n raise(\n e,\n str(`Parameter \\`${wireKey}\\` must be between ${minValue} and ${maxValue} (inclusive)`),\n ),\n );\n } else if (minValue !== undefined) {\n e.cb.line(`if ${valueExpr} < ${pyNum(minValue)}:`);\n e.cb.indent(() => raise(e, str(`Parameter \\`${wireKey}\\` must be at least ${minValue}`)));\n } else if (maxValue !== undefined) {\n e.cb.line(`if ${valueExpr} > ${pyNum(maxValue)}:`);\n e.cb.indent(() => raise(e, str(`Parameter \\`${wireKey}\\` must be at most ${maxValue}`)));\n }\n}\n\nfunction emitListLength(e: Emit, node: Expr | undefined, wireKey: string, valueExpr: string): void {\n const rep = findRepeatNode(node);\n if (!rep) return;\n const { countMin, countMax } = rep.attrs;\n if (countMin !== undefined && countMax !== undefined) {\n e.cb.line(`if not (${countMin} <= len(${valueExpr}) <= ${countMax}):`);\n e.cb.indent(() =>\n raise(\n e,\n str(\n `Parameter \\`${wireKey}\\` must contain between ${countMin} and ${countMax} elements (inclusive)`,\n ),\n ),\n );\n } else if (countMin !== undefined) {\n e.cb.line(`if len(${valueExpr}) < ${countMin}:`);\n e.cb.indent(() =>\n raise(\n e,\n str(\n `Parameter \\`${wireKey}\\` must contain at least ${countMin} ${plural(\"element\", countMin)}`,\n ),\n ),\n );\n } else if (countMax !== undefined) {\n e.cb.line(`if len(${valueExpr}) > ${countMax}:`);\n e.cb.indent(() =>\n raise(\n e,\n str(\n `Parameter \\`${wireKey}\\` must contain at most ${countMax} ${plural(\"element\", countMax)}`,\n ),\n ),\n );\n }\n}\n\n// -- Message + literal rendering --\n\nfunction raise(e: Emit, messageExpr: string): void {\n e.cb.line(`raise StyxValidationError(${messageExpr})`);\n}\n\n/** A plain double-quoted Python string message. */\nfunction str(text: string): string {\n return pyStr(text);\n}\n\n/** A single-quoted f-string \"wrong type\" message referencing the runtime type. */\nfunction wrongTypeMsg(wireKey: string, valueExpr: string, expected: string): string {\n return `f'\\`${wireKey}\\` has the wrong type: Received \\`{type(${valueExpr})}\\` expected \\`${expected}\\`'`;\n}\n\n/** The generic \"Params object has the wrong type\" f-string message. */\nfunction wrongObjectTypeMsg(valueExpr: string): string {\n return `f'Params object has the wrong type \\\\'{type(${valueExpr})}\\\\''`;\n}\n\nfunction expectedType(e: Emit, type: BoundType): string {\n return mapType(type, e.resolve);\n}\n\nfunction pyNum(n: number): string {\n return Number.isFinite(n) ? String(n) : \"float('nan')\";\n}\n\nfunction plural(word: string, count: number): string {\n return count === 1 ? word : `${word}s`;\n}\n","import type { BindingId, GateAtom, ResolvedOutput } from \"../bindings/index.js\";\nimport { outputGate } from \"../bindings/index.js\";\nimport type { Documentation, Expr } from \"../ir/index.js\";\nimport type { CodegenContext } from \"../manifest/index.js\";\n\n/**\n * Language-agnostic collection of a tool's Outputs object: the set of output\n * files it produces (resolved outputs + mutable inputs surfaced as outputs)\n * plus its captured stdout/stderr streams. Both the Python and TypeScript\n * backends, and the JSON Schema backend, consume this single source of truth so\n * the three describe the same Outputs shape (previously this logic was\n * near-duplicated between the two `outputs-emit.ts` files). Identifier\n * sanitization is the one language-specific concern, so callers pass an `idOf`\n * mapping a raw output name to their target language's field identifier; the\n * dedup space is keyed by that id, matching each backend's own field set.\n */\n\n/**\n * A `ResolvedOutput` plus a `mutable` marker. A mutable input file is surfaced\n * as an output: its single ref token points at the input binding, and the\n * backend emits a writable-copy call (`mutable_copy` / `mutableCopy`) - the\n * host path of the copy the runner staged for the matching mutable input -\n * instead of `output_file` / `outputFile`.\n */\nexport type EmittedOutput = ResolvedOutput & { mutable?: boolean };\n\n/**\n * The synthetic `root` output: the runner's output directory itself, surfaced as\n * an always-present, non-gated `OutputPathType` field. Modeled as a regular\n * `ResolvedOutput` with a single literal `\".\"` token so it flows through the\n * exact same collection and emit machinery as every declared output - its empty\n * gate makes it a required single, rendered as `output_file(\".\")` /\n * `outputFile(\".\")`. Because every tool emits it, every tool returns a\n * non-empty Outputs object (matching styx v1, which always carried `root`).\n */\nexport function rootOutput(ctx: CodegenContext, idOf: (name: string) => string): EmittedOutput {\n // Reserve a non-colliding field id. If a tool genuinely declares an output (or\n // a mutable input surfaced as an output) whose id sanitizes to \"root\", the\n // synthetic output-dir field dodges with a trailing \"_\" so it never silently\n // clobbers that real output (or flips it optional via shape merging).\n const taken = new Set<string>();\n for (const scope of ctx.outputScopes) for (const o of scope.outputs) taken.add(idOf(o.name));\n for (const o of collectMutableOutputs(ctx)) taken.add(idOf(o.name));\n let name = \"root\";\n while (taken.has(idOf(name))) name += \"_\";\n return { name, tokens: [{ kind: \"literal\", value: \".\" }] };\n}\n\n/**\n * Field shape for a single resolved output.\n *\n * - `single`: emitted at most once. Optional iff any `present`/`variant` atom\n * appears in the gate (the value may be absent under that gate).\n * - `list`: emitted once per element of an iterated binding (any `iter` atom in\n * the gate). A gated list still types as a list - the empty list stands for\n * \"nothing produced\".\n */\nexport type OutputShape = { kind: \"single\"; optional: boolean } | { kind: \"list\" };\n\nexport function outputShape(gate: GateAtom[]): OutputShape {\n const iter = gate.some((a) => a.kind === \"iter\");\n if (iter) return { kind: \"list\" };\n const optional = gate.some((a) => a.kind === \"present\" || a.kind === \"variant\");\n return { kind: \"single\", optional };\n}\n\n/**\n * Merge two shapes for outputs that share a field name across scopes/variants.\n * Any iterated contributor makes the field a list; otherwise it is a single\n * field that is optional if any contributor is gated.\n */\nexport function mergeShape(a: OutputShape, b: OutputShape): OutputShape {\n if (a.kind === \"list\" || b.kind === \"list\") return { kind: \"list\" };\n return { kind: \"single\", optional: a.optional || b.optional };\n}\n\n/** One collected Outputs field, deduped across same-named outputs. */\nexport interface OutputField {\n /** Backend-sanitized field identifier (via the caller's `idOf`). */\n id: string;\n /** First-seen raw output name (the descriptor's output id). */\n name: string;\n shape: OutputShape;\n doc?: string;\n}\n\n/**\n * Collect the unique Outputs fields in first-seen order, merging the shape and\n * doc of any outputs that resolve to the same field id. Multiple scopes (e.g.\n * the arms of a union output) routinely declare the same output name; without\n * deduping a backend would emit duplicate fields (a Python SyntaxError, a TS\n * duplicate member). `idOf` maps a raw output name to the target language's\n * sanitized identifier, so two raw names that collapse to the same identifier\n * merge into one field - exactly the field set the backend will emit.\n */\nexport function collectOutputFields(\n ctx: CodegenContext,\n idOf: (name: string) => string,\n): OutputField[] {\n const byId = new Map<string, OutputField>();\n const add = (output: EmittedOutput, scopeGate: GateAtom[]): void => {\n const gate = outputGate(scopeGate, output, ctx.bindings);\n const shape = outputShape(gate);\n const id = idOf(output.name);\n const doc = output.doc?.description ?? output.doc?.title;\n const existing = byId.get(id);\n if (existing) {\n existing.shape = mergeShape(existing.shape, shape);\n if (!existing.doc && doc) existing.doc = doc;\n } else {\n byId.set(id, { id, name: output.name, shape, doc });\n }\n };\n // The output directory itself, always present and ungated, listed first.\n add(rootOutput(ctx, idOf), []);\n for (const scope of ctx.outputScopes) {\n const scopeBinding = ctx.bindings.get(scope.scope);\n const scopeGate = scopeBinding?.gate ?? [];\n for (const output of scope.outputs) add(output, scopeGate);\n }\n // Mutable inputs surface as outputs; their binding gate is absolute (rooted),\n // so the scope gate is empty.\n for (const output of collectMutableOutputs(ctx)) add(output, []);\n return [...byId.values()];\n}\n\n/** Has any scope in the context attached at least one output? */\nexport function hasAnyOutputs(ctx: CodegenContext): boolean {\n return ctx.outputScopes.some((s) => s.outputs.length > 0);\n}\n\n/** A captured stream (stdout/stderr), surfaced as a list-of-lines Outputs field. */\nexport interface StreamField {\n /** First-seen raw stream name, bumped with a trailing `_` to dodge collisions. */\n name: string;\n /** Backend-sanitized identifier for `name` (via the caller's `idOf`). */\n id: string;\n doc?: string;\n}\n\n/**\n * The stdout/stderr fields declared by the app metadata, in declaration order\n * (stdout before stderr). Stream outputs are app-level: never gated (always\n * present when the tool runs), so they bypass the solver/gating machinery and\n * surface as plain list-of-string fields the wrapper appends to via the\n * `handle_stdout` / `handle_stderr` (Python) or `handleStdout` / `handleStderr`\n * (TS) callbacks. A stream whose sanitized id collides with a real output's id\n * is bumped (raw name gains a trailing `_`, re-sanitized) so it never shadows a\n * file output / emits a duplicate field.\n */\nexport function streamFields(ctx: CodegenContext, idOf: (name: string) => string): StreamField[] {\n const out: StreamField[] = [];\n // Seed with the file/mutable output field ids so a stream whose name collides\n // with a real output (e.g. an output literally named \"stdout\") is bumped\n // rather than emitting a duplicate field / repeated constructor argument.\n const used = new Set<string>(collectOutputFields(ctx, idOf).map((f) => f.id));\n const add = (rawName: string, doc?: string): void => {\n let name = rawName;\n while (used.has(idOf(name))) name += \"_\";\n used.add(idOf(name));\n out.push({ name, id: idOf(name), doc });\n };\n const so = ctx.app?.stdout;\n const se = ctx.app?.stderr;\n if (so) add(so.name, so.doc?.description ?? so.doc?.title);\n if (se) add(se.name, se.doc?.description ?? se.doc?.title);\n return out;\n}\n\n/** Does the app declare any stdout/stderr stream output? */\nexport function hasStreamOutputs(ctx: CodegenContext): boolean {\n return !!(ctx.app?.stdout || ctx.app?.stderr);\n}\n\n/**\n * Synthesize one output per mutable file input. Each is a `ResolvedOutput` with\n * a single ref token to the input binding and the `mutable` marker. The input\n * binding's solver-assigned gate fully encodes its ancestry (optional/variant/\n * iterated), so `outputGate([], ...)` yields the correct shape and gating for\n * free - no scope bucket needed.\n */\nexport function collectMutableOutputs(ctx: CodegenContext): EmittedOutput[] {\n const out: EmittedOutput[] = [];\n const seen = new Set<BindingId>();\n const walk = (node: Expr, inheritedDoc?: Documentation): void => {\n if (node.kind === \"path\") {\n if (node.attrs.mutable) {\n const binding = ctx.resolve(node);\n if (binding && !seen.has(binding.id)) {\n seen.add(binding.id);\n const doc = node.meta?.doc ?? inheritedDoc;\n out.push({\n name: binding.name,\n tokens: [{ kind: \"ref\", binding: binding.id }],\n ...(doc && { doc }),\n mutable: true,\n });\n }\n }\n return;\n }\n switch (node.kind) {\n case \"sequence\":\n for (const child of node.attrs.nodes) walk(child);\n break;\n case \"optional\":\n case \"repeat\":\n walk(node.attrs.node, node.meta?.doc ?? inheritedDoc);\n break;\n case \"alternative\":\n for (const alt of node.attrs.alts) walk(alt, node.meta?.doc ?? inheritedDoc);\n break;\n }\n };\n walk(ctx.expr);\n return out;\n}\n\n/** Does the tool have any mutable file input (surfaced as an output)? */\nexport function hasMutableInputs(ctx: CodegenContext): boolean {\n return collectMutableOutputs(ctx).length > 0;\n}\n","import type {\n Binding,\n BindingId,\n BoundType,\n GateAtom,\n ResolvedToken,\n} from \"../../bindings/index.js\";\nimport { outputGate } from \"../../bindings/index.js\";\nimport { collectFieldInfo } from \"../collect-field-info.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport {\n type EmittedOutput,\n type OutputShape,\n collectMutableOutputs,\n collectOutputFields,\n rootOutput,\n streamFields,\n} from \"../collect-output-fields.js\";\nimport { PY_KEYWORDS, emitDocstring } from \"./emit.js\";\nimport { pyStr, renderAccess, renderPyLiteral } from \"./typemap.js\";\n\n// The output-field/stream/mutable collection is language-agnostic and shared\n// with the TypeScript and JSON Schema backends; re-export the predicates the\n// backend entry point consumes so its import surface stays `./outputs-emit.js`.\nexport { hasAnyOutputs, hasMutableInputs, hasStreamOutputs } from \"../collect-output-fields.js\";\n\nfunction outputTypeExpr(shape: OutputShape): string {\n if (shape.kind === \"list\") return \"list[OutputPathType]\";\n return shape.optional ? \"OutputPathType | None\" : \"OutputPathType\";\n}\n\n/** Field ids for stdout/stderr (in declaration order), for wrapper wiring. */\nexport function streamFieldIds(ctx: CodegenContext): { stdout?: string; stderr?: string } {\n const fields = streamFields(ctx, pyId);\n const res: { stdout?: string; stderr?: string } = {};\n let idx = 0;\n if (ctx.app?.stdout) res.stdout = fields[idx++]!.id;\n if (ctx.app?.stderr) res.stderr = fields[idx++]!.id;\n return res;\n}\n\n/** Emit `@dataclasses.dataclass\\nclass <outputsType>:` declaration. */\nexport function emitOutputsClass(ctx: CodegenContext, outputsType: string, cb: CodeBuilder): void {\n cb.line(\"@dataclasses.dataclass\");\n cb.line(`class ${outputsType}:`);\n cb.indent(() => {\n emitDocstring(cb, \"Output paths produced by the tool.\");\n const fields = collectOutputFields(ctx, pyId);\n const streams = streamFields(ctx, pyId);\n if (fields.length === 0 && streams.length === 0) {\n cb.line(\"pass\");\n return;\n }\n for (const field of fields) {\n cb.line(`${field.id}: ${outputTypeExpr(field.shape)}`);\n if (field.doc) emitDocstring(cb, field.doc);\n }\n for (const s of streams) {\n cb.line(`${s.id}: list[str]`);\n if (s.doc) emitDocstring(cb, s.doc);\n }\n });\n}\n\n/**\n * Substitutions for ref access while inside an iteration loop, and how `iter`\n * segments in a binding's access path are resolved at emit time.\n */\ntype IterScope = Map<BindingId, string>;\n\ninterface OutputEmitCtx {\n ctx: CodegenContext;\n iter: IterScope;\n /**\n * Prefix substitutions for optional fields narrowed by an enclosing presence\n * gate: maps a rendered access prefix to the `.get()`-narrowed local holding\n * it. Threaded into `renderAccess` so reads use the local (one lookup, absent-\n * safe, mypy-narrowable) - mirrors the cargs builder's `valueSubst`.\n */\n subst: ReadonlyMap<string, string>;\n /**\n * Rendered Python default literals for root-level defaulted fields, keyed by\n * field name. An output path that interpolates such a field (e.g. an output\n * basename `maskfile`) reads it via `.get(key, <default>)` so an absent key\n * substitutes the default rather than raising `KeyError`. Mirrors the cargs\n * builder's `defaults`.\n */\n defaults: ReadonlyMap<string, string>;\n}\n\n/** The rendered default for a binding iff it is a root-level defaulted field. */\nfunction rootFieldDefault(\n binding: Binding | undefined,\n defaults: ReadonlyMap<string, string>,\n): string | undefined {\n if (!binding) return undefined;\n const a = binding.access;\n if (a.length === 1 && a[0]?.kind === \"field\") return defaults.get(binding.name);\n return undefined;\n}\n\n/** Build the field-name -> rendered-default map for the struct root (else empty).\n * Includes only non-optional defaulted fields (optional fields are\n * presence-guarded; their default comes from the factory's kwarg signature). */\nfunction collectDefaults(ctx: CodegenContext): Map<string, string> {\n const out = new Map<string, string>();\n const rootType = ctx.resolve(ctx.expr)?.type;\n if (rootType?.kind !== \"struct\") return out;\n for (const [name, fi] of collectFieldInfo(ctx, rootType)) {\n if (fi.defaultValue === undefined) continue;\n if (rootType.fields[name]?.kind === \"optional\") continue;\n out.set(name, renderPyLiteral(fi.defaultValue));\n }\n return out;\n}\n\ninterface WrapperRender {\n open: string;\n loopVar?: string;\n /** A `local = params.get(...)` line emitted before `open` (optional gates). */\n bindLine?: string;\n /** `[accessPrefix, local]` to add to the child scope's `subst` map. */\n subst?: [string, string];\n}\n\nlet loopCounter = 0;\n\nfunction renderWrapperOpen(atom: GateAtom, ec: OutputEmitCtx): WrapperRender {\n if (atom.kind === \"iter\") {\n const access = bindingAccess(atom.binding, ec);\n const v = `__o${loopCounter++}`;\n return { open: `for ${v} in ${access}:`, loopVar: v };\n }\n if (atom.kind === \"variant\") {\n const access = bindingAccess(atom.binding, ec);\n return { open: `if ${access}[\"@type\"] == ${pyStr(atom.variant)}:` };\n }\n // present\n const binding = ec.ctx.bindings.get(atom.binding);\n if (binding?.type.kind === \"optional\") {\n // Optional fields are NotRequired - the factory omits absent ones. Bind the\n // value to a narrowed local read via `.get()` (a bare subscript would\n // KeyError) and redirect inner reads to it via `subst`. Mirrors walkOptional.\n const subscriptAccess = bindingAccess(atom.binding, ec);\n const getAccess = bindingAccess(atom.binding, ec, true);\n const local = `__v${loopCounter++}`;\n return {\n open: `if ${local} is not None:`,\n bindLine: `${local} = ${getAccess}`,\n subst: [subscriptAccess, local],\n };\n }\n // A bool flag / count gating an output is NotRequired (a hand-authored config\n // may omit it), so read absence-safe via `.get()` - a bare subscript would\n // KeyError. `presentCondition` coerces the possibly-None `.get()` result.\n const t = binding?.type.kind;\n const absentSafe = t === \"bool\" || t === \"count\";\n const access = bindingAccess(atom.binding, ec, absentSafe);\n const cond = presentCondition(binding?.type, access);\n return { open: `if ${cond}:` };\n}\n\nfunction presentCondition(type: BoundType | undefined, access: string): string {\n if (!type) return access;\n switch (type.kind) {\n case \"optional\":\n return `${access} is not None`;\n case \"bool\":\n // `access` is a `.get()` read: None (absent) is falsy -> flag off.\n return access;\n case \"count\":\n // `access` is a `.get()` read: coerce None (absent) to 0 before comparing.\n return `(${access} or 0) > 0`;\n default:\n return access;\n }\n}\n\nfunction bindingAccess(\n id: BindingId,\n ec: OutputEmitCtx,\n finalGet = false,\n finalDefault?: string,\n): string {\n // The binding is itself the currently-iterated element (a ref to the list\n // being looped, or a scalar list element): use its loop variable directly.\n const iterVar = ec.iter.get(id);\n if (iterVar) return iterVar;\n const binding = ec.ctx.bindings.get(id);\n if (binding) {\n // Solver-assigned path; `iter` segments resolve to the loop variable bound\n // by the surrounding `iter` gate atom. `finalGet` renders the last field\n // segment as `.get()` when binding an optional's value; `finalDefault`\n // renders it as `.get(key, default)` for a defaulted field; `subst` redirects\n // an optional prefix to the narrowed local bound by its presence gate.\n return renderAccess(\n binding.access,\n (b) => ec.iter.get(b) ?? `None # unresolved loop var ${b}`,\n {\n finalFieldGet: finalGet,\n finalFieldDefault: finalDefault,\n subst: ec.subst,\n },\n );\n }\n return `None # unresolved binding ${id}`;\n}\n\n/** Render the path expression for an output's tokens. */\nfunction renderPathExpr(tokens: ResolvedToken[], ec: OutputEmitCtx): string {\n if (tokens.length === 0) return `\"\"`;\n if (tokens.length === 1) return renderToken(tokens[0]!, ec);\n // f-string interpolation. Use a single-quoted outer so embedded subscript\n // expressions like `params[\"key\"]` (with double quotes) don't collide with\n // the outer quote - PEP 701 (Python 3.12+) lifts this restriction, but we\n // target 3.10+.\n let result = \"f'\";\n for (const tok of tokens) {\n if (tok.kind === \"literal\") {\n // Escape backslashes, single quotes, and braces (the latter are f-string\n // metacharacters).\n result += tok.value\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/'/g, \"\\\\'\")\n .replace(/\\{/g, \"{{\")\n .replace(/\\}/g, \"}}\");\n } else {\n result += \"{\";\n result += renderRefValue(tok, ec);\n result += \"}\";\n }\n }\n result += \"'\";\n return result;\n}\n\nfunction renderToken(tok: ResolvedToken, ec: OutputEmitCtx): string {\n if (tok.kind === \"literal\") return pyStr(tok.value);\n return renderRefValue(tok, ec);\n}\n\nfunction renderRefValue(tok: Extract<ResolvedToken, { kind: \"ref\" }>, ec: OutputEmitCtx): string {\n // A defaulted root field interpolated into an output path is read absent-safe\n // via `.get(key, default)` (it is `NotRequired`); other refs render normally.\n const def = rootFieldDefault(ec.ctx.bindings.get(tok.binding), ec.defaults);\n let expr =\n def !== undefined && !ec.iter.has(tok.binding)\n ? bindingAccess(tok.binding, ec, false, def)\n : bindingAccess(tok.binding, ec);\n if (tok.fallback !== undefined) {\n expr = `(${expr} if ${expr} is not None else ${pyStr(tok.fallback)})`;\n }\n if (tok.stripExtensions && tok.stripExtensions.length > 0) {\n const sorted = [...tok.stripExtensions].sort((a, b) => b.length - a.length);\n const lits = sorted.map((s) => pyStr(s)).join(\", \");\n expr = `_strip_extensions(${expr}, [${lits}])`;\n }\n return expr;\n}\n\n/**\n * Emit one contributor's assignment into the field's shared local var,\n * wrapped in its gate. The local var's init is emitted upfront by the caller\n * (except for required-single fields, which declare at their first ungated\n * assignment; `reassign` marks a later same-named contributor that must assign\n * into the already-declared local rather than re-annotate it).\n */\nfunction emitOneOutput(\n output: EmittedOutput,\n gate: GateAtom[],\n fieldShape: OutputShape,\n localVar: string,\n reassign: boolean,\n ec: OutputEmitCtx,\n cb: CodeBuilder,\n): void {\n const typeAnnot = outputTypeExpr(fieldShape);\n\n function nest(remaining: GateAtom[], child: OutputEmitCtx): void {\n if (remaining.length === 0) {\n const pathExpr = renderPathExpr(output.tokens, child);\n // A mutable input's writable copy is surfaced via mutable_copy (its host\n // path); a regular output resolves a local path via output_file.\n const call = output.mutable\n ? `execution.mutable_copy(${pathExpr})`\n : `execution.output_file(${pathExpr})`;\n if (fieldShape.kind === \"list\") {\n cb.line(`${localVar}.append(${call})`);\n } else if (fieldShape.optional || reassign) {\n // Optional fields init upfront; a required-single's second-or-later\n // ungated contributor reassigns the already-declared local (a second\n // annotated declaration would be a mypy `no-redef`).\n cb.line(`${localVar} = ${call}`);\n } else {\n // Required single: the first ungated contributor declares the var here.\n cb.line(`${localVar}: ${typeAnnot} = ${call}`);\n }\n return;\n }\n const [head, ...rest] = remaining;\n if (!head) return;\n const wrapper = renderWrapperOpen(head, child);\n if (wrapper.bindLine) cb.line(wrapper.bindLine);\n cb.line(wrapper.open);\n cb.indent(() => {\n let inner = child;\n if (head.kind === \"iter\") {\n inner = { ...child, iter: new Map(child.iter).set(head.binding, wrapper.loopVar!) };\n } else if (wrapper.subst) {\n inner = { ...child, subst: new Map(child.subst).set(wrapper.subst[0], wrapper.subst[1]) };\n }\n nest(rest, inner);\n });\n }\n\n nest(gate, ec);\n}\n\n/**\n * Emit a standalone `_outputs(params, execution)` function that builds and\n * returns the `Outputs` dataclass. Mirrors the `_cargs` function so the\n * wrapper can just call both. Same-named outputs share one local var (init\n * once, then every contributor assigns into it under its own gate), and the\n * constructor receives one keyword argument per unique field.\n */\nexport function emitBuildOutputs(\n ctx: CodegenContext,\n paramsType: string,\n outputsType: string,\n funcName: string,\n cb: CodeBuilder,\n): void {\n cb.line(`def ${funcName}(params: ${paramsType}, execution: Execution) -> ${outputsType}:`);\n cb.indent(() => {\n cb.line(`\"\"\"Build the ${outputsType} object for this tool.\"\"\"`);\n loopCounter = 0;\n const ec: OutputEmitCtx = {\n ctx,\n iter: new Map(),\n subst: new Map(),\n defaults: collectDefaults(ctx),\n };\n\n const fields = collectOutputFields(ctx, pyId);\n const localVarOf = new Map<string, string>();\n for (const f of fields) {\n const localVar = `${f.id}_v`;\n localVarOf.set(f.id, localVar);\n // Initialize lists and gated singles upfront so each contributor only\n // assigns or appends. Required-singles are declared at their (sole)\n // ungated assignment - no init line here would leave the name unbound.\n if (f.shape.kind === \"list\") cb.line(`${localVar}: list[OutputPathType] = []`);\n else if (f.shape.optional) cb.line(`${localVar}: OutputPathType | None = None`);\n }\n\n // Required-single fields declare their local at the first ungated\n // contributor; a same-named ungated contributor seen later must reassign\n // (a second annotated declaration is a mypy `no-redef`). Some afni\n // descriptors give two output-files the same id with no gate.\n const declared = new Set<string>();\n const emitContributor = (output: EmittedOutput, scopeGate: GateAtom[]): void => {\n const gate = outputGate(scopeGate, output, ctx.bindings);\n const id = pyId(output.name);\n const field = fields.find((f) => f.id === id)!;\n const reassign = declared.has(id);\n declared.add(id);\n emitOneOutput(output, gate, field.shape, localVarOf.get(id)!, reassign, ec, cb);\n };\n // The always-present root output directory, declared before any declared\n // output (matches its first position in collectOutputFields).\n emitContributor(rootOutput(ctx, pyId), []);\n for (const scope of ctx.outputScopes) {\n const scopeBinding = ctx.bindings.get(scope.scope);\n const scopeGate = scopeBinding?.gate ?? [];\n for (const output of scope.outputs) emitContributor(output, scopeGate);\n }\n for (const output of collectMutableOutputs(ctx)) emitContributor(output, []);\n\n const streams = streamFields(ctx, pyId);\n if (fields.length === 0 && streams.length === 0) {\n cb.line(`return ${outputsType}()`);\n } else {\n cb.line(`return ${outputsType}(`);\n cb.indent(() => {\n for (const f of fields) cb.line(`${f.id}=${localVarOf.get(f.id)},`);\n // Stream fields start empty; the wrapper appends to them via the\n // handle_stdout / handle_stderr callbacks passed to execution.run.\n for (const s of streams) cb.line(`${s.id}=[],`);\n });\n cb.line(\")\");\n }\n });\n}\n\n/** Sanitize an output name to a valid Python identifier. */\nfunction pyId(name: string): string {\n let s = name.replace(/[^a-zA-Z0-9_]/g, \"_\");\n if (/^\\d/.test(s)) s = \"_\" + s;\n if (s === \"\") s = \"_\";\n if (PY_KEYWORDS.has(s)) s = s + \"_\";\n return s;\n}\n\n/** Whether any output reference has stripExtensions set. */\nexport function needsStripExtensionsHelper(ctx: CodegenContext): boolean {\n for (const scope of ctx.outputScopes) {\n for (const output of scope.outputs) {\n for (const tok of output.tokens) {\n if (tok.kind === \"ref\" && tok.stripExtensions?.length) return true;\n }\n }\n }\n return false;\n}\n\n/** Emit a small `_strip_extensions` helper used by ref tokens that strip suffixes. */\nexport function emitStripExtensionsHelper(cb: CodeBuilder): void {\n cb.line(\"def _strip_extensions(value: str, exts: list[str]) -> str:\");\n cb.indent(() => {\n cb.line(\"for ext in exts:\");\n cb.indent(() => {\n cb.line(\"if value.endswith(ext):\");\n cb.indent(() => {\n cb.line(\"return value[: -len(ext)]\");\n });\n });\n cb.line(\"return value\");\n });\n}\n","import type { BoundType } from \"../../bindings/index.js\";\nimport type { AppMeta } from \"../../ir/index.js\";\nimport type { CodegenContext, PackageMeta, ProjectMeta } from \"../../manifest/index.js\";\nimport type { AppEntrypoint, Backend, EmitResult, EmittedApp, EmittedPackage } from \"../backend.js\";\nimport type { SigEntry } from \"../sig-entries.js\";\nimport type { NamedType } from \"./types.js\";\nimport {\n generateRequirementsTxt,\n generateRootPyproject,\n generateRootReadme,\n generateSubPyproject,\n generateSubReadme,\n pyDistName,\n} from \"./packaging.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport { Scope } from \"../scope.js\";\nimport { pascalCase, screamingSnakeCase, snakeCase } from \"../string-case.js\";\nimport { buildSigEntries } from \"../sig-entries.js\";\nimport {\n emitBuildCargs,\n emitImports,\n emitKwargWrapper,\n emitMetadata,\n emitParamsFactory,\n emitTypeDeclarations,\n emitWrapperFunction,\n pyScrubIdent,\n pySigOptions,\n} from \"./emit.js\";\nimport { collectFieldInfo } from \"./types.js\";\nimport { emitValidate } from \"./validate-emit.js\";\nimport {\n emitBuildOutputs,\n emitOutputsClass,\n emitStripExtensionsHelper,\n needsStripExtensionsHelper,\n streamFieldIds,\n} from \"./outputs-emit.js\";\nimport { mapType } from \"./typemap.js\";\nimport { collectNamedTypes, resolveTypeName, structKey, unionKey } from \"./types.js\";\n\n// Python reserved words + commonly-shadowed built-ins. Used to avoid collisions\n// when generating identifiers. Includes keywords, common stdlib builtins, and\n// the styxdefs symbols we emit/import.\nconst PY_RESERVED: ReadonlySet<string> = new Set([\n \"False\",\n \"None\",\n \"True\",\n \"and\",\n \"as\",\n \"assert\",\n \"async\",\n \"await\",\n \"break\",\n \"class\",\n \"continue\",\n \"def\",\n \"del\",\n \"elif\",\n \"else\",\n \"except\",\n \"finally\",\n \"for\",\n \"from\",\n \"global\",\n \"if\",\n \"import\",\n \"in\",\n \"is\",\n \"lambda\",\n \"nonlocal\",\n \"not\",\n \"or\",\n \"pass\",\n \"raise\",\n \"return\",\n \"try\",\n \"while\",\n \"with\",\n \"yield\",\n // Common builtins to avoid shadowing.\n \"list\",\n \"dict\",\n \"tuple\",\n \"set\",\n \"int\",\n \"float\",\n \"str\",\n \"bool\",\n \"type\",\n \"print\",\n \"open\",\n \"input\",\n \"range\",\n \"len\",\n \"id\",\n \"object\",\n \"Exception\",\n \"ValueError\",\n \"TypeError\",\n // styxdefs symbols we emit/import.\n \"Runner\",\n \"Execution\",\n \"Metadata\",\n \"InputPathType\",\n \"OutputPathType\",\n \"get_global_runner\",\n \"dataclasses\",\n \"typing\",\n]);\n\n/**\n * Per-tool public symbol names. With the flat `fsl/bet.py` layout each tool\n * file emits these names directly - there is no internal/public alias split.\n */\nexport interface PublicNames {\n params: string;\n outputs: string;\n metadata: string;\n cargs: string;\n outputsFn: string;\n paramsFn: string;\n execute: string;\n validate: string;\n wrapper: string;\n}\n\n/** Public-name scheme used by the Python backend. Exported so the CLI and tests can use it. */\nexport function computePublicNames(appId: string | undefined): PublicNames {\n if (!appId) {\n return {\n params: \"Params\",\n outputs: \"Outputs\",\n metadata: \"METADATA\",\n cargs: \"cargs\",\n outputsFn: \"outputs\",\n paramsFn: \"build_params\",\n execute: \"execute\",\n validate: \"validate\",\n wrapper: \"run\",\n };\n }\n // Pre-scrub digit-leading ids (e.g. `3dPFM`) so all derived case forms\n // produce valid Python identifiers in a consistent case (matches v1's\n // `V_3D_PFM_METADATA` / `v_3d_pfm` style instead of mixed `v_3D_PFM`).\n const id = /^[0-9]/.test(appId) ? \"v_\" + appId : appId;\n return {\n params: pascalCase(id),\n outputs: pascalCase(id) + \"Outputs\",\n metadata: screamingSnakeCase(id) + \"_METADATA\",\n cargs: snakeCase(id) + \"_cargs\",\n outputsFn: snakeCase(id) + \"_outputs\",\n paramsFn: snakeCase(id) + \"_params\",\n execute: snakeCase(id) + \"_execute\",\n validate: snakeCase(id) + \"_validate\",\n wrapper: snakeCase(id),\n };\n}\n\n/**\n * The fully-derived naming/typing model for one tool's Python emission. Computed\n * once by `buildEmitModel` so the file emitter and the call-site snippet renderer\n * share the exact same public names, scrubbed kwarg names, and root typing - the\n * snippet must match the function the generated code actually exposes.\n */\nexport interface PyEmitModel {\n appId: string | undefined;\n pkg: string | undefined;\n names: {\n params: string;\n outputs: string;\n metadata: string;\n cargs: string;\n outputsFn: string;\n paramsFn: string;\n execute: string;\n validate: string;\n wrapper: string;\n };\n rootType: BoundType;\n rootIsStruct: boolean;\n namedTypes: Map<string, string>;\n typeDecls: NamedType[];\n rootTypeTag: string | undefined;\n paramsType: string;\n sigEntries: SigEntry[];\n}\n\n/**\n * Derive the public names, named-type declarations, root typing, and per-field\n * signature entries for one tool. Mutates `scope` exactly as the emitter needs\n * (the `reg` registrations and the `sigScope` child), so passing the same scope\n * the emitter continues with keeps later local registrations consistent.\n */\nexport function buildEmitModel(\n ctx: CodegenContext,\n scope: Scope = new Scope(PY_RESERVED),\n): PyEmitModel {\n const appId = ctx.app?.id;\n const pkg = ctx.package?.name;\n const publicNames = computePublicNames(appId);\n\n const rootBinding = ctx.resolve(ctx.expr);\n const rootType: BoundType = rootBinding?.type ?? { kind: \"struct\", fields: {} };\n // Only treat the root as struct-shaped when there's a real binding. A\n // synthesized empty-struct fallback (no root binding) means the solver\n // collapsed everything away, so the kwarg wrapper has nothing to wrap.\n const rootIsStruct = rootBinding?.type.kind === \"struct\";\n\n // Pre-reserve module-level public names so any IR-derived names colliding\n // with them get suffix-bumped. `params` is intentionally NOT pre-reserved -\n // `collectNamedTypes` claims it for the root struct just below. Each name\n // is scrubbed through `pyScrubIdent` first since the case helpers happily\n // pass through digit-leading app ids like `3dvolreg.afni`.\n const reg = (name: string) => scope.add(pyScrubIdent(name, PY_RESERVED));\n const names = {\n params: pyScrubIdent(publicNames.params, PY_RESERVED),\n outputs: reg(publicNames.outputs),\n metadata: reg(publicNames.metadata),\n cargs: reg(publicNames.cargs),\n outputsFn: reg(publicNames.outputsFn),\n paramsFn: rootIsStruct ? reg(publicNames.paramsFn) : \"\",\n execute: rootIsStruct ? reg(publicNames.execute) : \"\",\n validate: reg(publicNames.validate),\n wrapper: reg(publicNames.wrapper),\n };\n\n // Prefix nested type names with the tool's root name so a suite's flat\n // `from .x import *` re-exports don't shadow same-named types across tools.\n const { namedTypes, typeDecls } = collectNamedTypes(\n rootType,\n names.params,\n scope,\n pascalCase,\n appId ? names.params : \"\",\n );\n\n names.params =\n (rootType.kind === \"struct\" ? namedTypes.get(structKey(rootType)) : undefined) ??\n (rootType.kind === \"union\" ? namedTypes.get(unionKey(rootType)) : undefined) ??\n names.params;\n\n // Tag injected as `@type: Literal[...]` on the root TypedDict (and as a\n // constant key by the params factory). Skipped when appId/pkg aren't known.\n const rootTypeTag = appId && pkg ? `${pkg}/${appId}` : undefined;\n\n const paramsType =\n rootType.kind === \"struct\" || rootType.kind === \"union\"\n ? names.params\n : mapType(rootType, resolveTypeName(namedTypes));\n\n // Build the per-field SigEntry list once - the factory and kwarg wrapper\n // both consume it, so the host names registered here must satisfy both\n // function scopes. Pre-reserve `params` (factory + wrapper body) and\n // `runner` (wrapper signature) so a wire key matching either gets\n // suffix-bumped. `rootType` is narrowed by `rootIsStruct` for the `Extract`\n // constraint.\n const sigScope = scope.child([\"params\", \"runner\"]);\n const sigEntries =\n rootIsStruct && rootType.kind === \"struct\"\n ? buildSigEntries(\n rootType,\n collectFieldInfo(ctx, rootType),\n (wireKey) => sigScope.add(pyScrubIdent(wireKey, PY_RESERVED)),\n pySigOptions(resolveTypeName(namedTypes)),\n )\n : [];\n\n return {\n appId,\n pkg,\n names,\n rootType,\n rootIsStruct,\n namedTypes,\n typeDecls,\n rootTypeTag,\n paramsType,\n sigEntries,\n };\n}\n\nexport function generatePython(ctx: CodegenContext, packageScope?: Scope): string {\n const cb = new CodeBuilder(\" \");\n // A package-shared scope keeps top-level names unique across every tool in the\n // suite's `from .x import *` re-exports; without one a per-tool scope suffices.\n const scope = packageScope ?? new Scope(PY_RESERVED);\n\n const {\n names,\n rootType,\n rootIsStruct,\n namedTypes,\n typeDecls,\n rootTypeTag,\n paramsType,\n sigEntries,\n } = buildEmitModel(ctx, scope);\n\n // Auto-generated header.\n cb.comment(\"This file was auto generated by Styx.\", \"# \");\n cb.comment(\"Do not edit this file directly.\", \"# \");\n cb.blank();\n\n // Every tool emits an Outputs object: at minimum the synthetic `root` output\n // directory (output_file(\".\")), plus any declared file/mutable outputs and\n // stdout/stderr stream fields. OutputPathType is therefore always imported.\n const emitOutputs = true;\n\n emitImports(cb, true);\n cb.blank();\n\n emitMetadata(ctx, names.metadata, cb);\n cb.blank();\n\n emitTypeDeclarations(typeDecls, namedTypes, ctx, cb, names.params, rootTypeTag);\n\n if (emitOutputs) {\n emitOutputsClass(ctx, names.outputs, cb);\n cb.blank();\n }\n\n if (emitOutputs && needsStripExtensionsHelper(ctx)) {\n emitStripExtensionsHelper(cb);\n cb.blank();\n }\n\n // Params factory (struct-rooted tools only): a kwarg-style builder for the\n // params dict. Useful for callers that want to build a dict to mutate before\n // executing.\n if (rootIsStruct) {\n emitParamsFactory(sigEntries, names.paramsFn, paramsType, rootTypeTag, cb);\n cb.blank();\n }\n\n // Validation: walks the root binding and raises StyxValidationError on bad\n // input. Called first thing in the dict-style execute (below).\n emitValidate(\n ctx,\n rootType,\n ctx.expr,\n paramsType,\n names.validate,\n resolveTypeName(namedTypes),\n scope,\n cb,\n );\n cb.blank();\n\n emitBuildCargs(ctx, rootType, paramsType, names.cargs, cb);\n cb.blank();\n\n if (emitOutputs) {\n emitBuildOutputs(ctx, paramsType, names.outputs, names.outputsFn, cb);\n cb.blank();\n }\n\n // Dict-style execute function. For struct roots it's the internal\n // `<tool>_execute`; for other roots it doubles as the user-facing wrapper.\n const executeName = rootIsStruct ? names.execute : names.wrapper;\n emitWrapperFunction(\n ctx,\n paramsType,\n executeName,\n names.metadata,\n names.cargs,\n emitOutputs ? names.outputsFn : undefined,\n emitOutputs ? names.outputs : undefined,\n names.validate,\n streamFieldIds(ctx),\n cb,\n );\n cb.blank();\n\n // Kwarg-style wrapper (struct roots only): the v1-parity user-facing entry.\n if (rootIsStruct) {\n emitKwargWrapper(\n ctx,\n sigEntries,\n names.wrapper,\n names.paramsFn,\n names.execute,\n emitOutputs ? names.outputs : undefined,\n cb,\n );\n cb.blank();\n }\n\n // `__all__` keeps suite-level `from .bet import *` from re-exporting the\n // module's stdlib/styxdefs imports.\n const publicSymbols = [\n names.params,\n ...(emitOutputs ? [names.outputs] : []),\n names.metadata,\n names.cargs,\n ...(emitOutputs ? [names.outputsFn] : []),\n ...(rootIsStruct ? [names.paramsFn, names.execute] : []),\n names.validate,\n names.wrapper,\n ];\n cb.line(\"__all__ = [\");\n cb.indent(() => {\n for (const sym of publicSymbols) cb.line(`\"${sym}\",`);\n });\n cb.line(\"]\");\n\n return cb.toString();\n}\n\n/**\n * Module name (file stem) for an app: snake_case of app.id, fallback `output`.\n * Scrubbed so digit-leading app ids (e.g. `3dPFM` -> `v_3d_pfm`) and keyword\n * collisions don't break `from .<mod> import *` in the package __init__.\n */\nexport function appModuleName(meta: AppMeta | undefined): string {\n if (!meta?.id) return \"output\";\n return pyScrubIdent(snakeCase(meta.id), PY_RESERVED);\n}\n\n/**\n * The dispatch entrypoint for one app: its root `@type` (`<package>/<app>`) and\n * the dict-style execute function name. Returns undefined when the id or package\n * is unknown (no stable `@type`), so the app is left out of the suite dispatcher.\n */\nexport function appEntrypoint(ctx: CodegenContext): AppEntrypoint | undefined {\n const appId = ctx.app?.id;\n const pkg = ctx.package?.name;\n if (!appId || !pkg) return undefined;\n const publicNames = computePublicNames(appId);\n const rootIsStruct = ctx.resolve(ctx.expr)?.type.kind === \"struct\";\n const executeFn = pyScrubIdent(\n rootIsStruct ? publicNames.execute : publicNames.wrapper,\n PY_RESERVED,\n );\n return { type: `${pkg}/${appId}`, executeFn };\n}\n\n/**\n * Generate the suite-level `__init__.py` re-export for a package containing\n * multiple tool modules. Each tool module's public symbols are surfaced via\n * `from .bet import *` (each tool file defines `__all__`). When apps carry a\n * dispatch entrypoint, a suite-level `execute(params, runner)` is appended that\n * routes a config object to the right tool by its root `@type`.\n */\nexport function generatePackageInit(apps: EmittedApp[]): string {\n const cb = new CodeBuilder(\" \");\n cb.comment(\"This file was auto generated by Styx.\", \"# \");\n cb.comment(\"Do not edit this file directly.\", \"# \");\n cb.blank();\n\n const dispatch = apps\n .map((a) => a.entrypoint)\n .filter((e): e is AppEntrypoint => e !== undefined)\n .sort((a, b) => a.type.localeCompare(b.type));\n\n if (dispatch.length > 0) {\n cb.line(\"import typing\");\n cb.blank();\n cb.line(\"from styxdefs import Runner\");\n cb.blank();\n }\n\n const modules = apps\n .map((a) => appModuleName(a.meta))\n .filter((name): name is string => !!name)\n .sort();\n\n for (const mod of modules) {\n cb.line(`from .${mod} import *`);\n }\n\n if (dispatch.length > 0) {\n cb.blank();\n emitPackageDispatch(cb, dispatch);\n }\n\n return cb.toString();\n}\n\n/** Emit the suite-level `execute(params, runner)` dispatcher over `@type`. */\nfunction emitPackageDispatch(cb: CodeBuilder, dispatch: AppEntrypoint[]): void {\n cb.line(\n \"def execute(params: dict[str, typing.Any], runner: Runner | None = None) -> typing.Any:\",\n );\n cb.indent(() => {\n cb.line('\"\"\"Run a tool in this package from a params object, routed by its `@type`.\"\"\"');\n cb.line(\"_dispatch: dict[str, typing.Callable[[typing.Any, Runner | None], typing.Any]] = {\");\n cb.indent(() => {\n for (const e of dispatch) {\n cb.line(`${JSON.stringify(e.type)}: ${e.executeFn},`);\n }\n });\n cb.line(\"}\");\n cb.line('_fn = _dispatch.get(params[\"@type\"])');\n cb.line(\"if _fn is None:\");\n cb.indent(() => {\n cb.line(`raise ValueError(f\"No tool registered for @type {params['@type']!r}\")`);\n });\n cb.line(\"return _fn(params, runner)\");\n });\n}\n\nexport class PythonBackend implements Backend {\n readonly name = \"python\";\n readonly target = \"python\";\n\n emitApp(ctx: CodegenContext, scope?: Scope): EmittedApp {\n const code = generatePython(ctx, scope);\n const fileName = `${appModuleName(ctx.app)}.py`;\n return {\n meta: ctx.app,\n entrypoint: appEntrypoint(ctx),\n files: new Map([[fileName, code]]),\n errors: [],\n warnings: [],\n };\n }\n\n newPackageScope(): Scope {\n return new Scope(PY_RESERVED);\n }\n\n emitPackage(pkg: PackageMeta, apps: EmittedApp[]): EmittedPackage {\n return {\n meta: pkg,\n files: new Map([\n [\"__init__.py\", generatePackageInit(apps)],\n // PEP 561 marker so type-checkers treat the generated suite as typed.\n [\"py.typed\", \"\"],\n ]),\n errors: [],\n warnings: [],\n };\n }\n\n emitProject(proj: ProjectMeta, packages: EmittedPackage[]): EmitResult {\n const files = new Map<string, string>();\n const distNames: string[] = [];\n const pkgDirs: string[] = [];\n\n for (const p of packages) {\n const pkg = p.meta ?? {};\n // Mirror the CLI's `pkgDir` fallback so a nameless package's source dir\n // still gets a matching pyproject/README instead of being orphaned.\n const dir = pkg.name ?? \"package\";\n pkgDirs.push(dir);\n distNames.push(pyDistName(proj, pkg));\n files.set(`${dir}/pyproject.toml`, generateSubPyproject(proj, pkg));\n files.set(`${dir}/README.md`, generateSubReadme(proj, pkg));\n }\n\n files.set(\"pyproject.toml\", generateRootPyproject(proj, distNames));\n files.set(\"README.md\", generateRootReadme(proj, distNames));\n files.set(\"requirements.txt\", generateRequirementsTxt(pkgDirs));\n\n return { files, errors: [], warnings: [] };\n }\n}\n","import type { BoundType } from \"../bindings/index.js\";\n\n/**\n * Per-language rendering hooks for the call-site snippet renderer. The recursive\n * structure (struct -> object literal, union -> picked variant, list -> array)\n * is language-agnostic; only leaf-literal syntax, object keys, and indentation\n * differ, and those are supplied here.\n */\nexport interface SnippetDialect {\n /** One indentation level (e.g. `\" \"` for Python, `\" \"` for TypeScript). */\n indentUnit: string;\n /** Render a string value as a host literal (quoted). */\n string(value: string): string;\n /** Render a boolean value as a host literal (`True`/`true`). */\n boolean(value: boolean): string;\n /** Render a number value as a host literal. */\n number(value: number): string;\n /** Host literal for a null/None value. */\n null: string;\n /** Render an object-literal key from a wire key, quoting when not a bare identifier. */\n objKey(wireKey: string): string;\n}\n\n/** Options shared by both language renderers. */\nexport interface SnippetOptions {\n /**\n * Module the package is imported from (e.g. `\"niwrap\"`). Defaults to the\n * project name on the context. When unset and no project name is available,\n * Python falls back to a bare `import <pkg>` and TypeScript omits the import.\n */\n packageRoot?: string;\n /** Whether to prepend an import line. Defaults to `true`. */\n includeImport?: boolean;\n}\n\n/** Is `value` a plain (non-array) object usable as a struct/union config? */\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Strip transparent `optional` wrappers down to the underlying value type. */\nfunction unwrap(type: BoundType): BoundType {\n return type.kind === \"optional\" ? unwrap(type.inner) : type;\n}\n\n/** Render a leaf primitive (string/number/bool/null) by its JS runtime type. */\nfunction renderPrimitive(value: unknown, d: SnippetDialect): string {\n if (value === null || value === undefined) return d.null;\n switch (typeof value) {\n case \"string\":\n return d.string(value);\n case \"boolean\":\n return d.boolean(value);\n case \"number\":\n return d.number(value);\n default:\n // Bigint / unexpected: fall back to a quoted string form.\n return d.string(String(value));\n }\n}\n\n/** The `@type` discriminator value carried by a struct type, if any. */\nfunction structAtType(type: Extract<BoundType, { kind: \"struct\" }>): string | undefined {\n const field = type.fields[\"@type\"];\n return field && field.kind === \"literal\" ? String(field.value) : undefined;\n}\n\n/**\n * Render a struct config as a host object literal (Python dict / TS object).\n * Keys are the Boutiques wire names (the generated TypedDict / interface keys) -\n * nested structs have no constructor function in the generated code, so callers\n * build them as plain object literals.\n *\n * `@type` is emitted from the struct's literal discriminator field when present\n * (union variants carry a required, load-bearing `@type`); for the root call the\n * tag is injected via `injectAtType` (the root's `@type` is derived from\n * `pkg/appId`, not stored as a field). Non-`@type` literal fields have no\n * runtime representation and are skipped.\n */\nexport function renderStructLiteral(\n value: unknown,\n type: Extract<BoundType, { kind: \"struct\" }>,\n indent: string,\n d: SnippetDialect,\n injectAtType?: string,\n): string {\n const obj = isRecord(value) ? value : {};\n const inner = indent + d.indentUnit;\n const lines: string[] = [];\n\n const atType = structAtType(type) ?? injectAtType;\n if (atType !== undefined) {\n lines.push(`${inner}${d.objKey(\"@type\")}: ${d.string(atType)},`);\n }\n\n for (const [wireKey, fieldType] of Object.entries(type.fields)) {\n if (wireKey === \"@type\") continue;\n if (fieldType.kind === \"literal\") continue; // no runtime representation\n if (!(wireKey in obj)) continue; // omitted optional / absent field\n lines.push(`${inner}${d.objKey(wireKey)}: ${renderValue(obj[wireKey], fieldType, inner, d)},`);\n }\n\n if (lines.length === 0) return \"{}\";\n return `{\\n${lines.join(\"\\n\")}\\n${indent}}`;\n}\n\n/**\n * Render a union config. An object value with an `@type` is matched to the\n * struct variant whose discriminator equals that tag and rendered as that\n * variant's object literal; a primitive value (a bare literal/scalar variant,\n * e.g. a mixed union's `\"Linear\"` const arm) is rendered directly.\n */\nfunction renderUnion(\n value: unknown,\n type: Extract<BoundType, { kind: \"union\" }>,\n indent: string,\n d: SnippetDialect,\n): string {\n if (isRecord(value)) {\n const tag = value[\"@type\"];\n const match = type.variants.find(\n (v) => v.type.kind === \"struct\" && structAtType(v.type) === String(tag),\n );\n if (match && match.type.kind === \"struct\") {\n return renderStructLiteral(value, match.type, indent, d);\n }\n // Unknown/missing tag: fall back to the sole struct variant if there is one,\n // otherwise emit an empty object. (Well-formed configs always match.)\n const onlyStruct = type.variants.filter((v) => v.type.kind === \"struct\");\n if (onlyStruct.length === 1 && onlyStruct[0]!.type.kind === \"struct\") {\n return renderStructLiteral(value, onlyStruct[0]!.type, indent, d);\n }\n return \"{}\";\n }\n return renderPrimitive(value, d);\n}\n\n/**\n * Render a list config. A list of structs/unions renders multi-line (one object\n * literal per element); a list of primitives renders inline (`[1, 2, 3]`).\n */\nfunction renderList(value: unknown, item: BoundType, indent: string, d: SnippetDialect): string {\n if (!Array.isArray(value) || value.length === 0) return \"[]\";\n const it = unwrap(item);\n if (it.kind === \"struct\" || it.kind === \"union\") {\n const inner = indent + d.indentUnit;\n const elems = value.map((el) => `${inner}${renderValue(el, it, inner, d)},`);\n return `[\\n${elems.join(\"\\n\")}\\n${indent}]`;\n }\n return `[${value.map((el) => renderValue(el, it, indent, d)).join(\", \")}]`;\n}\n\n/**\n * Render a config value to a host-language expression, guided by its BoundType.\n *\n * `indent` is the leading whitespace of the line the value starts on; multi-line\n * forms (object/array literals) place their members one level deeper and close\n * back at `indent`. The renderer follows the BoundType tree for shape and reads\n * the parallel config object for values, so unknown / absent keys are simply\n * omitted (a partial config produces a partial snippet).\n */\nexport function renderValue(\n value: unknown,\n type: BoundType,\n indent: string,\n d: SnippetDialect,\n): string {\n // A present null/undefined renders as the host null literal regardless of the\n // declared type. An explicitly-unset optional field (a form may emit `null`\n // rather than omitting the key) must not be coerced into an empty `{}` / `[]`\n // by the struct/list branches below - that would be a value the generated code\n // rejects (a struct missing its required keys, a non-array for a list).\n if (value === null || value === undefined) return d.null;\n const t = unwrap(type);\n switch (t.kind) {\n case \"struct\":\n return renderStructLiteral(value, t, indent, d);\n case \"union\":\n return renderUnion(value, t, indent, d);\n case \"list\":\n return renderList(value, t.item, indent, d);\n default:\n return renderPrimitive(value, d);\n }\n}\n","import type { BoundType } from \"../../bindings/index.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport type { SigEntry } from \"../sig-entries.js\";\nimport type { SnippetDialect, SnippetOptions } from \"../snippet-core.js\";\nimport { renderValue } from \"../snippet-core.js\";\nimport { buildEmitModel } from \"./python.js\";\nimport { pyStr } from \"./typemap.js\";\n\n/** Snippet rendering hooks for Python (dict literals, `True`/`None`). */\nconst pyDialect: SnippetDialect = {\n indentUnit: \" \",\n string: pyStr,\n boolean: (b) => (b ? \"True\" : \"False\"),\n number: (n) => (Number.isFinite(n) ? String(n) : \"float('nan')\"),\n null: \"None\",\n objKey: (k) => pyStr(k),\n};\n\n/**\n * Render a Python call snippet for one tool from a config object (the params\n * dict the form produces, keyed by Boutiques wire names).\n *\n * Struct-rooted tools use the ergonomic kwarg wrapper -\n * `fsl.bet(infile=..., fractional_intensity=0.5)` - whose keyword names are the\n * *scrubbed host* identifiers (`float` -> `float_`), not the wire keys; the\n * per-field mapping comes from the same `buildSigEntries` the generated wrapper\n * is built from, so the snippet matches the real signature. Nested structs /\n * union variants / lists-of-structs have no constructor in the generated code,\n * so they render as plain dict literals keyed by wire names.\n *\n * Union- (or otherwise non-struct-) rooted tools have no kwarg wrapper; the\n * single dict-style `<tool>` entry is called with one object-literal argument.\n *\n * The snippet matches the *standalone* (single-descriptor) emission of the same\n * context - which is how the hub compiles - not a catalog emission where a\n * shared package scope could suffix-bump a name.\n *\n * @param ctx - The compiled context (compile -> pipeline -> solve ->\n * resolveOutputs -> createContext, as in the CLI's `readAndCompile`).\n * @param config - The params object, keyed by Boutiques *wire* names (not host\n * identifiers). Every union-typed value - including the root of a union-rooted\n * tool - must carry its `@type` discriminator so the variant can be matched;\n * the root struct's `@type` is supplied by the renderer, so omit it there.\n * @param opts - Import and package-root options.\n */\nexport function renderPythonCall(\n ctx: CodegenContext,\n config: Record<string, unknown>,\n opts: SnippetOptions = {},\n): string {\n const model = buildEmitModel(ctx);\n const pkg = ctx.package?.name;\n const callee = pkg ? `${pkg}.${model.names.wrapper}` : model.names.wrapper;\n\n const call =\n model.rootIsStruct && model.rootType.kind === \"struct\"\n ? renderKwargCall(callee, model.sigEntries, model.rootType, config)\n : `${callee}(${renderValue(config, model.rootType, \"\", pyDialect)})`;\n\n if (opts.includeImport === false || !pkg) return call;\n const root = opts.packageRoot ?? ctx.project?.name;\n const importLine = root ? `from ${root} import ${pkg}` : `import ${pkg}`;\n return `${importLine}\\n\\n${call}`;\n}\n\n/** Render `callee(name=value, ...)` for a struct root using scrubbed kwarg names. */\nfunction renderKwargCall(\n callee: string,\n sigEntries: readonly SigEntry[],\n rootType: Extract<BoundType, { kind: \"struct\" }>,\n config: Record<string, unknown>,\n): string {\n const nameFor = new Map(sigEntries.map((e) => [e.wireKey, e.name]));\n const indent = pyDialect.indentUnit;\n const lines: string[] = [];\n for (const [wireKey, fieldType] of Object.entries(rootType.fields)) {\n if (fieldType.kind === \"literal\") continue; // @type / consts injected by the wrapper\n if (!(wireKey in config)) continue;\n const name = nameFor.get(wireKey) ?? wireKey;\n lines.push(`${indent}${name}=${renderValue(config[wireKey], fieldType, indent, pyDialect)},`);\n }\n if (lines.length === 0) return `${callee}()`;\n return `${callee}(\\n${lines.join(\"\\n\")}\\n)`;\n}\n","import type { Binding, BoundType, BoundVariant } from \"../../bindings/index.js\";\nimport type { Expr, ScalarKind } from \"../../ir/index.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport type { Backend, EmittedApp } from \"../backend.js\";\nimport { type OutputShape, collectOutputFields, streamFields } from \"../collect-output-fields.js\";\nimport { findDoc } from \"../find-doc.js\";\nimport { findStructNode } from \"../find-struct-node.js\";\nimport { resolveFieldBinding } from \"../resolve-field-binding.js\";\nimport { Scope } from \"../scope.js\";\nimport { snakeCase } from \"../string-case.js\";\n\nexport interface JsonSchema {\n type?: string | string[];\n items?: JsonSchema;\n properties?: Record<string, JsonSchema>;\n required?: string[];\n oneOf?: JsonSchema[];\n enum?: (string | number)[];\n const?: string | number;\n [key: string]: unknown;\n}\n\nclass SchemaBuilder {\n constructor(private ctx: CodegenContext) {}\n\n build(): JsonSchema {\n const envelope: JsonSchema = {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n };\n if (this.ctx.app?.doc?.title) envelope.title = this.ctx.app.doc.title;\n if (this.ctx.app?.doc?.description) envelope.description = this.ctx.app.doc.description;\n\n const rootBinding = this.ctx.resolve(this.ctx.expr);\n if (!rootBinding) return envelope;\n\n const schema = { ...envelope, ...this.fromBinding(rootBinding) };\n\n if (this.ctx.app?.id && schema.properties) {\n const pkg = this.ctx.package?.name ?? \"unknown\";\n schema.properties = {\n \"@type\": { const: `${pkg}/${this.ctx.app.id}` },\n ...schema.properties,\n };\n schema.required = [\"@type\", ...(schema.required ?? [])];\n }\n\n return schema;\n }\n\n private fromBinding(binding: Binding): JsonSchema {\n const schema = this.fromType(binding.type, binding.node);\n const meta = binding.node.meta;\n if (meta?.doc?.title) schema.title = meta.doc.title;\n if (meta?.doc?.description) schema.description = meta.doc.description;\n if (meta?.defaultValue !== undefined) schema.default = meta.defaultValue;\n return schema;\n }\n\n private fromType(type: BoundType, node?: Expr): JsonSchema {\n switch (type.kind) {\n case \"scalar\":\n return this.scalarSchema(type.scalar, node);\n case \"bool\":\n return { type: \"boolean\" };\n case \"count\":\n return { type: \"integer\", minimum: 0 };\n case \"literal\":\n return { const: type.value };\n case \"optional\":\n return this.fromType(type.inner, node?.kind === \"optional\" ? node.attrs.node : undefined);\n case \"list\": {\n const repeat = node?.kind === \"repeat\" ? node : undefined;\n const schema: JsonSchema = {\n type: \"array\",\n items: this.fromType(type.item, repeat?.attrs.node),\n };\n // Bounded/fixed-length vectors (e.g. a 3-element coordinate) carry length\n // constraints so a form consumer can render the right number of slots.\n if (repeat?.attrs.countMin !== undefined) schema.minItems = repeat.attrs.countMin;\n if (repeat?.attrs.countMax !== undefined) schema.maxItems = repeat.attrs.countMax;\n return schema;\n }\n case \"struct\":\n return this.structSchema(type, node);\n case \"union\":\n return this.unionSchema(type);\n }\n }\n\n private findTerminal(node: Expr): Expr {\n switch (node.kind) {\n case \"optional\":\n return this.findTerminal(node.attrs.node);\n case \"repeat\":\n return this.findTerminal(node.attrs.node);\n case \"sequence\": {\n const nonLiteral = node.attrs.nodes.find((n) => n.kind !== \"literal\");\n return nonLiteral ? this.findTerminal(nonLiteral) : node;\n }\n default:\n return node;\n }\n }\n\n private scalarSchema(scalar: ScalarKind, node?: Expr): JsonSchema {\n const base: JsonSchema = {\n int: { type: \"integer\" } as JsonSchema,\n float: { type: \"number\" } as JsonSchema,\n str: { type: \"string\" } as JsonSchema,\n path: { type: \"string\", \"x-styx-type\": \"path\" } as JsonSchema,\n }[scalar];\n\n const terminal = node ? this.findTerminal(node) : undefined;\n if (terminal && (terminal.kind === \"int\" || terminal.kind === \"float\")) {\n if (terminal.attrs.minValue !== undefined) base.minimum = terminal.attrs.minValue;\n if (terminal.attrs.maxValue !== undefined) base.maximum = terminal.attrs.maxValue;\n }\n\n return base;\n }\n\n private structSchema(type: Extract<BoundType, { kind: \"struct\" }>, node?: Expr): JsonSchema {\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n\n // Use shared findStructNode for correct traversal through opt/rep/alt wrappers\n const structNode = node ? findStructNode(node, this.ctx, type) : undefined;\n if (structNode) {\n for (const child of structNode.attrs.nodes) {\n // Use shared resolveFieldBinding for correct collapsed-sequence handling\n const match = resolveFieldBinding(child, this.ctx, type);\n if (!match) continue;\n const { binding, wrapperNode } = match;\n\n const schema = this.fromType(binding.type, binding.node);\n const fieldType = type.fields[binding.name]!;\n\n // Use shared findDoc for correct doc propagation through collapsed sequences\n const doc =\n findDoc(wrapperNode, fieldType) ??\n findDoc(binding.node, fieldType) ??\n wrapperNode.meta?.doc?.description;\n if (doc) schema.description = doc;\n\n const title = wrapperNode.meta?.doc?.title ?? binding.node.meta?.doc?.title;\n if (title) schema.title = title;\n\n const defaultValue = wrapperNode.meta?.defaultValue ?? binding.node.meta?.defaultValue;\n if (defaultValue !== undefined) schema.default = defaultValue;\n\n properties[binding.name] = schema;\n if (fieldType.kind !== \"optional\" && defaultValue === undefined) {\n required.push(binding.name);\n }\n }\n } else {\n for (const [name, fieldType] of Object.entries(type.fields)) {\n properties[name] = this.fromType(fieldType);\n if (fieldType.kind !== \"optional\") {\n required.push(name);\n }\n }\n }\n\n const schema: JsonSchema = { type: \"object\", properties };\n if (required.length > 0) schema.required = required;\n return schema;\n }\n\n private unionSchema(type: Extract<BoundType, { kind: \"union\" }>): JsonSchema {\n const allLiterals = type.variants.every((v: BoundVariant) => v.type.kind === \"literal\");\n if (allLiterals) {\n return {\n enum: type.variants.map((v: BoundVariant) =>\n v.type.kind === \"literal\" ? v.type.value : \"\",\n ),\n };\n }\n return { oneOf: type.variants.map((v: BoundVariant) => this.fromType(v.type)) };\n }\n}\n\nexport function generateSchema(ctx: CodegenContext): JsonSchema {\n return new SchemaBuilder(ctx).build();\n}\n\n/** Output names are language-neutral in the schema; key by the raw descriptor id. */\nconst rawName = (name: string): string => name;\n\n/** The JSON Schema for one output field, given its solved shape. */\nfunction outputFieldSchema(shape: OutputShape): JsonSchema {\n // A list output is always present (an empty array when nothing is produced),\n // its elements never null: `OutputPathType[]` / `list[OutputPathType]`.\n if (shape.kind === \"list\") {\n return { type: \"array\", items: { type: \"string\", \"x-styx-type\": \"path\" } };\n }\n // A single output's key is always present on the Outputs object; when its gate\n // is off the value is `null` (the backends type it `OutputPathType | None` /\n // `OutputPathType | null`). So a gated single is a path OR null - not an\n // absent key. We mark it `required` (see below) and carry the null branch.\n if (shape.optional) return { type: [\"string\", \"null\"], \"x-styx-type\": \"path\" };\n return { type: \"string\", \"x-styx-type\": \"path\" };\n}\n\n/**\n * JSON Schema for a tool's **Outputs object**: the set of files it produces\n * (resolved outputs + mutable inputs surfaced as outputs) plus its captured\n * stdout/stderr streams. Built from the same `collectOutputFields` /\n * `streamFields` source of truth the Python and TypeScript backends use to type\n * the Outputs dataclass/interface, so the three describe the same shape.\n *\n * Field encoding (mirrors how the language backends type each field):\n * - required single -> `{ type: \"string\", x-styx-type: \"path\" }`\n * - optional single -> `{ type: [\"string\", \"null\"], x-styx-type: \"path\" }`\n * - list output -> `{ type: \"array\", items: { type: \"string\", x-styx-type: \"path\" } }`\n * - stream field -> `{ type: \"array\", items: { type: \"string\" } }` (lines of\n * text, NOT paths - the absent `x-styx-type` lets a consumer tell them apart)\n *\n * EVERY field is `required`: unlike the inputs schema (where an optional param\n * key is genuinely omitted, so \"not in `required`\" is faithful), an Outputs\n * field is always present - a gated single is `null`, a gated list is an empty\n * array. So optionality is carried by the `null` type branch, and a strict\n * validator accepts the actual emitted object (e.g. `{ \"out_file\": null }`).\n */\nexport function generateOutputsSchema(ctx: CodegenContext): JsonSchema {\n const schema: JsonSchema = {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n };\n if (ctx.app?.doc?.title) schema.title = ctx.app.doc.title;\n if (ctx.app?.doc?.description) schema.description = ctx.app.doc.description;\n\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n\n for (const field of collectOutputFields(ctx, rawName)) {\n const prop = outputFieldSchema(field.shape);\n if (field.doc) prop.description = field.doc;\n properties[field.name] = prop;\n required.push(field.name);\n }\n\n for (const stream of streamFields(ctx, rawName)) {\n const prop: JsonSchema = { type: \"array\", items: { type: \"string\" } };\n if (stream.doc) prop.description = stream.doc;\n properties[stream.name] = prop;\n required.push(stream.name);\n }\n\n schema.properties = properties;\n if (required.length > 0) schema.required = required;\n return schema;\n}\n\n/**\n * Filesystem-safe, unique-within-the-package stem for one tool's schema files.\n *\n * In catalog mode every tool in a package emits into the same `<pkg>/` directory,\n * so fixed `schema.json` names would clobber each other (only the last tool would\n * survive). We prefix each tool's files with a slug derived from its app id -\n * `snakeCase` so symbol-heavy ids like `3dfim+` / `@2dwarper.Allin` become safe,\n * lowercase, collision-resistant stems (`3dfim` / `2dwarper_allin`) - and dedup\n * through the shared package `scope` so the rare slug collision still gets a `_2`.\n *\n * Returns undefined when there is no scope (standalone single-tool emission, where\n * one unprefixed `schema.json` is unambiguous) or no app id (anonymous descriptor).\n */\nfunction schemaStem(ctx: CodegenContext, scope?: Scope): string | undefined {\n const id = ctx.app?.id;\n if (!id || !scope) return undefined;\n return scope.add(snakeCase(id) || \"schema\");\n}\n\nexport class JsonSchemaBackend implements Backend {\n readonly name = \"json-schema\";\n readonly target = \"json-schema\";\n\n /** One scope per package so per-tool schema file stems stay unique in the suite directory. */\n newPackageScope(): Scope {\n return new Scope();\n }\n\n emitApp(ctx: CodegenContext, scope?: Scope): EmittedApp {\n const schema = generateSchema(ctx);\n const outputsSchema = generateOutputsSchema(ctx);\n // In a catalog build, prefix with a per-tool stem so co-located tools don't\n // clobber one another; standalone single-tool builds keep the bare names.\n const stem = schemaStem(ctx, scope);\n const prefix = stem ? `${stem}.` : \"\";\n return {\n meta: ctx.app,\n // Inputs and outputs are kept as two cleanly addressable artifacts\n // (mirroring v1's `<tool>.input.json` / `<tool>.output.json` split): a\n // consumer can fetch/compute either independently.\n files: new Map([\n [`${prefix}schema.json`, JSON.stringify(schema, null, 2)],\n [`${prefix}outputs.schema.json`, JSON.stringify(outputsSchema, null, 2)],\n ]),\n errors: [],\n warnings: [],\n };\n }\n}\n","import type { BoundType } from \"../../bindings/index.js\";\n\nexport function mapType(type: BoundType, resolve: (type: BoundType) => string | undefined): string {\n switch (type.kind) {\n case \"scalar\":\n return { int: \"number\", float: \"number\", str: \"string\", path: \"InputPathType\" }[type.scalar];\n case \"bool\":\n return \"boolean\";\n case \"count\":\n return \"number\";\n case \"literal\":\n return typeof type.value === \"string\" ? JSON.stringify(type.value) : String(type.value);\n case \"optional\":\n // The solver has no nullable type: `optional` means \"omittable\" (the key\n // may be absent), never \"the value may be null\". Omittability is expressed\n // structurally at the field level (`?:` on the interface key, NotRequired\n // in Python); the value type itself is just the inner type. So in any\n // value position (nested list/union arm, validator messages) we render the\n // inner type with no `| null | undefined`.\n return mapType(type.inner, resolve);\n case \"list\": {\n const inner = mapType(type.item, resolve);\n return inner.includes(\"|\") ? `Array<${inner}>` : `${inner}[]`;\n }\n case \"struct\": {\n const name = resolve(type);\n if (name) return name;\n const fields = Object.entries(type.fields)\n .filter(([, v]) => v.kind !== \"literal\")\n .map(([k, v]) => `${k}: ${mapType(v, resolve)}`)\n .join(\"; \");\n return `{ ${fields} }`;\n }\n case \"union\": {\n const name = resolve(type);\n if (name) return name;\n return type.variants.map((v) => mapType(v.type, resolve)).join(\" | \");\n }\n }\n}\n\n/** Render a JS default value as a TypeScript literal (signatures, `?? default`). */\nexport function renderTsLiteral(value: string | number | boolean): string {\n if (typeof value === \"boolean\") return value ? \"true\" : \"false\";\n if (typeof value === \"number\") return Number.isFinite(value) ? String(value) : \"NaN\";\n return JSON.stringify(value);\n}\n","import type { ProjectMeta } from \"../../manifest/index.js\";\nimport type { EmittedPackage } from \"../backend.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport { Scope } from \"../scope.js\";\nimport { STYXDEFS_COMPAT } from \"../styxdefs-compat.js\";\n\n// JS keywords that are illegal as the binding name in `export * as <name>`\n// (`default` is intentionally allowed - it is valid there).\nconst NS_RESERVED = [\n \"import\",\n \"export\",\n \"class\",\n \"function\",\n \"const\",\n \"let\",\n \"var\",\n \"return\",\n \"new\",\n \"delete\",\n \"typeof\",\n \"void\",\n \"in\",\n \"instanceof\",\n \"enum\",\n \"extends\",\n \"super\",\n];\n\nfunction description(proj: ProjectMeta): string {\n if (proj.doc?.description) return proj.doc.description;\n return `Styx generated wrappers for ${proj.doc?.title ?? proj.name ?? \"tools\"}.`;\n}\n\n/** npm names must be lowercase and URL-safe; normalize or fall back. */\nfunction npmName(name: string | undefined): string {\n const normalized = (name ?? \"\")\n .toLowerCase()\n .replace(/[^a-z0-9-._]/g, \"-\")\n .replace(/^[-._]+/, \"\");\n return normalized || \"styx-wrappers\";\n}\n\n/**\n * Single npm `package.json` for the whole project (TypeScript ships one package\n * spanning all suites, unlike Python's per-suite distributions). The styxdefs\n * floor is baked in as the lone runtime dependency.\n */\nexport function generatePackageJson(proj: ProjectMeta): string {\n const pkg = {\n name: npmName(proj.name),\n version: proj.version ?? \"0.0.0\",\n description: description(proj),\n type: \"module\",\n types: \"./dist/index.d.ts\",\n main: \"./dist/index.js\",\n exports: {\n \".\": {\n types: \"./dist/index.d.ts\",\n import: \"./dist/index.js\",\n },\n },\n files: [\"dist\"],\n scripts: {\n build: \"tsc\",\n prepublishOnly: \"npm run build\",\n },\n license: proj.license?.description ?? \"unknown\",\n dependencies: {\n styxdefs: STYXDEFS_COMPAT.npm,\n },\n devDependencies: {\n typescript: \"^5.6.0\",\n },\n };\n return JSON.stringify(pkg, null, 2) + \"\\n\";\n}\n\n/** Turn a suite directory name into a valid JS namespace identifier. */\nfunction nsIdent(name: string): string {\n const cleaned = name.replace(/[^a-zA-Z0-9_$]/g, \"_\");\n return /^[0-9]/.test(cleaned) ? `_${cleaned}` : cleaned;\n}\n\n/**\n * Root barrel namespacing each per-suite `index.ts` by suite\n * (`export * as afni from \"./afni/index.js\"`). Namespacing avoids cross-suite\n * collisions when the same tool id appears in two suites, and keeps the root\n * from flattening every tool into one giant namespace.\n */\nexport function generateRootIndex(packages: EmittedPackage[]): string {\n const cb = new CodeBuilder(\" \");\n cb.comment(\"This file was auto generated by Styx.\");\n cb.comment(\"Do not edit this file directly.\");\n cb.blank();\n\n const dirs = packages\n .map((p) => p.meta?.name)\n .filter((name): name is string => !!name)\n .sort();\n\n // Dodge namespace collisions (two dirs cleaning to the same identifier, or a\n // dir named like a keyword) the same way per-tool names are dodged.\n const nsScope = new Scope(NS_RESERVED);\n for (const dir of dirs) {\n const ns = nsScope.add(nsIdent(dir));\n cb.line(`export * as ${ns} from \"./${dir}/index.js\";`);\n }\n\n return cb.toString() + \"\\n\";\n}\n\n/** Minimal `tsconfig.json` producing ESM + declarations into `dist/`. */\nexport function generateTsconfig(): string {\n const config = {\n compilerOptions: {\n target: \"ES2020\",\n module: \"NodeNext\",\n moduleResolution: \"NodeNext\",\n declaration: true,\n outDir: \"./dist\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n forceConsistentCasingInFileNames: true,\n },\n include: [\"**/*.ts\"],\n exclude: [\"dist\", \"node_modules\"],\n };\n return JSON.stringify(config, null, 2) + \"\\n\";\n}\n","import type { Binding, BindingId, BoundType, BoundVariant } from \"../../bindings/index.js\";\nimport { collectFieldInfo } from \"../collect-field-info.js\";\nimport type { Expr } from \"../../ir/index.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport { structVariants } from \"../union-variants.js\";\nimport { renderAccess } from \"./emit.js\";\nimport { renderTsLiteral } from \"./typemap.js\";\n\n// -- Result types --\n\ninterface Expr_ {\n expr: string;\n}\ninterface Stmt {\n stmt: string;\n}\nexport type ArgResult = Expr_ | Stmt;\n\nfunction isExpr(r: ArgResult): r is Expr_ {\n return \"expr\" in r;\n}\n\nexport function resultToStmt(r: ArgResult): string {\n return isExpr(r) ? `cargs.push(${r.expr});` : r.stmt;\n}\n\nfunction appendLines(cb: CodeBuilder, code: string): void {\n for (const line of code.split(\"\\n\")) cb.line(line);\n}\n\n// -- Type helpers --\n\nfunction toStringExpr(node: Expr, type: BoundType, expr: string): string {\n if (type.kind === \"scalar\") {\n if (type.scalar === \"str\") return expr;\n if (type.scalar === \"path\") return pathArg(node, expr);\n }\n return `String(${expr})`;\n}\n\n/**\n * Command-line value for a path input via `execution.inputFile`. The styxdefs\n * signature is `inputFile(hostFile, resolveParent?, mutable?)`, so `mutable`\n * requires supplying `resolveParent` positionally first. `mutable=true` tells\n * the runner to stage a writable COPY (original untouched) and return the copy's\n * command-line path; the outputs builder surfaces that same copy's host path via\n * `execution.mutableCopy`.\n */\nfunction pathArg(node: Expr, expr: string): string {\n if (node.kind !== \"path\") return `execution.inputFile(${expr})`;\n const { resolveParent, mutable } = node.attrs;\n if (mutable) return `execution.inputFile(${expr}, ${resolveParent ? \"true\" : \"false\"}, true)`;\n if (resolveParent) return `execution.inputFile(${expr}, true)`;\n return `execution.inputFile(${expr})`;\n}\n\n// -- Context passed down through recursion --\n\ninterface ArgContext {\n /** Join nesting depth (controls ternary vs if-statement for optionals). */\n joinDepth: number;\n /**\n * Loop variables bound by enclosing `repeat`-of-list nodes, keyed by the\n * repeat binding's id. `renderAccess` consults this to resolve the `iter`\n * segments in a binding's solver-assigned access path.\n */\n loopVars: ReadonlyMap<BindingId, string>;\n /**\n * Rendered TS default literals for root-level NON-OPTIONAL fields that carry a\n * Boutiques default (e.g. `maskfile -> \"img_bet\"`), keyed by field name. Such a\n * field is `?:` (a hand-authored config may omit it) yet is read\n * unconditionally - so every read of its value becomes `(access ?? <default>)`\n * to substitute the default instead of stringifying `undefined`. Optional\n * fields are excluded: they are presence-guarded (their default, if any, comes\n * from the factory's kwarg signature).\n */\n defaults: ReadonlyMap<string, string>;\n}\n\n/** Render a binding's solver-assigned access path in the current loop scope. */\nfunction accessOf(binding: Binding, arg: ArgContext): string {\n return renderAccess(binding.access, (b) => {\n const v = arg.loopVars.get(b);\n if (v === undefined) throw new Error(`arg-builder: unbound loop variable for binding ${b}`);\n return v;\n });\n}\n\n/**\n * The rendered default for a binding iff it is a root-level NON-OPTIONAL field\n * carrying a Boutiques default. Restricted to single-segment (root) field access\n * so a nested field can never accidentally pick up a same-named root default.\n */\nfunction rootFieldDefault(\n binding: Binding,\n defaults: ReadonlyMap<string, string>,\n): string | undefined {\n const a = binding.access;\n if (a.length === 1 && a[0]?.kind === \"field\") return defaults.get(binding.name);\n return undefined;\n}\n\n/**\n * Render a binding's access for an UNCONDITIONAL value read (terminal, repeat\n * loop, alternative dispatch): substitutes the field's default via\n * `(access ?? default)` when it is a defaulted non-optional field, else the\n * plain access. Returns plain access for every non-defaulted field, so the\n * emitted code is byte-identical to before for the common case.\n */\nfunction readAccess(binding: Binding, arg: ArgContext): string {\n const def = rootFieldDefault(binding, arg.defaults);\n return def !== undefined ? `(${accessOf(binding, arg)} ?? ${def})` : accessOf(binding, arg);\n}\n\n/** Build the field-name -> rendered-default map for a struct root (else empty).\n * Includes only non-optional defaulted fields (optional fields are\n * presence-guarded; their default comes from the factory's kwarg signature). */\nfunction collectDefaults(ctx: CodegenContext, rootType?: BoundType): Map<string, string> {\n const out = new Map<string, string>();\n if (rootType?.kind !== \"struct\") return out;\n for (const [name, fi] of collectFieldInfo(ctx, rootType)) {\n if (fi.defaultValue === undefined) continue;\n if (rootType.fields[name]?.kind === \"optional\") continue;\n out.set(name, renderTsLiteral(fi.defaultValue));\n }\n return out;\n}\n\n// -- Recursive descent --\n\nlet loopVarCounter = 0;\n\n/**\n * Build arg-building code for an IR tree via recursive descent.\n *\n * Context flows down via the immutable `arg` parameter (access paths, join depth, etc.).\n * Results flow up via return values (expressions or statement blocks).\n */\nexport function buildArgs(rootExpr: Expr, ctx: CodegenContext, rootType?: BoundType): ArgResult {\n loopVarCounter = 0;\n const initialCtx: ArgContext = {\n joinDepth: 0,\n loopVars: new Map(),\n defaults: collectDefaults(ctx, rootType),\n };\n return walk(rootExpr, ctx, initialCtx);\n}\n\nfunction walk(node: Expr, ctx: CodegenContext, arg: ArgContext): ArgResult {\n switch (node.kind) {\n case \"literal\":\n return { expr: JSON.stringify(node.attrs.str) };\n\n case \"int\":\n case \"float\":\n case \"str\":\n case \"path\":\n return walkTerminal(node, ctx, arg);\n\n case \"sequence\":\n return walkSequence(node, ctx, arg);\n\n case \"optional\":\n return walkOptional(node, ctx, arg);\n\n case \"repeat\":\n return walkRepeat(node, ctx, arg);\n\n case \"alternative\":\n return walkAlternative(node, ctx, arg);\n }\n}\n\nfunction walkTerminal(node: Expr, ctx: CodegenContext, arg: ArgContext): ArgResult {\n const binding = ctx.resolve(node);\n if (!binding) throw new Error(`Missing binding for terminal node: ${node.kind}`);\n // A root-level defaulted field (e.g. an output basename `maskfile=\"img_bet\"`)\n // is read here unconditionally but is `?:`, so `readAccess` substitutes the\n // default for an absent key via `(access ?? default)`.\n return { expr: toStringExpr(node, binding.type, readAccess(binding, arg)) };\n}\n\nfunction walkSequence(\n node: Extract<Expr, { kind: \"sequence\" }>,\n ctx: CodegenContext,\n arg: ArgContext,\n): ArgResult {\n // A non-join sequence inside an outer join must concatenate (rather than\n // push separate args) so it can stand in as a single Expr element of the\n // outer join. Boutiques produces this shape for `command-line-flag` inputs\n // nested under a parent join template (e.g. `[OUTPUT][FLAG]` -> seqJoin('')\n // around an opt(seq(lit(FLAG), value))).\n const join = node.attrs.join ?? (arg.joinDepth > 0 ? \"\" : undefined);\n\n // Struct scoping is already baked into each child's access path by the\n // solver; here we only thread join depth (a codegen concern).\n const childArg: ArgContext = join !== undefined ? { ...arg, joinDepth: arg.joinDepth + 1 } : arg;\n\n const parts = node.attrs.nodes.map((child) => walk(child, ctx, childArg));\n\n if (join !== undefined) {\n const exprs = parts.map((p) => (isExpr(p) ? p.expr : p.stmt));\n if (exprs.length === 1) return { expr: exprs[0]! };\n return { expr: `[${exprs.join(\", \")}].join(${JSON.stringify(join)})` };\n }\n\n return { stmt: parts.map(resultToStmt).join(\"\\n\") };\n}\n\nfunction walkOptional(\n node: Extract<Expr, { kind: \"optional\" }>,\n ctx: CodegenContext,\n arg: ArgContext,\n): ArgResult {\n const binding = ctx.resolve(node);\n if (!binding) throw new Error(\"Missing binding for optional node\");\n const access = accessOf(binding, arg);\n\n // The inner node's access path is solver-assigned (it either inherits this\n // optional's path on a collapse, or scopes into it for a struct), so no scope\n // context needs threading - only the existing loop scope and join depth.\n const inner = walk(node.attrs.node, ctx, arg);\n\n // Inside a join context, emit as ternary expression\n if (arg.joinDepth > 0 && isExpr(inner)) {\n if (binding.type.kind === \"optional\") {\n return { expr: `(${access} != null ? ${inner.expr} : \"\")` };\n }\n return { expr: `(${access} ? ${inner.expr} : \"\")` };\n }\n\n const cb = new CodeBuilder(\" \");\n const innerStmt = resultToStmt(inner);\n if (binding.type.kind === \"optional\") {\n cb.line(`if (${access} != null) {`);\n cb.indent(() => appendLines(cb, innerStmt));\n cb.line(\"}\");\n } else {\n cb.line(`if (${access}) {`);\n cb.indent(() => appendLines(cb, innerStmt));\n cb.line(\"}\");\n }\n return { stmt: cb.toString() };\n}\n\nfunction walkRepeat(\n node: Extract<Expr, { kind: \"repeat\" }>,\n ctx: CodegenContext,\n arg: ArgContext,\n): ArgResult {\n const binding = ctx.resolve(node);\n if (!binding) throw new Error(\"Missing binding for repeat node\");\n // A non-join repeat inside an outer join concatenates rather than pushing\n // separate args, mirroring walkSequence's handling of bare non-join seqs.\n const join = node.attrs.join ?? (arg.joinDepth > 0 ? \"\" : undefined);\n // Unconditional read (the count/list value) - `readAccess` substitutes a\n // defaulted non-optional field's default for an absent key.\n const access = readAccess(binding, arg);\n\n // Count repeat: emit a counted for-loop. Inside a join the for-loop would\n // be dropped into a list literal as raw text, so emit `Array.from` instead.\n if (binding.type.kind === \"count\") {\n const inner = walk(node.attrs.node, ctx, arg);\n const v = `i${loopVarCounter++}`;\n if (join !== undefined && isExpr(inner)) {\n return {\n expr: `Array.from({length: ${access}}, (_, ${v}) => ${inner.expr}).join(${JSON.stringify(join)})`,\n };\n }\n const cb = new CodeBuilder(\" \");\n cb.line(`for (let ${v} = 0; ${v} < ${access}; ${v}++) {`);\n cb.indent(() => appendLines(cb, resultToStmt(inner)));\n cb.line(\"}\");\n return { stmt: cb.toString() };\n }\n\n // List repeat: emit a for-of loop or .map().join(). The loop variable is\n // registered under this repeat's binding id so inner bindings' `iter`\n // segments resolve to it via `renderAccess`.\n const loopVar = `item${loopVarCounter++}`;\n const childArg: ArgContext = {\n ...arg,\n loopVars: new Map(arg.loopVars).set(binding.id, loopVar),\n };\n\n const inner = walk(node.attrs.node, ctx, childArg);\n\n if (join !== undefined && isExpr(inner)) {\n return { expr: `${access}.map((${loopVar}) => ${inner.expr}).join(${JSON.stringify(join)})` };\n }\n\n const cb = new CodeBuilder(\" \");\n cb.line(`for (const ${loopVar} of ${access}) {`);\n cb.indent(() => appendLines(cb, resultToStmt(inner)));\n cb.line(\"}\");\n return { stmt: cb.toString() };\n}\n\nfunction walkAlternative(\n node: Extract<Expr, { kind: \"alternative\" }>,\n ctx: CodegenContext,\n arg: ArgContext,\n): ArgResult {\n const binding = ctx.resolve(node);\n if (!binding) throw new Error(\"Missing binding for alternative node\");\n // Unconditional read (the enum value / bool guard / union discriminator) -\n // `readAccess` substitutes a defaulted non-optional field's default for an\n // absent key (e.g. a `value-choices` String with a default).\n const access = readAccess(binding, arg);\n\n // Complex-union variant fields already carry the union's path in their\n // solver-assigned access, so arms walk with the current context unchanged.\n const variants = node.attrs.alts.map((alt) => walk(alt, ctx, arg));\n\n if (\n binding.type.kind === \"union\" &&\n binding.type.variants.every((v: BoundVariant) => v.type.kind === \"literal\")\n ) {\n return { expr: `String(${access})` };\n }\n\n if (binding.type.kind === \"bool\") {\n // Inside a join, the alternative's output must be an expression, not a\n // statement: dropping an `if/else` block into a `[...].join(\"\")` list\n // literal is not valid TypeScript. Emit a ternary when both arms are exprs.\n if (arg.joinDepth > 0) {\n if (!variants[1]) {\n throw new Error(\n \"single-arm bool alternative inside a join: cannot produce an expression \" +\n \"without ambiguous semantics (omitting the entry vs emitting empty string)\",\n );\n }\n if (!variants.every(isExpr)) {\n throw new Error(\n \"bool alternative inside a join has statement-shaped variants; \" +\n \"expected all arms to fold to expressions\",\n );\n }\n const v0 = (variants[0] as Expr_).expr;\n const v1 = (variants[1] as Expr_).expr;\n return { expr: `(${access} ? ${v0} : ${v1})` };\n }\n const cb = new CodeBuilder(\" \");\n cb.line(`if (${access}) {`);\n cb.indent(() => appendLines(cb, resultToStmt(variants[0]!)));\n if (variants[1]) {\n cb.line(\"} else {\");\n cb.indent(() => appendLines(cb, resultToStmt(variants[1]!)));\n }\n cb.line(\"}\");\n return { stmt: cb.toString() };\n }\n\n if (binding.type.kind === \"union\") {\n const unionType = binding.type;\n // A union may be pure-discriminated (every variant a struct with `@type`) or\n // mixed (struct variants plus bare-literal variants, e.g. ants\n // `Interpolation = \"Linear\" | MultiLabel | ...`). Pure-enum unions returned\n // above. Dispatch struct variants on `@type`; a bare literal is its own value.\n // `structVariants` throws if two share an `@type` (an unreachable, dead\n // branch - frontends must dodge duplicate tags before codegen).\n const structVars = structVariants(unionType);\n const hasLiteral = unionType.variants.some((v) => v.type.kind === \"literal\");\n\n // Inside a join: chained ternary, same reason as bool above.\n if (arg.joinDepth > 0) {\n if (!variants.every(isExpr)) {\n throw new Error(\n \"union alternative inside a join has statement-shaped variants; \" +\n \"expected all arms to fold to expressions\",\n );\n }\n let structExpr = '\"\"';\n for (let k = structVars.length - 1; k >= 0; k--) {\n const { variant, i } = structVars[k]!;\n const v = (variants[i] as Expr_).expr;\n structExpr = `(${access}[\"@type\"] === ${JSON.stringify(variant.name ?? \"\")} ? ${v} : ${structExpr})`;\n }\n if (!hasLiteral) return { expr: structExpr };\n // Mixed: an object value dispatches by `@type`; a bare literal is itself.\n return {\n expr: `(typeof ${access} === \"object\" && ${access} !== null ? ${structExpr} : String(${access}))`,\n };\n }\n\n const cb = new CodeBuilder(\" \");\n // `switch` (not an `if`/`else if` ===-chain): each `case` narrows the\n // discriminated union, whereas a chain accumulates narrowing and TS rejects\n // later arms (TS2367).\n const emitStructSwitch = (): void => {\n cb.line(`switch (${access}[\"@type\"]) {`);\n cb.indent(() => {\n for (const { variant, i } of structVars) {\n cb.line(`case ${JSON.stringify(variant.name ?? \"\")}: {`);\n cb.indent(() => {\n appendLines(cb, resultToStmt(variants[i]!));\n cb.line(\"break;\");\n });\n cb.line(\"}\");\n }\n });\n cb.line(\"}\");\n };\n if (!hasLiteral) {\n emitStructSwitch();\n return { stmt: cb.toString() };\n }\n // Mixed union: branch on runtime shape. `typeof === \"object\"` narrows to the\n // struct variants; the `else` to the bare-literal members.\n cb.line(`if (typeof ${access} === \"object\" && ${access} !== null) {`);\n cb.indent(emitStructSwitch);\n cb.line(`} else {`);\n cb.indent(() => appendLines(cb, resultToStmt({ expr: `String(${access})` })));\n cb.line(`}`);\n return { stmt: cb.toString() };\n }\n\n return { stmt: variants.map(resultToStmt).join(\"\\n\") };\n}\n","import type { AccessPath, BindingId, BoundType } from \"../../bindings/index.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport type { SigEntry, SigOptions } from \"../sig-entries.js\";\nimport type { ArgResult } from \"./arg-builder.js\";\nimport { buildArgs, resultToStmt } from \"./arg-builder.js\";\nimport { mapType, renderTsLiteral } from \"./typemap.js\";\nimport type { NamedType } from \"./types.js\";\nimport { collectFieldInfo, resolveTypeName } from \"./types.js\";\n\nexport function emitJsDoc(cb: CodeBuilder, description?: string): void {\n if (!description) return;\n const lines = description.split(\"\\n\");\n if (lines.length === 1) {\n cb.line(`/** ${lines[0]} */`);\n } else {\n cb.line(\"/**\");\n for (const line of lines) {\n cb.line(` * ${line}`);\n }\n cb.line(\" */\");\n }\n}\n\nexport function emitImports(cb: CodeBuilder, emitOutputs: boolean): void {\n const inputs = [\"Runner\", \"Execution\", \"Metadata\", \"InputPathType\"];\n if (emitOutputs) inputs.push(\"OutputPathType\");\n cb.line(`import type { ${inputs.join(\", \")} } from \"styxdefs\";`);\n cb.line('import { getGlobalRunner, StyxValidationError } from \"styxdefs\";');\n}\n\nexport function emitMetadata(ctx: CodegenContext, metaConst: string, cb: CodeBuilder): void {\n const id = ctx.app?.id ?? \"unknown\";\n const name = ctx.app?.doc?.title ?? ctx.app?.id ?? \"unknown\";\n const pkg = ctx.package?.name ?? \"unknown\";\n\n cb.line(`export const ${metaConst}: Metadata = {`);\n cb.indent(() => {\n cb.line(`id: ${JSON.stringify(id)},`);\n cb.line(`name: ${JSON.stringify(name)},`);\n cb.line(`package: ${JSON.stringify(pkg)},`);\n if (ctx.app?.doc?.literature?.length) {\n cb.line(`citations: ${JSON.stringify(ctx.app.doc.literature)},`);\n }\n if (ctx.app?.container?.image) {\n cb.line(`container_image_tag: ${JSON.stringify(ctx.app.container.image)},`);\n }\n });\n cb.line(\"};\");\n}\n\nexport function emitTypeDeclarations(\n typeDecls: NamedType[],\n namedTypes: Map<string, string>,\n ctx: CodegenContext,\n rootName: string,\n appId: string | undefined,\n pkg: string,\n cb: CodeBuilder,\n): void {\n const resolve = resolveTypeName(namedTypes);\n\n for (const { name, type } of typeDecls) {\n const isRoot = name === rootName;\n\n if (type.kind === \"struct\") {\n const fieldInfo = collectFieldInfo(ctx, type);\n\n cb.line(`export interface ${name} {`);\n cb.indent(() => {\n // @type discriminator on root params interface. Optional: the params\n // factory always sets it and runtime dispatch tables read it, but the\n // type system doesn't need it required (there's only one shape). Union\n // variants below keep their @type required - that one IS load-bearing\n // for discriminated-union narrowing.\n if (isRoot && appId) {\n cb.line(`\"@type\"?: \"${pkg}/${appId}\";`);\n }\n\n for (const [fieldName, fieldType] of Object.entries(type.fields)) {\n // Emit literal @type discriminators on union variant structs\n if (fieldType.kind === \"literal\") {\n if (fieldName === \"@type\") {\n cb.line(`\"@type\": ${JSON.stringify(fieldType.value)};`);\n }\n continue;\n }\n const fi = fieldInfo.get(fieldName);\n emitJsDoc(cb, fi?.doc);\n\n const isOptional = fieldType.kind === \"optional\";\n // A field is omittable (key may be absent) iff it is `optional` or it\n // carries a default (which includes flags - their `defaultValue` is\n // false). The default/absent case is handled by the params factory and\n // the absence-safe runtime reads; the type only needs to permit the key\n // to be missing. Never `| null`: the solver has no nullable, so a\n // present value is never null - omittability is the only \"unset\".\n const omittable = isOptional || fi?.defaultValue !== undefined;\n const optional = omittable ? \"?\" : \"\";\n\n const mapped = isOptional\n ? mapType(fieldType.inner, resolve)\n : mapType(fieldType, resolve);\n // Quote keys that aren't valid identifiers (e.g. `4d_input`). TS\n // allows reserved-word identifiers as interface keys without quotes.\n cb.line(`${tsObjKey(fieldName)}${optional}: ${mapped};`);\n }\n });\n cb.line(\"}\");\n cb.blank();\n } else if (type.kind === \"union\") {\n const parts = type.variants.map((v) => mapType(v.type, resolve));\n cb.line(`export type ${name} = ${parts.join(\" | \")};`);\n cb.blank();\n }\n }\n}\n\nexport function emitBuildCargs(\n ctx: CodegenContext,\n rootType: BoundType,\n paramsType: string,\n funcName: string,\n cb: CodeBuilder,\n): void {\n const paramsVar = \"params\";\n\n let result: ArgResult;\n try {\n result = buildArgs(ctx.expr, ctx, rootType);\n } catch {\n emitJsDoc(cb, \"Build command-line arguments from parameters.\");\n cb.line(\n `export function ${funcName}(_${paramsVar}: ${paramsType}, _execution: Execution): string[] {`,\n );\n cb.indent(() => cb.line(\"return [];\"));\n cb.line(\"}\");\n return;\n }\n\n const argsCode = resultToStmt(result);\n\n emitJsDoc(cb, \"Build command-line arguments from parameters.\");\n cb.line(\n `export function ${funcName}(${paramsVar}: ${paramsType}, execution: Execution): string[] {`,\n );\n cb.indent(() => {\n cb.line(\"const cargs: string[] = [];\");\n for (const line of argsCode.split(\"\\n\")) {\n if (line.trim()) cb.line(line);\n }\n cb.line(\"return cargs;\");\n });\n cb.line(\"}\");\n}\n\n/**\n * SigOptions hooks for TypeScript. The kwarg-signature sentinel for an optional\n * param is `T | null = null` - here `| null` is the *parameter* type (the\n * \"not provided\" sentinel a caller passes), not the dict field type, which is\n * just `T?`. Keeping the sentinel keeps the ergonomic `foo(x)` call where\n * omitted optionals default to `null` and the factory then drops them.\n */\nexport function tsSigOptions(resolve: (t: BoundType) => string | undefined): SigOptions {\n return {\n renderType: (t) => mapType(t, resolve),\n nullableSuffix: \" | null\",\n nullableDefault: \"null\",\n renderDefault: renderTsLiteral,\n };\n}\n\n/**\n * Scrub a Boutiques wire name into a valid TypeScript host identifier.\n * Mirrors Python's scrub: non-`[A-Za-z0-9_$]` replaced with `_`, digit\n * prefixes get `v_`, reserved-word matches get a trailing `_`. Dedupe through\n * a `Scope` for collisions with already-registered locals.\n */\nexport function tsScrubIdent(name: string, reserved: ReadonlySet<string>): string {\n let scrubbed = name.replace(/[^A-Za-z0-9_$]/g, \"_\");\n if (/^[0-9]/.test(scrubbed)) scrubbed = \"v_\" + scrubbed;\n if (scrubbed === \"\") scrubbed = \"_\";\n if (reserved.has(scrubbed)) scrubbed = scrubbed + \"_\";\n return scrubbed;\n}\n\nconst TS_IDENT_RE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\n/**\n * Render a TypeScript property access path. Uses dot notation when the key is\n * a valid identifier, bracket notation otherwise. (Wire keys like `4d_input`\n * or `@type` can't be dot-accessed.)\n */\nexport function tsPropAccess(base: string, key: string): string {\n return TS_IDENT_RE.test(key) ? `${base}.${key}` : `${base}[${JSON.stringify(key)}]`;\n}\n\n/**\n * Render a solver-assigned `AccessPath` to a TypeScript expression. Starts from\n * `params`; each `field` segment descends a property, and each `iter` segment\n * resets the base to the loop variable bound to that repeat binding (resolved\n * via `lookupLoopVar` - the `iter` gate atom's loop in outputs codegen, or the\n * arg-builder's local loop). Both the arg-builder and the outputs emitter feed\n * this one function instead of re-deriving paths.\n */\nexport function renderAccess(\n path: AccessPath,\n lookupLoopVar: (binding: BindingId) => string,\n): string {\n let cur = \"params\";\n for (const seg of path) {\n cur = seg.kind === \"field\" ? tsPropAccess(cur, seg.name) : lookupLoopVar(seg.binding);\n }\n return cur;\n}\n\n/**\n * Render a TypeScript object-literal key. Bare ident when valid, quoted\n * otherwise. (`name: ...` for `name`, `\"4d_input\": ...` for `4d_input`.)\n */\nexport function tsObjKey(key: string): string {\n return TS_IDENT_RE.test(key) ? key : JSON.stringify(key);\n}\n\n/** Emit `name: type [= default],` lines (one per entry) into `cb`. */\nfunction emitSigParams(entries: readonly SigEntry[], cb: CodeBuilder): void {\n for (const e of entries) {\n if (e.sigDefault !== undefined) {\n cb.line(`${e.name}: ${e.sigType} = ${e.sigDefault},`);\n } else {\n cb.line(`${e.name}: ${e.sigType},`);\n }\n }\n}\n\n/** Emit `@param <name> <doc>` JSDoc lines (trimmed empty docs) for each entry. */\nfunction emitJsDocParams(\n entries: readonly { name: string; doc?: string }[],\n cb: CodeBuilder,\n): void {\n for (const e of entries) {\n cb.line(` * @param ${e.name} ${e.doc ?? \"\"}`.trimEnd());\n }\n}\n\n/**\n * Emit the `<tool>Params(...)` factory: a kwarg-style builder for the params\n * object. Non-optional fields (required, and defaulted scalars whose default\n * lives on the signature) are always set in the literal. Every optional field is\n * set conditionally when not null - including optional-with-default ones: their\n * value type is `T | null` (the omit sentinel) but the dict field is the\n * non-null `T?`, so a bare literal assignment of a possibly-null value would not\n * type-check. When the caller omits the arg, the signature default (a concrete\n * non-null value) flows through the guard and is written.\n */\nexport function emitParamsFactory(\n entries: readonly SigEntry[],\n funcName: string,\n paramsType: string,\n typeTag: string | undefined,\n cb: CodeBuilder,\n): void {\n // JSDoc\n cb.line(\"/**\");\n cb.line(\" * Build parameters.\");\n if (entries.length > 0) cb.line(\" *\");\n emitJsDocParams(entries, cb);\n cb.line(\" *\");\n cb.line(\" * @returns Parameter object.\");\n cb.line(\" */\");\n\n if (entries.length === 0) {\n cb.line(`export function ${funcName}(): ${paramsType} {`);\n } else {\n cb.line(`export function ${funcName}(`);\n cb.indent(() => emitSigParams(entries, cb));\n cb.line(`): ${paramsType} {`);\n }\n cb.indent(() => {\n cb.line(`const params: ${paramsType} = {`);\n cb.indent(() => {\n if (typeTag !== undefined) cb.line(`\"@type\": ${JSON.stringify(typeTag)},`);\n for (const e of entries) {\n if (!e.isOptional) {\n cb.line(`${tsObjKey(e.wireKey)}: ${e.name},`);\n }\n }\n });\n cb.line(\"};\");\n for (const e of entries) {\n if (e.isOptional) {\n cb.line(`if (${e.name} !== null) {`);\n cb.indent(() => cb.line(`${tsPropAccess(\"params\", e.wireKey)} = ${e.name};`));\n cb.line(\"}\");\n }\n }\n cb.line(\"return params;\");\n });\n cb.line(\"}\");\n}\n\n/**\n * Emit the user-facing kwarg wrapper: takes the same kwargs as the factory\n * plus `runner`, builds the params object, and delegates to the dict-style\n * execute function.\n */\nexport function emitKwargWrapper(\n ctx: CodegenContext,\n entries: readonly SigEntry[],\n funcName: string,\n paramsFnName: string,\n executeFnName: string,\n outputsType: string | undefined,\n cb: CodeBuilder,\n): void {\n const appDoc = ctx.app?.doc;\n cb.line(\"/**\");\n if (appDoc?.title) cb.line(` * ${appDoc.title}`);\n if (appDoc?.description) {\n if (appDoc?.title) cb.line(\" *\");\n cb.line(` * ${appDoc.description}`);\n }\n if (appDoc?.authors?.length) {\n cb.line(\" *\");\n cb.line(` * Author: ${appDoc.authors.join(\", \")}`);\n }\n if (appDoc?.urls?.length) {\n cb.line(\" *\");\n cb.line(` * URL: ${appDoc.urls[0]}`);\n }\n cb.line(\" *\");\n emitJsDocParams(\n [...entries, { name: \"runner\", doc: \"Command runner (defaults to global runner).\" }],\n cb,\n );\n cb.line(\" *\");\n cb.line(\n outputsType\n ? \" * @returns Tool outputs (paths to files produced by the tool).\"\n : \" * @returns void\",\n );\n cb.line(\" */\");\n\n const returnType = outputsType ?? \"void\";\n cb.line(`export function ${funcName}(`);\n cb.indent(() => {\n emitSigParams(entries, cb);\n cb.line(\"runner: Runner | null = null,\");\n });\n cb.line(`): ${returnType} {`);\n\n cb.indent(() => {\n if (entries.length === 0) {\n cb.line(`const params = ${paramsFnName}();`);\n } else {\n cb.line(`const params = ${paramsFnName}(`);\n cb.indent(() => {\n for (const e of entries) cb.line(`${e.name},`);\n });\n cb.line(\");\");\n }\n if (outputsType) {\n cb.line(`return ${executeFnName}(params, runner);`);\n } else {\n cb.line(`${executeFnName}(params, runner);`);\n }\n });\n cb.line(\"}\");\n}\n\nexport function emitWrapperFunction(\n ctx: CodegenContext,\n paramsType: string,\n funcName: string,\n metaConst: string,\n cargsFunc: string,\n outputsFunc: string | undefined,\n outputsType: string | undefined,\n validateFunc: string | undefined,\n streams: { stdout?: string; stderr?: string },\n cb: CodeBuilder,\n): void {\n const appDoc = ctx.app?.doc;\n const docLines: string[] = [];\n if (appDoc?.title) docLines.push(appDoc.title);\n if (appDoc?.description) {\n if (docLines.length > 0) docLines.push(\"\");\n docLines.push(appDoc.description);\n }\n if (appDoc?.authors?.length) {\n docLines.push(\"\");\n docLines.push(`Author: ${appDoc.authors.join(\", \")}`);\n }\n if (appDoc?.urls?.length) {\n docLines.push(\"\");\n docLines.push(`URL: ${appDoc.urls[0]}`);\n }\n\n const emitOutputs = outputsFunc !== undefined;\n\n if (docLines.length > 0) {\n cb.line(\"/**\");\n for (const line of docLines) {\n cb.line(` * ${line}`);\n }\n cb.line(\" *\");\n cb.line(\" * @param params - The parameters.\");\n cb.line(\" * @param runner - Command runner (defaults to global runner).\");\n if (emitOutputs) cb.line(\" * @returns Tool outputs (paths to files produced by the tool).\");\n cb.line(\" */\");\n }\n\n const returnType = emitOutputs && outputsType ? outputsType : \"void\";\n cb.line(\n `export function ${funcName}(params: ${paramsType}, runner: Runner | null = null): ${returnType} {`,\n );\n cb.indent(() => {\n // Validate the params object first (the kwarg wrapper delegates here, so it\n // gets validation transitively; the statically-typed kwargs don't need it).\n if (validateFunc) cb.line(`${validateFunc}(params);`);\n cb.line(\"runner = runner ?? getGlobalRunner();\");\n cb.line(`const execution = runner.startExecution(${metaConst});`);\n cb.line(\"execution.params(params);\");\n // Local names `args`/`out` avoid colliding with the module-level `cargs` /\n // `outputs` functions when they share generic names.\n cb.line(`const args = ${cargsFunc}(params, execution);`);\n if (emitOutputs) {\n cb.line(`const out = ${outputsFunc}(params, execution);`);\n const { stdout, stderr } = streams;\n if (stdout || stderr) {\n // run(cargs, handleStdout?, handleStderr?): pass `undefined` for an\n // absent stdout handler so a stderr-only handler lands in position 3.\n const runArgs = [\"args\"];\n runArgs.push(\n stdout ? `(s: string): void => { ${tsPropAccess(\"out\", stdout)}.push(s); }` : \"undefined\",\n );\n if (stderr) {\n runArgs.push(`(s: string): void => { ${tsPropAccess(\"out\", stderr)}.push(s); }`);\n }\n cb.line(`execution.run(${runArgs.join(\", \")});`);\n } else {\n cb.line(\"execution.run(args);\");\n }\n cb.line(\"return out;\");\n } else {\n cb.line(\"execution.run(args);\");\n }\n });\n cb.line(\"}\");\n}\n","import type { BoundType } from \"../../bindings/index.js\";\nimport type { Expr } from \"../../ir/index.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport type { CodeBuilder } from \"../code-builder.js\";\nimport type { Scope } from \"../scope.js\";\nimport {\n findAlternativeNode,\n findRangeNode,\n findRepeatNode,\n structFields,\n} from \"../validate-walk.js\";\nimport { structVariants } from \"../union-variants.js\";\nimport { emitJsDoc, tsPropAccess } from \"./emit.js\";\nimport { mapType } from \"./typemap.js\";\n\n/**\n * Emit a `<tool>Validate(params)` function that walks the solved root\n * `BoundType` and throws `StyxValidationError` on invalid input. Hand-rolled\n * (no runtime deps): `typeof`/`Array.isArray` stand in for Python's\n * `isinstance`. Mirrors the Python backend's validation behavior, inlined into\n * a single function.\n */\n\ntype Resolve = (t: BoundType) => string | undefined;\n\ninterface Emit {\n ctx: CodegenContext;\n resolve: Resolve;\n /** Per-function scope for generated locals (loop vars), reserving `params`. */\n scope: Scope;\n cb: CodeBuilder;\n}\n\nexport function emitValidate(\n ctx: CodegenContext,\n rootType: BoundType,\n rootNode: Expr,\n paramsType: string,\n funcName: string,\n resolve: Resolve,\n scope: Scope,\n cb: CodeBuilder,\n): void {\n const e: Emit = { ctx, resolve, scope: scope.child([\"params\"]), cb };\n emitJsDoc(\n cb,\n `Validate untrusted parameters. Throws StyxValidationError if \\`params\\` is not a valid ${paramsType}; narrows it to ${paramsType} on success.`,\n );\n // Assertion signature over untyped input: a boundary guard usable on a parsed\n // dict / config blob, not just an already-typed value. The body walks `params`\n // dynamically, so the parameter is `any` (the assertion still narrows callers).\n cb.line(`export function ${funcName}(params: any): asserts params is ${paramsType} {`);\n cb.indent(() => emitRoot(e, rootType, rootNode));\n cb.line(\"}\");\n}\n\nfunction emitRoot(e: Emit, rootType: BoundType, rootNode: Expr): void {\n if (rootType.kind === \"struct\") {\n block(e, `typeof params !== \"object\" || params === null`, () =>\n raise(e, \"Params object has the wrong type\"),\n );\n for (const f of structFields(e.ctx, rootType, rootNode)) {\n emitField(e, f.name, f.type, f.node, f.hasDefault, \"params\");\n }\n } else if (rootType.kind === \"union\") {\n emitUnion(e, rootType, rootNode, \"params\", \"params\");\n } else {\n emitValue(e, rootType, rootNode, \"params\", \"params\", expectedType(e, rootType));\n }\n}\n\n/** Validate one struct field, handling required-presence vs optional gating. */\nfunction emitField(\n e: Emit,\n name: string,\n fieldType: BoundType,\n node: Expr | undefined,\n hasDefault: boolean,\n base: string,\n): void {\n if (fieldType.kind === \"literal\") return;\n\n const access = tsPropAccess(base, name);\n const expected = expectedType(e, fieldType);\n const valueType = fieldType.kind === \"optional\" ? fieldType.inner : fieldType;\n\n // Optionals and defaulted fields/flags accept null (null = \"use default\"), so\n // gate the body instead of requiring presence.\n if (fieldType.kind === \"optional\" || hasDefault) {\n e.cb.line(`if (${access} != null) {`);\n e.cb.indent(() => emitValue(e, valueType, node, name, access, expected));\n e.cb.line(\"}\");\n } else {\n block(e, `${access} == null`, () => raise(e, \"`\" + name + \"` must not be null\"));\n emitValue(e, valueType, node, name, access, expected);\n }\n}\n\n/** Validate a known-present value at `access` against `type`. */\nfunction emitValue(\n e: Emit,\n type: BoundType,\n node: Expr | undefined,\n wireKey: string,\n access: string,\n expected: string,\n): void {\n switch (type.kind) {\n case \"optional\":\n emitValue(e, type.inner, node, wireKey, access, expected);\n return;\n case \"literal\":\n return;\n case \"scalar\":\n switch (type.scalar) {\n case \"str\":\n case \"path\":\n checkType(e, `typeof ${access} !== \"string\"`, wireKey, expected);\n return;\n case \"int\":\n case \"float\":\n checkType(e, `typeof ${access} !== \"number\"`, wireKey, expected);\n emitRange(e, node, wireKey, access);\n return;\n }\n return;\n case \"bool\":\n checkType(e, `typeof ${access} !== \"boolean\"`, wireKey, expected);\n return;\n case \"count\":\n checkType(e, `typeof ${access} !== \"number\"`, wireKey, expected);\n return;\n case \"list\": {\n checkType(e, `!Array.isArray(${access})`, wireKey, expected);\n emitListLength(e, node, wireKey, access);\n const itemNode = findRepeatNode(node)?.attrs.node;\n const elem = e.scope.add(\"el\");\n e.cb.line(`for (const ${elem} of ${access}) {`);\n e.cb.indent(() => emitValue(e, type.item, itemNode, wireKey, elem, expected));\n e.cb.line(\"}\");\n return;\n }\n case \"struct\": {\n block(e, `typeof ${access} !== \"object\" || ${access} === null`, () =>\n raise(e, \"Params object has the wrong type\"),\n );\n for (const f of structFields(e.ctx, type, node)) {\n emitField(e, f.name, f.type, f.node, f.hasDefault, access);\n }\n return;\n }\n case \"union\":\n emitUnion(e, type, node, wireKey, access);\n return;\n }\n}\n\nfunction emitUnion(\n e: Emit,\n unionType: Extract<BoundType, { kind: \"union\" }>,\n node: Expr | undefined,\n wireKey: string,\n access: string,\n): void {\n const litVariants = unionType.variants.filter((v) => v.type.kind === \"literal\");\n const hasStruct = unionType.variants.some((v) => v.type.kind === \"struct\");\n\n // Pure enum/choice: no struct variants, just literal values (no `@type`).\n if (!hasStruct) {\n const values = litVariants.map(\n (v) => (v.type as Extract<BoundType, { kind: \"literal\" }>).value,\n );\n const allStr = values.every((x) => typeof x === \"string\");\n checkType(\n e,\n `typeof ${access} !== ${allStr ? '\"string\"' : '\"number\"'}`,\n wireKey,\n expectedType(e, unionType),\n );\n emitLiteralMembership(e, values, wireKey, access);\n return;\n }\n\n const altNode = findAlternativeNode(node);\n // Struct variants with their indices; throws if two share an `@type` (a\n // duplicate-tagged variant is unreachable and a mypy `comparison-overlap` in\n // the Python mirror - frontends must dodge duplicate tags before codegen).\n // The index keeps each arm aligned with the IR `alts`.\n const structVars = structVariants(unionType);\n const emitStructArm = (): void => {\n // `access` is known to be an object here.\n block(e, `!(\"@type\" in ${access})`, () => raise(e, \"Params object is missing `@type`\"));\n const names = structVars\n .map(({ variant }) => variant.name)\n .filter((n): n is string => n !== undefined)\n .map((n) => JSON.stringify(n));\n // `.includes` rather than a `!==`-chain: the discriminant is a closed literal\n // union and an exhaustive chain is rejected by TS as TS2367. It also leaves\n // the union un-narrowed, so the `switch` dispatch below narrows it.\n block(e, `![${names.join(\", \")}].includes(${access}[\"@type\"])`, () =>\n raise(e, \"Parameter `\" + wireKey + \"`s `@type` must be one of [\" + names.join(\", \") + \"]\"),\n );\n // `switch` (mirroring the cargs builder): each `case` narrows correctly,\n // whereas an `if`/`else if` chain on `===` accumulates narrowing and TS\n // rejects later arms.\n e.cb.line(`switch (${access}[\"@type\"]) {`);\n e.cb.indent(() => {\n structVars.forEach(({ variant, i }) => {\n const vt = variant.type as Extract<BoundType, { kind: \"struct\" }>;\n e.cb.line(`case ${JSON.stringify(variant.name ?? \"\")}: {`);\n e.cb.indent(() => {\n const fields = structFields(e.ctx, vt, altNode?.attrs.alts[i]).filter(\n (f) => f.type.kind !== \"literal\",\n );\n for (const f of fields) emitField(e, f.name, f.type, f.node, f.hasDefault, access);\n e.cb.line(\"break;\");\n });\n e.cb.line(\"}\");\n });\n });\n e.cb.line(\"}\");\n };\n\n // Pure discriminated union: every variant is a struct with an `@type`.\n if (litVariants.length === 0) {\n block(e, `typeof ${access} !== \"object\" || ${access} === null`, () =>\n raise(e, \"Params object has the wrong type\"),\n );\n emitStructArm();\n return;\n }\n\n // Mixed union: a value is either a struct (dict with `@type`) or a bare\n // literal. Branch on the runtime shape - `typeof === \"object\"` narrows to the\n // struct members, the `else` to the literal members.\n e.cb.line(`if (typeof ${access} === \"object\" && ${access} !== null) {`);\n e.cb.indent(emitStructArm);\n e.cb.line(`} else {`);\n e.cb.indent(() => {\n const values = litVariants.map(\n (v) => (v.type as Extract<BoundType, { kind: \"literal\" }>).value,\n );\n emitLiteralMembership(e, values, wireKey, access);\n });\n e.cb.line(\"}\");\n}\n\n/** Emit a `.includes`-based membership check over literal values. */\nfunction emitLiteralMembership(\n e: Emit,\n values: (string | number)[],\n wireKey: string,\n access: string,\n): void {\n const rendered = values.map(renderLiteral);\n block(e, `![${rendered.join(\", \")}].includes(${access})`, () =>\n raise(e, \"Parameter `\" + wireKey + \"` must be one of [\" + rendered.join(\", \") + \"]\"),\n );\n}\n\nfunction checkType(e: Emit, condition: string, wireKey: string, expected: string): void {\n block(e, condition, () =>\n raise(e, \"`\" + wireKey + \"` has the wrong type (expected \" + expected + \")\"),\n );\n}\n\nfunction emitRange(e: Emit, node: Expr | undefined, wireKey: string, access: string): void {\n const term = findRangeNode(node);\n if (!term) return;\n const { minValue, maxValue } = term.attrs;\n if (minValue !== undefined && maxValue !== undefined) {\n block(e, `!(${tsNum(minValue)} <= ${access} && ${access} <= ${tsNum(maxValue)})`, () =>\n raise(e, `Parameter \\`${wireKey}\\` must be between ${minValue} and ${maxValue} (inclusive)`),\n );\n } else if (minValue !== undefined) {\n block(e, `${access} < ${tsNum(minValue)}`, () =>\n raise(e, `Parameter \\`${wireKey}\\` must be at least ${minValue}`),\n );\n } else if (maxValue !== undefined) {\n block(e, `${access} > ${tsNum(maxValue)}`, () =>\n raise(e, `Parameter \\`${wireKey}\\` must be at most ${maxValue}`),\n );\n }\n}\n\nfunction emitListLength(e: Emit, node: Expr | undefined, wireKey: string, access: string): void {\n const rep = findRepeatNode(node);\n if (!rep) return;\n const { countMin, countMax } = rep.attrs;\n if (countMin !== undefined && countMax !== undefined) {\n block(e, `!(${countMin} <= ${access}.length && ${access}.length <= ${countMax})`, () =>\n raise(\n e,\n `Parameter \\`${wireKey}\\` must contain between ${countMin} and ${countMax} elements (inclusive)`,\n ),\n );\n } else if (countMin !== undefined) {\n block(e, `${access}.length < ${countMin}`, () =>\n raise(\n e,\n `Parameter \\`${wireKey}\\` must contain at least ${countMin} ${plural(\"element\", countMin)}`,\n ),\n );\n } else if (countMax !== undefined) {\n block(e, `${access}.length > ${countMax}`, () =>\n raise(\n e,\n `Parameter \\`${wireKey}\\` must contain at most ${countMax} ${plural(\"element\", countMax)}`,\n ),\n );\n }\n}\n\n// -- Emit helpers --\n\n/** Emit `if (<cond>) { <body> }`. */\nfunction block(e: Emit, condition: string, body: () => void): void {\n e.cb.line(`if (${condition}) {`);\n e.cb.indent(body);\n e.cb.line(\"}\");\n}\n\nfunction raise(e: Emit, message: string): void {\n e.cb.line(`throw new StyxValidationError(${JSON.stringify(message)});`);\n}\n\nfunction expectedType(e: Emit, type: BoundType): string {\n return mapType(type, e.resolve);\n}\n\nfunction renderLiteral(value: string | number): string {\n return typeof value === \"string\" ? JSON.stringify(value) : String(value);\n}\n\nfunction tsNum(n: number): string {\n return Number.isFinite(n) ? String(n) : \"NaN\";\n}\n\nfunction plural(word: string, count: number): string {\n return count === 1 ? word : `${word}s`;\n}\n","import type {\n Binding,\n BindingId,\n BoundType,\n GateAtom,\n ResolvedToken,\n} from \"../../bindings/index.js\";\nimport { outputGate } from \"../../bindings/index.js\";\nimport { collectFieldInfo } from \"../collect-field-info.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport {\n type EmittedOutput,\n type OutputShape,\n collectMutableOutputs,\n collectOutputFields,\n outputShape,\n rootOutput,\n streamFields,\n} from \"../collect-output-fields.js\";\nimport { emitJsDoc, renderAccess, tsPropAccess } from \"./emit.js\";\nimport { renderTsLiteral } from \"./typemap.js\";\n\n// The output-field/stream/mutable collection is language-agnostic and shared\n// with the Python and JSON Schema backends; re-export the predicates the\n// backend entry point consumes so its import surface stays `./outputs-emit.js`.\nexport { hasAnyOutputs, hasMutableInputs, hasStreamOutputs } from \"../collect-output-fields.js\";\n\nfunction outputTypeExpr(shape: OutputShape): string {\n if (shape.kind === \"list\") return \"OutputPathType[]\";\n return shape.optional ? \"OutputPathType | null\" : \"OutputPathType\";\n}\n\nfunction initialValue(shape: OutputShape): string {\n if (shape.kind === \"list\") return \"[]\";\n // Required fields get a non-null assertion placeholder; the linear-flow\n // assignment below makes the placeholder unobservable.\n return shape.optional ? \"null\" : \"null!\";\n}\n\n/** Raw field names for stdout/stderr (in declaration order), for wrapper wiring. */\nexport function streamFieldIds(ctx: CodegenContext): { stdout?: string; stderr?: string } {\n const fields = streamFields(ctx, jsId);\n const res: { stdout?: string; stderr?: string } = {};\n let idx = 0;\n if (ctx.app?.stdout) res.stdout = fields[idx++]!.name;\n if (ctx.app?.stderr) res.stderr = fields[idx++]!.name;\n return res;\n}\n\n/** Emit the `export interface <outputsType> { ... }` declaration. */\nexport function emitOutputsInterface(\n ctx: CodegenContext,\n outputsType: string,\n cb: CodeBuilder,\n): void {\n cb.line(`export interface ${outputsType} {`);\n cb.indent(() => {\n for (const field of collectOutputFields(ctx, jsId)) {\n emitJsDoc(cb, field.doc);\n cb.line(`${field.id}: ${outputTypeExpr(field.shape)};`);\n }\n for (const s of streamFields(ctx, jsId)) {\n emitJsDoc(cb, s.doc);\n cb.line(`${s.id}: string[];`);\n }\n });\n cb.line(`}`);\n}\n\n/**\n * Substitutions for ref access while inside an iteration loop. When emitting\n * `for (const item of foo)`, refs to `foo` inside should resolve to `item`.\n * This is also how `iter` segments in a binding's access path are resolved.\n */\ntype IterScope = Map<BindingId, string>;\n\ninterface OutputEmitCtx {\n ctx: CodegenContext;\n iter: IterScope;\n /**\n * Merged shape per emitted field id (jsId of the output name), across every\n * contributing scope. An output name can be declared in several scopes with\n * different shapes - e.g. a list scope (repeatable option) and a single scope\n * (plain option) both writing `volume_out`. The field's type follows the\n * merged shape (a list if any contributor iterates), so the *write* must too:\n * a single-scope contributor pushes one element into a list field rather than\n * assigning. Keyed identically to `collectOutputFields`.\n */\n fieldShapes: Map<string, OutputShape>;\n /**\n * Rendered TS default literals for root-level defaulted fields, keyed by field\n * name. An output path interpolating such a field (e.g. an output basename\n * `maskfile`) reads it via `(access ?? default)` so an absent key substitutes\n * the default rather than stringifying `undefined`. Mirrors the cargs builder.\n */\n defaults: ReadonlyMap<string, string>;\n}\n\n/** The rendered default for a binding iff it is a root-level defaulted field. */\nfunction rootFieldDefault(\n binding: Binding | undefined,\n defaults: ReadonlyMap<string, string>,\n): string | undefined {\n if (!binding) return undefined;\n const a = binding.access;\n if (a.length === 1 && a[0]?.kind === \"field\") return defaults.get(binding.name);\n return undefined;\n}\n\n/** Build the field-name -> rendered-default map for the struct root (else empty).\n * Includes only non-optional defaulted fields (optional fields are\n * presence-guarded; their default comes from the factory's kwarg signature). */\nfunction collectDefaults(ctx: CodegenContext): Map<string, string> {\n const out = new Map<string, string>();\n const rootType = ctx.resolve(ctx.expr)?.type;\n if (rootType?.kind !== \"struct\") return out;\n for (const [name, fi] of collectFieldInfo(ctx, rootType)) {\n if (fi.defaultValue === undefined) continue;\n if (rootType.fields[name]?.kind === \"optional\") continue;\n out.set(name, renderTsLiteral(fi.defaultValue));\n }\n return out;\n}\n\n/**\n * Render one output's wrapper stack and emit the assignment inside the\n * innermost wrapper. Nesting is done via recursive callbacks so the\n * CodeBuilder's auto-indentation tracks correctly.\n */\nfunction emitOneOutput(\n output: EmittedOutput,\n gate: GateAtom[],\n ec: OutputEmitCtx,\n cb: CodeBuilder,\n): void {\n const occShape = outputShape(gate);\n // Push-vs-assign follows the *field's* merged shape, not this occurrence's:\n // when the same name is a list in one scope and single in another, the field\n // is a list, so a single-scope contributor must push (one element) rather\n // than assign a scalar into the array. Falls back to the occurrence shape for\n // a name that somehow has no merged entry.\n const shape = ec.fieldShapes.get(jsId(output.name)) ?? occShape;\n // Bracket-access for non-identifier field names (e.g. `in-file`, `4d`); dot\n // for valid identifiers. The interface key is jsId-quoted to match.\n const fieldRef = tsPropAccess(\"outputs\", output.name);\n\n function nest(remaining: GateAtom[], child: OutputEmitCtx): void {\n if (remaining.length === 0) {\n const pathExpr = renderPathExpr(output.tokens, child);\n // A mutable input's writable copy is surfaced via mutableCopy (its host\n // path); a regular output resolves a local path via outputFile. The\n // optional `, true` arg only applies to a single (non-list) field.\n const optionalArg =\n !output.mutable &&\n shape.kind === \"single\" &&\n occShape.kind === \"single\" &&\n occShape.optional\n ? \", true\"\n : \"\";\n const call = output.mutable\n ? `execution.mutableCopy(${pathExpr})`\n : `execution.outputFile(${pathExpr}${optionalArg})`;\n if (shape.kind === \"list\") {\n cb.line(`${fieldRef}.push(${call});`);\n } else {\n cb.line(`${fieldRef} = ${call};`);\n }\n return;\n }\n const [head, ...rest] = remaining;\n if (!head) return;\n const wrapper = renderWrapperOpen(head, child);\n cb.line(wrapper.open);\n cb.indent(() => {\n const inner =\n head.kind === \"iter\"\n ? { ...child, iter: new Map(child.iter).set(head.binding, wrapper.loopVar!) }\n : child;\n nest(rest, inner);\n });\n cb.line(wrapper.close);\n }\n\n nest(gate, ec);\n}\n\ninterface WrapperRender {\n open: string;\n close: string;\n loopVar?: string;\n}\n\nlet loopCounter = 0;\n\nfunction renderWrapperOpen(atom: GateAtom, ec: OutputEmitCtx): WrapperRender {\n if (atom.kind === \"iter\") {\n const access = bindingAccess(atom.binding, ec);\n const v = `__o${loopCounter++}`;\n return { open: `for (const ${v} of ${access}) {`, close: `}`, loopVar: v };\n }\n if (atom.kind === \"variant\") {\n const access = bindingAccess(atom.binding, ec);\n return {\n open: `if (${access}[\"@type\"] === ${JSON.stringify(atom.variant)}) {`,\n close: `}`,\n };\n }\n // present\n const binding = ec.ctx.bindings.get(atom.binding);\n const access = bindingAccess(atom.binding, ec);\n const cond = presentCondition(binding?.type, access);\n return { open: `if (${cond}) {`, close: `}` };\n}\n\nfunction presentCondition(type: BoundType | undefined, access: string): string {\n if (!type) return access;\n switch (type.kind) {\n case \"optional\":\n return `${access} !== null && ${access} !== undefined`;\n case \"bool\":\n return access;\n case \"count\":\n return `${access} > 0`;\n default:\n return access;\n }\n}\n\nfunction bindingAccess(id: BindingId, ec: OutputEmitCtx): string {\n // The binding is itself the currently-iterated element (a `ref` to the list\n // being looped, or a scalar list element): use its loop variable directly.\n const subst = ec.iter.get(id);\n if (subst) return subst;\n const binding = ec.ctx.bindings.get(id);\n if (binding) {\n // Solver-assigned path; `iter` segments resolve to the loop variable bound\n // by the surrounding `iter` gate atom (always open by the time a ref to a\n // binding under that repeat renders).\n return renderAccess(binding.access, (b) => ec.iter.get(b) ?? unresolvedLoopVar(b));\n }\n // Fallback: shouldn't happen for well-formed IR, but emit a comment-style\n // placeholder so the generated code surfaces the issue.\n return `/* unresolved binding ${id} */ null as any`;\n}\n\nfunction unresolvedLoopVar(binding: BindingId): string {\n return `/* unresolved loop var ${binding} */ (null as any)`;\n}\n\nfunction renderPathExpr(tokens: ResolvedToken[], ec: OutputEmitCtx): string {\n if (tokens.length === 0) return `\"\"`;\n if (tokens.length === 1) return renderToken(tokens[0]!, ec);\n // Template-literal join: \\`${...}${...}\\`\n let result = \"`\";\n for (const tok of tokens) {\n if (tok.kind === \"literal\") {\n result += tok.value.replace(/\\\\/g, \"\\\\\\\\\").replace(/`/g, \"\\\\`\").replace(/\\$\\{/g, \"\\\\${\");\n } else {\n result += \"${\";\n result += renderRefValue(tok, ec);\n result += \"}\";\n }\n }\n result += \"`\";\n return result;\n}\n\nfunction renderToken(tok: ResolvedToken, ec: OutputEmitCtx): string {\n if (tok.kind === \"literal\") return JSON.stringify(tok.value);\n return renderRefValue(tok, ec);\n}\n\nfunction renderRefValue(tok: Extract<ResolvedToken, { kind: \"ref\" }>, ec: OutputEmitCtx): string {\n // A defaulted root field interpolated into an output path is read absent-safe\n // via `(access ?? default)` (it is `?:`); other refs render normally.\n const def = rootFieldDefault(ec.ctx.bindings.get(tok.binding), ec.defaults);\n let expr =\n def !== undefined && !ec.iter.has(tok.binding)\n ? `(${bindingAccess(tok.binding, ec)} ?? ${def})`\n : bindingAccess(tok.binding, ec);\n // Optional refs with a fallback substitute the fallback on null/undefined.\n if (tok.fallback !== undefined) {\n expr = `(${expr} ?? ${JSON.stringify(tok.fallback)})`;\n }\n // stripExtensions: cut listed suffixes from the value (longest match first).\n if (tok.stripExtensions && tok.stripExtensions.length > 0) {\n const sorted = [...tok.stripExtensions].sort((a, b) => b.length - a.length);\n const lits = sorted.map((s) => JSON.stringify(s)).join(\", \");\n expr = `stripExtensions(${expr}, [${lits}])`;\n }\n return expr;\n}\n\nfunction jsId(name: string): string {\n // Output ids may contain characters that aren't valid JS identifier chars.\n // Quote when needed.\n if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name)) return name;\n return JSON.stringify(name);\n}\n\n/**\n * Emit a standalone `_outputs(params, execution)` function that builds and\n * returns the `Outputs` object. Mirrors the `_cargs` function structurally so\n * the wrapper can just call both.\n */\nexport function emitBuildOutputs(\n ctx: CodegenContext,\n paramsType: string,\n outputsType: string,\n funcName: string,\n cb: CodeBuilder,\n): void {\n cb.line(\n `export function ${funcName}(params: ${paramsType}, execution: Execution): ${outputsType} {`,\n );\n cb.indent(() => {\n loopCounter = 0;\n const fields = collectOutputFields(ctx, jsId);\n const ec: OutputEmitCtx = {\n ctx,\n iter: new Map(),\n fieldShapes: new Map(fields.map((f) => [f.id, f.shape])),\n defaults: collectDefaults(ctx),\n };\n\n // Initialize the outputs object with defaults so wrapper code can assign or\n // push into it without conditional construction. Deduped by field id so\n // same-named outputs (e.g. union arms) yield one initializer entry.\n cb.line(`const outputs: ${outputsType} = {`);\n cb.indent(() => {\n for (const field of fields) {\n cb.line(`${field.id}: ${initialValue(field.shape)},`);\n }\n // Stream fields start empty; the wrapper pushes onto them via the\n // handleStdout / handleStderr callbacks passed to execution.run.\n for (const s of streamFields(ctx, jsId)) {\n cb.line(`${s.id}: [],`);\n }\n });\n cb.line(`};`);\n\n const emitContributor = (output: EmittedOutput, scopeGate: GateAtom[]): void => {\n const gate = outputGate(scopeGate, output, ctx.bindings);\n emitOneOutput(output, gate, ec, cb);\n };\n // The always-present root output directory, assigned before any declared\n // output (matches its first position in collectOutputFields).\n emitContributor(rootOutput(ctx, jsId), []);\n for (const scope of ctx.outputScopes) {\n const scopeBinding = ctx.bindings.get(scope.scope);\n const scopeGate = scopeBinding?.gate ?? [];\n for (const output of scope.outputs) emitContributor(output, scopeGate);\n }\n for (const output of collectMutableOutputs(ctx)) emitContributor(output, []);\n\n cb.line(`return outputs;`);\n });\n cb.line(`}`);\n}\n\n/**\n * Whether the generated module needs a `stripExtensions` helper (any ref\n * token has stripExtensions set).\n */\nexport function needsStripExtensionsHelper(ctx: CodegenContext): boolean {\n for (const scope of ctx.outputScopes) {\n for (const output of scope.outputs) {\n for (const tok of output.tokens) {\n if (tok.kind === \"ref\" && tok.stripExtensions?.length) return true;\n }\n }\n }\n return false;\n}\n\n/** Emit a small `stripExtensions` helper used by ref tokens that strip suffixes. */\nexport function emitStripExtensionsHelper(cb: CodeBuilder): void {\n cb.line(`function stripExtensions(value: string, exts: string[]): string {`);\n cb.indent(() => {\n cb.line(`for (const ext of exts) {`);\n cb.indent(() => {\n cb.line(`if (value.endsWith(ext)) return value.slice(0, value.length - ext.length);`);\n });\n cb.line(`}`);\n cb.line(`return value;`);\n });\n cb.line(`}`);\n}\n","import type { BoundType } from \"../../bindings/index.js\";\nimport type { AppMeta } from \"../../ir/index.js\";\nimport type { CodegenContext, PackageMeta, ProjectMeta } from \"../../manifest/index.js\";\nimport type { AppEntrypoint, Backend, EmitResult, EmittedApp, EmittedPackage } from \"../backend.js\";\nimport type { SigEntry } from \"../sig-entries.js\";\nimport type { NamedType } from \"./types.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport { generatePackageJson, generateRootIndex, generateTsconfig } from \"./packaging.js\";\nimport { Scope } from \"../scope.js\";\nimport { camelCase, pascalCase, screamingSnakeCase, snakeCase } from \"../string-case.js\";\nimport { buildSigEntries } from \"../sig-entries.js\";\nimport {\n emitBuildCargs,\n emitImports,\n emitKwargWrapper,\n emitMetadata,\n emitParamsFactory,\n emitTypeDeclarations,\n emitWrapperFunction,\n tsScrubIdent,\n tsSigOptions,\n} from \"./emit.js\";\nimport { collectFieldInfo } from \"./types.js\";\nimport { emitValidate } from \"./validate-emit.js\";\nimport {\n emitBuildOutputs,\n emitOutputsInterface,\n emitStripExtensionsHelper,\n needsStripExtensionsHelper,\n streamFieldIds,\n} from \"./outputs-emit.js\";\nimport { mapType } from \"./typemap.js\";\nimport { collectNamedTypes, resolveTypeName, structKey, unionKey } from \"./types.js\";\n\nconst TS_RESERVED: ReadonlySet<string> = new Set([\n \"break\",\n \"case\",\n \"catch\",\n \"class\",\n \"const\",\n \"continue\",\n \"debugger\",\n \"default\",\n \"delete\",\n \"do\",\n \"else\",\n \"enum\",\n \"export\",\n \"extends\",\n \"false\",\n \"finally\",\n \"for\",\n \"function\",\n \"if\",\n \"import\",\n \"in\",\n \"instanceof\",\n \"new\",\n \"null\",\n \"return\",\n \"super\",\n \"switch\",\n \"this\",\n \"throw\",\n \"true\",\n \"try\",\n \"typeof\",\n \"undefined\",\n \"var\",\n \"void\",\n \"while\",\n \"with\",\n \"yield\",\n \"let\",\n \"static\",\n \"implements\",\n \"interface\",\n \"package\",\n \"private\",\n \"protected\",\n \"public\",\n \"type\",\n // Not keywords, but forbidden as binding names in strict mode (ES modules are\n // always strict), so a parameter/local named these is a hard error.\n \"arguments\",\n \"eval\",\n \"await\",\n]);\n\n/**\n * Per-tool public symbol names emitted directly in the flat tool file. Wrapper\n * and function names use camelCase; type names use PascalCase; the metadata\n * constant uses SCREAMING_SNAKE_CASE.\n */\nexport interface PublicNames {\n params: string;\n outputs: string;\n metadata: string;\n cargs: string;\n outputsFn: string;\n paramsFn: string;\n execute: string;\n validate: string;\n wrapper: string;\n}\n\n/** Public-name scheme used by the TypeScript backend. Exported so the CLI and tests can use it. */\nexport function computePublicNames(appId: string | undefined): PublicNames {\n if (!appId) {\n return {\n params: \"Params\",\n outputs: \"Outputs\",\n metadata: \"METADATA\",\n cargs: \"cargs\",\n outputsFn: \"outputs\",\n paramsFn: \"buildParams\",\n execute: \"execute\",\n validate: \"validate\",\n wrapper: \"run\",\n };\n }\n // Pre-scrub digit-leading ids so derived case forms produce valid\n // identifiers in a consistent case.\n const id = /^[0-9]/.test(appId) ? \"v_\" + appId : appId;\n return {\n params: pascalCase(id),\n outputs: pascalCase(id) + \"Outputs\",\n metadata: screamingSnakeCase(id) + \"_METADATA\",\n cargs: camelCase(id) + \"_cargs\",\n outputsFn: camelCase(id) + \"_outputs\",\n paramsFn: camelCase(id) + \"Params\",\n execute: camelCase(id) + \"Execute\",\n validate: camelCase(id) + \"Validate\",\n wrapper: camelCase(id),\n };\n}\n\n/**\n * The fully-derived naming/typing model for one tool's TypeScript emission.\n * Computed once by `buildEmitModel` so the file emitter and the call-site snippet\n * renderer share the exact same public names and root typing - the snippet must\n * match the function the generated code actually exposes.\n */\nexport interface TsEmitModel {\n appId: string | undefined;\n pkg: string;\n names: {\n params: string;\n outputs: string;\n metadata: string;\n cargs: string;\n outputsFn: string;\n paramsFn: string;\n execute: string;\n validate: string;\n wrapper: string;\n };\n rootType: BoundType;\n rootIsStruct: boolean;\n namedTypes: Map<string, string>;\n typeDecls: NamedType[];\n rootTypeTag: string | undefined;\n paramsType: string;\n sigEntries: SigEntry[];\n}\n\n/**\n * Derive the public names, named-type declarations, root typing, and per-field\n * signature entries for one tool. Mutates `scope` exactly as the emitter needs\n * (the `reg` registrations and the `sigScope` child), so passing the same scope\n * the emitter continues with keeps later local registrations consistent.\n */\nexport function buildEmitModel(\n ctx: CodegenContext,\n scope: Scope = new Scope(TS_RESERVED),\n): TsEmitModel {\n const appId = ctx.app?.id;\n const pkg = ctx.package?.name ?? \"unknown\";\n const publicNames = computePublicNames(appId);\n\n const rootBinding = ctx.resolve(ctx.expr);\n const rootType: BoundType = rootBinding?.type ?? { kind: \"struct\", fields: {} };\n // Only treat the root as struct-shaped when there's a real binding. A\n // synthesized empty-struct fallback (no root binding) means the solver\n // collapsed everything away, so the kwarg wrapper has nothing to wrap.\n const rootIsStruct = rootBinding?.type.kind === \"struct\";\n\n // Pre-reserve module-level public names so any IR-derived names colliding\n // with them get suffix-bumped. `params` is intentionally NOT pre-reserved -\n // `collectNamedTypes` claims it for the root struct just below. Each name\n // is scrubbed through `tsScrubIdent` first since the case helpers happily\n // pass through digit-leading app ids.\n const reg = (name: string) => scope.add(tsScrubIdent(name, TS_RESERVED));\n const names = {\n params: tsScrubIdent(publicNames.params, TS_RESERVED),\n outputs: reg(publicNames.outputs),\n metadata: reg(publicNames.metadata),\n cargs: reg(publicNames.cargs),\n outputsFn: reg(publicNames.outputsFn),\n paramsFn: rootIsStruct ? reg(publicNames.paramsFn) : \"\",\n execute: rootIsStruct ? reg(publicNames.execute) : \"\",\n validate: reg(publicNames.validate),\n wrapper: reg(publicNames.wrapper),\n };\n\n // Prefix nested type names with the tool's root name so a suite's flat barrel\n // doesn't collide same-named types (e.g. `Outputtype`) across tools.\n const { namedTypes, typeDecls } = collectNamedTypes(\n rootType,\n names.params,\n scope,\n pascalCase,\n appId ? names.params : \"\",\n );\n\n names.params =\n (rootType.kind === \"struct\" ? namedTypes.get(structKey(rootType)) : undefined) ??\n (rootType.kind === \"union\" ? namedTypes.get(unionKey(rootType)) : undefined) ??\n names.params;\n\n const paramsType =\n rootType.kind === \"struct\" || rootType.kind === \"union\"\n ? names.params\n : mapType(rootType, resolveTypeName(namedTypes));\n\n // Build the per-field SigEntry list once - the factory and kwarg wrapper\n // both consume it, so the host names registered here must satisfy both\n // function scopes. Pre-reserve `params` (factory + wrapper body) and\n // `runner` (wrapper signature) so a wire key matching either gets\n // suffix-bumped. `rootType.kind === \"struct\"` check satisfies the `Extract`\n // constraint when `rootIsStruct` is true.\n const rootTypeTag = appId ? `${pkg}/${appId}` : undefined;\n const sigScope = scope.child([\"params\", \"runner\"]);\n const sigEntries =\n rootIsStruct && rootType.kind === \"struct\"\n ? buildSigEntries(\n rootType,\n collectFieldInfo(ctx, rootType),\n (wireKey) => sigScope.add(tsScrubIdent(wireKey, TS_RESERVED)),\n tsSigOptions(resolveTypeName(namedTypes)),\n )\n : [];\n\n return {\n appId,\n pkg,\n names,\n rootType,\n rootIsStruct,\n namedTypes,\n typeDecls,\n rootTypeTag,\n paramsType,\n sigEntries,\n };\n}\n\nexport function generateTypeScript(ctx: CodegenContext, packageScope?: Scope): string {\n const cb = new CodeBuilder(\" \");\n // A package-shared scope keeps top-level names unique across every tool in the\n // suite barrel; without one (standalone emit) a per-tool scope is enough.\n const scope = packageScope ?? new Scope(TS_RESERVED);\n\n const {\n appId,\n pkg,\n names,\n rootType,\n rootIsStruct,\n namedTypes,\n typeDecls,\n rootTypeTag,\n paramsType,\n sigEntries,\n } = buildEmitModel(ctx, scope);\n\n // Auto-generated header.\n cb.comment(\"This file was auto generated by Styx.\");\n cb.comment(\"Do not edit this file directly.\");\n cb.blank();\n\n // Every tool emits an Outputs object: at minimum the synthetic `root` output\n // directory (outputFile(\".\")), plus any declared file/mutable outputs and\n // stdout/stderr stream fields. OutputPathType is therefore always imported.\n const emitOutputs = true;\n\n emitImports(cb, true);\n cb.blank();\n\n emitMetadata(ctx, names.metadata, cb);\n cb.blank();\n\n emitTypeDeclarations(typeDecls, namedTypes, ctx, names.params, appId, pkg, cb);\n\n if (emitOutputs) {\n emitOutputsInterface(ctx, names.outputs, cb);\n cb.blank();\n }\n\n if (emitOutputs && needsStripExtensionsHelper(ctx)) {\n emitStripExtensionsHelper(cb);\n cb.blank();\n }\n\n // Params factory (struct-rooted tools only): a kwarg-style builder for the\n // params object. Useful for callers that want to build a params object to\n // mutate before executing.\n if (rootIsStruct) {\n emitParamsFactory(sigEntries, names.paramsFn, paramsType, rootTypeTag, cb);\n cb.blank();\n }\n\n // Validation: walks the root binding and throws StyxValidationError on bad\n // input. Called first thing in the dict-style execute (below).\n emitValidate(\n ctx,\n rootType,\n ctx.expr,\n paramsType,\n names.validate,\n resolveTypeName(namedTypes),\n scope,\n cb,\n );\n cb.blank();\n\n emitBuildCargs(ctx, rootType, paramsType, names.cargs, cb);\n cb.blank();\n\n if (emitOutputs) {\n emitBuildOutputs(ctx, paramsType, names.outputs, names.outputsFn, cb);\n cb.blank();\n }\n\n // Dict-style execute function. For struct roots it's the internal\n // `<tool>Execute`; for other roots it doubles as the user-facing wrapper.\n const executeName = rootIsStruct ? names.execute : names.wrapper;\n emitWrapperFunction(\n ctx,\n paramsType,\n executeName,\n names.metadata,\n names.cargs,\n emitOutputs ? names.outputsFn : undefined,\n emitOutputs ? names.outputs : undefined,\n names.validate,\n streamFieldIds(ctx),\n cb,\n );\n cb.blank();\n\n // Kwarg-style wrapper (struct roots only): the v1-parity user-facing entry.\n if (rootIsStruct) {\n emitKwargWrapper(\n ctx,\n sigEntries,\n names.wrapper,\n names.paramsFn,\n names.execute,\n emitOutputs ? names.outputs : undefined,\n cb,\n );\n cb.blank();\n }\n\n return cb.toString();\n}\n\n/**\n * Module name (file stem) for an app: snake_case of app.id, fallback `output`.\n * Scrubbed so digit-leading app ids (e.g. `3dPFM` -> `v_3d_pfm`) and keyword\n * collisions don't break `export * from \"./<mod>.js\"` in the package index.\n */\nexport function appModuleName(meta: AppMeta | undefined): string {\n if (!meta?.id) return \"output\";\n return tsScrubIdent(snakeCase(meta.id), TS_RESERVED);\n}\n\n/**\n * The dispatch entrypoint for one app: its root `@type` (`<package>/<app>`) and\n * the dict-style execute function name. Returns undefined when the id or package\n * is unknown (no stable `@type`), so the app is left out of the suite dispatcher.\n */\nexport function appEntrypoint(ctx: CodegenContext): AppEntrypoint | undefined {\n const appId = ctx.app?.id;\n const pkg = ctx.package?.name;\n if (!appId || !pkg) return undefined;\n const publicNames = computePublicNames(appId);\n const rootIsStruct = ctx.resolve(ctx.expr)?.type.kind === \"struct\";\n const executeFn = tsScrubIdent(\n rootIsStruct ? publicNames.execute : publicNames.wrapper,\n TS_RESERVED,\n );\n return { type: `${pkg}/${appId}`, executeFn };\n}\n\n/**\n * Generate the suite-level `index.ts` re-export for a package containing\n * multiple tool modules. Each tool module's public symbols are surfaced via\n * `export * from \"./bet.js\"`. When apps carry a dispatch entrypoint, a\n * suite-level `execute(params, runner)` is appended that routes a config object\n * to the right tool by its root `@type`.\n */\nexport function generatePackageIndex(apps: EmittedApp[]): string {\n const cb = new CodeBuilder(\" \");\n cb.comment(\"This file was auto generated by Styx.\");\n cb.comment(\"Do not edit this file directly.\");\n cb.blank();\n\n const sortedApps = [...apps].sort((a, b) =>\n appModuleName(a.meta).localeCompare(appModuleName(b.meta)),\n );\n const dispatch = sortedApps\n .map((a) => ({ entry: a.entrypoint, mod: appModuleName(a.meta) }))\n .filter((x): x is { entry: AppEntrypoint; mod: string } => x.entry !== undefined);\n\n if (dispatch.length > 0) {\n cb.line(`import type { Runner } from \"styxdefs\";`);\n for (const d of dispatch) {\n cb.line(`import { ${d.entry.executeFn} } from \"./${d.mod}.js\";`);\n }\n cb.blank();\n }\n\n for (const mod of sortedApps.map((a) => appModuleName(a.meta))) {\n cb.line(`export * from \"./${mod}.js\";`);\n }\n\n if (dispatch.length > 0) {\n cb.blank();\n emitPackageDispatch(\n cb,\n dispatch.map((d) => d.entry),\n );\n }\n\n return cb.toString();\n}\n\n/** Emit the suite-level `execute(params, runner)` dispatcher over `@type`. */\nfunction emitPackageDispatch(cb: CodeBuilder, dispatch: AppEntrypoint[]): void {\n cb.line(\"/**\");\n cb.line(\" * Run a tool in this package from a params object, routed by its `@type`.\");\n cb.line(\" */\");\n cb.line(\n `export function execute(params: { \"@type\": string }, runner: Runner | null = null): unknown {`,\n );\n cb.indent(() => {\n cb.line(\"const dispatch: Record<string, (params: any, runner: Runner | null) => unknown> = {\");\n cb.indent(() => {\n for (const e of dispatch) {\n cb.line(`${JSON.stringify(e.type)}: ${e.executeFn},`);\n }\n });\n cb.line(\"};\");\n cb.line(`const fn = dispatch[params[\"@type\"]];`);\n cb.line(\"if (fn === undefined) {\");\n cb.indent(() => {\n cb.line(\"throw new Error(`No tool registered for @type '${params[\\\"@type\\\"]}'`);\");\n });\n cb.line(\"}\");\n cb.line(\"return fn(params, runner);\");\n });\n cb.line(\"}\");\n}\n\nexport class TypeScriptBackend implements Backend {\n readonly name = \"typescript\";\n readonly target = \"typescript\";\n\n emitApp(ctx: CodegenContext, scope?: Scope): EmittedApp {\n const code = generateTypeScript(ctx, scope);\n const fileName = `${appModuleName(ctx.app)}.ts`;\n return {\n meta: ctx.app,\n entrypoint: appEntrypoint(ctx),\n files: new Map([[fileName, code]]),\n errors: [],\n warnings: [],\n };\n }\n\n newPackageScope(): Scope {\n return new Scope(TS_RESERVED);\n }\n\n emitPackage(pkg: PackageMeta, apps: EmittedApp[]): EmittedPackage {\n return {\n meta: pkg,\n files: new Map([[\"index.ts\", generatePackageIndex(apps)]]),\n errors: [],\n warnings: [],\n };\n }\n\n emitProject(proj: ProjectMeta, packages: EmittedPackage[]): EmitResult {\n return {\n files: new Map([\n [\"package.json\", generatePackageJson(proj)],\n [\"index.ts\", generateRootIndex(packages)],\n [\"tsconfig.json\", generateTsconfig()],\n ]),\n errors: [],\n warnings: [],\n };\n }\n}\n","import type { CodegenContext } from \"../../manifest/index.js\";\nimport type { SnippetDialect, SnippetOptions } from \"../snippet-core.js\";\nimport { renderStructLiteral, renderValue } from \"../snippet-core.js\";\nimport { tsObjKey } from \"./emit.js\";\nimport { buildEmitModel } from \"./typescript.js\";\n\n/** Snippet rendering hooks for TypeScript (object literals, `true`/`null`). */\nconst tsDialect: SnippetDialect = {\n indentUnit: \" \",\n string: (s) => JSON.stringify(s),\n boolean: (b) => (b ? \"true\" : \"false\"),\n number: (n) => (Number.isFinite(n) ? String(n) : \"NaN\"),\n null: \"null\",\n objKey: tsObjKey,\n};\n\n/**\n * Render a TypeScript call snippet for one tool from a config object (keyed by\n * Boutiques wire names).\n *\n * The generated v2 kwarg wrapper takes *positional* arguments, which can't skip\n * a middle optional - so the runnable object-style entry is the dict-style\n * `<tool>Execute(params)` (struct roots). The snippet builds the params object\n * literal (wire-keyed, with the root `@type` injected) and passes it there.\n * Union- (or otherwise non-struct-) rooted tools call the dict-style `<tool>`\n * entry the same way. Nested structs / union variants / lists-of-structs have no\n * constructor in the generated code and render as object literals.\n *\n * The snippet matches the *standalone* (single-descriptor) emission of the same\n * context - which is how the hub compiles - not a catalog emission where a\n * shared package scope could suffix-bump a name.\n *\n * @param ctx - The compiled context (compile -> pipeline -> solve ->\n * resolveOutputs -> createContext, as in the CLI's `readAndCompile`).\n * @param config - The params object, keyed by Boutiques *wire* names. Every\n * union-typed value - including the root of a union-rooted tool - must carry\n * its `@type` discriminator so the variant can be matched; the root struct's\n * `@type` is supplied by the renderer, so omit it there.\n * @param opts - Import and package-root options.\n */\nexport function renderTypeScriptCall(\n ctx: CodegenContext,\n config: Record<string, unknown>,\n opts: SnippetOptions = {},\n): string {\n const model = buildEmitModel(ctx);\n const pkg = ctx.package?.name;\n const fnName = model.rootIsStruct ? model.names.execute : model.names.wrapper;\n const callee = pkg ? `${pkg}.${fnName}` : fnName;\n\n const arg =\n model.rootIsStruct && model.rootType.kind === \"struct\"\n ? renderStructLiteral(config, model.rootType, \"\", tsDialect, model.rootTypeTag)\n : renderValue(config, model.rootType, \"\", tsDialect);\n const call = `${callee}(${arg})`;\n\n if (opts.includeImport === false || !pkg) return call;\n const root = opts.packageRoot ?? ctx.project?.name ?? \"niwrap\";\n return `import { ${pkg} } from \"${root}\";\\n\\n${call}`;\n}\n","import type { AppMeta, Output, OutputToken } from \"./meta.js\";\nimport type { Expr } from \"./node.js\";\n\nexport function format(expr: Expr, meta?: AppMeta): string {\n const lines: string[] = [];\n\n if (meta) {\n lines.push(`app ${meta.id ?? \"unknown\"}${meta.version ? `@${meta.version}` : \"\"}`);\n if (meta.doc?.description) {\n lines.push(` \"${meta.doc.description}\"`);\n }\n if (meta.doc?.authors?.length) {\n lines.push(` authors: ${meta.doc.authors.join(\", \")}`);\n }\n if (meta.container) {\n lines.push(` container: ${meta.container.image}`);\n }\n if (meta.stdout) {\n lines.push(` stdout: ${meta.stdout.name}`);\n }\n if (meta.stderr) {\n lines.push(` stderr: ${meta.stderr.name}`);\n }\n lines.push(\"\");\n }\n\n lines.push(formatExpr(expr, 0));\n return lines.join(\"\\n\");\n}\n\nfunction formatOutputToken(token: OutputToken): string {\n if (token.kind === \"literal\") return JSON.stringify(token.value);\n const flags = [\n token.stripExtensions?.length && `strip=${JSON.stringify(token.stripExtensions)}`,\n token.fallback !== undefined && `fallback=${JSON.stringify(token.fallback)}`,\n ].filter(Boolean);\n const suffix = flags.length > 0 ? ` {${flags.join(\", \")}}` : \"\";\n return `ref(${token.target.name})${suffix}`;\n}\n\nfunction formatOutputsBlock(outputs: Output[], indent: number): string {\n const pad = \" \".repeat(indent);\n const lines = [`${pad}outputs:`];\n for (const out of outputs) {\n const name = out.name ?? \"<anon>\";\n const media = out.mediaTypes?.length ? ` (${out.mediaTypes.join(\", \")})` : \"\";\n const tokens = out.tokens.map(formatOutputToken).join(\" + \") || `\"\"`;\n lines.push(`${pad} ${name}${media}: ${tokens}`);\n }\n return lines.join(\"\\n\");\n}\n\n// Splice the outputs block in right after the node's header line (its first\n// line), before any child lines, so outputs read naturally as belonging to\n// the node they decorate.\nfunction spliceOutputs(body: string, outputsBlock: string): string {\n if (!outputsBlock) return body;\n const nl = body.indexOf(\"\\n\");\n if (nl === -1) return `${body}\\n${outputsBlock}`;\n return `${body.slice(0, nl)}\\n${outputsBlock}${body.slice(nl)}`;\n}\n\nfunction formatExpr(expr: Expr, indent: number): string {\n const pad = \" \".repeat(indent);\n const name = expr.meta?.name ? ` [${expr.meta.name}]` : \"\";\n const outputsBlock = expr.meta?.outputs?.length\n ? formatOutputsBlock(expr.meta.outputs, indent + 1)\n : \"\";\n\n let body: string;\n switch (expr.kind) {\n case \"literal\":\n body = `${pad}literal${name} \"${expr.attrs.str}\"`;\n break;\n\n case \"str\":\n body = `${pad}str${name}`;\n break;\n\n case \"int\": {\n const { minValue, maxValue } = expr.attrs;\n const range =\n minValue !== undefined || maxValue !== undefined\n ? ` (${minValue ?? \"\"}..${maxValue ?? \"\"})`\n : \"\";\n body = `${pad}int${name}${range}`;\n break;\n }\n\n case \"float\": {\n const { minValue, maxValue } = expr.attrs;\n const range =\n minValue !== undefined || maxValue !== undefined\n ? ` (${minValue ?? \"\"}..${maxValue ?? \"\"})`\n : \"\";\n body = `${pad}float${name}${range}`;\n break;\n }\n\n case \"path\": {\n const flags = [\n expr.attrs.resolveParent && \"resolveParent\",\n expr.attrs.mutable && \"mutable\",\n ].filter(Boolean);\n const suffix = flags.length > 0 ? ` {${flags.join(\", \")}}` : \"\";\n body = `${pad}path${name}${suffix}`;\n break;\n }\n\n case \"sequence\": {\n const join = expr.attrs.join !== undefined ? ` join=\"${expr.attrs.join}\"` : \"\";\n const header = `${pad}sequence${name}${join}`;\n if (expr.attrs.nodes.length === 0) {\n body = `${header} (empty)`;\n } else {\n const children = expr.attrs.nodes.map((n) => formatExpr(n, indent + 1)).join(\"\\n\");\n body = `${header}\\n${children}`;\n }\n break;\n }\n\n case \"alternative\": {\n const header = `${pad}alternative${name}`;\n const children = expr.attrs.alts.map((n) => formatExpr(n, indent + 1)).join(\"\\n\");\n body = `${header}\\n${children}`;\n break;\n }\n\n case \"optional\": {\n const header = `${pad}optional${name}`;\n const child = formatExpr(expr.attrs.node, indent + 1);\n body = `${header}\\n${child}`;\n break;\n }\n\n case \"repeat\": {\n const { join, countMin, countMax } = expr.attrs;\n const parts = [\n join !== undefined && `join=\"${join}\"`,\n countMin !== undefined && `min=${countMin}`,\n countMax !== undefined && `max=${countMax}`,\n ].filter(Boolean);\n const suffix = parts.length > 0 ? ` {${parts.join(\", \")}}` : \"\";\n const header = `${pad}repeat${name}${suffix}`;\n const child = formatExpr(expr.attrs.node, indent + 1);\n body = `${header}\\n${child}`;\n break;\n }\n\n default: {\n const _exhaustive: never = expr;\n body = `${pad}unknown`;\n }\n }\n\n return spliceOutputs(body, outputsBlock);\n}\n","import type { NodeMeta } from \"./meta.js\";\nimport type { MediaTypeIdentifier } from \"./types.js\";\n\n/** Base structure for all IR nodes */\ninterface BaseNode<K extends string, Attrs> {\n kind: K;\n meta?: NodeMeta;\n attrs: Attrs;\n}\n\n// Structural nodes\n\nexport type Literal = BaseNode<\n \"literal\",\n {\n str: string;\n }\n>;\n\nexport type Sequence = BaseNode<\n \"sequence\",\n {\n nodes: Expr[];\n join?: string;\n }\n>;\n\nexport type Optional = BaseNode<\n \"optional\",\n {\n node: Expr;\n }\n>;\n\nexport type Alternative = BaseNode<\n \"alternative\",\n {\n alts: Expr[];\n }\n>;\n\nexport type Repeat = BaseNode<\n \"repeat\",\n {\n node: Expr;\n join?: string;\n countMin?: number;\n countMax?: number;\n }\n>;\n\n// Terminal nodes\n\nexport type Int = BaseNode<\n \"int\",\n {\n minValue?: number;\n maxValue?: number;\n }\n>;\n\nexport type Float = BaseNode<\n \"float\",\n {\n minValue?: number;\n maxValue?: number;\n }\n>;\n\nexport type Str = BaseNode<\"str\", Record<string, never>>;\n\nexport type Path = BaseNode<\n \"path\",\n {\n resolveParent?: boolean;\n mutable?: boolean;\n mediaTypes?: MediaTypeIdentifier[];\n }\n>;\n\n// Union types\n\nexport type StructuralNode = Sequence | Optional | Alternative | Repeat;\nexport type Terminal = Literal | Int | Float | Str | Path;\nexport type Expr = StructuralNode | Terminal;\n\n// Type guards\n\nexport function isTerminal(expr: Expr): expr is Terminal {\n return [\"literal\", \"int\", \"float\", \"str\", \"path\"].includes(expr.kind);\n}\n\nexport function isStructural(expr: Expr): expr is StructuralNode {\n return [\"sequence\", \"optional\", \"alternative\", \"repeat\"].includes(expr.kind);\n}\n","import type { Expr } from \"../node.js\";\n\nexport enum PassStatus {\n Unchanged = \"unchanged\",\n Changed = \"changed\",\n ChangedNeedsRerun = \"changed-needs-rerun\",\n}\n\nexport interface PassResult {\n expr: Expr;\n status: PassStatus;\n warnings?: string[];\n}\n\nexport interface Pass {\n readonly name: string;\n apply(expr: Expr): PassResult;\n}\n\nexport function compose(...passes: Pass[]): Pass {\n return {\n name: passes.map((p) => p.name).join(\" → \"),\n apply(expr: Expr): PassResult {\n let current = expr;\n let overallStatus = PassStatus.Unchanged;\n const warnings: string[] = [];\n\n for (const pass of passes) {\n const result = pass.apply(current);\n current = result.expr;\n\n if (result.status !== PassStatus.Unchanged) {\n overallStatus = result.status;\n }\n if (result.warnings) {\n warnings.push(...result.warnings);\n }\n }\n\n return {\n expr: current,\n status: overallStatus,\n ...(warnings.length > 0 && { warnings }),\n };\n },\n };\n}\n\nexport function fixpoint(pass: Pass, maxIterations = 10): Pass {\n return {\n name: `fixpoint(${pass.name})`,\n apply(expr: Expr): PassResult {\n let current = expr;\n const allWarnings: string[] = [];\n\n for (let i = 0; i < maxIterations; ++i) {\n const result = pass.apply(current);\n\n if (result.warnings) {\n allWarnings.push(...result.warnings);\n }\n\n // Stop if unchanged or no rerun needed\n if (result.status !== PassStatus.ChangedNeedsRerun) {\n return {\n expr: result.expr,\n status:\n result.status === PassStatus.Unchanged ? PassStatus.Unchanged : PassStatus.Changed,\n ...(allWarnings.length > 0 && { warnings: allWarnings }),\n };\n }\n\n current = result.expr;\n }\n\n return {\n expr: current,\n status: PassStatus.Changed,\n warnings: [\n ...allWarnings,\n `${pass.name} did not converge after ${maxIterations} iterations`,\n ],\n };\n },\n };\n}\n","import type { Expr } from \"../node.js\";\nimport { PassStatus, type Pass, type PassResult } from \"./pass.js\";\n\n/**\n * Canonicalize IR for consistent representation:\n * - Sort alternatives by kind, then name, then structure\n * - Deduplicate identical alternatives\n */\nexport const canonicalize: Pass = {\n name: \"canonicalize\",\n apply(expr: Expr): PassResult {\n let changed = false;\n\n function structuralHash(node: Expr): string {\n switch (node.kind) {\n case \"literal\":\n return `lit:${node.attrs.str}`;\n case \"int\":\n return `int:${node.attrs.minValue ?? \"\"}:${node.attrs.maxValue ?? \"\"}`;\n case \"float\":\n return `float:${node.attrs.minValue ?? \"\"}:${node.attrs.maxValue ?? \"\"}`;\n case \"str\":\n return \"str\";\n case \"path\":\n return `path:${node.attrs.resolveParent ?? \"\"}:${node.attrs.mutable ?? \"\"}`;\n case \"optional\":\n return `opt:${structuralHash(node.attrs.node)}`;\n case \"repeat\":\n return `rep:${node.attrs.join ?? \"\"}:${structuralHash(node.attrs.node)}`;\n case \"sequence\":\n return `seq:${node.attrs.join ?? \"\"}:${node.attrs.nodes.map(structuralHash).join(\",\")}`;\n case \"alternative\":\n return `alt:${node.attrs.alts.map(structuralHash).join(\",\")}`;\n default: {\n const _exhaustive: never = node;\n return \"\";\n }\n }\n }\n\n function sortKey(node: Expr): string {\n const name = node.meta?.name ?? \"\";\n return `${node.kind}:${name}:${structuralHash(node)}`;\n }\n\n function visit(node: Expr): Expr {\n switch (node.kind) {\n case \"alternative\": {\n const children = node.attrs.alts.map(visit);\n\n // Sort alternatives\n const sorted = [...children].sort((a, b) => sortKey(a).localeCompare(sortKey(b)));\n\n // Deduplicate by structural hash\n const seen = new Set<string>();\n const alts: Expr[] = [];\n for (const child of sorted) {\n const hash = structuralHash(child);\n if (!seen.has(hash)) {\n seen.add(hash);\n alts.push(child);\n } else {\n changed = true;\n }\n }\n\n // Check if order changed\n if (\n alts.length !== children.length ||\n alts.some((alt, i) => structuralHash(alt) !== structuralHash(children[i]!))\n ) {\n changed = true;\n }\n\n return { ...node, attrs: { ...node.attrs, alts } };\n }\n\n case \"sequence\": {\n const nodes = node.attrs.nodes.map(visit);\n return { ...node, attrs: { ...node.attrs, nodes } };\n }\n\n case \"optional\":\n return { ...node, attrs: { node: visit(node.attrs.node) } };\n\n case \"repeat\":\n return { ...node, attrs: { ...node.attrs, node: visit(node.attrs.node) } };\n\n case \"literal\":\n case \"int\":\n case \"float\":\n case \"str\":\n case \"path\":\n return node;\n\n default: {\n const _exhaustive: never = node;\n return node;\n }\n }\n }\n\n return {\n expr: visit(expr),\n status: changed ? PassStatus.Changed : PassStatus.Unchanged,\n };\n },\n};\n","import type { Expr } from \"../node.js\";\nimport { PassStatus, type Pass, type PassResult } from \"./pass.js\";\n\n/**\n * Flatten passes\n * - seq(a, seq(b, c)) -> seq(a, b, c)\n * - alt(a, alt(b, c)) -> alt(a, b, c)\n */\nexport const flatten: Pass = {\n name: \"flatten\",\n apply(expr: Expr): PassResult {\n let changed = false;\n\n function visit(node: Expr): Expr {\n switch (node.kind) {\n case \"sequence\": {\n const children = node.attrs.nodes.map(visit);\n const nodes: Expr[] = [];\n\n for (const child of children) {\n if (child.kind === \"sequence\" && child.attrs.join === node.attrs.join && !child.meta) {\n changed = true;\n nodes.push(...child.attrs.nodes);\n } else {\n nodes.push(child);\n }\n }\n\n return { ...node, attrs: { ...node.attrs, nodes } };\n }\n\n case \"alternative\": {\n const children = node.attrs.alts.map(visit);\n const alts: Expr[] = [];\n\n for (const child of children) {\n if (child.kind === \"alternative\" && !child.meta) {\n changed = true;\n alts.push(...child.attrs.alts);\n } else {\n alts.push(child);\n }\n }\n\n return { ...node, attrs: { ...node.attrs, alts } };\n }\n\n case \"optional\":\n return { ...node, attrs: { node: visit(node.attrs.node) } };\n\n case \"repeat\":\n return { ...node, attrs: { ...node.attrs, node: visit(node.attrs.node) } };\n\n case \"literal\":\n case \"int\":\n case \"float\":\n case \"str\":\n case \"path\":\n return node;\n\n default: {\n const _exhaustive: never = node;\n return node;\n }\n }\n }\n\n return {\n expr: visit(expr),\n status: changed ? PassStatus.Changed : PassStatus.Unchanged,\n };\n },\n};\n","import type { Expr } from \"../node.js\";\nimport { PassStatus, type Pass, type PassResult } from \"./pass.js\";\n\n/**\n * Remove empty nodes:\n * - seq() → removed\n * - alt() → removed\n * - opt(seq()) → removed\n * - rep(alt()) → removed\n */\nexport const removeEmpty: Pass = {\n name: \"remove-empty\",\n apply(expr: Expr): PassResult {\n let changed = false;\n\n function isEmpty(node: Expr): boolean {\n return (\n (node.kind === \"sequence\" && node.attrs.nodes.length === 0) ||\n (node.kind === \"alternative\" && node.attrs.alts.length === 0)\n );\n }\n\n function isRemovable(node: Expr): boolean {\n if (node.meta) return false; // Preserve metadata\n return (\n isEmpty(node) ||\n ((node.kind === \"optional\" || node.kind === \"repeat\") && isEmpty(node.attrs.node))\n );\n }\n\n function visit(node: Expr): Expr {\n switch (node.kind) {\n case \"sequence\": {\n const nodes = node.attrs.nodes.map(visit).filter((child) => {\n const removable = isRemovable(child);\n if (removable) changed = true;\n return !removable;\n });\n return { ...node, attrs: { ...node.attrs, nodes } };\n }\n\n case \"alternative\": {\n const alts = node.attrs.alts.map(visit).filter((child) => {\n const removable = isRemovable(child);\n if (removable) changed = true;\n return !removable;\n });\n return { ...node, attrs: { ...node.attrs, alts } };\n }\n\n case \"optional\":\n return { ...node, attrs: { node: visit(node.attrs.node) } };\n\n case \"repeat\":\n return { ...node, attrs: { ...node.attrs, node: visit(node.attrs.node) } };\n\n case \"literal\":\n case \"int\":\n case \"float\":\n case \"str\":\n case \"path\":\n return node;\n\n default: {\n const _exhaustive: never = node;\n return node;\n }\n }\n }\n\n return {\n expr: visit(expr),\n status: changed ? PassStatus.Changed : PassStatus.Unchanged,\n };\n },\n};\n","import type { NodeMeta } from \"../meta.js\";\nimport type { Expr } from \"../node.js\";\nimport { PassStatus, type Pass, type PassResult } from \"./pass.js\";\n\n/**\n * Merge two `NodeMeta` when collapsing a wrapper layer (the child is the\n * inner/surviving node). Name, doc fields and defaultValue take the innermost\n * value; `outputs` from both layers are concatenated so an output attached to\n * a collapsed wrapper survives on whatever node absorbs it.\n */\nfunction mergeMeta(parent?: NodeMeta, child?: NodeMeta): NodeMeta | undefined {\n if (!parent && !child) return undefined;\n if (!parent) return child;\n if (!child) return parent;\n\n const merged: NodeMeta = {};\n\n const name = child.name ?? parent.name;\n if (name !== undefined) merged.name = name;\n\n // The variant tag is the union discriminator (the sub-command id); unlike\n // `name` it must survive a single-field sub-command collapsing onto its inner\n // field (whose `name` wins above), so the `@type` stays the sub-command id\n // rather than the inner field's id. The parent (the sub-command wrapper)\n // carries it; the inner field has none.\n const variantTag = parent.variantTag ?? child.variantTag;\n if (variantTag !== undefined) merged.variantTag = variantTag;\n\n const defaultValue = child.defaultValue ?? parent.defaultValue;\n if (defaultValue !== undefined) merged.defaultValue = defaultValue;\n\n if (parent.doc || child.doc) {\n merged.doc = {\n title: child.doc?.title ?? parent.doc?.title,\n description: child.doc?.description ?? parent.doc?.description,\n authors: [...(parent.doc?.authors ?? []), ...(child.doc?.authors ?? [])],\n literature: [...(parent.doc?.literature ?? []), ...(child.doc?.literature ?? [])],\n urls: [...(parent.doc?.urls ?? []), ...(child.doc?.urls ?? [])],\n comment: child.doc?.comment ?? parent.doc?.comment,\n };\n }\n\n const outputs = [...(parent.outputs ?? []), ...(child.outputs ?? [])];\n if (outputs.length > 0) merged.outputs = outputs;\n\n return merged;\n}\n\n/**\n * Simplify passes:\n * - optional(optional(T)) -> optional(T)\n * - repeat(repeat(T)) -> repeat(T) with merged constraints\n * - seq(T) -> T, alt(T) -> T (singleton unwrapping)\n * - seq(lit(\"a\"), lit(\"b\")) -> seq(lit(\"ab\")) (merge consecutive literals)\n *\n * Every collapse that drops a wrapper layer merges that layer's `NodeMeta`\n * into the surviving node via `mergeMeta`, so names and attached outputs are\n * never lost.\n */\nexport const simplify: Pass = {\n name: \"simplify\",\n apply(expr: Expr): PassResult {\n let changed = false;\n\n function visit(node: Expr): Expr {\n switch (node.kind) {\n case \"optional\": {\n const inner = visit(node.attrs.node);\n\n // optional(optional(T)) -> optional(T)\n if (inner.kind === \"optional\") {\n changed = true;\n return {\n ...node,\n attrs: { node: inner.attrs.node },\n meta: mergeMeta(node.meta, inner.meta),\n };\n }\n\n return { ...node, attrs: { node: inner } };\n }\n\n case \"repeat\": {\n const inner = visit(node.attrs.node);\n\n // repeat(repeat(T)) -> repeat(T) with merged constraints\n if (inner.kind === \"repeat\") {\n changed = true;\n return {\n ...node,\n attrs: {\n node: inner.attrs.node,\n join: node.attrs.join ?? inner.attrs.join,\n countMin: Math.max(node.attrs.countMin ?? 0, inner.attrs.countMin ?? 0),\n countMax:\n node.attrs.countMax === undefined || inner.attrs.countMax === undefined\n ? undefined\n : Math.min(node.attrs.countMax, inner.attrs.countMax),\n },\n meta: mergeMeta(node.meta, inner.meta),\n };\n }\n\n return { ...node, attrs: { ...node.attrs, node: inner } };\n }\n\n case \"sequence\": {\n const children = node.attrs.nodes.map(visit);\n\n // Merge consecutive metadata-less literals, but only in an explicit\n // concatenation context (`join === \"\"`). The merge is separator-free\n // (`prev.str += child.str`), which only matches the semantics of an\n // empty join. A sequence with no join joins its children with a space\n // (they become separate argv tokens at the top level), so merging\n // adjacent literals there would wrongly fuse two arguments into one\n // (e.g. `seq(lit(\"wb_command\"), lit(\"-foo\"))` -> `\"wb_command-foo\"`).\n // Inside a join context the backend concatenates anyway, so leaving\n // such literals unmerged stays correct (just one node larger).\n const nodes: Expr[] = [];\n for (const child of children) {\n const prev = nodes[nodes.length - 1];\n if (\n prev?.kind === \"literal\" &&\n child.kind === \"literal\" &&\n !prev.meta &&\n !child.meta &&\n node.attrs.join === \"\"\n ) {\n changed = true;\n prev.attrs.str += child.attrs.str;\n } else {\n nodes.push(child);\n }\n }\n\n // seq(T) -> T, carrying the seq's meta down onto the child.\n if (nodes.length === 1) {\n const child = nodes[0]!;\n changed = true;\n const mergedMeta = mergeMeta(node.meta, child.meta);\n return mergedMeta ? { ...child, meta: mergedMeta } : child;\n }\n\n return { ...node, attrs: { ...node.attrs, nodes } };\n }\n\n case \"alternative\": {\n const alts = node.attrs.alts.map(visit);\n\n // alt(T) -> T. Only when the alt carries no metadata of its own\n // (otherwise the collapse would orphan it).\n if (alts.length === 1 && !node.meta) {\n changed = true;\n return alts[0]!;\n }\n\n return { ...node, attrs: { ...node.attrs, alts } };\n }\n\n case \"literal\":\n case \"int\":\n case \"float\":\n case \"str\":\n case \"path\":\n return node;\n\n default: {\n const _exhaustive: never = node;\n return node;\n }\n }\n }\n\n return {\n expr: visit(expr),\n status: changed ? PassStatus.Changed : PassStatus.Unchanged,\n };\n },\n};\n","// import { canonicalize } from \"./canonicalize.js\";\nimport { flatten } from \"./flatten.js\";\nimport type { Pass } from \"./pass.js\";\nimport { compose, fixpoint } from \"./pass.js\";\nimport { removeEmpty } from \"./remove-empty.js\";\nimport { simplify } from \"./simplify.js\";\n\nexport const defaultPipeline: Pass = fixpoint(\n compose(flatten, removeEmpty, simplify /* canonicalize */),\n);\n\nexport function createPipeline(\n passes: Pass[],\n options?: { fixpoint?: boolean; maxIterations?: number },\n): Pass {\n const composed = compose(...passes);\n if (options?.fixpoint) {\n return fixpoint(composed, options.maxIterations);\n }\n return composed;\n}\n","import type {\n BindingRegistry,\n OutputScope,\n OutputValidationResult,\n SolveResult,\n} from \"../bindings/index.js\";\nimport type { AppMeta, Expr } from \"../ir/index.js\";\nimport type { OutputResolution } from \"../solver/index.js\";\nimport type { PackageMeta, ProjectMeta } from \"./types.js\";\n\nexport interface CodegenContext {\n expr: Expr;\n bindings: BindingRegistry;\n resolve: SolveResult[\"resolve\"];\n outputScopes: OutputScope[];\n outputDiagnostics: OutputValidationResult;\n app?: AppMeta;\n package?: PackageMeta;\n project?: ProjectMeta;\n}\n\nexport function createContext(\n expr: Expr,\n solveResult: SolveResult,\n outputs: OutputResolution,\n meta?: { app?: AppMeta; package?: PackageMeta; project?: ProjectMeta },\n): CodegenContext {\n return {\n expr,\n bindings: solveResult.bindings,\n resolve: solveResult.resolve,\n outputScopes: outputs.scopes,\n outputDiagnostics: outputs.diagnostics,\n ...meta,\n };\n}\n","import type {\n Binding,\n BindingId,\n BoundType,\n OutputDiagnostic,\n OutputScope,\n OutputValidationResult,\n ResolvedOutput,\n ResolvedToken,\n SolveResult,\n} from \"../bindings/index.js\";\nimport type { Expr, Output } from \"../ir/index.js\";\nimport { effectiveOutputName } from \"../ir/index.js\";\n\nexport interface OutputResolution {\n scopes: OutputScope[];\n diagnostics: OutputValidationResult;\n}\n\n/**\n * Per-binding map keyed by `Binding.name`. Frontends attach outputs to the\n * declaring struct, so refs name fields visible in that scope (the resolver\n * accepts a single global name index because optimization can move bindings\n * around but never duplicates names within a scope).\n */\ninterface NameIndex {\n byName: Map<string, Binding>;\n}\n\n/**\n * Whether a binding resolves to a value that can be interpolated into an output\n * path token. Scalars/bool/count/literals (and optional/list wrappers of them)\n * carry a concrete value; structs and complex unions do not.\n *\n * This drives the name-tie preference below: an unnamed multi-field struct\n * inherits its first field's name (`findDeepName`), so a struct and its scalar\n * field can share a name. An output ref always means the value, so the\n * interpolable binding must win regardless of which sits shallower.\n */\nfunction isInterpolable(type: BoundType): boolean {\n switch (type.kind) {\n case \"optional\":\n return isInterpolable(type.inner);\n case \"list\":\n return isInterpolable(type.item);\n case \"struct\":\n return false;\n case \"union\":\n // Pure-enum unions are interpolable (the value is a literal); a union with\n // any struct variant is not.\n return type.variants.every((v) => isInterpolable(v.type));\n default:\n return true;\n }\n}\n\n/**\n * `includeRoot` controls whether the binding on `root` itself (depth 0) is\n * indexed. The global index excludes it (a ref must never resolve to the root\n * struct, which shares its name with a deep field via `findDeepName`). A\n * scope-local index includes it: a collapsed single-field union arm boxes its\n * lone field's binding onto the scope node itself (e.g. ants DenoiseImage's\n * `correctedOutputFileName` arm), and that binding - with the field's access\n * path and the arm's variant gate - is exactly what the arm's output ref needs.\n */\nfunction indexBindingsByName(\n root: Expr,\n resolve: (n: Expr) => Binding | undefined,\n includeRoot = false,\n): NameIndex {\n const byNameDepth = new Map<string, { binding: Binding; depth: number }>();\n function walk(node: Expr, depth: number): void {\n const binding = resolve(node);\n if (binding && (depth > 0 || includeRoot)) {\n const existing = byNameDepth.get(binding.name);\n if (!existing || preferCandidate({ binding, depth }, existing)) {\n byNameDepth.set(binding.name, { binding, depth });\n }\n }\n switch (node.kind) {\n case \"sequence\":\n for (const child of node.attrs.nodes) walk(child, depth + 1);\n break;\n case \"optional\":\n case \"repeat\":\n walk(node.attrs.node, depth + 1);\n break;\n case \"alternative\":\n for (const alt of node.attrs.alts) walk(alt, depth + 1);\n break;\n }\n }\n walk(root, 0);\n const byName = new Map<string, Binding>();\n for (const [name, { binding }] of byNameDepth) byName.set(name, binding);\n return { byName };\n}\n\n/**\n * Decide whether `cand` should replace `existing` for a shared name. An\n * interpolable binding always beats a structured one (the struct/scalar name\n * collision); otherwise the shallowest binding wins, as before.\n */\nfunction preferCandidate(\n cand: { binding: Binding; depth: number },\n existing: { binding: Binding; depth: number },\n): boolean {\n const candLeaf = isInterpolable(cand.binding.type);\n const exLeaf = isInterpolable(existing.binding.type);\n if (candLeaf !== exLeaf) return candLeaf;\n return cand.depth < existing.depth;\n}\n\n/**\n * Walk the IR collecting `(node, outputs)` pairs in tree order. Outputs attach\n * to struct/sequence nodes by frontend convention.\n */\nfunction collectScopes(root: Expr): { node: Expr; outputs: Output[] }[] {\n const out: { node: Expr; outputs: Output[] }[] = [];\n function walk(node: Expr): void {\n if (node.meta?.outputs?.length) out.push({ node, outputs: node.meta.outputs });\n switch (node.kind) {\n case \"sequence\":\n for (const child of node.attrs.nodes) walk(child);\n break;\n case \"optional\":\n case \"repeat\":\n walk(node.attrs.node);\n break;\n case \"alternative\":\n for (const alt of node.attrs.alts) walk(alt);\n break;\n }\n }\n walk(root);\n return out;\n}\n\nfunction resolveOne(\n output: Output,\n index: number,\n localNames: NameIndex,\n globalNames: NameIndex,\n): { resolved: ResolvedOutput; errors: OutputDiagnostic[] } {\n const errors: OutputDiagnostic[] = [];\n const name = effectiveOutputName(output, index);\n const tokens: ResolvedToken[] = [];\n for (const token of output.tokens) {\n if (token.kind === \"literal\") {\n tokens.push({ kind: \"literal\", value: token.value });\n continue;\n }\n // Prefer a binding declared within the output's own scope subtree. Union\n // arms duplicate field names across scopes (each arm is its own scope), so\n // the global index alone would resolve an arm's output ref to a sibling\n // arm's binding, mixing contradictory variant gates into one output. Fall\n // back to the global index for refs to bindings outside the local subtree.\n const binding =\n localNames.byName.get(token.target.name) ?? globalNames.byName.get(token.target.name);\n if (!binding) {\n errors.push({\n output: name,\n level: \"error\",\n message: `token ref '${token.target.name}' has no binding with that name (frontend produced an inconsistent output spec)`,\n });\n continue;\n }\n tokens.push({\n kind: \"ref\",\n binding: binding.id,\n ...(token.stripExtensions && { stripExtensions: token.stripExtensions }),\n ...(token.fallback !== undefined && { fallback: token.fallback }),\n });\n }\n const resolved: ResolvedOutput = {\n name,\n ...(output.doc && { doc: output.doc }),\n tokens,\n ...(output.mediaTypes && { mediaTypes: output.mediaTypes }),\n };\n return { resolved, errors };\n}\n\n/**\n * Translate each `NodeMeta.outputs` entry against the binding registry,\n * grouped by the declaring struct binding (the \"scope\"). The solver forces a\n * binding on every output-carrying sequence, so an output without a scope\n * binding indicates a frontend bug (outputs attached to a non-sequence\n * node) - it is reported as a diagnostic and dropped.\n */\nexport function resolveOutputs(root: Expr, solved: SolveResult): OutputResolution {\n const names = indexBindingsByName(root, solved.resolve);\n const collected = collectScopes(root);\n\n const byScope = new Map<BindingId, OutputScope>();\n const errors: OutputDiagnostic[] = [];\n const warnings: OutputDiagnostic[] = [];\n\n let outputIndex = 0;\n for (const { node, outputs } of collected) {\n const scopeBinding = solved.resolve(node);\n if (!scopeBinding) {\n for (const output of outputs) {\n const name = effectiveOutputName(output, outputIndex++);\n errors.push({\n output: name,\n level: \"error\",\n message: `output '${name}' is attached to a node without a binding (frontends should attach outputs to struct sequences)`,\n });\n }\n continue;\n }\n let bucket = byScope.get(scopeBinding.id);\n if (!bucket) {\n bucket = { scope: scopeBinding.id, outputs: [] };\n byScope.set(scopeBinding.id, bucket);\n }\n // Index only the bindings within this scope's subtree (including the scope\n // node's own binding), so an output ref resolves to the field declared in\n // the same scope (union arm) before falling back to the global index.\n const localNames = indexBindingsByName(node, solved.resolve, true);\n for (const output of outputs) {\n const { resolved, errors: outErrors } = resolveOne(output, outputIndex++, localNames, names);\n errors.push(...outErrors);\n bucket.outputs.push(resolved);\n }\n }\n\n return {\n scopes: Array.from(byScope.values()),\n diagnostics: { errors, warnings },\n };\n}\n","import type { AccessPath, AccessSegment, Binding, BoundType } from \"../bindings/index.js\";\nimport type { Expr } from \"../ir/index.js\";\n\n/**\n * Attach `Binding.access` to every binding by walking the IR once, threading\n * the same scope state the backend walkers used to re-derive independently\n * (`arg-builder.walk` and `outputs-emit.walkAccess`). Producing the paths here,\n * after types settle, collapses both walkers into pure `renderAccess` lookups\n * and removes the drift class between them.\n *\n * The walk faithfully mirrors the (post-`ca61dc8`) arg-builder/outputs-emit\n * scope handling for sequence/optional/alternative, and adopts the\n * arg-builder's `repeat` recursion (which `walkAccess` lacked) so bindings\n * inside a `repeat`-of-list get an `iter`-rooted path instead of being absent.\n */\nexport function assignAccessPaths(expr: Expr, resolve: (node: Expr) => Binding | undefined): void {\n const rootBinding = resolve(expr);\n walk(expr, resolve, { path: [], currentStructType: rootBinding?.type });\n}\n\n/**\n * Scope state threaded down the walk, mirroring the arg-builder's `ArgContext`\n * but carrying structured paths instead of rendered strings.\n */\ninterface AccessCtx {\n /** Access path of the enclosing struct scope (the base for child fields). */\n path: AccessPath;\n /**\n * When set, the next binding's value lives at this exact path rather than at\n * `path + field(name)` - the wrapper collapsed the inner value onto its own\n * path (`optional<scalar>`/`optional<bool>`, scalar lists). Mirrors the\n * arg-builder's `directValue`. Not a rendered segment: it is \"inherit the\n * parent's path, append nothing\".\n */\n directPath?: AccessPath;\n /** The struct type at the current scope level (prevents double-scoping). */\n currentStructType?: BoundType;\n}\n\nfunction field(name: string): AccessSegment {\n return { kind: \"field\", name };\n}\n\nfunction iter(binding: string): AccessSegment {\n return { kind: \"iter\", binding };\n}\n\n/** The path at which a binding's own value lives in the current scope. */\nfunction ownAccess(arg: AccessCtx, name: string): AccessPath {\n return arg.directPath ?? [...arg.path, field(name)];\n}\n\n/** Whether a BoundType contains a struct that requires scoping when entered. */\nfunction hasStructScope(type: BoundType): boolean {\n switch (type.kind) {\n case \"optional\":\n return hasStructScope(type.inner);\n case \"list\":\n return hasStructScope(type.item);\n case \"struct\":\n return true;\n default:\n return false;\n }\n}\n\n/** Unwrap optional/list to find the inner struct type, if any. */\nfunction unwrapToStruct(type: BoundType): Extract<BoundType, { kind: \"struct\" }> | undefined {\n switch (type.kind) {\n case \"optional\":\n return unwrapToStruct(type.inner);\n case \"list\":\n return unwrapToStruct(type.item);\n case \"struct\":\n return type;\n default:\n return undefined;\n }\n}\n\nfunction walk(node: Expr, resolve: (node: Expr) => Binding | undefined, arg: AccessCtx): void {\n const binding = resolve(node);\n\n switch (node.kind) {\n case \"literal\":\n return;\n\n case \"int\":\n case \"float\":\n case \"str\":\n case \"path\": {\n if (binding) binding.access = ownAccess(arg, binding.name);\n return;\n }\n\n case \"sequence\": {\n let childArg = arg;\n if (binding && hasStructScope(binding.type) && binding.type !== arg.currentStructType) {\n // A nested struct: children access fields under this binding's path.\n const access: AccessPath = [...arg.path, field(binding.name)];\n binding.access = access;\n childArg = {\n path: access,\n currentStructType: unwrapToStruct(binding.type) ?? arg.currentStructType,\n };\n } else if (binding) {\n // Root struct or a struct already scoped by an enclosing wrapper: the\n // binding reuses the current path (collapse / already-scoped).\n binding.access = arg.directPath ?? arg.path;\n }\n for (const child of node.attrs.nodes) walk(child, resolve, childArg);\n return;\n }\n\n case \"optional\": {\n if (!binding) {\n walk(node.attrs.node, resolve, arg);\n return;\n }\n const access: AccessPath = [...arg.path, field(binding.name)];\n binding.access = access;\n // The inner node, after unwrapping the optional from the binding type.\n const innerType = binding.type.kind === \"optional\" ? binding.type.inner : binding.type;\n let childArg: AccessCtx;\n if (binding.type === arg.currentStructType) {\n // This optional IS the boxed single-field union variant: a collapsed\n // single-input arm whose type the solver retyped to the variant's\n // struct (so `binding.type === currentStructType`). It maps to the\n // variant's lone field, so the inner value collapses onto this\n // optional's own field access. Without this, the struct-scope branch\n // below would add a spurious extra segment named after the inner IR\n // node (e.g. `params.opts.exponential_options.smoothing_standard_deviation`)\n // instead of the boxed field (`params.opts.exponential_options`). The\n // sequence case guards the same way via its `!== currentStructType` test.\n childArg = { ...arg, directPath: access };\n } else if (innerType.kind === \"list\") {\n // optional<list>: the inner node is a `repeat` that represents this same\n // value and assigns its own (iter-based) child scope. It must reuse this\n // optional's path rather than append its field again - otherwise a\n // struct-list field whose name matches the optional's collides into a\n // doubled path (`params.config.config`). `directPath` = \"inherit this\n // path, append nothing\". Scalar lists already reached here via the\n // optional/bool branch below; struct lists previously fell into the\n // `hasStructScope` branch and got the doubled path.\n childArg = { ...arg, directPath: access };\n } else if (hasStructScope(binding.type)) {\n childArg = {\n path: access,\n currentStructType: unwrapToStruct(binding.type) ?? arg.currentStructType,\n };\n } else if (binding.type.kind === \"optional\" || binding.type.kind === \"bool\") {\n // Collapsed non-struct: the inner value lives at the optional's path.\n childArg = { ...arg, directPath: access };\n } else {\n childArg = arg;\n }\n walk(node.attrs.node, resolve, childArg);\n return;\n }\n\n case \"repeat\": {\n // The solver always binds repeat nodes, so this is defensive only; unlike\n // optional/alternative there are no children to recurse into without it.\n if (!binding) return;\n // The list/count binding lives at its own access path.\n binding.access = ownAccess(arg, binding.name);\n\n if (binding.type.kind === \"count\") {\n // Count repeats wrap a literal (no inner binding); recurse harmlessly\n // with the scope unchanged, mirroring the arg-builder.\n walk(node.attrs.node, resolve, arg);\n return;\n }\n\n // List repeat: inner bindings are iteration-scoped. Reset the base to an\n // `iter` segment bound to this repeat; the renderer substitutes the loop\n // variable. Scalar lists collapse the element onto the loop var directly\n // (directPath), struct lists scope into the element type.\n const itemType = binding.type.kind === \"list\" ? binding.type.item : undefined;\n const isScalar = !itemType || !hasStructScope(itemType);\n const elementPath: AccessPath = [iter(binding.id)];\n const childArg: AccessCtx = {\n path: elementPath,\n directPath: isScalar ? elementPath : undefined,\n currentStructType:\n !isScalar && itemType?.kind === \"struct\" ? itemType : arg.currentStructType,\n };\n walk(node.attrs.node, resolve, childArg);\n return;\n }\n\n case \"alternative\": {\n if (!binding) {\n for (const alt of node.attrs.alts) walk(alt, resolve, arg);\n return;\n }\n const access = ownAccess(arg, binding.name);\n binding.access = access;\n const isComplexUnion =\n binding.type.kind === \"union\" &&\n !binding.type.variants.every((v) => v.type.kind === \"literal\");\n node.attrs.alts.forEach((alt, i) => {\n if (isComplexUnion && binding.type.kind === \"union\") {\n // A complex-union variant's fields are accessed via the union's own\n // path (the `@type` discriminant narrows it), so scope into `access`.\n const variantType = binding.type.variants[i]?.type;\n walk(alt, resolve, {\n path: access,\n currentStructType: variantType?.kind === \"struct\" ? variantType : arg.currentStructType,\n });\n } else {\n walk(alt, resolve, arg);\n }\n });\n return;\n }\n }\n}\n","import type { Binding, BindingId, BoundType, GateAtom, SolveResult } from \"../bindings/index.js\";\nimport { createRegistry } from \"../bindings/index.js\";\nimport type { Expr, Literal } from \"../ir/index.js\";\nimport { assignAccessPaths } from \"./assign-access.js\";\n\nexport interface SolveOptions {\n namingStrategy?: NamingStrategy;\n}\n\nexport interface NamingStrategy {\n getName: (node: Expr, path: string[]) => string;\n generateId: () => BindingId;\n}\n\n// Shared helper for deep name search\nfunction findDeepName(node: Expr): string | undefined {\n if (node.meta?.name) return node.meta.name;\n\n if (node.kind === \"optional\" || node.kind === \"repeat\") {\n return findDeepName(node.attrs.node);\n }\n\n if (node.kind === \"sequence\") {\n return node.attrs.nodes\n .filter((n) => n.kind !== \"literal\")\n .map(findDeepName)\n .find(Boolean);\n }\n\n return undefined;\n}\n\nexport function defaultNamingStrategy(): NamingStrategy {\n let counter = 0;\n\n return {\n getName: (node, path) => findDeepName(node) ?? path[path.length - 1] ?? `param_${counter++}`,\n generateId: () => `binding_${counter++}`,\n };\n}\n\n// Helper to check if alternative should collapse to bool\nfunction isBooleanLiteralPair(variants: Array<{ type: BoundType }>): boolean {\n if (variants.length !== 2 || !variants.every((v) => v.type.kind === \"literal\")) {\n return false;\n }\n const [a, b] = variants.map((v) => (v.type.kind === \"literal\" ? v.type.value : null));\n return (\n (a === 0 && b === 1) ||\n (a === 1 && b === 0) ||\n (a === \"0\" && b === \"1\") ||\n (a === \"1\" && b === \"0\") ||\n (a === \"false\" && b === \"true\") ||\n (a === \"true\" && b === \"false\")\n );\n}\n\n// Helper to create literal bound type from IR literal\nfunction literalFromNode(node: Literal): BoundType {\n const str = node.attrs.str;\n const num = Number(str);\n const isCleanInt = Number.isInteger(num) && !Number.isNaN(num) && String(num) === str;\n return { kind: \"literal\", value: isCleanInt ? num : str };\n}\n\n/**\n * Name to give the single wrapped field when a non-struct variant gets boxed\n * into a discriminated struct. For a sequence arm the wrapped value is the\n * inner parameter (`seq(lit(\"convert\"), path{src})` -> `src`), so look past the\n * arm's own (variant) name; otherwise use the value's own deep name.\n */\nfunction innerParamName(armNode: Expr): string {\n if (armNode.kind === \"sequence\") {\n const inner = armNode.attrs.nodes\n .filter((n) => n.kind !== \"literal\")\n .map(findDeepName)\n .find(Boolean);\n if (inner) return inner;\n }\n return findDeepName(armNode) ?? \"value\";\n}\n\n/**\n * Discriminated form of a variant's type: literal variants discriminate by\n * value (returned unchanged); struct variants get an `@type` field prepended;\n * anything else is boxed into `{ \"@type\": <name>, <field>: <type> }`. Pure -\n * never mutates `type`.\n */\nfunction taggedVariantType(name: string, type: BoundType, armNode: Expr): BoundType {\n if (type.kind === \"literal\") return type;\n const tag: BoundType = { kind: \"literal\", value: name };\n if (type.kind === \"struct\") return { kind: \"struct\", fields: { \"@type\": tag, ...type.fields } };\n return { kind: \"struct\", fields: { \"@type\": tag, [innerParamName(armNode)]: type } };\n}\n\nexport function solve(expr: Expr, options?: SolveOptions): SolveResult {\n const strategy = options?.namingStrategy ?? defaultNamingStrategy();\n const registry = createRegistry();\n const nodeToBinding = new WeakMap<Expr, Binding>();\n\n // Wrapper bindings (optional/repeat/alternative) need an id BEFORE recursing\n // into children so the child's `gate` can reference it. Pre-allocate the id\n // here, then materialize the binding with its computed type after the\n // recursion settles.\n function preallocate(): BindingId {\n return strategy.generateId();\n }\n\n function registerBinding(\n id: BindingId,\n node: Expr,\n name: string,\n type: BoundType,\n gate: GateAtom[],\n ): Binding {\n // `access` is filled by `assignAccessPaths` once all types have settled\n // (sequence collapse-vs-struct and union arm retyping are only known after\n // the full recursion). Start empty so the field is always present.\n const binding: Binding = { id, node, name, type, gate, access: [] };\n registry.set(id, binding);\n nodeToBinding.set(node, binding);\n return binding;\n }\n\n function createBinding(node: Expr, name: string, type: BoundType, gate: GateAtom[]): Binding {\n return registerBinding(strategy.generateId(), node, name, type, gate);\n }\n\n function solveNode(node: Expr, path: string[], gate: GateAtom[]): BoundType | null {\n const name = strategy.getName(node, path);\n\n switch (node.kind) {\n case \"literal\":\n return null;\n\n case \"optional\": {\n const id = preallocate();\n const childGate = [...gate, { kind: \"present\" as const, binding: id }];\n const inner = solveNode(node.attrs.node, [...path, name], childGate);\n const type: BoundType = inner === null ? { kind: \"bool\" } : { kind: \"optional\", inner };\n registerBinding(id, node, name, type, gate);\n return type;\n }\n\n case \"repeat\": {\n const id = preallocate();\n // We don't yet know if the inner collapses to a count (no inner\n // binding -> repeat-of-literal) or to a list. Optimistically tag the\n // child gate as `iter`; if the inner is null we replace the wrapper\n // type with `count` and the iter atom never reaches a real binding\n // (no inner binding consumes the gate).\n const childGate = [...gate, { kind: \"iter\" as const, binding: id }];\n const inner = solveNode(node.attrs.node, [...path, name], childGate);\n const type: BoundType = inner === null ? { kind: \"count\" } : { kind: \"list\", item: inner };\n registerBinding(id, node, name, type, gate);\n return type;\n }\n\n case \"sequence\": {\n const fields: Record<string, BoundType> = {};\n // Track the single binding-bearing child so the collapse check below can\n // inspect its node kind (only meaningful when exactly one field exists).\n let soleFieldChild: Expr | undefined;\n for (const child of node.attrs.nodes) {\n const childName = strategy.getName(child, path);\n const childType = solveNode(child, [...path, childName], gate);\n if (childType !== null) {\n fields[childName] = childType;\n soleFieldChild = child;\n }\n }\n // A sequence that carries `meta.outputs` must always produce a binding,\n // even when it would otherwise collapse - that binding is the scope key\n // for the outputs declared on it. Empty- and single-field collapses\n // would otherwise leave the scope unbound and the outputs orphaned.\n const hasOutputs = node.meta?.outputs && node.meta.outputs.length > 0;\n if (Object.keys(fields).length === 0) {\n if (hasOutputs) {\n const type: BoundType = { kind: \"struct\", fields: {} };\n createBinding(node, name, type, gate);\n return type;\n }\n return null;\n }\n // Collapse a single-field sequence to that field - e.g. `-x <val>`\n // (`seq(lit(\"-x\"), str)`) becomes just the value, so the flag and its\n // one value read as a single optional/required parameter.\n //\n // EXCEPTION: when the field comes from an `optional` child, the\n // sequence's own literal (e.g. `-whole-file`) can be present while the\n // optional sub-field (e.g. `-demean`) is absent. Collapsing would\n // conflate those two independent optional states and drop the sub-field\n // (it would have no struct to live on). Keep such a sequence a struct so\n // the sub-field stays addressable. A `repeat`/scalar/alternative child\n // is tied 1:1 to the flag's presence, so collapsing those stays correct.\n if (\n Object.keys(fields).length === 1 &&\n !hasOutputs &&\n soleFieldChild?.kind !== \"optional\"\n ) {\n return Object.values(fields)[0]!;\n }\n const type: BoundType = { kind: \"struct\", fields };\n createBinding(node, name, type, gate);\n return type;\n }\n\n case \"alternative\": {\n const id = preallocate();\n // Resolve each arm's variant name first so child gates can carry it.\n // `variantTag` (the sub-command id) is preferred over `name`: a\n // single-field sub-command collapses onto its inner field, whose `name`\n // wins, so `name` alone would derive the tag from the inner field's id\n // (two distinct sub-commands wrapping a same-named field would collide).\n const armNames = node.attrs.alts.map((alt, i) => {\n if (alt.meta?.variantTag) return alt.meta.variantTag;\n if (alt.meta?.name) return alt.meta.name;\n if (alt.kind === \"literal\") return alt.attrs.str.replace(/^-+/, \"\");\n return `variant_${i}`;\n });\n\n const variants = node.attrs.alts.map((alt, i) => {\n const variantName = armNames[i]!;\n const childGate = [\n ...gate,\n { kind: \"variant\" as const, binding: id, variant: variantName },\n ];\n const childType =\n solveNode(alt, [...path, `variant_${i}`], childGate) ??\n (alt.kind === \"literal\" ? literalFromNode(alt) : { kind: \"bool\" as const });\n return { name: variantName, type: childType, node: alt };\n });\n\n // Pattern: boolean pair -> bool. The pre-allocated variant atoms in\n // child gates are unreached (literal arms produce no bindings).\n if (isBooleanLiteralPair(variants)) {\n const type: BoundType = { kind: \"bool\" };\n registerBinding(id, node, name, type, gate);\n return type;\n }\n\n // Discriminate each variant. When an arm carries its own binding (a\n // multi-field struct), retype it so that binding and the union agree;\n // collapsed single-field arms keep their inner binding and the boxed\n // form lives only in the union's `variants`.\n for (const v of variants) {\n v.type = taggedVariantType(v.name, v.type, v.node);\n const armBinding = nodeToBinding.get(v.node);\n if (armBinding) armBinding.type = v.type;\n }\n\n const type: BoundType = {\n kind: \"union\",\n variants: variants.map(({ name, type }) => ({ name, type })),\n };\n registerBinding(id, node, name, type, gate);\n return type;\n }\n\n case \"int\":\n case \"float\":\n case \"str\":\n case \"path\": {\n const type: BoundType = { kind: \"scalar\", scalar: node.kind };\n createBinding(node, name, type, gate);\n return type;\n }\n }\n }\n\n const rootType = solveNode(expr, [], []);\n\n // Ensure a root binding always exists, even when the sequence collapsed\n // (0 fields -> empty struct, 1 field that's not already a struct -> wrap in single-field struct)\n if (!nodeToBinding.has(expr) && expr.kind === \"sequence\") {\n const name = strategy.getName(expr, []);\n if (rootType === null) {\n createBinding(expr, name, { kind: \"struct\", fields: {} }, []);\n } else if (rootType.kind === \"struct\") {\n // Already a struct (e.g. joined seq with 2+ fields) - use it directly\n createBinding(expr, name, rootType, []);\n } else {\n // Single scalar/optional/list field was collapsed - wrap it in a struct.\n // The field's binding may not be a direct child: a nested sequence that\n // collapsed (e.g. one preserved by flatten to keep its `meta.doc`) leaves\n // the binding buried one or more levels down. Search through collapsed\n // sequences for it. Using `binding.name` as the field name keeps the\n // struct field aligned with the access path the backends render\n // (`params.<binding.name>`).\n const findCollapsedBinding = (node: Expr): Binding | undefined => {\n const b = nodeToBinding.get(node);\n if (b) return b;\n // Only sequences collapse without leaving a binding; optional/repeat/\n // alternative always register one, so no need to descend into them.\n if (node.kind === \"sequence\") {\n for (const child of node.attrs.nodes) {\n const found = findCollapsedBinding(child);\n if (found) return found;\n }\n }\n return undefined;\n };\n const childName = expr.attrs.nodes.map(findCollapsedBinding).find(Boolean)?.name;\n if (childName) {\n createBinding(expr, name, { kind: \"struct\", fields: { [childName]: rootType } }, []);\n }\n }\n }\n\n const resolve = (node: Expr) => nodeToBinding.get(node);\n\n // Now that every binding's type has settled (sequence collapse, union arm\n // retyping, root fixup), walk the IR once more to attach each binding's\n // access path relative to top-level `params`. Backends render these paths\n // instead of re-deriving them.\n assignAccessPaths(expr, resolve);\n\n return { bindings: registry, resolve };\n}\n","import { ArgdumpParser } from \"./frontend/argdump/index.js\";\nimport { BoutiquesParser } from \"./frontend/boutiques/index.js\";\nimport { WorkbenchParser } from \"./frontend/workbench/index.js\";\nimport { detectFormat } from \"./frontend/detect-format.js\";\nimport type { FormatName } from \"./frontend/detect-format.js\";\nimport type { ParseResult } from \"./frontend/frontend.js\";\n\nexport * from \"./backend/index.js\";\nexport * from \"./bindings/index.js\";\nexport * from \"./frontend/index.js\";\nexport * from \"./ir/index.js\";\nexport * from \"./manifest/index.js\";\nexport * from \"./solver/index.js\";\n\nexport function compile(\n source: string,\n filenameOrOptions?: string | { format?: FormatName; filename?: string },\n): ParseResult {\n const options =\n typeof filenameOrOptions === \"string\"\n ? { filename: filenameOrOptions }\n : (filenameOrOptions ?? {});\n\n const format = options.format ?? detectFormat(source);\n\n if (!format) {\n return {\n expr: { kind: \"sequence\", attrs: { nodes: [] } },\n errors: [{ message: \"Could not detect input format. Specify format explicitly.\" }],\n warnings: [],\n };\n }\n\n const parser =\n format === \"argdump\"\n ? new ArgdumpParser()\n : format === \"workbench\"\n ? new WorkbenchParser()\n : new BoutiquesParser();\n return parser.parse(source, options.filename);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["findDeepName","isObject","isString","isNumber","isArray","isObject","isString","isNumber","isArray","isObject","isString","isArray","asArray","emptyExpr","description","mapType","renderAccess","isExpr","resultToStmt","appendLines","toStringExpr","pathArg","rootFieldDefault","readAccess","accessOf","renderAccess","collectDefaults","loopVarCounter","buildArgs","walk","walkTerminal","walkSequence","walkOptional","walkRepeat","walkAlternative","emitImports","emitMetadata","mapType","emitTypeDeclarations","emitBuildCargs","buildArgs","resultToStmt","emitWrapperFunction","emitSigParams","emitParamsFactory","emitKwargWrapper","emitValidate","emitRoot","raise","expectedType","emitField","emitValue","str","emitUnion","emitLiteralMembership","checkType","emitRange","emitListLength","plural","mapType","outputTypeExpr","streamFieldIds","rootFieldDefault","collectDefaults","loopCounter","renderWrapperOpen","bindingAccess","presentCondition","renderAccess","renderPathExpr","renderToken","renderRefValue","emitOneOutput","emitBuildOutputs","needsStripExtensionsHelper","emitStripExtensionsHelper","computePublicNames","buildEmitModel","mapType","needsStripExtensionsHelper","streamFieldIds","appModuleName","appEntrypoint","emitPackageDispatch","buildEmitModel","rootFieldDefault","collectDefaults","walk"],"sources":["../src/frontend/argdump/parser.ts","../src/ir/meta.ts","../src/frontend/boutiques/destruct-template.ts","../src/frontend/boutiques/split-command.ts","../src/frontend/boutiques/parser.ts","../src/ir/builders.ts","../src/backend/string-case.ts","../src/frontend/mrtrix/parser.ts","../src/frontend/workbench/parser.ts","../src/frontend/detect-format.ts","../src/backend/find-doc.ts","../src/backend/resolve-field-binding.ts","../src/backend/find-struct-node.ts","../src/backend/collect-field-info.ts","../src/bindings/binding.ts","../src/bindings/output-gate.ts","../src/bindings/format.ts","../src/backend/resolve-output-tokens.ts","../src/backend/scope.ts","../src/backend/boutiques/boutiques.ts","../src/backend/code-builder.ts","../src/backend/type-keys.ts","../src/backend/collect-named-types.ts","../src/backend/styxdefs-compat.ts","../src/backend/python/packaging.ts","../src/backend/sig-entries.ts","../src/backend/union-variants.ts","../src/backend/python/typemap.ts","../src/backend/python/arg-builder.ts","../src/backend/python/emit.ts","../src/backend/validate-walk.ts","../src/backend/python/validate-emit.ts","../src/backend/collect-output-fields.ts","../src/backend/python/outputs-emit.ts","../src/backend/python/python.ts","../src/backend/snippet-core.ts","../src/backend/python/snippet.ts","../src/backend/schema/jsonschema.ts","../src/backend/typescript/typemap.ts","../src/backend/typescript/packaging.ts","../src/backend/typescript/arg-builder.ts","../src/backend/typescript/emit.ts","../src/backend/typescript/validate-emit.ts","../src/backend/typescript/outputs-emit.ts","../src/backend/typescript/typescript.ts","../src/backend/typescript/snippet.ts","../src/ir/format.ts","../src/ir/node.ts","../src/ir/passes/pass.ts","../src/ir/passes/canonicalize.ts","../src/ir/passes/flatten.ts","../src/ir/passes/remove-empty.ts","../src/ir/passes/simplify.ts","../src/ir/passes/pipeline.ts","../src/manifest/context.ts","../src/solver/resolve-outputs.ts","../src/solver/assign-access.ts","../src/solver/solver.ts","../src/index.ts"],"sourcesContent":["import type { AppMeta, NodeMeta } from \"../../ir/meta.js\";\nimport type {\n Alternative,\n Expr,\n Float,\n Int,\n Literal,\n Optional,\n Path,\n Repeat,\n Sequence,\n Str,\n} from \"../../ir/node.js\";\nimport type {\n Frontend,\n ParseError,\n ParseResult,\n ParseWarning,\n SourceLocation,\n} from \"../frontend.js\";\n\n// Find the deepest existing name in a subtree, mirroring solver semantics.\n// Used by the mutex code so the synthesized inner name matches the binding\n// name the solver will produce for the same subtree.\nfunction findDeepName(node: Expr): string | undefined {\n if (node.meta?.name) return node.meta.name;\n if (node.kind === \"optional\" || node.kind === \"repeat\") {\n return findDeepName(node.attrs.node);\n }\n if (node.kind === \"sequence\") {\n for (const child of node.attrs.nodes) {\n if (child.kind === \"literal\") continue;\n const name = findDeepName(child);\n if (name) return name;\n }\n }\n return undefined;\n}\n\n// Type guards\n\nfunction isObject(x: unknown): x is Record<string, unknown> {\n return typeof x === \"object\" && x !== null && !Array.isArray(x);\n}\n\nfunction isString(x: unknown): x is string {\n return typeof x === \"string\";\n}\n\nfunction isNumber(x: unknown): x is number {\n return typeof x === \"number\";\n}\n\nfunction isArray(x: unknown): x is unknown[] {\n return Array.isArray(x);\n}\n\n// Argdump types\n\ntype AdAction = Record<string, unknown>;\ntype AdDescriptor = Record<string, unknown>;\n\ninterface ArgparseMarker {\n __argparse__: string;\n}\n\nfunction isArgparseMarker(x: unknown): x is ArgparseMarker {\n return isObject(x) && isString(x.__argparse__);\n}\n\nfunction isSuppressed(x: unknown): boolean {\n return isArgparseMarker(x) && x.__argparse__ === \"SUPPRESS\";\n}\n\n// Parser\n\nexport class ArgdumpParser implements Frontend {\n readonly name = \"argdump\";\n readonly extensions = [\"json\"];\n\n private errors: ParseError[] = [];\n private warnings: ParseWarning[] = [];\n\n private reset(): void {\n this.errors = [];\n this.warnings = [];\n }\n\n private error(message: string, location?: SourceLocation): void {\n this.errors.push({ message, location });\n }\n\n private warn(message: string, location?: SourceLocation): void {\n this.warnings.push({ message, location });\n }\n\n // JSON parsing\n\n private parseJSON(source: string): AdDescriptor | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(source);\n } catch (e) {\n this.error(e instanceof SyntaxError ? e.message : \"Invalid JSON\");\n return null;\n }\n\n if (!isObject(parsed)) {\n this.error(\"JSON source is not an object\");\n return null;\n }\n\n return parsed;\n }\n\n // Metadata building\n\n private buildAppMeta(descriptor: AdDescriptor): AppMeta | undefined {\n const prog = descriptor.prog;\n if (!isString(prog)) return undefined;\n\n // Use prog as id, fall back to first word of description\n let id = prog || undefined;\n if (!id) {\n const desc = descriptor.description;\n if (isString(desc)) {\n // Extract tool name: first word, strip trailing punctuation\n const match = desc.match(/^(\\S+)/);\n if (match) id = match[1]!.replace(/[:;,]+$/, \"\") || undefined;\n }\n }\n if (!id) return undefined;\n\n const description = descriptor.description;\n const epilog = descriptor.epilog;\n // Try to extract version from a version action\n let versionStr: string | undefined;\n const actions = descriptor.actions;\n if (isArray(actions)) {\n for (const action of actions) {\n if (isObject(action) && action.action_type === \"version\" && isString(action.version)) {\n // Strip %(prog)s prefix if present\n versionStr = action.version.replace(/%%?\\(prog\\)s\\s*/g, \"\").trim();\n if (!versionStr) versionStr = undefined;\n break;\n }\n }\n }\n\n return {\n id,\n ...(versionStr && { version: versionStr }),\n ...((isString(description) || isString(epilog)) && {\n doc: {\n ...(isString(description) && { description }),\n ...(isString(epilog) && { comment: epilog }),\n },\n }),\n };\n }\n\n // Terminal node building\n\n private resolveTerminal(action: AdAction): Expr | null {\n const typeInfo = action.type_info;\n const fileTypeInfo = action.file_type_info;\n const choices = action.choices;\n\n // Choices -> enum alternative\n if (isArray(choices) && choices.length > 0) {\n const alts: Literal[] = [];\n for (const choice of choices) {\n if (isString(choice) || isNumber(choice)) {\n alts.push({ kind: \"literal\", attrs: { str: String(choice) } });\n } else {\n this.warn(`Ignoring non-string/number choice: ${JSON.stringify(choice)}`);\n }\n }\n if (alts.length === 0) return null;\n return { kind: \"alternative\", attrs: { alts } };\n }\n\n // FileType -> path\n if (isObject(fileTypeInfo)) {\n return { kind: \"path\", attrs: {} } satisfies Path;\n }\n\n // type_info-based resolution\n if (isObject(typeInfo)) {\n const name = typeInfo.name;\n\n if (!isString(name)) {\n return this.inferFromSamples(action) ?? ({ kind: \"str\", attrs: {} } satisfies Str);\n }\n\n // Non-serializable type -> infer from samples, else str + warning\n if (typeInfo.serializable === false) {\n const inferred = this.inferFromSamples(action);\n const fallback = inferred ? inferred.kind : \"string\";\n this.warn(`Non-serializable type '${name}' for '${action.dest}', treating as ${fallback}`);\n return inferred ?? ({ kind: \"str\", attrs: {} } satisfies Str);\n }\n\n switch (name) {\n case \"int\":\n return { kind: \"int\", attrs: {} } satisfies Int;\n case \"float\":\n return { kind: \"float\", attrs: {} } satisfies Float;\n case \"Path\":\n case \"PosixPath\":\n case \"WindowsPath\":\n return { kind: \"path\", attrs: {} } satisfies Path;\n default: {\n const moduleHit = this.resolveByModule(typeInfo.module);\n if (moduleHit) return moduleHit;\n // Unknown type -> infer from samples, else str\n const inferred = this.inferFromSamples(action);\n if (name !== \"str\") {\n const fallback = inferred ? inferred.kind : \"string\";\n this.warn(`Unknown type '${name}' for '${action.dest}', treating as ${fallback}`);\n }\n return inferred ?? ({ kind: \"str\", attrs: {} } satisfies Str);\n }\n }\n }\n\n // No type_info -> infer from samples, else str (argparse default)\n return this.inferFromSamples(action) ?? ({ kind: \"str\", attrs: {} } satisfies Str);\n }\n\n private resolveByModule(mod: unknown): Path | Float | null {\n if (!isString(mod)) return null;\n if (mod === \"pathlib\" || mod === \"os.path\" || mod.includes(\"path\")) {\n return { kind: \"path\", attrs: {} } satisfies Path;\n }\n if (mod === \"decimal\" || mod === \"fractions\") {\n return { kind: \"float\", attrs: {} } satisfies Float;\n }\n return null;\n }\n\n /** Infer numeric type from sample values: default (incl. list elements) or const. */\n private inferFromSamples(action: AdAction): Int | Float | null {\n const samples: unknown[] = [];\n const def = action.default;\n if (isArray(def)) samples.push(...def);\n else samples.push(def);\n samples.push(action.const);\n\n let sawNumber = false;\n let sawNonInteger = false;\n for (const s of samples) {\n if (typeof s !== \"number\" || !Number.isFinite(s)) continue;\n sawNumber = true;\n if (!Number.isInteger(s)) sawNonInteger = true;\n }\n if (!sawNumber) return null;\n return sawNonInteger\n ? ({ kind: \"float\", attrs: {} } satisfies Float)\n : ({ kind: \"int\", attrs: {} } satisfies Int);\n }\n\n // Nargs wrapping\n\n private wrapWithNargs(node: Expr, nargs: unknown): Expr {\n if (nargs === null || nargs === undefined) {\n // No nargs -> bare value\n return node;\n }\n\n if (isArgparseMarker(nargs)) {\n if (nargs.__argparse__ === \"REMAINDER\") {\n // REMAINDER -> rep(str())\n const rep: Repeat = {\n kind: \"repeat\",\n attrs: { node: { kind: \"str\", attrs: {} }, countMin: 0 },\n };\n return rep;\n }\n if (nargs.__argparse__ === \"SUPPRESS\") {\n return node;\n }\n }\n\n if (nargs === \"?\") {\n const opt: Optional = { kind: \"optional\", attrs: { node } };\n return opt;\n }\n\n if (nargs === \"*\") {\n const rep: Repeat = { kind: \"repeat\", attrs: { node, countMin: 0 } };\n return rep;\n }\n\n if (nargs === \"+\") {\n const rep: Repeat = { kind: \"repeat\", attrs: { node, countMin: 1 } };\n return rep;\n }\n\n if (isNumber(nargs) && Number.isInteger(nargs) && nargs >= 0) {\n if (nargs === 1) return node;\n const rep: Repeat = {\n kind: \"repeat\",\n attrs: { node, countMin: nargs, countMax: nargs },\n };\n return rep;\n }\n\n return node;\n }\n\n // Action building\n\n private buildNodeMeta(action: AdAction): NodeMeta | undefined {\n const dest = action.dest;\n const help = action.help;\n const defaultVal = action.default;\n const name = this.preferredName(action) ?? (isString(dest) ? dest : undefined);\n\n const hasName = name !== undefined;\n const hasHelp = isString(help) && !isSuppressed(help);\n const hasDefault =\n (isString(defaultVal) || isNumber(defaultVal) || typeof defaultVal === \"boolean\") &&\n !isSuppressed(defaultVal);\n\n if (!hasName && !hasHelp && !hasDefault) return undefined;\n\n return {\n ...(hasName && { name }),\n ...(hasHelp && { doc: { description: help } }),\n ...(hasDefault && { defaultValue: defaultVal }),\n };\n }\n\n private getOptionFlag(action: AdAction): string | null {\n const optionStrings = action.option_strings;\n if (!isArray(optionStrings) || optionStrings.length === 0) return null;\n\n // Prefer long option, fallback to first\n for (const opt of optionStrings) {\n if (isString(opt) && opt.startsWith(\"--\")) return opt;\n }\n const first = optionStrings[0];\n return isString(first) ? first : null;\n }\n\n /** Prefer the first --long flag (without leading dashes) over dest. */\n private preferredName(action: AdAction): string | undefined {\n const optionStrings = action.option_strings;\n if (!isArray(optionStrings)) return undefined;\n for (const opt of optionStrings) {\n if (isString(opt) && opt.startsWith(\"--\") && opt.length > 2) {\n return opt.slice(2);\n }\n }\n return undefined;\n }\n\n private isPositional(action: AdAction): boolean {\n const optionStrings = action.option_strings;\n return !isArray(optionStrings) || optionStrings.length === 0;\n }\n\n private buildAction(action: AdAction): Expr | null {\n const actionType = action.action_type ?? \"store\";\n\n switch (actionType) {\n case \"store\":\n return this.buildStore(action);\n case \"store_true\":\n return this.buildStoreTrue(action);\n case \"store_false\":\n return this.buildStoreFalse(action);\n case \"store_const\":\n return this.buildStoreConst(action);\n case \"boolean_optional\":\n return this.buildBooleanOptional(action);\n case \"count\":\n return this.buildCount(action);\n case \"append\":\n case \"extend\":\n return this.buildAppendExtend(action);\n case \"append_const\":\n return this.buildAppendConst(action);\n case \"parsers\":\n return this.buildSubparsers(action);\n case \"help\":\n case \"version\":\n // Skip help/version actions - not part of the tool interface\n return null;\n case \"unknown\":\n this.warn(\n `Unknown action type for '${action.dest}'` +\n (isString(action.custom_action_class)\n ? ` (custom class: ${action.custom_action_class})`\n : \"\") +\n \", treating as store\",\n );\n return this.buildStore(action);\n default:\n this.warn(`Unrecognized action_type '${actionType}' for '${action.dest}', skipping`);\n return null;\n }\n }\n\n private buildStore(action: AdAction): Expr | null {\n const terminal = this.resolveTerminal(action);\n if (!terminal) return null;\n\n const meta = this.buildNodeMeta(action);\n if (meta) terminal.meta = meta;\n\n const node: Expr = this.wrapWithNargs(terminal, action.nargs);\n\n if (this.isPositional(action)) {\n // Hoist metadata from terminal to outermost wrapper\n if (node !== terminal && terminal.meta) {\n const { name, ...rest } = terminal.meta;\n if (Object.keys(rest).length > 0) {\n node.meta = { ...node.meta, ...rest };\n terminal.meta = name ? { name } : undefined;\n }\n }\n return node;\n }\n\n // Optional argument: seq(lit(flag), value)\n const flag = this.getOptionFlag(action);\n if (!flag) {\n this.error(`Optional argument '${action.dest}' has no option strings`);\n return null;\n }\n\n const flagLit: Literal = { kind: \"literal\", attrs: { str: flag } };\n const seq: Sequence = { kind: \"sequence\", attrs: { nodes: [flagLit, node] } };\n\n // Wrap in optional unless explicitly required\n const isRequired = action.required === true;\n let result: Expr;\n if (isRequired) {\n result = seq;\n } else {\n const opt: Optional = { kind: \"optional\", attrs: { node: seq } };\n result = opt;\n }\n\n // Hoist metadata to outermost node\n if (terminal.meta) {\n const { name, ...rest } = terminal.meta;\n if (Object.keys(rest).length > 0) {\n result.meta = { ...result.meta, ...rest };\n terminal.meta = name ? { name } : undefined;\n }\n }\n\n return result;\n }\n\n private buildStoreTrue(action: AdAction): Expr | null {\n const flag = this.getOptionFlag(action);\n if (!flag) {\n this.error(`store_true action '${action.dest}' has no option strings`);\n return null;\n }\n\n const literal: Literal = { kind: \"literal\", attrs: { str: flag } };\n const opt: Optional = { kind: \"optional\", attrs: { node: literal } };\n\n const meta = this.buildNodeMeta(action);\n const flagMeta = meta ?? {};\n if (flagMeta.defaultValue === undefined) flagMeta.defaultValue = false;\n opt.meta = flagMeta;\n\n return opt;\n }\n\n private buildStoreFalse(action: AdAction): Expr | null {\n const flag = this.getOptionFlag(action);\n if (!flag) {\n this.error(`store_false action '${action.dest}' has no option strings`);\n return null;\n }\n\n const literal: Literal = { kind: \"literal\", attrs: { str: flag } };\n const opt: Optional = { kind: \"optional\", attrs: { node: literal } };\n\n const meta = this.buildNodeMeta(action);\n const flagMeta = meta ?? {};\n if (flagMeta.defaultValue === undefined) flagMeta.defaultValue = true;\n opt.meta = flagMeta;\n\n return opt;\n }\n\n private buildStoreConst(action: AdAction): Expr | null {\n const flag = this.getOptionFlag(action);\n if (!flag) {\n this.error(`store_const action '${action.dest}' has no option strings`);\n return null;\n }\n\n const literal: Literal = { kind: \"literal\", attrs: { str: flag } };\n const opt: Optional = { kind: \"optional\", attrs: { node: literal } };\n\n const meta = this.buildNodeMeta(action);\n if (meta) opt.meta = meta;\n\n return opt;\n }\n\n private buildBooleanOptional(action: AdAction): Expr | null {\n const optionStrings = action.option_strings;\n if (!isArray(optionStrings) || optionStrings.length === 0) {\n this.error(`boolean_optional action '${action.dest}' has no option strings`);\n return null;\n }\n\n // Find --flag and --no-flag forms\n let posFlag: string | null = null;\n let negFlag: string | null = null;\n\n for (const opt of optionStrings) {\n if (!isString(opt)) continue;\n if (opt.startsWith(\"--no-\")) {\n negFlag = opt;\n } else if (opt.startsWith(\"--\")) {\n posFlag = opt;\n }\n }\n\n if (!posFlag) {\n // Fallback: use first two option strings\n posFlag = isString(optionStrings[0]) ? optionStrings[0] : null;\n negFlag = isString(optionStrings[1]) ? optionStrings[1] : null;\n }\n\n if (!posFlag) {\n this.error(`boolean_optional action '${action.dest}' has no valid option strings`);\n return null;\n }\n\n const posLit: Literal = { kind: \"literal\", attrs: { str: posFlag } };\n\n let innerNode: Expr;\n if (negFlag) {\n const negLit: Literal = { kind: \"literal\", attrs: { str: negFlag } };\n const alt: Alternative = { kind: \"alternative\", attrs: { alts: [posLit, negLit] } };\n innerNode = alt;\n } else {\n innerNode = posLit;\n }\n\n const opt: Optional = { kind: \"optional\", attrs: { node: innerNode } };\n\n const meta = this.buildNodeMeta(action);\n const flagMeta = meta ?? {};\n if (flagMeta.defaultValue === undefined) flagMeta.defaultValue = false;\n opt.meta = flagMeta;\n\n return opt;\n }\n\n private buildCount(action: AdAction): Expr | null {\n const flag = this.getOptionFlag(action);\n if (!flag) {\n this.error(`count action '${action.dest}' has no option strings`);\n return null;\n }\n\n const literal: Literal = { kind: \"literal\", attrs: { str: flag } };\n const rep: Repeat = { kind: \"repeat\", attrs: { node: literal, countMin: 0 } };\n\n const meta = this.buildNodeMeta(action);\n if (meta) rep.meta = meta;\n\n return rep;\n }\n\n private buildAppendExtend(action: AdAction): Expr | null {\n const terminal = this.resolveTerminal(action);\n if (!terminal) return null;\n\n const meta = this.buildNodeMeta(action);\n if (meta) terminal.meta = meta;\n\n // Inner value may have nargs\n const nargsWrapped: Expr = this.wrapWithNargs(terminal, action.nargs);\n\n // Always wrap in repeat (append/extend accumulates)\n const inner: Expr =\n nargsWrapped.kind === \"repeat\"\n ? nargsWrapped\n : ({ kind: \"repeat\", attrs: { node: nargsWrapped, countMin: 0 } } satisfies Repeat);\n\n if (this.isPositional(action)) {\n // Hoist metadata\n if (inner !== terminal && terminal.meta) {\n const { name, ...rest } = terminal.meta;\n if (Object.keys(rest).length > 0) {\n inner.meta = { ...inner.meta, ...rest };\n terminal.meta = name ? { name } : undefined;\n }\n }\n return inner;\n }\n\n // Optional argument with flag\n const flag = this.getOptionFlag(action);\n if (!flag) {\n this.error(`append/extend action '${action.dest}' has no option strings`);\n return null;\n }\n\n // For append with flag: rep(seq(lit(flag), value))\n // Unwrap the repeat we just added\n const valueNode = inner.kind === \"repeat\" ? inner.attrs.node : inner;\n const flagLit: Literal = { kind: \"literal\", attrs: { str: flag } };\n const flagSeq: Sequence = { kind: \"sequence\", attrs: { nodes: [flagLit, valueNode] } };\n const outerRep: Repeat = { kind: \"repeat\", attrs: { node: flagSeq, countMin: 0 } };\n\n // Hoist metadata\n if (terminal.meta) {\n const { name, ...rest } = terminal.meta;\n if (Object.keys(rest).length > 0) {\n outerRep.meta = { ...outerRep.meta, ...rest };\n terminal.meta = name ? { name } : undefined;\n }\n }\n\n return outerRep;\n }\n\n private buildAppendConst(action: AdAction): Expr | null {\n const flag = this.getOptionFlag(action);\n if (!flag) {\n this.error(`append_const action '${action.dest}' has no option strings`);\n return null;\n }\n\n // Similar to count - repeated flag\n const literal: Literal = { kind: \"literal\", attrs: { str: flag } };\n const rep: Repeat = { kind: \"repeat\", attrs: { node: literal, countMin: 0 } };\n\n const meta = this.buildNodeMeta(action);\n if (meta) rep.meta = meta;\n\n return rep;\n }\n\n private buildSubparsers(action: AdAction): Expr | null {\n const subparsers = action.subparsers;\n if (!isObject(subparsers)) {\n this.error(`parsers action '${action.dest}' has no subparsers`);\n return null;\n }\n\n const aliases = isObject(action.subparsers_aliases) ? action.subparsers_aliases : {};\n const alts: Expr[] = [];\n\n for (const [name, parserInfo] of Object.entries(subparsers)) {\n if (!isObject(parserInfo)) {\n this.warn(`Skipping non-object subparser '${name}'`);\n continue;\n }\n\n const subExpr = this.parseParserInfo(parserInfo);\n if (!subExpr) continue;\n\n // Prepend subcommand literal\n const cmdLit: Literal = { kind: \"literal\", attrs: { str: name } };\n const seq: Sequence = {\n kind: \"sequence\",\n attrs: { nodes: [cmdLit, ...subExpr.attrs.nodes] },\n };\n\n // Attach name and aliases as doc\n const subAliases = aliases[name];\n const aliasDoc =\n isArray(subAliases) && subAliases.length > 0\n ? ` (aliases: ${subAliases.filter(isString).join(\", \")})`\n : \"\";\n\n const description = isString(parserInfo.description) ? parserInfo.description : undefined;\n const docStr = description\n ? description + aliasDoc\n : aliasDoc\n ? aliasDoc.slice(1) // Remove leading space\n : undefined;\n\n seq.meta = {\n name,\n ...(docStr && { doc: { description: docStr } }),\n };\n\n alts.push(seq);\n }\n\n if (alts.length === 0) {\n this.error(`No valid subparsers for '${action.dest}'`);\n return null;\n }\n\n if (alts.length === 1) {\n return alts[0]!;\n }\n\n const alt: Alternative = { kind: \"alternative\", attrs: { alts } };\n\n const isRequired = action.subparsers_required === true || action.required === true;\n if (!isRequired) {\n const opt: Optional = { kind: \"optional\", attrs: { node: alt } };\n\n const meta = this.buildNodeMeta(action);\n if (meta) opt.meta = meta;\n\n return opt;\n }\n\n const meta = this.buildNodeMeta(action);\n if (meta) alt.meta = meta;\n\n return alt;\n }\n\n // Mutual exclusion\n\n private applyMutualExclusion(\n actionsByDest: Map<string, AdAction>,\n groups: unknown[],\n nodes: Expr[],\n nodesByDest: Map<string, Expr>,\n ): Expr[] {\n const excluded = new Set<string>();\n\n for (const group of groups) {\n if (!isObject(group)) continue;\n const groupActions = group.actions;\n if (!isArray(groupActions)) continue;\n\n const memberDests: string[] = [];\n for (const dest of groupActions) {\n if (isString(dest) && nodesByDest.has(dest)) {\n memberDests.push(dest);\n }\n }\n\n if (memberDests.length < 2) continue;\n\n // Build alt from member nodes. Unwrapping the optional drops its meta\n // (doc/default), so merge it onto the inner node and tag the inner\n // with the dest so backends can derive a per-variant name.\n const altMembers: Expr[] = [];\n for (const dest of memberDests) {\n const node = nodesByDest.get(dest)!;\n let inner: Expr;\n let outerMeta: NodeMeta | undefined;\n if (node.kind === \"optional\") {\n inner = node.attrs.node;\n outerMeta = node.meta;\n } else {\n inner = node;\n }\n inner.meta = {\n ...outerMeta,\n ...inner.meta,\n // Prefer the deepest existing name in the subtree so the synthesized\n // name matches the binding the solver derives for the same node.\n // Otherwise findDeepName short-circuits on the inner's new name and\n // the variant struct's field key drifts from the binding name.\n name: inner.meta?.name ?? findDeepName(inner) ?? dest,\n };\n altMembers.push(inner);\n excluded.add(dest);\n }\n\n const alt: Alternative = { kind: \"alternative\", attrs: { alts: altMembers } };\n\n const isRequired = group.required === true;\n let groupNode: Expr;\n if (isRequired) {\n groupNode = alt;\n } else {\n groupNode = { kind: \"optional\", attrs: { node: alt } } satisfies Optional;\n }\n\n // Synthesize a name so backends can derive a meaningful id instead of\n // a Scope-generated placeholder. Prefer an explicit title if surfaced\n // by argdump, otherwise concat dests for 2-member groups, fall back\n // to a \"_choice\" suffix for larger groups.\n const title = isString(group.title) ? group.title : undefined;\n const groupName =\n title ??\n (memberDests.length === 2\n ? `${memberDests[0]}_or_${memberDests[1]}`\n : `${memberDests[0]}_choice`);\n groupNode.meta = { ...groupNode.meta, name: groupName };\n\n // Insert at position of first member\n const firstDest = memberDests[0]!;\n const firstIdx = nodes.findIndex((n) => n === nodesByDest.get(firstDest));\n if (firstIdx >= 0) {\n nodes.splice(firstIdx, 0, groupNode);\n } else {\n nodes.push(groupNode);\n }\n }\n\n // Remove excluded nodes\n return nodes.filter((n) => {\n // Find which dest this node corresponds to\n for (const [dest, node] of nodesByDest) {\n if (node === n && excluded.has(dest)) return false;\n }\n return true;\n });\n }\n\n // Main parser\n\n private parseParserInfo(descriptor: AdDescriptor): Sequence | null {\n const actions = descriptor.actions;\n if (!isArray(actions)) {\n return { kind: \"sequence\", attrs: { nodes: [] } };\n }\n\n const positionals: Expr[] = [];\n const optionals: Expr[] = [];\n const actionsByDest = new Map<string, AdAction>();\n const nodesByDest = new Map<string, Expr>();\n\n for (const rawAction of actions) {\n if (!isObject(rawAction)) continue;\n\n const node = this.buildAction(rawAction);\n if (!node) continue;\n\n const dest = rawAction.dest;\n if (isString(dest)) {\n actionsByDest.set(dest, rawAction);\n nodesByDest.set(dest, node);\n }\n\n if (this.isPositional(rawAction) && rawAction.action_type !== \"parsers\") {\n positionals.push(node);\n } else {\n optionals.push(node);\n }\n }\n\n // Assemble: positionals first, then optionals\n let allNodes = [...positionals, ...optionals];\n\n // Apply mutual exclusion groups\n const mutexGroups = descriptor.mutually_exclusive_groups;\n if (isArray(mutexGroups) && mutexGroups.length > 0) {\n allNodes = this.applyMutualExclusion(actionsByDest, mutexGroups, allNodes, nodesByDest);\n }\n\n return { kind: \"sequence\", attrs: { nodes: allNodes } };\n }\n\n // Public API\n\n parse(source: string, _filename?: string): ParseResult {\n this.reset();\n\n const descriptor = this.parseJSON(source);\n if (descriptor === null) {\n return {\n expr: { kind: \"sequence\", attrs: { nodes: [] } },\n errors: this.errors,\n warnings: this.warnings,\n };\n }\n\n const meta = this.buildAppMeta(descriptor);\n if (!meta) {\n this.error(\"Descriptor is missing prog\");\n return {\n expr: { kind: \"sequence\", attrs: { nodes: [] } },\n errors: this.errors,\n warnings: this.warnings,\n };\n }\n\n const expr = this.parseParserInfo(descriptor);\n if (expr === null) {\n this.error(\"Failed to parse argument structure\");\n return {\n expr: { kind: \"sequence\", attrs: { nodes: [] } },\n errors: this.errors,\n warnings: this.warnings,\n };\n }\n\n // Prepend prog as command literal (like Boutiques' command-line prefix)\n const prog = descriptor.prog;\n if (isString(prog) && prog) {\n expr.attrs.nodes.unshift({ kind: \"literal\", attrs: { str: prog } });\n }\n\n // Set root struct name\n if (!expr.meta?.name && meta.id) {\n expr.meta = { ...expr.meta, name: meta.id };\n }\n\n return {\n meta,\n expr,\n errors: this.errors,\n warnings: this.warnings,\n };\n }\n}\n","import type { Documentation, MediaTypeIdentifier } from \"./types.js\";\n\n/**\n * Opaque, name-based reference to an IR node by its `NodeMeta.name`.\n *\n * Resolved post-solve against the binding registry, not within IR passes.\n * Names survive optimization (pointers don't), so token refs stay valid even\n * after passes rewrite the tree. See `memory/design_outputs.md`.\n */\nexport interface NodeRef {\n kind: \"node-ref\";\n name: string;\n}\n\n/** Construct a NodeRef from a node name. */\nexport function nodeRef(name: string): NodeRef {\n return { kind: \"node-ref\", name };\n}\n\n/** Output token: literal text or a parameter reference. */\nexport type OutputToken =\n | { kind: \"literal\"; value: string }\n | {\n kind: \"ref\";\n target: NodeRef;\n stripExtensions?: string[];\n fallback?: string;\n };\n\n/**\n * Specification for a file the tool produces. Lives on `NodeMeta.outputs` of\n * the struct node (root sequence or subcommand sequence) that declared it.\n * Per-output gating is derived downstream from the scope's binding gate and\n * each ref binding's gate, so no host node or `optional` flag is stored.\n */\nexport interface Output {\n name?: string;\n doc?: Documentation;\n tokens: OutputToken[];\n mediaTypes?: MediaTypeIdentifier[];\n}\n\n/** Metadata attached to any IR node. */\nexport interface NodeMeta {\n /** Name identifier for this node (used by solver for binding names). */\n name?: string;\n /**\n * The discriminator (`@type`) tag for this node when it is a union arm (a\n * Boutiques sub-command). Kept separate from `name`: a single-field\n * sub-command collapses onto its inner field, whose `name` then wins, so the\n * tag would otherwise become the inner field's id - e.g. two distinct\n * sub-commands `VariousString`/`VariousFile` both wrapping an `obj` field\n * would collide on `@type: \"obj\"` (and the second arm would be unreachable).\n * `mergeMeta` preserves this through the collapse and the solver prefers it\n * for the variant tag, so distinct sub-commands keep distinct, reachable\n * `@type`s.\n */\n variantTag?: string;\n doc?: Documentation;\n defaultValue?: string | number | boolean;\n /** Files produced when this node is active. See `Output`. */\n outputs?: Output[];\n}\n\n/** Application-level metadata for the root node. */\nexport interface AppMeta {\n id?: string;\n version?: string;\n doc?: Documentation;\n container?: {\n image: string;\n type?: \"docker\" | \"singularity\";\n };\n stdout?: StreamOutput;\n stderr?: StreamOutput;\n}\n\nexport interface StreamOutput {\n name: string;\n doc?: Documentation;\n}\n\n/**\n * Produce a usable name for an Output. Frontends may leave `Output.name`\n * unset; downstream code (resolver, validator, backends) needs a stable\n * identifier for diagnostics and field naming. Falls back to `output_<index>`\n * keyed by the output's position in tree-walk order.\n */\nexport function effectiveOutputName(output: Output, index: number): string {\n return output.name ?? `output_${index}`;\n}\n","/**\n * Destruct a template string to a list of strings and replacements.\n *\n * This is used to safely destruct boutiques `command-line` as well as `path-template` strings.\n *\n * @example\n * destructTemplate(\"hello x, I am y\", { x: 12, y: 34 })\n * // => [\"hello \", 12, \", I am \", 34]\n */\nexport function destructTemplate<T>(template: string, lookup: Record<string, T>): (string | T)[] {\n const destructed: (string | T)[] = [];\n const stack: (string | T)[] = [template];\n\n while (stack.length > 0) {\n // biome-ignore lint/style/noNonNullAssertion: length check guarantees element exists\n const x = stack.shift()!;\n\n if (typeof x !== \"string\") {\n destructed.push(x);\n continue;\n }\n\n let didSplit = false;\n\n for (const [alias, replacement] of Object.entries(lookup)) {\n const idx = x.indexOf(alias);\n if (idx !== -1) {\n const left = x.slice(0, idx);\n const right = x.slice(idx + alias.length);\n\n if (right.length > 0) {\n stack.unshift(right);\n }\n stack.unshift(replacement);\n if (left.length > 0) {\n stack.unshift(left);\n }\n\n didSplit = true;\n break;\n }\n }\n\n if (!didSplit) {\n destructed.push(x);\n }\n }\n\n return destructed;\n}\n","/**\n * Split a Boutiques command into a list of arguments.\n *\n * @param command - The Boutiques command.\n * @returns The list of arguments.\n * @throws {Error} If command is null or undefined.\n */\nexport function boutiquesSplitCommand(command: string): string[] {\n if (command == null) {\n throw new Error(\"Command cannot be null or undefined\");\n }\n\n const args: string[] = [];\n let current = \"\";\n let inSingleQuote = false;\n let inDoubleQuote = false;\n let escaped = false;\n\n for (const char of command) {\n if (escaped) {\n // In double quotes, only certain escapes are meaningful\n if (inDoubleQuote && ![\"\\\\\", '\"', \"$\", \"`\", \"\\n\"].includes(char)) {\n current += \"\\\\\";\n }\n current += char;\n escaped = false;\n continue;\n }\n\n if (char === \"\\\\\" && !inSingleQuote) {\n escaped = true;\n continue;\n }\n\n if (char === \"'\" && !inDoubleQuote) {\n inSingleQuote = !inSingleQuote;\n continue;\n }\n\n if (char === '\"' && !inSingleQuote) {\n inDoubleQuote = !inDoubleQuote;\n continue;\n }\n\n if (/\\s/.test(char) && !inSingleQuote && !inDoubleQuote) {\n if (current) {\n args.push(current);\n current = \"\";\n }\n continue;\n }\n\n current += char;\n }\n\n if (inSingleQuote || inDoubleQuote) {\n throw new Error(\"Unclosed quote in command string\");\n }\n\n if (escaped) {\n throw new Error(\"Trailing backslash in command string\");\n }\n\n if (current) {\n args.push(current);\n }\n\n return args;\n}\n","import { nodeRef } from \"../../ir/meta.js\";\nimport type { AppMeta, NodeMeta, NodeRef, Output, OutputToken } from \"../../ir/meta.js\";\nimport type { Documentation } from \"../../ir/types.js\";\nimport type {\n Alternative,\n Expr,\n Float,\n Int,\n Literal,\n Optional,\n Path,\n Repeat,\n Sequence,\n Str,\n} from \"../../ir/node.js\";\nimport type {\n Frontend,\n ParseError,\n ParseResult,\n ParseWarning,\n SourceLocation,\n} from \"../frontend.js\";\nimport { destructTemplate } from \"./destruct-template.js\";\nimport { boutiquesSplitCommand } from \"./split-command.js\";\n\n// Type guards\n\nfunction isObject(x: unknown): x is Record<string, unknown> {\n return typeof x === \"object\" && x !== null && !Array.isArray(x);\n}\n\nfunction isString(x: unknown): x is string {\n return typeof x === \"string\";\n}\n\nfunction isNumber(x: unknown): x is number {\n return typeof x === \"number\";\n}\n\nfunction isArray(x: unknown): x is unknown[] {\n return Array.isArray(x);\n}\n\n// Outputs attach to the rootSeq of the descriptor they were declared in\n// (root or a subcommand's sequence). Per-ref gating is computed downstream\n// from each referenced binding's `gate`.\n\n// Boutiques types\n\ntype BtInput = Record<string, unknown>;\ntype BtDescriptor = Record<string, unknown>;\n\nenum InputTypePrimitive {\n String = \"String\",\n Float = \"Float\",\n Integer = \"Integer\",\n File = \"File\",\n Flag = \"Flag\",\n SubCommand = \"SubCommand\",\n SubCommandUnion = \"SubCommandUnion\",\n}\n\ninterface InputType {\n primitive: InputTypePrimitive;\n isList: boolean;\n isOptional: boolean;\n isEnum: boolean;\n}\n\n// Parser\n\nexport class BoutiquesParser implements Frontend {\n readonly name = \"boutiques\";\n readonly extensions = [\"json\"];\n\n private errors: ParseError[] = [];\n private warnings: ParseWarning[] = [];\n\n private reset(): void {\n this.errors = [];\n this.warnings = [];\n }\n\n private error(message: string, location?: SourceLocation): void {\n this.errors.push({ message, location });\n }\n\n private warn(message: string, location?: SourceLocation): void {\n this.warnings.push({ message, location });\n }\n\n // JSON parsing\n\n private parseJSON(source: string): BtDescriptor | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(source);\n } catch (e) {\n this.error(e instanceof SyntaxError ? e.message : \"Invalid JSON\");\n return null;\n }\n\n if (!isObject(parsed)) {\n this.error(\"JSON source is not an object\");\n return null;\n }\n\n return parsed;\n }\n\n // Input type detection\n\n private getInputTypePrimitive(btInput: BtInput): InputTypePrimitive | null {\n const btType = btInput.type;\n\n if (btType === undefined) {\n this.error(`type is missing for input: '${btInput.id}'`);\n return null;\n }\n\n if (isObject(btType)) return InputTypePrimitive.SubCommand;\n if (isArray(btType)) return InputTypePrimitive.SubCommandUnion;\n\n const typeName = isString(btType) ? btType : String(btType);\n\n switch (typeName) {\n case \"String\":\n return InputTypePrimitive.String;\n case \"File\":\n return InputTypePrimitive.File;\n case \"Flag\":\n return InputTypePrimitive.Flag;\n case \"Number\":\n return btInput.integer ? InputTypePrimitive.Integer : InputTypePrimitive.Float;\n default:\n this.error(`Unknown input type: '${typeName}'`);\n return null;\n }\n }\n\n private getInputType(btInput: BtInput): InputType | null {\n const primitive = this.getInputTypePrimitive(btInput);\n if (primitive === null) return null;\n\n if (primitive === InputTypePrimitive.Flag) {\n return { primitive, isList: false, isOptional: true, isEnum: false };\n }\n\n const isList = btInput.list === true;\n const isOptional = btInput.optional === true;\n const isEnum = btInput[\"value-choices\"] !== undefined;\n\n if (primitive === InputTypePrimitive.File && isEnum) {\n this.error(`File input '${btInput.id}' cannot have value-choices`);\n return null;\n }\n\n return { primitive, isList, isOptional, isEnum };\n }\n\n // Metadata building\n\n private buildNodeMeta(btInput: BtInput): NodeMeta | undefined {\n const name = btInput.id;\n const title = btInput.name;\n const description = btInput.description;\n const defaultValue = btInput[\"default-value\"];\n\n const hasDefault =\n isString(defaultValue) || isNumber(defaultValue) || typeof defaultValue === \"boolean\";\n\n if (!isString(name) && !isString(title) && !isString(description) && !hasDefault) {\n return undefined;\n }\n\n return {\n ...(isString(name) && { name }),\n ...((isString(title) || isString(description)) && {\n doc: {\n ...(isString(title) && { title }),\n ...(isString(description) && { description }),\n },\n }),\n ...(hasDefault && { defaultValue }),\n };\n }\n\n private buildStreamMeta(\n bt: Record<string, unknown>,\n ): { name: string; doc?: { title?: string; description?: string } } | undefined {\n const id = bt.id;\n if (!isString(id)) return undefined;\n\n const name = bt.name;\n const description = bt.description;\n\n return {\n name: id,\n ...((isString(name) || isString(description)) && {\n doc: {\n ...(isString(name) && { title: name }),\n ...(isString(description) && { description }),\n },\n }),\n };\n }\n\n private buildOutput(\n out: BtInput,\n lookup: Record<string, NodeRef>,\n idOptional: Set<string>,\n ): { output: Output } | null {\n const id = out.id;\n if (!isString(id)) {\n this.error(\"output-files entry missing id\");\n return null;\n }\n\n const template = out[\"path-template\"];\n if (!isString(template)) {\n this.error(`output-files entry '${id}' missing path-template`);\n return null;\n }\n\n const stripRaw = out[\"path-template-stripped-extensions\"];\n const stripExtensions =\n isArray(stripRaw) && stripRaw.every(isString) && stripRaw.length > 0\n ? (stripRaw as string[])\n : undefined;\n\n const parts = destructTemplate<NodeRef>(template, lookup);\n\n const tokens: OutputToken[] = parts.map((part) => {\n if (typeof part === \"string\") return { kind: \"literal\" as const, value: part };\n return {\n kind: \"ref\" as const,\n target: part,\n ...(stripExtensions && { stripExtensions }),\n // Boutiques substitutes an unset optional input with the empty string.\n ...(idOptional.has(part.name) && { fallback: \"\" }),\n };\n });\n\n const title = out.name;\n const description = out.description;\n const output: Output = { name: id, tokens };\n if (isString(title) || isString(description)) {\n output.doc = {\n ...(isString(title) && { title }),\n ...(isString(description) && { description }),\n };\n }\n // Boutiques' `optional: bool` on output-files is a tool-author hint and is\n // re-derived at emit time from the refs' bindings - we don't store it.\n\n return { output };\n }\n\n /**\n * Attach `output-files` entries to the descriptor's rootSeq. Per-output\n * gating (which refs are optional, which arm we're inside) is recovered\n * downstream from each ref binding's `gate`.\n */\n private attachOutputs(rootSeq: Sequence, bt: BtDescriptor): void {\n const outputFiles = bt[\"output-files\"];\n if (!isArray(outputFiles)) return;\n\n const lookup: Record<string, NodeRef> = {};\n const idOptional = new Set<string>();\n const inputs = bt[\"inputs\"];\n if (isArray(inputs)) {\n for (const input of inputs) {\n if (isObject(input) && isString(input[\"value-key\"]) && isString(input.id)) {\n lookup[input[\"value-key\"]] = nodeRef(input.id);\n if (input.optional === true) idOptional.add(input.id);\n }\n }\n }\n\n for (const out of outputFiles) {\n if (!isObject(out)) {\n this.warn(\"Skipping non-object output-files entry\");\n continue;\n }\n const built = this.buildOutput(out, lookup, idOptional);\n if (!built) continue;\n\n if (!rootSeq.meta) rootSeq.meta = {};\n rootSeq.meta.outputs = [...(rootSeq.meta.outputs ?? []), built.output];\n }\n }\n\n private buildAppMeta(bt: BtDescriptor): AppMeta | undefined {\n const id = bt.id ?? bt.name;\n if (!isString(id)) return undefined;\n\n const name = bt.name;\n const description = bt.description;\n const version = bt[\"tool-version\"];\n const author = bt.author;\n const url = bt.url;\n const container = bt[\"container-image\"];\n const stdout = bt[\"stdout-output\"];\n const stderr = bt[\"stderr-output\"];\n\n const doc: Documentation = {\n ...(isString(name) && { title: name }),\n ...(isString(description) && { description }),\n ...(isString(author) && { authors: [author] }),\n ...(isString(url) && { urls: [url] }),\n };\n\n return {\n id,\n ...(isString(version) && { version }),\n ...(Object.keys(doc).length > 0 && { doc }),\n ...(isObject(container) &&\n isString(container.image) && {\n container: {\n image: container.image,\n ...(isString(container.type) && {\n type: container.type as \"docker\" | \"singularity\",\n }),\n },\n }),\n ...(isObject(stdout) && { stdout: this.buildStreamMeta(stdout) }),\n ...(isObject(stderr) && { stderr: this.buildStreamMeta(stderr) }),\n };\n }\n\n // Terminal node building\n\n private buildEnumAlternative(choices: unknown[], meta?: NodeMeta): Alternative | null {\n const alts: Literal[] = [];\n\n for (const choice of choices) {\n if (isString(choice)) {\n alts.push({ kind: \"literal\", attrs: { str: choice } });\n } else if (isNumber(choice)) {\n alts.push({ kind: \"literal\", attrs: { str: String(choice) } });\n } else {\n this.warn(`Ignoring non-string/number enum choice: ${JSON.stringify(choice)}`);\n }\n }\n\n if (alts.length === 0) return null;\n\n const node: Alternative = { kind: \"alternative\", attrs: { alts } };\n if (meta) node.meta = meta;\n return node;\n }\n\n private buildTerminal(btInput: BtInput, inputType: InputType): Expr | null {\n const meta = this.buildNodeMeta(btInput);\n\n if (inputType.isEnum) {\n const choices = btInput[\"value-choices\"];\n if (!isArray(choices)) {\n this.error(`Invalid value-choices for '${btInput.id}'`);\n return null;\n }\n return this.buildEnumAlternative(choices, meta);\n }\n\n switch (inputType.primitive) {\n case InputTypePrimitive.String: {\n const node: Str = { kind: \"str\", attrs: {} };\n if (meta) node.meta = meta;\n return node;\n }\n\n case InputTypePrimitive.Integer: {\n const node: Int = { kind: \"int\", attrs: {} };\n if (isNumber(btInput.minimum)) {\n node.attrs.minValue = Math.floor(btInput.minimum);\n if (btInput[\"exclusive-minimum\"] === true) node.attrs.minValue += 1;\n }\n if (isNumber(btInput.maximum)) {\n node.attrs.maxValue = Math.floor(btInput.maximum);\n if (btInput[\"exclusive-maximum\"] === true) node.attrs.maxValue -= 1;\n }\n if (meta) node.meta = meta;\n return node;\n }\n\n case InputTypePrimitive.Float: {\n const node: Float = { kind: \"float\", attrs: {} };\n if (isNumber(btInput.minimum)) node.attrs.minValue = btInput.minimum;\n if (isNumber(btInput.maximum)) node.attrs.maxValue = btInput.maximum;\n if (meta) node.meta = meta;\n return node;\n }\n\n case InputTypePrimitive.File: {\n const node: Path = {\n kind: \"path\",\n attrs: {\n ...(btInput[\"resolve-parent\"] === true && { resolveParent: true }),\n ...(btInput.mutable === true && { mutable: true }),\n },\n };\n if (meta) node.meta = meta;\n return node;\n }\n\n case InputTypePrimitive.Flag: {\n const flag = btInput[\"command-line-flag\"];\n if (!isString(flag)) {\n this.error(`Flag input '${btInput.id}' missing command-line-flag`);\n return null;\n }\n const literal: Literal = { kind: \"literal\", attrs: { str: flag } };\n const node: Optional = { kind: \"optional\", attrs: { node: literal } };\n const flagMeta = meta ?? {};\n if (flagMeta.defaultValue === undefined) flagMeta.defaultValue = false;\n node.meta = flagMeta;\n return node;\n }\n\n case InputTypePrimitive.SubCommand: {\n const nested = btInput.type;\n if (!isObject(nested)) {\n this.error(`Invalid subcommand type for '${btInput.id}'`);\n return null;\n }\n const node = this.parseDescriptor(nested);\n if (node && meta) node.meta = meta;\n return node;\n }\n\n case InputTypePrimitive.SubCommandUnion: {\n const alts = btInput.type;\n if (!isArray(alts)) {\n this.error(`Invalid subcommand union type for '${btInput.id}'`);\n return null;\n }\n const parsedAlts: Expr[] = [];\n // A discriminated union dispatches on a unique `@type` (the subcommand\n // id), recorded as `variantTag` so it survives a single-field\n // sub-command collapsing onto its inner field. Two genuinely-duplicate\n // ids (c3d c2d/c3d/c4d declare two byte-identical sub-commands) are\n // dodged to a unique tag so both arms stay addressable rather than the\n // second being an unreachable, codegen-breaking duplicate (the backend\n // rejects duplicate `@type`s outright).\n const usedTags = new Set<string>();\n for (const alt of alts) {\n if (!isObject(alt)) {\n this.warn(\"Skipping non-object subcommand alternative\");\n continue;\n }\n const parsed = this.parseDescriptor(alt);\n if (parsed) {\n // Tag the arm from the subcommand descriptor's id.\n const altMeta = this.buildAppMeta(alt);\n if (altMeta?.id) {\n let tag = altMeta.id;\n if (usedTags.has(tag)) {\n let n = 2;\n while (usedTags.has(`${altMeta.id}_${n}`)) n++;\n tag = `${altMeta.id}_${n}`;\n this.warn(\n `Duplicate subcommand id '${altMeta.id}' in union '${btInput.id}'; ` +\n `renamed variant to '${tag}' to keep the @type discriminator unique.`,\n );\n }\n usedTags.add(tag);\n // `variantTag` is the discriminator (survives collapse); `name`\n // gives a unique binding/type name for non-collapsing (multi-field)\n // arms - it is clobbered by the inner field's name when the arm\n // collapses, which is why the tag needs its own channel.\n parsed.meta = { ...parsed.meta, name: tag, variantTag: tag };\n }\n parsedAlts.push(parsed);\n }\n }\n if (parsedAlts.length === 0) {\n this.error(`No valid alternatives for subcommand union '${btInput.id}'`);\n return null;\n }\n if (parsedAlts.length === 1) {\n const node = parsedAlts[0]!;\n if (meta) node.meta = { ...node.meta, ...meta };\n return node;\n }\n const node: Alternative = { kind: \"alternative\", attrs: { alts: parsedAlts } };\n if (meta) node.meta = meta;\n return node;\n }\n\n default:\n return null;\n }\n }\n\n // Node wrapping (repeat, flag, optional)\n\n private wrapWithRepeat(node: Expr, btInput: BtInput): Repeat {\n return {\n kind: \"repeat\",\n attrs: {\n node,\n ...(isString(btInput[\"list-separator\"]) && { join: btInput[\"list-separator\"] }),\n ...(isNumber(btInput[\"min-list-entries\"]) && { countMin: btInput[\"min-list-entries\"] }),\n ...(isNumber(btInput[\"max-list-entries\"]) && { countMax: btInput[\"max-list-entries\"] }),\n },\n };\n }\n\n private wrapWithFlag(node: Expr, btInput: BtInput): Expr {\n const flag = btInput[\"command-line-flag\"];\n if (!isString(flag)) return node;\n\n const flagSep = btInput[\"command-line-flag-separator\"];\n const prefix: Literal = {\n kind: \"literal\",\n attrs: { str: flag + (flagSep ?? \"\") },\n };\n\n return { kind: \"sequence\", attrs: { nodes: [prefix, node] } };\n }\n\n private wrapWithOptional(node: Expr): Optional {\n return { kind: \"optional\", attrs: { node } };\n }\n\n private wrapNode(node: Expr, btInput: BtInput, inputType: InputType): Expr {\n // Flags handle their own optional wrapping\n if (inputType.primitive === InputTypePrimitive.Flag) {\n return node;\n }\n\n const inner = node;\n\n // Order: repeat -> flag -> optional\n // This produces: optional(sequence(flag, repeat(value)))\n\n if (inputType.isList) {\n node = this.wrapWithRepeat(node, btInput);\n }\n\n node = this.wrapWithFlag(node, btInput);\n\n if (inputType.isOptional) {\n node = this.wrapWithOptional(node);\n }\n\n // Hoist metadata (doc, default) to outermost wrapper so backends find it\n // on the binding node. Keep name on inner for solver's findDeepName.\n if (node !== inner && inner.meta) {\n const { name, ...rest } = inner.meta;\n if (Object.keys(rest).length > 0) {\n node.meta = { ...node.meta, ...rest };\n inner.meta = name ? { name } : undefined;\n }\n }\n\n return node;\n }\n\n // Command line parsing\n\n private parseCommandLineTemplate(\n template: string,\n inputsLookup: Map<string, BtInput>,\n ): Array<Array<string | BtInput>> {\n let args: string[];\n try {\n args = boutiquesSplitCommand(template);\n } catch (e) {\n this.error(`Failed to parse command-line: ${e instanceof Error ? e.message : String(e)}`);\n return [];\n }\n\n const lookupObj = Object.fromEntries(inputsLookup);\n return args.map((arg) => destructTemplate(arg, lookupObj));\n }\n\n private parseDescriptor(bt: BtDescriptor): Sequence | null {\n // Build inputs lookup\n const inputs = bt[\"inputs\"];\n const inputsLookup = new Map<string, BtInput>();\n\n if (isArray(inputs)) {\n for (const input of inputs) {\n if (isObject(input) && isString(input[\"value-key\"])) {\n inputsLookup.set(input[\"value-key\"], input);\n }\n }\n }\n\n // Parse command line template\n const commandLine = bt[\"command-line\"];\n const segments = isString(commandLine)\n ? this.parseCommandLineTemplate(commandLine, inputsLookup)\n : [];\n\n // Build IR\n const rootSeq: Sequence = { kind: \"sequence\", attrs: { nodes: [] } };\n\n for (const segment of segments) {\n const seq: Sequence = { kind: \"sequence\", attrs: { nodes: [], join: \"\" } };\n\n for (const elem of segment) {\n if (isObject(elem)) {\n const inputType = this.getInputType(elem);\n if (inputType === null) continue;\n\n let node = this.buildTerminal(elem, inputType);\n if (node === null) continue;\n\n node = this.wrapNode(node, elem, inputType);\n seq.attrs.nodes.push(node);\n } else {\n seq.attrs.nodes.push({ kind: \"literal\", attrs: { str: elem } });\n }\n }\n\n // Flatten single-node sequences\n if (seq.attrs.nodes.length === 1) {\n rootSeq.attrs.nodes.push(seq.attrs.nodes[0]!);\n } else if (seq.attrs.nodes.length > 1) {\n rootSeq.attrs.nodes.push(seq);\n }\n }\n\n this.attachOutputs(rootSeq, bt);\n return rootSeq;\n }\n\n // Public API\n\n parse(source: string, _filename?: string): ParseResult {\n this.reset();\n\n const bt = this.parseJSON(source);\n if (bt === null) {\n return {\n expr: { kind: \"sequence\", attrs: { nodes: [] } },\n errors: this.errors,\n warnings: this.warnings,\n };\n }\n\n const baseMeta = this.buildAppMeta(bt);\n if (!baseMeta) {\n this.error(\"Descriptor is missing id/name\");\n return {\n expr: { kind: \"sequence\", attrs: { nodes: [] } },\n errors: this.errors,\n warnings: this.warnings,\n };\n }\n\n const expr = this.parseDescriptor(bt);\n if (expr === null) {\n this.error(\"Failed to parse command structure\");\n return {\n expr: { kind: \"sequence\", attrs: { nodes: [] } },\n errors: this.errors,\n warnings: this.warnings,\n };\n }\n\n // Set root struct name from descriptor id if not already set\n if (!expr.meta?.name && baseMeta?.id) {\n expr.meta = { ...expr.meta, name: baseMeta.id };\n }\n\n return {\n meta: baseMeta,\n expr,\n errors: this.errors,\n warnings: this.warnings,\n };\n }\n}\n","import type { NodeMeta } from \"./meta.js\";\nimport type {\n Alternative,\n Expr,\n Float,\n Int,\n Literal,\n Optional,\n Path,\n Repeat,\n Sequence,\n Str,\n} from \"./node.js\";\n\n// -- Terminals --\n\nexport function lit(str: string): Literal {\n return { kind: \"literal\", attrs: { str } };\n}\n\nexport function str(meta?: NodeMeta | string): Str {\n return { kind: \"str\", attrs: {}, meta: normalizeMeta(meta) };\n}\n\nexport function int(meta?: NodeMeta | string): Int {\n return { kind: \"int\", attrs: {}, meta: normalizeMeta(meta) };\n}\n\nexport function float(meta?: NodeMeta | string): Float {\n return { kind: \"float\", attrs: {}, meta: normalizeMeta(meta) };\n}\n\nexport function path(meta?: NodeMeta | string): Path {\n return { kind: \"path\", attrs: {}, meta: normalizeMeta(meta) };\n}\n\n// -- Structural --\n\nexport function seq(...nodes: Expr[]): Sequence {\n return { kind: \"sequence\", attrs: { nodes } };\n}\n\nexport function seqJoin(join: string, ...nodes: Expr[]): Sequence {\n return { kind: \"sequence\", attrs: { nodes, join } };\n}\n\nexport function opt(node: Expr, meta?: NodeMeta | string): Optional {\n return { kind: \"optional\", attrs: { node }, meta: normalizeMeta(meta) };\n}\n\nexport function rep(node: Expr, meta?: NodeMeta | string): Repeat {\n return { kind: \"repeat\", attrs: { node }, meta: normalizeMeta(meta) };\n}\n\nexport function repJoin(join: string, node: Expr, meta?: NodeMeta | string): Repeat {\n return { kind: \"repeat\", attrs: { node, join }, meta: normalizeMeta(meta) };\n}\n\nexport function alt(...alts: Expr[]): Alternative {\n return { kind: \"alternative\", attrs: { alts } };\n}\n\n// -- Helpers --\n\nfunction normalizeMeta(meta: NodeMeta | string | undefined): NodeMeta | undefined {\n if (meta === undefined) return undefined;\n if (typeof meta === \"string\") return { name: meta };\n return meta;\n}\n","/** Split a string into lowercase word tokens for case conversion. */\nfunction tokenize(s: string): string[] {\n return s\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\") // camelCase boundary\n .replace(/([A-Z]+)([A-Z][a-z])/g, \"$1 $2\") // consecutive uppercase -> keep runs\n .replace(/[^a-zA-Z0-9]+/g, \" \")\n .trim()\n .toLowerCase()\n .split(/\\s+/)\n .filter(Boolean);\n}\n\nexport function snakeCase(s: string): string {\n return tokenize(s).join(\"_\");\n}\n\nexport function screamingSnakeCase(s: string): string {\n return tokenize(s).join(\"_\").toUpperCase();\n}\n\nexport function pascalCase(s: string): string {\n return tokenize(s)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(\"\");\n}\n\nexport function camelCase(s: string): string {\n const pascal = pascalCase(s);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n}\n","import { alt, float, int, lit, opt, path, rep, repJoin, seq, str } from \"../../ir/builders.js\";\nimport { nodeRef } from \"../../ir/meta.js\";\nimport type { AppMeta, NodeMeta, Output } from \"../../ir/meta.js\";\nimport type { Documentation } from \"../../ir/types.js\";\nimport type { Expr, Sequence } from \"../../ir/node.js\";\nimport { snakeCase } from \"../../backend/string-case.js\";\nimport type {\n Frontend,\n ParseError,\n ParseResult,\n ParseWarning,\n SourceLocation,\n} from \"../frontend.js\";\n\n// Type guards\n\nfunction isObject(x: unknown): x is Record<string, unknown> {\n return typeof x === \"object\" && x !== null && !Array.isArray(x);\n}\n\nfunction isString(x: unknown): x is string {\n return typeof x === \"string\";\n}\n\nfunction isNumber(x: unknown): x is number {\n return typeof x === \"number\" && Number.isFinite(x);\n}\n\nfunction isArray(x: unknown): x is unknown[] {\n return Array.isArray(x);\n}\n\n/** Coerce a possibly-missing list field to an array. */\nfunction asArray(x: unknown): unknown[] {\n return isArray(x) ? x : [];\n}\n\n/** Input file types: each maps to a plain path terminal. */\nconst INPUT_TYPES = new Set<string>([\"file in\", \"image in\", \"directory in\", \"tracks in\"]);\n\n/** Output file types: each maps to a `str` (the user-supplied filename) + an `Output`. */\nconst OUTPUT_TYPES = new Set<string>([\"file out\", \"image out\", \"directory out\", \"tracks out\"]);\n\n/** A fresh empty root sequence for error returns (IR passes mutate in place,\n * so callers must not share a single instance). */\nfunction emptyExpr(): Sequence {\n return { kind: \"sequence\", attrs: { nodes: [] } };\n}\n\n/**\n * Parser for MRtrix3 C++ command definitions (`mrtrix.json`), as dumped by the\n * `__print_usage_json__` hook (see niwrap `extraction/mrtrix/`).\n *\n * The format is flat: positional `arguments`, plus `option_groups[].options`\n * where each option is a single-dash switch (`-id`) carrying 0..N positional\n * `arguments`. There are no unions, conditionals, or nested options. We lower\n * it onto the same `Expr` shapes the Boutiques/Workbench parsers emit:\n *\n * <command> <positionals...> [-option ...] ...\n *\n * - argument (input type) -> typed terminal\n * - argument (`* out`) -> str terminal + an Output entry referencing it\n * - option, 0 args -> opt(lit(-switch)) (bool flag)\n * - option, 1 arg -> opt(seq(lit(-switch), value)) (flat optional)\n * - option, >1 arg / multi -> opt|rep(seq(lit(-switch), ...)) (sub-struct)\n *\n * Type mapping mirrors the v1 `mrt2bt.js` converter's `set_type`, plus `choice`\n * values: when the dump carries `choices` it lowers to an enum (an alternative\n * of literals), else a plain string (older dumps that omit the values - as v1\n * always did). Per-command quirks v1 hand-coded that the flat dump cannot\n * express (e.g. dwi2fod/mtnormalise paired in/out args) are intentionally NOT\n * special-cased here - they are patched on the niwrap side post-dump, keeping\n * this frontend format-general.\n */\nexport class MrtrixParser implements Frontend {\n readonly name = \"mrtrix\";\n readonly extensions = [\"json\"];\n\n private errors: ParseError[] = [];\n private warnings: ParseWarning[] = [];\n // Root-level sibling names (positionals + options). MRtrix reuses an id\n // across the positional and option namespaces (e.g. amp2response's `directions`\n // is both), which would collide as struct field names once flattened. Unlike\n // Boutiques/argdump/workbench, this format does not guarantee unique ids, so\n // the frontend disambiguates. The flag token keeps the raw `-id`; only the\n // binding name is suffixed.\n private usedNames = new Set<string>();\n\n private reset(): void {\n this.errors = [];\n this.warnings = [];\n this.usedNames = new Set<string>();\n }\n\n /** Reserve a unique sibling name, suffixing `_2`, `_3`, ... on collision. */\n private uniqueName(base: string): string {\n if (!this.usedNames.has(base)) {\n this.usedNames.add(base);\n return base;\n }\n let n = 2;\n while (this.usedNames.has(`${base}_${n}`)) n++;\n const name = `${base}_${n}`;\n this.usedNames.add(name);\n this.warn(`Duplicate id '${base}'; renamed a sibling binding to '${name}'`);\n return name;\n }\n\n private error(message: string, location?: SourceLocation): void {\n this.errors.push({ message, location });\n }\n\n private warn(message: string, location?: SourceLocation): void {\n this.warnings.push({ message, location });\n }\n\n private parseJSON(source: string): Record<string, unknown> | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(source);\n } catch (e) {\n this.error(e instanceof SyntaxError ? e.message : \"Invalid JSON\");\n return null;\n }\n if (!isObject(parsed)) {\n this.error(\"JSON source is not an object\");\n return null;\n }\n return parsed;\n }\n\n // -- Metadata --\n\n private docFrom(description: unknown): Documentation | undefined {\n return isString(description) && description.length > 0 ? { description } : undefined;\n }\n\n private buildAppMeta(cmd: Record<string, unknown>): AppMeta | undefined {\n const name = cmd.name;\n if (!isString(name) || name.length === 0) {\n this.error(\"MRtrix descriptor missing required 'name' string\");\n return undefined;\n }\n\n const synopsis = cmd.synopsis;\n const paragraphs = asArray(cmd.description).filter(isString).join(\"\\n\\n\");\n const author = cmd.author;\n const references = asArray(cmd.references).filter(isString);\n const version = cmd.version;\n\n const doc: Documentation = {\n ...(isString(synopsis) && synopsis.length > 0 && { title: synopsis }),\n ...(paragraphs.length > 0 && { description: paragraphs }),\n ...(isString(author) && author.length > 0 && { authors: [author] }),\n ...(references.length > 0 && { literature: references }),\n urls: [`https://mrtrix.readthedocs.io/en/latest/reference/commands/${name}.html`],\n };\n\n return {\n id: name,\n ...(isString(version) && version.length > 0 && { version }),\n doc,\n };\n }\n\n // -- Terminals --\n\n /**\n * Integer/float bounds, when the dump carries them. The C++ hook serializes\n * `Argument::limits.{i,f}.{min,max}` as `min`/`max`, omitting the unbounded\n * sentinels - so a present value is a real, tool-enforced bound.\n */\n private numericBounds(arg: Record<string, unknown>): { minValue?: number; maxValue?: number } {\n const lo = arg.min;\n const hi = arg.max;\n return {\n ...(isNumber(lo) && { minValue: lo }),\n ...(isNumber(hi) && { maxValue: hi }),\n };\n }\n\n /**\n * Lower one MRtrix argument to its terminal node (carrying name + doc) and,\n * for output types, an accompanying `Output`.\n */\n private buildArgTerminal(\n arg: Record<string, unknown>,\n meta: NodeMeta,\n ): { node: Expr; output?: Output } | null {\n const argType = arg.type;\n if (!isString(argType)) {\n this.error(`MRtrix argument '${String(arg.id)}' missing 'type'`);\n return null;\n }\n\n const name = meta.name!;\n\n switch (argType) {\n case \"integer\": {\n const node = int(meta);\n Object.assign(node.attrs, this.numericBounds(arg));\n return { node };\n }\n case \"float\": {\n const node = float(meta);\n Object.assign(node.attrs, this.numericBounds(arg));\n return { node };\n }\n case \"text\":\n case \"undefined\":\n case \"boolean\":\n // `boolean` rarely (if ever) appears in a dump; treat its literal token\n // as a string rather than erroring on an unknown type.\n return { node: str(meta) };\n case \"choice\": {\n // A `choice` carries its allowed values in `choices` (the C++ hook\n // serializes `Argument::limits.choices`). Lower to an enum: an\n // alternative of string literals. Older dumps omit the values - fall\n // back to a plain string so they still compile.\n const choices = arg.choices;\n if (isArray(choices)) {\n const alts = choices.filter(isString).map((c) => lit(c));\n if (alts.length > 0) {\n const node = alt(...alts);\n node.meta = meta;\n return { node };\n }\n }\n return { node: str(meta) };\n }\n // MRtrix sequences are always a single comma-separated token (parse_ints /\n // parse_floats split on `,`), so the list is comma-joined, never spaced.\n case \"int seq\": {\n const node = repJoin(\",\", int());\n node.meta = meta;\n return { node };\n }\n case \"float seq\": {\n const node = repJoin(\",\", float());\n node.meta = meta;\n return { node };\n }\n case \"various\": {\n // Anything: a bare string or a file. Mirror v1's `VariousString`/\n // `VariousFile` union so a path can be mounted while a plain literal is\n // still accepted. Union arms must be single-field structs (a bare scalar\n // arm has no data key for the backend to read); the `variantTag` keeps\n // the two `@type`s distinct after each single-field struct collapses.\n const stringArm = seq(str({ name: \"obj\" }));\n stringArm.meta = { name: \"VariousString\", variantTag: \"VariousString\" };\n const fileArm = seq(path({ name: \"obj\" }));\n fileArm.meta = { name: \"VariousFile\", variantTag: \"VariousFile\" };\n const node = alt(stringArm, fileArm);\n node.meta = meta;\n return { node };\n }\n default: {\n if (INPUT_TYPES.has(argType)) {\n return { node: path(meta) };\n }\n if (OUTPUT_TYPES.has(argType)) {\n const node = str(meta);\n const output: Output = {\n name,\n ...(meta.doc && { doc: meta.doc }),\n tokens: [{ kind: \"ref\", target: nodeRef(name) }],\n mediaTypes: [`mrtrix/${argType}`],\n };\n return { node, output };\n }\n this.error(`Unknown MRtrix type '${argType}' for '${name}'`);\n return null;\n }\n }\n }\n\n /**\n * A positional argument: typed terminal, wrapped for cardinality. Output-type\n * positionals push their `Output` onto the root's `outputs` collector.\n */\n private buildPositional(arg: unknown, rootOutputs: Output[]): Expr | null {\n if (!isObject(arg)) {\n this.warn(\"Skipping non-object argument\");\n return null;\n }\n const id = arg.id;\n if (!isString(id)) {\n this.error(\"MRtrix argument missing 'id'\");\n return null;\n }\n const meta: NodeMeta = {\n name: this.uniqueName(snakeCase(id)),\n ...this.docMeta(arg.description),\n };\n const built = this.buildArgTerminal(arg, meta);\n if (!built) return null;\n if (built.output) rootOutputs.push(built.output);\n\n return this.applyCardinality(built.node, arg, built.output !== undefined);\n }\n\n /** Wrap a terminal for `allow_multiple` (repeat) and `optional` (optional). */\n private applyCardinality(node: Expr, arg: Record<string, unknown>, isOutput: boolean): Expr {\n let result = node;\n if (arg.allow_multiple === true && !isOutput && result.kind !== \"repeat\") {\n result = rep(result);\n } else if (arg.allow_multiple === true && isOutput) {\n // Styx cannot rewrite a repeated output filename argument; v1 demoted\n // these to a single output. Keep the single str + warn.\n this.warn(`Output argument '${String(arg.id)}' is allow_multiple; treating as single`);\n }\n if (arg.optional === true) {\n result = opt(result);\n }\n return result;\n }\n\n private docMeta(description: unknown): { doc?: Documentation } {\n const doc = this.docFrom(description);\n return doc ? { doc } : {};\n }\n\n // -- Options --\n\n /**\n * An option `-{id}` with 0..N arguments. Returns the node plus any outputs\n * that must live on the ROOT (collapsing single-value options); sub-struct\n * options carry their own outputs on the struct sequence's meta.\n */\n private buildOption(option: unknown): { node: Expr; rootOutputs: Output[] } | null {\n if (!isObject(option)) {\n this.warn(\"Skipping non-object option\");\n return null;\n }\n const id = option.id;\n if (!isString(id)) {\n this.error(\"MRtrix option missing 'id'\");\n return null;\n }\n const flag = `-${id}`;\n const name = this.uniqueName(snakeCase(id));\n const optDoc = this.docFrom(option.description);\n const args = asArray(option.arguments);\n\n const required = option.optional === false;\n\n // Flag: no arguments. Repeatable -> a count (rep of the bare switch, like a\n // mrcalc stack operator that may be applied many times); otherwise a bool.\n if (args.length === 0) {\n if (option.allow_multiple === true) {\n return { node: rep(lit(flag), { name, ...(optDoc && { doc: optDoc }) }), rootOutputs: [] };\n }\n const meta: NodeMeta = { name, ...(optDoc && { doc: optDoc }), defaultValue: false };\n return { node: opt(lit(flag), meta), rootOutputs: [] };\n }\n\n // Single value, single occurrence: flat scalar named by the option (the\n // argument's own id is usually a generic metavar like \"number\"/\"image\", so\n // the binding takes the option's id + description, matching v1). Optional\n // unless the option is explicitly required.\n if (args.length === 1 && option.allow_multiple !== true) {\n const arg = args[0];\n if (!isObject(arg)) {\n this.error(`MRtrix option '${id}' has a non-object argument`);\n return null;\n }\n const meta: NodeMeta = { name, ...(optDoc && { doc: optDoc }) };\n const built = this.buildArgTerminal(arg, meta);\n if (!built) return null;\n const valueNode = this.applyCardinality(built.node, arg, built.output !== undefined);\n const flagSeq = seq(lit(flag), valueNode);\n const node = required ? flagSeq : opt(flagSeq);\n return { node, rootOutputs: built.output ? [built.output] : [] };\n }\n\n // Sub-struct: multiple arguments and/or a repeatable option.\n const inner: Expr[] = [lit(flag)];\n const structOutputs: Output[] = [];\n for (const rawArg of args) {\n if (!isObject(rawArg)) {\n this.warn(`Skipping non-object argument of option '${id}'`);\n continue;\n }\n const argId = rawArg.id;\n if (!isString(argId)) {\n this.error(`MRtrix option '${id}' has an argument missing 'id'`);\n continue;\n }\n // Fall back to the option's doc when the argument carries none.\n const argDoc = this.docFrom(rawArg.description) ?? optDoc;\n const meta: NodeMeta = { name: snakeCase(argId), ...(argDoc && { doc: argDoc }) };\n const built = this.buildArgTerminal(rawArg, meta);\n if (!built) continue;\n const valueNode = this.applyCardinality(built.node, rawArg, built.output !== undefined);\n inner.push(valueNode);\n if (built.output) structOutputs.push(built.output);\n }\n\n const structSeq = seq(...inner);\n structSeq.meta = { name, ...(structOutputs.length > 0 && { outputs: structOutputs }) };\n const wrapperMeta: NodeMeta | undefined = optDoc ? { doc: optDoc } : undefined;\n let node: Expr;\n if (option.allow_multiple === true) {\n node = rep(structSeq, wrapperMeta);\n } else if (required) {\n // Required, non-repeatable: keep the struct bare; doc lives on its meta.\n if (optDoc) structSeq.meta = { ...structSeq.meta, doc: optDoc };\n node = structSeq;\n } else {\n node = opt(structSeq, wrapperMeta);\n }\n return { node, rootOutputs: [] };\n }\n\n // -- Public API --\n\n parse(source: string, _filename?: string): ParseResult {\n this.reset();\n\n const cmd = this.parseJSON(source);\n if (!cmd) {\n return { expr: emptyExpr(), errors: this.errors, warnings: this.warnings };\n }\n\n const meta = this.buildAppMeta(cmd);\n if (!meta || !isString(cmd.name)) {\n return { expr: emptyExpr(), errors: this.errors, warnings: this.warnings };\n }\n\n const nodes: Expr[] = [lit(cmd.name)];\n const rootOutputs: Output[] = [];\n\n // Positionals first (ergonomic signature; MRtrix parses options anywhere).\n for (const arg of asArray(cmd.arguments)) {\n const node = this.buildPositional(arg, rootOutputs);\n if (node) nodes.push(node);\n }\n\n // Then options, in declaration order across all groups (incl. __standard_options).\n for (const group of asArray(cmd.option_groups)) {\n if (!isObject(group)) continue;\n for (const option of asArray(group.options)) {\n const built = this.buildOption(option);\n if (!built) continue;\n nodes.push(built.node);\n rootOutputs.push(...built.rootOutputs);\n }\n }\n\n const rootSeq = seq(...nodes);\n rootSeq.meta = { name: meta.id, ...(rootOutputs.length > 0 && { outputs: rootOutputs }) };\n\n return { meta, expr: rootSeq, errors: this.errors, warnings: this.warnings };\n }\n}\n","import { lit, opt, rep, seq, str, int, float, alt } from \"../../ir/builders.js\";\nimport { nodeRef } from \"../../ir/meta.js\";\nimport type { AppMeta, NodeMeta, Output } from \"../../ir/meta.js\";\nimport type { Documentation } from \"../../ir/types.js\";\nimport type { Expr, Path, Sequence } from \"../../ir/node.js\";\nimport { snakeCase } from \"../../backend/string-case.js\";\nimport type {\n Frontend,\n ParseError,\n ParseResult,\n ParseWarning,\n SourceLocation,\n} from \"../frontend.js\";\n\n// Type guards\n\nfunction isObject(x: unknown): x is Record<string, unknown> {\n return typeof x === \"object\" && x !== null && !Array.isArray(x);\n}\n\nfunction isString(x: unknown): x is string {\n return typeof x === \"string\";\n}\n\nfunction isArray(x: unknown): x is unknown[] {\n return Array.isArray(x);\n}\n\n// Workbench scalar/file type strings. See the v1 loader's model.py.\nconst TYPE_STRING = \"String\";\nconst TYPE_FLOATING_POINT = \"Floating Point\";\nconst TYPE_INTEGER = \"Integer\";\nconst TYPE_BOOLEAN = \"Boolean\";\n\nconst FILE_TYPES = new Set<string>([\n \"Surface File\",\n \"Border File\",\n \"Metric File\",\n \"Annotation File\",\n \"Cifti File\",\n \"Volume File\",\n \"Label File\",\n \"Foci File\",\n]);\n\n/** A fresh empty root sequence for error returns (IR passes mutate in place,\n * so callers must not share a single instance). */\nfunction emptyExpr(): Sequence {\n return { kind: \"sequence\", attrs: { nodes: [] } };\n}\n\n/**\n * Parser for Connectome Workbench command definitions (`workbench.json`).\n *\n * The format is recursive but flat in expressivity: positional `params`,\n * positional `outputs`, optional `options`, and `repeatable_options`, where an\n * option may nest its own options/repeatable_options arbitrarily deep. There\n * are no unions, constraints, or conditionals. We lower it onto the same `Expr`\n * shapes the Boutiques parser already emits for flagged sub-sequences:\n *\n * wb_command <command> <positionals...> [option ...] ...\n *\n * - param -> typed terminal (required)\n * - output -> str terminal (the user-supplied filename) + an Output\n * entry on the enclosing struct's meta, referencing it\n * - option -> opt(seq(lit(switch), ...)) (or opt(lit(switch)) flag)\n * - repeatable_option-> rep(seq(lit(switch), ...)) (or rep(lit(switch)) count)\n *\n * v1 reference: ../niwrap/tooling/src/wrap/apps/build/loaders/workbench/.\n */\nexport class WorkbenchParser implements Frontend {\n readonly name = \"workbench\";\n readonly extensions = [\"json\"];\n\n private errors: ParseError[] = [];\n private warnings: ParseWarning[] = [];\n\n private reset(): void {\n this.errors = [];\n this.warnings = [];\n }\n\n private error(message: string, location?: SourceLocation): void {\n this.errors.push({ message, location });\n }\n\n private warn(message: string, location?: SourceLocation): void {\n this.warnings.push({ message, location });\n }\n\n private parseJSON(source: string): Record<string, unknown> | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(source);\n } catch (e) {\n this.error(e instanceof SyntaxError ? e.message : \"Invalid JSON\");\n return null;\n }\n if (!isObject(parsed)) {\n this.error(\"JSON source is not an object\");\n return null;\n }\n return parsed;\n }\n\n // -- Metadata --\n\n private docFrom(description: unknown): Documentation | undefined {\n return isString(description) && description.length > 0 ? { description } : undefined;\n }\n\n private buildAppMeta(cmd: Record<string, unknown>): AppMeta | undefined {\n const command = cmd.command;\n if (!isString(command)) {\n this.error(\"Workbench descriptor missing required 'command' string\");\n return undefined;\n }\n\n const id = normalizeName(command);\n const title = cmd.short_description;\n const description = cmd.help_text;\n const doc: Documentation = {\n ...(isString(title) && { title }),\n ...(isString(description) && { description }),\n };\n\n const version = extractVersion(cmd.version_info);\n return {\n id,\n ...(version && { version }),\n ...(Object.keys(doc).length > 0 && { doc }),\n };\n }\n\n // -- Terminals --\n\n /** Map a workbench scalar/file type string to an IR terminal node. */\n private buildTerminal(type: string, meta: NodeMeta, ctx: string): Expr | null {\n switch (type) {\n case TYPE_STRING:\n return str(meta);\n case TYPE_INTEGER:\n return int(meta);\n case TYPE_FLOATING_POINT:\n return float(meta);\n case TYPE_BOOLEAN: {\n // A positional boolean emits the literal token \"true\" or \"false\". The\n // idiomatic styx2 representation is a two-literal choice (v1 used a\n // value_true/value_false Bool, which produces the same tokens).\n const node = alt(lit(\"true\"), lit(\"false\"));\n node.meta = meta;\n return node;\n }\n default: {\n if (FILE_TYPES.has(type)) {\n const node: Path = {\n kind: \"path\",\n attrs: { mediaTypes: [`workbench/${type}`] },\n meta,\n };\n return node;\n }\n this.error(`Unknown workbench type '${type}' for '${ctx}'`);\n return null;\n }\n }\n }\n\n // -- Params / outputs --\n\n /** Positional parameter -> required typed terminal. */\n private buildParam(param: unknown): Expr | null {\n if (!isObject(param)) {\n this.warn(\"Skipping non-object param\");\n return null;\n }\n const shortName = param.short_name;\n const type = param.type;\n if (!isString(shortName) || !isString(type)) {\n this.error(\"Workbench param missing 'short_name'/'type'\");\n return null;\n }\n const doc = this.docFrom(param.description);\n const meta: NodeMeta = { name: snakeCase(shortName), ...(doc && { doc }) };\n return this.buildTerminal(type, meta, shortName);\n }\n\n /**\n * Positional/option output -> a `str` terminal (the user-supplied output\n * filename) plus an `Output` declaration referencing it by name. Mirrors v1's\n * `_load_output`, which emits both a String param and an OutputParamReference.\n */\n private buildOutput(output: unknown): { node: Expr; output: Output } | null {\n if (!isObject(output)) {\n this.warn(\"Skipping non-object output\");\n return null;\n }\n const shortName = output.short_name;\n const type = output.type;\n if (!isString(shortName) || !isString(type)) {\n this.error(\"Workbench output missing 'short_name'/'type'\");\n return null;\n }\n if (!FILE_TYPES.has(type)) {\n this.error(`Workbench output '${shortName}' has non-file type '${type}'`);\n return null;\n }\n const name = snakeCase(shortName);\n const doc = this.docFrom(output.description);\n const node = str({ name, ...(doc && { doc }) });\n const out: Output = {\n name,\n ...(doc && { doc }),\n tokens: [{ kind: \"ref\", target: nodeRef(name) }],\n mediaTypes: [`workbench/${type}`],\n };\n return { node, output: out };\n }\n\n // -- Options --\n\n /**\n * An option/repeatable_option -> an optional (or repeated) switch group.\n *\n * With no sub-content it collapses to a bare flag (`opt(lit(switch))` ->\n * bool, `rep(lit(switch))` -> count). With content it is a struct sequence\n * `seq(lit(switch), ...)`; the struct's name + any outputs live on that\n * sequence's meta, the option's doc on the optional/repeat wrapper (matching\n * the Boutiques metadata-hoisting convention).\n */\n private buildOption(option: unknown, repeatable: boolean): Expr | null {\n if (!isObject(option)) {\n this.warn(\"Skipping non-object option\");\n return null;\n }\n const sw = option.option_switch;\n if (!isString(sw)) {\n this.error(\"Workbench option missing 'option_switch'\");\n return null;\n }\n const name = normalizeName(sw);\n const doc = this.docFrom(option.description);\n\n const inner: Expr[] = [lit(sw)];\n const outputs: Output[] = [];\n\n for (const p of asArray(option.params)) {\n const node = this.buildParam(p);\n if (node) inner.push(node);\n }\n for (const o of asArray(option.outputs)) {\n const built = this.buildOutput(o);\n if (built) {\n inner.push(built.node);\n outputs.push(built.output);\n }\n }\n for (const o of asArray(option.options)) {\n const node = this.buildOption(o, false);\n if (node) inner.push(node);\n }\n for (const o of asArray(option.repeatable_options)) {\n const node = this.buildOption(o, true);\n if (node) inner.push(node);\n }\n\n const wrapperMeta: NodeMeta = { ...(doc && { doc }) };\n\n if (inner.length === 1) {\n // Pure flag: no parameters or sub-options.\n const flagMeta: NodeMeta = { name, ...wrapperMeta };\n if (!repeatable) flagMeta.defaultValue = false;\n return repeatable ? rep(lit(sw), flagMeta) : opt(lit(sw), flagMeta);\n }\n\n const structSeq = seq(...inner);\n structSeq.meta = { name, ...(outputs.length > 0 && { outputs }) };\n return repeatable ? rep(structSeq, wrapperMeta) : opt(structSeq, wrapperMeta);\n }\n\n // -- Public API --\n\n parse(source: string, _filename?: string): ParseResult {\n this.reset();\n\n const cmd = this.parseJSON(source);\n if (!cmd) {\n return { expr: emptyExpr(), errors: this.errors, warnings: this.warnings };\n }\n\n const meta = this.buildAppMeta(cmd);\n if (!meta || !isString(cmd.command)) {\n return { expr: emptyExpr(), errors: this.errors, warnings: this.warnings };\n }\n\n const nodes: Expr[] = [lit(\"wb_command\"), lit(cmd.command)];\n const rootOutputs: Output[] = [];\n\n for (const p of asArray(cmd.params)) {\n const node = this.buildParam(p);\n if (node) nodes.push(node);\n }\n for (const o of asArray(cmd.outputs)) {\n const built = this.buildOutput(o);\n if (built) {\n nodes.push(built.node);\n rootOutputs.push(built.output);\n }\n }\n for (const o of asArray(cmd.options)) {\n const node = this.buildOption(o, false);\n if (node) nodes.push(node);\n }\n for (const o of asArray(cmd.repeatable_options)) {\n const node = this.buildOption(o, true);\n if (node) nodes.push(node);\n }\n\n const rootSeq = seq(...nodes);\n rootSeq.meta = { name: meta.id, ...(rootOutputs.length > 0 && { outputs: rootOutputs }) };\n\n return { meta, expr: rootSeq, errors: this.errors, warnings: this.warnings };\n }\n}\n\n// -- Helpers --\n\n/** Strip a leading dash from a switch/command and snake_case it. */\nfunction normalizeName(name: string): string {\n return snakeCase(name.replace(/^-+/, \"\"));\n}\n\n/** Coerce a possibly-missing list field to an array. */\nfunction asArray(x: unknown): unknown[] {\n return isArray(x) ? x : [];\n}\n\n/**\n * Pull a clean version out of workbench's noisy `version_info` lines\n * (e.g. \"Version: 2.1.0\"). Returns undefined if none is present.\n */\nfunction extractVersion(versionInfo: unknown): string | undefined {\n if (!isArray(versionInfo)) return undefined;\n for (const line of versionInfo) {\n if (isString(line)) {\n const m = /^Version:\\s*(.+)$/.exec(line.trim());\n if (m && m[1]) return m[1].trim();\n }\n }\n return undefined;\n}\n","export type FormatName = \"boutiques\" | \"argdump\" | \"workbench\" | \"mrtrix\";\n\n/**\n * Auto-detect the format of a JSON descriptor source string.\n * Returns null if the format cannot be determined.\n */\nexport function detectFormat(source: string): FormatName | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(source);\n } catch {\n return null;\n }\n\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n return null;\n }\n\n const obj = parsed as Record<string, unknown>;\n\n // Check $schema for argdump\n if (typeof obj.$schema === \"string\" && obj.$schema.includes(\"argdump\")) {\n return \"argdump\";\n }\n\n // Workbench: has a \"command\" switch plus \"short_description\"\n if (typeof obj.command === \"string\" && typeof obj.short_description === \"string\") {\n return \"workbench\";\n }\n\n // MRtrix C++ dump: a \"synopsis\" string plus \"option_groups\" and \"arguments\" arrays\n if (\n typeof obj.synopsis === \"string\" &&\n Array.isArray(obj.option_groups) &&\n Array.isArray(obj.arguments)\n ) {\n return \"mrtrix\";\n }\n\n // Boutiques: has \"command-line\" or \"inputs\" array\n if (\"command-line\" in obj || (Array.isArray(obj.inputs) && \"name\" in obj)) {\n return \"boutiques\";\n }\n\n // Argdump: has \"actions\" array + \"prog\"\n if (Array.isArray(obj.actions) && \"prog\" in obj) {\n return \"argdump\";\n }\n\n return null;\n}\n","import type { BoundType } from \"../bindings/index.js\";\nimport type { Expr } from \"../ir/index.js\";\n\n/**\n * Find a description from an IR node, traversing through wrapper nodes.\n *\n * The parser's `wrapNode` hoists doc metadata to the outermost wrapper node,\n * but the solver's simplify pass can collapse sequences, burying descriptions\n * deeper in the tree.\n *\n * This traversal is type-aware: it only enters sequences when the corresponding\n * BoundType is not a struct. Struct sequences have their own field collection\n * call, so entering them would steal nested struct children's descriptions.\n *\n * @param node - The IR node to search for a description.\n * @param fieldType - The BoundType of the field, used to determine traversal boundaries.\n */\nexport function findDoc(node: Expr, fieldType: BoundType): string | undefined {\n if (node.meta?.doc?.description) return node.meta.doc.description;\n switch (node.kind) {\n case \"optional\":\n return findDoc(node.attrs.node, fieldType.kind === \"optional\" ? fieldType.inner : fieldType);\n case \"repeat\":\n return findDoc(node.attrs.node, fieldType.kind === \"list\" ? fieldType.item : fieldType);\n case \"sequence\": {\n // Only traverse into sequences that were collapsed (non-struct field types).\n // Struct sequences have their own collectFieldInfo call for their children.\n if (fieldType.kind === \"struct\") return undefined;\n for (const child of node.attrs.nodes) {\n const doc = findDoc(child, fieldType);\n if (doc) return doc;\n }\n return undefined;\n }\n default:\n return undefined;\n }\n}\n","import type { Binding, BoundType } from \"../bindings/index.js\";\nimport type { Expr } from \"../ir/index.js\";\nimport type { CodegenContext } from \"../manifest/index.js\";\n\n/**\n * Resolve a struct child node to its field binding, handling collapsed sequences.\n *\n * When the solver's simplify pass collapses `seq(lit(\"--flag\"), terminal)` into\n * just the terminal, the binding ends up on the inner node while metadata (doc,\n * defaultValue) may remain on the outermost wrapper. This function recursively\n * descends through collapsed sequences to find the binding, tracking the outermost\n * node for metadata recovery.\n *\n * Uses type identity (`===`) to verify the binding matches the struct's field type,\n * preventing cross-nesting name collisions where an inner struct has a field with\n * the same name as the outer struct.\n */\nexport function resolveFieldBinding(\n node: Expr,\n ctx: CodegenContext,\n structType: Extract<BoundType, { kind: \"struct\" }>,\n outermost?: Expr,\n): { binding: Binding; wrapperNode: Expr } | undefined {\n const wrapper = outermost ?? node;\n const binding = ctx.resolve(node);\n if (\n binding &&\n binding.name in structType.fields &&\n binding.type === structType.fields[binding.name]\n ) {\n return { binding, wrapperNode: wrapper };\n }\n // Recurse into collapsed sequences to find the binding deeper\n if (node.kind === \"sequence\") {\n for (const inner of node.attrs.nodes) {\n const result = resolveFieldBinding(inner, ctx, structType, wrapper);\n if (result) return result;\n }\n }\n return undefined;\n}\n","import type { BoundType } from \"../bindings/index.js\";\nimport type { Expr } from \"../ir/index.js\";\nimport type { CodegenContext } from \"../manifest/index.js\";\nimport { resolveFieldBinding } from \"./resolve-field-binding.js\";\n\n/**\n * Find the sequence node whose child bindings match a struct type's fields.\n *\n * Traverses through optional, repeat, and alternative wrappers to find the\n * sequence that directly contains the struct's field bindings. This is necessary\n * because the solver may collapse `seq(lit(\"--flag\"), terminal)` into the terminal,\n * burying bindings deeper in the tree.\n *\n * Uses a two-phase check for sequences:\n * 1. Direct binding check (`ctx.resolve`) - matches when bindings are on immediate children\n * 2. Recursive binding check (`resolveFieldBinding`) - matches when solver collapsed\n * a seq(lit, terminal) and the binding is buried deeper\n *\n * Phase 1 is tried first to avoid falsely matching an outer sequence when an inner\n * sequence is the actual struct owner (e.g. `seq(lit(\"--flag\"), seq(field1, field2))`).\n */\nexport function findStructNode(\n node: Expr,\n ctx: CodegenContext,\n structType: Extract<BoundType, { kind: \"struct\" }>,\n): Extract<Expr, { kind: \"sequence\" }> | undefined {\n switch (node.kind) {\n case \"sequence\": {\n // Phase 1: Check if any direct child has a binding matching a struct field\n for (const child of node.attrs.nodes) {\n const binding = ctx.resolve(child);\n if (\n binding &&\n binding.name in structType.fields &&\n binding.type === structType.fields[binding.name]\n ) {\n return node;\n }\n }\n // Recurse into child nodes first (prefer deeper matches)\n for (const child of node.attrs.nodes) {\n const result = findStructNode(child, ctx, structType);\n if (result) return result;\n }\n // Phase 2: Check via resolveFieldBinding for collapsed sequences\n // where bindings are buried inside collapsed seq(lit, terminal)\n for (const child of node.attrs.nodes) {\n if (resolveFieldBinding(child, ctx, structType)) return node;\n }\n return undefined;\n }\n case \"optional\":\n return findStructNode(node.attrs.node, ctx, structType);\n case \"repeat\":\n return findStructNode(node.attrs.node, ctx, structType);\n case \"alternative\": {\n for (const alt of node.attrs.alts) {\n const result = findStructNode(alt, ctx, structType);\n if (result) return result;\n }\n return undefined;\n }\n default:\n return undefined;\n }\n}\n","import type { BoundType } from \"../bindings/index.js\";\nimport type { CodegenContext } from \"../manifest/index.js\";\nimport { findDoc } from \"./find-doc.js\";\nimport { findStructNode } from \"./find-struct-node.js\";\nimport { resolveFieldBinding } from \"./resolve-field-binding.js\";\n\n/**\n * Metadata extracted for each field of a struct type.\n *\n * `doc` is the field's description, recovered from wrapper nodes via `findDoc`.\n * `defaultValue` is pulled from the wrapper or binding node's metadata.\n */\nexport interface FieldInfo {\n doc?: string;\n defaultValue?: string | number | boolean;\n}\n\n/**\n * Collect field metadata (doc, defaultValue) for each field of a struct type.\n *\n * Walks the IR tree to find the sequence node containing the struct's fields,\n * then resolves each child to its field binding. Metadata is recovered from both\n * the wrapper node (where the parser hoists doc) and the binding node (where the\n * solver places the binding after sequence collapse).\n */\nexport function collectFieldInfo(\n ctx: CodegenContext,\n structType: Extract<BoundType, { kind: \"struct\" }>,\n): Map<string, FieldInfo> {\n const info = new Map<string, FieldInfo>();\n\n const structNode = findStructNode(ctx.expr, ctx, structType);\n if (!structNode) return info;\n\n for (const child of structNode.attrs.nodes) {\n const match = resolveFieldBinding(child, ctx, structType);\n if (!match) continue;\n const { binding, wrapperNode } = match;\n const fieldInfo: FieldInfo = {};\n const fieldType = structType.fields[binding.name]!;\n // Check wrapper node first (doc may be hoisted there), then binding node\n const doc = findDoc(wrapperNode, fieldType) ?? findDoc(binding.node, fieldType);\n if (doc) fieldInfo.doc = doc;\n const defaultValue = wrapperNode.meta?.defaultValue ?? binding.node.meta?.defaultValue;\n if (defaultValue !== undefined) fieldInfo.defaultValue = defaultValue;\n info.set(binding.name, fieldInfo);\n }\n\n return info;\n}\n","import type { Expr } from \"../ir/index.js\";\nimport type { GateAtom } from \"./resolved-output.js\";\nimport type { BoundType } from \"./types.js\";\n\nexport type BindingId = string;\n\n/**\n * One step in a binding's access path relative to top-level `params`.\n *\n * - `field`: descend into a named field of the enclosing struct scope. Renders\n * as `params.name` (TS) / `params[\"name\"]` (Python).\n * - `iter`: the access base resets to the per-element loop variable bound to\n * `binding` (a `repeat`-of-list). The renderer substitutes the active loop\n * variable at emit time (from the `iter` gate atom's loop, or the\n * arg-builder's local loop), so segments after an `iter` build off the\n * element rather than off `params`.\n *\n * There is deliberately no `variant` or `directValue` segment: complex-union\n * variant fields are plain `field` segments off the union's own path (the\n * `@type` discriminant lives in `GateAtom`, not the access path), and the\n * solver's wrapper collapses (`optional<scalar>`, scalar lists) are expressed\n * by a binding simply inheriting its parent wrapper's path.\n */\nexport type AccessSegment = { kind: \"field\"; name: string } | { kind: \"iter\"; binding: BindingId };\n\n/**\n * A binding's location relative to top-level `params`, as a structured segment\n * sequence. Computed once by the solver (`assignAccessPaths`) and rendered by\n * each backend's `renderAccess`, so the arg-builder and outputs emitter share\n * one source of truth instead of each re-deriving paths.\n */\nexport type AccessPath = AccessSegment[];\n\nexport interface Binding {\n id: BindingId;\n node: Expr;\n name: string;\n type: BoundType;\n /**\n * Wrapper layers on the path from the root to this binding, root-to-leaf.\n * Captures the optional/repeat/alternative ancestors as `present`/`iter`/\n * `variant` atoms. Backends nest wrappers in array order; \"is this binding\n * conditionally active?\" reduces to `gate.length > 0`.\n */\n gate: GateAtom[];\n /**\n * Access path relative to top-level `params`, assigned by the solver's\n * `assignAccessPaths` pass after types settle. Backends render it via\n * `renderAccess` rather than re-walking the IR to recompute where this\n * binding lives.\n */\n access: AccessPath;\n}\n\nexport type BindingRegistry = Map<BindingId, Binding>;\n\nexport type OutputDiagnosticLevel = \"error\" | \"warning\";\n\nexport interface OutputDiagnostic {\n output: string;\n message: string;\n level: OutputDiagnosticLevel;\n}\n\nexport interface OutputValidationResult {\n errors: OutputDiagnostic[];\n warnings: OutputDiagnostic[];\n}\n\nexport interface SolveResult {\n bindings: BindingRegistry;\n resolve: (node: Expr) => Binding | undefined;\n}\n\nexport function createRegistry(): BindingRegistry {\n return new Map();\n}\n","import type { BindingRegistry } from \"./binding.js\";\nimport type { GateAtom, ResolvedOutput } from \"./resolved-output.js\";\n\n/**\n * The unified wrapper sequence for a single output: the scope's gate, then for\n * each ref token both the ref binding's path-gate and (if its type is itself\n * \"thick\" - nullable or iterable) a self-atom on the ref binding. Atoms are\n * deduped while preserving first-occurrence order.\n *\n * The self-atom encodes facts derivable from `Binding.type` alone:\n * - `optional`, `bool`, `count` -> `present(binding)` (value may be absent)\n * - `list` -> `iter(binding)` (iterate per element)\n *\n * `scopeGate` is the gate of the scope's struct binding (often `[]` at the\n * root). Backends nest wrappers in array order; the atom kind decides whether\n * it renders as a guard (`present` / `variant`) or a loop (`iter`).\n */\nexport function outputGate(\n scopeGate: GateAtom[],\n output: ResolvedOutput,\n bindings: BindingRegistry,\n): GateAtom[] {\n const seen = new Set<string>();\n const result: GateAtom[] = [];\n const push = (atom: GateAtom): void => {\n const key = atomKey(atom);\n if (seen.has(key)) return;\n seen.add(key);\n result.push(atom);\n };\n for (const atom of scopeGate) push(atom);\n for (const token of output.tokens) {\n if (token.kind !== \"ref\") continue;\n const refBinding = bindings.get(token.binding);\n if (!refBinding) continue;\n for (const atom of refBinding.gate) push(atom);\n const kind = refBinding.type.kind;\n if (kind === \"optional\" || kind === \"bool\" || kind === \"count\") {\n push({ kind: \"present\", binding: refBinding.id });\n } else if (kind === \"list\") {\n push({ kind: \"iter\", binding: refBinding.id });\n }\n }\n return result;\n}\n\nexport function atomKey(atom: GateAtom): string {\n if (atom.kind === \"variant\") return `v:${atom.binding}:${atom.variant}`;\n return `${atom.kind[0]}:${atom.binding}`;\n}\n","import type { Expr } from \"../ir/node.js\";\nimport type { AccessPath, BindingRegistry, OutputValidationResult } from \"./binding.js\";\nimport type { SolveResult } from \"./index.js\";\nimport { outputGate } from \"./output-gate.js\";\nimport type { GateAtom, OutputScope, ResolvedOutput, ResolvedToken } from \"./resolved-output.js\";\nimport type { BoundType } from \"./types.js\";\n\nexport interface FormatExtras {\n scopes?: OutputScope[];\n diagnostics?: OutputValidationResult;\n}\n\nexport function formatSolveResult(result: SolveResult, expr: Expr, extras?: FormatExtras): string {\n const binding = result.resolve(expr);\n const rootLine = binding ? `${binding.name}: ${formatType(binding.type)}` : \"(no binding)\";\n\n const sections = [rootLine];\n\n const gatedBindings = [...result.bindings.values()].filter(\n (b) => b.gate.length > 0 && b !== binding,\n );\n if (gatedBindings.length > 0) {\n sections.push(\"\", \"gates:\");\n for (const b of gatedBindings) {\n sections.push(` ${b.name}: ${formatGate(b.gate, result.bindings)}`);\n }\n }\n\n const accessBindings = [...result.bindings.values()].filter((b) => b.access.length > 0);\n if (accessBindings.length > 0) {\n sections.push(\"\", \"access:\");\n for (const b of accessBindings) {\n sections.push(` ${b.name}: ${formatAccess(b.access, result.bindings)}`);\n }\n }\n\n if (extras?.scopes?.length) {\n sections.push(\"\", \"outputs:\");\n for (const scope of extras.scopes) {\n const scopeBinding = result.bindings.get(scope.scope);\n const header = scopeBinding ? ` on ${scopeBinding.name}:` : \" on <unbound>:\";\n sections.push(header);\n const scopeGate = scopeBinding?.gate ?? [];\n for (const out of scope.outputs) {\n sections.push(formatResolvedOutput(out, scopeGate, result.bindings, 2));\n }\n }\n }\n\n const diags = [...(extras?.diagnostics?.errors ?? []), ...(extras?.diagnostics?.warnings ?? [])];\n if (diags.length > 0) {\n sections.push(\"\", \"diagnostics:\");\n for (const d of diags) sections.push(` [${d.level}] ${d.output}: ${d.message}`);\n }\n\n return sections.join(\"\\n\");\n}\n\nfunction formatResolvedOutput(\n out: ResolvedOutput,\n scopeGate: GateAtom[],\n bindings: BindingRegistry,\n indent: number,\n): string {\n const pad = \" \".repeat(indent);\n const media = out.mediaTypes?.length ? ` (${out.mediaTypes.join(\", \")})` : \"\";\n const tokens = out.tokens.map((t) => formatResolvedToken(t, bindings)).join(\" + \") || `\"\"`;\n const gateAtoms = outputGate(scopeGate, out, bindings);\n const optional = gateAtoms.some((a) => a.kind === \"present\" || a.kind === \"variant\");\n const optTag = optional ? \" [optional]\" : \"\";\n const gate =\n gateAtoms.length > 0\n ? ` when (${gateAtoms.map((a) => formatGateAtom(a, bindings)).join(\" AND \")})`\n : \"\";\n return `${pad}${out.name}${optTag}${media}: ${tokens}${gate}`;\n}\n\nfunction bindingName(bindings: BindingRegistry, id: string): string {\n return bindings.get(id)?.name ?? `<${id}>`;\n}\n\nexport function formatResolvedToken(token: ResolvedToken, bindings: BindingRegistry): string {\n if (token.kind === \"literal\") return JSON.stringify(token.value);\n const flags = [\n token.stripExtensions?.length && `strip=${JSON.stringify(token.stripExtensions)}`,\n token.fallback !== undefined && `fallback=${JSON.stringify(token.fallback)}`,\n ].filter(Boolean);\n const suffix = flags.length > 0 ? ` {${flags.join(\", \")}}` : \"\";\n return `ref(${bindingName(bindings, token.binding)})${suffix}`;\n}\n\nexport function formatGateAtom(atom: GateAtom, bindings: BindingRegistry): string {\n switch (atom.kind) {\n case \"present\":\n return `present(${bindingName(bindings, atom.binding)})`;\n case \"variant\":\n return `${bindingName(bindings, atom.binding)}=${atom.variant}`;\n case \"iter\":\n return `iter(${bindingName(bindings, atom.binding)})`;\n }\n}\n\nexport function formatGate(gate: GateAtom[], bindings: BindingRegistry): string {\n if (gate.length === 0) return \"(unconditional)\";\n return gate.map((a) => formatGateAtom(a, bindings)).join(\" / \");\n}\n\n/**\n * Render a binding's access path for debugging, e.g. `params.sub.x` or\n * `<iter:things>.file`. An `iter` segment shows the repeat it loops, since the\n * concrete loop variable is a backend emit-time detail.\n */\nexport function formatAccess(access: AccessPath, bindings: BindingRegistry): string {\n let out = \"params\";\n for (const seg of access) {\n out =\n seg.kind === \"field\" ? `${out}.${seg.name}` : `<iter:${bindingName(bindings, seg.binding)}>`;\n }\n return out;\n}\n\nfunction formatType(type: BoundType, indent = 0): string {\n const pad = \" \".repeat(indent);\n const inner = (t: BoundType) => formatType(t, indent + 1);\n\n switch (type.kind) {\n case \"scalar\":\n return type.scalar;\n case \"bool\":\n return \"bool\";\n case \"count\":\n return \"count\";\n case \"literal\":\n return typeof type.value === \"number\" ? String(type.value) : `\"${type.value}\"`;\n case \"optional\":\n return `optional<${inner(type.inner)}>`;\n case \"list\":\n return `list<${inner(type.item)}>`;\n\n case \"struct\": {\n const entries = Object.entries(type.fields);\n if (entries.length === 0) return \"struct {}\";\n if (entries.length === 1) {\n const [name, t] = entries[0]!;\n return `struct { ${name}: ${formatType(t)} }`;\n }\n const fields = entries.map(([name, t]) => `${pad} ${name}: ${inner(t)}`).join(\"\\n\");\n return `struct {\\n${fields}\\n${pad}}`;\n }\n\n case \"union\": {\n if (type.variants.length === 0) return \"union {}\";\n\n // If all variants are literals, display inline\n const allLiterals = type.variants.every((v) => v.type.kind === \"literal\");\n if (allLiterals) {\n return type.variants\n .map((v) =>\n v.type.kind === \"literal\"\n ? typeof v.type.value === \"number\"\n ? String(v.type.value)\n : `\"${v.type.value}\"`\n : \"?\",\n )\n .join(\" | \");\n }\n\n // Otherwise multi-line union\n const variants = type.variants.map((v) => `${pad} | ${v.name}: ${inner(v.type)}`).join(\"\\n\");\n return `union {\\n${variants}\\n${pad}}`;\n }\n\n default:\n return ((_x: never) => \"unknown\")(type);\n }\n}\n","import type {\n BindingRegistry,\n GateAtom,\n OutputScope,\n ResolvedOutput,\n ResolvedToken,\n} from \"../bindings/index.js\";\nimport { outputGate } from \"../bindings/index.js\";\n\n// Re-export the core helper so backends have a single entry point.\nexport { outputGate };\n\n/**\n * Compact consecutive literal tokens. Backends that emit string concatenation\n * benefit from a shorter token stream; backends that template each token\n * individually can ignore this and use `output.tokens` directly.\n */\nexport function compactTokens(tokens: ResolvedToken[]): ResolvedToken[] {\n const out: ResolvedToken[] = [];\n for (const tok of tokens) {\n const last = out[out.length - 1];\n if (tok.kind === \"literal\" && last && last.kind === \"literal\") {\n out[out.length - 1] = { kind: \"literal\", value: last.value + tok.value };\n } else {\n out.push(tok);\n }\n }\n return out;\n}\n\n/**\n * One output ready for codegen. `gate` is the wrapper sequence (outermost\n * first); the backend renders each atom as the appropriate scope-introducing\n * statement, then emits the path expression inside the innermost layer.\n */\nexport interface OutputEmitPlan {\n name: string;\n gate: GateAtom[];\n tokens: ResolvedToken[];\n resolved: ResolvedOutput;\n}\n\nexport function planOutput(\n scopeGate: GateAtom[],\n output: ResolvedOutput,\n bindings: BindingRegistry,\n): OutputEmitPlan {\n return {\n name: output.name,\n gate: outputGate(scopeGate, output, bindings),\n tokens: compactTokens(output.tokens),\n resolved: output,\n };\n}\n\n/**\n * Does the output have any conditional wrapper? Equivalent to \"is at least one\n * atom a `present` or `variant`?\". `iter` alone means the output emits a list\n * and is not conditionally absent.\n */\nexport function isGated(plan: OutputEmitPlan): boolean {\n return plan.gate.some((a) => a.kind === \"present\" || a.kind === \"variant\");\n}\n\n/** Does the output iterate (emit zero-or-more values)? */\nexport function isIterated(plan: OutputEmitPlan): boolean {\n return plan.gate.some((a) => a.kind === \"iter\");\n}\n\n/**\n * Convenience for backends emitting all outputs of a scope at once. The caller\n * provides the scope's gate (typically `bindings.get(scope.scope)?.gate ?? []`).\n */\nexport function planScope(\n scope: OutputScope,\n scopeGate: GateAtom[],\n bindings: BindingRegistry,\n): OutputEmitPlan[] {\n return scope.outputs.map((output) => planOutput(scopeGate, output, bindings));\n}\n","/** Symbol collision avoidance for code generation. */\nexport class Scope {\n private readonly reserved: ReadonlySet<string>;\n private readonly used: Set<string>;\n private readonly parent?: Scope;\n\n constructor(reserved: Iterable<string> = [], parent?: Scope) {\n this.reserved = new Set(reserved);\n this.used = new Set();\n this.parent = parent;\n }\n\n /** Check if a symbol is already taken (in this scope or any parent). */\n has(symbol: string): boolean {\n return (\n this.reserved.has(symbol) || this.used.has(symbol) || (this.parent?.has(symbol) ?? false)\n );\n }\n\n /**\n * Add a symbol, appending a numeric suffix to avoid collisions. Returns the\n * safe name.\n *\n * When a `recase` transform is given, a disambiguated candidate is routed back\n * through it so the suffix is absorbed into the identifier's casing - e.g.\n * `pascalCase` folds `Config_2` into `Config2` - rather than leaving a\n * mixed-case `Config_2`. Uniqueness is always checked on the final emitted\n * form, so two hints that case-collide still get distinct names. Defaults to\n * identity (the bare `<name>_<n>` suffix) for callers that don't case-normalize.\n */\n add(candidate: string, recase: (s: string) => string = (s) => s): string {\n if (!this.has(candidate)) {\n this.used.add(candidate);\n return candidate;\n }\n let suffix = 2;\n let safe = recase(`${candidate}_${suffix}`);\n while (this.has(safe)) {\n suffix++;\n safe = recase(`${candidate}_${suffix}`);\n }\n this.used.add(safe);\n return safe;\n }\n\n /** Create a child scope that inherits this scope's restrictions. */\n child(reserved: Iterable<string> = []): Scope {\n return new Scope(reserved, this);\n }\n}\n","import type {\n Binding,\n BindingId,\n BoundType,\n BoundVariant,\n GateAtom,\n OutputScope,\n ResolvedOutput,\n} from \"../../bindings/index.js\";\nimport type { Expr, ScalarKind } from \"../../ir/index.js\";\nimport type { AppMeta } from \"../../ir/meta.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport type { Backend, EmittedApp, EmitWarning } from \"../backend.js\";\nimport { collectFieldInfo } from \"../collect-field-info.js\";\nimport { findDoc } from \"../find-doc.js\";\nimport { findStructNode } from \"../find-struct-node.js\";\nimport { outputGate } from \"../resolve-output-tokens.js\";\nimport { resolveFieldBinding } from \"../resolve-field-binding.js\";\nimport { Scope } from \"../scope.js\";\nimport { screamingSnakeCase } from \"../string-case.js\";\n\n// Boutiques descriptor types (output format)\n\ninterface BtDescriptor {\n name?: string;\n id?: string;\n description?: string;\n \"schema-version\"?: string;\n \"tool-version\"?: string;\n author?: string;\n url?: string;\n \"container-image\"?: { image: string; type?: string };\n \"command-line\"?: string;\n inputs?: BtInput[];\n \"stdout-output\"?: { id: string; name?: string; description?: string };\n \"stderr-output\"?: { id: string; name?: string; description?: string };\n \"output-files\"?: BtOutputFile[];\n}\n\ninterface BtOutputFile {\n id: string;\n name?: string;\n description?: string;\n \"path-template\": string;\n optional?: boolean;\n list?: boolean;\n \"path-template-stripped-extensions\"?: string[];\n}\n\ninterface BtInput {\n id: string;\n name?: string;\n description?: string;\n type: string | BtDescriptor | BtDescriptor[];\n \"value-key\": string;\n optional?: boolean;\n list?: boolean;\n \"list-separator\"?: string;\n \"min-list-entries\"?: number;\n \"max-list-entries\"?: number;\n \"command-line-flag\"?: string;\n \"command-line-flag-separator\"?: string;\n \"value-choices\"?: (string | number)[];\n \"default-value\"?: string | number | boolean;\n minimum?: number;\n maximum?: number;\n integer?: boolean;\n \"resolve-parent\"?: boolean;\n mutable?: boolean;\n}\n\n// Wrapper peeling result\n\ninterface PeeledInput {\n isOptional: boolean;\n isList: boolean;\n listSeparator?: string;\n minListEntries?: number;\n maxListEntries?: number;\n flag?: string;\n flagSeparator?: string;\n}\n\nclass BoutiquesEmitter {\n private warnings: EmitWarning[] = [];\n // Scope binding id -> outputs declared on that struct. The solver forces a\n // binding on every output-carrying sequence, so this is a one-liner.\n private outputsByScope = new Map<BindingId, OutputScope>();\n\n constructor(private ctx: CodegenContext) {\n for (const scope of ctx.outputScopes) this.outputsByScope.set(scope.scope, scope);\n }\n\n private warn(message: string): void {\n this.warnings.push({ message });\n }\n\n emit(): { descriptor: BtDescriptor; warnings: EmitWarning[] } {\n const descriptor = this.buildRootDescriptor();\n return { descriptor, warnings: this.warnings };\n }\n\n private buildRootDescriptor(): BtDescriptor {\n const bt: BtDescriptor = { \"schema-version\": \"0.5+styx\" };\n\n // Map AppMeta to root descriptor fields\n const app = this.ctx.app;\n if (app) {\n this.applyAppMeta(bt, app);\n }\n\n // Resolve root binding\n const rootBinding = this.ctx.resolve(this.ctx.expr);\n if (!rootBinding) {\n // No root binding - the solver collapsed single-field sequences.\n // Walk the expression tree directly to synthesize the descriptor.\n this.buildFromUnboundSequence(bt, this.ctx.expr);\n return bt;\n }\n\n this.buildDescriptorBody(bt, rootBinding, this.ctx.expr);\n return bt;\n }\n\n private applyAppMeta(bt: BtDescriptor, app: AppMeta): void {\n // Boutiques requires `name` at root and disallows `id` there.\n const rootName = app.doc?.title ?? app.id;\n if (rootName) bt.name = rootName;\n if (app.doc?.description) bt.description = app.doc.description;\n if (app.version) bt[\"tool-version\"] = app.version;\n if (app.doc?.authors?.[0]) bt.author = app.doc.authors[0];\n if (app.doc?.urls?.[0]) bt.url = app.doc.urls[0];\n if (app.container) {\n bt[\"container-image\"] = {\n image: app.container.image,\n ...(app.container.type && { type: app.container.type }),\n };\n }\n if (app.stdout) {\n bt[\"stdout-output\"] = {\n id: app.stdout.name,\n ...(app.stdout.doc?.title && { name: app.stdout.doc.title }),\n ...(app.stdout.doc?.description && { description: app.stdout.doc.description }),\n };\n }\n if (app.stderr) {\n bt[\"stderr-output\"] = {\n id: app.stderr.name,\n ...(app.stderr.doc?.title && { name: app.stderr.doc.title }),\n ...(app.stderr.doc?.description && { description: app.stderr.doc.description }),\n };\n }\n }\n\n private buildDescriptorBody(bt: BtDescriptor, binding: Binding, expr: Expr): void {\n const type = binding.type;\n\n if (type.kind === \"struct\") {\n this.buildFromStruct(bt, type, expr);\n } else {\n // Root is not a struct (e.g. simplified to a literal) - just build command line\n bt[\"command-line\"] = this.buildCommandLineFromExpr(expr);\n }\n }\n\n // Handle sequences where the solver collapsed single-field structs.\n // Walk children, emitting literals as command-line text and bound nodes as inputs.\n private buildFromUnboundSequence(bt: BtDescriptor, expr: Expr): void {\n if (expr.kind !== \"sequence\") {\n bt[\"command-line\"] = this.buildCommandLineFromExpr(expr);\n return;\n }\n\n const scope = new Scope();\n const idScope = new Scope();\n const commandParts: string[] = [];\n const inputs: BtInput[] = [];\n const valueKeyByBinding = new Map<BindingId, string>();\n\n for (const child of expr.attrs.nodes) {\n if (child.kind === \"literal\") {\n commandParts.push(child.attrs.str);\n continue;\n }\n\n const binding = this.ctx.resolve(child);\n if (binding) {\n // Direct binding on this child\n const id = idScope.add(this.sanitizeId(binding.name));\n const valueKey = scope.add(screamingSnakeCase(id));\n const valueKeyStr = `[${valueKey}]`;\n valueKeyByBinding.set(binding.id, valueKeyStr);\n const peeled = this.peelNode(child, binding.type);\n if (this.isBool(binding.type) && !peeled.flag) {\n const flagStr = this.extractBoolFlag(child);\n if (flagStr) peeled.flag = flagStr;\n }\n const input = this.buildInputFromBinding(binding, id, valueKeyStr, peeled, child);\n commandParts.push(valueKeyStr);\n inputs.push(input);\n } else {\n // No direct binding - might be a nested sequence (subcommand).\n // Try to find bindings deeper inside.\n const deepBinding = this.findDeepBinding(child);\n if (deepBinding) {\n const rawName = child.meta?.name ?? deepBinding.name;\n const id = idScope.add(this.sanitizeId(rawName));\n const valueKey = scope.add(screamingSnakeCase(id));\n const valueKeyStr = `[${valueKey}]`;\n const subBt = this.buildSubCommandFromUnbound(child);\n const input: BtInput = {\n id,\n type: subBt,\n \"value-key\": valueKeyStr,\n };\n this.finalizeInput(input);\n commandParts.push(valueKeyStr);\n inputs.push(input);\n } else {\n commandParts.push(this.buildCommandLineFromExpr(child));\n }\n }\n }\n\n bt[\"command-line\"] = commandParts.join(\" \");\n bt.inputs = inputs;\n this.emitOutputFiles(bt, expr, valueKeyByBinding, idScope);\n }\n\n // Build a subcommand descriptor from an unbound sequence node\n private buildSubCommandFromUnbound(node: Expr): BtDescriptor {\n const bt: BtDescriptor = {};\n if (node.meta?.name) {\n bt.name = node.meta.name;\n bt.id = this.sanitizeId(node.meta.name);\n }\n this.buildFromUnboundSequence(bt, node);\n return bt;\n }\n\n // Find any binding in a subtree\n private findDeepBinding(node: Expr): Binding | undefined {\n const binding = this.ctx.resolve(node);\n if (binding) return binding;\n\n switch (node.kind) {\n case \"sequence\":\n for (const child of node.attrs.nodes) {\n const found = this.findDeepBinding(child);\n if (found) return found;\n }\n return undefined;\n case \"optional\":\n return this.findDeepBinding(node.attrs.node);\n case \"repeat\":\n return this.findDeepBinding(node.attrs.node);\n case \"alternative\":\n for (const alt of node.attrs.alts) {\n const found = this.findDeepBinding(alt);\n if (found) return found;\n }\n return undefined;\n default:\n return undefined;\n }\n }\n\n // Build an input from a binding directly (without struct context)\n private buildInputFromBinding(\n binding: Binding,\n id: string,\n valueKey: string,\n peeled: PeeledInput,\n wrapperNode: Expr,\n ): BtInput {\n const innerType = this.unwrapType(binding.type);\n const mapped = this.mapType(innerType, wrapperNode);\n\n const input: BtInput = {\n id,\n type: mapped.type,\n \"value-key\": valueKey,\n };\n\n if (binding.node.meta?.doc?.title) input.name = binding.node.meta.doc.title;\n if (binding.node.meta?.doc?.description) input.description = binding.node.meta.doc.description;\n\n if (peeled.isOptional || mapped.optional) input.optional = true;\n const isList = peeled.isList || mapped.list === true;\n if (isList) {\n input.list = true;\n const listSep = peeled.listSeparator ?? mapped.listSeparator;\n const minEntries = peeled.minListEntries ?? mapped.minListEntries;\n if (listSep !== undefined) input[\"list-separator\"] = listSep;\n if (minEntries !== undefined) input[\"min-list-entries\"] = minEntries;\n if (peeled.maxListEntries !== undefined) input[\"max-list-entries\"] = peeled.maxListEntries;\n }\n if (peeled.flag) {\n input[\"command-line-flag\"] = peeled.flag;\n if (peeled.flagSeparator) input[\"command-line-flag-separator\"] = peeled.flagSeparator;\n }\n if (mapped.integer) input.integer = true;\n if (mapped.minimum !== undefined) input.minimum = mapped.minimum;\n if (mapped.maximum !== undefined) input.maximum = mapped.maximum;\n if (mapped.valueChoices) input[\"value-choices\"] = mapped.valueChoices;\n if (mapped.resolveParent) input[\"resolve-parent\"] = true;\n if (mapped.mutable) input[\"mutable\"] = true;\n\n if (innerType.kind !== \"count\") {\n const defaultValue = binding.node.meta?.defaultValue;\n if (defaultValue !== undefined) input[\"default-value\"] = defaultValue;\n }\n\n this.finalizeInput(input);\n return input;\n }\n\n // Boutiques' default-value substitutes when the user omits the input;\n // argparse's default is the parser's internal fallback, not a CLI value\n // to materialize. Surface it in the description instead.\n private mergeDefaultIntoDescription(input: BtInput): void {\n const dv = input[\"default-value\"];\n if (dv === undefined) return;\n delete input[\"default-value\"];\n if (input.type === \"Flag\") return;\n const formatted = typeof dv === \"string\" ? JSON.stringify(dv) : String(dv);\n const suffix = `Default: ${formatted}`;\n const desc = input.description;\n input.description = desc ? `${desc.replace(/\\s+$/, \"\")} (${suffix})` : suffix;\n }\n\n private buildFromStruct(\n bt: BtDescriptor,\n structType: Extract<BoundType, { kind: \"struct\" }>,\n expr: Expr,\n ): void {\n const structNode = findStructNode(expr, this.ctx, structType);\n if (!structNode) {\n bt[\"command-line\"] = \"\";\n bt.inputs = [];\n return;\n }\n\n // `findStructNode` may descend below `expr` to the sequence whose direct\n // children are the struct's fields (e.g. when a single-field inner sequence\n // was preserved by flatten to keep its doc, then collapsed). Any command\n // literals on the path from `expr` down to that node would otherwise be\n // dropped - including the tool's own command name. Recover them as a prefix.\n const prefixLiterals =\n structNode === expr ? [] : (commandPrefixLiterals(expr, structNode) ?? []);\n\n const scope = new Scope();\n const idScope = new Scope();\n const commandParts: string[] = [...prefixLiterals];\n const inputs: BtInput[] = [];\n const valueKeyByBinding = new Map<BindingId, string>();\n const fieldInfo = collectFieldInfo(this.ctx, structType);\n\n for (const child of structNode.attrs.nodes) {\n // Literal nodes -> command-line text\n if (child.kind === \"literal\") {\n commandParts.push(child.attrs.str);\n continue;\n }\n\n // Try to resolve to a field binding\n const match = resolveFieldBinding(child, this.ctx, structType);\n if (!match) {\n // Unbound non-literal node - no command-line text we can emit.\n continue;\n }\n\n const { binding, wrapperNode } = match;\n const fieldType = structType.fields[binding.name];\n if (!fieldType) continue;\n\n // Skip literal fields (union discriminators, not user-facing)\n if (fieldType.kind === \"literal\") continue;\n\n const id = idScope.add(this.sanitizeId(binding.name));\n const valueKey = scope.add(screamingSnakeCase(id));\n const valueKeyStr = `[${valueKey}]`;\n valueKeyByBinding.set(binding.id, valueKeyStr);\n\n // Peel wrapper layers from the IR node\n const peeled = this.peelNode(wrapperNode, fieldType);\n\n // Bool IR pattern: optional(literal(\"-v\")) - the literal IS the flag.\n if (this.isBool(fieldType) && !peeled.flag) {\n const flagStr = this.extractBoolFlag(wrapperNode);\n if (flagStr) peeled.flag = flagStr;\n }\n\n const input = this.buildInput(\n binding,\n id,\n fieldType,\n valueKeyStr,\n peeled,\n fieldInfo,\n wrapperNode,\n );\n\n // Add flag to command line if present, then value-key\n if (peeled.flag) {\n if (\n fieldType.kind === \"bool\" ||\n (fieldType.kind === \"optional\" && this.isBool(fieldType))\n ) {\n // Bool flags: the value-key IS the flag\n commandParts.push(valueKeyStr);\n } else {\n // Value flags: flag then value-key as separate args\n commandParts.push(valueKeyStr);\n }\n } else {\n commandParts.push(valueKeyStr);\n }\n\n inputs.push(input);\n }\n\n bt[\"command-line\"] = commandParts.join(\" \");\n bt.inputs = inputs;\n this.emitOutputFiles(bt, expr, valueKeyByBinding, idScope);\n }\n\n // Emit `output-files` entries declared on this struct binding. `optional`\n // and `list` are derived from the unified gate (scope binding's gate plus\n // each ref's binding gate plus type-derived atoms). Refs that point to\n // bindings outside the scope are dropped with a warning; output ids share\n // the input id scope so they cannot collide.\n private emitOutputFiles(\n bt: BtDescriptor,\n scopeNode: Expr,\n valueKeys: Map<BindingId, string>,\n idScope: Scope,\n ): void {\n const scopeBinding = this.ctx.resolve(scopeNode);\n if (!scopeBinding) return;\n const scope = this.outputsByScope.get(scopeBinding.id);\n if (!scope || scope.outputs.length === 0) return;\n\n const files: BtOutputFile[] = [];\n for (const output of scope.outputs) {\n const file = this.buildOutputFile(scopeBinding.gate, output, valueKeys, idScope);\n if (file) files.push(file);\n }\n if (files.length > 0) bt[\"output-files\"] = files;\n }\n\n private buildOutputFile(\n scopeGate: GateAtom[],\n output: ResolvedOutput,\n valueKeys: Map<BindingId, string>,\n idScope: Scope,\n ): BtOutputFile | null {\n let template = \"\";\n let stripExtensions: string[] | undefined;\n let droppedRef = false;\n\n for (const token of output.tokens) {\n if (token.kind === \"literal\") {\n template += token.value;\n continue;\n }\n const key = valueKeys.get(token.binding);\n if (!key) {\n const bindingName = this.ctx.bindings.get(token.binding)?.name ?? \"<unknown>\";\n this.warn(\n `Output '${output.name}' references binding '${bindingName}' that is not in the same descriptor scope`,\n );\n droppedRef = true;\n continue;\n }\n template += key;\n // The parser applies the same stripped-extensions list to every ref in\n // an output, so taking the first non-empty list round-trips cleanly.\n if (token.stripExtensions && !stripExtensions) stripExtensions = token.stripExtensions;\n }\n\n // If we couldn't resolve any refs and the template is empty, drop the\n // output entirely. (A literal-only template stays.)\n if (droppedRef && template === \"\") return null;\n\n const gate = outputGate(scopeGate, output, this.ctx.bindings);\n const isOptional = gate.some((a) => a.kind === \"present\" || a.kind === \"variant\");\n const isList = gate.some((a) => a.kind === \"iter\");\n\n const id = idScope.add(this.sanitizeId(output.name));\n const file: BtOutputFile = { id, \"path-template\": template };\n if (output.doc?.title) file.name = output.doc.title;\n if (output.doc?.description) file.description = output.doc.description;\n if (isOptional) file.optional = true;\n if (isList) file.list = true;\n if (stripExtensions) file[\"path-template-stripped-extensions\"] = stripExtensions;\n return file;\n }\n\n // Extract flag literal from a bool IR pattern: optional(literal(\"-v\"))\n private extractBoolFlag(node: Expr): string | undefined {\n if (node.kind === \"optional\") return this.extractBoolFlag(node.attrs.node);\n if (node.kind === \"literal\") return node.attrs.str;\n return undefined;\n }\n\n private buildInput(\n binding: Binding,\n id: string,\n fieldType: BoundType,\n valueKey: string,\n peeled: PeeledInput,\n fieldInfo: Map<string, { doc?: string; defaultValue?: string | number | boolean }>,\n wrapperNode: Expr,\n ): BtInput {\n const info = fieldInfo.get(binding.name);\n const innerType = this.unwrapType(fieldType);\n const mapped = this.mapType(innerType, wrapperNode);\n\n const input: BtInput = {\n id,\n type: mapped.type,\n \"value-key\": valueKey,\n };\n\n // Name (short label) - only from explicit title, not description\n const title = binding.node.meta?.doc?.title;\n if (title) input.name = title;\n\n // Description (longer help text)\n const description =\n info?.doc ?? binding.node.meta?.doc?.description ?? findDoc(binding.node, fieldType);\n if (description) input.description = description;\n\n if (peeled.isOptional || mapped.optional) input.optional = true;\n\n const isList = peeled.isList || mapped.list === true;\n if (isList) {\n input.list = true;\n const listSep = peeled.listSeparator ?? mapped.listSeparator;\n const minEntries = peeled.minListEntries ?? mapped.minListEntries;\n if (listSep !== undefined) input[\"list-separator\"] = listSep;\n if (minEntries !== undefined) input[\"min-list-entries\"] = minEntries;\n if (peeled.maxListEntries !== undefined) input[\"max-list-entries\"] = peeled.maxListEntries;\n }\n\n // Flag\n if (peeled.flag) {\n input[\"command-line-flag\"] = peeled.flag;\n if (peeled.flagSeparator) input[\"command-line-flag-separator\"] = peeled.flagSeparator;\n }\n\n // Constraints from mapped type\n if (mapped.integer) input.integer = true;\n if (mapped.minimum !== undefined) input.minimum = mapped.minimum;\n if (mapped.maximum !== undefined) input.maximum = mapped.maximum;\n if (mapped.valueChoices) input[\"value-choices\"] = mapped.valueChoices;\n if (mapped.resolveParent) input[\"resolve-parent\"] = true;\n if (mapped.mutable) input[\"mutable\"] = true;\n\n // count's \"default\" is implicit via min-list-entries:0; skip emitting it.\n if (innerType.kind !== \"count\") {\n const defaultValue = info?.defaultValue ?? binding.node.meta?.defaultValue;\n if (defaultValue !== undefined) input[\"default-value\"] = defaultValue;\n }\n\n this.finalizeInput(input);\n return input;\n }\n\n // Normalize an input so the descriptor is valid even when upstream types\n // are dynamic (functools.partial, custom action classes) and the parser\n // had to fall back to String.\n private finalizeInput(input: BtInput): void {\n if (input.name === undefined) input.name = input.id;\n\n // A String with a bool default and no choices is really a Flag.\n if (\n input.type === \"String\" &&\n typeof input[\"default-value\"] === \"boolean\" &&\n input[\"value-choices\"] === undefined\n ) {\n input.type = \"Flag\";\n }\n\n if (input.type === \"Flag\") {\n delete input[\"default-value\"];\n delete input[\"value-choices\"];\n delete input.list;\n delete input[\"list-separator\"];\n delete input[\"min-list-entries\"];\n delete input[\"max-list-entries\"];\n } else if (input.type === \"String\") {\n const dv = input[\"default-value\"];\n if (dv !== undefined && typeof dv !== \"string\") {\n input[\"default-value\"] = String(dv);\n }\n const choices = input[\"value-choices\"];\n if (Array.isArray(choices)) {\n input[\"value-choices\"] = choices.map((c) => (typeof c === \"string\" ? c : String(c)));\n }\n } else if (input.type === \"Number\") {\n const dv = input[\"default-value\"];\n if (dv !== undefined && typeof dv !== \"number\") {\n const num = Number(dv);\n if (Number.isFinite(num)) input[\"default-value\"] = num;\n else delete input[\"default-value\"];\n }\n }\n\n // Default must be one of the choices, or dropped.\n const choices = input[\"value-choices\"];\n const dv = input[\"default-value\"];\n if (Array.isArray(choices) && dv !== undefined && !choices.some((c) => c === dv)) {\n delete input[\"default-value\"];\n }\n\n this.mergeDefaultIntoDescription(input);\n }\n\n // Peel wrapper layers from an IR node to extract Boutiques input properties.\n // Walks from outermost to innermost, detecting optional/repeat/flag patterns.\n private peelNode(node: Expr, type: BoundType): PeeledInput {\n const result: PeeledInput = { isOptional: false, isList: false };\n this.peelNodeInner(node, type, result);\n return result;\n }\n\n private peelNodeInner(node: Expr, type: BoundType, result: PeeledInput): void {\n switch (node.kind) {\n case \"optional\":\n result.isOptional = true;\n this.peelNodeInner(node.attrs.node, type.kind === \"optional\" ? type.inner : type, result);\n break;\n\n case \"repeat\":\n // count's Repeat is the count, not a list - mapType handles it.\n if (this.isCount(type)) {\n break;\n }\n result.isList = true;\n if (node.attrs.join !== undefined) result.listSeparator = node.attrs.join;\n if (node.attrs.countMin !== undefined) result.minListEntries = node.attrs.countMin;\n if (node.attrs.countMax !== undefined) result.maxListEntries = node.attrs.countMax;\n this.peelNodeInner(node.attrs.node, type.kind === \"list\" ? type.item : type, result);\n break;\n\n case \"sequence\": {\n // Detect flag pattern: seq(lit(flag), inner)\n const nodes = node.attrs.nodes;\n if (nodes.length === 2 && nodes[0]!.kind === \"literal\") {\n const flagLit = nodes[0]!.attrs.str;\n const { flag, separator } = this.splitFlagLiteral(flagLit);\n result.flag = flag;\n if (separator) result.flagSeparator = separator;\n this.peelNodeInner(nodes[1]!, type, result);\n }\n // Otherwise don't peel further (it's a struct sequence or similar)\n break;\n }\n\n default:\n // Terminal or other node - nothing more to peel\n break;\n }\n }\n\n // Split a flag literal like \"-f \" or \"--flag=\" into flag + separator.\n // The parser merges flag + separator into one literal: `flag + (flagSep ?? \"\")`\n private splitFlagLiteral(str: string): { flag: string; separator: string } {\n // If it ends with \"=\", split there\n if (str.endsWith(\"=\")) {\n return { flag: str.slice(0, -1), separator: \"=\" };\n }\n // If it ends with whitespace, strip it\n const trimmed = str.trimEnd();\n if (trimmed.length < str.length) {\n return { flag: trimmed, separator: str.slice(trimmed.length) };\n }\n // No separator\n return { flag: str, separator: \"\" };\n }\n\n // Unwrap optional/list layers to get the \"core\" type for mapping\n private unwrapType(type: BoundType): BoundType {\n if (type.kind === \"optional\") return this.unwrapType(type.inner);\n if (type.kind === \"list\") return this.unwrapType(type.item);\n return type;\n }\n\n // Returned list/optional fields override peeled values (for `count`, whose\n // IR Repeat does not correspond to a Boutiques list).\n private mapType(\n type: BoundType,\n node: Expr,\n ): {\n type: string | BtDescriptor | BtDescriptor[];\n integer?: boolean;\n minimum?: number;\n maximum?: number;\n valueChoices?: (string | number)[];\n resolveParent?: boolean;\n mutable?: boolean;\n list?: boolean;\n listSeparator?: string;\n minListEntries?: number;\n optional?: boolean;\n } {\n switch (type.kind) {\n case \"scalar\":\n return this.mapScalar(type.scalar, node);\n\n case \"bool\":\n return { type: \"Flag\" };\n\n case \"count\":\n return this.mapCount(node);\n\n case \"literal\":\n // Single literal - emit as String with value-choices\n return {\n type: \"String\",\n valueChoices: [type.value],\n };\n\n case \"struct\":\n return { type: this.buildSubCommand(type, node) };\n\n case \"union\":\n return this.mapUnion(type, node);\n\n // optional/list should have been unwrapped already\n case \"optional\":\n return this.mapType(type.inner, node);\n case \"list\":\n return this.mapType(type.item, node);\n }\n }\n\n private mapScalar(\n scalar: ScalarKind,\n node: Expr,\n ): {\n type: string;\n integer?: boolean;\n minimum?: number;\n maximum?: number;\n resolveParent?: boolean;\n mutable?: boolean;\n } {\n const terminal = this.findTerminal(node);\n\n switch (scalar) {\n case \"int\": {\n const result: { type: string; integer: true; minimum?: number; maximum?: number } = {\n type: \"Number\",\n integer: true,\n };\n if (terminal?.kind === \"int\") {\n if (terminal.attrs.minValue !== undefined) result.minimum = terminal.attrs.minValue;\n if (terminal.attrs.maxValue !== undefined) result.maximum = terminal.attrs.maxValue;\n }\n return result;\n }\n\n case \"float\": {\n const result: { type: string; minimum?: number; maximum?: number } = { type: \"Number\" };\n if (terminal?.kind === \"float\") {\n if (terminal.attrs.minValue !== undefined) result.minimum = terminal.attrs.minValue;\n if (terminal.attrs.maxValue !== undefined) result.maximum = terminal.attrs.maxValue;\n }\n return result;\n }\n\n case \"str\":\n return { type: \"String\" };\n\n case \"path\": {\n const result: { type: string; resolveParent?: boolean; mutable?: boolean } = {\n type: \"File\",\n };\n if (terminal?.kind === \"path\") {\n if (terminal.attrs.resolveParent) result.resolveParent = true;\n if (terminal.attrs.mutable) result.mutable = true;\n }\n return result;\n }\n }\n }\n\n private mapUnion(\n type: Extract<BoundType, { kind: \"union\" }>,\n node: Expr,\n ): {\n type: string | BtDescriptor | BtDescriptor[];\n valueChoices?: (string | number)[];\n } {\n // All-literal union -> value-choices\n const allLiteral = type.variants.every((v: BoundVariant) => v.type.kind === \"literal\");\n if (allLiteral) {\n return {\n type: \"String\",\n valueChoices: type.variants.map((v: BoundVariant) =>\n v.type.kind === \"literal\" ? v.type.value : \"\",\n ),\n };\n }\n\n // All-struct union -> SubCommandUnion\n const allStruct = type.variants.every((v: BoundVariant) => v.type.kind === \"struct\");\n if (allStruct) {\n return { type: this.buildSubCommandUnion(type, node) };\n }\n\n // Mixed union -> wrap each variant as a SubCommand descriptor\n return { type: this.buildMixedUnionAsSubCommands(type, node) };\n }\n\n private buildSubCommand(type: Extract<BoundType, { kind: \"struct\" }>, node: Expr): BtDescriptor {\n const bt: BtDescriptor = {};\n const structNode = findStructNode(node, this.ctx, type);\n if (structNode) {\n // Recursively serialize as nested descriptor\n this.buildFromStruct(bt, type, node);\n }\n if (node.meta?.name) {\n bt.name = node.meta.name;\n bt.id = this.sanitizeId(node.meta.name);\n }\n return bt;\n }\n\n private buildSubCommandUnion(\n type: Extract<BoundType, { kind: \"union\" }>,\n node: Expr,\n ): BtDescriptor[] {\n const alts = node.kind === \"alternative\" ? node.attrs.alts : [node];\n\n return type.variants.map((variant: BoundVariant, i: number) => {\n const altNode = alts[i] ?? node;\n if (variant.type.kind === \"struct\") {\n const bt = this.buildSubCommand(variant.type, altNode);\n // The variant has its own name; the wrapperNode's name is the\n // parent (mutex group) name and would otherwise leak down.\n if (variant.name) {\n bt.name = variant.name;\n bt.id = this.sanitizeId(variant.name);\n }\n return bt;\n }\n return this.wrapAsDescriptor(variant, altNode);\n });\n }\n\n private buildMixedUnionAsSubCommands(\n type: Extract<BoundType, { kind: \"union\" }>,\n node: Expr,\n ): BtDescriptor[] {\n const alts = node.kind === \"alternative\" ? node.attrs.alts : [node];\n\n return type.variants.map((variant: BoundVariant, i: number) => {\n const altNode = alts[i] ?? node;\n if (variant.type.kind === \"struct\") {\n const bt = this.buildSubCommand(variant.type, altNode);\n // The variant has its own name; the wrapperNode's name is the\n // parent (mutex group) name and would otherwise leak down.\n if (variant.name) {\n bt.name = variant.name;\n bt.id = this.sanitizeId(variant.name);\n }\n return bt;\n }\n return this.wrapAsDescriptor(variant, altNode);\n });\n }\n\n // Wrap a non-struct variant as a trivial single-input descriptor\n private wrapAsDescriptor(variant: BoundVariant, node: Expr): BtDescriptor {\n const name = variant.name ?? \"value\";\n const id = this.sanitizeId(name);\n const mapped = this.mapType(variant.type, node);\n const input: BtInput = {\n id,\n type: mapped.type,\n \"value-key\": `[${screamingSnakeCase(id)}]`,\n };\n if (mapped.valueChoices) input[\"value-choices\"] = mapped.valueChoices;\n if (mapped.integer) input.integer = true;\n if (mapped.minimum !== undefined) input.minimum = mapped.minimum;\n if (mapped.maximum !== undefined) input.maximum = mapped.maximum;\n\n this.finalizeInput(input);\n\n return {\n name,\n id,\n \"command-line\": `[${screamingSnakeCase(id)}]`,\n inputs: [input],\n };\n }\n\n // Find terminal node through wrappers\n private findTerminal(node: Expr): Expr | undefined {\n switch (node.kind) {\n case \"optional\":\n return this.findTerminal(node.attrs.node);\n case \"repeat\":\n return this.findTerminal(node.attrs.node);\n case \"sequence\": {\n const nonLiteral = node.attrs.nodes.find((n) => n.kind !== \"literal\");\n return nonLiteral ? this.findTerminal(nonLiteral) : undefined;\n }\n default:\n return node;\n }\n }\n\n // Build a simple command-line string from literal nodes in an expression\n private buildCommandLineFromExpr(expr: Expr): string {\n if (expr.kind === \"literal\") return expr.attrs.str;\n if (expr.kind === \"sequence\") {\n return expr.attrs.nodes.map((n) => this.buildCommandLineFromExpr(n)).join(\" \");\n }\n return \"\";\n }\n\n private isBool(type: BoundType): boolean {\n if (type.kind === \"bool\") return true;\n if (type.kind === \"optional\") return this.isBool(type.inner);\n return false;\n }\n\n private isCount(type: BoundType): boolean {\n if (type.kind === \"count\") return true;\n if (type.kind === \"optional\") return this.isCount(type.inner);\n return false;\n }\n\n // Boutiques `id` must match /^[0-9A-Za-z_]+$/ (input ids, sub-descriptor\n // ids, value-keys after [ ] removal). Non-matching chars (e.g. argparse\n // subparser names with hyphens) become underscores.\n private sanitizeId(raw: string): string {\n const cleaned = raw.replace(/[^0-9A-Za-z_]/g, \"_\");\n return cleaned.length > 0 ? cleaned : \"id\";\n }\n\n private findCountRepeat(node: Expr): Extract<Expr, { kind: \"repeat\" }> | undefined {\n switch (node.kind) {\n case \"repeat\":\n return node;\n case \"optional\":\n return this.findCountRepeat(node.attrs.node);\n default:\n return undefined;\n }\n }\n\n // Bounded count -> String + enumerated value-choices.\n // Unbounded count -> SubCommand + list:true (no list-separator: each\n // occurrence must be a separate argv element for argparse to count it).\n private mapCount(node: Expr): {\n type: string | BtDescriptor;\n valueChoices?: string[];\n list?: boolean;\n listSeparator?: string;\n minListEntries?: number;\n optional?: boolean;\n } {\n const repeat = this.findCountRepeat(node);\n if (!repeat || repeat.attrs.node.kind !== \"literal\") {\n return { type: \"Flag\" };\n }\n const flag = repeat.attrs.node.attrs.str;\n const countMin = repeat.attrs.countMin ?? 0;\n const countMax = repeat.attrs.countMax;\n\n if (countMax !== undefined && countMax >= Math.max(countMin, 1)) {\n const choices: string[] = [];\n const start = Math.max(countMin, 1);\n for (let i = start; i <= countMax; i++) choices.push(flag.repeat(i));\n return {\n type: \"String\",\n valueChoices: choices,\n ...(countMin === 0 && { optional: true }),\n };\n }\n\n const dest = repeat.meta?.name;\n const subId = this.sanitizeId(dest ? `${dest}_token` : \"count_token\");\n const subBt: BtDescriptor = {\n name: subId,\n id: subId,\n \"command-line\": flag,\n inputs: [],\n };\n\n return {\n type: subBt,\n list: true,\n minListEntries: countMin,\n };\n }\n}\n\n/**\n * The ordered command literals on the path from `node` down to `target`,\n * descending only through sequences (the structure `findStructNode` follows to\n * reach a struct whose fields are direct children). Returns `null` when\n * `target` is not reachable that way - callers then emit no prefix. Literals\n * inside `target` itself are excluded; the caller walks those separately.\n */\nfunction commandPrefixLiterals(node: Expr, target: Expr): string[] | null {\n if (node === target) return [];\n if (node.kind !== \"sequence\") return null;\n const lits: string[] = [];\n for (const child of node.attrs.nodes) {\n if (child === target) return lits;\n if (child.kind === \"literal\") {\n lits.push(child.attrs.str);\n continue;\n }\n const deeper = commandPrefixLiterals(child, target);\n if (deeper !== null) return [...lits, ...deeper];\n }\n return null;\n}\n\nexport function generateBoutiques(ctx: CodegenContext): {\n descriptor: BtDescriptor;\n warnings: EmitWarning[];\n} {\n return new BoutiquesEmitter(ctx).emit();\n}\n\nexport class BoutiquesBackend implements Backend {\n readonly name = \"boutiques\";\n readonly target = \"boutiques\";\n\n emitApp(ctx: CodegenContext): EmittedApp {\n const { descriptor, warnings } = generateBoutiques(ctx);\n const json = JSON.stringify(descriptor, null, 2);\n return {\n meta: ctx.app,\n files: new Map([[\"descriptor.json\", json]]),\n errors: [],\n warnings,\n };\n }\n}\n","/** Line-buffer abstraction for code emission. */\nexport class CodeBuilder {\n private readonly lines: string[] = [];\n private depth = 0;\n private readonly indentStr: string;\n\n constructor(indent = \" \") {\n this.indentStr = indent;\n }\n\n /** Append a line at the current indentation level. */\n line(text: string): this {\n this.lines.push(this.indentStr.repeat(this.depth) + text);\n return this;\n }\n\n /** Append a blank line. */\n blank(): this {\n this.lines.push(\"\");\n return this;\n }\n\n /** Append a comment line. */\n comment(text: string, prefix = \"// \"): this {\n return this.line(`${prefix}${text}`);\n }\n\n /** Run a callback with increased indentation. */\n indent(fn: () => void): this {\n this.depth++;\n fn();\n this.depth--;\n return this;\n }\n\n /** Append all lines from another CodeBuilder at the current indentation level. */\n append(other: CodeBuilder): this {\n const prefix = this.indentStr.repeat(this.depth);\n for (const line of other.lines) {\n this.lines.push(line === \"\" ? \"\" : prefix + line);\n }\n return this;\n }\n\n /** Return the built code as a string. */\n toString(): string {\n return this.lines.join(\"\\n\");\n }\n}\n","import type { BoundType } from \"../bindings/index.js\";\n\n/**\n * Stable, fully structural identity key for any BoundType.\n *\n * Two types share a key iff they are structurally identical - same shape AND\n * same leaf types/literal values, recursively. This is what `collectNamedTypes`\n * dedups on: distinct nominal types must get distinct keys so each gets its own\n * generated name.\n *\n * Keying on field/variant *names* alone is too coarse: discriminated-union\n * variants that differ only by their `@type` literal (e.g. ANTs' `transform_*`\n * variants, all `{ \"@type\": <literal>, gradient_step: float }`) would collapse\n * to one identity, emitting `Transform = TransformRigid | TransformRigid | ...`\n * and breaking discriminated-union narrowing. Including the field types (and\n * thus the `@type` literal value) keeps them distinct.\n */\nexport function typeKey(type: BoundType): string {\n switch (type.kind) {\n case \"scalar\":\n return `scalar:${type.scalar}`;\n case \"bool\":\n return \"bool\";\n case \"count\":\n return \"count\";\n case \"literal\":\n // JSON.stringify disambiguates the value's type too (e.g. \"2\" vs 2).\n return `literal:${JSON.stringify(type.value)}`;\n case \"optional\":\n return `optional(${typeKey(type.inner)})`;\n case \"list\":\n return `list(${typeKey(type.item)})`;\n case \"struct\":\n return structKey(type);\n case \"union\":\n return unionKey(type);\n }\n}\n\n/** Stable identity key for a struct type (field names + field types). */\nexport function structKey(type: Extract<BoundType, { kind: \"struct\" }>): string {\n const fields = Object.entries(type.fields)\n .map(([name, fieldType]) => `${name}=${typeKey(fieldType)}`)\n .join(\",\");\n return `struct{${fields}}`;\n}\n\n/** Stable identity key for a union type (variant names + variant types). */\nexport function unionKey(type: Extract<BoundType, { kind: \"union\" }>): string {\n const variants = type.variants.map((v) => `${v.name ?? \"?\"}=${typeKey(v.type)}`).join(\"|\");\n return `union[${variants}]`;\n}\n","import type { BoundType } from \"../bindings/index.js\";\nimport { Scope } from \"./scope.js\";\nimport { structKey, unionKey } from \"./type-keys.js\";\n\n/** A named compound type (struct or union) discovered during type collection. */\nexport interface NamedType {\n name: string;\n type: BoundType;\n}\n\n/**\n * Recursively collect all struct/union types and assign unique names.\n *\n * Walks the BoundType tree depth-first, using structural keys (`structKey`,\n * `unionKey`) to deduplicate types that appear multiple times in the tree.\n * Each unique struct/union gets a name generated by applying `nameTransform`\n * to a hint string (derived from the root name or field/variant names).\n *\n * @param rootType - The root BoundType to walk.\n * @param rootName - The hint for the root type's name (already tool-qualified).\n * @param scope - Symbol scope for collision avoidance.\n * @param nameTransform - Converts a hint string to a type name (e.g. pascalCase, snake_case).\n * @param nestedPrefix - Prepended to every NON-root type name so a suite's flat\n * barrel (`export * from`/`from .x import *`) can't collide two tools' types\n * that share a local field/variant name (e.g. `Outputtype`). Pass the tool's\n * type prefix (its root name); defaults to \"\" for single-tool emission.\n * @returns `namedTypes` maps structural keys to assigned names, `typeDecls` lists declarations in order.\n */\nexport function collectNamedTypes(\n rootType: BoundType,\n rootName: string,\n scope: Scope,\n nameTransform: (hint: string) => string,\n nestedPrefix = \"\",\n): { namedTypes: Map<string, string>; typeDecls: NamedType[] } {\n const namedTypes = new Map<string, string>();\n const typeDecls: NamedType[] = [];\n\n function nameFor(hint: string, isRoot: boolean): string {\n const cased = isRoot ? nameTransform(hint) : nestedPrefix + nameTransform(hint);\n // Dedup in the cased (emitted) namespace, folding any disambiguation suffix\n // back through nameTransform so a collision yields e.g. `Config2`, not the\n // mixed-case `Config_2`. Uniqueness is still checked on the final form, so\n // two hints that case-collide get distinct names.\n return scope.add(cased, nameTransform);\n }\n\n function visit(type: BoundType, hint: string, isRoot: boolean): void {\n switch (type.kind) {\n case \"struct\": {\n const key = structKey(type);\n if (!namedTypes.has(key)) {\n const name = nameFor(hint, isRoot);\n namedTypes.set(key, name);\n typeDecls.push({ name, type });\n for (const [fieldName, fieldType] of Object.entries(type.fields)) {\n visit(fieldType, fieldName, false);\n }\n }\n break;\n }\n case \"union\": {\n const key = unionKey(type);\n if (!namedTypes.has(key)) {\n const name = nameFor(hint, isRoot);\n namedTypes.set(key, name);\n typeDecls.push({ name, type });\n for (const v of type.variants) {\n visit(v.type, v.name ?? hint, false);\n }\n }\n break;\n }\n // Wrappers are transparent: an optional/list at the root still names its\n // inner type as the root (no prefix), matching the pre-prefix behavior.\n case \"optional\":\n visit(type.inner, hint, isRoot);\n break;\n case \"list\":\n visit(type.item, hint, isRoot);\n break;\n default:\n break;\n }\n }\n\n visit(rootType, rootName, true);\n return { namedTypes, typeDecls };\n}\n\n/**\n * Create a type name resolver from a namedTypes map.\n * Returns a function that maps a BoundType to its assigned name (if any).\n */\nexport function resolveTypeName(\n namedTypes: Map<string, string>,\n): (type: BoundType) => string | undefined {\n return (type) => {\n if (type.kind === \"struct\") return namedTypes.get(structKey(type));\n if (type.kind === \"union\") return namedTypes.get(unionKey(type));\n return undefined;\n };\n}\n","/**\n * Runtime version floors baked into generated dependency metadata.\n *\n * styx2-generated code calls `mutable_copy` / `mutableCopy` (introduced in the\n * styxdefs 0.7.0 / styxdefs-js 0.2.0 release), so emitted packages genuinely\n * require that runtime floor. This is the single source of truth: bump here and\n * both the Python and TypeScript backends pick it up.\n */\nexport const STYXDEFS_COMPAT = {\n /** PEP 508 specifier for the Python `styxdefs` package. */\n python: \">=0.7.0,<0.8.0\",\n /** npm semver range for the `styxdefs` package. */\n npm: \"^0.2.0\",\n} as const;\n\n/**\n * Extra Python runtime packages the root distribution pulls in (container +\n * graph runners). Left unpinned - styxdefs's floor constrains them transitively\n * via their own inter-package pins.\n */\nexport const PYTHON_RUNNER_DEPS = [\"styxdocker\", \"styxsingularity\", \"styxgraph\"] as const;\n","import type { Documentation } from \"../../ir/index.js\";\nimport type { PackageMeta, ProjectMeta } from \"../../manifest/index.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport { PYTHON_RUNNER_DEPS, STYXDEFS_COMPAT } from \"../styxdefs-compat.js\";\n\nconst REQUIRES_PYTHON = \">=3.10\";\nconst BUILD_SYSTEM = `[build-system]\nrequires = [\"setuptools>=61\"]\nbuild-backend = \"setuptools.build_meta\"`;\n\n/** Escape a value for embedding in a TOML basic string. */\nfunction tomlStr(s: string): string {\n return (\n s\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\"/g, '\\\\\"')\n .replace(/[\\r\\n]+/g, \" \")\n // TOML basic strings forbid literal control chars (tab U+0009 is allowed);\n // strip the rest so scraped docs can't produce invalid TOML.\n // eslint-disable-next-line no-control-regex\n .replace(/[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f]/g, \"\")\n .trim()\n );\n}\n\n/** Suite directory / importable package name; matches the CLI's `pkgDir` fallback. */\nfunction pkgDir(pkg: PackageMeta): string {\n return pkg.name ?? \"package\";\n}\n\n/** Distribution (PyPI) name for a package: `<project>_<package>`, or just `<package>`. */\nexport function pyDistName(proj: ProjectMeta, pkg: PackageMeta): string {\n const name = pkgDir(pkg);\n return proj.name ? `${proj.name}_${name}` : name;\n}\n\n// pyproject's `[project] description` becomes the core-metadata `Summary` field,\n// which PyPI caps at 512 chars. The catalog's `doc.description` is often a full\n// paragraph (and is emitted in full into the README / long description anyway),\n// so the summary is clamped to fit.\nconst SUMMARY_MAX_LEN = 512;\n\n/**\n * Clamp a description to a <=512-char one-line summary. Prefer cutting at the\n * last complete sentence that fits (clean, no dangling fragment); if there is no\n * sentence boundary early enough, cut at a word boundary and mark the elision.\n */\nfunction clampSummary(s: string): string {\n if (s.length <= SUMMARY_MAX_LEN) return s;\n const window = s.slice(0, SUMMARY_MAX_LEN);\n const lastSentence = window.lastIndexOf(\". \");\n if (lastSentence >= 0) return s.slice(0, lastSentence + 1); // keep the period\n const ellipsis = \"...\";\n const body = window.slice(0, SUMMARY_MAX_LEN - ellipsis.length);\n const lastSpace = body.lastIndexOf(\" \");\n return (lastSpace > 0 ? body.slice(0, lastSpace) : body).replace(/[.,;:\\s]+$/, \"\") + ellipsis;\n}\n\nfunction description(doc: Documentation | undefined, fallbackName: string | undefined): string {\n const summary =\n doc?.description ?? `Styx generated wrappers for ${doc?.title ?? fallbackName ?? \"tools\"}.`;\n return clampSummary(summary);\n}\n\nfunction authorsField(doc: Documentation | undefined): string {\n const authors = doc?.authors?.length ? doc.authors : [\"unknown\"];\n return `[${authors.map((a) => `{ name = \"${tomlStr(a)}\" }`).join(\", \")}]`;\n}\n\nfunction licenseField(proj: ProjectMeta): string {\n return `{ text = \"${tomlStr(proj.license?.description ?? \"unknown\")}\" }`;\n}\n\n/**\n * Per-suite `pyproject.toml`. The flat layout (`python/<pkg>/bet.py`) makes the\n * directory itself the importable package, so setuptools' `package-dir` maps the\n * import name (`<pkg>`) onto the distribution's root directory. The styxdefs\n * floor is the only runtime dependency.\n *\n * Precondition: `pkg.name` must be a valid Python identifier - the flat layout's\n * relative imports (`from .bet import *`) already require this, and the CLI uses\n * it verbatim as the directory name, so this stays consistent with that.\n */\nexport function generateSubPyproject(proj: ProjectMeta, pkg: PackageMeta): string {\n const importName = pkgDir(pkg);\n const cb = new CodeBuilder(\" \");\n cb.line(\"[project]\");\n cb.line(`name = \"${tomlStr(pyDistName(proj, pkg))}\"`);\n // The wrapper distribution is released as part of the project, so it carries\n // the project (catalog) version - NOT the wrapped tool's version. This keeps\n // every niwrap_<pkg> in lockstep with the niwrap meta package, matching the\n // single-package TypeScript distribution and the v1 release scheme.\n cb.line(`version = \"${tomlStr(proj.version ?? \"0.0.0\")}\"`);\n cb.line(`description = \"${tomlStr(description(pkg.doc, pkg.name))}\"`);\n cb.line(`readme = \"README.md\"`);\n cb.line(`license = ${licenseField(proj)}`);\n cb.line(`authors = ${authorsField(pkg.doc ?? proj.doc)}`);\n cb.line(`requires-python = \"${REQUIRES_PYTHON}\"`);\n cb.line(\"dependencies = [\");\n cb.line(` \"styxdefs${STYXDEFS_COMPAT.python}\",`);\n cb.line(\"]\");\n cb.blank();\n cb.line(\"[tool.setuptools]\");\n cb.line(`packages = [\"${importName}\"]`);\n cb.line(`package-dir = { \"${importName}\" = \".\" }`);\n cb.blank();\n cb.line(\"[tool.setuptools.package-data]\");\n cb.line(`\"${importName}\" = [\"py.typed\"]`);\n cb.blank();\n cb.line(BUILD_SYSTEM);\n return cb.toString() + \"\\n\";\n}\n\n/**\n * Root `pyproject.toml`: a metapackage depending on each per-suite distribution\n * plus the container/graph runner packages. `packages = []` keeps setuptools\n * from sweeping the sibling suite directories into this distribution.\n */\nexport function generateRootPyproject(proj: ProjectMeta, distNames: string[]): string {\n const cb = new CodeBuilder(\" \");\n cb.line(\"[project]\");\n cb.line(`name = \"${tomlStr(proj.name ?? \"project\")}\"`);\n cb.line(`version = \"${tomlStr(proj.version ?? \"0.0.0\")}\"`);\n cb.line(`description = \"${tomlStr(description(proj.doc, proj.name))}\"`);\n cb.line(`readme = \"README.md\"`);\n cb.line(`license = ${licenseField(proj)}`);\n cb.line(`authors = ${authorsField(proj.doc)}`);\n cb.line(`requires-python = \"${REQUIRES_PYTHON}\"`);\n cb.line(\"dependencies = [\");\n for (const dep of PYTHON_RUNNER_DEPS) cb.line(` \"${dep}\",`);\n for (const dist of distNames) cb.line(` \"${tomlStr(dist)}\",`);\n cb.line(\"]\");\n cb.blank();\n cb.line(\"[tool.setuptools]\");\n cb.line(\"packages = []\");\n cb.blank();\n cb.line(BUILD_SYSTEM);\n return cb.toString() + \"\\n\";\n}\n\n/** Per-suite README crediting the upstream tool authors. */\nexport function generateSubReadme(proj: ProjectMeta, pkg: PackageMeta): string {\n const projectTitle = proj.doc?.title ?? proj.name ?? \"Styx\";\n const packageTitle = pkg.doc?.title ?? pkg.name ?? \"package\";\n const url = pkg.doc?.urls?.[0];\n const titleMd = url ? `[${packageTitle}](${url})` : packageTitle;\n const credits = pkg.doc?.authors?.length\n ? pkg.doc.authors.join(\", \")\n : (pkg.doc?.urls?.join(\", \") ?? \"unknown\");\n const desc = pkg.doc?.description ? `\\n\\n${pkg.doc.description}` : \"\";\n return (\n `# ${projectTitle} wrappers for ${titleMd}${desc}\\n\\n` +\n `${packageTitle} is made by ${credits}.\\n\\n` +\n `This package contains wrappers only and has no affiliation with the original authors.\\n`\n );\n}\n\n/** Root README listing the bundled per-suite distributions. */\nexport function generateRootReadme(proj: ProjectMeta, distNames: string[]): string {\n const title = proj.doc?.title ?? proj.name ?? \"Styx\";\n const desc = proj.doc?.description ? `\\n${proj.doc.description}\\n` : \"\";\n const list = distNames.map((d) => `- ${d}`).join(\"\\n\");\n return (\n `# ${title}\\n${desc}\\n` +\n `Auto-generated Styx wrappers. This project bundles the following packages:\\n\\n` +\n `${list}\\n`\n );\n}\n\n/** Local-install manifest: each suite directory first, then the root metapackage. */\nexport function generateRequirementsTxt(pkgDirs: string[]): string {\n return [...pkgDirs.map((d) => `./${d}`), \"./\"].join(\"\\n\") + \"\\n\";\n}\n","import type { BoundType } from \"../bindings/index.js\";\nimport type { FieldInfo } from \"./collect-field-info.js\";\n\n/**\n * One entry of a kwarg-style signature, shared across language backends. Each\n * entry describes a single user-facing parameter of the `_params()` factory\n * and the kwarg wrapper:\n * - `sigType`/`sigDefault` go directly into the function signature\n * - `isOptional`/`hasExplicitDefault` drive the dict-build branches (required\n * and explicitly-defaulted fields are always set; optional-no-default fields\n * are conditionally set when not None/null)\n * - `doc` is rendered into the per-param doc block (Args / @param)\n *\n * `name` is the scrubbed host identifier (used in the signature and function\n * body); `wireKey` is the Boutiques field name (used as the dict key /\n * TypedDict field key). They diverge when the wire key collides with a host\n * reserved word, is not a valid identifier, or shadows a local in the emitting\n * function (e.g. wire `float` -> host `float_`, wire `4d_input` -> host\n * `v_4d_input`).\n */\nexport interface SigEntry {\n /** Scrubbed host identifier - safe to use in signatures and as a local. */\n name: string;\n /** Boutiques field name - used as the dict key / TypedDict field key. */\n wireKey: string;\n sigType: string;\n /** Rendered default expression in the host language, or undefined for required-no-default. */\n sigDefault?: string;\n /** True iff the BoundType is `optional` (i.e. dict-build conditionally includes). */\n isOptional: boolean;\n /** True iff the field carries an explicit defaultValue in its FieldInfo. */\n hasExplicitDefault: boolean;\n doc?: string;\n}\n\n/** Per-backend rendering hooks for `buildSigEntries`. */\nexport interface SigOptions {\n /** Render a non-optional BoundType as a language-native type expression. */\n renderType: (t: BoundType) => string;\n /** Suffix appended to `renderType(inner)` for optional fields (e.g. ` | None`, ` | null`). */\n nullableSuffix: string;\n /** Default expression for optional-no-default fields (e.g. `None`, `null`). */\n nullableDefault: string;\n /** Render a JS scalar default as a host-language literal (e.g. `True`/`true`). */\n renderDefault: (v: string | number | boolean) => string;\n}\n\n/**\n * Build per-field signature entries for the kwarg wrapper and params factory.\n * Skips `@type` (the factory injects it as a constant). Required-no-default\n * entries are placed before defaulted ones so the resulting signature is\n * syntactically valid in both Python and TS.\n *\n * `registerLocal` is called once per field with the wire key; it must return\n * a scrubbed, unique host identifier (typically by combining a language-aware\n * scrub function with `Scope.add()`). The caller's scope should already have\n * the function's other locals (`params`, `runner`, ...) reserved so this\n * registration cannot collide with them.\n */\nexport function buildSigEntries(\n rootType: Extract<BoundType, { kind: \"struct\" }>,\n fieldInfo: Map<string, FieldInfo>,\n registerLocal: (wireKey: string) => string,\n opts: SigOptions,\n): SigEntry[] {\n const entries: SigEntry[] = [];\n for (const [fieldName, fieldType] of Object.entries(rootType.fields)) {\n if (fieldType.kind === \"literal\") continue;\n\n const fi = fieldInfo.get(fieldName);\n const isOptional = fieldType.kind === \"optional\";\n const inner = isOptional ? fieldType.inner : fieldType;\n let sigType = opts.renderType(inner);\n if (isOptional) sigType += opts.nullableSuffix;\n\n let sigDefault: string | undefined;\n const hasExplicitDefault = fi?.defaultValue !== undefined;\n if (hasExplicitDefault) {\n sigDefault = opts.renderDefault(fi!.defaultValue!);\n } else if (isOptional) {\n sigDefault = opts.nullableDefault;\n }\n\n entries.push({\n name: registerLocal(fieldName),\n wireKey: fieldName,\n sigType,\n sigDefault,\n isOptional,\n hasExplicitDefault,\n doc: fi?.doc,\n });\n }\n const required = entries.filter((e) => e.sigDefault === undefined);\n const defaulted = entries.filter((e) => e.sigDefault !== undefined);\n return [...required, ...defaulted];\n}\n","import type { BoundType, BoundVariant } from \"../bindings/index.js\";\n\n/** A union's struct variant paired with its index into the union's `variants`\n * array (which stays parallel to the IR `alts` and the per-arm results a caller\n * builds, so the index must be threaded through). */\nexport interface IndexedStructVariant {\n variant: BoundVariant;\n i: number;\n}\n\n/**\n * The struct variants of a union, each with its index into `variants`.\n *\n * A discriminated union dispatches on a unique `@type`, so two struct variants\n * sharing a tag are a malformed union: the second is unreachable at runtime and\n * emits a dead branch (a mypy `comparison-overlap` in the Python backend's\n * `if`/`elif` chain). Producing well-formed, unique-tagged unions is a frontend\n * responsibility - the Boutiques frontend dodges duplicate sub-command ids\n * (`orient` -> `orient_2`). This asserts that invariant at the backend boundary\n * and throws if it is violated, rather than silently emitting a dead branch.\n */\nexport function structVariants(\n unionType: Extract<BoundType, { kind: \"union\" }>,\n): IndexedStructVariant[] {\n const seen = new Set<string>();\n const out: IndexedStructVariant[] = [];\n unionType.variants.forEach((variant, i) => {\n if (variant.type.kind !== \"struct\") return;\n const tag = variant.name ?? \"\";\n if (seen.has(tag)) {\n throw new Error(\n `duplicate union variant @type ${JSON.stringify(tag)}: a discriminated ` +\n `union dispatches on a unique @type, so a second variant with the same ` +\n `tag is unreachable. Frontends must dodge duplicate variant tags before ` +\n `codegen (the Boutiques frontend renames duplicate sub-command ids).`,\n );\n }\n seen.add(tag);\n out.push({ variant, i });\n });\n return out;\n}\n","import type { AccessPath, BindingId, BoundType } from \"../../bindings/index.js\";\n\n/**\n * Map a BoundType to its Python type expression.\n *\n * `resolve` is the named-type resolver from `collectNamedTypes` - returns the\n * declared name for struct/union types so they can be referenced symbolically\n * rather than inlined.\n *\n * Python target: 3.10+ (uses `X | None`, `list[T]`, `int`/`str`/etc.).\n */\nexport function mapType(type: BoundType, resolve: (type: BoundType) => string | undefined): string {\n switch (type.kind) {\n case \"scalar\":\n return { int: \"int\", float: \"float\", str: \"str\", path: \"InputPathType\" }[type.scalar];\n case \"bool\":\n return \"bool\";\n case \"count\":\n return \"int\";\n case \"literal\":\n return typeof type.value === \"string\"\n ? `typing.Literal[${pyStr(type.value)}]`\n : `typing.Literal[${type.value}]`;\n case \"optional\":\n // The solver has no nullable type: `optional` means \"omittable\" (the key\n // may be absent), never \"the value may be None\". Omittability is expressed\n // structurally at the field level (`typing.NotRequired[...]`); the value\n // type itself is just the inner type. So in any value position (nested\n // list/union arm, validator messages) we render the inner type with no\n // `| None`.\n return mapType(type.inner, resolve);\n case \"list\":\n return `list[${mapType(type.item, resolve)}]`;\n case \"struct\": {\n const name = resolve(type);\n if (name) return name;\n // Fallback: inline as Mapping[str, object]. Real struct types should always\n // resolve to a declared TypedDict.\n return \"typing.Mapping[str, object]\";\n }\n case \"union\": {\n const name = resolve(type);\n if (name) return name;\n return type.variants.map((v) => mapType(v.type, resolve)).join(\" | \");\n }\n }\n}\n\n/** Render a JS default value as a Python literal (signatures, `.get(k, default)`). */\nexport function renderPyLiteral(value: string | number | boolean): string {\n if (typeof value === \"boolean\") return value ? \"True\" : \"False\";\n if (typeof value === \"number\") return Number.isFinite(value) ? String(value) : \"float('nan')\";\n return pyStr(value);\n}\n\n/** Python double-quoted string literal with minimal escaping. */\nexport function pyStr(value: string): string {\n // For any value containing control characters, JSON encoding produces a valid\n // Python double-quoted literal (with the same `\\n`/`\\t`/`\\uXXXX` escapes).\n // Otherwise we hand-escape backslashes and double quotes only.\n for (let i = 0; i < value.length; i++) {\n if (value.charCodeAt(i) < 0x20) return JSON.stringify(value);\n }\n return `\"${value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`;\n}\n\n/** Options controlling how `renderAccess` renders an access path. */\nexport interface RenderAccessOptions {\n /**\n * Render the LAST segment - if it is a `field` - as `base.get(key)` instead of\n * `base[key]`. Used when binding the value of an optional field to a narrowed\n * local: the params factory omits optional-without-default keys entirely (they\n * are `typing.NotRequired`), so a bare subscript would raise `KeyError`. `.get()`\n * yields `None` for an absent key, matching the present-and-None case. (Unlike\n * JS, where `obj[missing]` is `undefined`, Python subscript on a missing key\n * raises - so the structurally-mirrored TS walk needs this read in Python.)\n */\n finalFieldGet?: boolean;\n /**\n * Render the LAST segment - if it is a `field` - as `base.get(key, <default>)`,\n * supplying a fallback value for an absent key. Used for fields that carry a\n * Boutiques default and are read unconditionally (e.g. an output-basename like\n * `maskfile=\"img_bet\"`): the field is `NotRequired`, so a bare subscript would\n * raise `KeyError`, and a bare `.get()` would yield `None` (wrong - the default\n * must be substituted). The string is an already-rendered Python literal.\n * Takes precedence over `finalFieldGet`.\n */\n finalFieldDefault?: string;\n /**\n * Prefix substitutions: maps a rendered access prefix (e.g. `params[\"cfg\"]`) to\n * a local variable name. After each segment is appended, if the rendered prefix\n * so far matches a key, it is replaced by the local. This lets reads of an\n * optional field (and anything nested under it) resolve to the `.get()`-narrowed\n * local bound by the enclosing presence guard - one lookup, absent-safe, and\n * mypy can narrow it (a re-subscript or a fresh `.get()` cannot be narrowed).\n */\n subst?: ReadonlyMap<string, string>;\n}\n\n/**\n * Render a solver-assigned `AccessPath` to a Python expression. Starts from\n * `params`; each `field` segment subscripts a key, and each `iter` segment\n * resets the base to the loop variable bound to that repeat binding (resolved\n * via `lookupLoopVar`). Mirrors the TypeScript `renderAccess`.\n */\nexport function renderAccess(\n path: AccessPath,\n lookupLoopVar: (binding: BindingId) => string,\n options: RenderAccessOptions = {},\n): string {\n const { finalFieldGet = false, finalFieldDefault, subst } = options;\n let cur = \"params\";\n path.forEach((seg, i) => {\n if (seg.kind !== \"field\") {\n cur = lookupLoopVar(seg.binding);\n } else {\n const isLast = i === path.length - 1;\n if (isLast && finalFieldDefault !== undefined) {\n cur = `${cur}.get(${pyStr(seg.name)}, ${finalFieldDefault})`;\n } else if (isLast && finalFieldGet) {\n cur = `${cur}.get(${pyStr(seg.name)})`;\n } else {\n cur = `${cur}[${pyStr(seg.name)}]`;\n }\n }\n // Swap in a narrowed local if this prefix was bound by an enclosing guard.\n const sub = subst?.get(cur);\n if (sub !== undefined) cur = sub;\n });\n return cur;\n}\n","import type { Binding, BindingId, BoundType, BoundVariant } from \"../../bindings/index.js\";\nimport { collectFieldInfo } from \"../collect-field-info.js\";\nimport type { Expr } from \"../../ir/index.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport { structVariants } from \"../union-variants.js\";\nimport { pyStr, renderAccess, renderPyLiteral } from \"./typemap.js\";\n\n// -- Result types --\n\ninterface Expr_ {\n expr: string;\n}\ninterface Stmt {\n stmt: string;\n}\nexport type ArgResult = Expr_ | Stmt;\n\nfunction isExpr(r: ArgResult): r is Expr_ {\n return \"expr\" in r;\n}\n\nexport function resultToStmt(r: ArgResult): string {\n return isExpr(r) ? `cargs.append(${r.expr})` : r.stmt;\n}\n\nfunction appendLines(cb: CodeBuilder, code: string): void {\n for (const line of code.split(\"\\n\")) cb.line(line);\n}\n\n// -- Type helpers --\n\nfunction toStringExpr(node: Expr, type: BoundType, expr: string): string {\n if (type.kind === \"scalar\") {\n if (type.scalar === \"str\") return expr;\n if (type.scalar === \"path\") return pathArg(node, expr);\n }\n return `str(${expr})`;\n}\n\n/**\n * Command-line value for a path input via `execution.input_file`, threading the\n * path node's `resolve_parent` / `mutable` attrs as keyword args. `mutable=True`\n * tells the runner to stage a writable COPY (original untouched) and return the\n * copy's command-line path; the outputs builder surfaces that same copy's host\n * path via `execution.mutable_copy`.\n */\nfunction pathArg(node: Expr, expr: string): string {\n if (node.kind !== \"path\") return `execution.input_file(${expr})`;\n let extra = \"\";\n if (node.attrs.resolveParent) extra += \", resolve_parent=True\";\n if (node.attrs.mutable) extra += \", mutable=True\";\n return `execution.input_file(${expr}${extra})`;\n}\n\n// -- Context passed down through recursion --\n\ninterface ArgContext {\n /** Join nesting depth (controls ternary vs if-statement for optionals). */\n joinDepth: number;\n /**\n * Loop variables bound by enclosing `repeat`-of-list nodes, keyed by the\n * repeat binding's id. `renderAccess` consults this to resolve the `iter`\n * segments in a binding's solver-assigned access path.\n */\n loopVars: ReadonlyMap<BindingId, string>;\n /**\n * Prefix substitutions for optional fields narrowed by an enclosing presence\n * guard: maps a rendered access prefix to the `.get()`-narrowed local that\n * holds it. Threaded into `renderAccess` so inner reads use the local (one\n * lookup, absent-safe, mypy-narrowable) instead of re-subscripting.\n */\n valueSubst: ReadonlyMap<string, string>;\n /**\n * Rendered Python default literals for root-level NON-OPTIONAL fields that\n * carry a Boutiques default (e.g. `maskfile -> \"img_bet\"`), keyed by field\n * name. Such a field is `NotRequired` (a hand-authored config may omit it) yet\n * is read unconditionally - so every read of its value becomes\n * `.get(key, <default>)` to substitute the default instead of raising\n * `KeyError`. Optional fields are excluded: they are presence-guarded (their\n * default, if any, is supplied by the factory's kwarg signature), so reading\n * them with a default here would both be wrong and collide with `valueSubst`.\n */\n defaults: ReadonlyMap<string, string>;\n}\n\n/**\n * The rendered default for a binding iff it is a root-level NON-OPTIONAL field\n * carrying a Boutiques default. Restricted to single-segment (root) field access\n * so a nested field can never accidentally pick up a same-named root default.\n */\nfunction rootFieldDefault(\n binding: Binding,\n defaults: ReadonlyMap<string, string>,\n): string | undefined {\n const a = binding.access;\n if (a.length === 1 && a[0]?.kind === \"field\") return defaults.get(binding.name);\n return undefined;\n}\n\n/**\n * Render a binding's access for an UNCONDITIONAL value read (terminal, repeat\n * loop, alternative dispatch): substitutes the field's default via\n * `.get(key, default)` when it is a defaulted non-optional field, else the plain\n * access. Returns plain access for every non-defaulted field, so the emitted\n * code is byte-identical to before for the common case. Not used by\n * `walkOptional` (its bare access is the `valueSubst` key and its guard reads\n * via `.get()`).\n */\nfunction readAccess(binding: Binding, arg: ArgContext): string {\n const def = rootFieldDefault(binding, arg.defaults);\n return accessOf(binding, arg, def !== undefined ? { finalDefault: def } : {});\n}\n\ninterface AccessOpts {\n /** Render the final field segment as `.get(key)` (absent key -> None). */\n finalGet?: boolean;\n /** Render the final field segment as `.get(key, default)` (absent key -> default). */\n finalDefault?: string;\n}\n\n/**\n * Render a binding's solver-assigned access path in the current loop scope.\n * `finalGet` renders the final field segment as `.get(key)` (used when binding\n * an optional's value to a narrowed local); `finalDefault` renders it as\n * `.get(key, default)` (used for absent-safe reads of a defaulted field).\n */\nfunction accessOf(binding: Binding, arg: ArgContext, opts: AccessOpts = {}): string {\n return renderAccess(\n binding.access,\n (b) => {\n const v = arg.loopVars.get(b);\n if (v === undefined) throw new Error(`arg-builder: unbound loop variable for binding ${b}`);\n return v;\n },\n { finalFieldGet: opts.finalGet, finalFieldDefault: opts.finalDefault, subst: arg.valueSubst },\n );\n}\n\n/**\n * Build the field-name -> rendered-default map for a struct root (else empty).\n * Includes only non-optional defaulted fields (optional fields are\n * presence-guarded; their default comes from the factory's kwarg signature).\n */\nfunction collectDefaults(ctx: CodegenContext, rootType?: BoundType): Map<string, string> {\n const out = new Map<string, string>();\n if (rootType?.kind !== \"struct\") return out;\n for (const [name, fi] of collectFieldInfo(ctx, rootType)) {\n if (fi.defaultValue === undefined) continue;\n if (rootType.fields[name]?.kind === \"optional\") continue;\n out.set(name, renderPyLiteral(fi.defaultValue));\n }\n return out;\n}\n\n// -- Recursive descent --\n\nlet loopVarCounter = 0;\nlet optVarCounter = 0;\n\n/**\n * Build arg-building code for an IR tree via recursive descent.\n *\n * Mirrors the TypeScript backend's `walk` structurally so the emitted Python\n * has the same shape (and the same correctness story) as the TS output.\n */\nexport function buildArgs(rootExpr: Expr, ctx: CodegenContext, rootType?: BoundType): ArgResult {\n loopVarCounter = 0;\n optVarCounter = 0;\n const initialCtx: ArgContext = {\n joinDepth: 0,\n loopVars: new Map(),\n valueSubst: new Map(),\n defaults: collectDefaults(ctx, rootType),\n };\n return walk(rootExpr, ctx, initialCtx);\n}\n\nfunction walk(node: Expr, ctx: CodegenContext, arg: ArgContext): ArgResult {\n switch (node.kind) {\n case \"literal\":\n return { expr: pyStr(node.attrs.str) };\n\n case \"int\":\n case \"float\":\n case \"str\":\n case \"path\":\n return walkTerminal(node, ctx, arg);\n\n case \"sequence\":\n return walkSequence(node, ctx, arg);\n\n case \"optional\":\n return walkOptional(node, ctx, arg);\n\n case \"repeat\":\n return walkRepeat(node, ctx, arg);\n\n case \"alternative\":\n return walkAlternative(node, ctx, arg);\n }\n}\n\nfunction walkTerminal(node: Expr, ctx: CodegenContext, arg: ArgContext): ArgResult {\n const binding = ctx.resolve(node);\n if (!binding) throw new Error(`Missing binding for terminal node: ${node.kind}`);\n // A root-level defaulted field (e.g. an output basename `maskfile=\"img_bet\"`)\n // is read here unconditionally but is `NotRequired`, so `readAccess`\n // substitutes the default for an absent key via `.get(key, default)`.\n return { expr: toStringExpr(node, binding.type, readAccess(binding, arg)) };\n}\n\nfunction walkSequence(\n node: Extract<Expr, { kind: \"sequence\" }>,\n ctx: CodegenContext,\n arg: ArgContext,\n): ArgResult {\n // A non-join sequence inside an outer join must concatenate (rather than\n // push separate args) so it can stand in as a single Expr element of the\n // outer join. Boutiques produces this shape for `command-line-flag` inputs\n // nested under a parent join template (e.g. `[OUTPUT][FLAG]` -> seqJoin('')\n // around an opt(seq(lit(FLAG), value))).\n const join = node.attrs.join ?? (arg.joinDepth > 0 ? \"\" : undefined);\n\n // Struct scoping is already baked into each child's access path by the\n // solver; here we only thread join depth (a codegen concern).\n const childArg: ArgContext = join !== undefined ? { ...arg, joinDepth: arg.joinDepth + 1 } : arg;\n\n const parts = node.attrs.nodes.map((child) => walk(child, ctx, childArg));\n\n if (join !== undefined) {\n const exprs = parts.map((p) => (isExpr(p) ? p.expr : p.stmt));\n if (exprs.length === 1) return { expr: exprs[0]! };\n return { expr: `${pyStr(join)}.join([${exprs.join(\", \")}])` };\n }\n\n return { stmt: parts.map(resultToStmt).join(\"\\n\") };\n}\n\nfunction walkOptional(\n node: Extract<Expr, { kind: \"optional\" }>,\n ctx: CodegenContext,\n arg: ArgContext,\n): ArgResult {\n const binding = ctx.resolve(node);\n if (!binding) throw new Error(\"Missing binding for optional node\");\n const isOpt = binding.type.kind === \"optional\";\n const access = accessOf(binding, arg);\n\n // For a nullable optional, bind the value to a narrowed local read via `.get()`\n // (the key is `NotRequired` - the factory omits it when None, so a bare\n // subscript would KeyError). Inner reads of this access (and anything nested\n // under it) are redirected to the local via `valueSubst`: one lookup, absent-\n // safe, and mypy can narrow the local (it cannot narrow a re-subscript or a\n // fresh `.get()`). Bool-flag optionals are also `NotRequired` (default false),\n // so the truthy guard reads via `.get()` too (absent key -> None -> flag off).\n let childArg = arg;\n let local: string | undefined;\n let getAccess: string | undefined;\n if (isOpt) {\n local = `v_${optVarCounter++}`;\n getAccess = accessOf(binding, arg, { finalGet: true });\n childArg = { ...arg, valueSubst: new Map(arg.valueSubst).set(access, local) };\n }\n // Absent-safe truthy guard for the bool-flag case.\n const boolGuard = accessOf(binding, arg, { finalGet: true });\n\n // The inner node's access path is solver-assigned (it either inherits this\n // optional's path on a collapse, or scopes into it for a struct); we thread the\n // loop scope, join depth, and the optional's value substitution.\n const inner = walk(node.attrs.node, ctx, childArg);\n\n // Inside a join context, emit as ternary expression.\n if (arg.joinDepth > 0 && isExpr(inner)) {\n if (isOpt) {\n // Walrus binds the narrowed local inside the lazy ternary; the inner expr\n // (which references `local`) only evaluates when the key is present.\n return { expr: `(${inner.expr} if (${local} := ${getAccess}) is not None else \"\")` };\n }\n return { expr: `(${inner.expr} if ${boolGuard} else \"\")` };\n }\n\n const cb = new CodeBuilder(\" \");\n const innerStmt = resultToStmt(inner);\n if (isOpt) {\n cb.line(`${local} = ${getAccess}`);\n cb.line(`if ${local} is not None:`);\n cb.indent(() => appendLines(cb, innerStmt));\n } else {\n cb.line(`if ${boolGuard}:`);\n cb.indent(() => appendLines(cb, innerStmt));\n }\n return { stmt: cb.toString() };\n}\n\nfunction walkRepeat(\n node: Extract<Expr, { kind: \"repeat\" }>,\n ctx: CodegenContext,\n arg: ArgContext,\n): ArgResult {\n const binding = ctx.resolve(node);\n if (!binding) throw new Error(\"Missing binding for repeat node\");\n // A non-join repeat inside an outer join concatenates rather than pushing\n // separate args, mirroring walkSequence's handling of bare non-join seqs.\n const join = node.attrs.join ?? (arg.joinDepth > 0 ? \"\" : undefined);\n // Unconditional read (the count/list value) - `readAccess` substitutes a\n // defaulted non-optional field's default for an absent key.\n const access = readAccess(binding, arg);\n\n // Count repeat: emit a counted for-loop. Inside a join the for-loop would\n // be dropped into a list literal as raw text, so emit a comprehension.\n if (binding.type.kind === \"count\") {\n const inner = walk(node.attrs.node, ctx, arg);\n const v = `_i${loopVarCounter++}`;\n if (join !== undefined && isExpr(inner)) {\n return { expr: `${pyStr(join)}.join([${inner.expr} for ${v} in range(${access})])` };\n }\n const cb = new CodeBuilder(\" \");\n cb.line(`for ${v} in range(${access}):`);\n cb.indent(() => appendLines(cb, resultToStmt(inner)));\n return { stmt: cb.toString() };\n }\n\n // List repeat: emit a for-in loop or generator-join. The loop variable is\n // registered under this repeat's binding id so inner bindings' `iter`\n // segments resolve to it via `renderAccess`.\n const loopVar = `item${loopVarCounter++}`;\n const childArg: ArgContext = {\n ...arg,\n loopVars: new Map(arg.loopVars).set(binding.id, loopVar),\n };\n\n const inner = walk(node.attrs.node, ctx, childArg);\n\n if (join !== undefined && isExpr(inner)) {\n return {\n expr: `${pyStr(join)}.join([${inner.expr} for ${loopVar} in ${access}])`,\n };\n }\n\n const cb = new CodeBuilder(\" \");\n cb.line(`for ${loopVar} in ${access}:`);\n cb.indent(() => appendLines(cb, resultToStmt(inner)));\n return { stmt: cb.toString() };\n}\n\nfunction walkAlternative(\n node: Extract<Expr, { kind: \"alternative\" }>,\n ctx: CodegenContext,\n arg: ArgContext,\n): ArgResult {\n const binding = ctx.resolve(node);\n if (!binding) throw new Error(\"Missing binding for alternative node\");\n // Unconditional read (the enum value / bool guard / union discriminator) -\n // `readAccess` substitutes a defaulted non-optional field's default for an\n // absent key (e.g. a `value-choices` String with a default).\n const access = readAccess(binding, arg);\n\n // Complex-union variant fields already carry the union's path in their\n // solver-assigned access, so arms walk with the current context unchanged.\n const variants = node.attrs.alts.map((alt) => walk(alt, ctx, arg));\n\n if (\n binding.type.kind === \"union\" &&\n binding.type.variants.every((v: BoundVariant) => v.type.kind === \"literal\")\n ) {\n return { expr: `str(${access})` };\n }\n\n if (binding.type.kind === \"bool\") {\n // Inside a join, the alternative's output must be an expression, not a\n // statement: an `if/else` block dropped into a `\"\".join([...])` list\n // literal is not valid Python. Emit a ternary when both arms are exprs.\n if (arg.joinDepth > 0) {\n if (!variants[1]) {\n throw new Error(\n \"single-arm bool alternative inside a join: cannot produce an expression \" +\n \"without ambiguous semantics (omitting the entry vs emitting empty string)\",\n );\n }\n if (!variants.every(isExpr)) {\n throw new Error(\n \"bool alternative inside a join has statement-shaped variants; \" +\n \"expected all arms to fold to expressions\",\n );\n }\n const v0 = (variants[0] as Expr_).expr;\n const v1 = (variants[1] as Expr_).expr;\n return { expr: `(${v0} if ${access} else ${v1})` };\n }\n const cb = new CodeBuilder(\" \");\n cb.line(`if ${access}:`);\n cb.indent(() => appendLines(cb, resultToStmt(variants[0]!)));\n if (variants[1]) {\n cb.line(`else:`);\n cb.indent(() => appendLines(cb, resultToStmt(variants[1]!)));\n }\n return { stmt: cb.toString() };\n }\n\n if (binding.type.kind === \"union\") {\n const unionType = binding.type;\n // A union may be pure-discriminated (every variant a struct with `@type`) or\n // mixed (struct variants plus bare-literal variants, e.g. ants\n // `Interpolation = \"Linear\" | MultiLabel | ...`). Pure-enum unions returned\n // above. Dispatch struct variants on `@type`; a bare literal is its own value.\n // Struct variants with their indices; throws if two share an `@type` (a\n // duplicate-tagged variant is unreachable and a mypy `comparison-overlap` -\n // frontends must dodge duplicate tags before codegen).\n const structVars = structVariants(unionType);\n const hasLiteral = unionType.variants.some((v) => v.type.kind === \"literal\");\n\n // Inside a join: chained ternary, same reason as bool above.\n if (arg.joinDepth > 0) {\n if (!variants.every(isExpr)) {\n throw new Error(\n \"union alternative inside a join has statement-shaped variants; \" +\n \"expected all arms to fold to expressions\",\n );\n }\n let structExpr = pyStr(\"\");\n for (let k = structVars.length - 1; k >= 0; k--) {\n const { variant, i } = structVars[k]!;\n const v = (variants[i] as Expr_).expr;\n structExpr = `(${v} if ${access}[\"@type\"] == ${pyStr(variant.name ?? \"\")} else ${structExpr})`;\n }\n if (!hasLiteral) return { expr: structExpr };\n // Mixed: a dict value dispatches by `@type`; a bare literal is itself.\n return { expr: `(${structExpr} if isinstance(${access}, dict) else str(${access}))` };\n }\n\n const cb = new CodeBuilder(\" \");\n const emitStructDispatch = (): void => {\n structVars.forEach(({ variant, i }, k) => {\n const keyword = k === 0 ? \"if\" : \"elif\";\n cb.line(`${keyword} ${access}[\"@type\"] == ${pyStr(variant.name ?? \"\")}:`);\n cb.indent(() => appendLines(cb, resultToStmt(variants[i]!)));\n });\n };\n if (!hasLiteral) {\n emitStructDispatch();\n return { stmt: cb.toString() };\n }\n // Mixed union: branch on runtime shape (dict -> `@type` dispatch; else a\n // bare literal used directly), mirroring the validator.\n cb.line(`if isinstance(${access}, dict):`);\n cb.indent(emitStructDispatch);\n cb.line(`else:`);\n cb.indent(() => appendLines(cb, resultToStmt({ expr: `str(${access})` })));\n return { stmt: cb.toString() };\n }\n\n return { stmt: variants.map(resultToStmt).join(\"\\n\") };\n}\n","import type { BoundType } from \"../../bindings/index.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport type { SigEntry, SigOptions } from \"../sig-entries.js\";\nimport { snakeCase } from \"../string-case.js\";\nimport { structKey, unionKey } from \"../type-keys.js\";\nimport type { ArgResult } from \"./arg-builder.js\";\nimport { buildArgs, resultToStmt } from \"./arg-builder.js\";\nimport { mapType, pyStr, renderPyLiteral } from \"./typemap.js\";\nimport type { NamedType } from \"./types.js\";\nimport { collectFieldInfo, resolveTypeName } from \"./types.js\";\n\n/**\n * Emit a Python triple-quoted docstring. Single-line if short, multi-line for\n * longer text. Should be placed as the first statement inside a function/class\n * body or as a field doc immediately after the annotation.\n */\nexport function emitDocstring(cb: CodeBuilder, text?: string): void {\n if (!text) return;\n const lines = text.split(\"\\n\");\n if (lines.length === 1 && !lines[0]!.includes('\"')) {\n cb.line(`\"\"\"${lines[0]}\"\"\"`);\n return;\n }\n cb.line(`\"\"\"`);\n for (const line of lines) cb.line(line);\n cb.line(`\"\"\"`);\n}\n\nexport function emitImports(cb: CodeBuilder, emitOutputs: boolean): void {\n cb.line(\"import dataclasses\");\n cb.line(\"import pathlib\");\n cb.line(\"import typing\");\n cb.blank();\n const fromStyxdefs = [\"Execution\", \"InputPathType\", \"Metadata\", \"Runner\", \"StyxValidationError\"];\n if (emitOutputs) fromStyxdefs.push(\"OutputPathType\");\n cb.line(`from styxdefs import ${fromStyxdefs.join(\", \")}, get_global_runner`);\n}\n\nexport function emitMetadata(ctx: CodegenContext, metaConst: string, cb: CodeBuilder): void {\n const id = ctx.app?.id ?? \"unknown\";\n const name = ctx.app?.doc?.title ?? ctx.app?.id ?? \"unknown\";\n const pkg = ctx.package?.name ?? \"unknown\";\n\n cb.line(`${metaConst} = Metadata(`);\n cb.indent(() => {\n cb.line(`id=${pyStr(id)},`);\n cb.line(`name=${pyStr(name)},`);\n cb.line(`package=${pyStr(pkg)},`);\n if (ctx.app?.doc?.literature?.length) {\n cb.line(`citations=[${ctx.app.doc.literature.map(pyStr).join(\", \")}],`);\n }\n if (ctx.app?.container?.image) {\n cb.line(`container_image_tag=${pyStr(ctx.app.container.image)},`);\n }\n });\n cb.line(\")\");\n}\n\n/**\n * Python keywords that would cause a SyntaxError or silent miscompile if used\n * as a class-body annotation key (e.g. `lambda: float` parses as a lambda\n * expression statement, not a TypedDict field). The class-syntax check uses\n * this to force functional syntax for those fields. Builtins like `int`/`str`\n * are NOT in this set - those are valid class attribute names.\n */\nexport const PY_KEYWORDS = new Set([\n \"False\",\n \"None\",\n \"True\",\n \"and\",\n \"as\",\n \"assert\",\n \"async\",\n \"await\",\n \"break\",\n \"class\",\n \"continue\",\n \"def\",\n \"del\",\n \"elif\",\n \"else\",\n \"except\",\n \"finally\",\n \"for\",\n \"from\",\n \"global\",\n \"if\",\n \"import\",\n \"in\",\n \"is\",\n \"lambda\",\n \"nonlocal\",\n \"not\",\n \"or\",\n \"pass\",\n \"raise\",\n \"return\",\n \"try\",\n \"while\",\n \"with\",\n \"yield\",\n]);\n\n/** Can `s` be used as a class-attribute name in a TypedDict class body? */\nfunction isPyIdent(s: string): boolean {\n return /^[A-Za-z_][A-Za-z0-9_]*$/.test(s) && !PY_KEYWORDS.has(s);\n}\n\n/**\n * Emit the python source for one struct as a TypedDict. Uses functional syntax\n * if any field name is not a Python identifier (e.g. `@type` discriminators);\n * otherwise uses class syntax for readability.\n *\n * When `injectAtTypeTag` is given, an `@type: typing.Literal[<tag>]` entry is\n * prepended; used by the root struct of single-tool params, whose tag is\n * derived from `pkg/appId` rather than from the IR.\n */\nfunction emitStructTypedDict(\n name: string,\n type: Extract<BoundType, { kind: \"struct\" }>,\n ctx: CodegenContext,\n resolve: (t: BoundType) => string | undefined,\n cb: CodeBuilder,\n injectAtTypeTag?: string,\n): void {\n const fieldInfo = collectFieldInfo(ctx, type);\n const entries = Object.entries(type.fields);\n // @type literal fields are special: they're not user-provided regular fields\n // but discriminator values. Other literals are skipped (they have no runtime\n // representation in the dict).\n const hasInjectedAtType = injectAtTypeTag !== undefined;\n const hasNonIdentKey =\n hasInjectedAtType ||\n entries.some(([k, v]) => {\n if (v.kind === \"literal\") return k === \"@type\";\n return !isPyIdent(k);\n });\n\n // Compute the typed entry list (skipping non-discriminator literals).\n const typedEntries: Array<{ key: string; type: string; doc?: string }> = [];\n if (injectAtTypeTag !== undefined) {\n // NotRequired: the factory always sets @type and runtime dispatch tables\n // read it, but callers building a dict by hand shouldn't have to type it.\n // (Union variants further down keep their @type required - that one IS\n // load-bearing for discriminated-union narrowing.)\n typedEntries.push({\n key: \"@type\",\n type: `typing.NotRequired[typing.Literal[${pyStr(injectAtTypeTag)}]]`,\n });\n }\n for (const [fieldName, fieldType] of entries) {\n if (fieldType.kind === \"literal\") {\n if (fieldName === \"@type\") {\n const lit =\n typeof fieldType.value === \"string\"\n ? `typing.Literal[${pyStr(fieldType.value)}]`\n : `typing.Literal[${fieldType.value}]`;\n typedEntries.push({ key: fieldName, type: lit });\n }\n continue;\n }\n const fi = fieldInfo.get(fieldName);\n const hasDefault = fi?.defaultValue !== undefined;\n const isOptional = fieldType.kind === \"optional\";\n // The value type is the inner type, never `| None`: the solver has no\n // nullable, so a present value is never None. Omittability (the key may be\n // absent) is expressed structurally via `typing.NotRequired[...]`.\n const inner = isOptional ? fieldType.inner : fieldType;\n let typeExpr = mapType(inner, resolve);\n // A field is omittable iff it is `optional` or it carries a default (which\n // includes flags - `defaultValue` false). Mark omittable fields NotRequired:\n // optional-without-default fields are conditionally set by the factory, and\n // defaulted fields may legitimately be absent in a hand-authored config (the\n // absence-safe runtime reads apply the default). Required-without-default\n // fields stay bare - the factory always writes them.\n if (isOptional || hasDefault) {\n typeExpr = `typing.NotRequired[${typeExpr}]`;\n }\n typedEntries.push({ key: fieldName, type: typeExpr, doc: fi?.doc });\n }\n\n if (hasNonIdentKey) {\n cb.line(`${name} = typing.TypedDict(`);\n cb.indent(() => {\n cb.line(`${pyStr(name)},`);\n cb.line(`{`);\n cb.indent(() => {\n for (const { key, type } of typedEntries) {\n cb.line(`${pyStr(key)}: ${type},`);\n }\n });\n cb.line(`},`);\n });\n cb.line(`)`);\n } else {\n cb.line(`class ${name}(typing.TypedDict):`);\n cb.indent(() => {\n if (typedEntries.length === 0) {\n cb.line(\"pass\");\n return;\n }\n for (const { key, type, doc } of typedEntries) {\n cb.line(`${key}: ${type}`);\n if (doc) emitDocstring(cb, doc);\n }\n });\n }\n}\n\n/** Structural identity key for a NamedType (only structs/unions are collected). */\nfunction declKey(type: BoundType): string | undefined {\n if (type.kind === \"struct\") return structKey(type);\n if (type.kind === \"union\") return unionKey(type);\n return undefined;\n}\n\n/**\n * Collect the keys of every named struct/union directly referenced by `type`'s\n * emitted expression. Wrappers (optional/list) are transparent; a nested\n * struct/union is its own declaration, so we record its key and stop. This is\n * the dependency edge set used to order declarations.\n */\nfunction collectRefs(type: BoundType, namedTypes: Map<string, string>, out: Set<string>): void {\n switch (type.kind) {\n case \"optional\":\n collectRefs(type.inner, namedTypes, out);\n break;\n case \"list\":\n collectRefs(type.item, namedTypes, out);\n break;\n case \"struct\": {\n const k = structKey(type);\n if (namedTypes.has(k)) out.add(k);\n break;\n }\n case \"union\": {\n const k = unionKey(type);\n if (namedTypes.has(k)) out.add(k);\n break;\n }\n default:\n break;\n }\n}\n\n/** Direct named-type dependencies of one declaration (its field/variant types). */\nfunction declDeps(type: BoundType, namedTypes: Map<string, string>): Set<string> {\n const out = new Set<string>();\n if (type.kind === \"struct\") {\n for (const fieldType of Object.values(type.fields)) collectRefs(fieldType, namedTypes, out);\n } else if (type.kind === \"union\") {\n for (const v of type.variants) collectRefs(v.type, namedTypes, out);\n }\n return out;\n}\n\nexport function emitTypeDeclarations(\n typeDecls: NamedType[],\n namedTypes: Map<string, string>,\n ctx: CodegenContext,\n cb: CodeBuilder,\n rootName?: string,\n rootTypeTag?: string,\n): void {\n const resolve = resolveTypeName(namedTypes);\n\n // Python evaluates type expressions eagerly (no hoisting like TS): a name\n // must be defined before any declaration references it. The collector yields\n // types in forward-discovery order (parents before children); the old\n // emission just reversed that, but reverse-discovery breaks for shared types\n // in a DAG - e.g. a union arm discovered deep under the FIRST variant that is\n // also referenced by a LATER sibling arm ends up emitted after its user.\n // Instead, do a real topological sort over the dependency graph (post-order\n // DFS so a type is emitted only after every type it references). Back-edges\n // from a cycle are ignored - the recursion guard breaks them, and recursive\n // descriptor types don't occur in practice.\n const byKey = new Map<string, NamedType>();\n for (const decl of typeDecls) {\n const k = declKey(decl.type);\n if (k !== undefined) byKey.set(k, decl);\n }\n\n const ordered: NamedType[] = [];\n const visited = new Set<string>();\n const onStack = new Set<string>();\n function emitInOrder(key: string): void {\n if (visited.has(key)) return;\n const decl = byKey.get(key);\n if (decl === undefined) return;\n onStack.add(key);\n for (const dep of declDeps(decl.type, namedTypes)) {\n if (!onStack.has(dep)) emitInOrder(dep);\n }\n onStack.delete(key);\n visited.add(key);\n ordered.push(decl);\n }\n // Drive from the original discovery order so independent declarations keep a\n // stable, deterministic relative order.\n for (const decl of typeDecls) {\n const k = declKey(decl.type);\n if (k !== undefined) emitInOrder(k);\n }\n\n for (const { name, type } of ordered) {\n if (type.kind === \"struct\") {\n const inject = name === rootName ? rootTypeTag : undefined;\n emitStructTypedDict(name, type, ctx, resolve, cb, inject);\n cb.blank();\n } else if (type.kind === \"union\") {\n const parts = type.variants.map((v) => mapType(v.type, resolve));\n cb.line(`${name} = ${parts.join(\" | \")}`);\n cb.blank();\n }\n }\n}\n\nexport function emitBuildCargs(\n ctx: CodegenContext,\n rootType: BoundType,\n paramsType: string,\n funcName: string,\n cb: CodeBuilder,\n): void {\n let result: ArgResult;\n try {\n result = buildArgs(ctx.expr, ctx, rootType);\n } catch {\n cb.line(`def ${funcName}(params: ${paramsType}, execution: Execution) -> list[str]:`);\n cb.indent(() => {\n emitDocstring(cb, \"Build command-line arguments from parameters.\");\n cb.line(\"return []\");\n });\n return;\n }\n\n const argsCode = resultToStmt(result);\n\n cb.line(`def ${funcName}(params: ${paramsType}, execution: Execution) -> list[str]:`);\n cb.indent(() => {\n emitDocstring(cb, \"Build command-line arguments from parameters.\");\n cb.line(\"cargs: list[str] = []\");\n for (const line of argsCode.split(\"\\n\")) {\n if (line.trim()) cb.line(line);\n }\n cb.line(\"return cargs\");\n });\n}\n\nexport function emitWrapperFunction(\n ctx: CodegenContext,\n paramsType: string,\n funcName: string,\n metaConst: string,\n cargsFunc: string,\n outputsFunc: string | undefined,\n outputsType: string | undefined,\n validateFunc: string | undefined,\n streams: { stdout?: string; stderr?: string },\n cb: CodeBuilder,\n): void {\n const emitOutputs = outputsFunc !== undefined;\n const appDoc = ctx.app?.doc;\n const returnType = emitOutputs && outputsType ? outputsType : \"None\";\n\n cb.line(`def ${funcName}(params: ${paramsType}, runner: Runner | None = None) -> ${returnType}:`);\n cb.indent(() => {\n cb.line('\"\"\"');\n let hasContent = false;\n if (appDoc?.title) {\n cb.line(appDoc.title);\n hasContent = true;\n }\n if (appDoc?.description) {\n if (hasContent) cb.blank();\n cb.line(appDoc.description);\n hasContent = true;\n }\n if (appDoc?.authors?.length) {\n if (hasContent) cb.blank();\n cb.line(`Author: ${appDoc.authors.join(\", \")}`);\n hasContent = true;\n }\n if (appDoc?.urls?.length) {\n if (hasContent) cb.blank();\n cb.line(`URL: ${appDoc.urls[0]}`);\n hasContent = true;\n }\n if (hasContent) cb.blank();\n cb.line(\"Args:\");\n cb.line(\" params: The parameters.\");\n cb.line(\" runner: Command runner (defaults to global runner).\");\n cb.blank();\n cb.line(\"Returns:\");\n cb.line(emitOutputs ? \" Tool outputs (paths to files produced by the tool).\" : \" None.\");\n cb.line('\"\"\"');\n // Validate the params dict first (the kwarg wrapper delegates here, so it\n // gets validation transitively; the statically-typed kwargs don't need it).\n if (validateFunc) cb.line(`${validateFunc}(params)`);\n cb.line(\"runner = runner if runner is not None else get_global_runner()\");\n cb.line(`execution = runner.start_execution(${metaConst})`);\n cb.line(\"execution.params(params)\");\n // Local names `args`/`out` avoid colliding with the module-level `cargs`\n // and `outputs` functions when they share generic names.\n cb.line(`args = ${cargsFunc}(params, execution)`);\n if (emitOutputs) {\n cb.line(`out = ${outputsFunc}(params, execution)`);\n const handlers: string[] = [];\n if (streams.stdout) handlers.push(`handle_stdout=lambda s: out.${streams.stdout}.append(s)`);\n if (streams.stderr) handlers.push(`handle_stderr=lambda s: out.${streams.stderr}.append(s)`);\n cb.line(`execution.run(args${handlers.length ? \", \" + handlers.join(\", \") : \"\"})`);\n cb.line(\"return out\");\n } else {\n cb.line(\"execution.run(args)\");\n }\n });\n}\n\n/** Convenience: derive a snake_case function name from the app id. */\nexport function appFuncName(ctx: CodegenContext, fallback: string): string {\n return snakeCase(ctx.app?.id ?? fallback);\n}\n\n/**\n * SigOptions hooks for Python. The kwarg-signature sentinel for an optional\n * param is `T | None = None` - here `| None` is the *parameter* type (the\n * \"not provided\" sentinel a caller passes), not the dict field type, which is\n * just `typing.NotRequired[T]`. Keeping the sentinel preserves the ergonomic\n * `foo(x)` call where omitted optionals default to `None` and the factory then\n * drops them.\n */\nexport function pySigOptions(resolve: (t: BoundType) => string | undefined): SigOptions {\n return {\n renderType: (t) => mapType(t, resolve),\n nullableSuffix: \" | None\",\n nullableDefault: \"None\",\n renderDefault: renderPyLiteral,\n };\n}\n\n/**\n * Scrub a Boutiques wire name into a valid Python host identifier. Replaces\n * any non-`[A-Za-z0-9_]` character with `_`; prefixes `v_` if the result\n * starts with a digit; appends a single trailing underscore when the scrubbed\n * name matches a reserved word or shadowed built-in (matching v1 niwrap's\n * `float_:` style). The caller is responsible for further deduping the result\n * through a `Scope` so collisions with already-registered locals don't slip\n * through.\n */\nexport function pyScrubIdent(name: string, reserved: ReadonlySet<string>): string {\n let scrubbed = name.replace(/[^A-Za-z0-9_]/g, \"_\");\n if (/^[0-9]/.test(scrubbed)) scrubbed = \"v_\" + scrubbed;\n if (scrubbed === \"\") scrubbed = \"_\";\n if (reserved.has(scrubbed)) scrubbed = scrubbed + \"_\";\n return scrubbed;\n}\n\n/** Emit a sequence of `name: type [= default],` lines (one per entry) into `cb`. */\nfunction emitSigParams(entries: readonly SigEntry[], cb: CodeBuilder): void {\n for (const e of entries) {\n if (e.sigDefault !== undefined) {\n cb.line(`${e.name}: ${e.sigType} = ${e.sigDefault},`);\n } else {\n cb.line(`${e.name}: ${e.sigType},`);\n }\n }\n}\n\n/**\n * Word-wrap a Google-style \"Args:\" entry. Produces lines like\n * `name: description that continues...\\`\n * ` until it ends here.`\n * The first line is prefixed with `<indent><name>: `; continuations use\n * `<indent> ` (4 spaces deeper). Lines that exceed `lineWidth` end with a\n * `\\` continuation marker.\n */\nfunction wrapDocEntry(name: string, doc: string, indent: string, lineWidth = 80): string[] {\n const firstPrefix = `${indent}${name}: `;\n const contPrefix = `${indent} `;\n const words = doc.split(/\\s+/).filter((w) => w.length > 0);\n if (words.length === 0) return [`${firstPrefix.trimEnd()}`];\n\n const lines: string[] = [];\n let current = firstPrefix + words[0]!;\n for (let i = 1; i < words.length; i++) {\n const word = words[i]!;\n if (current.length + 1 + word.length + 1 > lineWidth) {\n lines.push(current + \"\\\\\");\n current = contPrefix + word;\n } else {\n current += \" \" + word;\n }\n }\n lines.push(current);\n return lines;\n}\n\n/** Emit the per-field `Args:` block for a docstring. Caller is already at the\n * correct indent (i.e. inside the function body). */\nfunction emitArgsBlock(entries: readonly { name: string; doc?: string }[], cb: CodeBuilder): void {\n cb.line(\"Args:\");\n for (const e of entries) {\n for (const ln of wrapDocEntry(e.name, e.doc ?? \"\", \" \")) cb.line(ln);\n }\n}\n\n/**\n * Emit the `_params(...)` factory: a kwarg-style function that builds and\n * returns the params dict (with `@type` injected). Non-optional fields (required,\n * and defaulted scalars whose default lives on the signature) are always set in\n * the literal. Every optional field is set conditionally when not None -\n * including optional-with-default ones: their value type is `T | None` (the omit\n * sentinel) but the dict field is the non-None `NotRequired[T]`, so a bare\n * literal assignment of a possibly-None value would not type-check. When the\n * caller omits the arg, the signature default (a concrete non-None value) flows\n * through the guard and is written.\n */\nexport function emitParamsFactory(\n entries: readonly SigEntry[],\n funcName: string,\n paramsType: string,\n typeTag: string | undefined,\n cb: CodeBuilder,\n): void {\n // Signature\n if (entries.length === 0) {\n cb.line(`def ${funcName}() -> ${paramsType}:`);\n } else {\n cb.line(`def ${funcName}(`);\n cb.indent(() => emitSigParams(entries, cb));\n cb.line(`) -> ${paramsType}:`);\n }\n\n cb.indent(() => {\n // Docstring\n cb.line('\"\"\"');\n cb.line(\"Build parameters.\");\n if (entries.length > 0) {\n cb.blank();\n emitArgsBlock(entries, cb);\n }\n cb.blank();\n cb.line(\"Returns:\");\n cb.line(\" Parameter dictionary.\");\n cb.line('\"\"\"');\n\n // Build dict: required and explicitly-defaulted fields go into the literal\n cb.line(`params: ${paramsType} = {`);\n cb.indent(() => {\n if (typeTag !== undefined) cb.line(`\"@type\": ${pyStr(typeTag)},`);\n for (const e of entries) {\n if (!e.isOptional) {\n cb.line(`${pyStr(e.wireKey)}: ${e.name},`);\n }\n }\n });\n cb.line(\"}\");\n\n // Conditional include for every optional field (its kwarg default supplies a\n // non-None value when the caller omits the arg).\n for (const e of entries) {\n if (e.isOptional) {\n cb.line(`if ${e.name} is not None:`);\n cb.indent(() => cb.line(`params[${pyStr(e.wireKey)}] = ${e.name}`));\n }\n }\n cb.line(\"return params\");\n });\n}\n\n/**\n * Emit the user-facing kwarg wrapper: takes the same kwargs as `_params()`\n * plus `runner`, builds the params dict, and delegates to the dict-style\n * execute function.\n */\nexport function emitKwargWrapper(\n ctx: CodegenContext,\n entries: readonly SigEntry[],\n funcName: string,\n paramsFnName: string,\n executeFnName: string,\n outputsType: string | undefined,\n cb: CodeBuilder,\n): void {\n // Signature: same as params factory + `runner` last\n cb.line(`def ${funcName}(`);\n cb.indent(() => {\n emitSigParams(entries, cb);\n cb.line(\"runner: Runner | None = None,\");\n });\n const returnType = outputsType ?? \"None\";\n cb.line(`) -> ${returnType}:`);\n\n cb.indent(() => {\n // Docstring: app title/description + per-field docs + runner + Returns.\n const appDoc = ctx.app?.doc;\n cb.line('\"\"\"');\n if (appDoc?.title) cb.line(appDoc.title);\n if (appDoc?.description) {\n if (appDoc?.title) cb.blank();\n cb.line(appDoc.description);\n }\n if (appDoc?.authors?.length) {\n cb.blank();\n cb.line(`Author: ${appDoc.authors.join(\", \")}`);\n }\n if (appDoc?.urls?.length) {\n cb.blank();\n cb.line(`URL: ${appDoc.urls[0]}`);\n }\n cb.blank();\n emitArgsBlock(\n [...entries, { name: \"runner\", doc: \"Command runner (defaults to global runner).\" }],\n cb,\n );\n cb.blank();\n cb.line(\"Returns:\");\n cb.line(outputsType ? \" Tool outputs (paths to files produced by the tool).\" : \" None.\");\n cb.line('\"\"\"');\n\n // Body: delegate to factory + execute\n if (entries.length === 0) {\n cb.line(`params = ${paramsFnName}()`);\n } else {\n cb.line(`params = ${paramsFnName}(`);\n cb.indent(() => {\n for (const e of entries) cb.line(`${e.name}=${e.name},`);\n });\n cb.line(\")\");\n }\n if (outputsType) {\n cb.line(`return ${executeFnName}(params, runner)`);\n } else {\n cb.line(`${executeFnName}(params, runner)`);\n }\n });\n}\n","import type { BoundType } from \"../bindings/index.js\";\nimport type { Expr, Float, Int, Repeat } from \"../ir/index.js\";\nimport type { CodegenContext } from \"../manifest/index.js\";\nimport { collectFieldInfo } from \"./collect-field-info.js\";\nimport { findStructNode } from \"./find-struct-node.js\";\nimport { resolveFieldBinding } from \"./resolve-field-binding.js\";\n\n/**\n * Shared, language-agnostic tree-walk helpers for validation emit.\n *\n * Validation walks the solved root `BoundType` for the data shape, but the\n * runtime constraints it checks (int/float range, list length) live on the\n * underlying IR nodes, not the `BoundType`. These helpers bridge the two: they\n * map a struct's fields to their IR binding nodes and locate the IR node that\n * carries a given constraint within a field's subtree.\n */\n\n/** A struct field paired with its BoundType and (when resolvable) its IR node. */\nexport interface FieldEntry {\n name: string;\n type: BoundType;\n /** The IR node the field's binding was solved from. `undefined` if it could\n * not be resolved (constraint lookups then degrade gracefully). */\n node: Expr | undefined;\n /**\n * Whether the field has a default value. Such fields (and flags) accept\n * `None`/`null` to mean \"use the default\", so validation gates them like\n * optionals rather than requiring presence - matching v1 niwrap.\n */\n hasDefault: boolean;\n}\n\n/**\n * Enumerate a struct type's fields in declaration order, each paired with the\n * IR node its binding resolved from. `searchRoot` is the IR subtree known to\n * contain the struct (the root expr for the top-level struct, or a field /\n * union-arm node for nested ones).\n */\nexport function structFields(\n ctx: CodegenContext,\n structType: Extract<BoundType, { kind: \"struct\" }>,\n searchRoot: Expr | undefined,\n): FieldEntry[] {\n const nodeByName = new Map<string, Expr>();\n if (searchRoot) {\n const structNode = findStructNode(searchRoot, ctx, structType);\n if (structNode) {\n for (const child of structNode.attrs.nodes) {\n const match = resolveFieldBinding(child, ctx, structType);\n if (match) nodeByName.set(match.binding.name, match.binding.node);\n }\n }\n }\n const fieldInfo = collectFieldInfo(ctx, structType);\n return Object.entries(structType.fields).map(([name, type]) => ({\n name,\n type,\n node: nodeByName.get(name),\n hasDefault: fieldInfo.get(name)?.defaultValue !== undefined,\n }));\n}\n\n/**\n * Depth-first search for the first node satisfying `pred`, descending through\n * the transparent structural wrappers the solver may bury a binding under\n * (sequence/optional/repeat/alternative).\n */\nexport function findNode(node: Expr | undefined, pred: (n: Expr) => boolean): Expr | undefined {\n if (!node) return undefined;\n if (pred(node)) return node;\n switch (node.kind) {\n case \"sequence\":\n for (const child of node.attrs.nodes) {\n const r = findNode(child, pred);\n if (r) return r;\n }\n return undefined;\n case \"optional\":\n return findNode(node.attrs.node, pred);\n case \"repeat\":\n return findNode(node.attrs.node, pred);\n case \"alternative\":\n for (const alt of node.attrs.alts) {\n const r = findNode(alt, pred);\n if (r) return r;\n }\n return undefined;\n default:\n return undefined;\n }\n}\n\n/** Locate the int/float node carrying a scalar field's numeric range. */\nexport function findRangeNode(node: Expr | undefined): Int | Float | undefined {\n const found = findNode(node, (n) => n.kind === \"int\" || n.kind === \"float\");\n return found as Int | Float | undefined;\n}\n\n/** Locate the repeat node carrying a list field's length bounds and item. */\nexport function findRepeatNode(node: Expr | undefined): Repeat | undefined {\n const found = findNode(node, (n) => n.kind === \"repeat\");\n return found as Repeat | undefined;\n}\n\n/** Locate the alternative node backing a union field, to map arms to variants. */\nexport function findAlternativeNode(\n node: Expr | undefined,\n): Extract<Expr, { kind: \"alternative\" }> | undefined {\n const found = findNode(node, (n) => n.kind === \"alternative\");\n return found as Extract<Expr, { kind: \"alternative\" }> | undefined;\n}\n","import type { BoundType } from \"../../bindings/index.js\";\nimport type { Expr } from \"../../ir/index.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport type { CodeBuilder } from \"../code-builder.js\";\nimport type { Scope } from \"../scope.js\";\nimport {\n findAlternativeNode,\n findRangeNode,\n findRepeatNode,\n structFields,\n} from \"../validate-walk.js\";\nimport { structVariants } from \"../union-variants.js\";\nimport { emitDocstring } from \"./emit.js\";\nimport { mapType, pyStr } from \"./typemap.js\";\n\n/**\n * Emit a `<tool>_validate(params)` function that walks the solved root\n * `BoundType` and raises `StyxValidationError` on invalid input. Mirrors the\n * runtime validation v1 niwrap emits, but as a single inlined function (the v2\n * backends inline `_cargs`/`_outputs` too, rather than v1's per-struct\n * dispatch).\n *\n * Constraints checked: presence (required fields), `isinstance`, int/float\n * range, list length, union `@type` membership + per-variant recursion, and\n * nested struct recursion.\n */\n\ntype Resolve = (t: BoundType) => string | undefined;\n\ninterface Emit {\n ctx: CodegenContext;\n resolve: Resolve;\n /** Per-function scope for generated locals (loop vars), reserving `params`. */\n scope: Scope;\n cb: CodeBuilder;\n}\n\nexport function emitValidate(\n ctx: CodegenContext,\n rootType: BoundType,\n rootNode: Expr,\n paramsType: string,\n funcName: string,\n resolve: Resolve,\n scope: Scope,\n cb: CodeBuilder,\n): void {\n const e: Emit = { ctx, resolve, scope: scope.child([\"params\"]), cb };\n // Untyped input: a boundary guard usable on a parsed dict / config blob, not\n // just an already-typed value (mirrors styx v1's `typing.Any` validator).\n cb.line(`def ${funcName}(params: typing.Any) -> None:`);\n cb.indent(() => {\n emitDocstring(\n cb,\n `Validate untrusted parameters. Raises StyxValidationError if \\`params\\` is not a valid ${paramsType}.`,\n );\n emitRoot(e, rootType, rootNode);\n });\n}\n\nfunction emitRoot(e: Emit, rootType: BoundType, rootNode: Expr): void {\n if (rootType.kind === \"struct\") {\n e.cb.line(\"if params is None or not isinstance(params, dict):\");\n e.cb.indent(() => raise(e, wrongObjectTypeMsg(\"params\")));\n for (const f of structFields(e.ctx, rootType, rootNode)) {\n emitField(e, f.name, f.type, f.node, f.hasDefault, \"params\");\n }\n } else if (rootType.kind === \"union\") {\n emitUnion(e, rootType, rootNode, \"params\", \"params\");\n } else {\n emitValue(e, rootType, rootNode, \"params\", \"params\", expectedType(e, rootType));\n }\n}\n\n/** Validate one struct field, handling required-presence vs optional gating. */\nfunction emitField(\n e: Emit,\n name: string,\n fieldType: BoundType,\n node: Expr | undefined,\n hasDefault: boolean,\n base: string,\n): void {\n // `@type` and other fixed literals have no user-supplied runtime value.\n if (fieldType.kind === \"literal\") return;\n\n const getExpr = `${base}.get(${pyStr(name)}, None)`;\n const idxExpr = `${base}[${pyStr(name)}]`;\n const expected = expectedType(e, fieldType);\n const valueType = fieldType.kind === \"optional\" ? fieldType.inner : fieldType;\n\n // Optionals and defaulted fields/flags accept None (None = \"use default\"), so\n // gate the body instead of requiring presence.\n if (fieldType.kind === \"optional\" || hasDefault) {\n e.cb.line(`if ${getExpr} is not None:`);\n e.cb.indent(() => emitValue(e, valueType, node, name, idxExpr, expected));\n } else {\n e.cb.line(`if ${getExpr} is None:`);\n e.cb.indent(() => raise(e, str(\"`\" + name + \"` must not be None\")));\n emitValue(e, valueType, node, name, idxExpr, expected);\n }\n}\n\n/** Validate a known-non-null value at `valueExpr` against `type`. */\nfunction emitValue(\n e: Emit,\n type: BoundType,\n node: Expr | undefined,\n wireKey: string,\n valueExpr: string,\n expected: string,\n): void {\n switch (type.kind) {\n case \"optional\":\n emitValue(e, type.inner, node, wireKey, valueExpr, expected);\n return;\n case \"literal\":\n return;\n case \"scalar\":\n switch (type.scalar) {\n case \"str\":\n checkType(e, valueExpr, \"str\", wireKey, expected);\n return;\n case \"int\":\n checkType(e, valueExpr, \"int\", wireKey, expected);\n emitRange(e, node, wireKey, valueExpr);\n return;\n case \"float\":\n checkType(e, valueExpr, \"(float, int)\", wireKey, expected);\n emitRange(e, node, wireKey, valueExpr);\n return;\n case \"path\":\n checkType(e, valueExpr, \"(pathlib.Path, str)\", wireKey, expected);\n return;\n }\n return;\n case \"bool\":\n checkType(e, valueExpr, \"bool\", wireKey, expected);\n return;\n case \"count\":\n checkType(e, valueExpr, \"int\", wireKey, expected);\n return;\n case \"list\": {\n checkType(e, valueExpr, \"list\", wireKey, expected);\n emitListLength(e, node, wireKey, valueExpr);\n const itemNode = findRepeatNode(node)?.attrs.node;\n const elem = e.scope.add(\"e\");\n e.cb.line(`for ${elem} in ${valueExpr}:`);\n e.cb.indent(() => emitValue(e, type.item, itemNode, wireKey, elem, expected));\n return;\n }\n case \"struct\": {\n e.cb.line(`if not isinstance(${valueExpr}, dict):`);\n e.cb.indent(() => raise(e, wrongObjectTypeMsg(valueExpr)));\n for (const f of structFields(e.ctx, type, node)) {\n emitField(e, f.name, f.type, f.node, f.hasDefault, valueExpr);\n }\n return;\n }\n case \"union\":\n emitUnion(e, type, node, wireKey, valueExpr);\n return;\n }\n}\n\nfunction emitUnion(\n e: Emit,\n unionType: Extract<BoundType, { kind: \"union\" }>,\n node: Expr | undefined,\n wireKey: string,\n valueExpr: string,\n): void {\n const litVariants = unionType.variants.filter((v) => v.type.kind === \"literal\");\n const hasStruct = unionType.variants.some((v) => v.type.kind === \"struct\");\n\n // Pure enum/choice: no struct variants, just literal values (no `@type`).\n if (!hasStruct) {\n const values = litVariants.map(\n (v) => (v.type as Extract<BoundType, { kind: \"literal\" }>).value,\n );\n const allStr = values.every((x) => typeof x === \"string\");\n checkType(e, valueExpr, allStr ? \"str\" : \"(float, int)\", wireKey, expectedType(e, unionType));\n emitLiteralMembership(e, values, wireKey, valueExpr);\n return;\n }\n\n const altNode = findAlternativeNode(node);\n // Struct variants with their indices; throws if two share an `@type` (a\n // duplicate-tagged variant is unreachable and a mypy `comparison-overlap` -\n // frontends must dodge duplicate tags before codegen). The index keeps each\n // arm aligned with the IR `alts`.\n const structVars = structVariants(unionType);\n const emitStructArm = (): void => {\n // `valueExpr` is known to be a dict here.\n e.cb.line(`if \"@type\" not in ${valueExpr}:`);\n e.cb.indent(() => raise(e, str(\"Params object is missing `@type`\")));\n const names = structVars\n .map(({ variant }) => variant.name)\n .filter((n): n is string => n !== undefined)\n .map((n) => pyStr(n))\n .join(\", \");\n e.cb.line(`if ${valueExpr}[\"@type\"] not in [${names}]:`);\n e.cb.indent(() =>\n raise(e, str(\"Parameter `\" + wireKey + \"`s `@type` must be one of [\" + names + \"]\")),\n );\n structVars.forEach(({ variant, i }, k) => {\n const vt = variant.type as Extract<BoundType, { kind: \"struct\" }>;\n const keyword = k === 0 ? \"if\" : \"elif\";\n e.cb.line(`${keyword} ${valueExpr}[\"@type\"] == ${pyStr(variant.name ?? \"\")}:`);\n e.cb.indent(() => {\n const fields = structFields(e.ctx, vt, altNode?.attrs.alts[i]).filter(\n (f) => f.type.kind !== \"literal\",\n );\n if (fields.length === 0) {\n e.cb.line(\"pass\");\n } else {\n for (const f of fields) emitField(e, f.name, f.type, f.node, f.hasDefault, valueExpr);\n }\n });\n });\n };\n\n // Pure discriminated union: every variant is a struct with an `@type`.\n if (litVariants.length === 0) {\n e.cb.line(`if not isinstance(${valueExpr}, dict):`);\n e.cb.indent(() => raise(e, wrongObjectTypeMsg(valueExpr)));\n emitStructArm();\n return;\n }\n\n // Mixed union: a value is either a struct (dict with `@type`) or a bare\n // literal. Branch on the runtime shape.\n e.cb.line(`if isinstance(${valueExpr}, dict):`);\n e.cb.indent(emitStructArm);\n e.cb.line(\"else:\");\n e.cb.indent(() => {\n const values = litVariants.map(\n (v) => (v.type as Extract<BoundType, { kind: \"literal\" }>).value,\n );\n emitLiteralMembership(e, values, wireKey, valueExpr);\n });\n}\n\n/** Emit a `not in [...]` membership check over literal values. */\nfunction emitLiteralMembership(\n e: Emit,\n values: (string | number)[],\n wireKey: string,\n valueExpr: string,\n): void {\n const rendered = values.map((x) => (typeof x === \"string\" ? pyStr(x) : pyNum(x))).join(\", \");\n e.cb.line(`if ${valueExpr} not in [${rendered}]:`);\n e.cb.indent(() => raise(e, str(\"Parameter `\" + wireKey + \"` must be one of [\" + rendered + \"]\")));\n}\n\nfunction checkType(\n e: Emit,\n valueExpr: string,\n pyType: string,\n wireKey: string,\n expected: string,\n): void {\n e.cb.line(`if not isinstance(${valueExpr}, ${pyType}):`);\n e.cb.indent(() => raise(e, wrongTypeMsg(wireKey, valueExpr, expected)));\n}\n\nfunction emitRange(e: Emit, node: Expr | undefined, wireKey: string, valueExpr: string): void {\n const term = findRangeNode(node);\n if (!term) return;\n const { minValue, maxValue } = term.attrs;\n if (minValue !== undefined && maxValue !== undefined) {\n e.cb.line(`if not (${pyNum(minValue)} <= ${valueExpr} <= ${pyNum(maxValue)}):`);\n e.cb.indent(() =>\n raise(\n e,\n str(`Parameter \\`${wireKey}\\` must be between ${minValue} and ${maxValue} (inclusive)`),\n ),\n );\n } else if (minValue !== undefined) {\n e.cb.line(`if ${valueExpr} < ${pyNum(minValue)}:`);\n e.cb.indent(() => raise(e, str(`Parameter \\`${wireKey}\\` must be at least ${minValue}`)));\n } else if (maxValue !== undefined) {\n e.cb.line(`if ${valueExpr} > ${pyNum(maxValue)}:`);\n e.cb.indent(() => raise(e, str(`Parameter \\`${wireKey}\\` must be at most ${maxValue}`)));\n }\n}\n\nfunction emitListLength(e: Emit, node: Expr | undefined, wireKey: string, valueExpr: string): void {\n const rep = findRepeatNode(node);\n if (!rep) return;\n const { countMin, countMax } = rep.attrs;\n if (countMin !== undefined && countMax !== undefined) {\n e.cb.line(`if not (${countMin} <= len(${valueExpr}) <= ${countMax}):`);\n e.cb.indent(() =>\n raise(\n e,\n str(\n `Parameter \\`${wireKey}\\` must contain between ${countMin} and ${countMax} elements (inclusive)`,\n ),\n ),\n );\n } else if (countMin !== undefined) {\n e.cb.line(`if len(${valueExpr}) < ${countMin}:`);\n e.cb.indent(() =>\n raise(\n e,\n str(\n `Parameter \\`${wireKey}\\` must contain at least ${countMin} ${plural(\"element\", countMin)}`,\n ),\n ),\n );\n } else if (countMax !== undefined) {\n e.cb.line(`if len(${valueExpr}) > ${countMax}:`);\n e.cb.indent(() =>\n raise(\n e,\n str(\n `Parameter \\`${wireKey}\\` must contain at most ${countMax} ${plural(\"element\", countMax)}`,\n ),\n ),\n );\n }\n}\n\n// -- Message + literal rendering --\n\nfunction raise(e: Emit, messageExpr: string): void {\n e.cb.line(`raise StyxValidationError(${messageExpr})`);\n}\n\n/** A plain double-quoted Python string message. */\nfunction str(text: string): string {\n return pyStr(text);\n}\n\n/** A single-quoted f-string \"wrong type\" message referencing the runtime type. */\nfunction wrongTypeMsg(wireKey: string, valueExpr: string, expected: string): string {\n return `f'\\`${wireKey}\\` has the wrong type: Received \\`{type(${valueExpr})}\\` expected \\`${expected}\\`'`;\n}\n\n/** The generic \"Params object has the wrong type\" f-string message. */\nfunction wrongObjectTypeMsg(valueExpr: string): string {\n return `f'Params object has the wrong type \\\\'{type(${valueExpr})}\\\\''`;\n}\n\nfunction expectedType(e: Emit, type: BoundType): string {\n return mapType(type, e.resolve);\n}\n\nfunction pyNum(n: number): string {\n return Number.isFinite(n) ? String(n) : \"float('nan')\";\n}\n\nfunction plural(word: string, count: number): string {\n return count === 1 ? word : `${word}s`;\n}\n","import type { BindingId, GateAtom, ResolvedOutput } from \"../bindings/index.js\";\nimport { outputGate } from \"../bindings/index.js\";\nimport type { Documentation, Expr } from \"../ir/index.js\";\nimport type { CodegenContext } from \"../manifest/index.js\";\n\n/**\n * Language-agnostic collection of a tool's Outputs object: the set of output\n * files it produces (resolved outputs + mutable inputs surfaced as outputs)\n * plus its captured stdout/stderr streams. Both the Python and TypeScript\n * backends, and the JSON Schema backend, consume this single source of truth so\n * the three describe the same Outputs shape (previously this logic was\n * near-duplicated between the two `outputs-emit.ts` files). Identifier\n * sanitization is the one language-specific concern, so callers pass an `idOf`\n * mapping a raw output name to their target language's field identifier; the\n * dedup space is keyed by that id, matching each backend's own field set.\n */\n\n/**\n * A `ResolvedOutput` plus a `mutable` marker. A mutable input file is surfaced\n * as an output: its single ref token points at the input binding, and the\n * backend emits a writable-copy call (`mutable_copy` / `mutableCopy`) - the\n * host path of the copy the runner staged for the matching mutable input -\n * instead of `output_file` / `outputFile`.\n */\nexport type EmittedOutput = ResolvedOutput & { mutable?: boolean };\n\n/**\n * The synthetic `root` output: the runner's output directory itself, surfaced as\n * an always-present, non-gated `OutputPathType` field. Modeled as a regular\n * `ResolvedOutput` with a single literal `\".\"` token so it flows through the\n * exact same collection and emit machinery as every declared output - its empty\n * gate makes it a required single, rendered as `output_file(\".\")` /\n * `outputFile(\".\")`. Because every tool emits it, every tool returns a\n * non-empty Outputs object (matching styx v1, which always carried `root`).\n */\nexport function rootOutput(ctx: CodegenContext, idOf: (name: string) => string): EmittedOutput {\n // Reserve a non-colliding field id. If a tool genuinely declares an output (or\n // a mutable input surfaced as an output) whose id sanitizes to \"root\", the\n // synthetic output-dir field dodges with a trailing \"_\" so it never silently\n // clobbers that real output (or flips it optional via shape merging).\n const taken = new Set<string>();\n for (const scope of ctx.outputScopes) for (const o of scope.outputs) taken.add(idOf(o.name));\n for (const o of collectMutableOutputs(ctx)) taken.add(idOf(o.name));\n let name = \"root\";\n while (taken.has(idOf(name))) name += \"_\";\n return { name, tokens: [{ kind: \"literal\", value: \".\" }] };\n}\n\n/**\n * Field shape for a single resolved output.\n *\n * - `single`: emitted at most once. Optional iff any `present`/`variant` atom\n * appears in the gate (the value may be absent under that gate).\n * - `list`: emitted once per element of an iterated binding (any `iter` atom in\n * the gate). A gated list still types as a list - the empty list stands for\n * \"nothing produced\".\n */\nexport type OutputShape = { kind: \"single\"; optional: boolean } | { kind: \"list\" };\n\nexport function outputShape(gate: GateAtom[]): OutputShape {\n const iter = gate.some((a) => a.kind === \"iter\");\n if (iter) return { kind: \"list\" };\n const optional = gate.some((a) => a.kind === \"present\" || a.kind === \"variant\");\n return { kind: \"single\", optional };\n}\n\n/**\n * Merge two shapes for outputs that share a field name across scopes/variants.\n * Any iterated contributor makes the field a list; otherwise it is a single\n * field that is optional if any contributor is gated.\n */\nexport function mergeShape(a: OutputShape, b: OutputShape): OutputShape {\n if (a.kind === \"list\" || b.kind === \"list\") return { kind: \"list\" };\n return { kind: \"single\", optional: a.optional || b.optional };\n}\n\n/** One collected Outputs field, deduped across same-named outputs. */\nexport interface OutputField {\n /** Backend-sanitized field identifier (via the caller's `idOf`). */\n id: string;\n /** First-seen raw output name (the descriptor's output id). */\n name: string;\n shape: OutputShape;\n doc?: string;\n}\n\n/**\n * Collect the unique Outputs fields in first-seen order, merging the shape and\n * doc of any outputs that resolve to the same field id. Multiple scopes (e.g.\n * the arms of a union output) routinely declare the same output name; without\n * deduping a backend would emit duplicate fields (a Python SyntaxError, a TS\n * duplicate member). `idOf` maps a raw output name to the target language's\n * sanitized identifier, so two raw names that collapse to the same identifier\n * merge into one field - exactly the field set the backend will emit.\n */\nexport function collectOutputFields(\n ctx: CodegenContext,\n idOf: (name: string) => string,\n): OutputField[] {\n const byId = new Map<string, OutputField>();\n const add = (output: EmittedOutput, scopeGate: GateAtom[]): void => {\n const gate = outputGate(scopeGate, output, ctx.bindings);\n const shape = outputShape(gate);\n const id = idOf(output.name);\n const doc = output.doc?.description ?? output.doc?.title;\n const existing = byId.get(id);\n if (existing) {\n existing.shape = mergeShape(existing.shape, shape);\n if (!existing.doc && doc) existing.doc = doc;\n } else {\n byId.set(id, { id, name: output.name, shape, doc });\n }\n };\n // The output directory itself, always present and ungated, listed first.\n add(rootOutput(ctx, idOf), []);\n for (const scope of ctx.outputScopes) {\n const scopeBinding = ctx.bindings.get(scope.scope);\n const scopeGate = scopeBinding?.gate ?? [];\n for (const output of scope.outputs) add(output, scopeGate);\n }\n // Mutable inputs surface as outputs; their binding gate is absolute (rooted),\n // so the scope gate is empty.\n for (const output of collectMutableOutputs(ctx)) add(output, []);\n return [...byId.values()];\n}\n\n/** Has any scope in the context attached at least one output? */\nexport function hasAnyOutputs(ctx: CodegenContext): boolean {\n return ctx.outputScopes.some((s) => s.outputs.length > 0);\n}\n\n/** A captured stream (stdout/stderr), surfaced as a list-of-lines Outputs field. */\nexport interface StreamField {\n /** First-seen raw stream name, bumped with a trailing `_` to dodge collisions. */\n name: string;\n /** Backend-sanitized identifier for `name` (via the caller's `idOf`). */\n id: string;\n doc?: string;\n}\n\n/**\n * The stdout/stderr fields declared by the app metadata, in declaration order\n * (stdout before stderr). Stream outputs are app-level: never gated (always\n * present when the tool runs), so they bypass the solver/gating machinery and\n * surface as plain list-of-string fields the wrapper appends to via the\n * `handle_stdout` / `handle_stderr` (Python) or `handleStdout` / `handleStderr`\n * (TS) callbacks. A stream whose sanitized id collides with a real output's id\n * is bumped (raw name gains a trailing `_`, re-sanitized) so it never shadows a\n * file output / emits a duplicate field.\n */\nexport function streamFields(ctx: CodegenContext, idOf: (name: string) => string): StreamField[] {\n const out: StreamField[] = [];\n // Seed with the file/mutable output field ids so a stream whose name collides\n // with a real output (e.g. an output literally named \"stdout\") is bumped\n // rather than emitting a duplicate field / repeated constructor argument.\n const used = new Set<string>(collectOutputFields(ctx, idOf).map((f) => f.id));\n const add = (rawName: string, doc?: string): void => {\n let name = rawName;\n while (used.has(idOf(name))) name += \"_\";\n used.add(idOf(name));\n out.push({ name, id: idOf(name), doc });\n };\n const so = ctx.app?.stdout;\n const se = ctx.app?.stderr;\n if (so) add(so.name, so.doc?.description ?? so.doc?.title);\n if (se) add(se.name, se.doc?.description ?? se.doc?.title);\n return out;\n}\n\n/** Does the app declare any stdout/stderr stream output? */\nexport function hasStreamOutputs(ctx: CodegenContext): boolean {\n return !!(ctx.app?.stdout || ctx.app?.stderr);\n}\n\n/**\n * Synthesize one output per mutable file input. Each is a `ResolvedOutput` with\n * a single ref token to the input binding and the `mutable` marker. The input\n * binding's solver-assigned gate fully encodes its ancestry (optional/variant/\n * iterated), so `outputGate([], ...)` yields the correct shape and gating for\n * free - no scope bucket needed.\n */\nexport function collectMutableOutputs(ctx: CodegenContext): EmittedOutput[] {\n const out: EmittedOutput[] = [];\n const seen = new Set<BindingId>();\n const walk = (node: Expr, inheritedDoc?: Documentation): void => {\n if (node.kind === \"path\") {\n if (node.attrs.mutable) {\n const binding = ctx.resolve(node);\n if (binding && !seen.has(binding.id)) {\n seen.add(binding.id);\n const doc = node.meta?.doc ?? inheritedDoc;\n out.push({\n name: binding.name,\n tokens: [{ kind: \"ref\", binding: binding.id }],\n ...(doc && { doc }),\n mutable: true,\n });\n }\n }\n return;\n }\n switch (node.kind) {\n case \"sequence\":\n for (const child of node.attrs.nodes) walk(child);\n break;\n case \"optional\":\n case \"repeat\":\n walk(node.attrs.node, node.meta?.doc ?? inheritedDoc);\n break;\n case \"alternative\":\n for (const alt of node.attrs.alts) walk(alt, node.meta?.doc ?? inheritedDoc);\n break;\n }\n };\n walk(ctx.expr);\n return out;\n}\n\n/** Does the tool have any mutable file input (surfaced as an output)? */\nexport function hasMutableInputs(ctx: CodegenContext): boolean {\n return collectMutableOutputs(ctx).length > 0;\n}\n","import type {\n Binding,\n BindingId,\n BoundType,\n GateAtom,\n ResolvedToken,\n} from \"../../bindings/index.js\";\nimport { outputGate } from \"../../bindings/index.js\";\nimport { collectFieldInfo } from \"../collect-field-info.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport {\n type EmittedOutput,\n type OutputShape,\n collectMutableOutputs,\n collectOutputFields,\n rootOutput,\n streamFields,\n} from \"../collect-output-fields.js\";\nimport { PY_KEYWORDS, emitDocstring } from \"./emit.js\";\nimport { pyStr, renderAccess, renderPyLiteral } from \"./typemap.js\";\n\n// The output-field/stream/mutable collection is language-agnostic and shared\n// with the TypeScript and JSON Schema backends; re-export the predicates the\n// backend entry point consumes so its import surface stays `./outputs-emit.js`.\nexport { hasAnyOutputs, hasMutableInputs, hasStreamOutputs } from \"../collect-output-fields.js\";\n\nfunction outputTypeExpr(shape: OutputShape): string {\n if (shape.kind === \"list\") return \"list[OutputPathType]\";\n return shape.optional ? \"OutputPathType | None\" : \"OutputPathType\";\n}\n\n/** Field ids for stdout/stderr (in declaration order), for wrapper wiring. */\nexport function streamFieldIds(ctx: CodegenContext): { stdout?: string; stderr?: string } {\n const fields = streamFields(ctx, pyId);\n const res: { stdout?: string; stderr?: string } = {};\n let idx = 0;\n if (ctx.app?.stdout) res.stdout = fields[idx++]!.id;\n if (ctx.app?.stderr) res.stderr = fields[idx++]!.id;\n return res;\n}\n\n/** Emit `@dataclasses.dataclass\\nclass <outputsType>:` declaration. */\nexport function emitOutputsClass(ctx: CodegenContext, outputsType: string, cb: CodeBuilder): void {\n cb.line(\"@dataclasses.dataclass\");\n cb.line(`class ${outputsType}:`);\n cb.indent(() => {\n emitDocstring(cb, \"Output paths produced by the tool.\");\n const fields = collectOutputFields(ctx, pyId);\n const streams = streamFields(ctx, pyId);\n if (fields.length === 0 && streams.length === 0) {\n cb.line(\"pass\");\n return;\n }\n for (const field of fields) {\n cb.line(`${field.id}: ${outputTypeExpr(field.shape)}`);\n if (field.doc) emitDocstring(cb, field.doc);\n }\n for (const s of streams) {\n cb.line(`${s.id}: list[str]`);\n if (s.doc) emitDocstring(cb, s.doc);\n }\n });\n}\n\n/**\n * Substitutions for ref access while inside an iteration loop, and how `iter`\n * segments in a binding's access path are resolved at emit time.\n */\ntype IterScope = Map<BindingId, string>;\n\ninterface OutputEmitCtx {\n ctx: CodegenContext;\n iter: IterScope;\n /**\n * Prefix substitutions for optional fields narrowed by an enclosing presence\n * gate: maps a rendered access prefix to the `.get()`-narrowed local holding\n * it. Threaded into `renderAccess` so reads use the local (one lookup, absent-\n * safe, mypy-narrowable) - mirrors the cargs builder's `valueSubst`.\n */\n subst: ReadonlyMap<string, string>;\n /**\n * Rendered Python default literals for root-level defaulted fields, keyed by\n * field name. An output path that interpolates such a field (e.g. an output\n * basename `maskfile`) reads it via `.get(key, <default>)` so an absent key\n * substitutes the default rather than raising `KeyError`. Mirrors the cargs\n * builder's `defaults`.\n */\n defaults: ReadonlyMap<string, string>;\n}\n\n/** The rendered default for a binding iff it is a root-level defaulted field. */\nfunction rootFieldDefault(\n binding: Binding | undefined,\n defaults: ReadonlyMap<string, string>,\n): string | undefined {\n if (!binding) return undefined;\n const a = binding.access;\n if (a.length === 1 && a[0]?.kind === \"field\") return defaults.get(binding.name);\n return undefined;\n}\n\n/** Build the field-name -> rendered-default map for the struct root (else empty).\n * Includes only non-optional defaulted fields (optional fields are\n * presence-guarded; their default comes from the factory's kwarg signature). */\nfunction collectDefaults(ctx: CodegenContext): Map<string, string> {\n const out = new Map<string, string>();\n const rootType = ctx.resolve(ctx.expr)?.type;\n if (rootType?.kind !== \"struct\") return out;\n for (const [name, fi] of collectFieldInfo(ctx, rootType)) {\n if (fi.defaultValue === undefined) continue;\n if (rootType.fields[name]?.kind === \"optional\") continue;\n out.set(name, renderPyLiteral(fi.defaultValue));\n }\n return out;\n}\n\ninterface WrapperRender {\n open: string;\n loopVar?: string;\n /** A `local = params.get(...)` line emitted before `open` (optional gates). */\n bindLine?: string;\n /** `[accessPrefix, local]` to add to the child scope's `subst` map. */\n subst?: [string, string];\n}\n\nlet loopCounter = 0;\n\nfunction renderWrapperOpen(atom: GateAtom, ec: OutputEmitCtx): WrapperRender {\n if (atom.kind === \"iter\") {\n const access = bindingAccess(atom.binding, ec);\n const v = `__o${loopCounter++}`;\n return { open: `for ${v} in ${access}:`, loopVar: v };\n }\n if (atom.kind === \"variant\") {\n const access = bindingAccess(atom.binding, ec);\n return { open: `if ${access}[\"@type\"] == ${pyStr(atom.variant)}:` };\n }\n // present\n const binding = ec.ctx.bindings.get(atom.binding);\n if (binding?.type.kind === \"optional\") {\n // Optional fields are NotRequired - the factory omits absent ones. Bind the\n // value to a narrowed local read via `.get()` (a bare subscript would\n // KeyError) and redirect inner reads to it via `subst`. Mirrors walkOptional.\n const subscriptAccess = bindingAccess(atom.binding, ec);\n const getAccess = bindingAccess(atom.binding, ec, true);\n const local = `__v${loopCounter++}`;\n return {\n open: `if ${local} is not None:`,\n bindLine: `${local} = ${getAccess}`,\n subst: [subscriptAccess, local],\n };\n }\n // A bool flag / count gating an output is NotRequired (a hand-authored config\n // may omit it), so read absence-safe via `.get()` - a bare subscript would\n // KeyError. `presentCondition` coerces the possibly-None `.get()` result.\n const t = binding?.type.kind;\n const absentSafe = t === \"bool\" || t === \"count\";\n const access = bindingAccess(atom.binding, ec, absentSafe);\n const cond = presentCondition(binding?.type, access);\n return { open: `if ${cond}:` };\n}\n\nfunction presentCondition(type: BoundType | undefined, access: string): string {\n if (!type) return access;\n switch (type.kind) {\n case \"optional\":\n return `${access} is not None`;\n case \"bool\":\n // `access` is a `.get()` read: None (absent) is falsy -> flag off.\n return access;\n case \"count\":\n // `access` is a `.get()` read: coerce None (absent) to 0 before comparing.\n return `(${access} or 0) > 0`;\n default:\n return access;\n }\n}\n\nfunction bindingAccess(\n id: BindingId,\n ec: OutputEmitCtx,\n finalGet = false,\n finalDefault?: string,\n): string {\n // The binding is itself the currently-iterated element (a ref to the list\n // being looped, or a scalar list element): use its loop variable directly.\n const iterVar = ec.iter.get(id);\n if (iterVar) return iterVar;\n const binding = ec.ctx.bindings.get(id);\n if (binding) {\n // Solver-assigned path; `iter` segments resolve to the loop variable bound\n // by the surrounding `iter` gate atom. `finalGet` renders the last field\n // segment as `.get()` when binding an optional's value; `finalDefault`\n // renders it as `.get(key, default)` for a defaulted field; `subst` redirects\n // an optional prefix to the narrowed local bound by its presence gate.\n return renderAccess(\n binding.access,\n (b) => ec.iter.get(b) ?? `None # unresolved loop var ${b}`,\n {\n finalFieldGet: finalGet,\n finalFieldDefault: finalDefault,\n subst: ec.subst,\n },\n );\n }\n return `None # unresolved binding ${id}`;\n}\n\n/** Render the path expression for an output's tokens. */\nfunction renderPathExpr(tokens: ResolvedToken[], ec: OutputEmitCtx): string {\n if (tokens.length === 0) return `\"\"`;\n if (tokens.length === 1) return renderToken(tokens[0]!, ec);\n // f-string interpolation. Use a single-quoted outer so embedded subscript\n // expressions like `params[\"key\"]` (with double quotes) don't collide with\n // the outer quote - PEP 701 (Python 3.12+) lifts this restriction, but we\n // target 3.10+.\n let result = \"f'\";\n for (const tok of tokens) {\n if (tok.kind === \"literal\") {\n // Escape backslashes, single quotes, and braces (the latter are f-string\n // metacharacters).\n result += tok.value\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/'/g, \"\\\\'\")\n .replace(/\\{/g, \"{{\")\n .replace(/\\}/g, \"}}\");\n } else {\n result += \"{\";\n result += renderRefValue(tok, ec);\n result += \"}\";\n }\n }\n result += \"'\";\n return result;\n}\n\nfunction renderToken(tok: ResolvedToken, ec: OutputEmitCtx): string {\n if (tok.kind === \"literal\") return pyStr(tok.value);\n return renderRefValue(tok, ec);\n}\n\nfunction renderRefValue(tok: Extract<ResolvedToken, { kind: \"ref\" }>, ec: OutputEmitCtx): string {\n // A defaulted root field interpolated into an output path is read absent-safe\n // via `.get(key, default)` (it is `NotRequired`); other refs render normally.\n const def = rootFieldDefault(ec.ctx.bindings.get(tok.binding), ec.defaults);\n let expr =\n def !== undefined && !ec.iter.has(tok.binding)\n ? bindingAccess(tok.binding, ec, false, def)\n : bindingAccess(tok.binding, ec);\n if (tok.fallback !== undefined) {\n expr = `(${expr} if ${expr} is not None else ${pyStr(tok.fallback)})`;\n }\n if (tok.stripExtensions && tok.stripExtensions.length > 0) {\n const sorted = [...tok.stripExtensions].sort((a, b) => b.length - a.length);\n const lits = sorted.map((s) => pyStr(s)).join(\", \");\n expr = `_strip_extensions(${expr}, [${lits}])`;\n }\n return expr;\n}\n\n/**\n * Emit one contributor's assignment into the field's shared local var,\n * wrapped in its gate. The local var's init is emitted upfront by the caller\n * (except for required-single fields, which declare at their first ungated\n * assignment; `reassign` marks a later same-named contributor that must assign\n * into the already-declared local rather than re-annotate it).\n */\nfunction emitOneOutput(\n output: EmittedOutput,\n gate: GateAtom[],\n fieldShape: OutputShape,\n localVar: string,\n reassign: boolean,\n ec: OutputEmitCtx,\n cb: CodeBuilder,\n): void {\n const typeAnnot = outputTypeExpr(fieldShape);\n\n function nest(remaining: GateAtom[], child: OutputEmitCtx): void {\n if (remaining.length === 0) {\n const pathExpr = renderPathExpr(output.tokens, child);\n // A mutable input's writable copy is surfaced via mutable_copy (its host\n // path); a regular output resolves a local path via output_file.\n const call = output.mutable\n ? `execution.mutable_copy(${pathExpr})`\n : `execution.output_file(${pathExpr})`;\n if (fieldShape.kind === \"list\") {\n cb.line(`${localVar}.append(${call})`);\n } else if (fieldShape.optional || reassign) {\n // Optional fields init upfront; a required-single's second-or-later\n // ungated contributor reassigns the already-declared local (a second\n // annotated declaration would be a mypy `no-redef`).\n cb.line(`${localVar} = ${call}`);\n } else {\n // Required single: the first ungated contributor declares the var here.\n cb.line(`${localVar}: ${typeAnnot} = ${call}`);\n }\n return;\n }\n const [head, ...rest] = remaining;\n if (!head) return;\n const wrapper = renderWrapperOpen(head, child);\n if (wrapper.bindLine) cb.line(wrapper.bindLine);\n cb.line(wrapper.open);\n cb.indent(() => {\n let inner = child;\n if (head.kind === \"iter\") {\n inner = { ...child, iter: new Map(child.iter).set(head.binding, wrapper.loopVar!) };\n } else if (wrapper.subst) {\n inner = { ...child, subst: new Map(child.subst).set(wrapper.subst[0], wrapper.subst[1]) };\n }\n nest(rest, inner);\n });\n }\n\n nest(gate, ec);\n}\n\n/**\n * Emit a standalone `_outputs(params, execution)` function that builds and\n * returns the `Outputs` dataclass. Mirrors the `_cargs` function so the\n * wrapper can just call both. Same-named outputs share one local var (init\n * once, then every contributor assigns into it under its own gate), and the\n * constructor receives one keyword argument per unique field.\n */\nexport function emitBuildOutputs(\n ctx: CodegenContext,\n paramsType: string,\n outputsType: string,\n funcName: string,\n cb: CodeBuilder,\n): void {\n cb.line(`def ${funcName}(params: ${paramsType}, execution: Execution) -> ${outputsType}:`);\n cb.indent(() => {\n cb.line(`\"\"\"Build the ${outputsType} object for this tool.\"\"\"`);\n loopCounter = 0;\n const ec: OutputEmitCtx = {\n ctx,\n iter: new Map(),\n subst: new Map(),\n defaults: collectDefaults(ctx),\n };\n\n const fields = collectOutputFields(ctx, pyId);\n const localVarOf = new Map<string, string>();\n for (const f of fields) {\n const localVar = `${f.id}_v`;\n localVarOf.set(f.id, localVar);\n // Initialize lists and gated singles upfront so each contributor only\n // assigns or appends. Required-singles are declared at their (sole)\n // ungated assignment - no init line here would leave the name unbound.\n if (f.shape.kind === \"list\") cb.line(`${localVar}: list[OutputPathType] = []`);\n else if (f.shape.optional) cb.line(`${localVar}: OutputPathType | None = None`);\n }\n\n // Required-single fields declare their local at the first ungated\n // contributor; a same-named ungated contributor seen later must reassign\n // (a second annotated declaration is a mypy `no-redef`). Some afni\n // descriptors give two output-files the same id with no gate.\n const declared = new Set<string>();\n const emitContributor = (output: EmittedOutput, scopeGate: GateAtom[]): void => {\n const gate = outputGate(scopeGate, output, ctx.bindings);\n const id = pyId(output.name);\n const field = fields.find((f) => f.id === id)!;\n const reassign = declared.has(id);\n declared.add(id);\n emitOneOutput(output, gate, field.shape, localVarOf.get(id)!, reassign, ec, cb);\n };\n // The always-present root output directory, declared before any declared\n // output (matches its first position in collectOutputFields).\n emitContributor(rootOutput(ctx, pyId), []);\n for (const scope of ctx.outputScopes) {\n const scopeBinding = ctx.bindings.get(scope.scope);\n const scopeGate = scopeBinding?.gate ?? [];\n for (const output of scope.outputs) emitContributor(output, scopeGate);\n }\n for (const output of collectMutableOutputs(ctx)) emitContributor(output, []);\n\n const streams = streamFields(ctx, pyId);\n if (fields.length === 0 && streams.length === 0) {\n cb.line(`return ${outputsType}()`);\n } else {\n cb.line(`return ${outputsType}(`);\n cb.indent(() => {\n for (const f of fields) cb.line(`${f.id}=${localVarOf.get(f.id)},`);\n // Stream fields start empty; the wrapper appends to them via the\n // handle_stdout / handle_stderr callbacks passed to execution.run.\n for (const s of streams) cb.line(`${s.id}=[],`);\n });\n cb.line(\")\");\n }\n });\n}\n\n/** Sanitize an output name to a valid Python identifier. */\nfunction pyId(name: string): string {\n let s = name.replace(/[^a-zA-Z0-9_]/g, \"_\");\n if (/^\\d/.test(s)) s = \"_\" + s;\n if (s === \"\") s = \"_\";\n if (PY_KEYWORDS.has(s)) s = s + \"_\";\n return s;\n}\n\n/** Whether any output reference has stripExtensions set. */\nexport function needsStripExtensionsHelper(ctx: CodegenContext): boolean {\n for (const scope of ctx.outputScopes) {\n for (const output of scope.outputs) {\n for (const tok of output.tokens) {\n if (tok.kind === \"ref\" && tok.stripExtensions?.length) return true;\n }\n }\n }\n return false;\n}\n\n/** Emit a small `_strip_extensions` helper used by ref tokens that strip suffixes. */\nexport function emitStripExtensionsHelper(cb: CodeBuilder): void {\n cb.line(\"def _strip_extensions(value: str, exts: list[str]) -> str:\");\n cb.indent(() => {\n cb.line(\"for ext in exts:\");\n cb.indent(() => {\n cb.line(\"if value.endswith(ext):\");\n cb.indent(() => {\n cb.line(\"return value[: -len(ext)]\");\n });\n });\n cb.line(\"return value\");\n });\n}\n","import type { BoundType } from \"../../bindings/index.js\";\nimport type { AppMeta } from \"../../ir/index.js\";\nimport type { CodegenContext, PackageMeta, ProjectMeta } from \"../../manifest/index.js\";\nimport type { AppEntrypoint, Backend, EmitResult, EmittedApp, EmittedPackage } from \"../backend.js\";\nimport type { SigEntry } from \"../sig-entries.js\";\nimport type { NamedType } from \"./types.js\";\nimport {\n generateRequirementsTxt,\n generateRootPyproject,\n generateRootReadme,\n generateSubPyproject,\n generateSubReadme,\n pyDistName,\n} from \"./packaging.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport { Scope } from \"../scope.js\";\nimport { pascalCase, screamingSnakeCase, snakeCase } from \"../string-case.js\";\nimport { buildSigEntries } from \"../sig-entries.js\";\nimport {\n emitBuildCargs,\n emitImports,\n emitKwargWrapper,\n emitMetadata,\n emitParamsFactory,\n emitTypeDeclarations,\n emitWrapperFunction,\n pyScrubIdent,\n pySigOptions,\n} from \"./emit.js\";\nimport { collectFieldInfo } from \"./types.js\";\nimport { emitValidate } from \"./validate-emit.js\";\nimport {\n emitBuildOutputs,\n emitOutputsClass,\n emitStripExtensionsHelper,\n needsStripExtensionsHelper,\n streamFieldIds,\n} from \"./outputs-emit.js\";\nimport { mapType } from \"./typemap.js\";\nimport { collectNamedTypes, resolveTypeName, structKey, unionKey } from \"./types.js\";\n\n// Python reserved words + commonly-shadowed built-ins. Used to avoid collisions\n// when generating identifiers. Includes keywords, common stdlib builtins, and\n// the styxdefs symbols we emit/import.\nconst PY_RESERVED: ReadonlySet<string> = new Set([\n \"False\",\n \"None\",\n \"True\",\n \"and\",\n \"as\",\n \"assert\",\n \"async\",\n \"await\",\n \"break\",\n \"class\",\n \"continue\",\n \"def\",\n \"del\",\n \"elif\",\n \"else\",\n \"except\",\n \"finally\",\n \"for\",\n \"from\",\n \"global\",\n \"if\",\n \"import\",\n \"in\",\n \"is\",\n \"lambda\",\n \"nonlocal\",\n \"not\",\n \"or\",\n \"pass\",\n \"raise\",\n \"return\",\n \"try\",\n \"while\",\n \"with\",\n \"yield\",\n // Common builtins to avoid shadowing.\n \"list\",\n \"dict\",\n \"tuple\",\n \"set\",\n \"int\",\n \"float\",\n \"str\",\n \"bool\",\n \"type\",\n \"print\",\n \"open\",\n \"input\",\n \"range\",\n \"len\",\n \"id\",\n \"object\",\n \"Exception\",\n \"ValueError\",\n \"TypeError\",\n // styxdefs symbols we emit/import.\n \"Runner\",\n \"Execution\",\n \"Metadata\",\n \"InputPathType\",\n \"OutputPathType\",\n \"get_global_runner\",\n \"dataclasses\",\n \"typing\",\n]);\n\n/**\n * Per-tool public symbol names. With the flat `fsl/bet.py` layout each tool\n * file emits these names directly - there is no internal/public alias split.\n */\nexport interface PublicNames {\n params: string;\n outputs: string;\n metadata: string;\n cargs: string;\n outputsFn: string;\n paramsFn: string;\n execute: string;\n validate: string;\n wrapper: string;\n}\n\n/** Public-name scheme used by the Python backend. Exported so the CLI and tests can use it. */\nexport function computePublicNames(appId: string | undefined): PublicNames {\n if (!appId) {\n return {\n params: \"Params\",\n outputs: \"Outputs\",\n metadata: \"METADATA\",\n cargs: \"cargs\",\n outputsFn: \"outputs\",\n paramsFn: \"build_params\",\n execute: \"execute\",\n validate: \"validate\",\n wrapper: \"run\",\n };\n }\n // Pre-scrub digit-leading ids (e.g. `3dPFM`) so all derived case forms\n // produce valid Python identifiers in a consistent case (matches v1's\n // `V_3D_PFM_METADATA` / `v_3d_pfm` style instead of mixed `v_3D_PFM`).\n const id = /^[0-9]/.test(appId) ? \"v_\" + appId : appId;\n return {\n params: pascalCase(id),\n outputs: pascalCase(id) + \"Outputs\",\n metadata: screamingSnakeCase(id) + \"_METADATA\",\n cargs: snakeCase(id) + \"_cargs\",\n outputsFn: snakeCase(id) + \"_outputs\",\n paramsFn: snakeCase(id) + \"_params\",\n execute: snakeCase(id) + \"_execute\",\n validate: snakeCase(id) + \"_validate\",\n wrapper: snakeCase(id),\n };\n}\n\n/**\n * The fully-derived naming/typing model for one tool's Python emission. Computed\n * once by `buildEmitModel` so the file emitter and the call-site snippet renderer\n * share the exact same public names, scrubbed kwarg names, and root typing - the\n * snippet must match the function the generated code actually exposes.\n */\nexport interface PyEmitModel {\n appId: string | undefined;\n pkg: string | undefined;\n names: {\n params: string;\n outputs: string;\n metadata: string;\n cargs: string;\n outputsFn: string;\n paramsFn: string;\n execute: string;\n validate: string;\n wrapper: string;\n };\n rootType: BoundType;\n rootIsStruct: boolean;\n namedTypes: Map<string, string>;\n typeDecls: NamedType[];\n rootTypeTag: string | undefined;\n paramsType: string;\n sigEntries: SigEntry[];\n}\n\n/**\n * Derive the public names, named-type declarations, root typing, and per-field\n * signature entries for one tool. Mutates `scope` exactly as the emitter needs\n * (the `reg` registrations and the `sigScope` child), so passing the same scope\n * the emitter continues with keeps later local registrations consistent.\n */\nexport function buildEmitModel(\n ctx: CodegenContext,\n scope: Scope = new Scope(PY_RESERVED),\n): PyEmitModel {\n const appId = ctx.app?.id;\n const pkg = ctx.package?.name;\n const publicNames = computePublicNames(appId);\n\n const rootBinding = ctx.resolve(ctx.expr);\n const rootType: BoundType = rootBinding?.type ?? { kind: \"struct\", fields: {} };\n // Only treat the root as struct-shaped when there's a real binding. A\n // synthesized empty-struct fallback (no root binding) means the solver\n // collapsed everything away, so the kwarg wrapper has nothing to wrap.\n const rootIsStruct = rootBinding?.type.kind === \"struct\";\n\n // Pre-reserve module-level public names so any IR-derived names colliding\n // with them get suffix-bumped. `params` is intentionally NOT pre-reserved -\n // `collectNamedTypes` claims it for the root struct just below. Each name\n // is scrubbed through `pyScrubIdent` first since the case helpers happily\n // pass through digit-leading app ids like `3dvolreg.afni`.\n const reg = (name: string) => scope.add(pyScrubIdent(name, PY_RESERVED));\n const names = {\n params: pyScrubIdent(publicNames.params, PY_RESERVED),\n outputs: reg(publicNames.outputs),\n metadata: reg(publicNames.metadata),\n cargs: reg(publicNames.cargs),\n outputsFn: reg(publicNames.outputsFn),\n paramsFn: rootIsStruct ? reg(publicNames.paramsFn) : \"\",\n execute: rootIsStruct ? reg(publicNames.execute) : \"\",\n validate: reg(publicNames.validate),\n wrapper: reg(publicNames.wrapper),\n };\n\n // Prefix nested type names with the tool's root name so a suite's flat\n // `from .x import *` re-exports don't shadow same-named types across tools.\n const { namedTypes, typeDecls } = collectNamedTypes(\n rootType,\n names.params,\n scope,\n pascalCase,\n appId ? names.params : \"\",\n );\n\n names.params =\n (rootType.kind === \"struct\" ? namedTypes.get(structKey(rootType)) : undefined) ??\n (rootType.kind === \"union\" ? namedTypes.get(unionKey(rootType)) : undefined) ??\n names.params;\n\n // Tag injected as `@type: Literal[...]` on the root TypedDict (and as a\n // constant key by the params factory). Skipped when appId/pkg aren't known.\n const rootTypeTag = appId && pkg ? `${pkg}/${appId}` : undefined;\n\n const paramsType =\n rootType.kind === \"struct\" || rootType.kind === \"union\"\n ? names.params\n : mapType(rootType, resolveTypeName(namedTypes));\n\n // Build the per-field SigEntry list once - the factory and kwarg wrapper\n // both consume it, so the host names registered here must satisfy both\n // function scopes. Pre-reserve `params` (factory + wrapper body) and\n // `runner` (wrapper signature) so a wire key matching either gets\n // suffix-bumped. `rootType` is narrowed by `rootIsStruct` for the `Extract`\n // constraint.\n const sigScope = scope.child([\"params\", \"runner\"]);\n const sigEntries =\n rootIsStruct && rootType.kind === \"struct\"\n ? buildSigEntries(\n rootType,\n collectFieldInfo(ctx, rootType),\n (wireKey) => sigScope.add(pyScrubIdent(wireKey, PY_RESERVED)),\n pySigOptions(resolveTypeName(namedTypes)),\n )\n : [];\n\n return {\n appId,\n pkg,\n names,\n rootType,\n rootIsStruct,\n namedTypes,\n typeDecls,\n rootTypeTag,\n paramsType,\n sigEntries,\n };\n}\n\nexport function generatePython(ctx: CodegenContext, packageScope?: Scope): string {\n const cb = new CodeBuilder(\" \");\n // A package-shared scope keeps top-level names unique across every tool in the\n // suite's `from .x import *` re-exports; without one a per-tool scope suffices.\n const scope = packageScope ?? new Scope(PY_RESERVED);\n\n const {\n names,\n rootType,\n rootIsStruct,\n namedTypes,\n typeDecls,\n rootTypeTag,\n paramsType,\n sigEntries,\n } = buildEmitModel(ctx, scope);\n\n // Auto-generated header.\n cb.comment(\"This file was auto generated by Styx.\", \"# \");\n cb.comment(\"Do not edit this file directly.\", \"# \");\n cb.blank();\n\n // Every tool emits an Outputs object: at minimum the synthetic `root` output\n // directory (output_file(\".\")), plus any declared file/mutable outputs and\n // stdout/stderr stream fields. OutputPathType is therefore always imported.\n const emitOutputs = true;\n\n emitImports(cb, true);\n cb.blank();\n\n emitMetadata(ctx, names.metadata, cb);\n cb.blank();\n\n emitTypeDeclarations(typeDecls, namedTypes, ctx, cb, names.params, rootTypeTag);\n\n if (emitOutputs) {\n emitOutputsClass(ctx, names.outputs, cb);\n cb.blank();\n }\n\n if (emitOutputs && needsStripExtensionsHelper(ctx)) {\n emitStripExtensionsHelper(cb);\n cb.blank();\n }\n\n // Params factory (struct-rooted tools only): a kwarg-style builder for the\n // params dict. Useful for callers that want to build a dict to mutate before\n // executing.\n if (rootIsStruct) {\n emitParamsFactory(sigEntries, names.paramsFn, paramsType, rootTypeTag, cb);\n cb.blank();\n }\n\n // Validation: walks the root binding and raises StyxValidationError on bad\n // input. Called first thing in the dict-style execute (below).\n emitValidate(\n ctx,\n rootType,\n ctx.expr,\n paramsType,\n names.validate,\n resolveTypeName(namedTypes),\n scope,\n cb,\n );\n cb.blank();\n\n emitBuildCargs(ctx, rootType, paramsType, names.cargs, cb);\n cb.blank();\n\n if (emitOutputs) {\n emitBuildOutputs(ctx, paramsType, names.outputs, names.outputsFn, cb);\n cb.blank();\n }\n\n // Dict-style execute function. For struct roots it's the internal\n // `<tool>_execute`; for other roots it doubles as the user-facing wrapper.\n const executeName = rootIsStruct ? names.execute : names.wrapper;\n emitWrapperFunction(\n ctx,\n paramsType,\n executeName,\n names.metadata,\n names.cargs,\n emitOutputs ? names.outputsFn : undefined,\n emitOutputs ? names.outputs : undefined,\n names.validate,\n streamFieldIds(ctx),\n cb,\n );\n cb.blank();\n\n // Kwarg-style wrapper (struct roots only): the v1-parity user-facing entry.\n if (rootIsStruct) {\n emitKwargWrapper(\n ctx,\n sigEntries,\n names.wrapper,\n names.paramsFn,\n names.execute,\n emitOutputs ? names.outputs : undefined,\n cb,\n );\n cb.blank();\n }\n\n // `__all__` keeps suite-level `from .bet import *` from re-exporting the\n // module's stdlib/styxdefs imports.\n const publicSymbols = [\n names.params,\n ...(emitOutputs ? [names.outputs] : []),\n names.metadata,\n names.cargs,\n ...(emitOutputs ? [names.outputsFn] : []),\n ...(rootIsStruct ? [names.paramsFn, names.execute] : []),\n names.validate,\n names.wrapper,\n ];\n cb.line(\"__all__ = [\");\n cb.indent(() => {\n for (const sym of publicSymbols) cb.line(`\"${sym}\",`);\n });\n cb.line(\"]\");\n\n return cb.toString();\n}\n\n/**\n * Module name (file stem) for an app: snake_case of app.id, fallback `output`.\n * Scrubbed so digit-leading app ids (e.g. `3dPFM` -> `v_3d_pfm`) and keyword\n * collisions don't break `from .<mod> import *` in the package __init__.\n */\nexport function appModuleName(meta: AppMeta | undefined): string {\n if (!meta?.id) return \"output\";\n return pyScrubIdent(snakeCase(meta.id), PY_RESERVED);\n}\n\n/**\n * The dispatch entrypoint for one app: its root `@type` (`<package>/<app>`) and\n * the dict-style execute function name. Returns undefined when the id or package\n * is unknown (no stable `@type`), so the app is left out of the suite dispatcher.\n */\nexport function appEntrypoint(ctx: CodegenContext): AppEntrypoint | undefined {\n const appId = ctx.app?.id;\n const pkg = ctx.package?.name;\n if (!appId || !pkg) return undefined;\n const publicNames = computePublicNames(appId);\n const rootIsStruct = ctx.resolve(ctx.expr)?.type.kind === \"struct\";\n const executeFn = pyScrubIdent(\n rootIsStruct ? publicNames.execute : publicNames.wrapper,\n PY_RESERVED,\n );\n return { type: `${pkg}/${appId}`, executeFn };\n}\n\n/**\n * Generate the suite-level `__init__.py` re-export for a package containing\n * multiple tool modules. Each tool module's public symbols are surfaced via\n * `from .bet import *` (each tool file defines `__all__`). When apps carry a\n * dispatch entrypoint, a suite-level `execute(params, runner)` is appended that\n * routes a config object to the right tool by its root `@type`.\n */\nexport function generatePackageInit(apps: EmittedApp[]): string {\n const cb = new CodeBuilder(\" \");\n cb.comment(\"This file was auto generated by Styx.\", \"# \");\n cb.comment(\"Do not edit this file directly.\", \"# \");\n cb.blank();\n\n const dispatch = apps\n .map((a) => a.entrypoint)\n .filter((e): e is AppEntrypoint => e !== undefined)\n .sort((a, b) => a.type.localeCompare(b.type));\n\n if (dispatch.length > 0) {\n cb.line(\"import typing\");\n cb.blank();\n cb.line(\"from styxdefs import Runner\");\n cb.blank();\n }\n\n const modules = apps\n .map((a) => appModuleName(a.meta))\n .filter((name): name is string => !!name)\n .sort();\n\n for (const mod of modules) {\n cb.line(`from .${mod} import *`);\n }\n\n if (dispatch.length > 0) {\n cb.blank();\n emitPackageDispatch(cb, dispatch);\n }\n\n return cb.toString();\n}\n\n/** Emit the suite-level `execute(params, runner)` dispatcher over `@type`. */\nfunction emitPackageDispatch(cb: CodeBuilder, dispatch: AppEntrypoint[]): void {\n cb.line(\n \"def execute(params: dict[str, typing.Any], runner: Runner | None = None) -> typing.Any:\",\n );\n cb.indent(() => {\n cb.line('\"\"\"Run a tool in this package from a params object, routed by its `@type`.\"\"\"');\n cb.line(\"_dispatch: dict[str, typing.Callable[[typing.Any, Runner | None], typing.Any]] = {\");\n cb.indent(() => {\n for (const e of dispatch) {\n cb.line(`${JSON.stringify(e.type)}: ${e.executeFn},`);\n }\n });\n cb.line(\"}\");\n cb.line('_fn = _dispatch.get(params[\"@type\"])');\n cb.line(\"if _fn is None:\");\n cb.indent(() => {\n cb.line(`raise ValueError(f\"No tool registered for @type {params['@type']!r}\")`);\n });\n cb.line(\"return _fn(params, runner)\");\n });\n}\n\nexport class PythonBackend implements Backend {\n readonly name = \"python\";\n readonly target = \"python\";\n\n emitApp(ctx: CodegenContext, scope?: Scope): EmittedApp {\n const code = generatePython(ctx, scope);\n const fileName = `${appModuleName(ctx.app)}.py`;\n return {\n meta: ctx.app,\n entrypoint: appEntrypoint(ctx),\n files: new Map([[fileName, code]]),\n errors: [],\n warnings: [],\n };\n }\n\n newPackageScope(): Scope {\n return new Scope(PY_RESERVED);\n }\n\n emitPackage(pkg: PackageMeta, apps: EmittedApp[]): EmittedPackage {\n return {\n meta: pkg,\n files: new Map([\n [\"__init__.py\", generatePackageInit(apps)],\n // PEP 561 marker so type-checkers treat the generated suite as typed.\n [\"py.typed\", \"\"],\n ]),\n errors: [],\n warnings: [],\n };\n }\n\n emitProject(proj: ProjectMeta, packages: EmittedPackage[]): EmitResult {\n const files = new Map<string, string>();\n const distNames: string[] = [];\n const pkgDirs: string[] = [];\n\n for (const p of packages) {\n const pkg = p.meta ?? {};\n // Mirror the CLI's `pkgDir` fallback so a nameless package's source dir\n // still gets a matching pyproject/README instead of being orphaned.\n const dir = pkg.name ?? \"package\";\n pkgDirs.push(dir);\n distNames.push(pyDistName(proj, pkg));\n files.set(`${dir}/pyproject.toml`, generateSubPyproject(proj, pkg));\n files.set(`${dir}/README.md`, generateSubReadme(proj, pkg));\n }\n\n files.set(\"pyproject.toml\", generateRootPyproject(proj, distNames));\n files.set(\"README.md\", generateRootReadme(proj, distNames));\n files.set(\"requirements.txt\", generateRequirementsTxt(pkgDirs));\n\n return { files, errors: [], warnings: [] };\n }\n}\n","import type { BoundType } from \"../bindings/index.js\";\n\n/**\n * Per-language rendering hooks for the call-site snippet renderer. The recursive\n * structure (struct -> object literal, union -> picked variant, list -> array)\n * is language-agnostic; only leaf-literal syntax, object keys, and indentation\n * differ, and those are supplied here.\n */\nexport interface SnippetDialect {\n /** One indentation level (e.g. `\" \"` for Python, `\" \"` for TypeScript). */\n indentUnit: string;\n /** Render a string value as a host literal (quoted). */\n string(value: string): string;\n /** Render a boolean value as a host literal (`True`/`true`). */\n boolean(value: boolean): string;\n /** Render a number value as a host literal. */\n number(value: number): string;\n /** Host literal for a null/None value. */\n null: string;\n /** Render an object-literal key from a wire key, quoting when not a bare identifier. */\n objKey(wireKey: string): string;\n}\n\n/** Options shared by both language renderers. */\nexport interface SnippetOptions {\n /**\n * Module the package is imported from (e.g. `\"niwrap\"`). Defaults to the\n * project name on the context. When unset and no project name is available,\n * Python falls back to a bare `import <pkg>` and TypeScript omits the import.\n */\n packageRoot?: string;\n /** Whether to prepend an import line. Defaults to `true`. */\n includeImport?: boolean;\n}\n\n/** Is `value` a plain (non-array) object usable as a struct/union config? */\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Strip transparent `optional` wrappers down to the underlying value type. */\nfunction unwrap(type: BoundType): BoundType {\n return type.kind === \"optional\" ? unwrap(type.inner) : type;\n}\n\n/** Render a leaf primitive (string/number/bool/null) by its JS runtime type. */\nfunction renderPrimitive(value: unknown, d: SnippetDialect): string {\n if (value === null || value === undefined) return d.null;\n switch (typeof value) {\n case \"string\":\n return d.string(value);\n case \"boolean\":\n return d.boolean(value);\n case \"number\":\n return d.number(value);\n default:\n // Bigint / unexpected: fall back to a quoted string form.\n return d.string(String(value));\n }\n}\n\n/** The `@type` discriminator value carried by a struct type, if any. */\nfunction structAtType(type: Extract<BoundType, { kind: \"struct\" }>): string | undefined {\n const field = type.fields[\"@type\"];\n return field && field.kind === \"literal\" ? String(field.value) : undefined;\n}\n\n/**\n * Render a struct config as a host object literal (Python dict / TS object).\n * Keys are the Boutiques wire names (the generated TypedDict / interface keys) -\n * nested structs have no constructor function in the generated code, so callers\n * build them as plain object literals.\n *\n * `@type` is emitted from the struct's literal discriminator field when present\n * (union variants carry a required, load-bearing `@type`); for the root call the\n * tag is injected via `injectAtType` (the root's `@type` is derived from\n * `pkg/appId`, not stored as a field). Non-`@type` literal fields have no\n * runtime representation and are skipped.\n */\nexport function renderStructLiteral(\n value: unknown,\n type: Extract<BoundType, { kind: \"struct\" }>,\n indent: string,\n d: SnippetDialect,\n injectAtType?: string,\n): string {\n const obj = isRecord(value) ? value : {};\n const inner = indent + d.indentUnit;\n const lines: string[] = [];\n\n const atType = structAtType(type) ?? injectAtType;\n if (atType !== undefined) {\n lines.push(`${inner}${d.objKey(\"@type\")}: ${d.string(atType)},`);\n }\n\n for (const [wireKey, fieldType] of Object.entries(type.fields)) {\n if (wireKey === \"@type\") continue;\n if (fieldType.kind === \"literal\") continue; // no runtime representation\n if (!(wireKey in obj)) continue; // omitted optional / absent field\n lines.push(`${inner}${d.objKey(wireKey)}: ${renderValue(obj[wireKey], fieldType, inner, d)},`);\n }\n\n if (lines.length === 0) return \"{}\";\n return `{\\n${lines.join(\"\\n\")}\\n${indent}}`;\n}\n\n/**\n * Render a union config. An object value with an `@type` is matched to the\n * struct variant whose discriminator equals that tag and rendered as that\n * variant's object literal; a primitive value (a bare literal/scalar variant,\n * e.g. a mixed union's `\"Linear\"` const arm) is rendered directly.\n */\nfunction renderUnion(\n value: unknown,\n type: Extract<BoundType, { kind: \"union\" }>,\n indent: string,\n d: SnippetDialect,\n): string {\n if (isRecord(value)) {\n const tag = value[\"@type\"];\n const match = type.variants.find(\n (v) => v.type.kind === \"struct\" && structAtType(v.type) === String(tag),\n );\n if (match && match.type.kind === \"struct\") {\n return renderStructLiteral(value, match.type, indent, d);\n }\n // Unknown/missing tag: fall back to the sole struct variant if there is one,\n // otherwise emit an empty object. (Well-formed configs always match.)\n const onlyStruct = type.variants.filter((v) => v.type.kind === \"struct\");\n if (onlyStruct.length === 1 && onlyStruct[0]!.type.kind === \"struct\") {\n return renderStructLiteral(value, onlyStruct[0]!.type, indent, d);\n }\n return \"{}\";\n }\n return renderPrimitive(value, d);\n}\n\n/**\n * Render a list config. A list of structs/unions renders multi-line (one object\n * literal per element); a list of primitives renders inline (`[1, 2, 3]`).\n */\nfunction renderList(value: unknown, item: BoundType, indent: string, d: SnippetDialect): string {\n if (!Array.isArray(value) || value.length === 0) return \"[]\";\n const it = unwrap(item);\n if (it.kind === \"struct\" || it.kind === \"union\") {\n const inner = indent + d.indentUnit;\n const elems = value.map((el) => `${inner}${renderValue(el, it, inner, d)},`);\n return `[\\n${elems.join(\"\\n\")}\\n${indent}]`;\n }\n return `[${value.map((el) => renderValue(el, it, indent, d)).join(\", \")}]`;\n}\n\n/**\n * Render a config value to a host-language expression, guided by its BoundType.\n *\n * `indent` is the leading whitespace of the line the value starts on; multi-line\n * forms (object/array literals) place their members one level deeper and close\n * back at `indent`. The renderer follows the BoundType tree for shape and reads\n * the parallel config object for values, so unknown / absent keys are simply\n * omitted (a partial config produces a partial snippet).\n */\nexport function renderValue(\n value: unknown,\n type: BoundType,\n indent: string,\n d: SnippetDialect,\n): string {\n // A present null/undefined renders as the host null literal regardless of the\n // declared type. An explicitly-unset optional field (a form may emit `null`\n // rather than omitting the key) must not be coerced into an empty `{}` / `[]`\n // by the struct/list branches below - that would be a value the generated code\n // rejects (a struct missing its required keys, a non-array for a list).\n if (value === null || value === undefined) return d.null;\n const t = unwrap(type);\n switch (t.kind) {\n case \"struct\":\n return renderStructLiteral(value, t, indent, d);\n case \"union\":\n return renderUnion(value, t, indent, d);\n case \"list\":\n return renderList(value, t.item, indent, d);\n default:\n return renderPrimitive(value, d);\n }\n}\n","import type { BoundType } from \"../../bindings/index.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport type { SigEntry } from \"../sig-entries.js\";\nimport type { SnippetDialect, SnippetOptions } from \"../snippet-core.js\";\nimport { renderValue } from \"../snippet-core.js\";\nimport { buildEmitModel } from \"./python.js\";\nimport { pyStr } from \"./typemap.js\";\n\n/** Snippet rendering hooks for Python (dict literals, `True`/`None`). */\nconst pyDialect: SnippetDialect = {\n indentUnit: \" \",\n string: pyStr,\n boolean: (b) => (b ? \"True\" : \"False\"),\n number: (n) => (Number.isFinite(n) ? String(n) : \"float('nan')\"),\n null: \"None\",\n objKey: (k) => pyStr(k),\n};\n\n/**\n * Render a Python call snippet for one tool from a config object (the params\n * dict the form produces, keyed by Boutiques wire names).\n *\n * Struct-rooted tools use the ergonomic kwarg wrapper -\n * `fsl.bet(infile=..., fractional_intensity=0.5)` - whose keyword names are the\n * *scrubbed host* identifiers (`float` -> `float_`), not the wire keys; the\n * per-field mapping comes from the same `buildSigEntries` the generated wrapper\n * is built from, so the snippet matches the real signature. Nested structs /\n * union variants / lists-of-structs have no constructor in the generated code,\n * so they render as plain dict literals keyed by wire names.\n *\n * Union- (or otherwise non-struct-) rooted tools have no kwarg wrapper; the\n * single dict-style `<tool>` entry is called with one object-literal argument.\n *\n * The snippet matches the *standalone* (single-descriptor) emission of the same\n * context - which is how the hub compiles - not a catalog emission where a\n * shared package scope could suffix-bump a name.\n *\n * @param ctx - The compiled context (compile -> pipeline -> solve ->\n * resolveOutputs -> createContext, as in the CLI's `readAndCompile`).\n * @param config - The params object, keyed by Boutiques *wire* names (not host\n * identifiers). Every union-typed value - including the root of a union-rooted\n * tool - must carry its `@type` discriminator so the variant can be matched;\n * the root struct's `@type` is supplied by the renderer, so omit it there.\n * @param opts - Import and package-root options.\n */\nexport function renderPythonCall(\n ctx: CodegenContext,\n config: Record<string, unknown>,\n opts: SnippetOptions = {},\n): string {\n const model = buildEmitModel(ctx);\n const pkg = ctx.package?.name;\n const callee = pkg ? `${pkg}.${model.names.wrapper}` : model.names.wrapper;\n\n const call =\n model.rootIsStruct && model.rootType.kind === \"struct\"\n ? renderKwargCall(callee, model.sigEntries, model.rootType, config)\n : `${callee}(${renderValue(config, model.rootType, \"\", pyDialect)})`;\n\n if (opts.includeImport === false || !pkg) return call;\n const root = opts.packageRoot ?? ctx.project?.name;\n const importLine = root ? `from ${root} import ${pkg}` : `import ${pkg}`;\n return `${importLine}\\n\\n${call}`;\n}\n\n/** Render `callee(name=value, ...)` for a struct root using scrubbed kwarg names. */\nfunction renderKwargCall(\n callee: string,\n sigEntries: readonly SigEntry[],\n rootType: Extract<BoundType, { kind: \"struct\" }>,\n config: Record<string, unknown>,\n): string {\n const nameFor = new Map(sigEntries.map((e) => [e.wireKey, e.name]));\n const indent = pyDialect.indentUnit;\n const lines: string[] = [];\n for (const [wireKey, fieldType] of Object.entries(rootType.fields)) {\n if (fieldType.kind === \"literal\") continue; // @type / consts injected by the wrapper\n if (!(wireKey in config)) continue;\n const name = nameFor.get(wireKey) ?? wireKey;\n lines.push(`${indent}${name}=${renderValue(config[wireKey], fieldType, indent, pyDialect)},`);\n }\n if (lines.length === 0) return `${callee}()`;\n return `${callee}(\\n${lines.join(\"\\n\")}\\n)`;\n}\n","import type { Binding, BoundType, BoundVariant } from \"../../bindings/index.js\";\nimport type { Expr, ScalarKind } from \"../../ir/index.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport type { Backend, EmittedApp } from \"../backend.js\";\nimport { type OutputShape, collectOutputFields, streamFields } from \"../collect-output-fields.js\";\nimport { findDoc } from \"../find-doc.js\";\nimport { findStructNode } from \"../find-struct-node.js\";\nimport { resolveFieldBinding } from \"../resolve-field-binding.js\";\nimport { Scope } from \"../scope.js\";\nimport { snakeCase } from \"../string-case.js\";\n\nexport interface JsonSchema {\n type?: string | string[];\n items?: JsonSchema;\n properties?: Record<string, JsonSchema>;\n required?: string[];\n oneOf?: JsonSchema[];\n enum?: (string | number)[];\n const?: string | number;\n [key: string]: unknown;\n}\n\nclass SchemaBuilder {\n constructor(private ctx: CodegenContext) {}\n\n build(): JsonSchema {\n const envelope: JsonSchema = {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n };\n if (this.ctx.app?.doc?.title) envelope.title = this.ctx.app.doc.title;\n if (this.ctx.app?.doc?.description) envelope.description = this.ctx.app.doc.description;\n\n const rootBinding = this.ctx.resolve(this.ctx.expr);\n if (!rootBinding) return envelope;\n\n const schema = { ...envelope, ...this.fromBinding(rootBinding) };\n\n if (this.ctx.app?.id && schema.properties) {\n const pkg = this.ctx.package?.name ?? \"unknown\";\n schema.properties = {\n \"@type\": { const: `${pkg}/${this.ctx.app.id}` },\n ...schema.properties,\n };\n schema.required = [\"@type\", ...(schema.required ?? [])];\n }\n\n return schema;\n }\n\n private fromBinding(binding: Binding): JsonSchema {\n const schema = this.fromType(binding.type, binding.node);\n const meta = binding.node.meta;\n if (meta?.doc?.title) schema.title = meta.doc.title;\n if (meta?.doc?.description) schema.description = meta.doc.description;\n if (meta?.defaultValue !== undefined) schema.default = meta.defaultValue;\n return schema;\n }\n\n private fromType(type: BoundType, node?: Expr): JsonSchema {\n switch (type.kind) {\n case \"scalar\":\n return this.scalarSchema(type.scalar, node);\n case \"bool\":\n return { type: \"boolean\" };\n case \"count\":\n return { type: \"integer\", minimum: 0 };\n case \"literal\":\n return { const: type.value };\n case \"optional\":\n return this.fromType(type.inner, node?.kind === \"optional\" ? node.attrs.node : undefined);\n case \"list\": {\n const repeat = node?.kind === \"repeat\" ? node : undefined;\n const schema: JsonSchema = {\n type: \"array\",\n items: this.fromType(type.item, repeat?.attrs.node),\n };\n // Bounded/fixed-length vectors (e.g. a 3-element coordinate) carry length\n // constraints so a form consumer can render the right number of slots.\n if (repeat?.attrs.countMin !== undefined) schema.minItems = repeat.attrs.countMin;\n if (repeat?.attrs.countMax !== undefined) schema.maxItems = repeat.attrs.countMax;\n return schema;\n }\n case \"struct\":\n return this.structSchema(type, node);\n case \"union\":\n return this.unionSchema(type);\n }\n }\n\n private findTerminal(node: Expr): Expr {\n switch (node.kind) {\n case \"optional\":\n return this.findTerminal(node.attrs.node);\n case \"repeat\":\n return this.findTerminal(node.attrs.node);\n case \"sequence\": {\n const nonLiteral = node.attrs.nodes.find((n) => n.kind !== \"literal\");\n return nonLiteral ? this.findTerminal(nonLiteral) : node;\n }\n default:\n return node;\n }\n }\n\n private scalarSchema(scalar: ScalarKind, node?: Expr): JsonSchema {\n const base: JsonSchema = {\n int: { type: \"integer\" } as JsonSchema,\n float: { type: \"number\" } as JsonSchema,\n str: { type: \"string\" } as JsonSchema,\n path: { type: \"string\", \"x-styx-type\": \"path\" } as JsonSchema,\n }[scalar];\n\n const terminal = node ? this.findTerminal(node) : undefined;\n if (terminal && (terminal.kind === \"int\" || terminal.kind === \"float\")) {\n if (terminal.attrs.minValue !== undefined) base.minimum = terminal.attrs.minValue;\n if (terminal.attrs.maxValue !== undefined) base.maximum = terminal.attrs.maxValue;\n }\n\n return base;\n }\n\n private structSchema(type: Extract<BoundType, { kind: \"struct\" }>, node?: Expr): JsonSchema {\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n\n // Use shared findStructNode for correct traversal through opt/rep/alt wrappers\n const structNode = node ? findStructNode(node, this.ctx, type) : undefined;\n if (structNode) {\n for (const child of structNode.attrs.nodes) {\n // Use shared resolveFieldBinding for correct collapsed-sequence handling\n const match = resolveFieldBinding(child, this.ctx, type);\n if (!match) continue;\n const { binding, wrapperNode } = match;\n\n const schema = this.fromType(binding.type, binding.node);\n const fieldType = type.fields[binding.name]!;\n\n // Use shared findDoc for correct doc propagation through collapsed sequences\n const doc =\n findDoc(wrapperNode, fieldType) ??\n findDoc(binding.node, fieldType) ??\n wrapperNode.meta?.doc?.description;\n if (doc) schema.description = doc;\n\n const title = wrapperNode.meta?.doc?.title ?? binding.node.meta?.doc?.title;\n if (title) schema.title = title;\n\n const defaultValue = wrapperNode.meta?.defaultValue ?? binding.node.meta?.defaultValue;\n if (defaultValue !== undefined) schema.default = defaultValue;\n\n properties[binding.name] = schema;\n if (fieldType.kind !== \"optional\" && defaultValue === undefined) {\n required.push(binding.name);\n }\n }\n } else {\n for (const [name, fieldType] of Object.entries(type.fields)) {\n properties[name] = this.fromType(fieldType);\n if (fieldType.kind !== \"optional\") {\n required.push(name);\n }\n }\n }\n\n const schema: JsonSchema = { type: \"object\", properties };\n if (required.length > 0) schema.required = required;\n return schema;\n }\n\n private unionSchema(type: Extract<BoundType, { kind: \"union\" }>): JsonSchema {\n const allLiterals = type.variants.every((v: BoundVariant) => v.type.kind === \"literal\");\n if (allLiterals) {\n return {\n enum: type.variants.map((v: BoundVariant) =>\n v.type.kind === \"literal\" ? v.type.value : \"\",\n ),\n };\n }\n return { oneOf: type.variants.map((v: BoundVariant) => this.fromType(v.type)) };\n }\n}\n\nexport function generateSchema(ctx: CodegenContext): JsonSchema {\n return new SchemaBuilder(ctx).build();\n}\n\n/** Output names are language-neutral in the schema; key by the raw descriptor id. */\nconst rawName = (name: string): string => name;\n\n/** The JSON Schema for one output field, given its solved shape. */\nfunction outputFieldSchema(shape: OutputShape): JsonSchema {\n // A list output is always present (an empty array when nothing is produced),\n // its elements never null: `OutputPathType[]` / `list[OutputPathType]`.\n if (shape.kind === \"list\") {\n return { type: \"array\", items: { type: \"string\", \"x-styx-type\": \"path\" } };\n }\n // A single output's key is always present on the Outputs object; when its gate\n // is off the value is `null` (the backends type it `OutputPathType | None` /\n // `OutputPathType | null`). So a gated single is a path OR null - not an\n // absent key. We mark it `required` (see below) and carry the null branch.\n if (shape.optional) return { type: [\"string\", \"null\"], \"x-styx-type\": \"path\" };\n return { type: \"string\", \"x-styx-type\": \"path\" };\n}\n\n/**\n * JSON Schema for a tool's **Outputs object**: the set of files it produces\n * (resolved outputs + mutable inputs surfaced as outputs) plus its captured\n * stdout/stderr streams. Built from the same `collectOutputFields` /\n * `streamFields` source of truth the Python and TypeScript backends use to type\n * the Outputs dataclass/interface, so the three describe the same shape.\n *\n * Field encoding (mirrors how the language backends type each field):\n * - required single -> `{ type: \"string\", x-styx-type: \"path\" }`\n * - optional single -> `{ type: [\"string\", \"null\"], x-styx-type: \"path\" }`\n * - list output -> `{ type: \"array\", items: { type: \"string\", x-styx-type: \"path\" } }`\n * - stream field -> `{ type: \"array\", items: { type: \"string\" } }` (lines of\n * text, NOT paths - the absent `x-styx-type` lets a consumer tell them apart)\n *\n * EVERY field is `required`: unlike the inputs schema (where an optional param\n * key is genuinely omitted, so \"not in `required`\" is faithful), an Outputs\n * field is always present - a gated single is `null`, a gated list is an empty\n * array. So optionality is carried by the `null` type branch, and a strict\n * validator accepts the actual emitted object (e.g. `{ \"out_file\": null }`).\n */\nexport function generateOutputsSchema(ctx: CodegenContext): JsonSchema {\n const schema: JsonSchema = {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n };\n if (ctx.app?.doc?.title) schema.title = ctx.app.doc.title;\n if (ctx.app?.doc?.description) schema.description = ctx.app.doc.description;\n\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n\n for (const field of collectOutputFields(ctx, rawName)) {\n const prop = outputFieldSchema(field.shape);\n if (field.doc) prop.description = field.doc;\n properties[field.name] = prop;\n required.push(field.name);\n }\n\n for (const stream of streamFields(ctx, rawName)) {\n const prop: JsonSchema = { type: \"array\", items: { type: \"string\" } };\n if (stream.doc) prop.description = stream.doc;\n properties[stream.name] = prop;\n required.push(stream.name);\n }\n\n schema.properties = properties;\n if (required.length > 0) schema.required = required;\n return schema;\n}\n\n/**\n * Filesystem-safe, unique-within-the-package stem for one tool's schema files.\n *\n * In catalog mode every tool in a package emits into the same `<pkg>/` directory,\n * so fixed `schema.json` names would clobber each other (only the last tool would\n * survive). We prefix each tool's files with a slug derived from its app id -\n * `snakeCase` so symbol-heavy ids like `3dfim+` / `@2dwarper.Allin` become safe,\n * lowercase, collision-resistant stems (`3dfim` / `2dwarper_allin`) - and dedup\n * through the shared package `scope` so the rare slug collision still gets a `_2`.\n *\n * Returns undefined when there is no scope (standalone single-tool emission, where\n * one unprefixed `schema.json` is unambiguous) or no app id (anonymous descriptor).\n */\nfunction schemaStem(ctx: CodegenContext, scope?: Scope): string | undefined {\n const id = ctx.app?.id;\n if (!id || !scope) return undefined;\n return scope.add(snakeCase(id) || \"schema\");\n}\n\nexport class JsonSchemaBackend implements Backend {\n readonly name = \"json-schema\";\n readonly target = \"json-schema\";\n\n /** One scope per package so per-tool schema file stems stay unique in the suite directory. */\n newPackageScope(): Scope {\n return new Scope();\n }\n\n emitApp(ctx: CodegenContext, scope?: Scope): EmittedApp {\n const schema = generateSchema(ctx);\n const outputsSchema = generateOutputsSchema(ctx);\n // In a catalog build, prefix with a per-tool stem so co-located tools don't\n // clobber one another; standalone single-tool builds keep the bare names.\n const stem = schemaStem(ctx, scope);\n const prefix = stem ? `${stem}.` : \"\";\n return {\n meta: ctx.app,\n // Inputs and outputs are kept as two cleanly addressable artifacts\n // (mirroring v1's `<tool>.input.json` / `<tool>.output.json` split): a\n // consumer can fetch/compute either independently.\n files: new Map([\n [`${prefix}schema.json`, JSON.stringify(schema, null, 2)],\n [`${prefix}outputs.schema.json`, JSON.stringify(outputsSchema, null, 2)],\n ]),\n errors: [],\n warnings: [],\n };\n }\n}\n","import type { BoundType } from \"../../bindings/index.js\";\n\nexport function mapType(type: BoundType, resolve: (type: BoundType) => string | undefined): string {\n switch (type.kind) {\n case \"scalar\":\n return { int: \"number\", float: \"number\", str: \"string\", path: \"InputPathType\" }[type.scalar];\n case \"bool\":\n return \"boolean\";\n case \"count\":\n return \"number\";\n case \"literal\":\n return typeof type.value === \"string\" ? JSON.stringify(type.value) : String(type.value);\n case \"optional\":\n // The solver has no nullable type: `optional` means \"omittable\" (the key\n // may be absent), never \"the value may be null\". Omittability is expressed\n // structurally at the field level (`?:` on the interface key, NotRequired\n // in Python); the value type itself is just the inner type. So in any\n // value position (nested list/union arm, validator messages) we render the\n // inner type with no `| null | undefined`.\n return mapType(type.inner, resolve);\n case \"list\": {\n const inner = mapType(type.item, resolve);\n return inner.includes(\"|\") ? `Array<${inner}>` : `${inner}[]`;\n }\n case \"struct\": {\n const name = resolve(type);\n if (name) return name;\n const fields = Object.entries(type.fields)\n .filter(([, v]) => v.kind !== \"literal\")\n .map(([k, v]) => `${k}: ${mapType(v, resolve)}`)\n .join(\"; \");\n return `{ ${fields} }`;\n }\n case \"union\": {\n const name = resolve(type);\n if (name) return name;\n return type.variants.map((v) => mapType(v.type, resolve)).join(\" | \");\n }\n }\n}\n\n/** Render a JS default value as a TypeScript literal (signatures, `?? default`). */\nexport function renderTsLiteral(value: string | number | boolean): string {\n if (typeof value === \"boolean\") return value ? \"true\" : \"false\";\n if (typeof value === \"number\") return Number.isFinite(value) ? String(value) : \"NaN\";\n return JSON.stringify(value);\n}\n","import type { ProjectMeta } from \"../../manifest/index.js\";\nimport type { EmittedPackage } from \"../backend.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport { Scope } from \"../scope.js\";\nimport { STYXDEFS_COMPAT } from \"../styxdefs-compat.js\";\n\n// JS keywords that are illegal as the binding name in `export * as <name>`\n// (`default` is intentionally allowed - it is valid there).\nconst NS_RESERVED = [\n \"import\",\n \"export\",\n \"class\",\n \"function\",\n \"const\",\n \"let\",\n \"var\",\n \"return\",\n \"new\",\n \"delete\",\n \"typeof\",\n \"void\",\n \"in\",\n \"instanceof\",\n \"enum\",\n \"extends\",\n \"super\",\n];\n\nfunction description(proj: ProjectMeta): string {\n if (proj.doc?.description) return proj.doc.description;\n return `Styx generated wrappers for ${proj.doc?.title ?? proj.name ?? \"tools\"}.`;\n}\n\n/** npm names must be lowercase and URL-safe; normalize or fall back. */\nfunction npmName(name: string | undefined): string {\n const normalized = (name ?? \"\")\n .toLowerCase()\n .replace(/[^a-z0-9-._]/g, \"-\")\n .replace(/^[-._]+/, \"\");\n return normalized || \"styx-wrappers\";\n}\n\n/**\n * Single npm `package.json` for the whole project (TypeScript ships one package\n * spanning all suites, unlike Python's per-suite distributions). The styxdefs\n * floor is baked in as the lone runtime dependency.\n */\nexport function generatePackageJson(proj: ProjectMeta): string {\n const pkg = {\n name: npmName(proj.name),\n version: proj.version ?? \"0.0.0\",\n description: description(proj),\n type: \"module\",\n types: \"./dist/index.d.ts\",\n main: \"./dist/index.js\",\n exports: {\n \".\": {\n types: \"./dist/index.d.ts\",\n import: \"./dist/index.js\",\n },\n },\n files: [\"dist\"],\n scripts: {\n build: \"tsc\",\n prepublishOnly: \"npm run build\",\n },\n license: proj.license?.description ?? \"unknown\",\n dependencies: {\n styxdefs: STYXDEFS_COMPAT.npm,\n },\n devDependencies: {\n typescript: \"^5.6.0\",\n },\n };\n return JSON.stringify(pkg, null, 2) + \"\\n\";\n}\n\n/** Turn a suite directory name into a valid JS namespace identifier. */\nfunction nsIdent(name: string): string {\n const cleaned = name.replace(/[^a-zA-Z0-9_$]/g, \"_\");\n return /^[0-9]/.test(cleaned) ? `_${cleaned}` : cleaned;\n}\n\n/**\n * Root barrel namespacing each per-suite `index.ts` by suite\n * (`export * as afni from \"./afni/index.js\"`). Namespacing avoids cross-suite\n * collisions when the same tool id appears in two suites, and keeps the root\n * from flattening every tool into one giant namespace.\n */\nexport function generateRootIndex(packages: EmittedPackage[]): string {\n const cb = new CodeBuilder(\" \");\n cb.comment(\"This file was auto generated by Styx.\");\n cb.comment(\"Do not edit this file directly.\");\n cb.blank();\n\n const dirs = packages\n .map((p) => p.meta?.name)\n .filter((name): name is string => !!name)\n .sort();\n\n // Dodge namespace collisions (two dirs cleaning to the same identifier, or a\n // dir named like a keyword) the same way per-tool names are dodged.\n const nsScope = new Scope(NS_RESERVED);\n for (const dir of dirs) {\n const ns = nsScope.add(nsIdent(dir));\n cb.line(`export * as ${ns} from \"./${dir}/index.js\";`);\n }\n\n return cb.toString() + \"\\n\";\n}\n\n/** Minimal `tsconfig.json` producing ESM + declarations into `dist/`. */\nexport function generateTsconfig(): string {\n const config = {\n compilerOptions: {\n target: \"ES2020\",\n module: \"NodeNext\",\n moduleResolution: \"NodeNext\",\n declaration: true,\n outDir: \"./dist\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n forceConsistentCasingInFileNames: true,\n },\n include: [\"**/*.ts\"],\n exclude: [\"dist\", \"node_modules\"],\n };\n return JSON.stringify(config, null, 2) + \"\\n\";\n}\n","import type { Binding, BindingId, BoundType, BoundVariant } from \"../../bindings/index.js\";\nimport { collectFieldInfo } from \"../collect-field-info.js\";\nimport type { Expr } from \"../../ir/index.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport { structVariants } from \"../union-variants.js\";\nimport { renderAccess } from \"./emit.js\";\nimport { renderTsLiteral } from \"./typemap.js\";\n\n// -- Result types --\n\ninterface Expr_ {\n expr: string;\n}\ninterface Stmt {\n stmt: string;\n}\nexport type ArgResult = Expr_ | Stmt;\n\nfunction isExpr(r: ArgResult): r is Expr_ {\n return \"expr\" in r;\n}\n\nexport function resultToStmt(r: ArgResult): string {\n return isExpr(r) ? `cargs.push(${r.expr});` : r.stmt;\n}\n\nfunction appendLines(cb: CodeBuilder, code: string): void {\n for (const line of code.split(\"\\n\")) cb.line(line);\n}\n\n// -- Type helpers --\n\nfunction toStringExpr(node: Expr, type: BoundType, expr: string): string {\n if (type.kind === \"scalar\") {\n if (type.scalar === \"str\") return expr;\n if (type.scalar === \"path\") return pathArg(node, expr);\n }\n return `String(${expr})`;\n}\n\n/**\n * Command-line value for a path input via `execution.inputFile`. The styxdefs\n * signature is `inputFile(hostFile, resolveParent?, mutable?)`, so `mutable`\n * requires supplying `resolveParent` positionally first. `mutable=true` tells\n * the runner to stage a writable COPY (original untouched) and return the copy's\n * command-line path; the outputs builder surfaces that same copy's host path via\n * `execution.mutableCopy`.\n */\nfunction pathArg(node: Expr, expr: string): string {\n if (node.kind !== \"path\") return `execution.inputFile(${expr})`;\n const { resolveParent, mutable } = node.attrs;\n if (mutable) return `execution.inputFile(${expr}, ${resolveParent ? \"true\" : \"false\"}, true)`;\n if (resolveParent) return `execution.inputFile(${expr}, true)`;\n return `execution.inputFile(${expr})`;\n}\n\n// -- Context passed down through recursion --\n\ninterface ArgContext {\n /** Join nesting depth (controls ternary vs if-statement for optionals). */\n joinDepth: number;\n /**\n * Loop variables bound by enclosing `repeat`-of-list nodes, keyed by the\n * repeat binding's id. `renderAccess` consults this to resolve the `iter`\n * segments in a binding's solver-assigned access path.\n */\n loopVars: ReadonlyMap<BindingId, string>;\n /**\n * Rendered TS default literals for root-level NON-OPTIONAL fields that carry a\n * Boutiques default (e.g. `maskfile -> \"img_bet\"`), keyed by field name. Such a\n * field is `?:` (a hand-authored config may omit it) yet is read\n * unconditionally - so every read of its value becomes `(access ?? <default>)`\n * to substitute the default instead of stringifying `undefined`. Optional\n * fields are excluded: they are presence-guarded (their default, if any, comes\n * from the factory's kwarg signature).\n */\n defaults: ReadonlyMap<string, string>;\n}\n\n/** Render a binding's solver-assigned access path in the current loop scope. */\nfunction accessOf(binding: Binding, arg: ArgContext): string {\n return renderAccess(binding.access, (b) => {\n const v = arg.loopVars.get(b);\n if (v === undefined) throw new Error(`arg-builder: unbound loop variable for binding ${b}`);\n return v;\n });\n}\n\n/**\n * The rendered default for a binding iff it is a root-level NON-OPTIONAL field\n * carrying a Boutiques default. Restricted to single-segment (root) field access\n * so a nested field can never accidentally pick up a same-named root default.\n */\nfunction rootFieldDefault(\n binding: Binding,\n defaults: ReadonlyMap<string, string>,\n): string | undefined {\n const a = binding.access;\n if (a.length === 1 && a[0]?.kind === \"field\") return defaults.get(binding.name);\n return undefined;\n}\n\n/**\n * Render a binding's access for an UNCONDITIONAL value read (terminal, repeat\n * loop, alternative dispatch): substitutes the field's default via\n * `(access ?? default)` when it is a defaulted non-optional field, else the\n * plain access. Returns plain access for every non-defaulted field, so the\n * emitted code is byte-identical to before for the common case.\n */\nfunction readAccess(binding: Binding, arg: ArgContext): string {\n const def = rootFieldDefault(binding, arg.defaults);\n return def !== undefined ? `(${accessOf(binding, arg)} ?? ${def})` : accessOf(binding, arg);\n}\n\n/** Build the field-name -> rendered-default map for a struct root (else empty).\n * Includes only non-optional defaulted fields (optional fields are\n * presence-guarded; their default comes from the factory's kwarg signature). */\nfunction collectDefaults(ctx: CodegenContext, rootType?: BoundType): Map<string, string> {\n const out = new Map<string, string>();\n if (rootType?.kind !== \"struct\") return out;\n for (const [name, fi] of collectFieldInfo(ctx, rootType)) {\n if (fi.defaultValue === undefined) continue;\n if (rootType.fields[name]?.kind === \"optional\") continue;\n out.set(name, renderTsLiteral(fi.defaultValue));\n }\n return out;\n}\n\n// -- Recursive descent --\n\nlet loopVarCounter = 0;\n\n/**\n * Build arg-building code for an IR tree via recursive descent.\n *\n * Context flows down via the immutable `arg` parameter (access paths, join depth, etc.).\n * Results flow up via return values (expressions or statement blocks).\n */\nexport function buildArgs(rootExpr: Expr, ctx: CodegenContext, rootType?: BoundType): ArgResult {\n loopVarCounter = 0;\n const initialCtx: ArgContext = {\n joinDepth: 0,\n loopVars: new Map(),\n defaults: collectDefaults(ctx, rootType),\n };\n return walk(rootExpr, ctx, initialCtx);\n}\n\nfunction walk(node: Expr, ctx: CodegenContext, arg: ArgContext): ArgResult {\n switch (node.kind) {\n case \"literal\":\n return { expr: JSON.stringify(node.attrs.str) };\n\n case \"int\":\n case \"float\":\n case \"str\":\n case \"path\":\n return walkTerminal(node, ctx, arg);\n\n case \"sequence\":\n return walkSequence(node, ctx, arg);\n\n case \"optional\":\n return walkOptional(node, ctx, arg);\n\n case \"repeat\":\n return walkRepeat(node, ctx, arg);\n\n case \"alternative\":\n return walkAlternative(node, ctx, arg);\n }\n}\n\nfunction walkTerminal(node: Expr, ctx: CodegenContext, arg: ArgContext): ArgResult {\n const binding = ctx.resolve(node);\n if (!binding) throw new Error(`Missing binding for terminal node: ${node.kind}`);\n // A root-level defaulted field (e.g. an output basename `maskfile=\"img_bet\"`)\n // is read here unconditionally but is `?:`, so `readAccess` substitutes the\n // default for an absent key via `(access ?? default)`.\n return { expr: toStringExpr(node, binding.type, readAccess(binding, arg)) };\n}\n\nfunction walkSequence(\n node: Extract<Expr, { kind: \"sequence\" }>,\n ctx: CodegenContext,\n arg: ArgContext,\n): ArgResult {\n // A non-join sequence inside an outer join must concatenate (rather than\n // push separate args) so it can stand in as a single Expr element of the\n // outer join. Boutiques produces this shape for `command-line-flag` inputs\n // nested under a parent join template (e.g. `[OUTPUT][FLAG]` -> seqJoin('')\n // around an opt(seq(lit(FLAG), value))).\n const join = node.attrs.join ?? (arg.joinDepth > 0 ? \"\" : undefined);\n\n // Struct scoping is already baked into each child's access path by the\n // solver; here we only thread join depth (a codegen concern).\n const childArg: ArgContext = join !== undefined ? { ...arg, joinDepth: arg.joinDepth + 1 } : arg;\n\n const parts = node.attrs.nodes.map((child) => walk(child, ctx, childArg));\n\n if (join !== undefined) {\n const exprs = parts.map((p) => (isExpr(p) ? p.expr : p.stmt));\n if (exprs.length === 1) return { expr: exprs[0]! };\n return { expr: `[${exprs.join(\", \")}].join(${JSON.stringify(join)})` };\n }\n\n return { stmt: parts.map(resultToStmt).join(\"\\n\") };\n}\n\nfunction walkOptional(\n node: Extract<Expr, { kind: \"optional\" }>,\n ctx: CodegenContext,\n arg: ArgContext,\n): ArgResult {\n const binding = ctx.resolve(node);\n if (!binding) throw new Error(\"Missing binding for optional node\");\n const access = accessOf(binding, arg);\n\n // The inner node's access path is solver-assigned (it either inherits this\n // optional's path on a collapse, or scopes into it for a struct), so no scope\n // context needs threading - only the existing loop scope and join depth.\n const inner = walk(node.attrs.node, ctx, arg);\n\n // Inside a join context, emit as ternary expression\n if (arg.joinDepth > 0 && isExpr(inner)) {\n if (binding.type.kind === \"optional\") {\n return { expr: `(${access} != null ? ${inner.expr} : \"\")` };\n }\n return { expr: `(${access} ? ${inner.expr} : \"\")` };\n }\n\n const cb = new CodeBuilder(\" \");\n const innerStmt = resultToStmt(inner);\n if (binding.type.kind === \"optional\") {\n cb.line(`if (${access} != null) {`);\n cb.indent(() => appendLines(cb, innerStmt));\n cb.line(\"}\");\n } else {\n cb.line(`if (${access}) {`);\n cb.indent(() => appendLines(cb, innerStmt));\n cb.line(\"}\");\n }\n return { stmt: cb.toString() };\n}\n\nfunction walkRepeat(\n node: Extract<Expr, { kind: \"repeat\" }>,\n ctx: CodegenContext,\n arg: ArgContext,\n): ArgResult {\n const binding = ctx.resolve(node);\n if (!binding) throw new Error(\"Missing binding for repeat node\");\n // A non-join repeat inside an outer join concatenates rather than pushing\n // separate args, mirroring walkSequence's handling of bare non-join seqs.\n const join = node.attrs.join ?? (arg.joinDepth > 0 ? \"\" : undefined);\n // Unconditional read (the count/list value) - `readAccess` substitutes a\n // defaulted non-optional field's default for an absent key.\n const access = readAccess(binding, arg);\n\n // Count repeat: emit a counted for-loop. Inside a join the for-loop would\n // be dropped into a list literal as raw text, so emit `Array.from` instead.\n if (binding.type.kind === \"count\") {\n const inner = walk(node.attrs.node, ctx, arg);\n const v = `i${loopVarCounter++}`;\n if (join !== undefined && isExpr(inner)) {\n return {\n expr: `Array.from({length: ${access}}, (_, ${v}) => ${inner.expr}).join(${JSON.stringify(join)})`,\n };\n }\n const cb = new CodeBuilder(\" \");\n cb.line(`for (let ${v} = 0; ${v} < ${access}; ${v}++) {`);\n cb.indent(() => appendLines(cb, resultToStmt(inner)));\n cb.line(\"}\");\n return { stmt: cb.toString() };\n }\n\n // List repeat: emit a for-of loop or .map().join(). The loop variable is\n // registered under this repeat's binding id so inner bindings' `iter`\n // segments resolve to it via `renderAccess`.\n const loopVar = `item${loopVarCounter++}`;\n const childArg: ArgContext = {\n ...arg,\n loopVars: new Map(arg.loopVars).set(binding.id, loopVar),\n };\n\n const inner = walk(node.attrs.node, ctx, childArg);\n\n if (join !== undefined && isExpr(inner)) {\n return { expr: `${access}.map((${loopVar}) => ${inner.expr}).join(${JSON.stringify(join)})` };\n }\n\n const cb = new CodeBuilder(\" \");\n cb.line(`for (const ${loopVar} of ${access}) {`);\n cb.indent(() => appendLines(cb, resultToStmt(inner)));\n cb.line(\"}\");\n return { stmt: cb.toString() };\n}\n\nfunction walkAlternative(\n node: Extract<Expr, { kind: \"alternative\" }>,\n ctx: CodegenContext,\n arg: ArgContext,\n): ArgResult {\n const binding = ctx.resolve(node);\n if (!binding) throw new Error(\"Missing binding for alternative node\");\n // Unconditional read (the enum value / bool guard / union discriminator) -\n // `readAccess` substitutes a defaulted non-optional field's default for an\n // absent key (e.g. a `value-choices` String with a default).\n const access = readAccess(binding, arg);\n\n // Complex-union variant fields already carry the union's path in their\n // solver-assigned access, so arms walk with the current context unchanged.\n const variants = node.attrs.alts.map((alt) => walk(alt, ctx, arg));\n\n if (\n binding.type.kind === \"union\" &&\n binding.type.variants.every((v: BoundVariant) => v.type.kind === \"literal\")\n ) {\n return { expr: `String(${access})` };\n }\n\n if (binding.type.kind === \"bool\") {\n // Inside a join, the alternative's output must be an expression, not a\n // statement: dropping an `if/else` block into a `[...].join(\"\")` list\n // literal is not valid TypeScript. Emit a ternary when both arms are exprs.\n if (arg.joinDepth > 0) {\n if (!variants[1]) {\n throw new Error(\n \"single-arm bool alternative inside a join: cannot produce an expression \" +\n \"without ambiguous semantics (omitting the entry vs emitting empty string)\",\n );\n }\n if (!variants.every(isExpr)) {\n throw new Error(\n \"bool alternative inside a join has statement-shaped variants; \" +\n \"expected all arms to fold to expressions\",\n );\n }\n const v0 = (variants[0] as Expr_).expr;\n const v1 = (variants[1] as Expr_).expr;\n return { expr: `(${access} ? ${v0} : ${v1})` };\n }\n const cb = new CodeBuilder(\" \");\n cb.line(`if (${access}) {`);\n cb.indent(() => appendLines(cb, resultToStmt(variants[0]!)));\n if (variants[1]) {\n cb.line(\"} else {\");\n cb.indent(() => appendLines(cb, resultToStmt(variants[1]!)));\n }\n cb.line(\"}\");\n return { stmt: cb.toString() };\n }\n\n if (binding.type.kind === \"union\") {\n const unionType = binding.type;\n // A union may be pure-discriminated (every variant a struct with `@type`) or\n // mixed (struct variants plus bare-literal variants, e.g. ants\n // `Interpolation = \"Linear\" | MultiLabel | ...`). Pure-enum unions returned\n // above. Dispatch struct variants on `@type`; a bare literal is its own value.\n // `structVariants` throws if two share an `@type` (an unreachable, dead\n // branch - frontends must dodge duplicate tags before codegen).\n const structVars = structVariants(unionType);\n const hasLiteral = unionType.variants.some((v) => v.type.kind === \"literal\");\n\n // Inside a join: chained ternary, same reason as bool above.\n if (arg.joinDepth > 0) {\n if (!variants.every(isExpr)) {\n throw new Error(\n \"union alternative inside a join has statement-shaped variants; \" +\n \"expected all arms to fold to expressions\",\n );\n }\n let structExpr = '\"\"';\n for (let k = structVars.length - 1; k >= 0; k--) {\n const { variant, i } = structVars[k]!;\n const v = (variants[i] as Expr_).expr;\n structExpr = `(${access}[\"@type\"] === ${JSON.stringify(variant.name ?? \"\")} ? ${v} : ${structExpr})`;\n }\n if (!hasLiteral) return { expr: structExpr };\n // Mixed: an object value dispatches by `@type`; a bare literal is itself.\n return {\n expr: `(typeof ${access} === \"object\" && ${access} !== null ? ${structExpr} : String(${access}))`,\n };\n }\n\n const cb = new CodeBuilder(\" \");\n // `switch` (not an `if`/`else if` ===-chain): each `case` narrows the\n // discriminated union, whereas a chain accumulates narrowing and TS rejects\n // later arms (TS2367).\n const emitStructSwitch = (): void => {\n cb.line(`switch (${access}[\"@type\"]) {`);\n cb.indent(() => {\n for (const { variant, i } of structVars) {\n cb.line(`case ${JSON.stringify(variant.name ?? \"\")}: {`);\n cb.indent(() => {\n appendLines(cb, resultToStmt(variants[i]!));\n cb.line(\"break;\");\n });\n cb.line(\"}\");\n }\n });\n cb.line(\"}\");\n };\n if (!hasLiteral) {\n emitStructSwitch();\n return { stmt: cb.toString() };\n }\n // Mixed union: branch on runtime shape. `typeof === \"object\"` narrows to the\n // struct variants; the `else` to the bare-literal members.\n cb.line(`if (typeof ${access} === \"object\" && ${access} !== null) {`);\n cb.indent(emitStructSwitch);\n cb.line(`} else {`);\n cb.indent(() => appendLines(cb, resultToStmt({ expr: `String(${access})` })));\n cb.line(`}`);\n return { stmt: cb.toString() };\n }\n\n return { stmt: variants.map(resultToStmt).join(\"\\n\") };\n}\n","import type { AccessPath, BindingId, BoundType } from \"../../bindings/index.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport type { SigEntry, SigOptions } from \"../sig-entries.js\";\nimport type { ArgResult } from \"./arg-builder.js\";\nimport { buildArgs, resultToStmt } from \"./arg-builder.js\";\nimport { mapType, renderTsLiteral } from \"./typemap.js\";\nimport type { NamedType } from \"./types.js\";\nimport { collectFieldInfo, resolveTypeName } from \"./types.js\";\n\nexport function emitJsDoc(cb: CodeBuilder, description?: string): void {\n if (!description) return;\n const lines = description.split(\"\\n\");\n if (lines.length === 1) {\n cb.line(`/** ${lines[0]} */`);\n } else {\n cb.line(\"/**\");\n for (const line of lines) {\n cb.line(` * ${line}`);\n }\n cb.line(\" */\");\n }\n}\n\nexport function emitImports(cb: CodeBuilder, emitOutputs: boolean): void {\n const inputs = [\"Runner\", \"Execution\", \"Metadata\", \"InputPathType\"];\n if (emitOutputs) inputs.push(\"OutputPathType\");\n cb.line(`import type { ${inputs.join(\", \")} } from \"styxdefs\";`);\n cb.line('import { getGlobalRunner, StyxValidationError } from \"styxdefs\";');\n}\n\nexport function emitMetadata(ctx: CodegenContext, metaConst: string, cb: CodeBuilder): void {\n const id = ctx.app?.id ?? \"unknown\";\n const name = ctx.app?.doc?.title ?? ctx.app?.id ?? \"unknown\";\n const pkg = ctx.package?.name ?? \"unknown\";\n\n cb.line(`export const ${metaConst}: Metadata = {`);\n cb.indent(() => {\n cb.line(`id: ${JSON.stringify(id)},`);\n cb.line(`name: ${JSON.stringify(name)},`);\n cb.line(`package: ${JSON.stringify(pkg)},`);\n if (ctx.app?.doc?.literature?.length) {\n cb.line(`citations: ${JSON.stringify(ctx.app.doc.literature)},`);\n }\n if (ctx.app?.container?.image) {\n cb.line(`container_image_tag: ${JSON.stringify(ctx.app.container.image)},`);\n }\n });\n cb.line(\"};\");\n}\n\nexport function emitTypeDeclarations(\n typeDecls: NamedType[],\n namedTypes: Map<string, string>,\n ctx: CodegenContext,\n rootName: string,\n appId: string | undefined,\n pkg: string,\n cb: CodeBuilder,\n): void {\n const resolve = resolveTypeName(namedTypes);\n\n for (const { name, type } of typeDecls) {\n const isRoot = name === rootName;\n\n if (type.kind === \"struct\") {\n const fieldInfo = collectFieldInfo(ctx, type);\n\n cb.line(`export interface ${name} {`);\n cb.indent(() => {\n // @type discriminator on root params interface. Optional: the params\n // factory always sets it and runtime dispatch tables read it, but the\n // type system doesn't need it required (there's only one shape). Union\n // variants below keep their @type required - that one IS load-bearing\n // for discriminated-union narrowing.\n if (isRoot && appId) {\n cb.line(`\"@type\"?: \"${pkg}/${appId}\";`);\n }\n\n for (const [fieldName, fieldType] of Object.entries(type.fields)) {\n // Emit literal @type discriminators on union variant structs\n if (fieldType.kind === \"literal\") {\n if (fieldName === \"@type\") {\n cb.line(`\"@type\": ${JSON.stringify(fieldType.value)};`);\n }\n continue;\n }\n const fi = fieldInfo.get(fieldName);\n emitJsDoc(cb, fi?.doc);\n\n const isOptional = fieldType.kind === \"optional\";\n // A field is omittable (key may be absent) iff it is `optional` or it\n // carries a default (which includes flags - their `defaultValue` is\n // false). The default/absent case is handled by the params factory and\n // the absence-safe runtime reads; the type only needs to permit the key\n // to be missing. Never `| null`: the solver has no nullable, so a\n // present value is never null - omittability is the only \"unset\".\n const omittable = isOptional || fi?.defaultValue !== undefined;\n const optional = omittable ? \"?\" : \"\";\n\n const mapped = isOptional\n ? mapType(fieldType.inner, resolve)\n : mapType(fieldType, resolve);\n // Quote keys that aren't valid identifiers (e.g. `4d_input`). TS\n // allows reserved-word identifiers as interface keys without quotes.\n cb.line(`${tsObjKey(fieldName)}${optional}: ${mapped};`);\n }\n });\n cb.line(\"}\");\n cb.blank();\n } else if (type.kind === \"union\") {\n const parts = type.variants.map((v) => mapType(v.type, resolve));\n cb.line(`export type ${name} = ${parts.join(\" | \")};`);\n cb.blank();\n }\n }\n}\n\nexport function emitBuildCargs(\n ctx: CodegenContext,\n rootType: BoundType,\n paramsType: string,\n funcName: string,\n cb: CodeBuilder,\n): void {\n const paramsVar = \"params\";\n\n let result: ArgResult;\n try {\n result = buildArgs(ctx.expr, ctx, rootType);\n } catch {\n emitJsDoc(cb, \"Build command-line arguments from parameters.\");\n cb.line(\n `export function ${funcName}(_${paramsVar}: ${paramsType}, _execution: Execution): string[] {`,\n );\n cb.indent(() => cb.line(\"return [];\"));\n cb.line(\"}\");\n return;\n }\n\n const argsCode = resultToStmt(result);\n\n emitJsDoc(cb, \"Build command-line arguments from parameters.\");\n cb.line(\n `export function ${funcName}(${paramsVar}: ${paramsType}, execution: Execution): string[] {`,\n );\n cb.indent(() => {\n cb.line(\"const cargs: string[] = [];\");\n for (const line of argsCode.split(\"\\n\")) {\n if (line.trim()) cb.line(line);\n }\n cb.line(\"return cargs;\");\n });\n cb.line(\"}\");\n}\n\n/**\n * SigOptions hooks for TypeScript. The kwarg-signature sentinel for an optional\n * param is `T | null = null` - here `| null` is the *parameter* type (the\n * \"not provided\" sentinel a caller passes), not the dict field type, which is\n * just `T?`. Keeping the sentinel keeps the ergonomic `foo(x)` call where\n * omitted optionals default to `null` and the factory then drops them.\n */\nexport function tsSigOptions(resolve: (t: BoundType) => string | undefined): SigOptions {\n return {\n renderType: (t) => mapType(t, resolve),\n nullableSuffix: \" | null\",\n nullableDefault: \"null\",\n renderDefault: renderTsLiteral,\n };\n}\n\n/**\n * Scrub a Boutiques wire name into a valid TypeScript host identifier.\n * Mirrors Python's scrub: non-`[A-Za-z0-9_$]` replaced with `_`, digit\n * prefixes get `v_`, reserved-word matches get a trailing `_`. Dedupe through\n * a `Scope` for collisions with already-registered locals.\n */\nexport function tsScrubIdent(name: string, reserved: ReadonlySet<string>): string {\n let scrubbed = name.replace(/[^A-Za-z0-9_$]/g, \"_\");\n if (/^[0-9]/.test(scrubbed)) scrubbed = \"v_\" + scrubbed;\n if (scrubbed === \"\") scrubbed = \"_\";\n if (reserved.has(scrubbed)) scrubbed = scrubbed + \"_\";\n return scrubbed;\n}\n\nconst TS_IDENT_RE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\n/**\n * Render a TypeScript property access path. Uses dot notation when the key is\n * a valid identifier, bracket notation otherwise. (Wire keys like `4d_input`\n * or `@type` can't be dot-accessed.)\n */\nexport function tsPropAccess(base: string, key: string): string {\n return TS_IDENT_RE.test(key) ? `${base}.${key}` : `${base}[${JSON.stringify(key)}]`;\n}\n\n/**\n * Render a solver-assigned `AccessPath` to a TypeScript expression. Starts from\n * `params`; each `field` segment descends a property, and each `iter` segment\n * resets the base to the loop variable bound to that repeat binding (resolved\n * via `lookupLoopVar` - the `iter` gate atom's loop in outputs codegen, or the\n * arg-builder's local loop). Both the arg-builder and the outputs emitter feed\n * this one function instead of re-deriving paths.\n */\nexport function renderAccess(\n path: AccessPath,\n lookupLoopVar: (binding: BindingId) => string,\n): string {\n let cur = \"params\";\n for (const seg of path) {\n cur = seg.kind === \"field\" ? tsPropAccess(cur, seg.name) : lookupLoopVar(seg.binding);\n }\n return cur;\n}\n\n/**\n * Render a TypeScript object-literal key. Bare ident when valid, quoted\n * otherwise. (`name: ...` for `name`, `\"4d_input\": ...` for `4d_input`.)\n */\nexport function tsObjKey(key: string): string {\n return TS_IDENT_RE.test(key) ? key : JSON.stringify(key);\n}\n\n/** Emit `name: type [= default],` lines (one per entry) into `cb`. */\nfunction emitSigParams(entries: readonly SigEntry[], cb: CodeBuilder): void {\n for (const e of entries) {\n if (e.sigDefault !== undefined) {\n cb.line(`${e.name}: ${e.sigType} = ${e.sigDefault},`);\n } else {\n cb.line(`${e.name}: ${e.sigType},`);\n }\n }\n}\n\n/** Emit `@param <name> <doc>` JSDoc lines (trimmed empty docs) for each entry. */\nfunction emitJsDocParams(\n entries: readonly { name: string; doc?: string }[],\n cb: CodeBuilder,\n): void {\n for (const e of entries) {\n cb.line(` * @param ${e.name} ${e.doc ?? \"\"}`.trimEnd());\n }\n}\n\n/**\n * Emit the `<tool>Params(...)` factory: a kwarg-style builder for the params\n * object. Non-optional fields (required, and defaulted scalars whose default\n * lives on the signature) are always set in the literal. Every optional field is\n * set conditionally when not null - including optional-with-default ones: their\n * value type is `T | null` (the omit sentinel) but the dict field is the\n * non-null `T?`, so a bare literal assignment of a possibly-null value would not\n * type-check. When the caller omits the arg, the signature default (a concrete\n * non-null value) flows through the guard and is written.\n */\nexport function emitParamsFactory(\n entries: readonly SigEntry[],\n funcName: string,\n paramsType: string,\n typeTag: string | undefined,\n cb: CodeBuilder,\n): void {\n // JSDoc\n cb.line(\"/**\");\n cb.line(\" * Build parameters.\");\n if (entries.length > 0) cb.line(\" *\");\n emitJsDocParams(entries, cb);\n cb.line(\" *\");\n cb.line(\" * @returns Parameter object.\");\n cb.line(\" */\");\n\n if (entries.length === 0) {\n cb.line(`export function ${funcName}(): ${paramsType} {`);\n } else {\n cb.line(`export function ${funcName}(`);\n cb.indent(() => emitSigParams(entries, cb));\n cb.line(`): ${paramsType} {`);\n }\n cb.indent(() => {\n cb.line(`const params: ${paramsType} = {`);\n cb.indent(() => {\n if (typeTag !== undefined) cb.line(`\"@type\": ${JSON.stringify(typeTag)},`);\n for (const e of entries) {\n if (!e.isOptional) {\n cb.line(`${tsObjKey(e.wireKey)}: ${e.name},`);\n }\n }\n });\n cb.line(\"};\");\n for (const e of entries) {\n if (e.isOptional) {\n cb.line(`if (${e.name} !== null) {`);\n cb.indent(() => cb.line(`${tsPropAccess(\"params\", e.wireKey)} = ${e.name};`));\n cb.line(\"}\");\n }\n }\n cb.line(\"return params;\");\n });\n cb.line(\"}\");\n}\n\n/**\n * Emit the user-facing kwarg wrapper: takes the same kwargs as the factory\n * plus `runner`, builds the params object, and delegates to the dict-style\n * execute function.\n */\nexport function emitKwargWrapper(\n ctx: CodegenContext,\n entries: readonly SigEntry[],\n funcName: string,\n paramsFnName: string,\n executeFnName: string,\n outputsType: string | undefined,\n cb: CodeBuilder,\n): void {\n const appDoc = ctx.app?.doc;\n cb.line(\"/**\");\n if (appDoc?.title) cb.line(` * ${appDoc.title}`);\n if (appDoc?.description) {\n if (appDoc?.title) cb.line(\" *\");\n cb.line(` * ${appDoc.description}`);\n }\n if (appDoc?.authors?.length) {\n cb.line(\" *\");\n cb.line(` * Author: ${appDoc.authors.join(\", \")}`);\n }\n if (appDoc?.urls?.length) {\n cb.line(\" *\");\n cb.line(` * URL: ${appDoc.urls[0]}`);\n }\n cb.line(\" *\");\n emitJsDocParams(\n [...entries, { name: \"runner\", doc: \"Command runner (defaults to global runner).\" }],\n cb,\n );\n cb.line(\" *\");\n cb.line(\n outputsType\n ? \" * @returns Tool outputs (paths to files produced by the tool).\"\n : \" * @returns void\",\n );\n cb.line(\" */\");\n\n const returnType = outputsType ?? \"void\";\n cb.line(`export function ${funcName}(`);\n cb.indent(() => {\n emitSigParams(entries, cb);\n cb.line(\"runner: Runner | null = null,\");\n });\n cb.line(`): ${returnType} {`);\n\n cb.indent(() => {\n if (entries.length === 0) {\n cb.line(`const params = ${paramsFnName}();`);\n } else {\n cb.line(`const params = ${paramsFnName}(`);\n cb.indent(() => {\n for (const e of entries) cb.line(`${e.name},`);\n });\n cb.line(\");\");\n }\n if (outputsType) {\n cb.line(`return ${executeFnName}(params, runner);`);\n } else {\n cb.line(`${executeFnName}(params, runner);`);\n }\n });\n cb.line(\"}\");\n}\n\nexport function emitWrapperFunction(\n ctx: CodegenContext,\n paramsType: string,\n funcName: string,\n metaConst: string,\n cargsFunc: string,\n outputsFunc: string | undefined,\n outputsType: string | undefined,\n validateFunc: string | undefined,\n streams: { stdout?: string; stderr?: string },\n cb: CodeBuilder,\n): void {\n const appDoc = ctx.app?.doc;\n const docLines: string[] = [];\n if (appDoc?.title) docLines.push(appDoc.title);\n if (appDoc?.description) {\n if (docLines.length > 0) docLines.push(\"\");\n docLines.push(appDoc.description);\n }\n if (appDoc?.authors?.length) {\n docLines.push(\"\");\n docLines.push(`Author: ${appDoc.authors.join(\", \")}`);\n }\n if (appDoc?.urls?.length) {\n docLines.push(\"\");\n docLines.push(`URL: ${appDoc.urls[0]}`);\n }\n\n const emitOutputs = outputsFunc !== undefined;\n\n if (docLines.length > 0) {\n cb.line(\"/**\");\n for (const line of docLines) {\n cb.line(` * ${line}`);\n }\n cb.line(\" *\");\n cb.line(\" * @param params - The parameters.\");\n cb.line(\" * @param runner - Command runner (defaults to global runner).\");\n if (emitOutputs) cb.line(\" * @returns Tool outputs (paths to files produced by the tool).\");\n cb.line(\" */\");\n }\n\n const returnType = emitOutputs && outputsType ? outputsType : \"void\";\n cb.line(\n `export function ${funcName}(params: ${paramsType}, runner: Runner | null = null): ${returnType} {`,\n );\n cb.indent(() => {\n // Validate the params object first (the kwarg wrapper delegates here, so it\n // gets validation transitively; the statically-typed kwargs don't need it).\n if (validateFunc) cb.line(`${validateFunc}(params);`);\n cb.line(\"runner = runner ?? getGlobalRunner();\");\n cb.line(`const execution = runner.startExecution(${metaConst});`);\n cb.line(\"execution.params(params);\");\n // Local names `args`/`out` avoid colliding with the module-level `cargs` /\n // `outputs` functions when they share generic names.\n cb.line(`const args = ${cargsFunc}(params, execution);`);\n if (emitOutputs) {\n cb.line(`const out = ${outputsFunc}(params, execution);`);\n const { stdout, stderr } = streams;\n if (stdout || stderr) {\n // run(cargs, handleStdout?, handleStderr?): pass `undefined` for an\n // absent stdout handler so a stderr-only handler lands in position 3.\n const runArgs = [\"args\"];\n runArgs.push(\n stdout ? `(s: string): void => { ${tsPropAccess(\"out\", stdout)}.push(s); }` : \"undefined\",\n );\n if (stderr) {\n runArgs.push(`(s: string): void => { ${tsPropAccess(\"out\", stderr)}.push(s); }`);\n }\n cb.line(`execution.run(${runArgs.join(\", \")});`);\n } else {\n cb.line(\"execution.run(args);\");\n }\n cb.line(\"return out;\");\n } else {\n cb.line(\"execution.run(args);\");\n }\n });\n cb.line(\"}\");\n}\n","import type { BoundType } from \"../../bindings/index.js\";\nimport type { Expr } from \"../../ir/index.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport type { CodeBuilder } from \"../code-builder.js\";\nimport type { Scope } from \"../scope.js\";\nimport {\n findAlternativeNode,\n findRangeNode,\n findRepeatNode,\n structFields,\n} from \"../validate-walk.js\";\nimport { structVariants } from \"../union-variants.js\";\nimport { emitJsDoc, tsPropAccess } from \"./emit.js\";\nimport { mapType } from \"./typemap.js\";\n\n/**\n * Emit a `<tool>Validate(params)` function that walks the solved root\n * `BoundType` and throws `StyxValidationError` on invalid input. Hand-rolled\n * (no runtime deps): `typeof`/`Array.isArray` stand in for Python's\n * `isinstance`. Mirrors the Python backend's validation behavior, inlined into\n * a single function.\n */\n\ntype Resolve = (t: BoundType) => string | undefined;\n\ninterface Emit {\n ctx: CodegenContext;\n resolve: Resolve;\n /** Per-function scope for generated locals (loop vars), reserving `params`. */\n scope: Scope;\n cb: CodeBuilder;\n}\n\nexport function emitValidate(\n ctx: CodegenContext,\n rootType: BoundType,\n rootNode: Expr,\n paramsType: string,\n funcName: string,\n resolve: Resolve,\n scope: Scope,\n cb: CodeBuilder,\n): void {\n const e: Emit = { ctx, resolve, scope: scope.child([\"params\"]), cb };\n emitJsDoc(\n cb,\n `Validate untrusted parameters. Throws StyxValidationError if \\`params\\` is not a valid ${paramsType}; narrows it to ${paramsType} on success.`,\n );\n // Assertion signature over untyped input: a boundary guard usable on a parsed\n // dict / config blob, not just an already-typed value. The body walks `params`\n // dynamically, so the parameter is `any` (the assertion still narrows callers).\n cb.line(`export function ${funcName}(params: any): asserts params is ${paramsType} {`);\n cb.indent(() => emitRoot(e, rootType, rootNode));\n cb.line(\"}\");\n}\n\nfunction emitRoot(e: Emit, rootType: BoundType, rootNode: Expr): void {\n if (rootType.kind === \"struct\") {\n block(e, `typeof params !== \"object\" || params === null`, () =>\n raise(e, \"Params object has the wrong type\"),\n );\n for (const f of structFields(e.ctx, rootType, rootNode)) {\n emitField(e, f.name, f.type, f.node, f.hasDefault, \"params\");\n }\n } else if (rootType.kind === \"union\") {\n emitUnion(e, rootType, rootNode, \"params\", \"params\");\n } else {\n emitValue(e, rootType, rootNode, \"params\", \"params\", expectedType(e, rootType));\n }\n}\n\n/** Validate one struct field, handling required-presence vs optional gating. */\nfunction emitField(\n e: Emit,\n name: string,\n fieldType: BoundType,\n node: Expr | undefined,\n hasDefault: boolean,\n base: string,\n): void {\n if (fieldType.kind === \"literal\") return;\n\n const access = tsPropAccess(base, name);\n const expected = expectedType(e, fieldType);\n const valueType = fieldType.kind === \"optional\" ? fieldType.inner : fieldType;\n\n // Optionals and defaulted fields/flags accept null (null = \"use default\"), so\n // gate the body instead of requiring presence.\n if (fieldType.kind === \"optional\" || hasDefault) {\n e.cb.line(`if (${access} != null) {`);\n e.cb.indent(() => emitValue(e, valueType, node, name, access, expected));\n e.cb.line(\"}\");\n } else {\n block(e, `${access} == null`, () => raise(e, \"`\" + name + \"` must not be null\"));\n emitValue(e, valueType, node, name, access, expected);\n }\n}\n\n/** Validate a known-present value at `access` against `type`. */\nfunction emitValue(\n e: Emit,\n type: BoundType,\n node: Expr | undefined,\n wireKey: string,\n access: string,\n expected: string,\n): void {\n switch (type.kind) {\n case \"optional\":\n emitValue(e, type.inner, node, wireKey, access, expected);\n return;\n case \"literal\":\n return;\n case \"scalar\":\n switch (type.scalar) {\n case \"str\":\n case \"path\":\n checkType(e, `typeof ${access} !== \"string\"`, wireKey, expected);\n return;\n case \"int\":\n case \"float\":\n checkType(e, `typeof ${access} !== \"number\"`, wireKey, expected);\n emitRange(e, node, wireKey, access);\n return;\n }\n return;\n case \"bool\":\n checkType(e, `typeof ${access} !== \"boolean\"`, wireKey, expected);\n return;\n case \"count\":\n checkType(e, `typeof ${access} !== \"number\"`, wireKey, expected);\n return;\n case \"list\": {\n checkType(e, `!Array.isArray(${access})`, wireKey, expected);\n emitListLength(e, node, wireKey, access);\n const itemNode = findRepeatNode(node)?.attrs.node;\n const elem = e.scope.add(\"el\");\n e.cb.line(`for (const ${elem} of ${access}) {`);\n e.cb.indent(() => emitValue(e, type.item, itemNode, wireKey, elem, expected));\n e.cb.line(\"}\");\n return;\n }\n case \"struct\": {\n block(e, `typeof ${access} !== \"object\" || ${access} === null`, () =>\n raise(e, \"Params object has the wrong type\"),\n );\n for (const f of structFields(e.ctx, type, node)) {\n emitField(e, f.name, f.type, f.node, f.hasDefault, access);\n }\n return;\n }\n case \"union\":\n emitUnion(e, type, node, wireKey, access);\n return;\n }\n}\n\nfunction emitUnion(\n e: Emit,\n unionType: Extract<BoundType, { kind: \"union\" }>,\n node: Expr | undefined,\n wireKey: string,\n access: string,\n): void {\n const litVariants = unionType.variants.filter((v) => v.type.kind === \"literal\");\n const hasStruct = unionType.variants.some((v) => v.type.kind === \"struct\");\n\n // Pure enum/choice: no struct variants, just literal values (no `@type`).\n if (!hasStruct) {\n const values = litVariants.map(\n (v) => (v.type as Extract<BoundType, { kind: \"literal\" }>).value,\n );\n const allStr = values.every((x) => typeof x === \"string\");\n checkType(\n e,\n `typeof ${access} !== ${allStr ? '\"string\"' : '\"number\"'}`,\n wireKey,\n expectedType(e, unionType),\n );\n emitLiteralMembership(e, values, wireKey, access);\n return;\n }\n\n const altNode = findAlternativeNode(node);\n // Struct variants with their indices; throws if two share an `@type` (a\n // duplicate-tagged variant is unreachable and a mypy `comparison-overlap` in\n // the Python mirror - frontends must dodge duplicate tags before codegen).\n // The index keeps each arm aligned with the IR `alts`.\n const structVars = structVariants(unionType);\n const emitStructArm = (): void => {\n // `access` is known to be an object here.\n block(e, `!(\"@type\" in ${access})`, () => raise(e, \"Params object is missing `@type`\"));\n const names = structVars\n .map(({ variant }) => variant.name)\n .filter((n): n is string => n !== undefined)\n .map((n) => JSON.stringify(n));\n // `.includes` rather than a `!==`-chain: the discriminant is a closed literal\n // union and an exhaustive chain is rejected by TS as TS2367. It also leaves\n // the union un-narrowed, so the `switch` dispatch below narrows it.\n block(e, `![${names.join(\", \")}].includes(${access}[\"@type\"])`, () =>\n raise(e, \"Parameter `\" + wireKey + \"`s `@type` must be one of [\" + names.join(\", \") + \"]\"),\n );\n // `switch` (mirroring the cargs builder): each `case` narrows correctly,\n // whereas an `if`/`else if` chain on `===` accumulates narrowing and TS\n // rejects later arms.\n e.cb.line(`switch (${access}[\"@type\"]) {`);\n e.cb.indent(() => {\n structVars.forEach(({ variant, i }) => {\n const vt = variant.type as Extract<BoundType, { kind: \"struct\" }>;\n e.cb.line(`case ${JSON.stringify(variant.name ?? \"\")}: {`);\n e.cb.indent(() => {\n const fields = structFields(e.ctx, vt, altNode?.attrs.alts[i]).filter(\n (f) => f.type.kind !== \"literal\",\n );\n for (const f of fields) emitField(e, f.name, f.type, f.node, f.hasDefault, access);\n e.cb.line(\"break;\");\n });\n e.cb.line(\"}\");\n });\n });\n e.cb.line(\"}\");\n };\n\n // Pure discriminated union: every variant is a struct with an `@type`.\n if (litVariants.length === 0) {\n block(e, `typeof ${access} !== \"object\" || ${access} === null`, () =>\n raise(e, \"Params object has the wrong type\"),\n );\n emitStructArm();\n return;\n }\n\n // Mixed union: a value is either a struct (dict with `@type`) or a bare\n // literal. Branch on the runtime shape - `typeof === \"object\"` narrows to the\n // struct members, the `else` to the literal members.\n e.cb.line(`if (typeof ${access} === \"object\" && ${access} !== null) {`);\n e.cb.indent(emitStructArm);\n e.cb.line(`} else {`);\n e.cb.indent(() => {\n const values = litVariants.map(\n (v) => (v.type as Extract<BoundType, { kind: \"literal\" }>).value,\n );\n emitLiteralMembership(e, values, wireKey, access);\n });\n e.cb.line(\"}\");\n}\n\n/** Emit a `.includes`-based membership check over literal values. */\nfunction emitLiteralMembership(\n e: Emit,\n values: (string | number)[],\n wireKey: string,\n access: string,\n): void {\n const rendered = values.map(renderLiteral);\n block(e, `![${rendered.join(\", \")}].includes(${access})`, () =>\n raise(e, \"Parameter `\" + wireKey + \"` must be one of [\" + rendered.join(\", \") + \"]\"),\n );\n}\n\nfunction checkType(e: Emit, condition: string, wireKey: string, expected: string): void {\n block(e, condition, () =>\n raise(e, \"`\" + wireKey + \"` has the wrong type (expected \" + expected + \")\"),\n );\n}\n\nfunction emitRange(e: Emit, node: Expr | undefined, wireKey: string, access: string): void {\n const term = findRangeNode(node);\n if (!term) return;\n const { minValue, maxValue } = term.attrs;\n if (minValue !== undefined && maxValue !== undefined) {\n block(e, `!(${tsNum(minValue)} <= ${access} && ${access} <= ${tsNum(maxValue)})`, () =>\n raise(e, `Parameter \\`${wireKey}\\` must be between ${minValue} and ${maxValue} (inclusive)`),\n );\n } else if (minValue !== undefined) {\n block(e, `${access} < ${tsNum(minValue)}`, () =>\n raise(e, `Parameter \\`${wireKey}\\` must be at least ${minValue}`),\n );\n } else if (maxValue !== undefined) {\n block(e, `${access} > ${tsNum(maxValue)}`, () =>\n raise(e, `Parameter \\`${wireKey}\\` must be at most ${maxValue}`),\n );\n }\n}\n\nfunction emitListLength(e: Emit, node: Expr | undefined, wireKey: string, access: string): void {\n const rep = findRepeatNode(node);\n if (!rep) return;\n const { countMin, countMax } = rep.attrs;\n if (countMin !== undefined && countMax !== undefined) {\n block(e, `!(${countMin} <= ${access}.length && ${access}.length <= ${countMax})`, () =>\n raise(\n e,\n `Parameter \\`${wireKey}\\` must contain between ${countMin} and ${countMax} elements (inclusive)`,\n ),\n );\n } else if (countMin !== undefined) {\n block(e, `${access}.length < ${countMin}`, () =>\n raise(\n e,\n `Parameter \\`${wireKey}\\` must contain at least ${countMin} ${plural(\"element\", countMin)}`,\n ),\n );\n } else if (countMax !== undefined) {\n block(e, `${access}.length > ${countMax}`, () =>\n raise(\n e,\n `Parameter \\`${wireKey}\\` must contain at most ${countMax} ${plural(\"element\", countMax)}`,\n ),\n );\n }\n}\n\n// -- Emit helpers --\n\n/** Emit `if (<cond>) { <body> }`. */\nfunction block(e: Emit, condition: string, body: () => void): void {\n e.cb.line(`if (${condition}) {`);\n e.cb.indent(body);\n e.cb.line(\"}\");\n}\n\nfunction raise(e: Emit, message: string): void {\n e.cb.line(`throw new StyxValidationError(${JSON.stringify(message)});`);\n}\n\nfunction expectedType(e: Emit, type: BoundType): string {\n return mapType(type, e.resolve);\n}\n\nfunction renderLiteral(value: string | number): string {\n return typeof value === \"string\" ? JSON.stringify(value) : String(value);\n}\n\nfunction tsNum(n: number): string {\n return Number.isFinite(n) ? String(n) : \"NaN\";\n}\n\nfunction plural(word: string, count: number): string {\n return count === 1 ? word : `${word}s`;\n}\n","import type {\n Binding,\n BindingId,\n BoundType,\n GateAtom,\n ResolvedToken,\n} from \"../../bindings/index.js\";\nimport { outputGate } from \"../../bindings/index.js\";\nimport { collectFieldInfo } from \"../collect-field-info.js\";\nimport type { CodegenContext } from \"../../manifest/index.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport {\n type EmittedOutput,\n type OutputShape,\n collectMutableOutputs,\n collectOutputFields,\n outputShape,\n rootOutput,\n streamFields,\n} from \"../collect-output-fields.js\";\nimport { emitJsDoc, renderAccess, tsPropAccess } from \"./emit.js\";\nimport { renderTsLiteral } from \"./typemap.js\";\n\n// The output-field/stream/mutable collection is language-agnostic and shared\n// with the Python and JSON Schema backends; re-export the predicates the\n// backend entry point consumes so its import surface stays `./outputs-emit.js`.\nexport { hasAnyOutputs, hasMutableInputs, hasStreamOutputs } from \"../collect-output-fields.js\";\n\nfunction outputTypeExpr(shape: OutputShape): string {\n if (shape.kind === \"list\") return \"OutputPathType[]\";\n return shape.optional ? \"OutputPathType | null\" : \"OutputPathType\";\n}\n\nfunction initialValue(shape: OutputShape): string {\n if (shape.kind === \"list\") return \"[]\";\n // Required fields get a non-null assertion placeholder; the linear-flow\n // assignment below makes the placeholder unobservable.\n return shape.optional ? \"null\" : \"null!\";\n}\n\n/** Raw field names for stdout/stderr (in declaration order), for wrapper wiring. */\nexport function streamFieldIds(ctx: CodegenContext): { stdout?: string; stderr?: string } {\n const fields = streamFields(ctx, jsId);\n const res: { stdout?: string; stderr?: string } = {};\n let idx = 0;\n if (ctx.app?.stdout) res.stdout = fields[idx++]!.name;\n if (ctx.app?.stderr) res.stderr = fields[idx++]!.name;\n return res;\n}\n\n/** Emit the `export interface <outputsType> { ... }` declaration. */\nexport function emitOutputsInterface(\n ctx: CodegenContext,\n outputsType: string,\n cb: CodeBuilder,\n): void {\n cb.line(`export interface ${outputsType} {`);\n cb.indent(() => {\n for (const field of collectOutputFields(ctx, jsId)) {\n emitJsDoc(cb, field.doc);\n cb.line(`${field.id}: ${outputTypeExpr(field.shape)};`);\n }\n for (const s of streamFields(ctx, jsId)) {\n emitJsDoc(cb, s.doc);\n cb.line(`${s.id}: string[];`);\n }\n });\n cb.line(`}`);\n}\n\n/**\n * Substitutions for ref access while inside an iteration loop. When emitting\n * `for (const item of foo)`, refs to `foo` inside should resolve to `item`.\n * This is also how `iter` segments in a binding's access path are resolved.\n */\ntype IterScope = Map<BindingId, string>;\n\ninterface OutputEmitCtx {\n ctx: CodegenContext;\n iter: IterScope;\n /**\n * Merged shape per emitted field id (jsId of the output name), across every\n * contributing scope. An output name can be declared in several scopes with\n * different shapes - e.g. a list scope (repeatable option) and a single scope\n * (plain option) both writing `volume_out`. The field's type follows the\n * merged shape (a list if any contributor iterates), so the *write* must too:\n * a single-scope contributor pushes one element into a list field rather than\n * assigning. Keyed identically to `collectOutputFields`.\n */\n fieldShapes: Map<string, OutputShape>;\n /**\n * Rendered TS default literals for root-level defaulted fields, keyed by field\n * name. An output path interpolating such a field (e.g. an output basename\n * `maskfile`) reads it via `(access ?? default)` so an absent key substitutes\n * the default rather than stringifying `undefined`. Mirrors the cargs builder.\n */\n defaults: ReadonlyMap<string, string>;\n}\n\n/** The rendered default for a binding iff it is a root-level defaulted field. */\nfunction rootFieldDefault(\n binding: Binding | undefined,\n defaults: ReadonlyMap<string, string>,\n): string | undefined {\n if (!binding) return undefined;\n const a = binding.access;\n if (a.length === 1 && a[0]?.kind === \"field\") return defaults.get(binding.name);\n return undefined;\n}\n\n/** Build the field-name -> rendered-default map for the struct root (else empty).\n * Includes only non-optional defaulted fields (optional fields are\n * presence-guarded; their default comes from the factory's kwarg signature). */\nfunction collectDefaults(ctx: CodegenContext): Map<string, string> {\n const out = new Map<string, string>();\n const rootType = ctx.resolve(ctx.expr)?.type;\n if (rootType?.kind !== \"struct\") return out;\n for (const [name, fi] of collectFieldInfo(ctx, rootType)) {\n if (fi.defaultValue === undefined) continue;\n if (rootType.fields[name]?.kind === \"optional\") continue;\n out.set(name, renderTsLiteral(fi.defaultValue));\n }\n return out;\n}\n\n/**\n * Render one output's wrapper stack and emit the assignment inside the\n * innermost wrapper. Nesting is done via recursive callbacks so the\n * CodeBuilder's auto-indentation tracks correctly.\n */\nfunction emitOneOutput(\n output: EmittedOutput,\n gate: GateAtom[],\n ec: OutputEmitCtx,\n cb: CodeBuilder,\n): void {\n const occShape = outputShape(gate);\n // Push-vs-assign follows the *field's* merged shape, not this occurrence's:\n // when the same name is a list in one scope and single in another, the field\n // is a list, so a single-scope contributor must push (one element) rather\n // than assign a scalar into the array. Falls back to the occurrence shape for\n // a name that somehow has no merged entry.\n const shape = ec.fieldShapes.get(jsId(output.name)) ?? occShape;\n // Bracket-access for non-identifier field names (e.g. `in-file`, `4d`); dot\n // for valid identifiers. The interface key is jsId-quoted to match.\n const fieldRef = tsPropAccess(\"outputs\", output.name);\n\n function nest(remaining: GateAtom[], child: OutputEmitCtx): void {\n if (remaining.length === 0) {\n const pathExpr = renderPathExpr(output.tokens, child);\n // A mutable input's writable copy is surfaced via mutableCopy (its host\n // path); a regular output resolves a local path via outputFile. The\n // optional `, true` arg only applies to a single (non-list) field.\n const optionalArg =\n !output.mutable &&\n shape.kind === \"single\" &&\n occShape.kind === \"single\" &&\n occShape.optional\n ? \", true\"\n : \"\";\n const call = output.mutable\n ? `execution.mutableCopy(${pathExpr})`\n : `execution.outputFile(${pathExpr}${optionalArg})`;\n if (shape.kind === \"list\") {\n cb.line(`${fieldRef}.push(${call});`);\n } else {\n cb.line(`${fieldRef} = ${call};`);\n }\n return;\n }\n const [head, ...rest] = remaining;\n if (!head) return;\n const wrapper = renderWrapperOpen(head, child);\n cb.line(wrapper.open);\n cb.indent(() => {\n const inner =\n head.kind === \"iter\"\n ? { ...child, iter: new Map(child.iter).set(head.binding, wrapper.loopVar!) }\n : child;\n nest(rest, inner);\n });\n cb.line(wrapper.close);\n }\n\n nest(gate, ec);\n}\n\ninterface WrapperRender {\n open: string;\n close: string;\n loopVar?: string;\n}\n\nlet loopCounter = 0;\n\nfunction renderWrapperOpen(atom: GateAtom, ec: OutputEmitCtx): WrapperRender {\n if (atom.kind === \"iter\") {\n const access = bindingAccess(atom.binding, ec);\n const v = `__o${loopCounter++}`;\n return { open: `for (const ${v} of ${access}) {`, close: `}`, loopVar: v };\n }\n if (atom.kind === \"variant\") {\n const access = bindingAccess(atom.binding, ec);\n return {\n open: `if (${access}[\"@type\"] === ${JSON.stringify(atom.variant)}) {`,\n close: `}`,\n };\n }\n // present\n const binding = ec.ctx.bindings.get(atom.binding);\n const access = bindingAccess(atom.binding, ec);\n const cond = presentCondition(binding?.type, access);\n return { open: `if (${cond}) {`, close: `}` };\n}\n\nfunction presentCondition(type: BoundType | undefined, access: string): string {\n if (!type) return access;\n switch (type.kind) {\n case \"optional\":\n return `${access} !== null && ${access} !== undefined`;\n case \"bool\":\n return access;\n case \"count\":\n return `${access} > 0`;\n default:\n return access;\n }\n}\n\nfunction bindingAccess(id: BindingId, ec: OutputEmitCtx): string {\n // The binding is itself the currently-iterated element (a `ref` to the list\n // being looped, or a scalar list element): use its loop variable directly.\n const subst = ec.iter.get(id);\n if (subst) return subst;\n const binding = ec.ctx.bindings.get(id);\n if (binding) {\n // Solver-assigned path; `iter` segments resolve to the loop variable bound\n // by the surrounding `iter` gate atom (always open by the time a ref to a\n // binding under that repeat renders).\n return renderAccess(binding.access, (b) => ec.iter.get(b) ?? unresolvedLoopVar(b));\n }\n // Fallback: shouldn't happen for well-formed IR, but emit a comment-style\n // placeholder so the generated code surfaces the issue.\n return `/* unresolved binding ${id} */ null as any`;\n}\n\nfunction unresolvedLoopVar(binding: BindingId): string {\n return `/* unresolved loop var ${binding} */ (null as any)`;\n}\n\nfunction renderPathExpr(tokens: ResolvedToken[], ec: OutputEmitCtx): string {\n if (tokens.length === 0) return `\"\"`;\n if (tokens.length === 1) return renderToken(tokens[0]!, ec);\n // Template-literal join: \\`${...}${...}\\`\n let result = \"`\";\n for (const tok of tokens) {\n if (tok.kind === \"literal\") {\n result += tok.value.replace(/\\\\/g, \"\\\\\\\\\").replace(/`/g, \"\\\\`\").replace(/\\$\\{/g, \"\\\\${\");\n } else {\n result += \"${\";\n result += renderRefValue(tok, ec);\n result += \"}\";\n }\n }\n result += \"`\";\n return result;\n}\n\nfunction renderToken(tok: ResolvedToken, ec: OutputEmitCtx): string {\n if (tok.kind === \"literal\") return JSON.stringify(tok.value);\n return renderRefValue(tok, ec);\n}\n\nfunction renderRefValue(tok: Extract<ResolvedToken, { kind: \"ref\" }>, ec: OutputEmitCtx): string {\n // A defaulted root field interpolated into an output path is read absent-safe\n // via `(access ?? default)` (it is `?:`); other refs render normally.\n const def = rootFieldDefault(ec.ctx.bindings.get(tok.binding), ec.defaults);\n let expr =\n def !== undefined && !ec.iter.has(tok.binding)\n ? `(${bindingAccess(tok.binding, ec)} ?? ${def})`\n : bindingAccess(tok.binding, ec);\n // Optional refs with a fallback substitute the fallback on null/undefined.\n if (tok.fallback !== undefined) {\n expr = `(${expr} ?? ${JSON.stringify(tok.fallback)})`;\n }\n // stripExtensions: cut listed suffixes from the value (longest match first).\n if (tok.stripExtensions && tok.stripExtensions.length > 0) {\n const sorted = [...tok.stripExtensions].sort((a, b) => b.length - a.length);\n const lits = sorted.map((s) => JSON.stringify(s)).join(\", \");\n expr = `stripExtensions(${expr}, [${lits}])`;\n }\n return expr;\n}\n\nfunction jsId(name: string): string {\n // Output ids may contain characters that aren't valid JS identifier chars.\n // Quote when needed.\n if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name)) return name;\n return JSON.stringify(name);\n}\n\n/**\n * Emit a standalone `_outputs(params, execution)` function that builds and\n * returns the `Outputs` object. Mirrors the `_cargs` function structurally so\n * the wrapper can just call both.\n */\nexport function emitBuildOutputs(\n ctx: CodegenContext,\n paramsType: string,\n outputsType: string,\n funcName: string,\n cb: CodeBuilder,\n): void {\n cb.line(\n `export function ${funcName}(params: ${paramsType}, execution: Execution): ${outputsType} {`,\n );\n cb.indent(() => {\n loopCounter = 0;\n const fields = collectOutputFields(ctx, jsId);\n const ec: OutputEmitCtx = {\n ctx,\n iter: new Map(),\n fieldShapes: new Map(fields.map((f) => [f.id, f.shape])),\n defaults: collectDefaults(ctx),\n };\n\n // Initialize the outputs object with defaults so wrapper code can assign or\n // push into it without conditional construction. Deduped by field id so\n // same-named outputs (e.g. union arms) yield one initializer entry.\n cb.line(`const outputs: ${outputsType} = {`);\n cb.indent(() => {\n for (const field of fields) {\n cb.line(`${field.id}: ${initialValue(field.shape)},`);\n }\n // Stream fields start empty; the wrapper pushes onto them via the\n // handleStdout / handleStderr callbacks passed to execution.run.\n for (const s of streamFields(ctx, jsId)) {\n cb.line(`${s.id}: [],`);\n }\n });\n cb.line(`};`);\n\n const emitContributor = (output: EmittedOutput, scopeGate: GateAtom[]): void => {\n const gate = outputGate(scopeGate, output, ctx.bindings);\n emitOneOutput(output, gate, ec, cb);\n };\n // The always-present root output directory, assigned before any declared\n // output (matches its first position in collectOutputFields).\n emitContributor(rootOutput(ctx, jsId), []);\n for (const scope of ctx.outputScopes) {\n const scopeBinding = ctx.bindings.get(scope.scope);\n const scopeGate = scopeBinding?.gate ?? [];\n for (const output of scope.outputs) emitContributor(output, scopeGate);\n }\n for (const output of collectMutableOutputs(ctx)) emitContributor(output, []);\n\n cb.line(`return outputs;`);\n });\n cb.line(`}`);\n}\n\n/**\n * Whether the generated module needs a `stripExtensions` helper (any ref\n * token has stripExtensions set).\n */\nexport function needsStripExtensionsHelper(ctx: CodegenContext): boolean {\n for (const scope of ctx.outputScopes) {\n for (const output of scope.outputs) {\n for (const tok of output.tokens) {\n if (tok.kind === \"ref\" && tok.stripExtensions?.length) return true;\n }\n }\n }\n return false;\n}\n\n/** Emit a small `stripExtensions` helper used by ref tokens that strip suffixes. */\nexport function emitStripExtensionsHelper(cb: CodeBuilder): void {\n cb.line(`function stripExtensions(value: string, exts: string[]): string {`);\n cb.indent(() => {\n cb.line(`for (const ext of exts) {`);\n cb.indent(() => {\n cb.line(`if (value.endsWith(ext)) return value.slice(0, value.length - ext.length);`);\n });\n cb.line(`}`);\n cb.line(`return value;`);\n });\n cb.line(`}`);\n}\n","import type { BoundType } from \"../../bindings/index.js\";\nimport type { AppMeta } from \"../../ir/index.js\";\nimport type { CodegenContext, PackageMeta, ProjectMeta } from \"../../manifest/index.js\";\nimport type { AppEntrypoint, Backend, EmitResult, EmittedApp, EmittedPackage } from \"../backend.js\";\nimport type { SigEntry } from \"../sig-entries.js\";\nimport type { NamedType } from \"./types.js\";\nimport { CodeBuilder } from \"../code-builder.js\";\nimport { generatePackageJson, generateRootIndex, generateTsconfig } from \"./packaging.js\";\nimport { Scope } from \"../scope.js\";\nimport { camelCase, pascalCase, screamingSnakeCase, snakeCase } from \"../string-case.js\";\nimport { buildSigEntries } from \"../sig-entries.js\";\nimport {\n emitBuildCargs,\n emitImports,\n emitKwargWrapper,\n emitMetadata,\n emitParamsFactory,\n emitTypeDeclarations,\n emitWrapperFunction,\n tsScrubIdent,\n tsSigOptions,\n} from \"./emit.js\";\nimport { collectFieldInfo } from \"./types.js\";\nimport { emitValidate } from \"./validate-emit.js\";\nimport {\n emitBuildOutputs,\n emitOutputsInterface,\n emitStripExtensionsHelper,\n needsStripExtensionsHelper,\n streamFieldIds,\n} from \"./outputs-emit.js\";\nimport { mapType } from \"./typemap.js\";\nimport { collectNamedTypes, resolveTypeName, structKey, unionKey } from \"./types.js\";\n\nconst TS_RESERVED: ReadonlySet<string> = new Set([\n \"break\",\n \"case\",\n \"catch\",\n \"class\",\n \"const\",\n \"continue\",\n \"debugger\",\n \"default\",\n \"delete\",\n \"do\",\n \"else\",\n \"enum\",\n \"export\",\n \"extends\",\n \"false\",\n \"finally\",\n \"for\",\n \"function\",\n \"if\",\n \"import\",\n \"in\",\n \"instanceof\",\n \"new\",\n \"null\",\n \"return\",\n \"super\",\n \"switch\",\n \"this\",\n \"throw\",\n \"true\",\n \"try\",\n \"typeof\",\n \"undefined\",\n \"var\",\n \"void\",\n \"while\",\n \"with\",\n \"yield\",\n \"let\",\n \"static\",\n \"implements\",\n \"interface\",\n \"package\",\n \"private\",\n \"protected\",\n \"public\",\n \"type\",\n // Not keywords, but forbidden as binding names in strict mode (ES modules are\n // always strict), so a parameter/local named these is a hard error.\n \"arguments\",\n \"eval\",\n \"await\",\n]);\n\n/**\n * Per-tool public symbol names emitted directly in the flat tool file. Wrapper\n * and function names use camelCase; type names use PascalCase; the metadata\n * constant uses SCREAMING_SNAKE_CASE.\n */\nexport interface PublicNames {\n params: string;\n outputs: string;\n metadata: string;\n cargs: string;\n outputsFn: string;\n paramsFn: string;\n execute: string;\n validate: string;\n wrapper: string;\n}\n\n/** Public-name scheme used by the TypeScript backend. Exported so the CLI and tests can use it. */\nexport function computePublicNames(appId: string | undefined): PublicNames {\n if (!appId) {\n return {\n params: \"Params\",\n outputs: \"Outputs\",\n metadata: \"METADATA\",\n cargs: \"cargs\",\n outputsFn: \"outputs\",\n paramsFn: \"buildParams\",\n execute: \"execute\",\n validate: \"validate\",\n wrapper: \"run\",\n };\n }\n // Pre-scrub digit-leading ids so derived case forms produce valid\n // identifiers in a consistent case.\n const id = /^[0-9]/.test(appId) ? \"v_\" + appId : appId;\n return {\n params: pascalCase(id),\n outputs: pascalCase(id) + \"Outputs\",\n metadata: screamingSnakeCase(id) + \"_METADATA\",\n cargs: camelCase(id) + \"_cargs\",\n outputsFn: camelCase(id) + \"_outputs\",\n paramsFn: camelCase(id) + \"Params\",\n execute: camelCase(id) + \"Execute\",\n validate: camelCase(id) + \"Validate\",\n wrapper: camelCase(id),\n };\n}\n\n/**\n * The fully-derived naming/typing model for one tool's TypeScript emission.\n * Computed once by `buildEmitModel` so the file emitter and the call-site snippet\n * renderer share the exact same public names and root typing - the snippet must\n * match the function the generated code actually exposes.\n */\nexport interface TsEmitModel {\n appId: string | undefined;\n pkg: string;\n names: {\n params: string;\n outputs: string;\n metadata: string;\n cargs: string;\n outputsFn: string;\n paramsFn: string;\n execute: string;\n validate: string;\n wrapper: string;\n };\n rootType: BoundType;\n rootIsStruct: boolean;\n namedTypes: Map<string, string>;\n typeDecls: NamedType[];\n rootTypeTag: string | undefined;\n paramsType: string;\n sigEntries: SigEntry[];\n}\n\n/**\n * Derive the public names, named-type declarations, root typing, and per-field\n * signature entries for one tool. Mutates `scope` exactly as the emitter needs\n * (the `reg` registrations and the `sigScope` child), so passing the same scope\n * the emitter continues with keeps later local registrations consistent.\n */\nexport function buildEmitModel(\n ctx: CodegenContext,\n scope: Scope = new Scope(TS_RESERVED),\n): TsEmitModel {\n const appId = ctx.app?.id;\n const pkg = ctx.package?.name ?? \"unknown\";\n const publicNames = computePublicNames(appId);\n\n const rootBinding = ctx.resolve(ctx.expr);\n const rootType: BoundType = rootBinding?.type ?? { kind: \"struct\", fields: {} };\n // Only treat the root as struct-shaped when there's a real binding. A\n // synthesized empty-struct fallback (no root binding) means the solver\n // collapsed everything away, so the kwarg wrapper has nothing to wrap.\n const rootIsStruct = rootBinding?.type.kind === \"struct\";\n\n // Pre-reserve module-level public names so any IR-derived names colliding\n // with them get suffix-bumped. `params` is intentionally NOT pre-reserved -\n // `collectNamedTypes` claims it for the root struct just below. Each name\n // is scrubbed through `tsScrubIdent` first since the case helpers happily\n // pass through digit-leading app ids.\n const reg = (name: string) => scope.add(tsScrubIdent(name, TS_RESERVED));\n const names = {\n params: tsScrubIdent(publicNames.params, TS_RESERVED),\n outputs: reg(publicNames.outputs),\n metadata: reg(publicNames.metadata),\n cargs: reg(publicNames.cargs),\n outputsFn: reg(publicNames.outputsFn),\n paramsFn: rootIsStruct ? reg(publicNames.paramsFn) : \"\",\n execute: rootIsStruct ? reg(publicNames.execute) : \"\",\n validate: reg(publicNames.validate),\n wrapper: reg(publicNames.wrapper),\n };\n\n // Prefix nested type names with the tool's root name so a suite's flat barrel\n // doesn't collide same-named types (e.g. `Outputtype`) across tools.\n const { namedTypes, typeDecls } = collectNamedTypes(\n rootType,\n names.params,\n scope,\n pascalCase,\n appId ? names.params : \"\",\n );\n\n names.params =\n (rootType.kind === \"struct\" ? namedTypes.get(structKey(rootType)) : undefined) ??\n (rootType.kind === \"union\" ? namedTypes.get(unionKey(rootType)) : undefined) ??\n names.params;\n\n const paramsType =\n rootType.kind === \"struct\" || rootType.kind === \"union\"\n ? names.params\n : mapType(rootType, resolveTypeName(namedTypes));\n\n // Build the per-field SigEntry list once - the factory and kwarg wrapper\n // both consume it, so the host names registered here must satisfy both\n // function scopes. Pre-reserve `params` (factory + wrapper body) and\n // `runner` (wrapper signature) so a wire key matching either gets\n // suffix-bumped. `rootType.kind === \"struct\"` check satisfies the `Extract`\n // constraint when `rootIsStruct` is true.\n const rootTypeTag = appId ? `${pkg}/${appId}` : undefined;\n const sigScope = scope.child([\"params\", \"runner\"]);\n const sigEntries =\n rootIsStruct && rootType.kind === \"struct\"\n ? buildSigEntries(\n rootType,\n collectFieldInfo(ctx, rootType),\n (wireKey) => sigScope.add(tsScrubIdent(wireKey, TS_RESERVED)),\n tsSigOptions(resolveTypeName(namedTypes)),\n )\n : [];\n\n return {\n appId,\n pkg,\n names,\n rootType,\n rootIsStruct,\n namedTypes,\n typeDecls,\n rootTypeTag,\n paramsType,\n sigEntries,\n };\n}\n\nexport function generateTypeScript(ctx: CodegenContext, packageScope?: Scope): string {\n const cb = new CodeBuilder(\" \");\n // A package-shared scope keeps top-level names unique across every tool in the\n // suite barrel; without one (standalone emit) a per-tool scope is enough.\n const scope = packageScope ?? new Scope(TS_RESERVED);\n\n const {\n appId,\n pkg,\n names,\n rootType,\n rootIsStruct,\n namedTypes,\n typeDecls,\n rootTypeTag,\n paramsType,\n sigEntries,\n } = buildEmitModel(ctx, scope);\n\n // Auto-generated header.\n cb.comment(\"This file was auto generated by Styx.\");\n cb.comment(\"Do not edit this file directly.\");\n cb.blank();\n\n // Every tool emits an Outputs object: at minimum the synthetic `root` output\n // directory (outputFile(\".\")), plus any declared file/mutable outputs and\n // stdout/stderr stream fields. OutputPathType is therefore always imported.\n const emitOutputs = true;\n\n emitImports(cb, true);\n cb.blank();\n\n emitMetadata(ctx, names.metadata, cb);\n cb.blank();\n\n emitTypeDeclarations(typeDecls, namedTypes, ctx, names.params, appId, pkg, cb);\n\n if (emitOutputs) {\n emitOutputsInterface(ctx, names.outputs, cb);\n cb.blank();\n }\n\n if (emitOutputs && needsStripExtensionsHelper(ctx)) {\n emitStripExtensionsHelper(cb);\n cb.blank();\n }\n\n // Params factory (struct-rooted tools only): a kwarg-style builder for the\n // params object. Useful for callers that want to build a params object to\n // mutate before executing.\n if (rootIsStruct) {\n emitParamsFactory(sigEntries, names.paramsFn, paramsType, rootTypeTag, cb);\n cb.blank();\n }\n\n // Validation: walks the root binding and throws StyxValidationError on bad\n // input. Called first thing in the dict-style execute (below).\n emitValidate(\n ctx,\n rootType,\n ctx.expr,\n paramsType,\n names.validate,\n resolveTypeName(namedTypes),\n scope,\n cb,\n );\n cb.blank();\n\n emitBuildCargs(ctx, rootType, paramsType, names.cargs, cb);\n cb.blank();\n\n if (emitOutputs) {\n emitBuildOutputs(ctx, paramsType, names.outputs, names.outputsFn, cb);\n cb.blank();\n }\n\n // Dict-style execute function. For struct roots it's the internal\n // `<tool>Execute`; for other roots it doubles as the user-facing wrapper.\n const executeName = rootIsStruct ? names.execute : names.wrapper;\n emitWrapperFunction(\n ctx,\n paramsType,\n executeName,\n names.metadata,\n names.cargs,\n emitOutputs ? names.outputsFn : undefined,\n emitOutputs ? names.outputs : undefined,\n names.validate,\n streamFieldIds(ctx),\n cb,\n );\n cb.blank();\n\n // Kwarg-style wrapper (struct roots only): the v1-parity user-facing entry.\n if (rootIsStruct) {\n emitKwargWrapper(\n ctx,\n sigEntries,\n names.wrapper,\n names.paramsFn,\n names.execute,\n emitOutputs ? names.outputs : undefined,\n cb,\n );\n cb.blank();\n }\n\n return cb.toString();\n}\n\n/**\n * Module name (file stem) for an app: snake_case of app.id, fallback `output`.\n * Scrubbed so digit-leading app ids (e.g. `3dPFM` -> `v_3d_pfm`) and keyword\n * collisions don't break `export * from \"./<mod>.js\"` in the package index.\n */\nexport function appModuleName(meta: AppMeta | undefined): string {\n if (!meta?.id) return \"output\";\n return tsScrubIdent(snakeCase(meta.id), TS_RESERVED);\n}\n\n/**\n * The dispatch entrypoint for one app: its root `@type` (`<package>/<app>`) and\n * the dict-style execute function name. Returns undefined when the id or package\n * is unknown (no stable `@type`), so the app is left out of the suite dispatcher.\n */\nexport function appEntrypoint(ctx: CodegenContext): AppEntrypoint | undefined {\n const appId = ctx.app?.id;\n const pkg = ctx.package?.name;\n if (!appId || !pkg) return undefined;\n const publicNames = computePublicNames(appId);\n const rootIsStruct = ctx.resolve(ctx.expr)?.type.kind === \"struct\";\n const executeFn = tsScrubIdent(\n rootIsStruct ? publicNames.execute : publicNames.wrapper,\n TS_RESERVED,\n );\n return { type: `${pkg}/${appId}`, executeFn };\n}\n\n/**\n * Generate the suite-level `index.ts` re-export for a package containing\n * multiple tool modules. Each tool module's public symbols are surfaced via\n * `export * from \"./bet.js\"`. When apps carry a dispatch entrypoint, a\n * suite-level `execute(params, runner)` is appended that routes a config object\n * to the right tool by its root `@type`.\n */\nexport function generatePackageIndex(apps: EmittedApp[]): string {\n const cb = new CodeBuilder(\" \");\n cb.comment(\"This file was auto generated by Styx.\");\n cb.comment(\"Do not edit this file directly.\");\n cb.blank();\n\n const sortedApps = [...apps].sort((a, b) =>\n appModuleName(a.meta).localeCompare(appModuleName(b.meta)),\n );\n const dispatch = sortedApps\n .map((a) => ({ entry: a.entrypoint, mod: appModuleName(a.meta) }))\n .filter((x): x is { entry: AppEntrypoint; mod: string } => x.entry !== undefined);\n\n if (dispatch.length > 0) {\n cb.line(`import type { Runner } from \"styxdefs\";`);\n for (const d of dispatch) {\n cb.line(`import { ${d.entry.executeFn} } from \"./${d.mod}.js\";`);\n }\n cb.blank();\n }\n\n for (const mod of sortedApps.map((a) => appModuleName(a.meta))) {\n cb.line(`export * from \"./${mod}.js\";`);\n }\n\n if (dispatch.length > 0) {\n cb.blank();\n emitPackageDispatch(\n cb,\n dispatch.map((d) => d.entry),\n );\n }\n\n return cb.toString();\n}\n\n/** Emit the suite-level `execute(params, runner)` dispatcher over `@type`. */\nfunction emitPackageDispatch(cb: CodeBuilder, dispatch: AppEntrypoint[]): void {\n cb.line(\"/**\");\n cb.line(\" * Run a tool in this package from a params object, routed by its `@type`.\");\n cb.line(\" */\");\n cb.line(\n `export function execute(params: { \"@type\": string }, runner: Runner | null = null): unknown {`,\n );\n cb.indent(() => {\n cb.line(\"const dispatch: Record<string, (params: any, runner: Runner | null) => unknown> = {\");\n cb.indent(() => {\n for (const e of dispatch) {\n cb.line(`${JSON.stringify(e.type)}: ${e.executeFn},`);\n }\n });\n cb.line(\"};\");\n cb.line(`const fn = dispatch[params[\"@type\"]];`);\n cb.line(\"if (fn === undefined) {\");\n cb.indent(() => {\n cb.line(\"throw new Error(`No tool registered for @type '${params[\\\"@type\\\"]}'`);\");\n });\n cb.line(\"}\");\n cb.line(\"return fn(params, runner);\");\n });\n cb.line(\"}\");\n}\n\nexport class TypeScriptBackend implements Backend {\n readonly name = \"typescript\";\n readonly target = \"typescript\";\n\n emitApp(ctx: CodegenContext, scope?: Scope): EmittedApp {\n const code = generateTypeScript(ctx, scope);\n const fileName = `${appModuleName(ctx.app)}.ts`;\n return {\n meta: ctx.app,\n entrypoint: appEntrypoint(ctx),\n files: new Map([[fileName, code]]),\n errors: [],\n warnings: [],\n };\n }\n\n newPackageScope(): Scope {\n return new Scope(TS_RESERVED);\n }\n\n emitPackage(pkg: PackageMeta, apps: EmittedApp[]): EmittedPackage {\n return {\n meta: pkg,\n files: new Map([[\"index.ts\", generatePackageIndex(apps)]]),\n errors: [],\n warnings: [],\n };\n }\n\n emitProject(proj: ProjectMeta, packages: EmittedPackage[]): EmitResult {\n return {\n files: new Map([\n [\"package.json\", generatePackageJson(proj)],\n [\"index.ts\", generateRootIndex(packages)],\n [\"tsconfig.json\", generateTsconfig()],\n ]),\n errors: [],\n warnings: [],\n };\n }\n}\n","import type { CodegenContext } from \"../../manifest/index.js\";\nimport type { SnippetDialect, SnippetOptions } from \"../snippet-core.js\";\nimport { renderStructLiteral, renderValue } from \"../snippet-core.js\";\nimport { tsObjKey } from \"./emit.js\";\nimport { buildEmitModel } from \"./typescript.js\";\n\n/** Snippet rendering hooks for TypeScript (object literals, `true`/`null`). */\nconst tsDialect: SnippetDialect = {\n indentUnit: \" \",\n string: (s) => JSON.stringify(s),\n boolean: (b) => (b ? \"true\" : \"false\"),\n number: (n) => (Number.isFinite(n) ? String(n) : \"NaN\"),\n null: \"null\",\n objKey: tsObjKey,\n};\n\n/**\n * Render a TypeScript call snippet for one tool from a config object (keyed by\n * Boutiques wire names).\n *\n * The generated v2 kwarg wrapper takes *positional* arguments, which can't skip\n * a middle optional - so the runnable object-style entry is the dict-style\n * `<tool>Execute(params)` (struct roots). The snippet builds the params object\n * literal (wire-keyed, with the root `@type` injected) and passes it there.\n * Union- (or otherwise non-struct-) rooted tools call the dict-style `<tool>`\n * entry the same way. Nested structs / union variants / lists-of-structs have no\n * constructor in the generated code and render as object literals.\n *\n * The snippet matches the *standalone* (single-descriptor) emission of the same\n * context - which is how the hub compiles - not a catalog emission where a\n * shared package scope could suffix-bump a name.\n *\n * @param ctx - The compiled context (compile -> pipeline -> solve ->\n * resolveOutputs -> createContext, as in the CLI's `readAndCompile`).\n * @param config - The params object, keyed by Boutiques *wire* names. Every\n * union-typed value - including the root of a union-rooted tool - must carry\n * its `@type` discriminator so the variant can be matched; the root struct's\n * `@type` is supplied by the renderer, so omit it there.\n * @param opts - Import and package-root options.\n */\nexport function renderTypeScriptCall(\n ctx: CodegenContext,\n config: Record<string, unknown>,\n opts: SnippetOptions = {},\n): string {\n const model = buildEmitModel(ctx);\n const pkg = ctx.package?.name;\n const fnName = model.rootIsStruct ? model.names.execute : model.names.wrapper;\n const callee = pkg ? `${pkg}.${fnName}` : fnName;\n\n const arg =\n model.rootIsStruct && model.rootType.kind === \"struct\"\n ? renderStructLiteral(config, model.rootType, \"\", tsDialect, model.rootTypeTag)\n : renderValue(config, model.rootType, \"\", tsDialect);\n const call = `${callee}(${arg})`;\n\n if (opts.includeImport === false || !pkg) return call;\n const root = opts.packageRoot ?? ctx.project?.name ?? \"niwrap\";\n return `import { ${pkg} } from \"${root}\";\\n\\n${call}`;\n}\n","import type { AppMeta, Output, OutputToken } from \"./meta.js\";\nimport type { Expr } from \"./node.js\";\n\nexport function format(expr: Expr, meta?: AppMeta): string {\n const lines: string[] = [];\n\n if (meta) {\n lines.push(`app ${meta.id ?? \"unknown\"}${meta.version ? `@${meta.version}` : \"\"}`);\n if (meta.doc?.description) {\n lines.push(` \"${meta.doc.description}\"`);\n }\n if (meta.doc?.authors?.length) {\n lines.push(` authors: ${meta.doc.authors.join(\", \")}`);\n }\n if (meta.container) {\n lines.push(` container: ${meta.container.image}`);\n }\n if (meta.stdout) {\n lines.push(` stdout: ${meta.stdout.name}`);\n }\n if (meta.stderr) {\n lines.push(` stderr: ${meta.stderr.name}`);\n }\n lines.push(\"\");\n }\n\n lines.push(formatExpr(expr, 0));\n return lines.join(\"\\n\");\n}\n\nfunction formatOutputToken(token: OutputToken): string {\n if (token.kind === \"literal\") return JSON.stringify(token.value);\n const flags = [\n token.stripExtensions?.length && `strip=${JSON.stringify(token.stripExtensions)}`,\n token.fallback !== undefined && `fallback=${JSON.stringify(token.fallback)}`,\n ].filter(Boolean);\n const suffix = flags.length > 0 ? ` {${flags.join(\", \")}}` : \"\";\n return `ref(${token.target.name})${suffix}`;\n}\n\nfunction formatOutputsBlock(outputs: Output[], indent: number): string {\n const pad = \" \".repeat(indent);\n const lines = [`${pad}outputs:`];\n for (const out of outputs) {\n const name = out.name ?? \"<anon>\";\n const media = out.mediaTypes?.length ? ` (${out.mediaTypes.join(\", \")})` : \"\";\n const tokens = out.tokens.map(formatOutputToken).join(\" + \") || `\"\"`;\n lines.push(`${pad} ${name}${media}: ${tokens}`);\n }\n return lines.join(\"\\n\");\n}\n\n// Splice the outputs block in right after the node's header line (its first\n// line), before any child lines, so outputs read naturally as belonging to\n// the node they decorate.\nfunction spliceOutputs(body: string, outputsBlock: string): string {\n if (!outputsBlock) return body;\n const nl = body.indexOf(\"\\n\");\n if (nl === -1) return `${body}\\n${outputsBlock}`;\n return `${body.slice(0, nl)}\\n${outputsBlock}${body.slice(nl)}`;\n}\n\nfunction formatExpr(expr: Expr, indent: number): string {\n const pad = \" \".repeat(indent);\n const name = expr.meta?.name ? ` [${expr.meta.name}]` : \"\";\n const outputsBlock = expr.meta?.outputs?.length\n ? formatOutputsBlock(expr.meta.outputs, indent + 1)\n : \"\";\n\n let body: string;\n switch (expr.kind) {\n case \"literal\":\n body = `${pad}literal${name} \"${expr.attrs.str}\"`;\n break;\n\n case \"str\":\n body = `${pad}str${name}`;\n break;\n\n case \"int\": {\n const { minValue, maxValue } = expr.attrs;\n const range =\n minValue !== undefined || maxValue !== undefined\n ? ` (${minValue ?? \"\"}..${maxValue ?? \"\"})`\n : \"\";\n body = `${pad}int${name}${range}`;\n break;\n }\n\n case \"float\": {\n const { minValue, maxValue } = expr.attrs;\n const range =\n minValue !== undefined || maxValue !== undefined\n ? ` (${minValue ?? \"\"}..${maxValue ?? \"\"})`\n : \"\";\n body = `${pad}float${name}${range}`;\n break;\n }\n\n case \"path\": {\n const flags = [\n expr.attrs.resolveParent && \"resolveParent\",\n expr.attrs.mutable && \"mutable\",\n ].filter(Boolean);\n const suffix = flags.length > 0 ? ` {${flags.join(\", \")}}` : \"\";\n body = `${pad}path${name}${suffix}`;\n break;\n }\n\n case \"sequence\": {\n const join = expr.attrs.join !== undefined ? ` join=\"${expr.attrs.join}\"` : \"\";\n const header = `${pad}sequence${name}${join}`;\n if (expr.attrs.nodes.length === 0) {\n body = `${header} (empty)`;\n } else {\n const children = expr.attrs.nodes.map((n) => formatExpr(n, indent + 1)).join(\"\\n\");\n body = `${header}\\n${children}`;\n }\n break;\n }\n\n case \"alternative\": {\n const header = `${pad}alternative${name}`;\n const children = expr.attrs.alts.map((n) => formatExpr(n, indent + 1)).join(\"\\n\");\n body = `${header}\\n${children}`;\n break;\n }\n\n case \"optional\": {\n const header = `${pad}optional${name}`;\n const child = formatExpr(expr.attrs.node, indent + 1);\n body = `${header}\\n${child}`;\n break;\n }\n\n case \"repeat\": {\n const { join, countMin, countMax } = expr.attrs;\n const parts = [\n join !== undefined && `join=\"${join}\"`,\n countMin !== undefined && `min=${countMin}`,\n countMax !== undefined && `max=${countMax}`,\n ].filter(Boolean);\n const suffix = parts.length > 0 ? ` {${parts.join(\", \")}}` : \"\";\n const header = `${pad}repeat${name}${suffix}`;\n const child = formatExpr(expr.attrs.node, indent + 1);\n body = `${header}\\n${child}`;\n break;\n }\n\n default: {\n const _exhaustive: never = expr;\n body = `${pad}unknown`;\n }\n }\n\n return spliceOutputs(body, outputsBlock);\n}\n","import type { NodeMeta } from \"./meta.js\";\nimport type { MediaTypeIdentifier } from \"./types.js\";\n\n/** Base structure for all IR nodes */\ninterface BaseNode<K extends string, Attrs> {\n kind: K;\n meta?: NodeMeta;\n attrs: Attrs;\n}\n\n// Structural nodes\n\nexport type Literal = BaseNode<\n \"literal\",\n {\n str: string;\n }\n>;\n\nexport type Sequence = BaseNode<\n \"sequence\",\n {\n nodes: Expr[];\n join?: string;\n }\n>;\n\nexport type Optional = BaseNode<\n \"optional\",\n {\n node: Expr;\n }\n>;\n\nexport type Alternative = BaseNode<\n \"alternative\",\n {\n alts: Expr[];\n }\n>;\n\nexport type Repeat = BaseNode<\n \"repeat\",\n {\n node: Expr;\n join?: string;\n countMin?: number;\n countMax?: number;\n }\n>;\n\n// Terminal nodes\n\nexport type Int = BaseNode<\n \"int\",\n {\n minValue?: number;\n maxValue?: number;\n }\n>;\n\nexport type Float = BaseNode<\n \"float\",\n {\n minValue?: number;\n maxValue?: number;\n }\n>;\n\nexport type Str = BaseNode<\"str\", Record<string, never>>;\n\nexport type Path = BaseNode<\n \"path\",\n {\n resolveParent?: boolean;\n mutable?: boolean;\n mediaTypes?: MediaTypeIdentifier[];\n }\n>;\n\n// Union types\n\nexport type StructuralNode = Sequence | Optional | Alternative | Repeat;\nexport type Terminal = Literal | Int | Float | Str | Path;\nexport type Expr = StructuralNode | Terminal;\n\n// Type guards\n\nexport function isTerminal(expr: Expr): expr is Terminal {\n return [\"literal\", \"int\", \"float\", \"str\", \"path\"].includes(expr.kind);\n}\n\nexport function isStructural(expr: Expr): expr is StructuralNode {\n return [\"sequence\", \"optional\", \"alternative\", \"repeat\"].includes(expr.kind);\n}\n","import type { Expr } from \"../node.js\";\n\nexport enum PassStatus {\n Unchanged = \"unchanged\",\n Changed = \"changed\",\n ChangedNeedsRerun = \"changed-needs-rerun\",\n}\n\nexport interface PassResult {\n expr: Expr;\n status: PassStatus;\n warnings?: string[];\n}\n\nexport interface Pass {\n readonly name: string;\n apply(expr: Expr): PassResult;\n}\n\nexport function compose(...passes: Pass[]): Pass {\n return {\n name: passes.map((p) => p.name).join(\" → \"),\n apply(expr: Expr): PassResult {\n let current = expr;\n let overallStatus = PassStatus.Unchanged;\n const warnings: string[] = [];\n\n for (const pass of passes) {\n const result = pass.apply(current);\n current = result.expr;\n\n if (result.status !== PassStatus.Unchanged) {\n overallStatus = result.status;\n }\n if (result.warnings) {\n warnings.push(...result.warnings);\n }\n }\n\n return {\n expr: current,\n status: overallStatus,\n ...(warnings.length > 0 && { warnings }),\n };\n },\n };\n}\n\nexport function fixpoint(pass: Pass, maxIterations = 10): Pass {\n return {\n name: `fixpoint(${pass.name})`,\n apply(expr: Expr): PassResult {\n let current = expr;\n const allWarnings: string[] = [];\n\n for (let i = 0; i < maxIterations; ++i) {\n const result = pass.apply(current);\n\n if (result.warnings) {\n allWarnings.push(...result.warnings);\n }\n\n // Stop if unchanged or no rerun needed\n if (result.status !== PassStatus.ChangedNeedsRerun) {\n return {\n expr: result.expr,\n status:\n result.status === PassStatus.Unchanged ? PassStatus.Unchanged : PassStatus.Changed,\n ...(allWarnings.length > 0 && { warnings: allWarnings }),\n };\n }\n\n current = result.expr;\n }\n\n return {\n expr: current,\n status: PassStatus.Changed,\n warnings: [\n ...allWarnings,\n `${pass.name} did not converge after ${maxIterations} iterations`,\n ],\n };\n },\n };\n}\n","import type { Expr } from \"../node.js\";\nimport { PassStatus, type Pass, type PassResult } from \"./pass.js\";\n\n/**\n * Canonicalize IR for consistent representation:\n * - Sort alternatives by kind, then name, then structure\n * - Deduplicate identical alternatives\n */\nexport const canonicalize: Pass = {\n name: \"canonicalize\",\n apply(expr: Expr): PassResult {\n let changed = false;\n\n function structuralHash(node: Expr): string {\n switch (node.kind) {\n case \"literal\":\n return `lit:${node.attrs.str}`;\n case \"int\":\n return `int:${node.attrs.minValue ?? \"\"}:${node.attrs.maxValue ?? \"\"}`;\n case \"float\":\n return `float:${node.attrs.minValue ?? \"\"}:${node.attrs.maxValue ?? \"\"}`;\n case \"str\":\n return \"str\";\n case \"path\":\n return `path:${node.attrs.resolveParent ?? \"\"}:${node.attrs.mutable ?? \"\"}`;\n case \"optional\":\n return `opt:${structuralHash(node.attrs.node)}`;\n case \"repeat\":\n return `rep:${node.attrs.join ?? \"\"}:${structuralHash(node.attrs.node)}`;\n case \"sequence\":\n return `seq:${node.attrs.join ?? \"\"}:${node.attrs.nodes.map(structuralHash).join(\",\")}`;\n case \"alternative\":\n return `alt:${node.attrs.alts.map(structuralHash).join(\",\")}`;\n default: {\n const _exhaustive: never = node;\n return \"\";\n }\n }\n }\n\n function sortKey(node: Expr): string {\n const name = node.meta?.name ?? \"\";\n return `${node.kind}:${name}:${structuralHash(node)}`;\n }\n\n function visit(node: Expr): Expr {\n switch (node.kind) {\n case \"alternative\": {\n const children = node.attrs.alts.map(visit);\n\n // Sort alternatives\n const sorted = [...children].sort((a, b) => sortKey(a).localeCompare(sortKey(b)));\n\n // Deduplicate by structural hash\n const seen = new Set<string>();\n const alts: Expr[] = [];\n for (const child of sorted) {\n const hash = structuralHash(child);\n if (!seen.has(hash)) {\n seen.add(hash);\n alts.push(child);\n } else {\n changed = true;\n }\n }\n\n // Check if order changed\n if (\n alts.length !== children.length ||\n alts.some((alt, i) => structuralHash(alt) !== structuralHash(children[i]!))\n ) {\n changed = true;\n }\n\n return { ...node, attrs: { ...node.attrs, alts } };\n }\n\n case \"sequence\": {\n const nodes = node.attrs.nodes.map(visit);\n return { ...node, attrs: { ...node.attrs, nodes } };\n }\n\n case \"optional\":\n return { ...node, attrs: { node: visit(node.attrs.node) } };\n\n case \"repeat\":\n return { ...node, attrs: { ...node.attrs, node: visit(node.attrs.node) } };\n\n case \"literal\":\n case \"int\":\n case \"float\":\n case \"str\":\n case \"path\":\n return node;\n\n default: {\n const _exhaustive: never = node;\n return node;\n }\n }\n }\n\n return {\n expr: visit(expr),\n status: changed ? PassStatus.Changed : PassStatus.Unchanged,\n };\n },\n};\n","import type { Expr } from \"../node.js\";\nimport { PassStatus, type Pass, type PassResult } from \"./pass.js\";\n\n/**\n * Flatten passes\n * - seq(a, seq(b, c)) -> seq(a, b, c)\n * - alt(a, alt(b, c)) -> alt(a, b, c)\n */\nexport const flatten: Pass = {\n name: \"flatten\",\n apply(expr: Expr): PassResult {\n let changed = false;\n\n function visit(node: Expr): Expr {\n switch (node.kind) {\n case \"sequence\": {\n const children = node.attrs.nodes.map(visit);\n const nodes: Expr[] = [];\n\n for (const child of children) {\n if (child.kind === \"sequence\" && child.attrs.join === node.attrs.join && !child.meta) {\n changed = true;\n nodes.push(...child.attrs.nodes);\n } else {\n nodes.push(child);\n }\n }\n\n return { ...node, attrs: { ...node.attrs, nodes } };\n }\n\n case \"alternative\": {\n const children = node.attrs.alts.map(visit);\n const alts: Expr[] = [];\n\n for (const child of children) {\n if (child.kind === \"alternative\" && !child.meta) {\n changed = true;\n alts.push(...child.attrs.alts);\n } else {\n alts.push(child);\n }\n }\n\n return { ...node, attrs: { ...node.attrs, alts } };\n }\n\n case \"optional\":\n return { ...node, attrs: { node: visit(node.attrs.node) } };\n\n case \"repeat\":\n return { ...node, attrs: { ...node.attrs, node: visit(node.attrs.node) } };\n\n case \"literal\":\n case \"int\":\n case \"float\":\n case \"str\":\n case \"path\":\n return node;\n\n default: {\n const _exhaustive: never = node;\n return node;\n }\n }\n }\n\n return {\n expr: visit(expr),\n status: changed ? PassStatus.Changed : PassStatus.Unchanged,\n };\n },\n};\n","import type { Expr } from \"../node.js\";\nimport { PassStatus, type Pass, type PassResult } from \"./pass.js\";\n\n/**\n * Remove empty nodes:\n * - seq() → removed\n * - alt() → removed\n * - opt(seq()) → removed\n * - rep(alt()) → removed\n */\nexport const removeEmpty: Pass = {\n name: \"remove-empty\",\n apply(expr: Expr): PassResult {\n let changed = false;\n\n function isEmpty(node: Expr): boolean {\n return (\n (node.kind === \"sequence\" && node.attrs.nodes.length === 0) ||\n (node.kind === \"alternative\" && node.attrs.alts.length === 0)\n );\n }\n\n function isRemovable(node: Expr): boolean {\n if (node.meta) return false; // Preserve metadata\n return (\n isEmpty(node) ||\n ((node.kind === \"optional\" || node.kind === \"repeat\") && isEmpty(node.attrs.node))\n );\n }\n\n function visit(node: Expr): Expr {\n switch (node.kind) {\n case \"sequence\": {\n const nodes = node.attrs.nodes.map(visit).filter((child) => {\n const removable = isRemovable(child);\n if (removable) changed = true;\n return !removable;\n });\n return { ...node, attrs: { ...node.attrs, nodes } };\n }\n\n case \"alternative\": {\n const alts = node.attrs.alts.map(visit).filter((child) => {\n const removable = isRemovable(child);\n if (removable) changed = true;\n return !removable;\n });\n return { ...node, attrs: { ...node.attrs, alts } };\n }\n\n case \"optional\":\n return { ...node, attrs: { node: visit(node.attrs.node) } };\n\n case \"repeat\":\n return { ...node, attrs: { ...node.attrs, node: visit(node.attrs.node) } };\n\n case \"literal\":\n case \"int\":\n case \"float\":\n case \"str\":\n case \"path\":\n return node;\n\n default: {\n const _exhaustive: never = node;\n return node;\n }\n }\n }\n\n return {\n expr: visit(expr),\n status: changed ? PassStatus.Changed : PassStatus.Unchanged,\n };\n },\n};\n","import type { NodeMeta } from \"../meta.js\";\nimport type { Expr } from \"../node.js\";\nimport { PassStatus, type Pass, type PassResult } from \"./pass.js\";\n\n/**\n * Merge two `NodeMeta` when collapsing a wrapper layer (the child is the\n * inner/surviving node). Name, doc fields and defaultValue take the innermost\n * value; `outputs` from both layers are concatenated so an output attached to\n * a collapsed wrapper survives on whatever node absorbs it.\n */\nfunction mergeMeta(parent?: NodeMeta, child?: NodeMeta): NodeMeta | undefined {\n if (!parent && !child) return undefined;\n if (!parent) return child;\n if (!child) return parent;\n\n const merged: NodeMeta = {};\n\n const name = child.name ?? parent.name;\n if (name !== undefined) merged.name = name;\n\n // The variant tag is the union discriminator (the sub-command id); unlike\n // `name` it must survive a single-field sub-command collapsing onto its inner\n // field (whose `name` wins above), so the `@type` stays the sub-command id\n // rather than the inner field's id. The parent (the sub-command wrapper)\n // carries it; the inner field has none.\n const variantTag = parent.variantTag ?? child.variantTag;\n if (variantTag !== undefined) merged.variantTag = variantTag;\n\n const defaultValue = child.defaultValue ?? parent.defaultValue;\n if (defaultValue !== undefined) merged.defaultValue = defaultValue;\n\n if (parent.doc || child.doc) {\n merged.doc = {\n title: child.doc?.title ?? parent.doc?.title,\n description: child.doc?.description ?? parent.doc?.description,\n authors: [...(parent.doc?.authors ?? []), ...(child.doc?.authors ?? [])],\n literature: [...(parent.doc?.literature ?? []), ...(child.doc?.literature ?? [])],\n urls: [...(parent.doc?.urls ?? []), ...(child.doc?.urls ?? [])],\n comment: child.doc?.comment ?? parent.doc?.comment,\n };\n }\n\n const outputs = [...(parent.outputs ?? []), ...(child.outputs ?? [])];\n if (outputs.length > 0) merged.outputs = outputs;\n\n return merged;\n}\n\n/**\n * Simplify passes:\n * - optional(optional(T)) -> optional(T)\n * - repeat(repeat(T)) -> repeat(T) with merged constraints\n * - seq(T) -> T, alt(T) -> T (singleton unwrapping)\n * - seq(lit(\"a\"), lit(\"b\")) -> seq(lit(\"ab\")) (merge consecutive literals)\n *\n * Every collapse that drops a wrapper layer merges that layer's `NodeMeta`\n * into the surviving node via `mergeMeta`, so names and attached outputs are\n * never lost.\n */\nexport const simplify: Pass = {\n name: \"simplify\",\n apply(expr: Expr): PassResult {\n let changed = false;\n\n function visit(node: Expr): Expr {\n switch (node.kind) {\n case \"optional\": {\n const inner = visit(node.attrs.node);\n\n // optional(optional(T)) -> optional(T)\n if (inner.kind === \"optional\") {\n changed = true;\n return {\n ...node,\n attrs: { node: inner.attrs.node },\n meta: mergeMeta(node.meta, inner.meta),\n };\n }\n\n return { ...node, attrs: { node: inner } };\n }\n\n case \"repeat\": {\n const inner = visit(node.attrs.node);\n\n // repeat(repeat(T)) -> repeat(T) with merged constraints\n if (inner.kind === \"repeat\") {\n changed = true;\n return {\n ...node,\n attrs: {\n node: inner.attrs.node,\n join: node.attrs.join ?? inner.attrs.join,\n countMin: Math.max(node.attrs.countMin ?? 0, inner.attrs.countMin ?? 0),\n countMax:\n node.attrs.countMax === undefined || inner.attrs.countMax === undefined\n ? undefined\n : Math.min(node.attrs.countMax, inner.attrs.countMax),\n },\n meta: mergeMeta(node.meta, inner.meta),\n };\n }\n\n return { ...node, attrs: { ...node.attrs, node: inner } };\n }\n\n case \"sequence\": {\n const children = node.attrs.nodes.map(visit);\n\n // Merge consecutive metadata-less literals, but only in an explicit\n // concatenation context (`join === \"\"`). The merge is separator-free\n // (`prev.str += child.str`), which only matches the semantics of an\n // empty join. A sequence with no join joins its children with a space\n // (they become separate argv tokens at the top level), so merging\n // adjacent literals there would wrongly fuse two arguments into one\n // (e.g. `seq(lit(\"wb_command\"), lit(\"-foo\"))` -> `\"wb_command-foo\"`).\n // Inside a join context the backend concatenates anyway, so leaving\n // such literals unmerged stays correct (just one node larger).\n const nodes: Expr[] = [];\n for (const child of children) {\n const prev = nodes[nodes.length - 1];\n if (\n prev?.kind === \"literal\" &&\n child.kind === \"literal\" &&\n !prev.meta &&\n !child.meta &&\n node.attrs.join === \"\"\n ) {\n changed = true;\n prev.attrs.str += child.attrs.str;\n } else {\n nodes.push(child);\n }\n }\n\n // seq(T) -> T, carrying the seq's meta down onto the child.\n if (nodes.length === 1) {\n const child = nodes[0]!;\n changed = true;\n const mergedMeta = mergeMeta(node.meta, child.meta);\n return mergedMeta ? { ...child, meta: mergedMeta } : child;\n }\n\n return { ...node, attrs: { ...node.attrs, nodes } };\n }\n\n case \"alternative\": {\n const alts = node.attrs.alts.map(visit);\n\n // alt(T) -> T. Only when the alt carries no metadata of its own\n // (otherwise the collapse would orphan it).\n if (alts.length === 1 && !node.meta) {\n changed = true;\n return alts[0]!;\n }\n\n return { ...node, attrs: { ...node.attrs, alts } };\n }\n\n case \"literal\":\n case \"int\":\n case \"float\":\n case \"str\":\n case \"path\":\n return node;\n\n default: {\n const _exhaustive: never = node;\n return node;\n }\n }\n }\n\n return {\n expr: visit(expr),\n status: changed ? PassStatus.Changed : PassStatus.Unchanged,\n };\n },\n};\n","// import { canonicalize } from \"./canonicalize.js\";\nimport { flatten } from \"./flatten.js\";\nimport type { Pass } from \"./pass.js\";\nimport { compose, fixpoint } from \"./pass.js\";\nimport { removeEmpty } from \"./remove-empty.js\";\nimport { simplify } from \"./simplify.js\";\n\nexport const defaultPipeline: Pass = fixpoint(\n compose(flatten, removeEmpty, simplify /* canonicalize */),\n);\n\nexport function createPipeline(\n passes: Pass[],\n options?: { fixpoint?: boolean; maxIterations?: number },\n): Pass {\n const composed = compose(...passes);\n if (options?.fixpoint) {\n return fixpoint(composed, options.maxIterations);\n }\n return composed;\n}\n","import type {\n BindingRegistry,\n OutputScope,\n OutputValidationResult,\n SolveResult,\n} from \"../bindings/index.js\";\nimport type { AppMeta, Expr } from \"../ir/index.js\";\nimport type { OutputResolution } from \"../solver/index.js\";\nimport type { PackageMeta, ProjectMeta } from \"./types.js\";\n\nexport interface CodegenContext {\n expr: Expr;\n bindings: BindingRegistry;\n resolve: SolveResult[\"resolve\"];\n outputScopes: OutputScope[];\n outputDiagnostics: OutputValidationResult;\n app?: AppMeta;\n package?: PackageMeta;\n project?: ProjectMeta;\n}\n\nexport function createContext(\n expr: Expr,\n solveResult: SolveResult,\n outputs: OutputResolution,\n meta?: { app?: AppMeta; package?: PackageMeta; project?: ProjectMeta },\n): CodegenContext {\n return {\n expr,\n bindings: solveResult.bindings,\n resolve: solveResult.resolve,\n outputScopes: outputs.scopes,\n outputDiagnostics: outputs.diagnostics,\n ...meta,\n };\n}\n","import type {\n Binding,\n BindingId,\n BoundType,\n OutputDiagnostic,\n OutputScope,\n OutputValidationResult,\n ResolvedOutput,\n ResolvedToken,\n SolveResult,\n} from \"../bindings/index.js\";\nimport type { Expr, Output } from \"../ir/index.js\";\nimport { effectiveOutputName } from \"../ir/index.js\";\n\nexport interface OutputResolution {\n scopes: OutputScope[];\n diagnostics: OutputValidationResult;\n}\n\n/**\n * Per-binding map keyed by `Binding.name`. Frontends attach outputs to the\n * declaring struct, so refs name fields visible in that scope (the resolver\n * accepts a single global name index because optimization can move bindings\n * around but never duplicates names within a scope).\n */\ninterface NameIndex {\n byName: Map<string, Binding>;\n}\n\n/**\n * Whether a binding resolves to a value that can be interpolated into an output\n * path token. Scalars/bool/count/literals (and optional/list wrappers of them)\n * carry a concrete value; structs and complex unions do not.\n *\n * This drives the name-tie preference below: an unnamed multi-field struct\n * inherits its first field's name (`findDeepName`), so a struct and its scalar\n * field can share a name. An output ref always means the value, so the\n * interpolable binding must win regardless of which sits shallower.\n */\nfunction isInterpolable(type: BoundType): boolean {\n switch (type.kind) {\n case \"optional\":\n return isInterpolable(type.inner);\n case \"list\":\n return isInterpolable(type.item);\n case \"struct\":\n return false;\n case \"union\":\n // Pure-enum unions are interpolable (the value is a literal); a union with\n // any struct variant is not.\n return type.variants.every((v) => isInterpolable(v.type));\n default:\n return true;\n }\n}\n\n/**\n * `includeRoot` controls whether the binding on `root` itself (depth 0) is\n * indexed. The global index excludes it (a ref must never resolve to the root\n * struct, which shares its name with a deep field via `findDeepName`). A\n * scope-local index includes it: a collapsed single-field union arm boxes its\n * lone field's binding onto the scope node itself (e.g. ants DenoiseImage's\n * `correctedOutputFileName` arm), and that binding - with the field's access\n * path and the arm's variant gate - is exactly what the arm's output ref needs.\n */\nfunction indexBindingsByName(\n root: Expr,\n resolve: (n: Expr) => Binding | undefined,\n includeRoot = false,\n): NameIndex {\n const byNameDepth = new Map<string, { binding: Binding; depth: number }>();\n function walk(node: Expr, depth: number): void {\n const binding = resolve(node);\n if (binding && (depth > 0 || includeRoot)) {\n const existing = byNameDepth.get(binding.name);\n if (!existing || preferCandidate({ binding, depth }, existing)) {\n byNameDepth.set(binding.name, { binding, depth });\n }\n }\n switch (node.kind) {\n case \"sequence\":\n for (const child of node.attrs.nodes) walk(child, depth + 1);\n break;\n case \"optional\":\n case \"repeat\":\n walk(node.attrs.node, depth + 1);\n break;\n case \"alternative\":\n for (const alt of node.attrs.alts) walk(alt, depth + 1);\n break;\n }\n }\n walk(root, 0);\n const byName = new Map<string, Binding>();\n for (const [name, { binding }] of byNameDepth) byName.set(name, binding);\n return { byName };\n}\n\n/**\n * Decide whether `cand` should replace `existing` for a shared name. An\n * interpolable binding always beats a structured one (the struct/scalar name\n * collision); otherwise the shallowest binding wins, as before.\n */\nfunction preferCandidate(\n cand: { binding: Binding; depth: number },\n existing: { binding: Binding; depth: number },\n): boolean {\n const candLeaf = isInterpolable(cand.binding.type);\n const exLeaf = isInterpolable(existing.binding.type);\n if (candLeaf !== exLeaf) return candLeaf;\n return cand.depth < existing.depth;\n}\n\n/**\n * Walk the IR collecting `(node, outputs)` pairs in tree order. Outputs attach\n * to struct/sequence nodes by frontend convention.\n */\nfunction collectScopes(root: Expr): { node: Expr; outputs: Output[] }[] {\n const out: { node: Expr; outputs: Output[] }[] = [];\n function walk(node: Expr): void {\n if (node.meta?.outputs?.length) out.push({ node, outputs: node.meta.outputs });\n switch (node.kind) {\n case \"sequence\":\n for (const child of node.attrs.nodes) walk(child);\n break;\n case \"optional\":\n case \"repeat\":\n walk(node.attrs.node);\n break;\n case \"alternative\":\n for (const alt of node.attrs.alts) walk(alt);\n break;\n }\n }\n walk(root);\n return out;\n}\n\nfunction resolveOne(\n output: Output,\n index: number,\n localNames: NameIndex,\n globalNames: NameIndex,\n): { resolved: ResolvedOutput; errors: OutputDiagnostic[] } {\n const errors: OutputDiagnostic[] = [];\n const name = effectiveOutputName(output, index);\n const tokens: ResolvedToken[] = [];\n for (const token of output.tokens) {\n if (token.kind === \"literal\") {\n tokens.push({ kind: \"literal\", value: token.value });\n continue;\n }\n // Prefer a binding declared within the output's own scope subtree. Union\n // arms duplicate field names across scopes (each arm is its own scope), so\n // the global index alone would resolve an arm's output ref to a sibling\n // arm's binding, mixing contradictory variant gates into one output. Fall\n // back to the global index for refs to bindings outside the local subtree.\n const binding =\n localNames.byName.get(token.target.name) ?? globalNames.byName.get(token.target.name);\n if (!binding) {\n errors.push({\n output: name,\n level: \"error\",\n message: `token ref '${token.target.name}' has no binding with that name (frontend produced an inconsistent output spec)`,\n });\n continue;\n }\n tokens.push({\n kind: \"ref\",\n binding: binding.id,\n ...(token.stripExtensions && { stripExtensions: token.stripExtensions }),\n ...(token.fallback !== undefined && { fallback: token.fallback }),\n });\n }\n const resolved: ResolvedOutput = {\n name,\n ...(output.doc && { doc: output.doc }),\n tokens,\n ...(output.mediaTypes && { mediaTypes: output.mediaTypes }),\n };\n return { resolved, errors };\n}\n\n/**\n * Translate each `NodeMeta.outputs` entry against the binding registry,\n * grouped by the declaring struct binding (the \"scope\"). The solver forces a\n * binding on every output-carrying sequence, so an output without a scope\n * binding indicates a frontend bug (outputs attached to a non-sequence\n * node) - it is reported as a diagnostic and dropped.\n */\nexport function resolveOutputs(root: Expr, solved: SolveResult): OutputResolution {\n const names = indexBindingsByName(root, solved.resolve);\n const collected = collectScopes(root);\n\n const byScope = new Map<BindingId, OutputScope>();\n const errors: OutputDiagnostic[] = [];\n const warnings: OutputDiagnostic[] = [];\n\n let outputIndex = 0;\n for (const { node, outputs } of collected) {\n const scopeBinding = solved.resolve(node);\n if (!scopeBinding) {\n for (const output of outputs) {\n const name = effectiveOutputName(output, outputIndex++);\n errors.push({\n output: name,\n level: \"error\",\n message: `output '${name}' is attached to a node without a binding (frontends should attach outputs to struct sequences)`,\n });\n }\n continue;\n }\n let bucket = byScope.get(scopeBinding.id);\n if (!bucket) {\n bucket = { scope: scopeBinding.id, outputs: [] };\n byScope.set(scopeBinding.id, bucket);\n }\n // Index only the bindings within this scope's subtree (including the scope\n // node's own binding), so an output ref resolves to the field declared in\n // the same scope (union arm) before falling back to the global index.\n const localNames = indexBindingsByName(node, solved.resolve, true);\n for (const output of outputs) {\n const { resolved, errors: outErrors } = resolveOne(output, outputIndex++, localNames, names);\n errors.push(...outErrors);\n bucket.outputs.push(resolved);\n }\n }\n\n return {\n scopes: Array.from(byScope.values()),\n diagnostics: { errors, warnings },\n };\n}\n","import type { AccessPath, AccessSegment, Binding, BoundType } from \"../bindings/index.js\";\nimport type { Expr } from \"../ir/index.js\";\n\n/**\n * Attach `Binding.access` to every binding by walking the IR once, threading\n * the same scope state the backend walkers used to re-derive independently\n * (`arg-builder.walk` and `outputs-emit.walkAccess`). Producing the paths here,\n * after types settle, collapses both walkers into pure `renderAccess` lookups\n * and removes the drift class between them.\n *\n * The walk faithfully mirrors the (post-`ca61dc8`) arg-builder/outputs-emit\n * scope handling for sequence/optional/alternative, and adopts the\n * arg-builder's `repeat` recursion (which `walkAccess` lacked) so bindings\n * inside a `repeat`-of-list get an `iter`-rooted path instead of being absent.\n */\nexport function assignAccessPaths(expr: Expr, resolve: (node: Expr) => Binding | undefined): void {\n const rootBinding = resolve(expr);\n walk(expr, resolve, { path: [], currentStructType: rootBinding?.type });\n}\n\n/**\n * Scope state threaded down the walk, mirroring the arg-builder's `ArgContext`\n * but carrying structured paths instead of rendered strings.\n */\ninterface AccessCtx {\n /** Access path of the enclosing struct scope (the base for child fields). */\n path: AccessPath;\n /**\n * When set, the next binding's value lives at this exact path rather than at\n * `path + field(name)` - the wrapper collapsed the inner value onto its own\n * path (`optional<scalar>`/`optional<bool>`, scalar lists). Mirrors the\n * arg-builder's `directValue`. Not a rendered segment: it is \"inherit the\n * parent's path, append nothing\".\n */\n directPath?: AccessPath;\n /** The struct type at the current scope level (prevents double-scoping). */\n currentStructType?: BoundType;\n}\n\nfunction field(name: string): AccessSegment {\n return { kind: \"field\", name };\n}\n\nfunction iter(binding: string): AccessSegment {\n return { kind: \"iter\", binding };\n}\n\n/** The path at which a binding's own value lives in the current scope. */\nfunction ownAccess(arg: AccessCtx, name: string): AccessPath {\n return arg.directPath ?? [...arg.path, field(name)];\n}\n\n/** Whether a BoundType contains a struct that requires scoping when entered. */\nfunction hasStructScope(type: BoundType): boolean {\n switch (type.kind) {\n case \"optional\":\n return hasStructScope(type.inner);\n case \"list\":\n return hasStructScope(type.item);\n case \"struct\":\n return true;\n default:\n return false;\n }\n}\n\n/** Unwrap optional/list to find the inner struct type, if any. */\nfunction unwrapToStruct(type: BoundType): Extract<BoundType, { kind: \"struct\" }> | undefined {\n switch (type.kind) {\n case \"optional\":\n return unwrapToStruct(type.inner);\n case \"list\":\n return unwrapToStruct(type.item);\n case \"struct\":\n return type;\n default:\n return undefined;\n }\n}\n\nfunction walk(node: Expr, resolve: (node: Expr) => Binding | undefined, arg: AccessCtx): void {\n const binding = resolve(node);\n\n switch (node.kind) {\n case \"literal\":\n return;\n\n case \"int\":\n case \"float\":\n case \"str\":\n case \"path\": {\n if (binding) binding.access = ownAccess(arg, binding.name);\n return;\n }\n\n case \"sequence\": {\n let childArg = arg;\n if (binding && hasStructScope(binding.type) && binding.type !== arg.currentStructType) {\n // A nested struct: children access fields under this binding's path.\n const access: AccessPath = [...arg.path, field(binding.name)];\n binding.access = access;\n childArg = {\n path: access,\n currentStructType: unwrapToStruct(binding.type) ?? arg.currentStructType,\n };\n } else if (binding) {\n // Root struct or a struct already scoped by an enclosing wrapper: the\n // binding reuses the current path (collapse / already-scoped).\n binding.access = arg.directPath ?? arg.path;\n }\n for (const child of node.attrs.nodes) walk(child, resolve, childArg);\n return;\n }\n\n case \"optional\": {\n if (!binding) {\n walk(node.attrs.node, resolve, arg);\n return;\n }\n const access: AccessPath = [...arg.path, field(binding.name)];\n binding.access = access;\n // The inner node, after unwrapping the optional from the binding type.\n const innerType = binding.type.kind === \"optional\" ? binding.type.inner : binding.type;\n let childArg: AccessCtx;\n if (binding.type === arg.currentStructType) {\n // This optional IS the boxed single-field union variant: a collapsed\n // single-input arm whose type the solver retyped to the variant's\n // struct (so `binding.type === currentStructType`). It maps to the\n // variant's lone field, so the inner value collapses onto this\n // optional's own field access. Without this, the struct-scope branch\n // below would add a spurious extra segment named after the inner IR\n // node (e.g. `params.opts.exponential_options.smoothing_standard_deviation`)\n // instead of the boxed field (`params.opts.exponential_options`). The\n // sequence case guards the same way via its `!== currentStructType` test.\n childArg = { ...arg, directPath: access };\n } else if (innerType.kind === \"list\") {\n // optional<list>: the inner node is a `repeat` that represents this same\n // value and assigns its own (iter-based) child scope. It must reuse this\n // optional's path rather than append its field again - otherwise a\n // struct-list field whose name matches the optional's collides into a\n // doubled path (`params.config.config`). `directPath` = \"inherit this\n // path, append nothing\". Scalar lists already reached here via the\n // optional/bool branch below; struct lists previously fell into the\n // `hasStructScope` branch and got the doubled path.\n childArg = { ...arg, directPath: access };\n } else if (hasStructScope(binding.type)) {\n childArg = {\n path: access,\n currentStructType: unwrapToStruct(binding.type) ?? arg.currentStructType,\n };\n } else if (binding.type.kind === \"optional\" || binding.type.kind === \"bool\") {\n // Collapsed non-struct: the inner value lives at the optional's path.\n childArg = { ...arg, directPath: access };\n } else {\n childArg = arg;\n }\n walk(node.attrs.node, resolve, childArg);\n return;\n }\n\n case \"repeat\": {\n // The solver always binds repeat nodes, so this is defensive only; unlike\n // optional/alternative there are no children to recurse into without it.\n if (!binding) return;\n // The list/count binding lives at its own access path.\n binding.access = ownAccess(arg, binding.name);\n\n if (binding.type.kind === \"count\") {\n // Count repeats wrap a literal (no inner binding); recurse harmlessly\n // with the scope unchanged, mirroring the arg-builder.\n walk(node.attrs.node, resolve, arg);\n return;\n }\n\n // List repeat: inner bindings are iteration-scoped. Reset the base to an\n // `iter` segment bound to this repeat; the renderer substitutes the loop\n // variable. Scalar lists collapse the element onto the loop var directly\n // (directPath), struct lists scope into the element type.\n const itemType = binding.type.kind === \"list\" ? binding.type.item : undefined;\n const isScalar = !itemType || !hasStructScope(itemType);\n const elementPath: AccessPath = [iter(binding.id)];\n const childArg: AccessCtx = {\n path: elementPath,\n directPath: isScalar ? elementPath : undefined,\n currentStructType:\n !isScalar && itemType?.kind === \"struct\" ? itemType : arg.currentStructType,\n };\n walk(node.attrs.node, resolve, childArg);\n return;\n }\n\n case \"alternative\": {\n if (!binding) {\n for (const alt of node.attrs.alts) walk(alt, resolve, arg);\n return;\n }\n const access = ownAccess(arg, binding.name);\n binding.access = access;\n const isComplexUnion =\n binding.type.kind === \"union\" &&\n !binding.type.variants.every((v) => v.type.kind === \"literal\");\n node.attrs.alts.forEach((alt, i) => {\n if (isComplexUnion && binding.type.kind === \"union\") {\n // A complex-union variant's fields are accessed via the union's own\n // path (the `@type` discriminant narrows it), so scope into `access`.\n const variantType = binding.type.variants[i]?.type;\n walk(alt, resolve, {\n path: access,\n currentStructType: variantType?.kind === \"struct\" ? variantType : arg.currentStructType,\n });\n } else {\n walk(alt, resolve, arg);\n }\n });\n return;\n }\n }\n}\n","import type { Binding, BindingId, BoundType, GateAtom, SolveResult } from \"../bindings/index.js\";\nimport { createRegistry } from \"../bindings/index.js\";\nimport type { Expr, Literal } from \"../ir/index.js\";\nimport { assignAccessPaths } from \"./assign-access.js\";\n\nexport interface SolveOptions {\n namingStrategy?: NamingStrategy;\n}\n\nexport interface NamingStrategy {\n getName: (node: Expr, path: string[]) => string;\n generateId: () => BindingId;\n}\n\n// Shared helper for deep name search\nfunction findDeepName(node: Expr): string | undefined {\n if (node.meta?.name) return node.meta.name;\n\n if (node.kind === \"optional\" || node.kind === \"repeat\") {\n return findDeepName(node.attrs.node);\n }\n\n if (node.kind === \"sequence\") {\n return node.attrs.nodes\n .filter((n) => n.kind !== \"literal\")\n .map(findDeepName)\n .find(Boolean);\n }\n\n return undefined;\n}\n\nexport function defaultNamingStrategy(): NamingStrategy {\n let counter = 0;\n\n return {\n getName: (node, path) => findDeepName(node) ?? path[path.length - 1] ?? `param_${counter++}`,\n generateId: () => `binding_${counter++}`,\n };\n}\n\n// Helper to check if alternative should collapse to bool\nfunction isBooleanLiteralPair(variants: Array<{ type: BoundType }>): boolean {\n if (variants.length !== 2 || !variants.every((v) => v.type.kind === \"literal\")) {\n return false;\n }\n const [a, b] = variants.map((v) => (v.type.kind === \"literal\" ? v.type.value : null));\n return (\n (a === 0 && b === 1) ||\n (a === 1 && b === 0) ||\n (a === \"0\" && b === \"1\") ||\n (a === \"1\" && b === \"0\") ||\n (a === \"false\" && b === \"true\") ||\n (a === \"true\" && b === \"false\")\n );\n}\n\n// Helper to create literal bound type from IR literal\nfunction literalFromNode(node: Literal): BoundType {\n const str = node.attrs.str;\n const num = Number(str);\n const isCleanInt = Number.isInteger(num) && !Number.isNaN(num) && String(num) === str;\n return { kind: \"literal\", value: isCleanInt ? num : str };\n}\n\n/**\n * Name to give the single wrapped field when a non-struct variant gets boxed\n * into a discriminated struct. For a sequence arm the wrapped value is the\n * inner parameter (`seq(lit(\"convert\"), path{src})` -> `src`), so look past the\n * arm's own (variant) name; otherwise use the value's own deep name.\n */\nfunction innerParamName(armNode: Expr): string {\n if (armNode.kind === \"sequence\") {\n const inner = armNode.attrs.nodes\n .filter((n) => n.kind !== \"literal\")\n .map(findDeepName)\n .find(Boolean);\n if (inner) return inner;\n }\n return findDeepName(armNode) ?? \"value\";\n}\n\n/**\n * Discriminated form of a variant's type: literal variants discriminate by\n * value (returned unchanged); struct variants get an `@type` field prepended;\n * anything else is boxed into `{ \"@type\": <name>, <field>: <type> }`. Pure -\n * never mutates `type`.\n */\nfunction taggedVariantType(name: string, type: BoundType, armNode: Expr): BoundType {\n if (type.kind === \"literal\") return type;\n const tag: BoundType = { kind: \"literal\", value: name };\n if (type.kind === \"struct\") return { kind: \"struct\", fields: { \"@type\": tag, ...type.fields } };\n return { kind: \"struct\", fields: { \"@type\": tag, [innerParamName(armNode)]: type } };\n}\n\nexport function solve(expr: Expr, options?: SolveOptions): SolveResult {\n const strategy = options?.namingStrategy ?? defaultNamingStrategy();\n const registry = createRegistry();\n const nodeToBinding = new WeakMap<Expr, Binding>();\n\n // Wrapper bindings (optional/repeat/alternative) need an id BEFORE recursing\n // into children so the child's `gate` can reference it. Pre-allocate the id\n // here, then materialize the binding with its computed type after the\n // recursion settles.\n function preallocate(): BindingId {\n return strategy.generateId();\n }\n\n function registerBinding(\n id: BindingId,\n node: Expr,\n name: string,\n type: BoundType,\n gate: GateAtom[],\n ): Binding {\n // `access` is filled by `assignAccessPaths` once all types have settled\n // (sequence collapse-vs-struct and union arm retyping are only known after\n // the full recursion). Start empty so the field is always present.\n const binding: Binding = { id, node, name, type, gate, access: [] };\n registry.set(id, binding);\n nodeToBinding.set(node, binding);\n return binding;\n }\n\n function createBinding(node: Expr, name: string, type: BoundType, gate: GateAtom[]): Binding {\n return registerBinding(strategy.generateId(), node, name, type, gate);\n }\n\n function solveNode(node: Expr, path: string[], gate: GateAtom[]): BoundType | null {\n const name = strategy.getName(node, path);\n\n switch (node.kind) {\n case \"literal\":\n return null;\n\n case \"optional\": {\n const id = preallocate();\n const childGate = [...gate, { kind: \"present\" as const, binding: id }];\n const inner = solveNode(node.attrs.node, [...path, name], childGate);\n const type: BoundType = inner === null ? { kind: \"bool\" } : { kind: \"optional\", inner };\n registerBinding(id, node, name, type, gate);\n return type;\n }\n\n case \"repeat\": {\n const id = preallocate();\n // We don't yet know if the inner collapses to a count (no inner\n // binding -> repeat-of-literal) or to a list. Optimistically tag the\n // child gate as `iter`; if the inner is null we replace the wrapper\n // type with `count` and the iter atom never reaches a real binding\n // (no inner binding consumes the gate).\n const childGate = [...gate, { kind: \"iter\" as const, binding: id }];\n const inner = solveNode(node.attrs.node, [...path, name], childGate);\n const type: BoundType = inner === null ? { kind: \"count\" } : { kind: \"list\", item: inner };\n registerBinding(id, node, name, type, gate);\n return type;\n }\n\n case \"sequence\": {\n const fields: Record<string, BoundType> = {};\n // Track the single binding-bearing child so the collapse check below can\n // inspect its node kind (only meaningful when exactly one field exists).\n let soleFieldChild: Expr | undefined;\n for (const child of node.attrs.nodes) {\n const childName = strategy.getName(child, path);\n const childType = solveNode(child, [...path, childName], gate);\n if (childType !== null) {\n fields[childName] = childType;\n soleFieldChild = child;\n }\n }\n // A sequence that carries `meta.outputs` must always produce a binding,\n // even when it would otherwise collapse - that binding is the scope key\n // for the outputs declared on it. Empty- and single-field collapses\n // would otherwise leave the scope unbound and the outputs orphaned.\n const hasOutputs = node.meta?.outputs && node.meta.outputs.length > 0;\n if (Object.keys(fields).length === 0) {\n if (hasOutputs) {\n const type: BoundType = { kind: \"struct\", fields: {} };\n createBinding(node, name, type, gate);\n return type;\n }\n return null;\n }\n // Collapse a single-field sequence to that field - e.g. `-x <val>`\n // (`seq(lit(\"-x\"), str)`) becomes just the value, so the flag and its\n // one value read as a single optional/required parameter.\n //\n // EXCEPTION: when the field comes from an `optional` child, the\n // sequence's own literal (e.g. `-whole-file`) can be present while the\n // optional sub-field (e.g. `-demean`) is absent. Collapsing would\n // conflate those two independent optional states and drop the sub-field\n // (it would have no struct to live on). Keep such a sequence a struct so\n // the sub-field stays addressable. A `repeat`/scalar/alternative child\n // is tied 1:1 to the flag's presence, so collapsing those stays correct.\n if (\n Object.keys(fields).length === 1 &&\n !hasOutputs &&\n soleFieldChild?.kind !== \"optional\"\n ) {\n return Object.values(fields)[0]!;\n }\n const type: BoundType = { kind: \"struct\", fields };\n createBinding(node, name, type, gate);\n return type;\n }\n\n case \"alternative\": {\n const id = preallocate();\n // Resolve each arm's variant name first so child gates can carry it.\n // `variantTag` (the sub-command id) is preferred over `name`: a\n // single-field sub-command collapses onto its inner field, whose `name`\n // wins, so `name` alone would derive the tag from the inner field's id\n // (two distinct sub-commands wrapping a same-named field would collide).\n const armNames = node.attrs.alts.map((alt, i) => {\n if (alt.meta?.variantTag) return alt.meta.variantTag;\n if (alt.meta?.name) return alt.meta.name;\n if (alt.kind === \"literal\") return alt.attrs.str.replace(/^-+/, \"\");\n return `variant_${i}`;\n });\n\n const variants = node.attrs.alts.map((alt, i) => {\n const variantName = armNames[i]!;\n const childGate = [\n ...gate,\n { kind: \"variant\" as const, binding: id, variant: variantName },\n ];\n const childType =\n solveNode(alt, [...path, `variant_${i}`], childGate) ??\n (alt.kind === \"literal\" ? literalFromNode(alt) : { kind: \"bool\" as const });\n return { name: variantName, type: childType, node: alt };\n });\n\n // Pattern: boolean pair -> bool. The pre-allocated variant atoms in\n // child gates are unreached (literal arms produce no bindings).\n if (isBooleanLiteralPair(variants)) {\n const type: BoundType = { kind: \"bool\" };\n registerBinding(id, node, name, type, gate);\n return type;\n }\n\n // Discriminate each variant. When an arm carries its own binding (a\n // multi-field struct), retype it so that binding and the union agree;\n // collapsed single-field arms keep their inner binding and the boxed\n // form lives only in the union's `variants`.\n for (const v of variants) {\n v.type = taggedVariantType(v.name, v.type, v.node);\n const armBinding = nodeToBinding.get(v.node);\n if (armBinding) armBinding.type = v.type;\n }\n\n const type: BoundType = {\n kind: \"union\",\n variants: variants.map(({ name, type }) => ({ name, type })),\n };\n registerBinding(id, node, name, type, gate);\n return type;\n }\n\n case \"int\":\n case \"float\":\n case \"str\":\n case \"path\": {\n const type: BoundType = { kind: \"scalar\", scalar: node.kind };\n createBinding(node, name, type, gate);\n return type;\n }\n }\n }\n\n const rootType = solveNode(expr, [], []);\n\n // Ensure a root binding always exists, even when the sequence collapsed\n // (0 fields -> empty struct, 1 field that's not already a struct -> wrap in single-field struct)\n if (!nodeToBinding.has(expr) && expr.kind === \"sequence\") {\n const name = strategy.getName(expr, []);\n if (rootType === null) {\n createBinding(expr, name, { kind: \"struct\", fields: {} }, []);\n } else if (rootType.kind === \"struct\") {\n // Already a struct (e.g. joined seq with 2+ fields) - use it directly\n createBinding(expr, name, rootType, []);\n } else {\n // Single scalar/optional/list field was collapsed - wrap it in a struct.\n // The field's binding may not be a direct child: a nested sequence that\n // collapsed (e.g. one preserved by flatten to keep its `meta.doc`) leaves\n // the binding buried one or more levels down. Search through collapsed\n // sequences for it. Using `binding.name` as the field name keeps the\n // struct field aligned with the access path the backends render\n // (`params.<binding.name>`).\n const findCollapsedBinding = (node: Expr): Binding | undefined => {\n const b = nodeToBinding.get(node);\n if (b) return b;\n // Only sequences collapse without leaving a binding; optional/repeat/\n // alternative always register one, so no need to descend into them.\n if (node.kind === \"sequence\") {\n for (const child of node.attrs.nodes) {\n const found = findCollapsedBinding(child);\n if (found) return found;\n }\n }\n return undefined;\n };\n const childName = expr.attrs.nodes.map(findCollapsedBinding).find(Boolean)?.name;\n if (childName) {\n createBinding(expr, name, { kind: \"struct\", fields: { [childName]: rootType } }, []);\n }\n }\n }\n\n const resolve = (node: Expr) => nodeToBinding.get(node);\n\n // Now that every binding's type has settled (sequence collapse, union arm\n // retyping, root fixup), walk the IR once more to attach each binding's\n // access path relative to top-level `params`. Backends render these paths\n // instead of re-deriving them.\n assignAccessPaths(expr, resolve);\n\n return { bindings: registry, resolve };\n}\n","import { ArgdumpParser } from \"./frontend/argdump/index.js\";\nimport { BoutiquesParser } from \"./frontend/boutiques/index.js\";\nimport { MrtrixParser } from \"./frontend/mrtrix/index.js\";\nimport { WorkbenchParser } from \"./frontend/workbench/index.js\";\nimport { detectFormat } from \"./frontend/detect-format.js\";\nimport type { FormatName } from \"./frontend/detect-format.js\";\nimport type { ParseResult } from \"./frontend/frontend.js\";\n\nexport * from \"./backend/index.js\";\nexport * from \"./bindings/index.js\";\nexport * from \"./frontend/index.js\";\nexport * from \"./ir/index.js\";\nexport * from \"./manifest/index.js\";\nexport * from \"./solver/index.js\";\n\nexport function compile(\n source: string,\n filenameOrOptions?: string | { format?: FormatName; filename?: string },\n): ParseResult {\n const options =\n typeof filenameOrOptions === \"string\"\n ? { filename: filenameOrOptions }\n : (filenameOrOptions ?? {});\n\n const format = options.format ?? detectFormat(source);\n\n if (!format) {\n return {\n expr: { kind: \"sequence\", attrs: { nodes: [] } },\n errors: [{ message: \"Could not detect input format. Specify format explicitly.\" }],\n warnings: [],\n };\n }\n\n const parser =\n format === \"argdump\"\n ? new ArgdumpParser()\n : format === \"workbench\"\n ? new WorkbenchParser()\n : format === \"mrtrix\"\n ? new MrtrixParser()\n : new BoutiquesParser();\n return parser.parse(source, options.filename);\n}\n"],"mappings":"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"}
|