@mcmcjs/julia 0.3.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/driver.jl CHANGED
@@ -17,6 +17,8 @@ using Pkg
17
17
  import JuliaBUGS
18
18
  import AdvancedHMC
19
19
  import ForwardDiff
20
+ import FlexiChains
21
+ import DimensionalData
20
22
 
21
23
  function build_sampler(sampler, backend)
22
24
  algorithm = get(sampler, "algorithm", "NUTS")
@@ -76,12 +78,45 @@ end
76
78
  # Build the model and sample in one call so both run in the latest world age:
77
79
  # the model methods are defined by `include` at runtime, so a plain call from
78
80
  # this (older) world would fail with "method too new". invokelatest fixes that.
81
+ # Returns Turing's default chain type, a FlexiChain.
79
82
  function build_and_sample(entry, data, sampler, draws, chains, rng)
80
83
  model = entry(data)
81
- # Sample into Turing's default chain type (a FlexiChain), then convert to
82
- # MCMCChains for serialization.
83
- chn = sample(rng, model, sampler, MCMCSerial(), draws, chains; progress = false)
84
- return MCMCChains.Chains(chn)
84
+ return sample(rng, model, sampler, MCMCSerial(), draws, chains; progress = false)
85
+ end
86
+
87
+ # FlexiChains-native wire writer. DimArray(chn) splits array-valued parameters
88
+ # into scalar leaves (theta -> theta[1], theta[2]) in the (iter, chain, param)
89
+ # orientation; Real-valued extras become the internals section, matching what
90
+ # the MCMCChains bridge produced.
91
+ function vnchain_to_wire(chn)
92
+ da = DimensionalData.DimArray(chn)
93
+ pnames = string.(collect(DimensionalData.lookup(da, :param)))
94
+ arr = parent(da)
95
+ nIter, nChains, nParams = size(arr)
96
+
97
+ extras = [e for e in FlexiChains.extras(chn) if eltype(chn[e]) <: Union{Missing,Real}]
98
+ enames = [string(Symbol(e)) for e in extras]
99
+ total = nParams + length(extras)
100
+
101
+ flat = Vector{Union{Float64,Nothing}}(undef, nIter * total * nChains)
102
+ cell(v) = v === missing ? nothing : Float64(v)
103
+ for c in 1:nChains, p in 1:nParams, i in 1:nIter
104
+ flat[i + (p - 1) * nIter + (c - 1) * nIter * total] = cell(arr[i, c, p])
105
+ end
106
+ for (k, e) in enumerate(extras)
107
+ m = chn[e]
108
+ p = nParams + k
109
+ for c in 1:nChains, i in 1:nIter
110
+ flat[i + (p - 1) * nIter + (c - 1) * nIter * total] = cell(m[i, c])
111
+ end
112
+ end
113
+
114
+ return Dict(
115
+ "size" => [nIter, total, nChains],
116
+ "value_flat" => flat,
117
+ "parameters" => vcat(pnames, enames),
118
+ "name_map" => Dict("parameters" => pnames, "internals" => enames),
119
+ )
85
120
  end
86
121
 
87
122
  # JuliaBUGS compiles the model at runtime, so building and sampling must run in
@@ -119,7 +154,7 @@ function provenance()
119
154
  packages = Dict{String,String}()
120
155
  for (_, info) in Pkg.dependencies()
121
156
  if info.name in
122
- ("Turing", "MCMCChains", "DynamicPPL", "AbstractMCMC", "JuliaBUGS", "AdvancedHMC", "ForwardDiff", "ADTypes") &&
157
+ ("Turing", "FlexiChains", "MCMCChains", "DynamicPPL", "AbstractMCMC", "JuliaBUGS", "AdvancedHMC", "ForwardDiff", "ADTypes") &&
123
158
  info.version !== nothing
124
159
  packages[info.name] = string(info.version)
125
160
  end
@@ -160,13 +195,14 @@ function main()
160
195
  draws = Int(request["sampler"]["draws"])
161
196
  chains = Int(get(request["sampler"], "chains", 4))
162
197
  stage = "sample"
163
- chn = if backend == "juliabugs"
198
+ if backend == "juliabugs"
164
199
  model = Base.invokelatest(entry, data)
165
- Base.invokelatest(sample_bugs, model, sampler, warmup, draws, chains, rng)
200
+ chn = Base.invokelatest(sample_bugs, model, sampler, warmup, draws, chains, rng)
201
+ chains_to_wire(chn)
166
202
  else
167
- Base.invokelatest(build_and_sample, entry, data, sampler, draws, chains, rng)
203
+ chn = Base.invokelatest(build_and_sample, entry, data, sampler, draws, chains, rng)
204
+ vnchain_to_wire(chn)
168
205
  end
169
- chains_to_wire(chn)
170
206
  end
171
207
 
172
208
  stage = "write"
package/dist/index.cjs CHANGED
@@ -311,6 +311,8 @@ var import_node_path5 = require("path");
311
311
  var import_engine3 = require("@mcmcjs/engine");
312
312
  var PACKAGES = [
313
313
  "Turing",
314
+ "FlexiChains",
315
+ "DimensionalData",
314
316
  "MCMCChains",
315
317
  "JuliaBUGS",
316
318
  "AdvancedHMC",
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.15_typescript@6.0.3/node_modules/tsup/assets/cjs_shims.js","../src/environment.ts","../src/doctor.ts","../src/engine.ts","../src/fit.ts","../src/runner-common.ts","../src/predict.ts","../src/project.ts","../src/run-matrix.ts","../src/setup.ts","../src/versions.ts"],"sourcesContent":["export type { DoctorReport } from \"./doctor\";\nexport { runDoctor } from \"./doctor\";\nexport { juliaEngine } from \"./engine\";\nexport type { CommandRunner, ToolInfo } from \"./environment\";\nexport { detectJulia, detectJuliaup } from \"./environment\";\nexport type { FitIo } from \"./fit\";\nexport { runFit } from \"./fit\";\nexport type { PredictIo } from \"./predict\";\nexport { predictData, runPredict } from \"./predict\";\nexport { ensureProject, managedProjectDir, managedProjectReady } from \"./project\";\nexport type { MatrixEntry, MatrixIo, MatrixResult } from \"./run-matrix\";\nexport { runMatrix } from \"./run-matrix\";\nexport type {\n InstallCommand,\n SetupOptions,\n SetupResult,\n SetupStep,\n SetupStepResult,\n StepStatus,\n} from \"./setup\";\nexport { juliaupInstallCommand, planSetup, runSetup } from \"./setup\";\nexport {\n addVersion,\n assertVersionsInstalled,\n gcVersions,\n listVersions,\n removeVersion,\n resolveVersion,\n setDefaultVersion,\n updateVersion,\n} from \"./versions\";\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { type CommandRunner, createRunner, type ToolInfo } from \"@mcmcjs/engine\";\n\nexport type { CommandRunner, ToolInfo } from \"@mcmcjs/engine\";\nexport { createRunner } from \"@mcmcjs/engine\";\n\nconst defaultRunner = createRunner();\n\n// juliaup installs its shims here; we also fall back to whatever is on PATH.\nfunction candidates(binary: string): string[] {\n return [join(homedir(), \".juliaup\", \"bin\", binary), binary];\n}\n\nasync function detect(\n binary: string,\n parseVersion: (stdout: string) => string | undefined,\n runner: CommandRunner,\n): Promise<ToolInfo> {\n for (const path of candidates(binary)) {\n try {\n const version = parseVersion(await runner(path, [\"--version\"]));\n if (version) return { found: true, version, path };\n } catch {\n // not available at this path; try the next candidate\n }\n }\n return { found: false };\n}\n\nconst versionNumber = (stdout: string): string | undefined => stdout.match(/(\\d+\\.\\d+\\.\\d+)/)?.[1];\n\n/** Detects the Julia runtime via `julia --version`. */\nexport function detectJulia(runner: CommandRunner = defaultRunner): Promise<ToolInfo> {\n return detect(\"julia\", versionNumber, runner);\n}\n\n/** Detects the juliaup version manager via `juliaup --version`. */\nexport function detectJuliaup(runner: CommandRunner = defaultRunner): Promise<ToolInfo> {\n return detect(\"juliaup\", versionNumber, runner);\n}\n","import { type CommandRunner, detectJulia, detectJuliaup, type ToolInfo } from \"./environment\";\n\n/** A summary of the Julia toolchain available for inference. */\nexport interface DoctorReport {\n juliaup: ToolInfo;\n julia: ToolInfo;\n /** True when Julia itself is available (the minimum needed to run inference). */\n ready: boolean;\n}\n\n/** Detects the installed Julia toolchain and reports whether inference can run. */\nexport async function runDoctor(runner?: CommandRunner): Promise<DoctorReport> {\n const [juliaup, julia] = await Promise.all([detectJuliaup(runner), detectJulia(runner)]);\n return { juliaup, julia, ready: julia.found };\n}\n","import type { Engine, EngineContext, HealthReport } from \"@mcmcjs/engine\";\nimport { runDoctor } from \"./doctor\";\n\nconst JULIAUP_URL = \"https://github.com/JuliaLang/juliaup\";\n\nexport const juliaEngine: Engine = {\n id: \"julia\",\n displayName: \"Julia\",\n capabilities: { setup: true, versions: true, fit: true, predict: true },\n async doctor(ctx: EngineContext): Promise<HealthReport> {\n const report = await runDoctor(ctx.run);\n return {\n engineId: \"julia\",\n ready: report.ready,\n tools: [\n { name: \"juliaup\", ...report.juliaup },\n { name: \"julia\", ...report.julia },\n ],\n hint: report.ready\n ? undefined\n : `Julia not found. Install it with juliaup (${JULIAUP_URL}), or run \\`mcmc setup\\`.`,\n };\n },\n};\n","import { existsSync, mkdtempSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n canonicalJson,\n parseSamples,\n type ResolvedSpec,\n RUN_RECORD_SCHEMA_VERSION,\n type RunRecord,\n} from \"@mcmcjs/core\";\nimport type { FitResult, FitRunner } from \"@mcmcjs/engine\";\nimport { driverPath, lastJsonLine, sha256, toStage } from \"./runner-common\";\n\nexport interface FitIo {\n /** Spawns the Julia process; injectable so runFit is testable without Julia. */\n spawn: FitRunner;\n /** The managed Julia project directory passed as --project. */\n projectDir: string;\n /** Where the samples file is written. */\n outPath: string;\n tmpDir?: string;\n}\n\n/** Runs one inference for a resolved spec on a resolved runtime invocation. */\nexport async function runFit(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: FitIo,\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n const runtimeRequested = spec.backend.version;\n\n const tmp = io.tmpDir ?? mkdtempSync(join(tmpdir(), \"mcmcjs-fit-\"));\n const requestPath = join(tmp, \"request.json\");\n writeFileSync(\n requestPath,\n JSON.stringify({\n schema_version: spec.schema_version,\n backend: { id: spec.backend.id },\n model: { file: spec.modelPath, entry: spec.model.entry },\n data: spec.data,\n sampler: spec.sampler,\n seed: spec.seed,\n out: io.outPath,\n }),\n );\n\n const args = [\n ...resolved.args,\n \"--startup-file=no\",\n `--project=${io.projectDir}`,\n driverPath(),\n requestPath,\n ];\n const { stdout, stderr, code } = await io.spawn(resolved.command, args);\n const elapsedMs = Math.round(performance.now() - start);\n\n if (code !== 0 || !existsSync(io.outPath)) {\n const failure = lastJsonLine(stderr);\n const stage = toStage(failure?.stage);\n const error =\n (failure?.error as string) ??\n stderr.trim().split(\"\\n\").pop() ??\n `julia exited with code ${code}`;\n return { status: \"error\", runtimeRequested, elapsedMs, stage, error };\n }\n\n try {\n parseSamples(readFileSync(io.outPath, \"utf8\"));\n } catch (error) {\n return {\n status: \"error\",\n runtimeRequested,\n elapsedMs,\n stage: \"write\",\n error: `samples file did not parse: ${(error as Error).message}`,\n };\n }\n\n const provenance = lastJsonLine(stdout);\n const julia = provenance?.julia_version as string | undefined;\n const record: RunRecord = {\n schema_version: RUN_RECORD_SCHEMA_VERSION,\n spec_hash: spec.specHash,\n seed: spec.seed,\n backend: { id: spec.backend.id, runtime: spec.backend.runtime },\n runtime: { requested: runtimeRequested, actual: julia, path: resolved.command },\n manifest_sha256: provenance?.manifest_sha256 as string | undefined,\n packages: provenance?.packages as Record<string, string> | undefined,\n model_sha256: existsSync(spec.modelPath)\n ? sha256(readFileSync(spec.modelPath, \"utf8\"))\n : undefined,\n data_sha256: sha256(canonicalJson(spec.data)),\n samples_file: io.outPath,\n started_at: startedAt,\n elapsed_ms: elapsedMs,\n };\n writeFileSync(`${io.outPath}.run.json`, `${JSON.stringify(record, null, 2)}\\n`);\n\n return {\n status: \"ok\",\n samplesFile: io.outPath,\n runtimeRequested,\n runtimeActual: julia,\n elapsedMs,\n };\n}\n","import { createHash } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { FitResult } from \"@mcmcjs/engine\";\n\n/** Path to the shipped Julia driver, resolved next to this module in dist/. */\nexport function driverPath(): string {\n return join(dirname(fileURLToPath(import.meta.url)), \"driver.jl\");\n}\n\nexport function sha256(text: string): string {\n return createHash(\"sha256\").update(text).digest(\"hex\");\n}\n\n/** Parses the last JSON-object line of text (the driver's provenance or error line). */\nexport function lastJsonLine(text: string): Record<string, unknown> | undefined {\n for (const line of text.trimEnd().split(\"\\n\").reverse()) {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"{\")) continue;\n try {\n return JSON.parse(trimmed) as Record<string, unknown>;\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\nconst STAGES = new Set<NonNullable<FitResult[\"stage\"]>>([\n \"compile\",\n \"sample\",\n \"load_samples\",\n \"predict\",\n \"write\",\n \"spawn\",\n]);\n\n/** Narrows a driver-reported stage string to the known set. */\nexport function toStage(value: unknown): FitResult[\"stage\"] {\n return typeof value === \"string\" && STAGES.has(value as NonNullable<FitResult[\"stage\"]>)\n ? (value as FitResult[\"stage\"])\n : undefined;\n}\n","import { existsSync, mkdtempSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n canonicalJson,\n parseSamples,\n type ResolvedSpec,\n RUN_RECORD_SCHEMA_VERSION,\n type RunRecord,\n} from \"@mcmcjs/core\";\nimport type { FitResult, FitRunner } from \"@mcmcjs/engine\";\nimport { driverPath, lastJsonLine, sha256, toStage } from \"./runner-common\";\n\nexport interface PredictIo {\n /** Spawns the Julia process; injectable so runPredict is testable without Julia. */\n spawn: FitRunner;\n projectDir: string;\n /** Where the posterior-predictive samples file is written. */\n outPath: string;\n /** The posterior samples file fed to prediction. */\n samplesPath: string;\n tmpDir?: string;\n}\n\n/** The prediction data: [data] with [predict].data overrides, target outcomes blanked to nulls. */\nexport function predictData(spec: ResolvedSpec): Record<string, unknown> {\n const predict = spec.predict;\n if (!predict) throw new Error(\"spec has no [predict] block\");\n const data: Record<string, unknown> = { ...spec.data, ...(predict.data ?? {}) };\n // Blank a target to null, preserving array shape so the driver maps it to a\n // matching shape of `missing` (a multidimensional outcome stays nested).\n const blank = (value: unknown): unknown => (Array.isArray(value) ? value.map(blank) : null);\n for (const target of predict.targets) {\n data[target] = blank(data[target]);\n }\n return data;\n}\n\n/** Draws posterior-predictive samples from a fitted model and its posterior samples file. */\nexport async function runPredict(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: PredictIo,\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n const runtimeRequested = spec.backend.version;\n const data = predictData(spec);\n\n const tmp = io.tmpDir ?? mkdtempSync(join(tmpdir(), \"mcmcjs-predict-\"));\n const requestPath = join(tmp, \"request.json\");\n writeFileSync(\n requestPath,\n JSON.stringify({\n mode: \"predict\",\n schema_version: spec.schema_version,\n backend: { id: spec.backend.id },\n model: { file: spec.modelPath, entry: spec.model.entry },\n data,\n predict: { targets: spec.predict?.targets ?? [] },\n samples: io.samplesPath,\n seed: spec.seed,\n out: io.outPath,\n }),\n );\n\n const args = [\n ...resolved.args,\n \"--startup-file=no\",\n `--project=${io.projectDir}`,\n driverPath(),\n requestPath,\n ];\n const { stdout, stderr, code } = await io.spawn(resolved.command, args);\n const elapsedMs = Math.round(performance.now() - start);\n\n if (code !== 0 || !existsSync(io.outPath)) {\n const failure = lastJsonLine(stderr);\n const error =\n (failure?.error as string) ??\n stderr.trim().split(\"\\n\").pop() ??\n `julia exited with code ${code}`;\n return { status: \"error\", runtimeRequested, elapsedMs, stage: toStage(failure?.stage), error };\n }\n\n try {\n parseSamples(readFileSync(io.outPath, \"utf8\"));\n } catch (error) {\n return {\n status: \"error\",\n runtimeRequested,\n elapsedMs,\n stage: \"write\",\n error: `samples file did not parse: ${(error as Error).message}`,\n };\n }\n\n const provenance = lastJsonLine(stdout);\n const julia = provenance?.julia_version as string | undefined;\n const record: RunRecord = {\n schema_version: RUN_RECORD_SCHEMA_VERSION,\n spec_hash: spec.specHash,\n seed: spec.seed,\n backend: { id: spec.backend.id, runtime: spec.backend.runtime },\n runtime: { requested: runtimeRequested, actual: julia, path: resolved.command },\n manifest_sha256: provenance?.manifest_sha256 as string | undefined,\n packages: provenance?.packages as Record<string, string> | undefined,\n model_sha256: existsSync(spec.modelPath)\n ? sha256(readFileSync(spec.modelPath, \"utf8\"))\n : undefined,\n data_sha256: sha256(canonicalJson(data)),\n posterior_samples: io.samplesPath,\n posterior_samples_sha256: existsSync(io.samplesPath)\n ? sha256(readFileSync(io.samplesPath, \"utf8\"))\n : undefined,\n samples_file: io.outPath,\n started_at: startedAt,\n elapsed_ms: elapsedMs,\n };\n writeFileSync(`${io.outPath}.run.json`, `${JSON.stringify(record, null, 2)}\\n`);\n\n return {\n status: \"ok\",\n samplesFile: io.outPath,\n runtimeRequested,\n runtimeActual: julia,\n elapsedMs,\n };\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { type CommandRunner, createRunner } from \"@mcmcjs/engine\";\n\nconst PACKAGES = [\n \"Turing\",\n \"MCMCChains\",\n \"JuliaBUGS\",\n \"AdvancedHMC\",\n \"ForwardDiff\",\n \"JSON\",\n \"StableRNGs\",\n];\n\n/** The per-user directory holding the managed Julia project (Project + Manifest). */\nexport function managedProjectDir(): string {\n const base = process.env.XDG_DATA_HOME || join(homedir(), \".local\", \"share\");\n return join(base, \"mcmcjs\", \"julia\", \"env\");\n}\n\n// Records the package set a managed dir was provisioned with, so an env from an\n// older package set is healed (Pkg.add is additive) rather than left incomplete.\nfunction sentinelPath(dir: string): string {\n return join(dir, \".mcmcjs-packages.json\");\n}\n\nfunction provisioned(dir: string): boolean {\n try {\n return readFileSync(sentinelPath(dir), \"utf8\").trim() === JSON.stringify([...PACKAGES].sort());\n } catch {\n return false;\n }\n}\n\n/** Whether the managed project is present and provisioned with the current package set. */\nexport function managedProjectReady(dir: string = managedProjectDir()): boolean {\n return existsSync(join(dir, \"Project.toml\")) && provisioned(dir);\n}\n\n/**\n * Ensures the managed Julia project exists with the inference packages installed.\n * Idempotent: returns immediately when already provisioned with the current set,\n * otherwise adds (and precompiles) the missing packages. The first run resolves\n * and precompiles the project, which can take several minutes.\n */\nexport async function ensureProject(\n juliaBin: string,\n run: CommandRunner = createRunner(30 * 60_000),\n dir: string = managedProjectDir(),\n): Promise<string> {\n if (managedProjectReady(dir)) return dir;\n mkdirSync(dir, { recursive: true });\n const code = `using Pkg; Pkg.add(${JSON.stringify(PACKAGES)}); Pkg.precompile()`;\n await run(juliaBin, [\"--startup-file=no\", `--project=${dir}`, \"-e\", code]);\n writeFileSync(sentinelPath(dir), JSON.stringify([...PACKAGES].sort()));\n return dir;\n}\n","import { join } from \"node:path\";\nimport type { ResolvedSpec } from \"@mcmcjs/core\";\nimport type { FitResult, FitRunner } from \"@mcmcjs/engine\";\nimport { runFit } from \"./fit\";\n\nexport interface MatrixEntry {\n version: string;\n status: \"ok\" | \"error\";\n samplesFile?: string;\n runtimeActual?: string;\n elapsedMs: number;\n stage?: FitResult[\"stage\"];\n error?: string;\n}\n\nexport interface MatrixResult {\n entries: MatrixEntry[];\n /** True only when every requested version ran and succeeded. */\n ok: boolean;\n}\n\nexport interface MatrixIo {\n spawn: FitRunner;\n projectDir: string;\n /** Directory the per-version samples files are written into. */\n outDir: string;\n /** Resolves a version/channel to a concrete invocation; injectable for tests. */\n resolve: (version: string) => Promise<{ command: string; args: string[] }>;\n /** Continue after a version fails instead of stopping. */\n keepGoing?: boolean;\n}\n\n/** Runs the same spec across several Julia versions, one samples file per version. */\nexport async function runMatrix(\n spec: ResolvedSpec,\n versions: string[],\n io: MatrixIo,\n): Promise<MatrixResult> {\n const entries: MatrixEntry[] = [];\n for (const version of versions) {\n let entry: MatrixEntry;\n try {\n const resolved = await io.resolve(version);\n const versioned = { ...spec, backend: { ...spec.backend, version } };\n const result = await runFit(versioned, resolved, {\n spawn: io.spawn,\n projectDir: io.projectDir,\n outPath: join(io.outDir, `${version}.samples.json`),\n });\n entry = {\n version,\n status: result.status,\n samplesFile: result.samplesFile,\n runtimeActual: result.runtimeActual,\n elapsedMs: result.elapsedMs,\n stage: result.stage,\n error: result.error,\n };\n } catch (error) {\n entry = { version, status: \"error\", elapsedMs: 0, error: (error as Error).message };\n }\n entries.push(entry);\n if (entry.status === \"error\" && !io.keepGoing) break;\n }\n return {\n entries,\n ok: entries.length === versions.length && entries.every((e) => e.status === \"ok\"),\n };\n}\n","import { type DoctorReport, runDoctor } from \"./doctor\";\nimport { type CommandRunner, createRunner, type ToolInfo } from \"./environment\";\n\n/** The official juliaup install script, piped to a shell by the install step. */\nconst JULIAUP_INSTALL_URL = \"https://install.julialang.org\";\n\n/** An executable and its arguments, run directly (no shell word-splitting). */\nexport interface InstallCommand {\n command: string;\n args: string[];\n}\n\n/**\n * The command that installs juliaup on the given platform, or null when\n * automatic install is not yet supported there.\n */\nexport function juliaupInstallCommand(platform: NodeJS.Platform): InstallCommand | null {\n if (platform === \"win32\") {\n // TODO: install juliaup on Windows via winget or the Microsoft Store.\n return null;\n }\n return { command: \"sh\", args: [\"-c\", `curl -fsSL ${JULIAUP_INSTALL_URL} | sh -s -- --yes`] };\n}\n\n/** A single provisioning step needed to make the toolchain ready. */\nexport interface SetupStep {\n tool: \"juliaup\" | \"julia\";\n /** A short description of what the step does. */\n label: string;\n /** The command to run, or null when the step cannot be performed automatically. */\n command: InstallCommand | null;\n}\n\n/** The ordered steps needed to reach a ready toolchain, given the current state. */\nexport function planSetup(report: DoctorReport, platform: NodeJS.Platform): SetupStep[] {\n if (report.julia.found) return [];\n if (report.juliaup.found) {\n return [\n {\n tool: \"julia\",\n label: \"install the latest stable Julia via juliaup\",\n command: { command: report.juliaup.path ?? \"juliaup\", args: [\"add\", \"release\"] },\n },\n ];\n }\n return [\n {\n tool: \"juliaup\",\n label: \"install juliaup (this also installs Julia)\",\n command: juliaupInstallCommand(platform),\n },\n ];\n}\n\nexport type StepStatus = \"ran\" | \"skipped\" | \"failed\" | \"unsupported\";\n\nexport interface SetupStepResult extends SetupStep {\n status: StepStatus;\n /** Error detail when the step failed. */\n detail?: string;\n}\n\nexport interface SetupResult {\n juliaup: ToolInfo;\n julia: ToolInfo;\n /** True when Julia is available after setup. */\n ready: boolean;\n steps: SetupStepResult[];\n}\n\nexport interface SetupOptions {\n /** Runs detection commands. Injectable for tests. */\n runner?: CommandRunner;\n /** Runs install steps, which may take several minutes. Injectable for tests. */\n installer?: CommandRunner;\n /** Target platform; defaults to the current process platform. */\n platform?: NodeJS.Platform;\n /** Plan the steps but do not run them. */\n dryRun?: boolean;\n}\n\n/** Installs the Julia toolchain (juliaup and Julia) needed for inference. */\nexport async function runSetup(options: SetupOptions = {}): Promise<SetupResult> {\n const {\n runner,\n installer = createRunner(15 * 60_000),\n platform = process.platform,\n dryRun = false,\n } = options;\n\n const before = await runDoctor(runner);\n if (before.ready) return { ...before, steps: [] };\n\n const plan = planSetup(before, platform);\n\n if (dryRun) {\n return {\n ...before,\n steps: plan.map((step) => ({ ...step, status: step.command ? \"skipped\" : \"unsupported\" })),\n };\n }\n\n const steps: SetupStepResult[] = [];\n for (const step of plan) {\n if (!step.command) {\n steps.push({ ...step, status: \"unsupported\" });\n continue;\n }\n try {\n await installer(step.command.command, step.command.args);\n steps.push({ ...step, status: \"ran\" });\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n steps.push({ ...step, status: \"failed\", detail });\n }\n }\n\n const after = await runDoctor(runner);\n return { juliaup: after.juliaup, julia: after.julia, ready: after.ready, steps };\n}\n","import type { CommandRunner, RuntimeVersion } from \"@mcmcjs/engine\";\n\ninterface ChannelInfo {\n Name: string;\n File: string;\n Args?: string[];\n Version?: string;\n Arch?: string;\n}\n\ninterface Getconfig1 {\n DefaultChannel: ChannelInfo | null;\n OtherChannels: ChannelInfo[];\n}\n\nfunction parseChannel(value: unknown): ChannelInfo {\n const c = value as Record<string, unknown>;\n if (!c || typeof c.Name !== \"string\" || typeof c.File !== \"string\") {\n throw new Error(\"unexpected `juliaup api getconfig1` channel shape\");\n }\n return {\n Name: c.Name,\n File: c.File,\n Args: Array.isArray(c.Args) ? (c.Args as string[]) : undefined,\n Version: typeof c.Version === \"string\" ? c.Version : undefined,\n Arch: typeof c.Arch === \"string\" ? c.Arch : undefined,\n };\n}\n\nfunction parseGetconfig1(raw: string): Getconfig1 {\n let data: unknown;\n try {\n data = JSON.parse(raw);\n } catch {\n throw new Error(\"could not parse `juliaup api getconfig1` output as JSON\");\n }\n const obj = data as Record<string, unknown>;\n if (!obj || typeof obj !== \"object\" || !Array.isArray(obj.OtherChannels)) {\n throw new Error(\"unexpected `juliaup api getconfig1` output\");\n }\n return {\n DefaultChannel: obj.DefaultChannel ? parseChannel(obj.DefaultChannel) : null,\n OtherChannels: obj.OtherChannels.map(parseChannel),\n };\n}\n\nfunction toVersion(channel: ChannelInfo, isDefault: boolean): RuntimeVersion {\n return { id: channel.Name, version: channel.Version, path: channel.File || undefined, isDefault };\n}\n\n/** Lists the installed Julia versions, marking the default channel. */\nexport async function listVersions(bin: string, run: CommandRunner): Promise<RuntimeVersion[]> {\n const config = parseGetconfig1(await run(bin, [\"api\", \"getconfig1\"]));\n const versions: RuntimeVersion[] = [];\n if (config.DefaultChannel) versions.push(toVersion(config.DefaultChannel, true));\n for (const channel of config.OtherChannels) versions.push(toVersion(channel, false));\n return versions;\n}\n\nexport async function addVersion(\n bin: string,\n channel: string,\n opts: { default?: boolean },\n run: CommandRunner,\n): Promise<void> {\n await run(bin, [\"add\", channel]);\n if (opts.default) await run(bin, [\"default\", channel]);\n}\n\nexport async function removeVersion(\n bin: string,\n channel: string,\n run: CommandRunner,\n): Promise<void> {\n await run(bin, [\"remove\", channel]);\n}\n\nexport async function setDefaultVersion(\n bin: string,\n channel: string,\n run: CommandRunner,\n): Promise<void> {\n await run(bin, [\"default\", channel]);\n}\n\nexport async function updateVersion(\n bin: string,\n channel: string | undefined,\n run: CommandRunner,\n): Promise<void> {\n await run(bin, channel ? [\"update\", channel] : [\"update\"]);\n}\n\nexport async function gcVersions(bin: string, run: CommandRunner): Promise<void> {\n await run(bin, [\"gc\"]);\n}\n\n/** Resolves a channel to a concrete invocation, preferring its absolute binary path. */\nexport async function resolveVersion(\n bin: string,\n channel: string,\n run: CommandRunner,\n): Promise<{ command: string; args: string[] }> {\n const config = parseGetconfig1(await run(bin, [\"api\", \"getconfig1\"]));\n const all = config.DefaultChannel\n ? [config.DefaultChannel, ...config.OtherChannels]\n : config.OtherChannels;\n const match = all.find((c) => c.Name === channel);\n if (!match?.File) {\n throw new Error(\n `Julia version \"${channel}\" is not installed. Add it with: mcmc julia version add ${channel}`,\n );\n }\n return { command: match.File, args: match.Args ?? [] };\n}\n\n/** Throws with an actionable message if any requested channel is not installed. */\nexport function assertVersionsInstalled(channels: string[], installed: RuntimeVersion[]): void {\n const have = new Set(installed.map((v) => v.id));\n const missing = channels.filter((c) => !have.has(c));\n if (missing.length > 0) {\n const fixes = missing.map((m) => `mcmc julia version add ${m}`).join(\"; \");\n throw new Error(\n `Julia version(s) not installed: ${missing.join(\", \")}. Install with: ${fixes}`,\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACKA,IAAM,mBAAmB,MACvB,OAAO,aAAa,cAChB,IAAI,IAAI,QAAQ,UAAU,EAAE,EAAE,OAC7B,SAAS,iBAAiB,SAAS,cAAc,QAAQ,YAAY,MAAM,WAC1E,SAAS,cAAc,MACvB,IAAI,IAAI,WAAW,SAAS,OAAO,EAAE;AAEtC,IAAM,gBAAgC,iCAAiB;;;ACZ9D,qBAAwB;AACxB,uBAAqB;AACrB,oBAAgE;AAGhE,IAAAA,iBAA6B;AAE7B,IAAM,oBAAgB,4BAAa;AAGnC,SAAS,WAAW,QAA0B;AAC5C,SAAO,KAAC,2BAAK,wBAAQ,GAAG,YAAY,OAAO,MAAM,GAAG,MAAM;AAC5D;AAEA,eAAe,OACb,QACA,cACA,QACmB;AACnB,aAAW,QAAQ,WAAW,MAAM,GAAG;AACrC,QAAI;AACF,YAAM,UAAU,aAAa,MAAM,OAAO,MAAM,CAAC,WAAW,CAAC,CAAC;AAC9D,UAAI,QAAS,QAAO,EAAE,OAAO,MAAM,SAAS,KAAK;AAAA,IACnD,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO,EAAE,OAAO,MAAM;AACxB;AAEA,IAAM,gBAAgB,CAAC,WAAuC,OAAO,MAAM,iBAAiB,IAAI,CAAC;AAG1F,SAAS,YAAY,SAAwB,eAAkC;AACpF,SAAO,OAAO,SAAS,eAAe,MAAM;AAC9C;AAGO,SAAS,cAAc,SAAwB,eAAkC;AACtF,SAAO,OAAO,WAAW,eAAe,MAAM;AAChD;;;AC7BA,eAAsB,UAAU,QAA+C;AAC7E,QAAM,CAAC,SAAS,KAAK,IAAI,MAAM,QAAQ,IAAI,CAAC,cAAc,MAAM,GAAG,YAAY,MAAM,CAAC,CAAC;AACvF,SAAO,EAAE,SAAS,OAAO,OAAO,MAAM,MAAM;AAC9C;;;ACXA,IAAM,cAAc;AAEb,IAAM,cAAsB;AAAA,EACjC,IAAI;AAAA,EACJ,aAAa;AAAA,EACb,cAAc,EAAE,OAAO,MAAM,UAAU,MAAM,KAAK,MAAM,SAAS,KAAK;AAAA,EACtE,MAAM,OAAO,KAA2C;AACtD,UAAM,SAAS,MAAM,UAAU,IAAI,GAAG;AACtC,WAAO;AAAA,MACL,UAAU;AAAA,MACV,OAAO,OAAO;AAAA,MACd,OAAO;AAAA,QACL,EAAE,MAAM,WAAW,GAAG,OAAO,QAAQ;AAAA,QACrC,EAAE,MAAM,SAAS,GAAG,OAAO,MAAM;AAAA,MACnC;AAAA,MACA,MAAM,OAAO,QACT,SACA,6CAA6C,WAAW;AAAA,IAC9D;AAAA,EACF;AACF;;;ACvBA,qBAAqE;AACrE,IAAAC,kBAAuB;AACvB,IAAAC,oBAAqB;AACrB,kBAMO;;;ACTP,yBAA2B;AAC3B,IAAAC,oBAA8B;AAC9B,sBAA8B;AAIvB,SAAS,aAAqB;AACnC,aAAO,4BAAK,+BAAQ,+BAAc,aAAe,CAAC,GAAG,WAAW;AAClE;AAEO,SAAS,OAAO,MAAsB;AAC3C,aAAO,+BAAW,QAAQ,EAAE,OAAO,IAAI,EAAE,OAAO,KAAK;AACvD;AAGO,SAAS,aAAa,MAAmD;AAC9E,aAAW,QAAQ,KAAK,QAAQ,EAAE,MAAM,IAAI,EAAE,QAAQ,GAAG;AACvD,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,CAAC,QAAQ,WAAW,GAAG,EAAG;AAC9B,QAAI;AACF,aAAO,KAAK,MAAM,OAAO;AAAA,IAC3B,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAM,SAAS,oBAAI,IAAqC;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,SAAS,QAAQ,OAAoC;AAC1D,SAAO,OAAO,UAAU,YAAY,OAAO,IAAI,KAAwC,IAClF,QACD;AACN;;;ADlBA,eAAsB,OACpB,MACA,UACA,IACoB;AACpB,QAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,QAAM,QAAQ,YAAY,IAAI;AAC9B,QAAM,mBAAmB,KAAK,QAAQ;AAEtC,QAAM,MAAM,GAAG,cAAU,gCAAY,4BAAK,wBAAO,GAAG,aAAa,CAAC;AAClE,QAAM,kBAAc,wBAAK,KAAK,cAAc;AAC5C;AAAA,IACE;AAAA,IACA,KAAK,UAAU;AAAA,MACb,gBAAgB,KAAK;AAAA,MACrB,SAAS,EAAE,IAAI,KAAK,QAAQ,GAAG;AAAA,MAC/B,OAAO,EAAE,MAAM,KAAK,WAAW,OAAO,KAAK,MAAM,MAAM;AAAA,MACvD,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,MACd,MAAM,KAAK;AAAA,MACX,KAAK,GAAG;AAAA,IACV,CAAC;AAAA,EACH;AAEA,QAAM,OAAO;AAAA,IACX,GAAG,SAAS;AAAA,IACZ;AAAA,IACA,aAAa,GAAG,UAAU;AAAA,IAC1B,WAAW;AAAA,IACX;AAAA,EACF;AACA,QAAM,EAAE,QAAQ,QAAQ,KAAK,IAAI,MAAM,GAAG,MAAM,SAAS,SAAS,IAAI;AACtE,QAAM,YAAY,KAAK,MAAM,YAAY,IAAI,IAAI,KAAK;AAEtD,MAAI,SAAS,KAAK,KAAC,2BAAW,GAAG,OAAO,GAAG;AACzC,UAAM,UAAU,aAAa,MAAM;AACnC,UAAM,QAAQ,QAAQ,SAAS,KAAK;AACpC,UAAM,QACH,SAAS,SACV,OAAO,KAAK,EAAE,MAAM,IAAI,EAAE,IAAI,KAC9B,0BAA0B,IAAI;AAChC,WAAO,EAAE,QAAQ,SAAS,kBAAkB,WAAW,OAAO,MAAM;AAAA,EACtE;AAEA,MAAI;AACF,sCAAa,6BAAa,GAAG,SAAS,MAAM,CAAC;AAAA,EAC/C,SAAS,OAAO;AACd,WAAO;AAAA,MACL,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP,OAAO,+BAAgC,MAAgB,OAAO;AAAA,IAChE;AAAA,EACF;AAEA,QAAM,aAAa,aAAa,MAAM;AACtC,QAAM,QAAQ,YAAY;AAC1B,QAAM,SAAoB;AAAA,IACxB,gBAAgB;AAAA,IAChB,WAAW,KAAK;AAAA,IAChB,MAAM,KAAK;AAAA,IACX,SAAS,EAAE,IAAI,KAAK,QAAQ,IAAI,SAAS,KAAK,QAAQ,QAAQ;AAAA,IAC9D,SAAS,EAAE,WAAW,kBAAkB,QAAQ,OAAO,MAAM,SAAS,QAAQ;AAAA,IAC9E,iBAAiB,YAAY;AAAA,IAC7B,UAAU,YAAY;AAAA,IACtB,kBAAc,2BAAW,KAAK,SAAS,IACnC,WAAO,6BAAa,KAAK,WAAW,MAAM,CAAC,IAC3C;AAAA,IACJ,aAAa,WAAO,2BAAc,KAAK,IAAI,CAAC;AAAA,IAC5C,cAAc,GAAG;AAAA,IACjB,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AACA,oCAAc,GAAG,GAAG,OAAO,aAAa,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,CAAI;AAE9E,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,aAAa,GAAG;AAAA,IAChB;AAAA,IACA,eAAe;AAAA,IACf;AAAA,EACF;AACF;;;AE3GA,IAAAC,kBAAqE;AACrE,IAAAC,kBAAuB;AACvB,IAAAC,oBAAqB;AACrB,IAAAC,eAMO;AAgBA,SAAS,YAAY,MAA6C;AACvE,QAAM,UAAU,KAAK;AACrB,MAAI,CAAC,QAAS,OAAM,IAAI,MAAM,6BAA6B;AAC3D,QAAM,OAAgC,EAAE,GAAG,KAAK,MAAM,GAAI,QAAQ,QAAQ,CAAC,EAAG;AAG9E,QAAM,QAAQ,CAAC,UAA6B,MAAM,QAAQ,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI;AACtF,aAAW,UAAU,QAAQ,SAAS;AACpC,SAAK,MAAM,IAAI,MAAM,KAAK,MAAM,CAAC;AAAA,EACnC;AACA,SAAO;AACT;AAGA,eAAsB,WACpB,MACA,UACA,IACoB;AACpB,QAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,QAAM,QAAQ,YAAY,IAAI;AAC9B,QAAM,mBAAmB,KAAK,QAAQ;AACtC,QAAM,OAAO,YAAY,IAAI;AAE7B,QAAM,MAAM,GAAG,cAAU,iCAAY,4BAAK,wBAAO,GAAG,iBAAiB,CAAC;AACtE,QAAM,kBAAc,wBAAK,KAAK,cAAc;AAC5C;AAAA,IACE;AAAA,IACA,KAAK,UAAU;AAAA,MACb,MAAM;AAAA,MACN,gBAAgB,KAAK;AAAA,MACrB,SAAS,EAAE,IAAI,KAAK,QAAQ,GAAG;AAAA,MAC/B,OAAO,EAAE,MAAM,KAAK,WAAW,OAAO,KAAK,MAAM,MAAM;AAAA,MACvD;AAAA,MACA,SAAS,EAAE,SAAS,KAAK,SAAS,WAAW,CAAC,EAAE;AAAA,MAChD,SAAS,GAAG;AAAA,MACZ,MAAM,KAAK;AAAA,MACX,KAAK,GAAG;AAAA,IACV,CAAC;AAAA,EACH;AAEA,QAAM,OAAO;AAAA,IACX,GAAG,SAAS;AAAA,IACZ;AAAA,IACA,aAAa,GAAG,UAAU;AAAA,IAC1B,WAAW;AAAA,IACX;AAAA,EACF;AACA,QAAM,EAAE,QAAQ,QAAQ,KAAK,IAAI,MAAM,GAAG,MAAM,SAAS,SAAS,IAAI;AACtE,QAAM,YAAY,KAAK,MAAM,YAAY,IAAI,IAAI,KAAK;AAEtD,MAAI,SAAS,KAAK,KAAC,4BAAW,GAAG,OAAO,GAAG;AACzC,UAAM,UAAU,aAAa,MAAM;AACnC,UAAM,QACH,SAAS,SACV,OAAO,KAAK,EAAE,MAAM,IAAI,EAAE,IAAI,KAC9B,0BAA0B,IAAI;AAChC,WAAO,EAAE,QAAQ,SAAS,kBAAkB,WAAW,OAAO,QAAQ,SAAS,KAAK,GAAG,MAAM;AAAA,EAC/F;AAEA,MAAI;AACF,uCAAa,8BAAa,GAAG,SAAS,MAAM,CAAC;AAAA,EAC/C,SAAS,OAAO;AACd,WAAO;AAAA,MACL,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP,OAAO,+BAAgC,MAAgB,OAAO;AAAA,IAChE;AAAA,EACF;AAEA,QAAM,aAAa,aAAa,MAAM;AACtC,QAAM,QAAQ,YAAY;AAC1B,QAAM,SAAoB;AAAA,IACxB,gBAAgB;AAAA,IAChB,WAAW,KAAK;AAAA,IAChB,MAAM,KAAK;AAAA,IACX,SAAS,EAAE,IAAI,KAAK,QAAQ,IAAI,SAAS,KAAK,QAAQ,QAAQ;AAAA,IAC9D,SAAS,EAAE,WAAW,kBAAkB,QAAQ,OAAO,MAAM,SAAS,QAAQ;AAAA,IAC9E,iBAAiB,YAAY;AAAA,IAC7B,UAAU,YAAY;AAAA,IACtB,kBAAc,4BAAW,KAAK,SAAS,IACnC,WAAO,8BAAa,KAAK,WAAW,MAAM,CAAC,IAC3C;AAAA,IACJ,aAAa,WAAO,4BAAc,IAAI,CAAC;AAAA,IACvC,mBAAmB,GAAG;AAAA,IACtB,8BAA0B,4BAAW,GAAG,WAAW,IAC/C,WAAO,8BAAa,GAAG,aAAa,MAAM,CAAC,IAC3C;AAAA,IACJ,cAAc,GAAG;AAAA,IACjB,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AACA,qCAAc,GAAG,GAAG,OAAO,aAAa,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,CAAI;AAE9E,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,aAAa,GAAG;AAAA,IAChB;AAAA,IACA,eAAe;AAAA,IACf;AAAA,EACF;AACF;;;AChIA,IAAAC,kBAAmE;AACnE,IAAAC,kBAAwB;AACxB,IAAAC,oBAAqB;AACrB,IAAAC,iBAAiD;AAEjD,IAAM,WAAW;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,SAAS,oBAA4B;AAC1C,QAAM,OAAO,QAAQ,IAAI,qBAAiB,4BAAK,yBAAQ,GAAG,UAAU,OAAO;AAC3E,aAAO,wBAAK,MAAM,UAAU,SAAS,KAAK;AAC5C;AAIA,SAAS,aAAa,KAAqB;AACzC,aAAO,wBAAK,KAAK,uBAAuB;AAC1C;AAEA,SAAS,YAAY,KAAsB;AACzC,MAAI;AACF,eAAO,8BAAa,aAAa,GAAG,GAAG,MAAM,EAAE,KAAK,MAAM,KAAK,UAAU,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC;AAAA,EAC/F,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,oBAAoB,MAAc,kBAAkB,GAAY;AAC9E,aAAO,gCAAW,wBAAK,KAAK,cAAc,CAAC,KAAK,YAAY,GAAG;AACjE;AAQA,eAAsB,cACpB,UACA,UAAqB,6BAAa,KAAK,GAAM,GAC7C,MAAc,kBAAkB,GACf;AACjB,MAAI,oBAAoB,GAAG,EAAG,QAAO;AACrC,iCAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAClC,QAAM,OAAO,sBAAsB,KAAK,UAAU,QAAQ,CAAC;AAC3D,QAAM,IAAI,UAAU,CAAC,qBAAqB,aAAa,GAAG,IAAI,MAAM,IAAI,CAAC;AACzE,qCAAc,aAAa,GAAG,GAAG,KAAK,UAAU,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,CAAC;AACrE,SAAO;AACT;;;ACzDA,IAAAC,oBAAqB;AAiCrB,eAAsB,UACpB,MACA,UACA,IACuB;AACvB,QAAM,UAAyB,CAAC;AAChC,aAAW,WAAW,UAAU;AAC9B,QAAI;AACJ,QAAI;AACF,YAAM,WAAW,MAAM,GAAG,QAAQ,OAAO;AACzC,YAAM,YAAY,EAAE,GAAG,MAAM,SAAS,EAAE,GAAG,KAAK,SAAS,QAAQ,EAAE;AACnE,YAAM,SAAS,MAAM,OAAO,WAAW,UAAU;AAAA,QAC/C,OAAO,GAAG;AAAA,QACV,YAAY,GAAG;AAAA,QACf,aAAS,wBAAK,GAAG,QAAQ,GAAG,OAAO,eAAe;AAAA,MACpD,CAAC;AACD,cAAQ;AAAA,QACN;AAAA,QACA,QAAQ,OAAO;AAAA,QACf,aAAa,OAAO;AAAA,QACpB,eAAe,OAAO;AAAA,QACtB,WAAW,OAAO;AAAA,QAClB,OAAO,OAAO;AAAA,QACd,OAAO,OAAO;AAAA,MAChB;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,EAAE,SAAS,QAAQ,SAAS,WAAW,GAAG,OAAQ,MAAgB,QAAQ;AAAA,IACpF;AACA,YAAQ,KAAK,KAAK;AAClB,QAAI,MAAM,WAAW,WAAW,CAAC,GAAG,UAAW;AAAA,EACjD;AACA,SAAO;AAAA,IACL;AAAA,IACA,IAAI,QAAQ,WAAW,SAAS,UAAU,QAAQ,MAAM,CAAC,MAAM,EAAE,WAAW,IAAI;AAAA,EAClF;AACF;;;AChEA,IAAM,sBAAsB;AAYrB,SAAS,sBAAsB,UAAkD;AACtF,MAAI,aAAa,SAAS;AAExB,WAAO;AAAA,EACT;AACA,SAAO,EAAE,SAAS,MAAM,MAAM,CAAC,MAAM,cAAc,mBAAmB,mBAAmB,EAAE;AAC7F;AAYO,SAAS,UAAU,QAAsB,UAAwC;AACtF,MAAI,OAAO,MAAM,MAAO,QAAO,CAAC;AAChC,MAAI,OAAO,QAAQ,OAAO;AACxB,WAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,OAAO;AAAA,QACP,SAAS,EAAE,SAAS,OAAO,QAAQ,QAAQ,WAAW,MAAM,CAAC,OAAO,SAAS,EAAE;AAAA,MACjF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS,sBAAsB,QAAQ;AAAA,IACzC;AAAA,EACF;AACF;AA8BA,eAAsB,SAAS,UAAwB,CAAC,GAAyB;AAC/E,QAAM;AAAA,IACJ;AAAA,IACA,gBAAY,6BAAa,KAAK,GAAM;AAAA,IACpC,WAAW,QAAQ;AAAA,IACnB,SAAS;AAAA,EACX,IAAI;AAEJ,QAAM,SAAS,MAAM,UAAU,MAAM;AACrC,MAAI,OAAO,MAAO,QAAO,EAAE,GAAG,QAAQ,OAAO,CAAC,EAAE;AAEhD,QAAM,OAAO,UAAU,QAAQ,QAAQ;AAEvC,MAAI,QAAQ;AACV,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO,KAAK,IAAI,CAAC,UAAU,EAAE,GAAG,MAAM,QAAQ,KAAK,UAAU,YAAY,cAAc,EAAE;AAAA,IAC3F;AAAA,EACF;AAEA,QAAM,QAA2B,CAAC;AAClC,aAAW,QAAQ,MAAM;AACvB,QAAI,CAAC,KAAK,SAAS;AACjB,YAAM,KAAK,EAAE,GAAG,MAAM,QAAQ,cAAc,CAAC;AAC7C;AAAA,IACF;AACA,QAAI;AACF,YAAM,UAAU,KAAK,QAAQ,SAAS,KAAK,QAAQ,IAAI;AACvD,YAAM,KAAK,EAAE,GAAG,MAAM,QAAQ,MAAM,CAAC;AAAA,IACvC,SAAS,OAAO;AACd,YAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACpE,YAAM,KAAK,EAAE,GAAG,MAAM,QAAQ,UAAU,OAAO,CAAC;AAAA,IAClD;AAAA,EACF;AAEA,QAAM,QAAQ,MAAM,UAAU,MAAM;AACpC,SAAO,EAAE,SAAS,MAAM,SAAS,OAAO,MAAM,OAAO,OAAO,MAAM,OAAO,MAAM;AACjF;;;ACxGA,SAAS,aAAa,OAA6B;AACjD,QAAM,IAAI;AACV,MAAI,CAAC,KAAK,OAAO,EAAE,SAAS,YAAY,OAAO,EAAE,SAAS,UAAU;AAClE,UAAM,IAAI,MAAM,mDAAmD;AAAA,EACrE;AACA,SAAO;AAAA,IACL,MAAM,EAAE;AAAA,IACR,MAAM,EAAE;AAAA,IACR,MAAM,MAAM,QAAQ,EAAE,IAAI,IAAK,EAAE,OAAoB;AAAA,IACrD,SAAS,OAAO,EAAE,YAAY,WAAW,EAAE,UAAU;AAAA,IACrD,MAAM,OAAO,EAAE,SAAS,WAAW,EAAE,OAAO;AAAA,EAC9C;AACF;AAEA,SAAS,gBAAgB,KAAyB;AAChD,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,QAAQ;AACN,UAAM,IAAI,MAAM,yDAAyD;AAAA,EAC3E;AACA,QAAM,MAAM;AACZ,MAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,IAAI,aAAa,GAAG;AACxE,UAAM,IAAI,MAAM,4CAA4C;AAAA,EAC9D;AACA,SAAO;AAAA,IACL,gBAAgB,IAAI,iBAAiB,aAAa,IAAI,cAAc,IAAI;AAAA,IACxE,eAAe,IAAI,cAAc,IAAI,YAAY;AAAA,EACnD;AACF;AAEA,SAAS,UAAU,SAAsB,WAAoC;AAC3E,SAAO,EAAE,IAAI,QAAQ,MAAM,SAAS,QAAQ,SAAS,MAAM,QAAQ,QAAQ,QAAW,UAAU;AAClG;AAGA,eAAsB,aAAa,KAAa,KAA+C;AAC7F,QAAM,SAAS,gBAAgB,MAAM,IAAI,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AACpE,QAAM,WAA6B,CAAC;AACpC,MAAI,OAAO,eAAgB,UAAS,KAAK,UAAU,OAAO,gBAAgB,IAAI,CAAC;AAC/E,aAAW,WAAW,OAAO,cAAe,UAAS,KAAK,UAAU,SAAS,KAAK,CAAC;AACnF,SAAO;AACT;AAEA,eAAsB,WACpB,KACA,SACA,MACA,KACe;AACf,QAAM,IAAI,KAAK,CAAC,OAAO,OAAO,CAAC;AAC/B,MAAI,KAAK,QAAS,OAAM,IAAI,KAAK,CAAC,WAAW,OAAO,CAAC;AACvD;AAEA,eAAsB,cACpB,KACA,SACA,KACe;AACf,QAAM,IAAI,KAAK,CAAC,UAAU,OAAO,CAAC;AACpC;AAEA,eAAsB,kBACpB,KACA,SACA,KACe;AACf,QAAM,IAAI,KAAK,CAAC,WAAW,OAAO,CAAC;AACrC;AAEA,eAAsB,cACpB,KACA,SACA,KACe;AACf,QAAM,IAAI,KAAK,UAAU,CAAC,UAAU,OAAO,IAAI,CAAC,QAAQ,CAAC;AAC3D;AAEA,eAAsB,WAAW,KAAa,KAAmC;AAC/E,QAAM,IAAI,KAAK,CAAC,IAAI,CAAC;AACvB;AAGA,eAAsB,eACpB,KACA,SACA,KAC8C;AAC9C,QAAM,SAAS,gBAAgB,MAAM,IAAI,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AACpE,QAAM,MAAM,OAAO,iBACf,CAAC,OAAO,gBAAgB,GAAG,OAAO,aAAa,IAC/C,OAAO;AACX,QAAM,QAAQ,IAAI,KAAK,CAAC,MAAM,EAAE,SAAS,OAAO;AAChD,MAAI,CAAC,OAAO,MAAM;AAChB,UAAM,IAAI;AAAA,MACR,kBAAkB,OAAO,2DAA2D,OAAO;AAAA,IAC7F;AAAA,EACF;AACA,SAAO,EAAE,SAAS,MAAM,MAAM,MAAM,MAAM,QAAQ,CAAC,EAAE;AACvD;AAGO,SAAS,wBAAwB,UAAoB,WAAmC;AAC7F,QAAM,OAAO,IAAI,IAAI,UAAU,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC/C,QAAM,UAAU,SAAS,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;AACnD,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,QAAQ,QAAQ,IAAI,CAAC,MAAM,0BAA0B,CAAC,EAAE,EAAE,KAAK,IAAI;AACzE,UAAM,IAAI;AAAA,MACR,mCAAmC,QAAQ,KAAK,IAAI,CAAC,mBAAmB,KAAK;AAAA,IAC/E;AAAA,EACF;AACF;","names":["import_engine","import_node_os","import_node_path","import_node_path","import_node_fs","import_node_os","import_node_path","import_core","import_node_fs","import_node_os","import_node_path","import_engine","import_node_path"]}
1
+ {"version":3,"sources":["../src/index.ts","../../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.15_typescript@6.0.3/node_modules/tsup/assets/cjs_shims.js","../src/environment.ts","../src/doctor.ts","../src/engine.ts","../src/fit.ts","../src/runner-common.ts","../src/predict.ts","../src/project.ts","../src/run-matrix.ts","../src/setup.ts","../src/versions.ts"],"sourcesContent":["export type { DoctorReport } from \"./doctor\";\nexport { runDoctor } from \"./doctor\";\nexport { juliaEngine } from \"./engine\";\nexport type { CommandRunner, ToolInfo } from \"./environment\";\nexport { detectJulia, detectJuliaup } from \"./environment\";\nexport type { FitIo } from \"./fit\";\nexport { runFit } from \"./fit\";\nexport type { PredictIo } from \"./predict\";\nexport { predictData, runPredict } from \"./predict\";\nexport { ensureProject, managedProjectDir, managedProjectReady } from \"./project\";\nexport type { MatrixEntry, MatrixIo, MatrixResult } from \"./run-matrix\";\nexport { runMatrix } from \"./run-matrix\";\nexport type {\n InstallCommand,\n SetupOptions,\n SetupResult,\n SetupStep,\n SetupStepResult,\n StepStatus,\n} from \"./setup\";\nexport { juliaupInstallCommand, planSetup, runSetup } from \"./setup\";\nexport {\n addVersion,\n assertVersionsInstalled,\n gcVersions,\n listVersions,\n removeVersion,\n resolveVersion,\n setDefaultVersion,\n updateVersion,\n} from \"./versions\";\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { type CommandRunner, createRunner, type ToolInfo } from \"@mcmcjs/engine\";\n\nexport type { CommandRunner, ToolInfo } from \"@mcmcjs/engine\";\nexport { createRunner } from \"@mcmcjs/engine\";\n\nconst defaultRunner = createRunner();\n\n// juliaup installs its shims here; we also fall back to whatever is on PATH.\nfunction candidates(binary: string): string[] {\n return [join(homedir(), \".juliaup\", \"bin\", binary), binary];\n}\n\nasync function detect(\n binary: string,\n parseVersion: (stdout: string) => string | undefined,\n runner: CommandRunner,\n): Promise<ToolInfo> {\n for (const path of candidates(binary)) {\n try {\n const version = parseVersion(await runner(path, [\"--version\"]));\n if (version) return { found: true, version, path };\n } catch {\n // not available at this path; try the next candidate\n }\n }\n return { found: false };\n}\n\nconst versionNumber = (stdout: string): string | undefined => stdout.match(/(\\d+\\.\\d+\\.\\d+)/)?.[1];\n\n/** Detects the Julia runtime via `julia --version`. */\nexport function detectJulia(runner: CommandRunner = defaultRunner): Promise<ToolInfo> {\n return detect(\"julia\", versionNumber, runner);\n}\n\n/** Detects the juliaup version manager via `juliaup --version`. */\nexport function detectJuliaup(runner: CommandRunner = defaultRunner): Promise<ToolInfo> {\n return detect(\"juliaup\", versionNumber, runner);\n}\n","import { type CommandRunner, detectJulia, detectJuliaup, type ToolInfo } from \"./environment\";\n\n/** A summary of the Julia toolchain available for inference. */\nexport interface DoctorReport {\n juliaup: ToolInfo;\n julia: ToolInfo;\n /** True when Julia itself is available (the minimum needed to run inference). */\n ready: boolean;\n}\n\n/** Detects the installed Julia toolchain and reports whether inference can run. */\nexport async function runDoctor(runner?: CommandRunner): Promise<DoctorReport> {\n const [juliaup, julia] = await Promise.all([detectJuliaup(runner), detectJulia(runner)]);\n return { juliaup, julia, ready: julia.found };\n}\n","import type { Engine, EngineContext, HealthReport } from \"@mcmcjs/engine\";\nimport { runDoctor } from \"./doctor\";\n\nconst JULIAUP_URL = \"https://github.com/JuliaLang/juliaup\";\n\nexport const juliaEngine: Engine = {\n id: \"julia\",\n displayName: \"Julia\",\n capabilities: { setup: true, versions: true, fit: true, predict: true },\n async doctor(ctx: EngineContext): Promise<HealthReport> {\n const report = await runDoctor(ctx.run);\n return {\n engineId: \"julia\",\n ready: report.ready,\n tools: [\n { name: \"juliaup\", ...report.juliaup },\n { name: \"julia\", ...report.julia },\n ],\n hint: report.ready\n ? undefined\n : `Julia not found. Install it with juliaup (${JULIAUP_URL}), or run \\`mcmc setup\\`.`,\n };\n },\n};\n","import { existsSync, mkdtempSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n canonicalJson,\n parseSamples,\n type ResolvedSpec,\n RUN_RECORD_SCHEMA_VERSION,\n type RunRecord,\n} from \"@mcmcjs/core\";\nimport type { FitResult, FitRunner } from \"@mcmcjs/engine\";\nimport { driverPath, lastJsonLine, sha256, toStage } from \"./runner-common\";\n\nexport interface FitIo {\n /** Spawns the Julia process; injectable so runFit is testable without Julia. */\n spawn: FitRunner;\n /** The managed Julia project directory passed as --project. */\n projectDir: string;\n /** Where the samples file is written. */\n outPath: string;\n tmpDir?: string;\n}\n\n/** Runs one inference for a resolved spec on a resolved runtime invocation. */\nexport async function runFit(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: FitIo,\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n const runtimeRequested = spec.backend.version;\n\n const tmp = io.tmpDir ?? mkdtempSync(join(tmpdir(), \"mcmcjs-fit-\"));\n const requestPath = join(tmp, \"request.json\");\n writeFileSync(\n requestPath,\n JSON.stringify({\n schema_version: spec.schema_version,\n backend: { id: spec.backend.id },\n model: { file: spec.modelPath, entry: spec.model.entry },\n data: spec.data,\n sampler: spec.sampler,\n seed: spec.seed,\n out: io.outPath,\n }),\n );\n\n const args = [\n ...resolved.args,\n \"--startup-file=no\",\n `--project=${io.projectDir}`,\n driverPath(),\n requestPath,\n ];\n const { stdout, stderr, code } = await io.spawn(resolved.command, args);\n const elapsedMs = Math.round(performance.now() - start);\n\n if (code !== 0 || !existsSync(io.outPath)) {\n const failure = lastJsonLine(stderr);\n const stage = toStage(failure?.stage);\n const error =\n (failure?.error as string) ??\n stderr.trim().split(\"\\n\").pop() ??\n `julia exited with code ${code}`;\n return { status: \"error\", runtimeRequested, elapsedMs, stage, error };\n }\n\n try {\n parseSamples(readFileSync(io.outPath, \"utf8\"));\n } catch (error) {\n return {\n status: \"error\",\n runtimeRequested,\n elapsedMs,\n stage: \"write\",\n error: `samples file did not parse: ${(error as Error).message}`,\n };\n }\n\n const provenance = lastJsonLine(stdout);\n const julia = provenance?.julia_version as string | undefined;\n const record: RunRecord = {\n schema_version: RUN_RECORD_SCHEMA_VERSION,\n spec_hash: spec.specHash,\n seed: spec.seed,\n backend: { id: spec.backend.id, runtime: spec.backend.runtime },\n runtime: { requested: runtimeRequested, actual: julia, path: resolved.command },\n manifest_sha256: provenance?.manifest_sha256 as string | undefined,\n packages: provenance?.packages as Record<string, string> | undefined,\n model_sha256: existsSync(spec.modelPath)\n ? sha256(readFileSync(spec.modelPath, \"utf8\"))\n : undefined,\n data_sha256: sha256(canonicalJson(spec.data)),\n samples_file: io.outPath,\n started_at: startedAt,\n elapsed_ms: elapsedMs,\n };\n writeFileSync(`${io.outPath}.run.json`, `${JSON.stringify(record, null, 2)}\\n`);\n\n return {\n status: \"ok\",\n samplesFile: io.outPath,\n runtimeRequested,\n runtimeActual: julia,\n elapsedMs,\n };\n}\n","import { createHash } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { FitResult } from \"@mcmcjs/engine\";\n\n/** Path to the shipped Julia driver, resolved next to this module in dist/. */\nexport function driverPath(): string {\n return join(dirname(fileURLToPath(import.meta.url)), \"driver.jl\");\n}\n\nexport function sha256(text: string): string {\n return createHash(\"sha256\").update(text).digest(\"hex\");\n}\n\n/** Parses the last JSON-object line of text (the driver's provenance or error line). */\nexport function lastJsonLine(text: string): Record<string, unknown> | undefined {\n for (const line of text.trimEnd().split(\"\\n\").reverse()) {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"{\")) continue;\n try {\n return JSON.parse(trimmed) as Record<string, unknown>;\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\nconst STAGES = new Set<NonNullable<FitResult[\"stage\"]>>([\n \"compile\",\n \"sample\",\n \"load_samples\",\n \"predict\",\n \"write\",\n \"spawn\",\n]);\n\n/** Narrows a driver-reported stage string to the known set. */\nexport function toStage(value: unknown): FitResult[\"stage\"] {\n return typeof value === \"string\" && STAGES.has(value as NonNullable<FitResult[\"stage\"]>)\n ? (value as FitResult[\"stage\"])\n : undefined;\n}\n","import { existsSync, mkdtempSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n canonicalJson,\n parseSamples,\n type ResolvedSpec,\n RUN_RECORD_SCHEMA_VERSION,\n type RunRecord,\n} from \"@mcmcjs/core\";\nimport type { FitResult, FitRunner } from \"@mcmcjs/engine\";\nimport { driverPath, lastJsonLine, sha256, toStage } from \"./runner-common\";\n\nexport interface PredictIo {\n /** Spawns the Julia process; injectable so runPredict is testable without Julia. */\n spawn: FitRunner;\n projectDir: string;\n /** Where the posterior-predictive samples file is written. */\n outPath: string;\n /** The posterior samples file fed to prediction. */\n samplesPath: string;\n tmpDir?: string;\n}\n\n/** The prediction data: [data] with [predict].data overrides, target outcomes blanked to nulls. */\nexport function predictData(spec: ResolvedSpec): Record<string, unknown> {\n const predict = spec.predict;\n if (!predict) throw new Error(\"spec has no [predict] block\");\n const data: Record<string, unknown> = { ...spec.data, ...(predict.data ?? {}) };\n // Blank a target to null, preserving array shape so the driver maps it to a\n // matching shape of `missing` (a multidimensional outcome stays nested).\n const blank = (value: unknown): unknown => (Array.isArray(value) ? value.map(blank) : null);\n for (const target of predict.targets) {\n data[target] = blank(data[target]);\n }\n return data;\n}\n\n/** Draws posterior-predictive samples from a fitted model and its posterior samples file. */\nexport async function runPredict(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: PredictIo,\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n const runtimeRequested = spec.backend.version;\n const data = predictData(spec);\n\n const tmp = io.tmpDir ?? mkdtempSync(join(tmpdir(), \"mcmcjs-predict-\"));\n const requestPath = join(tmp, \"request.json\");\n writeFileSync(\n requestPath,\n JSON.stringify({\n mode: \"predict\",\n schema_version: spec.schema_version,\n backend: { id: spec.backend.id },\n model: { file: spec.modelPath, entry: spec.model.entry },\n data,\n predict: { targets: spec.predict?.targets ?? [] },\n samples: io.samplesPath,\n seed: spec.seed,\n out: io.outPath,\n }),\n );\n\n const args = [\n ...resolved.args,\n \"--startup-file=no\",\n `--project=${io.projectDir}`,\n driverPath(),\n requestPath,\n ];\n const { stdout, stderr, code } = await io.spawn(resolved.command, args);\n const elapsedMs = Math.round(performance.now() - start);\n\n if (code !== 0 || !existsSync(io.outPath)) {\n const failure = lastJsonLine(stderr);\n const error =\n (failure?.error as string) ??\n stderr.trim().split(\"\\n\").pop() ??\n `julia exited with code ${code}`;\n return { status: \"error\", runtimeRequested, elapsedMs, stage: toStage(failure?.stage), error };\n }\n\n try {\n parseSamples(readFileSync(io.outPath, \"utf8\"));\n } catch (error) {\n return {\n status: \"error\",\n runtimeRequested,\n elapsedMs,\n stage: \"write\",\n error: `samples file did not parse: ${(error as Error).message}`,\n };\n }\n\n const provenance = lastJsonLine(stdout);\n const julia = provenance?.julia_version as string | undefined;\n const record: RunRecord = {\n schema_version: RUN_RECORD_SCHEMA_VERSION,\n spec_hash: spec.specHash,\n seed: spec.seed,\n backend: { id: spec.backend.id, runtime: spec.backend.runtime },\n runtime: { requested: runtimeRequested, actual: julia, path: resolved.command },\n manifest_sha256: provenance?.manifest_sha256 as string | undefined,\n packages: provenance?.packages as Record<string, string> | undefined,\n model_sha256: existsSync(spec.modelPath)\n ? sha256(readFileSync(spec.modelPath, \"utf8\"))\n : undefined,\n data_sha256: sha256(canonicalJson(data)),\n posterior_samples: io.samplesPath,\n posterior_samples_sha256: existsSync(io.samplesPath)\n ? sha256(readFileSync(io.samplesPath, \"utf8\"))\n : undefined,\n samples_file: io.outPath,\n started_at: startedAt,\n elapsed_ms: elapsedMs,\n };\n writeFileSync(`${io.outPath}.run.json`, `${JSON.stringify(record, null, 2)}\\n`);\n\n return {\n status: \"ok\",\n samplesFile: io.outPath,\n runtimeRequested,\n runtimeActual: julia,\n elapsedMs,\n };\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { type CommandRunner, createRunner } from \"@mcmcjs/engine\";\n\nconst PACKAGES = [\n \"Turing\",\n \"FlexiChains\",\n \"DimensionalData\",\n \"MCMCChains\",\n \"JuliaBUGS\",\n \"AdvancedHMC\",\n \"ForwardDiff\",\n \"JSON\",\n \"StableRNGs\",\n];\n\n/** The per-user directory holding the managed Julia project (Project + Manifest). */\nexport function managedProjectDir(): string {\n const base = process.env.XDG_DATA_HOME || join(homedir(), \".local\", \"share\");\n return join(base, \"mcmcjs\", \"julia\", \"env\");\n}\n\n// Records the package set a managed dir was provisioned with, so an env from an\n// older package set is healed (Pkg.add is additive) rather than left incomplete.\nfunction sentinelPath(dir: string): string {\n return join(dir, \".mcmcjs-packages.json\");\n}\n\nfunction provisioned(dir: string): boolean {\n try {\n return readFileSync(sentinelPath(dir), \"utf8\").trim() === JSON.stringify([...PACKAGES].sort());\n } catch {\n return false;\n }\n}\n\n/** Whether the managed project is present and provisioned with the current package set. */\nexport function managedProjectReady(dir: string = managedProjectDir()): boolean {\n return existsSync(join(dir, \"Project.toml\")) && provisioned(dir);\n}\n\n/**\n * Ensures the managed Julia project exists with the inference packages installed.\n * Idempotent: returns immediately when already provisioned with the current set,\n * otherwise adds (and precompiles) the missing packages. The first run resolves\n * and precompiles the project, which can take several minutes.\n */\nexport async function ensureProject(\n juliaBin: string,\n run: CommandRunner = createRunner(30 * 60_000),\n dir: string = managedProjectDir(),\n): Promise<string> {\n if (managedProjectReady(dir)) return dir;\n mkdirSync(dir, { recursive: true });\n const code = `using Pkg; Pkg.add(${JSON.stringify(PACKAGES)}); Pkg.precompile()`;\n await run(juliaBin, [\"--startup-file=no\", `--project=${dir}`, \"-e\", code]);\n writeFileSync(sentinelPath(dir), JSON.stringify([...PACKAGES].sort()));\n return dir;\n}\n","import { join } from \"node:path\";\nimport type { ResolvedSpec } from \"@mcmcjs/core\";\nimport type { FitResult, FitRunner } from \"@mcmcjs/engine\";\nimport { runFit } from \"./fit\";\n\nexport interface MatrixEntry {\n version: string;\n status: \"ok\" | \"error\";\n samplesFile?: string;\n runtimeActual?: string;\n elapsedMs: number;\n stage?: FitResult[\"stage\"];\n error?: string;\n}\n\nexport interface MatrixResult {\n entries: MatrixEntry[];\n /** True only when every requested version ran and succeeded. */\n ok: boolean;\n}\n\nexport interface MatrixIo {\n spawn: FitRunner;\n projectDir: string;\n /** Directory the per-version samples files are written into. */\n outDir: string;\n /** Resolves a version/channel to a concrete invocation; injectable for tests. */\n resolve: (version: string) => Promise<{ command: string; args: string[] }>;\n /** Continue after a version fails instead of stopping. */\n keepGoing?: boolean;\n}\n\n/** Runs the same spec across several Julia versions, one samples file per version. */\nexport async function runMatrix(\n spec: ResolvedSpec,\n versions: string[],\n io: MatrixIo,\n): Promise<MatrixResult> {\n const entries: MatrixEntry[] = [];\n for (const version of versions) {\n let entry: MatrixEntry;\n try {\n const resolved = await io.resolve(version);\n const versioned = { ...spec, backend: { ...spec.backend, version } };\n const result = await runFit(versioned, resolved, {\n spawn: io.spawn,\n projectDir: io.projectDir,\n outPath: join(io.outDir, `${version}.samples.json`),\n });\n entry = {\n version,\n status: result.status,\n samplesFile: result.samplesFile,\n runtimeActual: result.runtimeActual,\n elapsedMs: result.elapsedMs,\n stage: result.stage,\n error: result.error,\n };\n } catch (error) {\n entry = { version, status: \"error\", elapsedMs: 0, error: (error as Error).message };\n }\n entries.push(entry);\n if (entry.status === \"error\" && !io.keepGoing) break;\n }\n return {\n entries,\n ok: entries.length === versions.length && entries.every((e) => e.status === \"ok\"),\n };\n}\n","import { type DoctorReport, runDoctor } from \"./doctor\";\nimport { type CommandRunner, createRunner, type ToolInfo } from \"./environment\";\n\n/** The official juliaup install script, piped to a shell by the install step. */\nconst JULIAUP_INSTALL_URL = \"https://install.julialang.org\";\n\n/** An executable and its arguments, run directly (no shell word-splitting). */\nexport interface InstallCommand {\n command: string;\n args: string[];\n}\n\n/**\n * The command that installs juliaup on the given platform, or null when\n * automatic install is not yet supported there.\n */\nexport function juliaupInstallCommand(platform: NodeJS.Platform): InstallCommand | null {\n if (platform === \"win32\") {\n // TODO: install juliaup on Windows via winget or the Microsoft Store.\n return null;\n }\n return { command: \"sh\", args: [\"-c\", `curl -fsSL ${JULIAUP_INSTALL_URL} | sh -s -- --yes`] };\n}\n\n/** A single provisioning step needed to make the toolchain ready. */\nexport interface SetupStep {\n tool: \"juliaup\" | \"julia\";\n /** A short description of what the step does. */\n label: string;\n /** The command to run, or null when the step cannot be performed automatically. */\n command: InstallCommand | null;\n}\n\n/** The ordered steps needed to reach a ready toolchain, given the current state. */\nexport function planSetup(report: DoctorReport, platform: NodeJS.Platform): SetupStep[] {\n if (report.julia.found) return [];\n if (report.juliaup.found) {\n return [\n {\n tool: \"julia\",\n label: \"install the latest stable Julia via juliaup\",\n command: { command: report.juliaup.path ?? \"juliaup\", args: [\"add\", \"release\"] },\n },\n ];\n }\n return [\n {\n tool: \"juliaup\",\n label: \"install juliaup (this also installs Julia)\",\n command: juliaupInstallCommand(platform),\n },\n ];\n}\n\nexport type StepStatus = \"ran\" | \"skipped\" | \"failed\" | \"unsupported\";\n\nexport interface SetupStepResult extends SetupStep {\n status: StepStatus;\n /** Error detail when the step failed. */\n detail?: string;\n}\n\nexport interface SetupResult {\n juliaup: ToolInfo;\n julia: ToolInfo;\n /** True when Julia is available after setup. */\n ready: boolean;\n steps: SetupStepResult[];\n}\n\nexport interface SetupOptions {\n /** Runs detection commands. Injectable for tests. */\n runner?: CommandRunner;\n /** Runs install steps, which may take several minutes. Injectable for tests. */\n installer?: CommandRunner;\n /** Target platform; defaults to the current process platform. */\n platform?: NodeJS.Platform;\n /** Plan the steps but do not run them. */\n dryRun?: boolean;\n}\n\n/** Installs the Julia toolchain (juliaup and Julia) needed for inference. */\nexport async function runSetup(options: SetupOptions = {}): Promise<SetupResult> {\n const {\n runner,\n installer = createRunner(15 * 60_000),\n platform = process.platform,\n dryRun = false,\n } = options;\n\n const before = await runDoctor(runner);\n if (before.ready) return { ...before, steps: [] };\n\n const plan = planSetup(before, platform);\n\n if (dryRun) {\n return {\n ...before,\n steps: plan.map((step) => ({ ...step, status: step.command ? \"skipped\" : \"unsupported\" })),\n };\n }\n\n const steps: SetupStepResult[] = [];\n for (const step of plan) {\n if (!step.command) {\n steps.push({ ...step, status: \"unsupported\" });\n continue;\n }\n try {\n await installer(step.command.command, step.command.args);\n steps.push({ ...step, status: \"ran\" });\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n steps.push({ ...step, status: \"failed\", detail });\n }\n }\n\n const after = await runDoctor(runner);\n return { juliaup: after.juliaup, julia: after.julia, ready: after.ready, steps };\n}\n","import type { CommandRunner, RuntimeVersion } from \"@mcmcjs/engine\";\n\ninterface ChannelInfo {\n Name: string;\n File: string;\n Args?: string[];\n Version?: string;\n Arch?: string;\n}\n\ninterface Getconfig1 {\n DefaultChannel: ChannelInfo | null;\n OtherChannels: ChannelInfo[];\n}\n\nfunction parseChannel(value: unknown): ChannelInfo {\n const c = value as Record<string, unknown>;\n if (!c || typeof c.Name !== \"string\" || typeof c.File !== \"string\") {\n throw new Error(\"unexpected `juliaup api getconfig1` channel shape\");\n }\n return {\n Name: c.Name,\n File: c.File,\n Args: Array.isArray(c.Args) ? (c.Args as string[]) : undefined,\n Version: typeof c.Version === \"string\" ? c.Version : undefined,\n Arch: typeof c.Arch === \"string\" ? c.Arch : undefined,\n };\n}\n\nfunction parseGetconfig1(raw: string): Getconfig1 {\n let data: unknown;\n try {\n data = JSON.parse(raw);\n } catch {\n throw new Error(\"could not parse `juliaup api getconfig1` output as JSON\");\n }\n const obj = data as Record<string, unknown>;\n if (!obj || typeof obj !== \"object\" || !Array.isArray(obj.OtherChannels)) {\n throw new Error(\"unexpected `juliaup api getconfig1` output\");\n }\n return {\n DefaultChannel: obj.DefaultChannel ? parseChannel(obj.DefaultChannel) : null,\n OtherChannels: obj.OtherChannels.map(parseChannel),\n };\n}\n\nfunction toVersion(channel: ChannelInfo, isDefault: boolean): RuntimeVersion {\n return { id: channel.Name, version: channel.Version, path: channel.File || undefined, isDefault };\n}\n\n/** Lists the installed Julia versions, marking the default channel. */\nexport async function listVersions(bin: string, run: CommandRunner): Promise<RuntimeVersion[]> {\n const config = parseGetconfig1(await run(bin, [\"api\", \"getconfig1\"]));\n const versions: RuntimeVersion[] = [];\n if (config.DefaultChannel) versions.push(toVersion(config.DefaultChannel, true));\n for (const channel of config.OtherChannels) versions.push(toVersion(channel, false));\n return versions;\n}\n\nexport async function addVersion(\n bin: string,\n channel: string,\n opts: { default?: boolean },\n run: CommandRunner,\n): Promise<void> {\n await run(bin, [\"add\", channel]);\n if (opts.default) await run(bin, [\"default\", channel]);\n}\n\nexport async function removeVersion(\n bin: string,\n channel: string,\n run: CommandRunner,\n): Promise<void> {\n await run(bin, [\"remove\", channel]);\n}\n\nexport async function setDefaultVersion(\n bin: string,\n channel: string,\n run: CommandRunner,\n): Promise<void> {\n await run(bin, [\"default\", channel]);\n}\n\nexport async function updateVersion(\n bin: string,\n channel: string | undefined,\n run: CommandRunner,\n): Promise<void> {\n await run(bin, channel ? [\"update\", channel] : [\"update\"]);\n}\n\nexport async function gcVersions(bin: string, run: CommandRunner): Promise<void> {\n await run(bin, [\"gc\"]);\n}\n\n/** Resolves a channel to a concrete invocation, preferring its absolute binary path. */\nexport async function resolveVersion(\n bin: string,\n channel: string,\n run: CommandRunner,\n): Promise<{ command: string; args: string[] }> {\n const config = parseGetconfig1(await run(bin, [\"api\", \"getconfig1\"]));\n const all = config.DefaultChannel\n ? [config.DefaultChannel, ...config.OtherChannels]\n : config.OtherChannels;\n const match = all.find((c) => c.Name === channel);\n if (!match?.File) {\n throw new Error(\n `Julia version \"${channel}\" is not installed. Add it with: mcmc julia version add ${channel}`,\n );\n }\n return { command: match.File, args: match.Args ?? [] };\n}\n\n/** Throws with an actionable message if any requested channel is not installed. */\nexport function assertVersionsInstalled(channels: string[], installed: RuntimeVersion[]): void {\n const have = new Set(installed.map((v) => v.id));\n const missing = channels.filter((c) => !have.has(c));\n if (missing.length > 0) {\n const fixes = missing.map((m) => `mcmc julia version add ${m}`).join(\"; \");\n throw new Error(\n `Julia version(s) not installed: ${missing.join(\", \")}. Install with: ${fixes}`,\n );\n }\n}\n"],"mappings":"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","names":["import_engine","import_node_os","import_node_path","import_node_path","import_node_fs","import_node_os","import_node_path","import_core","import_node_fs","import_node_os","import_node_path","import_engine","import_node_path"]}
package/dist/index.js CHANGED
@@ -268,6 +268,8 @@ import { join as join5 } from "path";
268
268
  import { createRunner as createRunner3 } from "@mcmcjs/engine";
269
269
  var PACKAGES = [
270
270
  "Turing",
271
+ "FlexiChains",
272
+ "DimensionalData",
271
273
  "MCMCChains",
272
274
  "JuliaBUGS",
273
275
  "AdvancedHMC",
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/environment.ts","../src/doctor.ts","../src/engine.ts","../src/fit.ts","../src/runner-common.ts","../src/predict.ts","../src/project.ts","../src/run-matrix.ts","../src/setup.ts","../src/versions.ts"],"sourcesContent":["import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { type CommandRunner, createRunner, type ToolInfo } from \"@mcmcjs/engine\";\n\nexport type { CommandRunner, ToolInfo } from \"@mcmcjs/engine\";\nexport { createRunner } from \"@mcmcjs/engine\";\n\nconst defaultRunner = createRunner();\n\n// juliaup installs its shims here; we also fall back to whatever is on PATH.\nfunction candidates(binary: string): string[] {\n return [join(homedir(), \".juliaup\", \"bin\", binary), binary];\n}\n\nasync function detect(\n binary: string,\n parseVersion: (stdout: string) => string | undefined,\n runner: CommandRunner,\n): Promise<ToolInfo> {\n for (const path of candidates(binary)) {\n try {\n const version = parseVersion(await runner(path, [\"--version\"]));\n if (version) return { found: true, version, path };\n } catch {\n // not available at this path; try the next candidate\n }\n }\n return { found: false };\n}\n\nconst versionNumber = (stdout: string): string | undefined => stdout.match(/(\\d+\\.\\d+\\.\\d+)/)?.[1];\n\n/** Detects the Julia runtime via `julia --version`. */\nexport function detectJulia(runner: CommandRunner = defaultRunner): Promise<ToolInfo> {\n return detect(\"julia\", versionNumber, runner);\n}\n\n/** Detects the juliaup version manager via `juliaup --version`. */\nexport function detectJuliaup(runner: CommandRunner = defaultRunner): Promise<ToolInfo> {\n return detect(\"juliaup\", versionNumber, runner);\n}\n","import { type CommandRunner, detectJulia, detectJuliaup, type ToolInfo } from \"./environment\";\n\n/** A summary of the Julia toolchain available for inference. */\nexport interface DoctorReport {\n juliaup: ToolInfo;\n julia: ToolInfo;\n /** True when Julia itself is available (the minimum needed to run inference). */\n ready: boolean;\n}\n\n/** Detects the installed Julia toolchain and reports whether inference can run. */\nexport async function runDoctor(runner?: CommandRunner): Promise<DoctorReport> {\n const [juliaup, julia] = await Promise.all([detectJuliaup(runner), detectJulia(runner)]);\n return { juliaup, julia, ready: julia.found };\n}\n","import type { Engine, EngineContext, HealthReport } from \"@mcmcjs/engine\";\nimport { runDoctor } from \"./doctor\";\n\nconst JULIAUP_URL = \"https://github.com/JuliaLang/juliaup\";\n\nexport const juliaEngine: Engine = {\n id: \"julia\",\n displayName: \"Julia\",\n capabilities: { setup: true, versions: true, fit: true, predict: true },\n async doctor(ctx: EngineContext): Promise<HealthReport> {\n const report = await runDoctor(ctx.run);\n return {\n engineId: \"julia\",\n ready: report.ready,\n tools: [\n { name: \"juliaup\", ...report.juliaup },\n { name: \"julia\", ...report.julia },\n ],\n hint: report.ready\n ? undefined\n : `Julia not found. Install it with juliaup (${JULIAUP_URL}), or run \\`mcmc setup\\`.`,\n };\n },\n};\n","import { existsSync, mkdtempSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n canonicalJson,\n parseSamples,\n type ResolvedSpec,\n RUN_RECORD_SCHEMA_VERSION,\n type RunRecord,\n} from \"@mcmcjs/core\";\nimport type { FitResult, FitRunner } from \"@mcmcjs/engine\";\nimport { driverPath, lastJsonLine, sha256, toStage } from \"./runner-common\";\n\nexport interface FitIo {\n /** Spawns the Julia process; injectable so runFit is testable without Julia. */\n spawn: FitRunner;\n /** The managed Julia project directory passed as --project. */\n projectDir: string;\n /** Where the samples file is written. */\n outPath: string;\n tmpDir?: string;\n}\n\n/** Runs one inference for a resolved spec on a resolved runtime invocation. */\nexport async function runFit(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: FitIo,\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n const runtimeRequested = spec.backend.version;\n\n const tmp = io.tmpDir ?? mkdtempSync(join(tmpdir(), \"mcmcjs-fit-\"));\n const requestPath = join(tmp, \"request.json\");\n writeFileSync(\n requestPath,\n JSON.stringify({\n schema_version: spec.schema_version,\n backend: { id: spec.backend.id },\n model: { file: spec.modelPath, entry: spec.model.entry },\n data: spec.data,\n sampler: spec.sampler,\n seed: spec.seed,\n out: io.outPath,\n }),\n );\n\n const args = [\n ...resolved.args,\n \"--startup-file=no\",\n `--project=${io.projectDir}`,\n driverPath(),\n requestPath,\n ];\n const { stdout, stderr, code } = await io.spawn(resolved.command, args);\n const elapsedMs = Math.round(performance.now() - start);\n\n if (code !== 0 || !existsSync(io.outPath)) {\n const failure = lastJsonLine(stderr);\n const stage = toStage(failure?.stage);\n const error =\n (failure?.error as string) ??\n stderr.trim().split(\"\\n\").pop() ??\n `julia exited with code ${code}`;\n return { status: \"error\", runtimeRequested, elapsedMs, stage, error };\n }\n\n try {\n parseSamples(readFileSync(io.outPath, \"utf8\"));\n } catch (error) {\n return {\n status: \"error\",\n runtimeRequested,\n elapsedMs,\n stage: \"write\",\n error: `samples file did not parse: ${(error as Error).message}`,\n };\n }\n\n const provenance = lastJsonLine(stdout);\n const julia = provenance?.julia_version as string | undefined;\n const record: RunRecord = {\n schema_version: RUN_RECORD_SCHEMA_VERSION,\n spec_hash: spec.specHash,\n seed: spec.seed,\n backend: { id: spec.backend.id, runtime: spec.backend.runtime },\n runtime: { requested: runtimeRequested, actual: julia, path: resolved.command },\n manifest_sha256: provenance?.manifest_sha256 as string | undefined,\n packages: provenance?.packages as Record<string, string> | undefined,\n model_sha256: existsSync(spec.modelPath)\n ? sha256(readFileSync(spec.modelPath, \"utf8\"))\n : undefined,\n data_sha256: sha256(canonicalJson(spec.data)),\n samples_file: io.outPath,\n started_at: startedAt,\n elapsed_ms: elapsedMs,\n };\n writeFileSync(`${io.outPath}.run.json`, `${JSON.stringify(record, null, 2)}\\n`);\n\n return {\n status: \"ok\",\n samplesFile: io.outPath,\n runtimeRequested,\n runtimeActual: julia,\n elapsedMs,\n };\n}\n","import { createHash } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { FitResult } from \"@mcmcjs/engine\";\n\n/** Path to the shipped Julia driver, resolved next to this module in dist/. */\nexport function driverPath(): string {\n return join(dirname(fileURLToPath(import.meta.url)), \"driver.jl\");\n}\n\nexport function sha256(text: string): string {\n return createHash(\"sha256\").update(text).digest(\"hex\");\n}\n\n/** Parses the last JSON-object line of text (the driver's provenance or error line). */\nexport function lastJsonLine(text: string): Record<string, unknown> | undefined {\n for (const line of text.trimEnd().split(\"\\n\").reverse()) {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"{\")) continue;\n try {\n return JSON.parse(trimmed) as Record<string, unknown>;\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\nconst STAGES = new Set<NonNullable<FitResult[\"stage\"]>>([\n \"compile\",\n \"sample\",\n \"load_samples\",\n \"predict\",\n \"write\",\n \"spawn\",\n]);\n\n/** Narrows a driver-reported stage string to the known set. */\nexport function toStage(value: unknown): FitResult[\"stage\"] {\n return typeof value === \"string\" && STAGES.has(value as NonNullable<FitResult[\"stage\"]>)\n ? (value as FitResult[\"stage\"])\n : undefined;\n}\n","import { existsSync, mkdtempSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n canonicalJson,\n parseSamples,\n type ResolvedSpec,\n RUN_RECORD_SCHEMA_VERSION,\n type RunRecord,\n} from \"@mcmcjs/core\";\nimport type { FitResult, FitRunner } from \"@mcmcjs/engine\";\nimport { driverPath, lastJsonLine, sha256, toStage } from \"./runner-common\";\n\nexport interface PredictIo {\n /** Spawns the Julia process; injectable so runPredict is testable without Julia. */\n spawn: FitRunner;\n projectDir: string;\n /** Where the posterior-predictive samples file is written. */\n outPath: string;\n /** The posterior samples file fed to prediction. */\n samplesPath: string;\n tmpDir?: string;\n}\n\n/** The prediction data: [data] with [predict].data overrides, target outcomes blanked to nulls. */\nexport function predictData(spec: ResolvedSpec): Record<string, unknown> {\n const predict = spec.predict;\n if (!predict) throw new Error(\"spec has no [predict] block\");\n const data: Record<string, unknown> = { ...spec.data, ...(predict.data ?? {}) };\n // Blank a target to null, preserving array shape so the driver maps it to a\n // matching shape of `missing` (a multidimensional outcome stays nested).\n const blank = (value: unknown): unknown => (Array.isArray(value) ? value.map(blank) : null);\n for (const target of predict.targets) {\n data[target] = blank(data[target]);\n }\n return data;\n}\n\n/** Draws posterior-predictive samples from a fitted model and its posterior samples file. */\nexport async function runPredict(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: PredictIo,\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n const runtimeRequested = spec.backend.version;\n const data = predictData(spec);\n\n const tmp = io.tmpDir ?? mkdtempSync(join(tmpdir(), \"mcmcjs-predict-\"));\n const requestPath = join(tmp, \"request.json\");\n writeFileSync(\n requestPath,\n JSON.stringify({\n mode: \"predict\",\n schema_version: spec.schema_version,\n backend: { id: spec.backend.id },\n model: { file: spec.modelPath, entry: spec.model.entry },\n data,\n predict: { targets: spec.predict?.targets ?? [] },\n samples: io.samplesPath,\n seed: spec.seed,\n out: io.outPath,\n }),\n );\n\n const args = [\n ...resolved.args,\n \"--startup-file=no\",\n `--project=${io.projectDir}`,\n driverPath(),\n requestPath,\n ];\n const { stdout, stderr, code } = await io.spawn(resolved.command, args);\n const elapsedMs = Math.round(performance.now() - start);\n\n if (code !== 0 || !existsSync(io.outPath)) {\n const failure = lastJsonLine(stderr);\n const error =\n (failure?.error as string) ??\n stderr.trim().split(\"\\n\").pop() ??\n `julia exited with code ${code}`;\n return { status: \"error\", runtimeRequested, elapsedMs, stage: toStage(failure?.stage), error };\n }\n\n try {\n parseSamples(readFileSync(io.outPath, \"utf8\"));\n } catch (error) {\n return {\n status: \"error\",\n runtimeRequested,\n elapsedMs,\n stage: \"write\",\n error: `samples file did not parse: ${(error as Error).message}`,\n };\n }\n\n const provenance = lastJsonLine(stdout);\n const julia = provenance?.julia_version as string | undefined;\n const record: RunRecord = {\n schema_version: RUN_RECORD_SCHEMA_VERSION,\n spec_hash: spec.specHash,\n seed: spec.seed,\n backend: { id: spec.backend.id, runtime: spec.backend.runtime },\n runtime: { requested: runtimeRequested, actual: julia, path: resolved.command },\n manifest_sha256: provenance?.manifest_sha256 as string | undefined,\n packages: provenance?.packages as Record<string, string> | undefined,\n model_sha256: existsSync(spec.modelPath)\n ? sha256(readFileSync(spec.modelPath, \"utf8\"))\n : undefined,\n data_sha256: sha256(canonicalJson(data)),\n posterior_samples: io.samplesPath,\n posterior_samples_sha256: existsSync(io.samplesPath)\n ? sha256(readFileSync(io.samplesPath, \"utf8\"))\n : undefined,\n samples_file: io.outPath,\n started_at: startedAt,\n elapsed_ms: elapsedMs,\n };\n writeFileSync(`${io.outPath}.run.json`, `${JSON.stringify(record, null, 2)}\\n`);\n\n return {\n status: \"ok\",\n samplesFile: io.outPath,\n runtimeRequested,\n runtimeActual: julia,\n elapsedMs,\n };\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { type CommandRunner, createRunner } from \"@mcmcjs/engine\";\n\nconst PACKAGES = [\n \"Turing\",\n \"MCMCChains\",\n \"JuliaBUGS\",\n \"AdvancedHMC\",\n \"ForwardDiff\",\n \"JSON\",\n \"StableRNGs\",\n];\n\n/** The per-user directory holding the managed Julia project (Project + Manifest). */\nexport function managedProjectDir(): string {\n const base = process.env.XDG_DATA_HOME || join(homedir(), \".local\", \"share\");\n return join(base, \"mcmcjs\", \"julia\", \"env\");\n}\n\n// Records the package set a managed dir was provisioned with, so an env from an\n// older package set is healed (Pkg.add is additive) rather than left incomplete.\nfunction sentinelPath(dir: string): string {\n return join(dir, \".mcmcjs-packages.json\");\n}\n\nfunction provisioned(dir: string): boolean {\n try {\n return readFileSync(sentinelPath(dir), \"utf8\").trim() === JSON.stringify([...PACKAGES].sort());\n } catch {\n return false;\n }\n}\n\n/** Whether the managed project is present and provisioned with the current package set. */\nexport function managedProjectReady(dir: string = managedProjectDir()): boolean {\n return existsSync(join(dir, \"Project.toml\")) && provisioned(dir);\n}\n\n/**\n * Ensures the managed Julia project exists with the inference packages installed.\n * Idempotent: returns immediately when already provisioned with the current set,\n * otherwise adds (and precompiles) the missing packages. The first run resolves\n * and precompiles the project, which can take several minutes.\n */\nexport async function ensureProject(\n juliaBin: string,\n run: CommandRunner = createRunner(30 * 60_000),\n dir: string = managedProjectDir(),\n): Promise<string> {\n if (managedProjectReady(dir)) return dir;\n mkdirSync(dir, { recursive: true });\n const code = `using Pkg; Pkg.add(${JSON.stringify(PACKAGES)}); Pkg.precompile()`;\n await run(juliaBin, [\"--startup-file=no\", `--project=${dir}`, \"-e\", code]);\n writeFileSync(sentinelPath(dir), JSON.stringify([...PACKAGES].sort()));\n return dir;\n}\n","import { join } from \"node:path\";\nimport type { ResolvedSpec } from \"@mcmcjs/core\";\nimport type { FitResult, FitRunner } from \"@mcmcjs/engine\";\nimport { runFit } from \"./fit\";\n\nexport interface MatrixEntry {\n version: string;\n status: \"ok\" | \"error\";\n samplesFile?: string;\n runtimeActual?: string;\n elapsedMs: number;\n stage?: FitResult[\"stage\"];\n error?: string;\n}\n\nexport interface MatrixResult {\n entries: MatrixEntry[];\n /** True only when every requested version ran and succeeded. */\n ok: boolean;\n}\n\nexport interface MatrixIo {\n spawn: FitRunner;\n projectDir: string;\n /** Directory the per-version samples files are written into. */\n outDir: string;\n /** Resolves a version/channel to a concrete invocation; injectable for tests. */\n resolve: (version: string) => Promise<{ command: string; args: string[] }>;\n /** Continue after a version fails instead of stopping. */\n keepGoing?: boolean;\n}\n\n/** Runs the same spec across several Julia versions, one samples file per version. */\nexport async function runMatrix(\n spec: ResolvedSpec,\n versions: string[],\n io: MatrixIo,\n): Promise<MatrixResult> {\n const entries: MatrixEntry[] = [];\n for (const version of versions) {\n let entry: MatrixEntry;\n try {\n const resolved = await io.resolve(version);\n const versioned = { ...spec, backend: { ...spec.backend, version } };\n const result = await runFit(versioned, resolved, {\n spawn: io.spawn,\n projectDir: io.projectDir,\n outPath: join(io.outDir, `${version}.samples.json`),\n });\n entry = {\n version,\n status: result.status,\n samplesFile: result.samplesFile,\n runtimeActual: result.runtimeActual,\n elapsedMs: result.elapsedMs,\n stage: result.stage,\n error: result.error,\n };\n } catch (error) {\n entry = { version, status: \"error\", elapsedMs: 0, error: (error as Error).message };\n }\n entries.push(entry);\n if (entry.status === \"error\" && !io.keepGoing) break;\n }\n return {\n entries,\n ok: entries.length === versions.length && entries.every((e) => e.status === \"ok\"),\n };\n}\n","import { type DoctorReport, runDoctor } from \"./doctor\";\nimport { type CommandRunner, createRunner, type ToolInfo } from \"./environment\";\n\n/** The official juliaup install script, piped to a shell by the install step. */\nconst JULIAUP_INSTALL_URL = \"https://install.julialang.org\";\n\n/** An executable and its arguments, run directly (no shell word-splitting). */\nexport interface InstallCommand {\n command: string;\n args: string[];\n}\n\n/**\n * The command that installs juliaup on the given platform, or null when\n * automatic install is not yet supported there.\n */\nexport function juliaupInstallCommand(platform: NodeJS.Platform): InstallCommand | null {\n if (platform === \"win32\") {\n // TODO: install juliaup on Windows via winget or the Microsoft Store.\n return null;\n }\n return { command: \"sh\", args: [\"-c\", `curl -fsSL ${JULIAUP_INSTALL_URL} | sh -s -- --yes`] };\n}\n\n/** A single provisioning step needed to make the toolchain ready. */\nexport interface SetupStep {\n tool: \"juliaup\" | \"julia\";\n /** A short description of what the step does. */\n label: string;\n /** The command to run, or null when the step cannot be performed automatically. */\n command: InstallCommand | null;\n}\n\n/** The ordered steps needed to reach a ready toolchain, given the current state. */\nexport function planSetup(report: DoctorReport, platform: NodeJS.Platform): SetupStep[] {\n if (report.julia.found) return [];\n if (report.juliaup.found) {\n return [\n {\n tool: \"julia\",\n label: \"install the latest stable Julia via juliaup\",\n command: { command: report.juliaup.path ?? \"juliaup\", args: [\"add\", \"release\"] },\n },\n ];\n }\n return [\n {\n tool: \"juliaup\",\n label: \"install juliaup (this also installs Julia)\",\n command: juliaupInstallCommand(platform),\n },\n ];\n}\n\nexport type StepStatus = \"ran\" | \"skipped\" | \"failed\" | \"unsupported\";\n\nexport interface SetupStepResult extends SetupStep {\n status: StepStatus;\n /** Error detail when the step failed. */\n detail?: string;\n}\n\nexport interface SetupResult {\n juliaup: ToolInfo;\n julia: ToolInfo;\n /** True when Julia is available after setup. */\n ready: boolean;\n steps: SetupStepResult[];\n}\n\nexport interface SetupOptions {\n /** Runs detection commands. Injectable for tests. */\n runner?: CommandRunner;\n /** Runs install steps, which may take several minutes. Injectable for tests. */\n installer?: CommandRunner;\n /** Target platform; defaults to the current process platform. */\n platform?: NodeJS.Platform;\n /** Plan the steps but do not run them. */\n dryRun?: boolean;\n}\n\n/** Installs the Julia toolchain (juliaup and Julia) needed for inference. */\nexport async function runSetup(options: SetupOptions = {}): Promise<SetupResult> {\n const {\n runner,\n installer = createRunner(15 * 60_000),\n platform = process.platform,\n dryRun = false,\n } = options;\n\n const before = await runDoctor(runner);\n if (before.ready) return { ...before, steps: [] };\n\n const plan = planSetup(before, platform);\n\n if (dryRun) {\n return {\n ...before,\n steps: plan.map((step) => ({ ...step, status: step.command ? \"skipped\" : \"unsupported\" })),\n };\n }\n\n const steps: SetupStepResult[] = [];\n for (const step of plan) {\n if (!step.command) {\n steps.push({ ...step, status: \"unsupported\" });\n continue;\n }\n try {\n await installer(step.command.command, step.command.args);\n steps.push({ ...step, status: \"ran\" });\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n steps.push({ ...step, status: \"failed\", detail });\n }\n }\n\n const after = await runDoctor(runner);\n return { juliaup: after.juliaup, julia: after.julia, ready: after.ready, steps };\n}\n","import type { CommandRunner, RuntimeVersion } from \"@mcmcjs/engine\";\n\ninterface ChannelInfo {\n Name: string;\n File: string;\n Args?: string[];\n Version?: string;\n Arch?: string;\n}\n\ninterface Getconfig1 {\n DefaultChannel: ChannelInfo | null;\n OtherChannels: ChannelInfo[];\n}\n\nfunction parseChannel(value: unknown): ChannelInfo {\n const c = value as Record<string, unknown>;\n if (!c || typeof c.Name !== \"string\" || typeof c.File !== \"string\") {\n throw new Error(\"unexpected `juliaup api getconfig1` channel shape\");\n }\n return {\n Name: c.Name,\n File: c.File,\n Args: Array.isArray(c.Args) ? (c.Args as string[]) : undefined,\n Version: typeof c.Version === \"string\" ? c.Version : undefined,\n Arch: typeof c.Arch === \"string\" ? c.Arch : undefined,\n };\n}\n\nfunction parseGetconfig1(raw: string): Getconfig1 {\n let data: unknown;\n try {\n data = JSON.parse(raw);\n } catch {\n throw new Error(\"could not parse `juliaup api getconfig1` output as JSON\");\n }\n const obj = data as Record<string, unknown>;\n if (!obj || typeof obj !== \"object\" || !Array.isArray(obj.OtherChannels)) {\n throw new Error(\"unexpected `juliaup api getconfig1` output\");\n }\n return {\n DefaultChannel: obj.DefaultChannel ? parseChannel(obj.DefaultChannel) : null,\n OtherChannels: obj.OtherChannels.map(parseChannel),\n };\n}\n\nfunction toVersion(channel: ChannelInfo, isDefault: boolean): RuntimeVersion {\n return { id: channel.Name, version: channel.Version, path: channel.File || undefined, isDefault };\n}\n\n/** Lists the installed Julia versions, marking the default channel. */\nexport async function listVersions(bin: string, run: CommandRunner): Promise<RuntimeVersion[]> {\n const config = parseGetconfig1(await run(bin, [\"api\", \"getconfig1\"]));\n const versions: RuntimeVersion[] = [];\n if (config.DefaultChannel) versions.push(toVersion(config.DefaultChannel, true));\n for (const channel of config.OtherChannels) versions.push(toVersion(channel, false));\n return versions;\n}\n\nexport async function addVersion(\n bin: string,\n channel: string,\n opts: { default?: boolean },\n run: CommandRunner,\n): Promise<void> {\n await run(bin, [\"add\", channel]);\n if (opts.default) await run(bin, [\"default\", channel]);\n}\n\nexport async function removeVersion(\n bin: string,\n channel: string,\n run: CommandRunner,\n): Promise<void> {\n await run(bin, [\"remove\", channel]);\n}\n\nexport async function setDefaultVersion(\n bin: string,\n channel: string,\n run: CommandRunner,\n): Promise<void> {\n await run(bin, [\"default\", channel]);\n}\n\nexport async function updateVersion(\n bin: string,\n channel: string | undefined,\n run: CommandRunner,\n): Promise<void> {\n await run(bin, channel ? [\"update\", channel] : [\"update\"]);\n}\n\nexport async function gcVersions(bin: string, run: CommandRunner): Promise<void> {\n await run(bin, [\"gc\"]);\n}\n\n/** Resolves a channel to a concrete invocation, preferring its absolute binary path. */\nexport async function resolveVersion(\n bin: string,\n channel: string,\n run: CommandRunner,\n): Promise<{ command: string; args: string[] }> {\n const config = parseGetconfig1(await run(bin, [\"api\", \"getconfig1\"]));\n const all = config.DefaultChannel\n ? [config.DefaultChannel, ...config.OtherChannels]\n : config.OtherChannels;\n const match = all.find((c) => c.Name === channel);\n if (!match?.File) {\n throw new Error(\n `Julia version \"${channel}\" is not installed. Add it with: mcmc julia version add ${channel}`,\n );\n }\n return { command: match.File, args: match.Args ?? [] };\n}\n\n/** Throws with an actionable message if any requested channel is not installed. */\nexport function assertVersionsInstalled(channels: string[], installed: RuntimeVersion[]): void {\n const have = new Set(installed.map((v) => v.id));\n const missing = channels.filter((c) => !have.has(c));\n if (missing.length > 0) {\n const fixes = missing.map((m) => `mcmc julia version add ${m}`).join(\"; \");\n throw new Error(\n `Julia version(s) not installed: ${missing.join(\", \")}. Install with: ${fixes}`,\n );\n }\n}\n"],"mappings":"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","names":["createRunner","join","join","join","existsSync","mkdtempSync","readFileSync","writeFileSync","tmpdir","join","canonicalJson","parseSamples","RUN_RECORD_SCHEMA_VERSION","mkdtempSync","join","tmpdir","writeFileSync","existsSync","parseSamples","readFileSync","RUN_RECORD_SCHEMA_VERSION","canonicalJson","existsSync","readFileSync","writeFileSync","homedir","join","createRunner","join","join","createRunner"]}
1
+ {"version":3,"sources":["../src/environment.ts","../src/doctor.ts","../src/engine.ts","../src/fit.ts","../src/runner-common.ts","../src/predict.ts","../src/project.ts","../src/run-matrix.ts","../src/setup.ts","../src/versions.ts"],"sourcesContent":["import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { type CommandRunner, createRunner, type ToolInfo } from \"@mcmcjs/engine\";\n\nexport type { CommandRunner, ToolInfo } from \"@mcmcjs/engine\";\nexport { createRunner } from \"@mcmcjs/engine\";\n\nconst defaultRunner = createRunner();\n\n// juliaup installs its shims here; we also fall back to whatever is on PATH.\nfunction candidates(binary: string): string[] {\n return [join(homedir(), \".juliaup\", \"bin\", binary), binary];\n}\n\nasync function detect(\n binary: string,\n parseVersion: (stdout: string) => string | undefined,\n runner: CommandRunner,\n): Promise<ToolInfo> {\n for (const path of candidates(binary)) {\n try {\n const version = parseVersion(await runner(path, [\"--version\"]));\n if (version) return { found: true, version, path };\n } catch {\n // not available at this path; try the next candidate\n }\n }\n return { found: false };\n}\n\nconst versionNumber = (stdout: string): string | undefined => stdout.match(/(\\d+\\.\\d+\\.\\d+)/)?.[1];\n\n/** Detects the Julia runtime via `julia --version`. */\nexport function detectJulia(runner: CommandRunner = defaultRunner): Promise<ToolInfo> {\n return detect(\"julia\", versionNumber, runner);\n}\n\n/** Detects the juliaup version manager via `juliaup --version`. */\nexport function detectJuliaup(runner: CommandRunner = defaultRunner): Promise<ToolInfo> {\n return detect(\"juliaup\", versionNumber, runner);\n}\n","import { type CommandRunner, detectJulia, detectJuliaup, type ToolInfo } from \"./environment\";\n\n/** A summary of the Julia toolchain available for inference. */\nexport interface DoctorReport {\n juliaup: ToolInfo;\n julia: ToolInfo;\n /** True when Julia itself is available (the minimum needed to run inference). */\n ready: boolean;\n}\n\n/** Detects the installed Julia toolchain and reports whether inference can run. */\nexport async function runDoctor(runner?: CommandRunner): Promise<DoctorReport> {\n const [juliaup, julia] = await Promise.all([detectJuliaup(runner), detectJulia(runner)]);\n return { juliaup, julia, ready: julia.found };\n}\n","import type { Engine, EngineContext, HealthReport } from \"@mcmcjs/engine\";\nimport { runDoctor } from \"./doctor\";\n\nconst JULIAUP_URL = \"https://github.com/JuliaLang/juliaup\";\n\nexport const juliaEngine: Engine = {\n id: \"julia\",\n displayName: \"Julia\",\n capabilities: { setup: true, versions: true, fit: true, predict: true },\n async doctor(ctx: EngineContext): Promise<HealthReport> {\n const report = await runDoctor(ctx.run);\n return {\n engineId: \"julia\",\n ready: report.ready,\n tools: [\n { name: \"juliaup\", ...report.juliaup },\n { name: \"julia\", ...report.julia },\n ],\n hint: report.ready\n ? undefined\n : `Julia not found. Install it with juliaup (${JULIAUP_URL}), or run \\`mcmc setup\\`.`,\n };\n },\n};\n","import { existsSync, mkdtempSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n canonicalJson,\n parseSamples,\n type ResolvedSpec,\n RUN_RECORD_SCHEMA_VERSION,\n type RunRecord,\n} from \"@mcmcjs/core\";\nimport type { FitResult, FitRunner } from \"@mcmcjs/engine\";\nimport { driverPath, lastJsonLine, sha256, toStage } from \"./runner-common\";\n\nexport interface FitIo {\n /** Spawns the Julia process; injectable so runFit is testable without Julia. */\n spawn: FitRunner;\n /** The managed Julia project directory passed as --project. */\n projectDir: string;\n /** Where the samples file is written. */\n outPath: string;\n tmpDir?: string;\n}\n\n/** Runs one inference for a resolved spec on a resolved runtime invocation. */\nexport async function runFit(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: FitIo,\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n const runtimeRequested = spec.backend.version;\n\n const tmp = io.tmpDir ?? mkdtempSync(join(tmpdir(), \"mcmcjs-fit-\"));\n const requestPath = join(tmp, \"request.json\");\n writeFileSync(\n requestPath,\n JSON.stringify({\n schema_version: spec.schema_version,\n backend: { id: spec.backend.id },\n model: { file: spec.modelPath, entry: spec.model.entry },\n data: spec.data,\n sampler: spec.sampler,\n seed: spec.seed,\n out: io.outPath,\n }),\n );\n\n const args = [\n ...resolved.args,\n \"--startup-file=no\",\n `--project=${io.projectDir}`,\n driverPath(),\n requestPath,\n ];\n const { stdout, stderr, code } = await io.spawn(resolved.command, args);\n const elapsedMs = Math.round(performance.now() - start);\n\n if (code !== 0 || !existsSync(io.outPath)) {\n const failure = lastJsonLine(stderr);\n const stage = toStage(failure?.stage);\n const error =\n (failure?.error as string) ??\n stderr.trim().split(\"\\n\").pop() ??\n `julia exited with code ${code}`;\n return { status: \"error\", runtimeRequested, elapsedMs, stage, error };\n }\n\n try {\n parseSamples(readFileSync(io.outPath, \"utf8\"));\n } catch (error) {\n return {\n status: \"error\",\n runtimeRequested,\n elapsedMs,\n stage: \"write\",\n error: `samples file did not parse: ${(error as Error).message}`,\n };\n }\n\n const provenance = lastJsonLine(stdout);\n const julia = provenance?.julia_version as string | undefined;\n const record: RunRecord = {\n schema_version: RUN_RECORD_SCHEMA_VERSION,\n spec_hash: spec.specHash,\n seed: spec.seed,\n backend: { id: spec.backend.id, runtime: spec.backend.runtime },\n runtime: { requested: runtimeRequested, actual: julia, path: resolved.command },\n manifest_sha256: provenance?.manifest_sha256 as string | undefined,\n packages: provenance?.packages as Record<string, string> | undefined,\n model_sha256: existsSync(spec.modelPath)\n ? sha256(readFileSync(spec.modelPath, \"utf8\"))\n : undefined,\n data_sha256: sha256(canonicalJson(spec.data)),\n samples_file: io.outPath,\n started_at: startedAt,\n elapsed_ms: elapsedMs,\n };\n writeFileSync(`${io.outPath}.run.json`, `${JSON.stringify(record, null, 2)}\\n`);\n\n return {\n status: \"ok\",\n samplesFile: io.outPath,\n runtimeRequested,\n runtimeActual: julia,\n elapsedMs,\n };\n}\n","import { createHash } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { FitResult } from \"@mcmcjs/engine\";\n\n/** Path to the shipped Julia driver, resolved next to this module in dist/. */\nexport function driverPath(): string {\n return join(dirname(fileURLToPath(import.meta.url)), \"driver.jl\");\n}\n\nexport function sha256(text: string): string {\n return createHash(\"sha256\").update(text).digest(\"hex\");\n}\n\n/** Parses the last JSON-object line of text (the driver's provenance or error line). */\nexport function lastJsonLine(text: string): Record<string, unknown> | undefined {\n for (const line of text.trimEnd().split(\"\\n\").reverse()) {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"{\")) continue;\n try {\n return JSON.parse(trimmed) as Record<string, unknown>;\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\nconst STAGES = new Set<NonNullable<FitResult[\"stage\"]>>([\n \"compile\",\n \"sample\",\n \"load_samples\",\n \"predict\",\n \"write\",\n \"spawn\",\n]);\n\n/** Narrows a driver-reported stage string to the known set. */\nexport function toStage(value: unknown): FitResult[\"stage\"] {\n return typeof value === \"string\" && STAGES.has(value as NonNullable<FitResult[\"stage\"]>)\n ? (value as FitResult[\"stage\"])\n : undefined;\n}\n","import { existsSync, mkdtempSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n canonicalJson,\n parseSamples,\n type ResolvedSpec,\n RUN_RECORD_SCHEMA_VERSION,\n type RunRecord,\n} from \"@mcmcjs/core\";\nimport type { FitResult, FitRunner } from \"@mcmcjs/engine\";\nimport { driverPath, lastJsonLine, sha256, toStage } from \"./runner-common\";\n\nexport interface PredictIo {\n /** Spawns the Julia process; injectable so runPredict is testable without Julia. */\n spawn: FitRunner;\n projectDir: string;\n /** Where the posterior-predictive samples file is written. */\n outPath: string;\n /** The posterior samples file fed to prediction. */\n samplesPath: string;\n tmpDir?: string;\n}\n\n/** The prediction data: [data] with [predict].data overrides, target outcomes blanked to nulls. */\nexport function predictData(spec: ResolvedSpec): Record<string, unknown> {\n const predict = spec.predict;\n if (!predict) throw new Error(\"spec has no [predict] block\");\n const data: Record<string, unknown> = { ...spec.data, ...(predict.data ?? {}) };\n // Blank a target to null, preserving array shape so the driver maps it to a\n // matching shape of `missing` (a multidimensional outcome stays nested).\n const blank = (value: unknown): unknown => (Array.isArray(value) ? value.map(blank) : null);\n for (const target of predict.targets) {\n data[target] = blank(data[target]);\n }\n return data;\n}\n\n/** Draws posterior-predictive samples from a fitted model and its posterior samples file. */\nexport async function runPredict(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: PredictIo,\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n const runtimeRequested = spec.backend.version;\n const data = predictData(spec);\n\n const tmp = io.tmpDir ?? mkdtempSync(join(tmpdir(), \"mcmcjs-predict-\"));\n const requestPath = join(tmp, \"request.json\");\n writeFileSync(\n requestPath,\n JSON.stringify({\n mode: \"predict\",\n schema_version: spec.schema_version,\n backend: { id: spec.backend.id },\n model: { file: spec.modelPath, entry: spec.model.entry },\n data,\n predict: { targets: spec.predict?.targets ?? [] },\n samples: io.samplesPath,\n seed: spec.seed,\n out: io.outPath,\n }),\n );\n\n const args = [\n ...resolved.args,\n \"--startup-file=no\",\n `--project=${io.projectDir}`,\n driverPath(),\n requestPath,\n ];\n const { stdout, stderr, code } = await io.spawn(resolved.command, args);\n const elapsedMs = Math.round(performance.now() - start);\n\n if (code !== 0 || !existsSync(io.outPath)) {\n const failure = lastJsonLine(stderr);\n const error =\n (failure?.error as string) ??\n stderr.trim().split(\"\\n\").pop() ??\n `julia exited with code ${code}`;\n return { status: \"error\", runtimeRequested, elapsedMs, stage: toStage(failure?.stage), error };\n }\n\n try {\n parseSamples(readFileSync(io.outPath, \"utf8\"));\n } catch (error) {\n return {\n status: \"error\",\n runtimeRequested,\n elapsedMs,\n stage: \"write\",\n error: `samples file did not parse: ${(error as Error).message}`,\n };\n }\n\n const provenance = lastJsonLine(stdout);\n const julia = provenance?.julia_version as string | undefined;\n const record: RunRecord = {\n schema_version: RUN_RECORD_SCHEMA_VERSION,\n spec_hash: spec.specHash,\n seed: spec.seed,\n backend: { id: spec.backend.id, runtime: spec.backend.runtime },\n runtime: { requested: runtimeRequested, actual: julia, path: resolved.command },\n manifest_sha256: provenance?.manifest_sha256 as string | undefined,\n packages: provenance?.packages as Record<string, string> | undefined,\n model_sha256: existsSync(spec.modelPath)\n ? sha256(readFileSync(spec.modelPath, \"utf8\"))\n : undefined,\n data_sha256: sha256(canonicalJson(data)),\n posterior_samples: io.samplesPath,\n posterior_samples_sha256: existsSync(io.samplesPath)\n ? sha256(readFileSync(io.samplesPath, \"utf8\"))\n : undefined,\n samples_file: io.outPath,\n started_at: startedAt,\n elapsed_ms: elapsedMs,\n };\n writeFileSync(`${io.outPath}.run.json`, `${JSON.stringify(record, null, 2)}\\n`);\n\n return {\n status: \"ok\",\n samplesFile: io.outPath,\n runtimeRequested,\n runtimeActual: julia,\n elapsedMs,\n };\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { type CommandRunner, createRunner } from \"@mcmcjs/engine\";\n\nconst PACKAGES = [\n \"Turing\",\n \"FlexiChains\",\n \"DimensionalData\",\n \"MCMCChains\",\n \"JuliaBUGS\",\n \"AdvancedHMC\",\n \"ForwardDiff\",\n \"JSON\",\n \"StableRNGs\",\n];\n\n/** The per-user directory holding the managed Julia project (Project + Manifest). */\nexport function managedProjectDir(): string {\n const base = process.env.XDG_DATA_HOME || join(homedir(), \".local\", \"share\");\n return join(base, \"mcmcjs\", \"julia\", \"env\");\n}\n\n// Records the package set a managed dir was provisioned with, so an env from an\n// older package set is healed (Pkg.add is additive) rather than left incomplete.\nfunction sentinelPath(dir: string): string {\n return join(dir, \".mcmcjs-packages.json\");\n}\n\nfunction provisioned(dir: string): boolean {\n try {\n return readFileSync(sentinelPath(dir), \"utf8\").trim() === JSON.stringify([...PACKAGES].sort());\n } catch {\n return false;\n }\n}\n\n/** Whether the managed project is present and provisioned with the current package set. */\nexport function managedProjectReady(dir: string = managedProjectDir()): boolean {\n return existsSync(join(dir, \"Project.toml\")) && provisioned(dir);\n}\n\n/**\n * Ensures the managed Julia project exists with the inference packages installed.\n * Idempotent: returns immediately when already provisioned with the current set,\n * otherwise adds (and precompiles) the missing packages. The first run resolves\n * and precompiles the project, which can take several minutes.\n */\nexport async function ensureProject(\n juliaBin: string,\n run: CommandRunner = createRunner(30 * 60_000),\n dir: string = managedProjectDir(),\n): Promise<string> {\n if (managedProjectReady(dir)) return dir;\n mkdirSync(dir, { recursive: true });\n const code = `using Pkg; Pkg.add(${JSON.stringify(PACKAGES)}); Pkg.precompile()`;\n await run(juliaBin, [\"--startup-file=no\", `--project=${dir}`, \"-e\", code]);\n writeFileSync(sentinelPath(dir), JSON.stringify([...PACKAGES].sort()));\n return dir;\n}\n","import { join } from \"node:path\";\nimport type { ResolvedSpec } from \"@mcmcjs/core\";\nimport type { FitResult, FitRunner } from \"@mcmcjs/engine\";\nimport { runFit } from \"./fit\";\n\nexport interface MatrixEntry {\n version: string;\n status: \"ok\" | \"error\";\n samplesFile?: string;\n runtimeActual?: string;\n elapsedMs: number;\n stage?: FitResult[\"stage\"];\n error?: string;\n}\n\nexport interface MatrixResult {\n entries: MatrixEntry[];\n /** True only when every requested version ran and succeeded. */\n ok: boolean;\n}\n\nexport interface MatrixIo {\n spawn: FitRunner;\n projectDir: string;\n /** Directory the per-version samples files are written into. */\n outDir: string;\n /** Resolves a version/channel to a concrete invocation; injectable for tests. */\n resolve: (version: string) => Promise<{ command: string; args: string[] }>;\n /** Continue after a version fails instead of stopping. */\n keepGoing?: boolean;\n}\n\n/** Runs the same spec across several Julia versions, one samples file per version. */\nexport async function runMatrix(\n spec: ResolvedSpec,\n versions: string[],\n io: MatrixIo,\n): Promise<MatrixResult> {\n const entries: MatrixEntry[] = [];\n for (const version of versions) {\n let entry: MatrixEntry;\n try {\n const resolved = await io.resolve(version);\n const versioned = { ...spec, backend: { ...spec.backend, version } };\n const result = await runFit(versioned, resolved, {\n spawn: io.spawn,\n projectDir: io.projectDir,\n outPath: join(io.outDir, `${version}.samples.json`),\n });\n entry = {\n version,\n status: result.status,\n samplesFile: result.samplesFile,\n runtimeActual: result.runtimeActual,\n elapsedMs: result.elapsedMs,\n stage: result.stage,\n error: result.error,\n };\n } catch (error) {\n entry = { version, status: \"error\", elapsedMs: 0, error: (error as Error).message };\n }\n entries.push(entry);\n if (entry.status === \"error\" && !io.keepGoing) break;\n }\n return {\n entries,\n ok: entries.length === versions.length && entries.every((e) => e.status === \"ok\"),\n };\n}\n","import { type DoctorReport, runDoctor } from \"./doctor\";\nimport { type CommandRunner, createRunner, type ToolInfo } from \"./environment\";\n\n/** The official juliaup install script, piped to a shell by the install step. */\nconst JULIAUP_INSTALL_URL = \"https://install.julialang.org\";\n\n/** An executable and its arguments, run directly (no shell word-splitting). */\nexport interface InstallCommand {\n command: string;\n args: string[];\n}\n\n/**\n * The command that installs juliaup on the given platform, or null when\n * automatic install is not yet supported there.\n */\nexport function juliaupInstallCommand(platform: NodeJS.Platform): InstallCommand | null {\n if (platform === \"win32\") {\n // TODO: install juliaup on Windows via winget or the Microsoft Store.\n return null;\n }\n return { command: \"sh\", args: [\"-c\", `curl -fsSL ${JULIAUP_INSTALL_URL} | sh -s -- --yes`] };\n}\n\n/** A single provisioning step needed to make the toolchain ready. */\nexport interface SetupStep {\n tool: \"juliaup\" | \"julia\";\n /** A short description of what the step does. */\n label: string;\n /** The command to run, or null when the step cannot be performed automatically. */\n command: InstallCommand | null;\n}\n\n/** The ordered steps needed to reach a ready toolchain, given the current state. */\nexport function planSetup(report: DoctorReport, platform: NodeJS.Platform): SetupStep[] {\n if (report.julia.found) return [];\n if (report.juliaup.found) {\n return [\n {\n tool: \"julia\",\n label: \"install the latest stable Julia via juliaup\",\n command: { command: report.juliaup.path ?? \"juliaup\", args: [\"add\", \"release\"] },\n },\n ];\n }\n return [\n {\n tool: \"juliaup\",\n label: \"install juliaup (this also installs Julia)\",\n command: juliaupInstallCommand(platform),\n },\n ];\n}\n\nexport type StepStatus = \"ran\" | \"skipped\" | \"failed\" | \"unsupported\";\n\nexport interface SetupStepResult extends SetupStep {\n status: StepStatus;\n /** Error detail when the step failed. */\n detail?: string;\n}\n\nexport interface SetupResult {\n juliaup: ToolInfo;\n julia: ToolInfo;\n /** True when Julia is available after setup. */\n ready: boolean;\n steps: SetupStepResult[];\n}\n\nexport interface SetupOptions {\n /** Runs detection commands. Injectable for tests. */\n runner?: CommandRunner;\n /** Runs install steps, which may take several minutes. Injectable for tests. */\n installer?: CommandRunner;\n /** Target platform; defaults to the current process platform. */\n platform?: NodeJS.Platform;\n /** Plan the steps but do not run them. */\n dryRun?: boolean;\n}\n\n/** Installs the Julia toolchain (juliaup and Julia) needed for inference. */\nexport async function runSetup(options: SetupOptions = {}): Promise<SetupResult> {\n const {\n runner,\n installer = createRunner(15 * 60_000),\n platform = process.platform,\n dryRun = false,\n } = options;\n\n const before = await runDoctor(runner);\n if (before.ready) return { ...before, steps: [] };\n\n const plan = planSetup(before, platform);\n\n if (dryRun) {\n return {\n ...before,\n steps: plan.map((step) => ({ ...step, status: step.command ? \"skipped\" : \"unsupported\" })),\n };\n }\n\n const steps: SetupStepResult[] = [];\n for (const step of plan) {\n if (!step.command) {\n steps.push({ ...step, status: \"unsupported\" });\n continue;\n }\n try {\n await installer(step.command.command, step.command.args);\n steps.push({ ...step, status: \"ran\" });\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n steps.push({ ...step, status: \"failed\", detail });\n }\n }\n\n const after = await runDoctor(runner);\n return { juliaup: after.juliaup, julia: after.julia, ready: after.ready, steps };\n}\n","import type { CommandRunner, RuntimeVersion } from \"@mcmcjs/engine\";\n\ninterface ChannelInfo {\n Name: string;\n File: string;\n Args?: string[];\n Version?: string;\n Arch?: string;\n}\n\ninterface Getconfig1 {\n DefaultChannel: ChannelInfo | null;\n OtherChannels: ChannelInfo[];\n}\n\nfunction parseChannel(value: unknown): ChannelInfo {\n const c = value as Record<string, unknown>;\n if (!c || typeof c.Name !== \"string\" || typeof c.File !== \"string\") {\n throw new Error(\"unexpected `juliaup api getconfig1` channel shape\");\n }\n return {\n Name: c.Name,\n File: c.File,\n Args: Array.isArray(c.Args) ? (c.Args as string[]) : undefined,\n Version: typeof c.Version === \"string\" ? c.Version : undefined,\n Arch: typeof c.Arch === \"string\" ? c.Arch : undefined,\n };\n}\n\nfunction parseGetconfig1(raw: string): Getconfig1 {\n let data: unknown;\n try {\n data = JSON.parse(raw);\n } catch {\n throw new Error(\"could not parse `juliaup api getconfig1` output as JSON\");\n }\n const obj = data as Record<string, unknown>;\n if (!obj || typeof obj !== \"object\" || !Array.isArray(obj.OtherChannels)) {\n throw new Error(\"unexpected `juliaup api getconfig1` output\");\n }\n return {\n DefaultChannel: obj.DefaultChannel ? parseChannel(obj.DefaultChannel) : null,\n OtherChannels: obj.OtherChannels.map(parseChannel),\n };\n}\n\nfunction toVersion(channel: ChannelInfo, isDefault: boolean): RuntimeVersion {\n return { id: channel.Name, version: channel.Version, path: channel.File || undefined, isDefault };\n}\n\n/** Lists the installed Julia versions, marking the default channel. */\nexport async function listVersions(bin: string, run: CommandRunner): Promise<RuntimeVersion[]> {\n const config = parseGetconfig1(await run(bin, [\"api\", \"getconfig1\"]));\n const versions: RuntimeVersion[] = [];\n if (config.DefaultChannel) versions.push(toVersion(config.DefaultChannel, true));\n for (const channel of config.OtherChannels) versions.push(toVersion(channel, false));\n return versions;\n}\n\nexport async function addVersion(\n bin: string,\n channel: string,\n opts: { default?: boolean },\n run: CommandRunner,\n): Promise<void> {\n await run(bin, [\"add\", channel]);\n if (opts.default) await run(bin, [\"default\", channel]);\n}\n\nexport async function removeVersion(\n bin: string,\n channel: string,\n run: CommandRunner,\n): Promise<void> {\n await run(bin, [\"remove\", channel]);\n}\n\nexport async function setDefaultVersion(\n bin: string,\n channel: string,\n run: CommandRunner,\n): Promise<void> {\n await run(bin, [\"default\", channel]);\n}\n\nexport async function updateVersion(\n bin: string,\n channel: string | undefined,\n run: CommandRunner,\n): Promise<void> {\n await run(bin, channel ? [\"update\", channel] : [\"update\"]);\n}\n\nexport async function gcVersions(bin: string, run: CommandRunner): Promise<void> {\n await run(bin, [\"gc\"]);\n}\n\n/** Resolves a channel to a concrete invocation, preferring its absolute binary path. */\nexport async function resolveVersion(\n bin: string,\n channel: string,\n run: CommandRunner,\n): Promise<{ command: string; args: string[] }> {\n const config = parseGetconfig1(await run(bin, [\"api\", \"getconfig1\"]));\n const all = config.DefaultChannel\n ? [config.DefaultChannel, ...config.OtherChannels]\n : config.OtherChannels;\n const match = all.find((c) => c.Name === channel);\n if (!match?.File) {\n throw new Error(\n `Julia version \"${channel}\" is not installed. Add it with: mcmc julia version add ${channel}`,\n );\n }\n return { command: match.File, args: match.Args ?? [] };\n}\n\n/** Throws with an actionable message if any requested channel is not installed. */\nexport function assertVersionsInstalled(channels: string[], installed: RuntimeVersion[]): void {\n const have = new Set(installed.map((v) => v.id));\n const missing = channels.filter((c) => !have.has(c));\n if (missing.length > 0) {\n const fixes = missing.map((m) => `mcmc julia version add ${m}`).join(\"; \");\n throw new Error(\n `Julia version(s) not installed: ${missing.join(\", \")}. Install with: ${fixes}`,\n );\n }\n}\n"],"mappings":"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","names":["createRunner","join","join","join","existsSync","mkdtempSync","readFileSync","writeFileSync","tmpdir","join","canonicalJson","parseSamples","RUN_RECORD_SCHEMA_VERSION","mkdtempSync","join","tmpdir","writeFileSync","existsSync","parseSamples","readFileSync","RUN_RECORD_SCHEMA_VERSION","canonicalJson","existsSync","readFileSync","writeFileSync","homedir","join","createRunner","join","join","createRunner"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcmcjs/julia",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Julia toolchain detection and the inference runner for MCMC.js.",
5
5
  "keywords": [
6
6
  "mcmc",