@styx-api/cli 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/bin.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const require_write = require('./write-BtRGJfHV.cjs');
2
+ const require_write = require('./write-CpqGjb9N.cjs');
3
3
  let cac = require("cac");
4
4
 
5
5
  //#region src/command.ts
package/dist/bin.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { i as build, n as knownBackends, r as resolveBackends, t as writeFiles } from "./write-DSW1zlom.mjs";
2
+ import { i as build, n as knownBackends, r as resolveBackends, t as writeFiles } from "./write-BSYxLVtX.mjs";
3
3
  import { cac } from "cac";
4
4
 
5
5
  //#region src/command.ts
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- const require_write = require('./write-BtRGJfHV.cjs');
1
+ const require_write = require('./write-CpqGjb9N.cjs');
2
2
 
3
3
  exports.build = require_write.build;
4
4
  exports.detectLevel = require_write.detectLevel;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/build.ts","../src/catalog.ts","../src/backends.ts","../src/write.ts"],"mappings":";;;KAoBY,SAAA;AAAA,UASK,YAAA;EATL;EAWV,KAAA;;EAEA,OAAA;EAbmB;EAenB,GAAA;EAN2B;EAQ3B,QAAA,EAAU,OAAA;EAEK;EAAf,IAAA,EAAM,SAAA;AAAA;;UAIS,SAAA;EANL;EAQV,IAAA;EACA,OAAA;AAAA;;UAIe,UAAA;EACf,YAAA;EACA,UAAA;EACA,WAAA;AAAA;AAAA,UAGe,WAAA;EACf,KAAA,EAAO,SAAA;EACP,MAAA;EACA,QAAA;EARA;EAUA,KAAA,GAAQ,UAAA;AAAA;;;AALV;;;iBAkBgB,KAAA,CAAM,OAAA,EAAS,YAAA,GAAe,WAAA;;;;;AAtD9C;;;UCViB,cAAA;EACf,IAAA,EAAM,WAAA;EACN,QAAA,EAAU,cAAA;EDiBiB;ECf3B,QAAA;AAAA;AAAA,UAGe,cAAA;EACf,IAAA,EAAM,WAAA;EACN,IAAA,EAAM,UAAA;AAAA;AAAA,UAGS,UAAA;EDiBf;ECfA,IAAA;EDee;ECbf,UAAA;EACA,YAAA;AAAA;;;;ADuBF;;KC4CY,YAAA;AAAA,iBAEI,WAAA,CAAY,GAAA,WAAc,YAAA;;;;;;iBAmH1B,WAAA,CAAY,IAAA,WAAe,cAAA;;;cC9L9B,aAAA;AAAA,iBAEG,eAAA,CAAgB,KAAA;EAAoB,QAAA,EAAU,OAAA;EAAW,OAAA;AAAA;;;iBClBzD,UAAA,CAAW,KAAA,EAAO,SAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/build.ts","../src/catalog.ts","../src/backends.ts","../src/write.ts"],"mappings":";;;KAoBY,SAAA;AAAA,UAUK,YAAA;EAVL;EAYV,KAAA;;EAEA,OAAA;EAdmB;EAgBnB,GAAA;EAN2B;EAQ3B,QAAA,EAAU,OAAA;EAEK;EAAf,IAAA,EAAM,SAAA;AAAA;;UAIS,SAAA;EANL;EAQV,IAAA;EACA,OAAA;AAAA;;UAIe,UAAA;EACf,YAAA;EACA,UAAA;EACA,WAAA;AAAA;AAAA,UAGe,WAAA;EACf,KAAA,EAAO,SAAA;EACP,MAAA;EACA,QAAA;EARA;EAUA,KAAA,GAAQ,UAAA;AAAA;;;AALV;;;iBAkBgB,KAAA,CAAM,OAAA,EAAS,YAAA,GAAe,WAAA;;;;;AAvD9C;;;UCViB,cAAA;EACf,IAAA,EAAM,WAAA;EACN,QAAA,EAAU,cAAA;EDkBiB;EChB3B,QAAA;AAAA;AAAA,UAGe,cAAA;EACf,IAAA,EAAM,WAAA;EACN,IAAA,EAAM,UAAA;AAAA;AAAA,UAGS,UAAA;EDkBf;EChBA,IAAA;EDgBe;ECdf,UAAA;EACA,YAAA;AAAA;;;;ADwBF;;KC2CY,YAAA;AAAA,iBAEI,WAAA,CAAY,GAAA,WAAc,YAAA;;;;;;iBAmH1B,WAAA,CAAY,IAAA,WAAe,cAAA;;;cC9L9B,aAAA;AAAA,iBAEG,eAAA,CAAgB,KAAA;EAAoB,QAAA,EAAU,OAAA;EAAW,OAAA;AAAA;;;iBClBzD,UAAA,CAAW,KAAA,EAAO,SAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/build.ts","../src/catalog.ts","../src/backends.ts","../src/write.ts"],"mappings":";;;KAoBY,SAAA;AAAA,UASK,YAAA;EATL;EAWV,KAAA;;EAEA,OAAA;EAbmB;EAenB,GAAA;EAN2B;EAQ3B,QAAA,EAAU,OAAA;EAEK;EAAf,IAAA,EAAM,SAAA;AAAA;;UAIS,SAAA;EANL;EAQV,IAAA;EACA,OAAA;AAAA;;UAIe,UAAA;EACf,YAAA;EACA,UAAA;EACA,WAAA;AAAA;AAAA,UAGe,WAAA;EACf,KAAA,EAAO,SAAA;EACP,MAAA;EACA,QAAA;EARA;EAUA,KAAA,GAAQ,UAAA;AAAA;;;AALV;;;iBAkBgB,KAAA,CAAM,OAAA,EAAS,YAAA,GAAe,WAAA;;;;;AAtD9C;;;UCViB,cAAA;EACf,IAAA,EAAM,WAAA;EACN,QAAA,EAAU,cAAA;EDiBiB;ECf3B,QAAA;AAAA;AAAA,UAGe,cAAA;EACf,IAAA,EAAM,WAAA;EACN,IAAA,EAAM,UAAA;AAAA;AAAA,UAGS,UAAA;EDiBf;ECfA,IAAA;EDee;ECbf,UAAA;EACA,YAAA;AAAA;;;;ADuBF;;KC4CY,YAAA;AAAA,iBAEI,WAAA,CAAY,GAAA,WAAc,YAAA;;;;;;iBAmH1B,WAAA,CAAY,IAAA,WAAe,cAAA;;;cC9L9B,aAAA;AAAA,iBAEG,eAAA,CAAgB,KAAA;EAAoB,QAAA,EAAU,OAAA;EAAW,OAAA;AAAA;;;iBClBzD,UAAA,CAAW,KAAA,EAAO,SAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/build.ts","../src/catalog.ts","../src/backends.ts","../src/write.ts"],"mappings":";;;KAoBY,SAAA;AAAA,UAUK,YAAA;EAVL;EAYV,KAAA;;EAEA,OAAA;EAdmB;EAgBnB,GAAA;EAN2B;EAQ3B,QAAA,EAAU,OAAA;EAEK;EAAf,IAAA,EAAM,SAAA;AAAA;;UAIS,SAAA;EANL;EAQV,IAAA;EACA,OAAA;AAAA;;UAIe,UAAA;EACf,YAAA;EACA,UAAA;EACA,WAAA;AAAA;AAAA,UAGe,WAAA;EACf,KAAA,EAAO,SAAA;EACP,MAAA;EACA,QAAA;EARA;EAUA,KAAA,GAAQ,UAAA;AAAA;;;AALV;;;iBAkBgB,KAAA,CAAM,OAAA,EAAS,YAAA,GAAe,WAAA;;;;;AAvD9C;;;UCViB,cAAA;EACf,IAAA,EAAM,WAAA;EACN,QAAA,EAAU,cAAA;EDkBiB;EChB3B,QAAA;AAAA;AAAA,UAGe,cAAA;EACf,IAAA,EAAM,WAAA;EACN,IAAA,EAAM,UAAA;AAAA;AAAA,UAGS,UAAA;EDkBf;EChBA,IAAA;EDgBe;ECdf,UAAA;EACA,YAAA;AAAA;;;;ADwBF;;KC2CY,YAAA;AAAA,iBAEI,WAAA,CAAY,GAAA,WAAc,YAAA;;;;;;iBAmH1B,WAAA,CAAY,IAAA,WAAe,cAAA;;;cC9L9B,aAAA;AAAA,iBAEG,eAAA,CAAgB,KAAA;EAAoB,QAAA,EAAU,OAAA;EAAW,OAAA;AAAA;;;iBClBzD,UAAA,CAAW,KAAA,EAAO,SAAA"}
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { a as detectLevel, i as build, n as knownBackends, o as loadCatalog, r as resolveBackends, t as writeFiles } from "./write-DSW1zlom.mjs";
1
+ import { a as detectLevel, i as build, n as knownBackends, o as loadCatalog, r as resolveBackends, t as writeFiles } from "./write-BSYxLVtX.mjs";
2
2
 
3
3
  export { build, detectLevel, knownBackends, loadCatalog, resolveBackends, writeFiles };
@@ -186,7 +186,8 @@ function loadCatalog(root) {
186
186
  const SUPPORTED_FORMATS = new Set([
187
187
  "boutiques",
188
188
  "argdump",
189
- "workbench"
189
+ "workbench",
190
+ "mrtrix"
190
191
  ]);
191
192
  /** Render an unknown thrown value as a message string. */
192
193
  function errMsg(e) {
@@ -412,4 +413,4 @@ function writeFiles(files) {
412
413
 
413
414
  //#endregion
414
415
  export { detectLevel as a, build as i, knownBackends as n, loadCatalog as o, resolveBackends as r, writeFiles as t };
415
- //# sourceMappingURL=write-DSW1zlom.mjs.map
416
+ //# sourceMappingURL=write-BSYxLVtX.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-BSYxLVtX.mjs","names":[],"sources":["../src/catalog.ts","../src/build.ts","../src/backends.ts","../src/write.ts"],"sourcesContent":["import { readFileSync, readdirSync, statSync } from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport type { Documentation, PackageMeta, ProjectMeta } from \"@styx-api/core\";\n\n/**\n * Loaded catalog: a project containing packages, each holding one or more\n * apps. We always normalize to project > package > app even when the catalog\n * root only describes a subset of the hierarchy (e.g. a single version dir).\n */\nexport interface CatalogProject {\n meta: ProjectMeta;\n packages: CatalogPackage[];\n /** Non-fatal issues found while walking the catalog (e.g. skipped stub apps). */\n warnings: string[];\n}\n\nexport interface CatalogPackage {\n meta: PackageMeta;\n apps: CatalogApp[];\n}\n\nexport interface CatalogApp {\n /** Stable identifier from `app.json#name`, used for the emitted module slug. */\n name: string;\n /** Absolute path to the descriptor file referenced by `app.json#source`. */\n sourcePath: string;\n sourceFormat?: string;\n}\n\ninterface ProjectJson {\n name?: string;\n version?: string;\n license?: string;\n packages?: string[];\n docs?: Documentation;\n}\n\ninterface PackageJson {\n name?: string;\n versions?: string[];\n default?: string;\n docs?: Documentation;\n}\n\ninterface VersionJson {\n name?: string;\n container?: string;\n apps?: string[];\n executables?: { required?: string[]; ignored?: string[] };\n}\n\ninterface AppJson {\n name?: string;\n source?: { type?: string; path?: string };\n docs?: Documentation;\n}\n\nfunction readJson<T>(file: string): T {\n let raw: string;\n try {\n raw = readFileSync(file, \"utf8\");\n } catch (e) {\n throw new Error(`${file}: ${e instanceof Error ? e.message : String(e)}`);\n }\n try {\n return JSON.parse(raw) as T;\n } catch (e) {\n throw new Error(`${file}: invalid JSON: ${e instanceof Error ? e.message : String(e)}`);\n }\n}\n\nfunction exists(p: string): boolean {\n try {\n statSync(p);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * Detect what level of the niwrap catalog a directory describes.\n * Project dirs contain `project.json`, package dirs contain `package.json`,\n * version dirs contain `version.json`, app dirs contain `app.json`.\n */\nexport type CatalogLevel = \"project\" | \"package\" | \"version\" | \"app\";\n\nexport function detectLevel(dir: string): CatalogLevel | null {\n if (exists(path.join(dir, \"project.json\"))) return \"project\";\n if (exists(path.join(dir, \"package.json\"))) return \"package\";\n if (exists(path.join(dir, \"version.json\"))) return \"version\";\n if (exists(path.join(dir, \"app.json\"))) return \"app\";\n return null;\n}\n\n/**\n * Load one app descriptor. When `warnings` is supplied (catalog-walk mode), a\n * stub app (`app.json` present but no `source.path`) is skipped with a warning\n * instead of aborting the whole build - real catalogs list not-yet-wrapped tools\n * alongside wrapped ones. Without `warnings` (a direct single-app target) the\n * missing source is a hard error, since the user pointed straight at it.\n */\nfunction loadApp(appDir: string, warnings?: string[]): CatalogApp | null {\n const appJsonPath = path.join(appDir, \"app.json\");\n if (!exists(appJsonPath)) return null;\n const app = readJson<AppJson>(appJsonPath);\n const name = app.name ?? path.basename(appDir);\n const sourceRel = app.source?.path;\n if (!sourceRel) {\n if (warnings) {\n warnings.push(`${appJsonPath}: skipped (no source.path - not yet wrapped)`);\n return null;\n }\n throw new Error(`${appJsonPath}: missing source.path`);\n }\n return {\n name,\n sourcePath: path.resolve(appDir, sourceRel),\n sourceFormat: app.source?.type,\n };\n}\n\nfunction loadVersion(versionDir: string, warnings?: string[]): CatalogPackage | null {\n const versionPath = path.join(versionDir, \"version.json\");\n if (!exists(versionPath)) return null;\n const version = readJson<VersionJson>(versionPath);\n\n // Sort the directory fallback so app order (and thus any shared-scope name\n // dodging) is deterministic regardless of filesystem iteration order.\n const appNames = version.apps ?? listSubdirs(versionDir).sort();\n const apps: CatalogApp[] = [];\n for (const appName of appNames) {\n const appDir = path.join(versionDir, appName);\n if (!isDir(appDir)) continue;\n const app = loadApp(appDir, warnings);\n if (app) apps.push(app);\n }\n\n // Try to enrich with the parent package.json if there is one (package > version layout).\n const parentPkg = path.join(versionDir, \"..\", \"package.json\");\n let pkgName: string | undefined;\n let pkgDoc: Documentation | undefined;\n if (exists(parentPkg)) {\n const pkg = readJson<PackageJson>(parentPkg);\n pkgName = pkg.name;\n pkgDoc = pkg.docs;\n }\n pkgName ??= path.basename(path.dirname(versionDir));\n\n return {\n meta: {\n name: pkgName,\n version: version.name,\n docker: version.container,\n doc: pkgDoc,\n },\n apps,\n };\n}\n\nfunction loadPackage(pkgDir: string, warnings?: string[]): CatalogPackage | null {\n const pkgPath = path.join(pkgDir, \"package.json\");\n if (!exists(pkgPath)) return null;\n const pkg = readJson<PackageJson>(pkgPath);\n\n const versionName = pkg.default ?? pkg.versions?.[0] ?? firstVersionDir(pkgDir);\n if (!versionName) return null;\n const versionDir = path.join(pkgDir, versionName);\n if (!isDir(versionDir)) return null;\n\n const loaded = loadVersion(versionDir, warnings);\n if (!loaded) return null;\n\n return {\n meta: {\n name: pkg.name ?? path.basename(pkgDir),\n version: versionName,\n docker: loaded.meta.docker,\n doc: pkg.docs ?? loaded.meta.doc,\n },\n apps: loaded.apps,\n };\n}\n\nfunction listSubdirs(dir: string): string[] {\n return readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name);\n}\n\nfunction firstVersionDir(pkgDir: string): string | null {\n for (const name of listSubdirs(pkgDir)) {\n if (exists(path.join(pkgDir, name, \"version.json\"))) return name;\n }\n return null;\n}\n\n/**\n * Load a catalog from any niwrap layout level. The level is auto-detected from\n * which `*.json` index file is present in `root`. Always returns a normalized\n * `project > package > app` shape, synthesizing missing layers as needed.\n */\nexport function loadCatalog(root: string): CatalogProject {\n const level = detectLevel(root);\n if (!level) {\n throw new Error(\n `${root}: no project.json / package.json / version.json / app.json found - not a catalog root`,\n );\n }\n\n const warnings: string[] = [];\n\n if (level === \"project\") {\n const project = readJson<ProjectJson>(path.join(root, \"project.json\"));\n const packageNames = project.packages ?? listSubdirs(root);\n const packages: CatalogPackage[] = [];\n for (const name of packageNames) {\n const pkgDir = path.join(root, name);\n const pkg = loadPackage(pkgDir, warnings);\n if (pkg) packages.push(pkg);\n }\n return {\n meta: {\n name: project.name,\n version: project.version,\n doc: project.docs,\n license: project.license ? { description: project.license } : undefined,\n },\n packages,\n warnings,\n };\n }\n\n if (level === \"package\") {\n const pkg = loadPackage(root, warnings);\n if (!pkg) throw new Error(`${root}: package.json present but no resolvable version`);\n return { meta: { name: pkg.meta.name }, packages: [pkg], warnings };\n }\n\n if (level === \"version\") {\n const pkg = loadVersion(root, warnings);\n if (!pkg) throw new Error(`${root}: version.json present but failed to load`);\n return { meta: { name: pkg.meta.name }, packages: [pkg], warnings };\n }\n\n // level === \"app\": a direct single-app target, so a missing source is fatal.\n const app = loadApp(root);\n if (!app) throw new Error(`${root}: app.json present but missing source.path`);\n return {\n meta: {},\n packages: [\n {\n meta: { name: path.basename(path.dirname(root)) },\n apps: [app],\n },\n ],\n warnings,\n };\n}\n","import { readFileSync } from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport {\n compile,\n createContext,\n defaultPipeline,\n resolveOutputs,\n solve,\n type Backend,\n type EmitResult,\n type EmittedApp,\n type EmittedPackage,\n type FormatName,\n type PackageMeta,\n type ProjectMeta,\n} from \"@styx-api/core\";\n\nimport { loadCatalog, type CatalogProject } from \"./catalog.js\";\n\nexport type BuildMode = \"scripts\" | \"single\" | \"multi\";\n\n/** Frontend formats the compiler can parse; others are skipped with a warning. */\nconst SUPPORTED_FORMATS: ReadonlySet<string> = new Set<FormatName>([\n \"boutiques\",\n \"argdump\",\n \"workbench\",\n \"mrtrix\",\n]);\n\nexport interface BuildOptions {\n /** Single-descriptor input file (mutually exclusive with `catalog`). */\n input?: string;\n /** Catalog directory (mutually exclusive with `input`). */\n catalog?: string;\n /** Output directory; per-backend files end up under `<out>/<backend.target>/...`. */\n out: string;\n /** Backends to run (instances pre-resolved by the caller). */\n backends: Backend[];\n /** Which emit tiers to run. */\n mode: BuildMode;\n}\n\n/** A single file from a backend run, keyed by destination path. */\nexport interface BuiltFile {\n /** Absolute destination path. */\n path: string;\n content: string;\n}\n\n/** Per-tool tallies for a catalog build (undefined for single-descriptor builds). */\nexport interface BuildStats {\n appsCompiled: number;\n appsFailed: number;\n appsSkipped: number;\n}\n\nexport interface BuildResult {\n files: BuiltFile[];\n errors: string[];\n warnings: string[];\n /** Catalog-build tallies; set only by `--catalog` builds. */\n stats?: BuildStats;\n}\n\n/** Render an unknown thrown value as a message string. */\nfunction errMsg(e: unknown): string {\n return e instanceof Error ? e.message : String(e);\n}\n\n/**\n * Run the build. Returns the assembled file map and diagnostics; the caller\n * is responsible for actually writing to disk (so tests can introspect the\n * map directly).\n */\nexport function build(options: BuildOptions): BuildResult {\n if (options.input && options.catalog) {\n return { files: [], errors: [\"--input and --catalog are mutually exclusive\"], warnings: [] };\n }\n if (!options.input && !options.catalog) {\n return {\n files: [],\n errors: [\"missing input: pass a descriptor path or --catalog\"],\n warnings: [],\n };\n }\n\n if (options.input) return buildSingle(options.input, options);\n return buildCatalog(options.catalog!, options);\n}\n\nfunction buildSingle(inputPath: string, options: BuildOptions): BuildResult {\n const result: BuildResult = { files: [], errors: [], warnings: [] };\n\n const ctx = readAndCompile(inputPath, undefined, undefined, undefined, result);\n if (!ctx) return result;\n\n for (const backend of options.backends) {\n let emitted;\n try {\n emitted = backend.emitApp(ctx);\n } catch (e) {\n result.errors.push(`[${backend.name}] ${errMsg(e)}`);\n continue;\n }\n appendEmitMessages(result, emitted, backend);\n for (const [name, content] of emitted.files) {\n result.files.push({\n path: path.resolve(options.out, backend.target, name),\n content,\n });\n }\n }\n return result;\n}\n\nfunction buildCatalog(catalogPath: string, options: BuildOptions): BuildResult {\n const result: BuildResult = {\n files: [],\n errors: [],\n warnings: [],\n stats: { appsCompiled: 0, appsFailed: 0, appsSkipped: 0 },\n };\n let catalog: CatalogProject;\n try {\n catalog = loadCatalog(catalogPath);\n } catch (e) {\n result.errors.push(e instanceof Error ? e.message : String(e));\n return result;\n }\n result.warnings.push(...catalog.warnings);\n\n // Skip/empty warnings are backend-independent, so only the first backend pass\n // records them - otherwise they'd be duplicated once per backend.\n options.backends.forEach((backend, i) => {\n runBackendOverCatalog(backend, catalog, options.mode, options.out, result, i === 0);\n });\n return result;\n}\n\n/**\n * Parse a descriptor, run the default optimization pipeline, solve to\n * bindings, and build a `CodegenContext` wired up with the supplied\n * package/project meta. Returns null on read failure (with the error already\n * appended to `result`). Parse-level errors/warnings are also appended.\n */\nfunction readAndCompile(\n sourcePath: string,\n format: string | undefined,\n pkg: PackageMeta | undefined,\n proj: ProjectMeta | undefined,\n result: BuildResult,\n): ReturnType<typeof createContext> | null {\n let source: string;\n try {\n source = readFileSync(sourcePath, \"utf8\");\n } catch (e) {\n result.errors.push(`${sourcePath}: ${errMsg(e)}`);\n return null;\n }\n\n // Isolate the compile pipeline: a single descriptor that makes the solver or\n // a downstream pass throw is recorded as an error and skipped, so one bad tool\n // can't crash a whole-catalog build.\n try {\n // Honor the catalog's declared format when it's one we support, so we don't\n // fall back to content sniffing (and get a clearer error if it mis-parses).\n const parsed = compile(\n source,\n format && SUPPORTED_FORMATS.has(format)\n ? { filename: sourcePath, format: format as FormatName }\n : sourcePath,\n );\n for (const e of parsed.errors) result.errors.push(`${sourcePath}: ${e.message}`);\n for (const w of parsed.warnings) result.warnings.push(`${sourcePath}: ${w.message}`);\n\n const piped = defaultPipeline.apply(parsed.expr);\n if (piped.warnings) {\n for (const w of piped.warnings) result.warnings.push(`${sourcePath}: ${w}`);\n }\n\n const solveResult = solve(piped.expr);\n const outputs = resolveOutputs(piped.expr, solveResult);\n return createContext(piped.expr, solveResult, outputs, {\n app: parsed.meta,\n package: pkg,\n project: proj,\n });\n } catch (e) {\n result.errors.push(`${sourcePath}: ${errMsg(e)}`);\n return null;\n }\n}\n\nfunction runBackendOverCatalog(\n backend: Backend,\n catalog: CatalogProject,\n mode: BuildMode,\n outRoot: string,\n result: BuildResult,\n recordWarnings: boolean,\n): void {\n const backendRoot = path.resolve(outRoot, backend.target);\n const packagesEmitted: EmittedPackage[] = [];\n\n for (const pkg of catalog.packages) {\n const pkgDir = pkg.meta.name ?? \"package\";\n const appsEmitted: EmittedApp[] = [];\n let skipped = 0;\n // One scope shared across every tool in the suite so top-level names stay\n // unique across the package's flat barrel re-exports.\n const pkgScope = backend.newPackageScope?.();\n\n for (const app of pkg.apps) {\n // A tool can declare a format we have no frontend for yet (e.g. Workbench).\n // Skip it with a warning rather than failing the whole catalog build.\n if (app.sourceFormat && !SUPPORTED_FORMATS.has(app.sourceFormat)) {\n skipped++;\n if (recordWarnings) {\n if (result.stats) result.stats.appsSkipped++;\n result.warnings.push(\n `${app.sourcePath}: skipped (unsupported source format \"${app.sourceFormat}\")`,\n );\n }\n continue;\n }\n\n const ctx = readAndCompile(app.sourcePath, app.sourceFormat, pkg.meta, catalog.meta, result);\n if (!ctx) {\n if (recordWarnings && result.stats) result.stats.appsFailed++;\n continue;\n }\n\n // Isolate emit so one tool that makes a backend throw doesn't crash the run.\n let emitted: EmittedApp;\n try {\n emitted = backend.emitApp(ctx, pkgScope);\n } catch (e) {\n result.errors.push(`[${backend.name} ${pkg.meta.name}/${app.name}] ${errMsg(e)}`);\n if (recordWarnings && result.stats) result.stats.appsFailed++;\n continue;\n }\n appendEmitMessages(result, emitted, backend, `${pkg.meta.name}/${app.name}`);\n appsEmitted.push(emitted);\n if (recordWarnings && result.stats) result.stats.appsCompiled++;\n\n for (const [name, content] of emitted.files) {\n result.files.push({ path: path.join(backendRoot, pkgDir, name), content });\n }\n }\n\n // A suite whose every tool was skipped (e.g. all-Workbench) emits nothing;\n // don't synthesize an empty package or wire it into the project metadata.\n // Only warn when emptiness is due to skips - genuine failures already errored.\n if (appsEmitted.length === 0) {\n if (recordWarnings && skipped > 0 && skipped === pkg.apps.length) {\n result.warnings.push(`${pkgDir}: all ${skipped} tool(s) skipped, package omitted`);\n }\n continue;\n }\n\n if (mode !== \"scripts\" && backend.emitPackage) {\n try {\n const pkgEmit = backend.emitPackage(pkg.meta, appsEmitted);\n appendEmitMessages(result, pkgEmit, backend, pkg.meta.name);\n packagesEmitted.push(pkgEmit);\n for (const [name, content] of pkgEmit.files) {\n result.files.push({ path: path.join(backendRoot, pkgDir, name), content });\n }\n } catch (e) {\n result.errors.push(`[${backend.name} ${pkgDir}] package emit failed: ${errMsg(e)}`);\n }\n }\n }\n\n if (mode === \"multi\" && backend.emitProject && packagesEmitted.length > 0) {\n try {\n const projEmit = backend.emitProject(catalog.meta, packagesEmitted);\n appendEmitMessages(result, projEmit, backend, catalog.meta.name);\n for (const [name, content] of projEmit.files) {\n result.files.push({ path: path.join(backendRoot, name), content });\n }\n } catch (e) {\n result.errors.push(`[${backend.name}] project emit failed: ${errMsg(e)}`);\n }\n }\n}\n\nfunction appendEmitMessages(\n result: BuildResult,\n emit: EmitResult,\n backend: Backend,\n scope?: string,\n): void {\n const tag = scope ? `[${backend.name} ${scope}]` : `[${backend.name}]`;\n for (const e of emit.errors) result.errors.push(`${tag} ${e.message}`);\n for (const w of emit.warnings) result.warnings.push(`${tag} ${w.message}`);\n}\n","import {\n BoutiquesBackend,\n JsonSchemaBackend,\n PythonBackend,\n TypeScriptBackend,\n type Backend,\n} from \"@styx-api/core\";\n\n/**\n * Registry of backends keyed by CLI alias. The alias is what users pass to\n * `-b`; the backend's `name`/`target` is what we use for the output subdir.\n */\nconst registry: Record<string, () => Backend> = {\n python: () => new PythonBackend(),\n typescript: () => new TypeScriptBackend(),\n ts: () => new TypeScriptBackend(),\n schema: () => new JsonSchemaBackend(),\n \"json-schema\": () => new JsonSchemaBackend(),\n boutiques: () => new BoutiquesBackend(),\n};\n\nexport const knownBackends = Object.keys(registry);\n\nexport function resolveBackends(names: string[]): { backends: Backend[]; unknown: string[] } {\n const backends: Backend[] = [];\n const seen = new Set<string>();\n const unknown: string[] = [];\n for (const name of names) {\n const factory = registry[name];\n if (!factory) {\n unknown.push(name);\n continue;\n }\n const backend = factory();\n if (seen.has(backend.name)) continue;\n seen.add(backend.name);\n backends.push(backend);\n }\n return { backends, unknown };\n}\n","import { mkdirSync, writeFileSync } from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport type { BuiltFile } from \"./build.js\";\n\nexport function writeFiles(files: BuiltFile[]): void {\n for (const file of files) {\n mkdirSync(path.dirname(file.path), { recursive: true });\n writeFileSync(file.path, file.content, \"utf8\");\n }\n}\n"],"mappings":"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"}
@@ -214,7 +214,8 @@ function loadCatalog(root) {
214
214
  const SUPPORTED_FORMATS = new Set([
215
215
  "boutiques",
216
216
  "argdump",
217
- "workbench"
217
+ "workbench",
218
+ "mrtrix"
218
219
  ]);
219
220
  /** Render an unknown thrown value as a message string. */
220
221
  function errMsg(e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@styx-api/cli",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Command-line interface for the Styx compiler (@styx-api/core): build typed wrappers from CLI tool descriptors and catalogs.",
5
5
  "keywords": [
6
6
  "styx",
@@ -37,7 +37,8 @@
37
37
  "files": [
38
38
  "dist",
39
39
  "src",
40
- "!src/**/*.test.ts"
40
+ "!src/**/*.test.ts",
41
+ "!src/**/__snapshots__/**"
41
42
  ],
42
43
  "publishConfig": {
43
44
  "access": "public"
@@ -48,7 +49,7 @@
48
49
  "prepublishOnly": "tsdown"
49
50
  },
50
51
  "dependencies": {
51
- "@styx-api/core": "0.2.0",
52
+ "@styx-api/core": "0.4.0",
52
53
  "cac": "^6.7.14"
53
54
  },
54
55
  "devDependencies": {
package/src/build.ts CHANGED
@@ -25,6 +25,7 @@ const SUPPORTED_FORMATS: ReadonlySet<string> = new Set<FormatName>([
25
25
  "boutiques",
26
26
  "argdump",
27
27
  "workbench",
28
+ "mrtrix",
28
29
  ]);
29
30
 
30
31
  export interface BuildOptions {
@@ -1 +0,0 @@
1
- {"version":3,"file":"write-DSW1zlom.mjs","names":[],"sources":["../src/catalog.ts","../src/build.ts","../src/backends.ts","../src/write.ts"],"sourcesContent":["import { readFileSync, readdirSync, statSync } from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport type { Documentation, PackageMeta, ProjectMeta } from \"@styx-api/core\";\n\n/**\n * Loaded catalog: a project containing packages, each holding one or more\n * apps. We always normalize to project > package > app even when the catalog\n * root only describes a subset of the hierarchy (e.g. a single version dir).\n */\nexport interface CatalogProject {\n meta: ProjectMeta;\n packages: CatalogPackage[];\n /** Non-fatal issues found while walking the catalog (e.g. skipped stub apps). */\n warnings: string[];\n}\n\nexport interface CatalogPackage {\n meta: PackageMeta;\n apps: CatalogApp[];\n}\n\nexport interface CatalogApp {\n /** Stable identifier from `app.json#name`, used for the emitted module slug. */\n name: string;\n /** Absolute path to the descriptor file referenced by `app.json#source`. */\n sourcePath: string;\n sourceFormat?: string;\n}\n\ninterface ProjectJson {\n name?: string;\n version?: string;\n license?: string;\n packages?: string[];\n docs?: Documentation;\n}\n\ninterface PackageJson {\n name?: string;\n versions?: string[];\n default?: string;\n docs?: Documentation;\n}\n\ninterface VersionJson {\n name?: string;\n container?: string;\n apps?: string[];\n executables?: { required?: string[]; ignored?: string[] };\n}\n\ninterface AppJson {\n name?: string;\n source?: { type?: string; path?: string };\n docs?: Documentation;\n}\n\nfunction readJson<T>(file: string): T {\n let raw: string;\n try {\n raw = readFileSync(file, \"utf8\");\n } catch (e) {\n throw new Error(`${file}: ${e instanceof Error ? e.message : String(e)}`);\n }\n try {\n return JSON.parse(raw) as T;\n } catch (e) {\n throw new Error(`${file}: invalid JSON: ${e instanceof Error ? e.message : String(e)}`);\n }\n}\n\nfunction exists(p: string): boolean {\n try {\n statSync(p);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * Detect what level of the niwrap catalog a directory describes.\n * Project dirs contain `project.json`, package dirs contain `package.json`,\n * version dirs contain `version.json`, app dirs contain `app.json`.\n */\nexport type CatalogLevel = \"project\" | \"package\" | \"version\" | \"app\";\n\nexport function detectLevel(dir: string): CatalogLevel | null {\n if (exists(path.join(dir, \"project.json\"))) return \"project\";\n if (exists(path.join(dir, \"package.json\"))) return \"package\";\n if (exists(path.join(dir, \"version.json\"))) return \"version\";\n if (exists(path.join(dir, \"app.json\"))) return \"app\";\n return null;\n}\n\n/**\n * Load one app descriptor. When `warnings` is supplied (catalog-walk mode), a\n * stub app (`app.json` present but no `source.path`) is skipped with a warning\n * instead of aborting the whole build - real catalogs list not-yet-wrapped tools\n * alongside wrapped ones. Without `warnings` (a direct single-app target) the\n * missing source is a hard error, since the user pointed straight at it.\n */\nfunction loadApp(appDir: string, warnings?: string[]): CatalogApp | null {\n const appJsonPath = path.join(appDir, \"app.json\");\n if (!exists(appJsonPath)) return null;\n const app = readJson<AppJson>(appJsonPath);\n const name = app.name ?? path.basename(appDir);\n const sourceRel = app.source?.path;\n if (!sourceRel) {\n if (warnings) {\n warnings.push(`${appJsonPath}: skipped (no source.path - not yet wrapped)`);\n return null;\n }\n throw new Error(`${appJsonPath}: missing source.path`);\n }\n return {\n name,\n sourcePath: path.resolve(appDir, sourceRel),\n sourceFormat: app.source?.type,\n };\n}\n\nfunction loadVersion(versionDir: string, warnings?: string[]): CatalogPackage | null {\n const versionPath = path.join(versionDir, \"version.json\");\n if (!exists(versionPath)) return null;\n const version = readJson<VersionJson>(versionPath);\n\n // Sort the directory fallback so app order (and thus any shared-scope name\n // dodging) is deterministic regardless of filesystem iteration order.\n const appNames = version.apps ?? listSubdirs(versionDir).sort();\n const apps: CatalogApp[] = [];\n for (const appName of appNames) {\n const appDir = path.join(versionDir, appName);\n if (!isDir(appDir)) continue;\n const app = loadApp(appDir, warnings);\n if (app) apps.push(app);\n }\n\n // Try to enrich with the parent package.json if there is one (package > version layout).\n const parentPkg = path.join(versionDir, \"..\", \"package.json\");\n let pkgName: string | undefined;\n let pkgDoc: Documentation | undefined;\n if (exists(parentPkg)) {\n const pkg = readJson<PackageJson>(parentPkg);\n pkgName = pkg.name;\n pkgDoc = pkg.docs;\n }\n pkgName ??= path.basename(path.dirname(versionDir));\n\n return {\n meta: {\n name: pkgName,\n version: version.name,\n docker: version.container,\n doc: pkgDoc,\n },\n apps,\n };\n}\n\nfunction loadPackage(pkgDir: string, warnings?: string[]): CatalogPackage | null {\n const pkgPath = path.join(pkgDir, \"package.json\");\n if (!exists(pkgPath)) return null;\n const pkg = readJson<PackageJson>(pkgPath);\n\n const versionName = pkg.default ?? pkg.versions?.[0] ?? firstVersionDir(pkgDir);\n if (!versionName) return null;\n const versionDir = path.join(pkgDir, versionName);\n if (!isDir(versionDir)) return null;\n\n const loaded = loadVersion(versionDir, warnings);\n if (!loaded) return null;\n\n return {\n meta: {\n name: pkg.name ?? path.basename(pkgDir),\n version: versionName,\n docker: loaded.meta.docker,\n doc: pkg.docs ?? loaded.meta.doc,\n },\n apps: loaded.apps,\n };\n}\n\nfunction listSubdirs(dir: string): string[] {\n return readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name);\n}\n\nfunction firstVersionDir(pkgDir: string): string | null {\n for (const name of listSubdirs(pkgDir)) {\n if (exists(path.join(pkgDir, name, \"version.json\"))) return name;\n }\n return null;\n}\n\n/**\n * Load a catalog from any niwrap layout level. The level is auto-detected from\n * which `*.json` index file is present in `root`. Always returns a normalized\n * `project > package > app` shape, synthesizing missing layers as needed.\n */\nexport function loadCatalog(root: string): CatalogProject {\n const level = detectLevel(root);\n if (!level) {\n throw new Error(\n `${root}: no project.json / package.json / version.json / app.json found - not a catalog root`,\n );\n }\n\n const warnings: string[] = [];\n\n if (level === \"project\") {\n const project = readJson<ProjectJson>(path.join(root, \"project.json\"));\n const packageNames = project.packages ?? listSubdirs(root);\n const packages: CatalogPackage[] = [];\n for (const name of packageNames) {\n const pkgDir = path.join(root, name);\n const pkg = loadPackage(pkgDir, warnings);\n if (pkg) packages.push(pkg);\n }\n return {\n meta: {\n name: project.name,\n version: project.version,\n doc: project.docs,\n license: project.license ? { description: project.license } : undefined,\n },\n packages,\n warnings,\n };\n }\n\n if (level === \"package\") {\n const pkg = loadPackage(root, warnings);\n if (!pkg) throw new Error(`${root}: package.json present but no resolvable version`);\n return { meta: { name: pkg.meta.name }, packages: [pkg], warnings };\n }\n\n if (level === \"version\") {\n const pkg = loadVersion(root, warnings);\n if (!pkg) throw new Error(`${root}: version.json present but failed to load`);\n return { meta: { name: pkg.meta.name }, packages: [pkg], warnings };\n }\n\n // level === \"app\": a direct single-app target, so a missing source is fatal.\n const app = loadApp(root);\n if (!app) throw new Error(`${root}: app.json present but missing source.path`);\n return {\n meta: {},\n packages: [\n {\n meta: { name: path.basename(path.dirname(root)) },\n apps: [app],\n },\n ],\n warnings,\n };\n}\n","import { readFileSync } from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport {\n compile,\n createContext,\n defaultPipeline,\n resolveOutputs,\n solve,\n type Backend,\n type EmitResult,\n type EmittedApp,\n type EmittedPackage,\n type FormatName,\n type PackageMeta,\n type ProjectMeta,\n} from \"@styx-api/core\";\n\nimport { loadCatalog, type CatalogProject } from \"./catalog.js\";\n\nexport type BuildMode = \"scripts\" | \"single\" | \"multi\";\n\n/** Frontend formats the compiler can parse; others are skipped with a warning. */\nconst SUPPORTED_FORMATS: ReadonlySet<string> = new Set<FormatName>([\n \"boutiques\",\n \"argdump\",\n \"workbench\",\n]);\n\nexport interface BuildOptions {\n /** Single-descriptor input file (mutually exclusive with `catalog`). */\n input?: string;\n /** Catalog directory (mutually exclusive with `input`). */\n catalog?: string;\n /** Output directory; per-backend files end up under `<out>/<backend.target>/...`. */\n out: string;\n /** Backends to run (instances pre-resolved by the caller). */\n backends: Backend[];\n /** Which emit tiers to run. */\n mode: BuildMode;\n}\n\n/** A single file from a backend run, keyed by destination path. */\nexport interface BuiltFile {\n /** Absolute destination path. */\n path: string;\n content: string;\n}\n\n/** Per-tool tallies for a catalog build (undefined for single-descriptor builds). */\nexport interface BuildStats {\n appsCompiled: number;\n appsFailed: number;\n appsSkipped: number;\n}\n\nexport interface BuildResult {\n files: BuiltFile[];\n errors: string[];\n warnings: string[];\n /** Catalog-build tallies; set only by `--catalog` builds. */\n stats?: BuildStats;\n}\n\n/** Render an unknown thrown value as a message string. */\nfunction errMsg(e: unknown): string {\n return e instanceof Error ? e.message : String(e);\n}\n\n/**\n * Run the build. Returns the assembled file map and diagnostics; the caller\n * is responsible for actually writing to disk (so tests can introspect the\n * map directly).\n */\nexport function build(options: BuildOptions): BuildResult {\n if (options.input && options.catalog) {\n return { files: [], errors: [\"--input and --catalog are mutually exclusive\"], warnings: [] };\n }\n if (!options.input && !options.catalog) {\n return {\n files: [],\n errors: [\"missing input: pass a descriptor path or --catalog\"],\n warnings: [],\n };\n }\n\n if (options.input) return buildSingle(options.input, options);\n return buildCatalog(options.catalog!, options);\n}\n\nfunction buildSingle(inputPath: string, options: BuildOptions): BuildResult {\n const result: BuildResult = { files: [], errors: [], warnings: [] };\n\n const ctx = readAndCompile(inputPath, undefined, undefined, undefined, result);\n if (!ctx) return result;\n\n for (const backend of options.backends) {\n let emitted;\n try {\n emitted = backend.emitApp(ctx);\n } catch (e) {\n result.errors.push(`[${backend.name}] ${errMsg(e)}`);\n continue;\n }\n appendEmitMessages(result, emitted, backend);\n for (const [name, content] of emitted.files) {\n result.files.push({\n path: path.resolve(options.out, backend.target, name),\n content,\n });\n }\n }\n return result;\n}\n\nfunction buildCatalog(catalogPath: string, options: BuildOptions): BuildResult {\n const result: BuildResult = {\n files: [],\n errors: [],\n warnings: [],\n stats: { appsCompiled: 0, appsFailed: 0, appsSkipped: 0 },\n };\n let catalog: CatalogProject;\n try {\n catalog = loadCatalog(catalogPath);\n } catch (e) {\n result.errors.push(e instanceof Error ? e.message : String(e));\n return result;\n }\n result.warnings.push(...catalog.warnings);\n\n // Skip/empty warnings are backend-independent, so only the first backend pass\n // records them - otherwise they'd be duplicated once per backend.\n options.backends.forEach((backend, i) => {\n runBackendOverCatalog(backend, catalog, options.mode, options.out, result, i === 0);\n });\n return result;\n}\n\n/**\n * Parse a descriptor, run the default optimization pipeline, solve to\n * bindings, and build a `CodegenContext` wired up with the supplied\n * package/project meta. Returns null on read failure (with the error already\n * appended to `result`). Parse-level errors/warnings are also appended.\n */\nfunction readAndCompile(\n sourcePath: string,\n format: string | undefined,\n pkg: PackageMeta | undefined,\n proj: ProjectMeta | undefined,\n result: BuildResult,\n): ReturnType<typeof createContext> | null {\n let source: string;\n try {\n source = readFileSync(sourcePath, \"utf8\");\n } catch (e) {\n result.errors.push(`${sourcePath}: ${errMsg(e)}`);\n return null;\n }\n\n // Isolate the compile pipeline: a single descriptor that makes the solver or\n // a downstream pass throw is recorded as an error and skipped, so one bad tool\n // can't crash a whole-catalog build.\n try {\n // Honor the catalog's declared format when it's one we support, so we don't\n // fall back to content sniffing (and get a clearer error if it mis-parses).\n const parsed = compile(\n source,\n format && SUPPORTED_FORMATS.has(format)\n ? { filename: sourcePath, format: format as FormatName }\n : sourcePath,\n );\n for (const e of parsed.errors) result.errors.push(`${sourcePath}: ${e.message}`);\n for (const w of parsed.warnings) result.warnings.push(`${sourcePath}: ${w.message}`);\n\n const piped = defaultPipeline.apply(parsed.expr);\n if (piped.warnings) {\n for (const w of piped.warnings) result.warnings.push(`${sourcePath}: ${w}`);\n }\n\n const solveResult = solve(piped.expr);\n const outputs = resolveOutputs(piped.expr, solveResult);\n return createContext(piped.expr, solveResult, outputs, {\n app: parsed.meta,\n package: pkg,\n project: proj,\n });\n } catch (e) {\n result.errors.push(`${sourcePath}: ${errMsg(e)}`);\n return null;\n }\n}\n\nfunction runBackendOverCatalog(\n backend: Backend,\n catalog: CatalogProject,\n mode: BuildMode,\n outRoot: string,\n result: BuildResult,\n recordWarnings: boolean,\n): void {\n const backendRoot = path.resolve(outRoot, backend.target);\n const packagesEmitted: EmittedPackage[] = [];\n\n for (const pkg of catalog.packages) {\n const pkgDir = pkg.meta.name ?? \"package\";\n const appsEmitted: EmittedApp[] = [];\n let skipped = 0;\n // One scope shared across every tool in the suite so top-level names stay\n // unique across the package's flat barrel re-exports.\n const pkgScope = backend.newPackageScope?.();\n\n for (const app of pkg.apps) {\n // A tool can declare a format we have no frontend for yet (e.g. Workbench).\n // Skip it with a warning rather than failing the whole catalog build.\n if (app.sourceFormat && !SUPPORTED_FORMATS.has(app.sourceFormat)) {\n skipped++;\n if (recordWarnings) {\n if (result.stats) result.stats.appsSkipped++;\n result.warnings.push(\n `${app.sourcePath}: skipped (unsupported source format \"${app.sourceFormat}\")`,\n );\n }\n continue;\n }\n\n const ctx = readAndCompile(app.sourcePath, app.sourceFormat, pkg.meta, catalog.meta, result);\n if (!ctx) {\n if (recordWarnings && result.stats) result.stats.appsFailed++;\n continue;\n }\n\n // Isolate emit so one tool that makes a backend throw doesn't crash the run.\n let emitted: EmittedApp;\n try {\n emitted = backend.emitApp(ctx, pkgScope);\n } catch (e) {\n result.errors.push(`[${backend.name} ${pkg.meta.name}/${app.name}] ${errMsg(e)}`);\n if (recordWarnings && result.stats) result.stats.appsFailed++;\n continue;\n }\n appendEmitMessages(result, emitted, backend, `${pkg.meta.name}/${app.name}`);\n appsEmitted.push(emitted);\n if (recordWarnings && result.stats) result.stats.appsCompiled++;\n\n for (const [name, content] of emitted.files) {\n result.files.push({ path: path.join(backendRoot, pkgDir, name), content });\n }\n }\n\n // A suite whose every tool was skipped (e.g. all-Workbench) emits nothing;\n // don't synthesize an empty package or wire it into the project metadata.\n // Only warn when emptiness is due to skips - genuine failures already errored.\n if (appsEmitted.length === 0) {\n if (recordWarnings && skipped > 0 && skipped === pkg.apps.length) {\n result.warnings.push(`${pkgDir}: all ${skipped} tool(s) skipped, package omitted`);\n }\n continue;\n }\n\n if (mode !== \"scripts\" && backend.emitPackage) {\n try {\n const pkgEmit = backend.emitPackage(pkg.meta, appsEmitted);\n appendEmitMessages(result, pkgEmit, backend, pkg.meta.name);\n packagesEmitted.push(pkgEmit);\n for (const [name, content] of pkgEmit.files) {\n result.files.push({ path: path.join(backendRoot, pkgDir, name), content });\n }\n } catch (e) {\n result.errors.push(`[${backend.name} ${pkgDir}] package emit failed: ${errMsg(e)}`);\n }\n }\n }\n\n if (mode === \"multi\" && backend.emitProject && packagesEmitted.length > 0) {\n try {\n const projEmit = backend.emitProject(catalog.meta, packagesEmitted);\n appendEmitMessages(result, projEmit, backend, catalog.meta.name);\n for (const [name, content] of projEmit.files) {\n result.files.push({ path: path.join(backendRoot, name), content });\n }\n } catch (e) {\n result.errors.push(`[${backend.name}] project emit failed: ${errMsg(e)}`);\n }\n }\n}\n\nfunction appendEmitMessages(\n result: BuildResult,\n emit: EmitResult,\n backend: Backend,\n scope?: string,\n): void {\n const tag = scope ? `[${backend.name} ${scope}]` : `[${backend.name}]`;\n for (const e of emit.errors) result.errors.push(`${tag} ${e.message}`);\n for (const w of emit.warnings) result.warnings.push(`${tag} ${w.message}`);\n}\n","import {\n BoutiquesBackend,\n JsonSchemaBackend,\n PythonBackend,\n TypeScriptBackend,\n type Backend,\n} from \"@styx-api/core\";\n\n/**\n * Registry of backends keyed by CLI alias. The alias is what users pass to\n * `-b`; the backend's `name`/`target` is what we use for the output subdir.\n */\nconst registry: Record<string, () => Backend> = {\n python: () => new PythonBackend(),\n typescript: () => new TypeScriptBackend(),\n ts: () => new TypeScriptBackend(),\n schema: () => new JsonSchemaBackend(),\n \"json-schema\": () => new JsonSchemaBackend(),\n boutiques: () => new BoutiquesBackend(),\n};\n\nexport const knownBackends = Object.keys(registry);\n\nexport function resolveBackends(names: string[]): { backends: Backend[]; unknown: string[] } {\n const backends: Backend[] = [];\n const seen = new Set<string>();\n const unknown: string[] = [];\n for (const name of names) {\n const factory = registry[name];\n if (!factory) {\n unknown.push(name);\n continue;\n }\n const backend = factory();\n if (seen.has(backend.name)) continue;\n seen.add(backend.name);\n backends.push(backend);\n }\n return { backends, unknown };\n}\n","import { mkdirSync, writeFileSync } from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport type { BuiltFile } from \"./build.js\";\n\nexport function writeFiles(files: BuiltFile[]): void {\n for (const file of files) {\n mkdirSync(path.dirname(file.path), { recursive: true });\n writeFileSync(file.path, file.content, \"utf8\");\n }\n}\n"],"mappings":"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"}
@@ -1,131 +0,0 @@
1
- # This file was auto generated by Styx.
2
- # Do not edit this file directly.
3
-
4
- import dataclasses
5
- import pathlib
6
- import typing
7
-
8
- from styxdefs import Execution, InputPathType, Metadata, Runner, StyxValidationError, OutputPathType, get_global_runner
9
-
10
- GREET_METADATA = Metadata(
11
- id="greet",
12
- name="greet",
13
- package="unknown",
14
- )
15
-
16
- class Greet(typing.TypedDict):
17
- name: str
18
- """Person to greet."""
19
- loud: typing.NotRequired[bool]
20
- """Shout the greeting."""
21
-
22
- @dataclasses.dataclass
23
- class GreetOutputs:
24
- """Output paths produced by the tool."""
25
- root: OutputPathType
26
-
27
- def greet_params(
28
- name: str,
29
- loud: bool = False,
30
- ) -> Greet:
31
- """
32
- Build parameters.
33
-
34
- Args:
35
- name: Person to greet.
36
- loud: Shout the greeting.
37
-
38
- Returns:
39
- Parameter dictionary.
40
- """
41
- params: Greet = {
42
- "name": name,
43
- "loud": loud,
44
- }
45
- return params
46
-
47
- def greet_validate(params: typing.Any) -> None:
48
- """Validate untrusted parameters. Raises StyxValidationError if `params` is not a valid Greet."""
49
- if params is None or not isinstance(params, dict):
50
- raise StyxValidationError(f'Params object has the wrong type \'{type(params)}\'')
51
- if params.get("name", None) is None:
52
- raise StyxValidationError("`name` must not be None")
53
- if not isinstance(params["name"], str):
54
- raise StyxValidationError(f'`name` has the wrong type: Received `{type(params["name"])}` expected `str`')
55
- if params.get("loud", None) is not None:
56
- if not isinstance(params["loud"], bool):
57
- raise StyxValidationError(f'`loud` has the wrong type: Received `{type(params["loud"])}` expected `bool`')
58
-
59
- def greet_cargs(params: Greet, execution: Execution) -> list[str]:
60
- """Build command-line arguments from parameters."""
61
- cargs: list[str] = []
62
- cargs.append("greet")
63
- cargs.append(params["name"])
64
- if params.get("loud"):
65
- cargs.append("--loud")
66
- return cargs
67
-
68
- def greet_outputs(params: Greet, execution: Execution) -> GreetOutputs:
69
- """Build the GreetOutputs object for this tool."""
70
- root_v: OutputPathType = execution.output_file(".")
71
- return GreetOutputs(
72
- root=root_v,
73
- )
74
-
75
- def greet_execute(params: Greet, runner: Runner | None = None) -> GreetOutputs:
76
- """
77
- greet
78
-
79
- Print a greeting.
80
-
81
- Args:
82
- params: The parameters.
83
- runner: Command runner (defaults to global runner).
84
-
85
- Returns:
86
- Tool outputs (paths to files produced by the tool).
87
- """
88
- greet_validate(params)
89
- runner = runner if runner is not None else get_global_runner()
90
- execution = runner.start_execution(GREET_METADATA)
91
- execution.params(params)
92
- args = greet_cargs(params, execution)
93
- out = greet_outputs(params, execution)
94
- execution.run(args)
95
- return out
96
-
97
- def greet(
98
- name: str,
99
- loud: bool = False,
100
- runner: Runner | None = None,
101
- ) -> GreetOutputs:
102
- """
103
- greet
104
-
105
- Print a greeting.
106
-
107
- Args:
108
- name: Person to greet.
109
- loud: Shout the greeting.
110
- runner: Command runner (defaults to global runner).
111
-
112
- Returns:
113
- Tool outputs (paths to files produced by the tool).
114
- """
115
- params = greet_params(
116
- name=name,
117
- loud=loud,
118
- )
119
- return greet_execute(params, runner)
120
-
121
- __all__ = [
122
- "Greet",
123
- "GreetOutputs",
124
- "GREET_METADATA",
125
- "greet_cargs",
126
- "greet_outputs",
127
- "greet_params",
128
- "greet_execute",
129
- "greet_validate",
130
- "greet",
131
- ]
@@ -1,123 +0,0 @@
1
- // This file was auto generated by Styx.
2
- // Do not edit this file directly.
3
-
4
- import type { Runner, Execution, Metadata, InputPathType, OutputPathType } from "styxdefs";
5
- import { getGlobalRunner, StyxValidationError } from "styxdefs";
6
-
7
- export const GREET_METADATA: Metadata = {
8
- id: "greet",
9
- name: "greet",
10
- package: "unknown",
11
- };
12
-
13
- export interface Greet {
14
- "@type"?: "unknown/greet";
15
- /** Person to greet. */
16
- name: string;
17
- /** Shout the greeting. */
18
- loud?: boolean;
19
- }
20
-
21
- export interface GreetOutputs {
22
- root: OutputPathType;
23
- }
24
-
25
- /**
26
- * Build parameters.
27
- *
28
- * @param name Person to greet.
29
- * @param loud Shout the greeting.
30
- *
31
- * @returns Parameter object.
32
- */
33
- export function greetParams(
34
- name: string,
35
- loud: boolean = false,
36
- ): Greet {
37
- const params: Greet = {
38
- "@type": "unknown/greet",
39
- name: name,
40
- loud: loud,
41
- };
42
- return params;
43
- }
44
-
45
- /** Validate untrusted parameters. Throws StyxValidationError if `params` is not a valid Greet; narrows it to Greet on success. */
46
- export function greetValidate(params: any): asserts params is Greet {
47
- if (typeof params !== "object" || params === null) {
48
- throw new StyxValidationError("Params object has the wrong type");
49
- }
50
- if (params.name == null) {
51
- throw new StyxValidationError("`name` must not be null");
52
- }
53
- if (typeof params.name !== "string") {
54
- throw new StyxValidationError("`name` has the wrong type (expected string)");
55
- }
56
- if (params.loud != null) {
57
- if (typeof params.loud !== "boolean") {
58
- throw new StyxValidationError("`loud` has the wrong type (expected boolean)");
59
- }
60
- }
61
- }
62
-
63
- /** Build command-line arguments from parameters. */
64
- export function greet_cargs(params: Greet, execution: Execution): string[] {
65
- const cargs: string[] = [];
66
- cargs.push("greet");
67
- cargs.push(params.name);
68
- if (params.loud) {
69
- cargs.push("--loud");
70
- }
71
- return cargs;
72
- }
73
-
74
- export function greet_outputs(params: Greet, execution: Execution): GreetOutputs {
75
- const outputs: GreetOutputs = {
76
- root: null!,
77
- };
78
- outputs.root = execution.outputFile(".");
79
- return outputs;
80
- }
81
-
82
- /**
83
- * greet
84
- *
85
- * Print a greeting.
86
- *
87
- * @param params - The parameters.
88
- * @param runner - Command runner (defaults to global runner).
89
- * @returns Tool outputs (paths to files produced by the tool).
90
- */
91
- export function greetExecute(params: Greet, runner: Runner | null = null): GreetOutputs {
92
- greetValidate(params);
93
- runner = runner ?? getGlobalRunner();
94
- const execution = runner.startExecution(GREET_METADATA);
95
- execution.params(params);
96
- const args = greet_cargs(params, execution);
97
- const out = greet_outputs(params, execution);
98
- execution.run(args);
99
- return out;
100
- }
101
-
102
- /**
103
- * greet
104
- *
105
- * Print a greeting.
106
- *
107
- * @param name Person to greet.
108
- * @param loud Shout the greeting.
109
- * @param runner Command runner (defaults to global runner).
110
- *
111
- * @returns Tool outputs (paths to files produced by the tool).
112
- */
113
- export function greet(
114
- name: string,
115
- loud: boolean = false,
116
- runner: Runner | null = null,
117
- ): GreetOutputs {
118
- const params = greetParams(
119
- name,
120
- loud,
121
- );
122
- return greetExecute(params, runner);
123
- }