@mcmcjs/julia 0.13.0 → 0.14.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/fitlib.jl CHANGED
@@ -5,6 +5,7 @@
5
5
  # chain type (FlexiChains), so a chain-type change is contained here.
6
6
  using JSON
7
7
  using Logging
8
+ import Distributed
8
9
  using Random
9
10
  using StableRNGs
10
11
  using Turing
@@ -23,6 +24,10 @@ import ReverseDiff
23
24
  import FlexiChains
24
25
  import DimensionalData
25
26
 
27
+ # Workers include this file to mirror the master's definitions (ModelData, the
28
+ # helpers a deserialized model may reference) when sampling MCMCDistributed.
29
+ const FITLIB_FILE = @__FILE__
30
+
26
31
  # AbstractMCMC reports sampling progress through ProgressLogging (reachable via
27
32
  # Turing's dependency, no extra package in the managed env).
28
33
  const ProgressLogging = Turing.AbstractMCMC.ProgressLogging
@@ -88,6 +93,22 @@ function Logging.handle_message(
88
93
  Logging.handle_message(logger.fallback, level, message, _module, group, id, file, line; kwargs...)
89
94
  end
90
95
 
96
+ # A Turing model file may declare the AD backend it needs by exporting, e.g.,
97
+ # `const MCMC_DEFAULTS = (; adtype = "mooncake")`. A spec or flag adtype wins;
98
+ # the model default fills in only when the request leaves adtype unset.
99
+ function apply_model_defaults(sampler, mod)
100
+ haskey(sampler, "adtype") && return sampler
101
+ # Only the gradient samplers take an AD backend.
102
+ get(sampler, "algorithm", "NUTS") in ("NUTS", "HMC", "HMCDA", "Gibbs", "External") ||
103
+ return sampler
104
+ Base.invokelatest(isdefined, mod, :MCMC_DEFAULTS) || return sampler
105
+ defaults = Base.invokelatest(getfield, mod, :MCMC_DEFAULTS)
106
+ hasproperty(defaults, :adtype) || return sampler
107
+ merged = copy(sampler)
108
+ merged["adtype"] = String(defaults.adtype)
109
+ return merged
110
+ end
111
+
91
112
  function build_adtype(name)
92
113
  name == "forwarddiff" && return Turing.ADTypes.AutoForwardDiff()
93
114
  name == "reversediff" && return Turing.ADTypes.AutoReverseDiff()
@@ -95,7 +116,7 @@ function build_adtype(name)
95
116
  error("unsupported adtype: $name")
96
117
  end
97
118
 
98
- function build_sampler(sampler, backend)
119
+ function build_sampler(sampler, backend, modelmod = nothing)
99
120
  algorithm = get(sampler, "algorithm", "NUTS")
100
121
  # Prior draws are iid: no warmup, no adaptation. The JuliaBUGS path samples
101
122
  # ancestrally (sample_bugs_prior) instead of going through a sampler object.
@@ -106,6 +127,10 @@ function build_sampler(sampler, backend)
106
127
  algorithm == "NUTS" || error("the juliabugs backend supports NUTS and Prior only")
107
128
  return AdvancedHMC.NUTS(adapt_delta), warmup
108
129
  end
130
+ algorithm == "MH" && return Turing.MH(), warmup
131
+ algorithm == "ESS" && return Turing.ESS(), warmup
132
+ algorithm == "SMC" && return Turing.SMC(), warmup
133
+ algorithm == "PG" && return Turing.PG(Int(sampler["particles"])), warmup
109
134
  adkw = haskey(sampler, "adtype") ? (; adtype = build_adtype(sampler["adtype"])) : (;)
110
135
  algorithm == "NUTS" && return Turing.NUTS(warmup, adapt_delta; adkw...), warmup
111
136
  algorithm == "HMC" &&
@@ -113,10 +138,42 @@ function build_sampler(sampler, backend)
113
138
  warmup
114
139
  algorithm == "HMCDA" &&
115
140
  return Turing.HMCDA(warmup, adapt_delta, Float64(sampler["lambda"]); adkw...), warmup
116
- algorithm == "MH" && return Turing.MH(), warmup
141
+ algorithm == "Gibbs" && return build_gibbs(sampler, adkw, warmup), warmup
142
+ if algorithm == "External"
143
+ modelmod === nothing && error("the External algorithm applies to Turing models only")
144
+ Base.invokelatest(isdefined, modelmod, :MCMC_SAMPLER) ||
145
+ error("algorithm External needs the model file to define MCMC_SAMPLER")
146
+ ext = Base.invokelatest(getfield, modelmod, :MCMC_SAMPLER)
147
+ return Turing.externalsampler(ext; adkw...), warmup
148
+ end
117
149
  error("unsupported sampler algorithm: $algorithm")
118
150
  end
119
151
 
152
+ # One Gibbs component: the block's variables get the block's sampler. A single
153
+ # variable keys by symbol, several by tuple, matching Turing's constructor.
154
+ function block_sampler(block, adkw, warmup)
155
+ algorithm = get(block, "algorithm", "NUTS")
156
+ adapt_delta = Float64(get(block, "adapt_delta", 0.8))
157
+ algorithm == "MH" && return Turing.MH()
158
+ algorithm == "ESS" && return Turing.ESS()
159
+ algorithm == "PG" && return Turing.PG(Int(block["particles"]))
160
+ algorithm == "NUTS" && return Turing.NUTS(warmup, adapt_delta; adkw...)
161
+ algorithm == "HMC" &&
162
+ return Turing.HMC(Float64(block["step_size"]), Int(block["leapfrog_steps"]); adkw...)
163
+ algorithm == "HMCDA" &&
164
+ return Turing.HMCDA(warmup, adapt_delta, Float64(block["lambda"]); adkw...)
165
+ error("unsupported Gibbs block algorithm: $algorithm")
166
+ end
167
+
168
+ function build_gibbs(sampler, adkw, warmup)
169
+ pairs = map(sampler["blocks"]) do block
170
+ vars = Symbol.(block["variables"])
171
+ key = length(vars) == 1 ? vars[1] : Tuple(vars)
172
+ key => block_sampler(block, adkw, warmup)
173
+ end
174
+ return Turing.Gibbs(pairs...)
175
+ end
176
+
120
177
  # Extra keyword arguments for AbstractMCMC.sample, from the request's sampler
121
178
  # table: thinning, burn-in for the non-adaptive samplers (NUTS and HMCDA discard
122
179
  # their own adaptation), and named starting values replicated across chains.
@@ -125,7 +182,23 @@ function sampling_kwargs(sampler, warmup, chains)
125
182
  thin = Int(get(sampler, "thin", 1))
126
183
  thin > 1 && (kw = merge(kw, (; thinning = thin)))
127
184
  algorithm = get(sampler, "algorithm", "NUTS")
128
- algorithm in ("MH", "HMC") && warmup > 0 && (kw = merge(kw, (; discard_initial = warmup)))
185
+ if algorithm in ("MH", "HMC", "ESS", "PG", "Gibbs", "External") && warmup > 0
186
+ kw = merge(kw, (; discard_initial = warmup))
187
+ end
188
+ # AdvancedHMC-style external samplers adapt only when told how many steps to
189
+ # use; without n_adapts a chain can freeze at its initial point.
190
+ if algorithm == "External" && warmup > 0
191
+ kw = merge(kw, (; n_adapts = warmup))
192
+ end
193
+ # NUTS/HMCDA blocks inside Gibbs adapt only through the sample-level nadapts
194
+ # keyword (the constructor's count is ignored there); without it the block
195
+ # never tunes its step size and can freeze.
196
+ if algorithm == "Gibbs" && warmup > 0
197
+ blocks = get(sampler, "blocks", Any[])
198
+ if any(get(b, "algorithm", "NUTS") in ("NUTS", "HMCDA") for b in blocks)
199
+ kw = merge(kw, (; nadapts = warmup))
200
+ end
201
+ end
129
202
  if haskey(sampler, "initial_params")
130
203
  nt = (; (Symbol(k) => narrow(v) for (k, v) in sampler["initial_params"])...)
131
204
  strategy = Turing.DynamicPPL.InitFromParams(nt)
@@ -327,14 +400,35 @@ end
327
400
  # the model methods are defined by `include` at runtime, so a plain call from
328
401
  # this (older) world would fail with "method too new". invokelatest fixes that.
329
402
  # Returns Turing's default chain type, a FlexiChain. With a callback, draws stream.
330
- function build_and_sample(entry, data, sampler, draws, chains, rng; callback = nothing, extra = (;))
403
+ function build_and_sample(
404
+ entry, data, sampler, draws, chains, rng; callback = nothing, extra = (;), parallel = "serial"
405
+ )
331
406
  model = condition_on_data(entry(data), data)
332
407
  kw = callback === nothing ? extra : merge(extra, (; callback))
408
+ ensemble = parallel == "threads" ? MCMCThreads() :
409
+ parallel == "distributed" ? MCMCDistributed() : MCMCSerial()
333
410
  return Logging.with_logger(JSONProgressLogger()) do
334
- sample(rng, model, sampler, MCMCSerial(), draws, chains; progress = true, kw...)
411
+ sample(rng, model, sampler, ensemble, draws, chains; progress = true, kw...)
335
412
  end
336
413
  end
337
414
 
415
+ # Distributed chains need the model's definitions on every process: workers get
416
+ # this file (ModelData and friends), then all processes include the model file
417
+ # into Main so the serialized model's references resolve identically everywhere.
418
+ function setup_distributed(chains, model_file)
419
+ missing_workers = chains - Distributed.nworkers()
420
+ if Distributed.nprocs() == 1 || missing_workers > 0
421
+ Distributed.addprocs(
422
+ Distributed.nprocs() == 1 ? chains : missing_workers;
423
+ exeflags = ["--project=$(Base.active_project())", "--startup-file=no"],
424
+ )
425
+ Distributed.remotecall_eval(
426
+ Main, Distributed.workers(), :(Base.include(Main, $FITLIB_FILE))
427
+ )
428
+ end
429
+ Distributed.remotecall_eval(Main, Distributed.procs(), :(Base.include(Main, $model_file)))
430
+ end
431
+
338
432
  # FlexiChains-native wire writer. DimArray(chn) splits array-valued parameters
339
433
  # into scalar leaves (theta -> theta[1], theta[2]) in the (iter, chain, param)
340
434
  # orientation; Real-valued extras become the internals section.
@@ -376,12 +470,16 @@ end
376
470
  # Returns a FlexiChain like the Turing path; gen_chains recovers generated
377
471
  # quantities (unobserved nodes with no observed descendants) after sampling.
378
472
  # With a callback, draws stream (see bugs_draw_streamer).
379
- function sample_bugs(model, sampler, warmup, draws, chains, rng; callback = nothing, thin = 1)
473
+ function sample_bugs(
474
+ model, sampler, warmup, draws, chains, rng;
475
+ callback = nothing, thin = 1, threads = false,
476
+ )
380
477
  kw = callback === nothing ? (;) : (; callback)
381
478
  thin > 1 && (kw = merge(kw, (; thinning = thin)))
479
+ ensemble = threads ? JuliaBUGS.AbstractMCMC.MCMCThreads() : JuliaBUGS.AbstractMCMC.MCMCSerial()
382
480
  return Logging.with_logger(JSONProgressLogger()) do
383
481
  JuliaBUGS.AbstractMCMC.sample(
384
- rng, model, sampler, JuliaBUGS.AbstractMCMC.MCMCSerial(), draws, chains;
482
+ rng, model, sampler, ensemble, draws, chains;
385
483
  chain_type = FlexiChains.VNChain, n_adapts = warmup, discard_initial = warmup,
386
484
  progress = true, kw...,
387
485
  )
@@ -712,9 +810,20 @@ function handle_request(request)
712
810
  end
713
811
  else
714
812
  data = backend == "juliabugs" ? bugs_namedtuple(request["data"]) : ModelData(to_namedtuple(request["data"]))
715
- sampler, warmup = build_sampler(request["sampler"], backend)
716
- draws = Int(request["sampler"]["draws"])
813
+ parallel = get(request["sampler"], "parallel", "serial")
717
814
  chains = Int(get(request["sampler"], "chains", 4))
815
+ if parallel == "distributed" && backend != "juliabugs"
816
+ # Every process needs the model's definitions under the same
817
+ # names; the module-per-request isolation gives way to Main.
818
+ stage = "distribute"
819
+ Base.invokelatest(setup_distributed, chains, request["model"]["file"])
820
+ modelmod = Main
821
+ entry = resolve_entry(Main, get(request["model"], "entry", nothing))
822
+ end
823
+ sampler_conf = backend == "juliabugs" ? request["sampler"] :
824
+ apply_model_defaults(request["sampler"], modelmod)
825
+ sampler, warmup = build_sampler(sampler_conf, backend, modelmod)
826
+ draws = Int(request["sampler"]["draws"])
718
827
  stage = "sample"
719
828
  if backend == "juliabugs"
720
829
  model = Base.invokelatest(entry, data)
@@ -723,21 +832,24 @@ function handle_request(request)
723
832
  else
724
833
  # Reconstruction reads the plain BUGSModel; entry may return a gradient wrapper.
725
834
  base = hasproperty(model, :base_model) ? model.base_model : model
726
- cb = get(request, "stream_draws", false) ?
835
+ threads = get(request["sampler"], "parallel", "serial") == "threads"
836
+ cb = get(request, "stream_draws", false) && !threads ?
727
837
  bugs_draw_streamer(base, draws, Int(get(request, "draw_batch_size", 25))) : nothing
728
838
  Base.invokelatest(
729
839
  sample_bugs, model, sampler, warmup, draws, chains, rng;
730
- callback = cb, thin = Int(get(request["sampler"], "thin", 1)),
840
+ callback = cb, thin = Int(get(request["sampler"], "thin", 1)), threads,
731
841
  )
732
842
  end
733
843
  vnchain_to_wire(chn)
734
844
  else
735
- cb = get(request, "stream_draws", false) ?
845
+ # The draw streamer assumes chains arrive one at a time; with
846
+ # concurrent chains the caller must not request streaming.
847
+ cb = get(request, "stream_draws", false) && parallel == "serial" ?
736
848
  draw_streamer(draws, Int(get(request, "draw_batch_size", 25))) : nothing
737
849
  extra = sampling_kwargs(request["sampler"], warmup, chains)
738
850
  chn = Base.invokelatest(
739
851
  build_and_sample, entry, data, sampler, draws, chains, rng;
740
- callback = cb, extra,
852
+ callback = cb, extra, parallel,
741
853
  )
742
854
  vnchain_to_wire(chn)
743
855
  end
package/dist/index.cjs CHANGED
@@ -257,6 +257,7 @@ async function runFit(spec, resolved, io) {
257
257
  const args = [
258
258
  ...resolved.args,
259
259
  "--startup-file=no",
260
+ ...spec.sampler.parallel === "threads" ? ["--threads=auto"] : [],
260
261
  `--project=${io.projectDir}`,
261
262
  driverPath(),
262
263
  requestPath
@@ -1026,7 +1027,7 @@ async function runFitAuto(spec, resolved, io) {
1026
1027
  if (io.signal?.aborted) {
1027
1028
  return { status: "cancelled", runtimeRequested: spec.backend.version, elapsedMs: 0 };
1028
1029
  }
1029
- if (io.daemon && process.platform !== "win32") {
1030
+ if (io.daemon && process.platform !== "win32" && spec.sampler.parallel !== "distributed") {
1030
1031
  const start = performance.now();
1031
1032
  try {
1032
1033
  return await runFitViaWorker(spec, resolved, io);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../../../node_modules/.pnpm/tsup@8.5.1_@microsoft+api-extractor@7.58.9_@types+node@24.12.4__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/loglik.ts","../src/predict.ts","../src/project.ts","../src/run-matrix.ts","../src/setup.ts","../src/versions.ts","../src/worker.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 LogLikIo, runLogLik } from \"./loglik\";\nexport type { PredictIo } from \"./predict\";\nexport { predictData, runPredict } from \"./predict\";\nexport type { PackagePins } from \"./project\";\nexport {\n ensureProject,\n managedProjectDir,\n managedProjectReady,\n validatePins,\n validateVersionString,\n} from \"./project\";\nexport type { MatrixEntry, MatrixIo, MatrixResult } from \"./run-matrix\";\nexport { runMatrix } from \"./run-matrix\";\nexport { sharedTmpParent } from \"./runner-common\";\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\";\nexport type { WorkerStatus } from \"./worker\";\nexport { killWorker, listWorkers, runFitAuto, stopWorker } from \"./worker\";\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 under the home directory; we also fall back to\n// whatever is on PATH. $HOME is honored first so a sandbox that redirects HOME\n// (mcmc sandbox --strict) finds its own juliaup, not the user's.\nfunction candidates(binary: string): string[] {\n const home = process.env.HOME || homedir();\n return [join(home, \".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, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\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 { DrawBatch, FitProgress, FitResult, FitRunner } from \"@mcmcjs/engine\";\nimport { driverPath, lastJsonLine, sha256, sharedTmpParent, 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 /** Where the run record is written; defaults to `<outPath>.run.json`. */\n recordPath?: string;\n /** Streamed per-chain sampling progress. */\n onProgress?: (progress: FitProgress) => void;\n /** Streamed draw batches as sampling proceeds. */\n onDraws?: (batch: DrawBatch) => void;\n /** Raw console lines from the sampler as they arrive (structured progress/draws\n * lines are filtered out), for surfacing solver logs live. */\n onLog?: (line: string, stream: \"stdout\" | \"stderr\") => void;\n /** Draws per streamed batch (driver default 25); lower it when models have many leaves. */\n drawBatchSize?: number;\n /** Aborts an in-progress fit; the run then ends with a \"cancelled\" status. */\n signal?: AbortSignal;\n /** Source path when the data came from a referenced file; recorded, not copied. */\n dataFile?: string;\n /** Overrides the recorded data hash (e.g. the data file's bytes hash). */\n dataSha256?: string;\n tmpDir?: string;\n}\n\n/** A fresh request dir under the shared per-user tmp parent. */\nexport function makeRequestDir(kind: string): string {\n const parent = sharedTmpParent();\n mkdirSync(parent, { recursive: true });\n return mkdtempSync(join(parent, `${kind}-`));\n}\n\n/** The driver/worker request object for one fit. */\nexport function fitRequest(\n spec: ResolvedSpec,\n outPath: string,\n opts?: { streamDraws?: boolean; drawBatchSize?: number },\n): Record<string, unknown> {\n return {\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: outPath,\n ...(opts?.streamDraws ? { stream_draws: true } : {}),\n ...(opts?.drawBatchSize ? { draw_batch_size: opts.drawBatchSize } : {}),\n };\n}\n\n/**\n * Validates the written samples and records provenance; the success tail\n * shared by the one-shot driver and the worker paths.\n */\nexport function finalizeOkFit(\n spec: ResolvedSpec,\n resolved: { command: string },\n io: Pick<FitIo, \"outPath\" | \"recordPath\" | \"dataFile\" | \"dataSha256\">,\n provenance: Record<string, unknown> | undefined,\n startedAt: string,\n elapsedMs: number,\n): FitResult {\n const runtimeRequested = spec.backend.version;\n if (!existsSync(io.outPath)) {\n return {\n status: \"error\",\n runtimeRequested,\n elapsedMs,\n stage: \"write\",\n error: \"the runtime reported success but wrote no samples file\",\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 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: io.dataSha256 ?? sha256(canonicalJson(spec.data)),\n ...(io.dataFile ? { data_file: io.dataFile } : {}),\n samples_file: io.outPath,\n started_at: startedAt,\n elapsed_ms: elapsedMs,\n };\n writeFileSync(io.recordPath ?? `${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\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 if (io.signal?.aborted) {\n return { status: \"cancelled\", runtimeRequested, elapsedMs: 0 };\n }\n\n const ownTmp = io.tmpDir === undefined;\n const tmp = io.tmpDir ?? makeRequestDir(\"fit\");\n const requestPath = join(tmp, \"request.json\");\n writeFileSync(\n requestPath,\n JSON.stringify(\n fitRequest(spec, io.outPath, {\n streamDraws: io.onDraws !== undefined,\n drawBatchSize: io.drawBatchSize,\n }),\n ),\n );\n\n const args = [\n ...resolved.args,\n \"--startup-file=no\",\n `--project=${io.projectDir}`,\n driverPath(),\n requestPath,\n ];\n let stdout: string;\n let stderr: string;\n let code: number;\n let cancelled: boolean | undefined;\n try {\n ({ stdout, stderr, code, cancelled } = await io.spawn(resolved.command, args, {\n onProgress: io.onProgress,\n onDraws: io.onDraws,\n onLog: io.onLog,\n signal: io.signal,\n }));\n } finally {\n if (ownTmp) rmSync(tmp, { recursive: true, force: true });\n }\n const elapsedMs = Math.round(performance.now() - start);\n\n if (cancelled) {\n return { status: \"cancelled\", runtimeRequested, elapsedMs };\n }\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 return finalizeOkFit(spec, resolved, io, lastJsonLine(stdout), startedAt, elapsedMs);\n}\n","import { createHash } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { FitResult } from \"@mcmcjs/engine\";\n\n/**\n * The per-user parent for all mcmcjs temp state. The uid suffix keeps users\n * on a shared /tmp out of each other's way (macOS tmpdir is per-user already,\n * Linux /tmp is not).\n */\nexport function sharedTmpParent(): string {\n const uid = typeof process.getuid === \"function\" ? `-${process.getuid()}` : \"\";\n return join(tmpdir(), `mcmcjs${uid}`);\n}\n\n// The driver scripts sit next to the bundle in the published dist/ (tsup copies\n// them there), but under src/driver/ when running from source (tests, tsx). Try\n// the bundle layout first, fall back to the source layout.\nfunction driverFile(name: string): string {\n const here = dirname(fileURLToPath(import.meta.url));\n const beside = join(here, name);\n return existsSync(beside) ? beside : join(here, \"driver\", name);\n}\n\n/** Path to the shipped Julia driver. */\nexport function driverPath(): string {\n return driverFile(\"driver.jl\");\n}\n\n/** Path to the shipped persistent worker. */\nexport function workerPath(): string {\n return driverFile(\"worker.jl\");\n}\n\n/**\n * Directory holding the shipped, resolved Julia env (Project.toml + Manifest.toml),\n * next to this module in dist/. A fresh default provision instantiates this exact\n * package set rather than re-resolving the latest compatible versions.\n */\nexport function pinnedEnvDir(): string {\n return join(dirname(fileURLToPath(import.meta.url)), \"julia-env\");\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 \"worker\",\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, readFileSync, rmSync, writeFileSync } from \"node:fs\";\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 { makeRequestDir } from \"./fit\";\nimport { driverPath, lastJsonLine, sha256, toStage } from \"./runner-common\";\n\nexport interface LogLikIo {\n /** Spawns the Julia process; injectable so runLogLik is testable without Julia. */\n spawn: FitRunner;\n projectDir: string;\n /** Where the pointwise log-likelihood file is written (samples wire, one column per observation). */\n outPath: string;\n /** The posterior samples file the log-likelihood is evaluated at. */\n samplesPath: string;\n tmpDir?: string;\n}\n\n/**\n * Computes the pointwise log-likelihood of the observed data at each posterior\n * draw: one column per observation, in the same wire format as a samples file.\n * This is the input LOO/WAIC model comparison needs.\n */\nexport async function runLogLik(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: LogLikIo,\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n const runtimeRequested = spec.backend.version;\n\n const ownTmp = io.tmpDir === undefined;\n const tmp = io.tmpDir ?? makeRequestDir(\"loglik\");\n const requestPath = join(tmp, \"request.json\");\n writeFileSync(\n requestPath,\n JSON.stringify({\n mode: \"loglik\",\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 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 let stdout: string;\n let stderr: string;\n let code: number;\n try {\n ({ stdout, stderr, code } = await io.spawn(resolved.command, args));\n } finally {\n if (ownTmp) rmSync(tmp, { recursive: true, force: true });\n }\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: `log-likelihood 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 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, readFileSync, rmSync, writeFileSync } from \"node:fs\";\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 { makeRequestDir } from \"./fit\";\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 ownTmp = io.tmpDir === undefined;\n const tmp = io.tmpDir ?? makeRequestDir(\"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 let stdout: string;\n let stderr: string;\n let code: number;\n try {\n ({ stdout, stderr, code } = await io.spawn(resolved.command, args));\n } finally {\n if (ownTmp) rmSync(tmp, { recursive: true, force: true });\n }\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 { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { canonicalJson, DEFAULT_JULIA_CHANNEL } from \"@mcmcjs/core\";\nimport { type CommandRunner, createRunner } from \"@mcmcjs/engine\";\nimport { pinnedEnvDir, sha256 } from \"./runner-common\";\n\nconst PACKAGES = [\n \"Turing\",\n \"FlexiChains\",\n \"DimensionalData\",\n \"MCMCChains\",\n \"JuliaBUGS\",\n \"AdvancedHMC\",\n \"ForwardDiff\",\n \"Mooncake\",\n \"ReverseDiff\",\n \"JSON\",\n \"StableRNGs\",\n \"StatsFuns\",\n];\n\n/** Version pins for managed packages, by name (e.g. { Turing: \"0.45\" }). */\nexport type PackagePins = Record<string, string>;\n\n// Version strings are interpolated into Julia source for Pkg.add; this allows\n// only the characters of a Julia version specifier (digits, letters, and the\n// range operators) and notably excludes `$` and backticks, which would\n// otherwise let a shared spec run arbitrary Julia via string interpolation.\nconst VERSION_RE = /^[0-9A-Za-z.+~^=<>,\\s-]+$/;\n\n/** Rejects a version string that could break out of the generated Julia literal. */\nexport function validateVersionString(name: string, version: string): void {\n if (!VERSION_RE.test(version)) {\n throw new Error(\n `invalid version \"${version}\" for package ${name}; a version may contain only digits, letters, and . + ~ ^ = < > , - and spaces`,\n );\n }\n}\n\n/** Rejects pins for unmanaged packages or with unsafe version strings. */\nexport function validatePins(pins: PackagePins | undefined): void {\n for (const [name, version] of Object.entries(pins ?? {})) {\n if (!PACKAGES.includes(name)) {\n throw new Error(\n `cannot pin unknown package \"${name}\"; managed packages are: ${PACKAGES.join(\", \")}`,\n );\n }\n validateVersionString(name, version);\n }\n}\n\nfunction hasPins(pins?: PackagePins): pins is PackagePins {\n return pins !== undefined && Object.keys(pins).length > 0;\n}\n\n/**\n * The per-user directory holding a managed Julia project (Project + Manifest).\n * Keyed by the concrete Julia version AND any package pins, so each version\n * resolves its own compatible Manifest and each distinct set of pins gets its\n * own environment: a Manifest resolved by one Julia version (or package set)\n * can pin versions that fail to precompile under another. A missing version\n * and no pins falls back to the unversioned root.\n */\nexport function managedProjectDir(version?: string, pins?: PackagePins): string {\n const base = process.env.XDG_DATA_HOME || join(homedir(), \".local\", \"share\");\n const root = join(base, \"mcmcjs\", \"julia\", \"env\");\n if (!version && !hasPins(pins)) return root;\n let leaf = (version ?? \"default\").replace(/[^A-Za-z0-9._-]/g, \"_\");\n if (hasPins(pins)) leaf += `-${sha256(canonicalJson(pins)).slice(0, 8)}`;\n return join(root, leaf);\n}\n\n// Records what a managed dir was provisioned with (package set + pins), so an\n// env from an older set is healed (Pkg.add is additive) rather than left stale.\nfunction sentinelPath(dir: string): string {\n return join(dir, \".mcmcjs-packages.json\");\n}\n\n// Bumped when the provisioning changes shape so existing envs re-provision; e.g.\n// generation 1 introduced instantiating the committed Manifest for the default,\n// which a pre-existing fresh-resolved env must pick up.\nconst PROVISION_GENERATION = 1;\n\nfunction expectedSentinel(pins?: PackagePins): string {\n return canonicalJson({\n gen: PROVISION_GENERATION,\n packages: [...PACKAGES].sort(),\n pins: pins ?? {},\n });\n}\n\nfunction provisioned(dir: string, pins?: PackagePins): boolean {\n try {\n return readFileSync(sentinelPath(dir), \"utf8\").trim() === expectedSentinel(pins);\n } catch {\n return false;\n }\n}\n\n/** Whether the managed project is present and provisioned with the current package set and pins. */\nexport function managedProjectReady(\n dir: string = managedProjectDir(),\n pins?: PackagePins,\n): boolean {\n return existsSync(join(dir, \"Project.toml\")) && provisioned(dir, pins);\n}\n\n/** The `Pkg.add` argument: a PackageSpec per managed package, version-pinned where requested. */\nfunction packageSpecsCode(pins?: PackagePins): string {\n const specs = PACKAGES.map((name) => {\n const version = pins?.[name];\n return version\n ? `Pkg.PackageSpec(name=${JSON.stringify(name)}, version=${JSON.stringify(version)})`\n : `Pkg.PackageSpec(name=${JSON.stringify(name)})`;\n });\n return `[${specs.join(\", \")}]`;\n}\n\n/**\n * Whether a provision should instantiate the shipped, resolved env (exact\n * committed package set) rather than resolving fresh: only the unpinned default\n * on the pinned Julia version, and only when the shipped env is present. Other\n * versions (a `--versions` matrix) and any package pins must resolve fresh,\n * since the committed Manifest was resolved for one specific Julia version.\n */\nfunction usesPinnedEnv(version: string | undefined, pins?: PackagePins): boolean {\n return !hasPins(pins) && version === DEFAULT_JULIA_CHANNEL && existsSync(pinnedEnvDir());\n}\n\n/**\n * Ensures the managed Julia project exists with the inference packages installed\n * (version-pinned where `pins` requests). Idempotent: returns immediately when\n * already provisioned with the current set and pins. For the default env on the\n * pinned Julia version it instantiates the shipped, resolved Manifest (the exact\n * committed package set); otherwise it resolves and adds the packages fresh. The\n * first provision 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 pins?: PackagePins,\n opts?: { version?: string },\n): Promise<string> {\n validatePins(pins);\n if (managedProjectReady(dir, pins)) return dir;\n mkdirSync(dir, { recursive: true });\n if (usesPinnedEnv(opts?.version, pins)) {\n copyFileSync(join(pinnedEnvDir(), \"Project.toml\"), join(dir, \"Project.toml\"));\n copyFileSync(join(pinnedEnvDir(), \"Manifest.toml\"), join(dir, \"Manifest.toml\"));\n await run(juliaBin, [\n \"--startup-file=no\",\n `--project=${dir}`,\n \"-e\",\n \"using Pkg; Pkg.instantiate(); Pkg.precompile()\",\n ]);\n } else {\n const code = `using Pkg; Pkg.add(${packageSpecsCode(pins)}); Pkg.precompile()`;\n await run(juliaBin, [\"--startup-file=no\", `--project=${dir}`, \"-e\", code]);\n }\n writeFileSync(sentinelPath(dir), expectedSentinel(pins));\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\" | \"cancelled\";\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 ResolvedInvocation {\n command: string;\n args: string[];\n version?: string;\n}\n\nexport interface MatrixIo {\n spawn: FitRunner;\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<ResolvedInvocation>;\n /** Provisions the managed env for a resolved version and returns its dir. */\n ensure: (resolved: ResolvedInvocation) => Promise<string>;\n /** Source path when the data came from a referenced file; recorded per version. */\n dataFile?: string;\n /** Overrides the recorded data hash (the data file's bytes hash). */\n dataSha256?: 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 projectDir = await io.ensure(resolved);\n const versioned = { ...spec, backend: { ...spec.backend, version } };\n const result = await runFit(versioned, resolved, {\n spawn: io.spawn,\n projectDir,\n outPath: join(io.outDir, `${version}.samples.json`),\n dataFile: io.dataFile,\n dataSha256: io.dataSha256,\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 // A cancelled run stops the whole matrix regardless of keepGoing.\n if (entry.status === \"cancelled\") break;\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 { DEFAULT_JULIA_CHANNEL } from \"@mcmcjs/core\";\nimport { 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 // `--default-channel` makes the installer add the pinned Julia version (not\n // just the latest \"release\") in the same step, so a clean machine lands on\n // the exact version the committed Manifest was resolved for.\n return {\n command: \"sh\",\n args: [\n \"-c\",\n `curl -fsSL ${JULIAUP_INSTALL_URL} | sh -s -- --yes --default-channel ${DEFAULT_JULIA_CHANNEL}`,\n ],\n };\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 // The pinned Julia is already the active default: nothing to do.\n if (report.julia.found && report.julia.version === DEFAULT_JULIA_CHANNEL) return [];\n if (report.juliaup.found) {\n return [\n {\n tool: \"julia\",\n label: `install the pinned Julia ${DEFAULT_JULIA_CHANNEL} via juliaup`,\n command: {\n command: report.juliaup.path ?? \"juliaup\",\n args: [\"add\", DEFAULT_JULIA_CHANNEL],\n },\n },\n ];\n }\n return [\n {\n tool: \"juliaup\",\n label: `install juliaup with the pinned Julia ${DEFAULT_JULIA_CHANNEL}`,\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 const plan = planSetup(before, platform);\n // Nothing to install only when the pinned Julia is already the active\n // default; a different installed Julia still triggers a pinned-version add.\n if (plan.length === 0) return { ...before, steps: [] };\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[]; version?: 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 ?? [], version: match.Version };\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","import { spawn } from \"node:child_process\";\nimport { mkdirSync, readdirSync, readFileSync, rmdirSync, rmSync, statSync } from \"node:fs\";\nimport { createConnection, type Socket } from \"node:net\";\nimport { join } from \"node:path\";\nimport type { ResolvedSpec } from \"@mcmcjs/core\";\nimport type { FitResult } from \"@mcmcjs/engine\";\nimport { parseDrawBatchLine, parseProgressLine } from \"@mcmcjs/engine\";\nimport { type FitIo, finalizeOkFit, fitRequest, runFit } from \"./fit\";\nimport { sha256, sharedTmpParent, toStage, workerPath } from \"./runner-common\";\n\nconst START_WAIT_MS = 180_000;\nconst CONNECT_TIMEOUT_MS = 1_000;\nconst STOP_ACK_TIMEOUT_MS = 3_000;\n\n/** Same 30-minute budget as the one-shot driver; MCMC_WORKER_TIMEOUT_MS overrides. */\nfunction fitInactivityTimeoutMs(): number {\n const fromEnv = Number(process.env.MCMC_WORKER_TIMEOUT_MS);\n return Number.isFinite(fromEnv) && fromEnv > 0 ? fromEnv : 30 * 60_000;\n}\n\n/** A hung worker is not retried; the fit is reported failed instead. */\nclass WorkerTimeoutError extends Error {}\n\n/** The caller aborted the fit; the worker is killed and the run ends cancelled. */\nclass FitCancelledError extends Error {}\n\n/** The pidfile a worker writes beside its socket so a fit can be killed cross-process. */\nfunction workerPidPath(socket: string): string {\n return `${socket}.pid`;\n}\n\n/**\n * Force-kills the worker serving `socket` (by the pid it wrote beside the\n * socket) and clears the socket and pidfile, so the next fit cold-starts a\n * fresh worker. Used to stop a worker mid-fit, which the polite stop cannot do\n * while it is busy sampling.\n */\nexport function killWorker(socket: string): void {\n const pidPath = workerPidPath(socket);\n try {\n const pid = Number(readFileSync(pidPath, \"utf8\").trim());\n if (Number.isInteger(pid) && pid > 0) {\n // The worker is a detached process-group leader, so signaling -pid takes\n // down any precompile/child processes it spawned, not just the parent.\n try {\n process.kill(-pid, \"SIGKILL\");\n } catch {\n process.kill(pid, \"SIGKILL\");\n }\n }\n } catch {}\n rmSync(socket, { force: true });\n rmSync(pidPath, { force: true });\n}\n\n/** Where worker sockets live; runtime dir when available, the shared tmp parent otherwise. */\nexport function workersDir(): string {\n const runtime = process.env.XDG_RUNTIME_DIR;\n const dir = runtime ? join(runtime, \"mcmcjs\") : join(sharedTmpParent(), \"workers\");\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n return dir;\n}\n\n/** One worker per (Julia binary, project env) pair, named by a key hash. */\nexport function workerSocketPath(command: string, projectDir: string): string {\n return join(workersDir(), `worker-${sha256(`${command}\\n${projectDir}`).slice(0, 12)}.sock`);\n}\n\nfunction connectOnce(path: string): Promise<Socket> {\n return new Promise((resolve, reject) => {\n const sock = createConnection(path);\n const timer = setTimeout(() => {\n sock.destroy();\n reject(new Error(\"connect timeout\"));\n }, CONNECT_TIMEOUT_MS);\n sock.once(\"connect\", () => {\n clearTimeout(timer);\n resolve(sock);\n });\n sock.once(\"error\", (error) => {\n clearTimeout(timer);\n reject(error);\n });\n });\n}\n\nconst delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\n/**\n * Serializes cold starts: only one invocation spawns a worker per socket path;\n * the rest poll the socket. A stale lock (a dead spawner) is taken over.\n */\nfunction acquireStartLock(socketPath: string): boolean {\n const lock = `${socketPath}.start`;\n try {\n mkdirSync(lock);\n return true;\n } catch {\n try {\n if (Date.now() - statSync(lock).mtimeMs > START_WAIT_MS) {\n rmdirSync(lock);\n mkdirSync(lock);\n return true;\n }\n } catch {}\n return false;\n }\n}\n\nfunction releaseStartLock(socketPath: string): void {\n try {\n rmdirSync(`${socketPath}.start`);\n } catch {}\n}\n\n/** Connects to the keyed worker, starting one (detached) if none answers. */\nexport async function ensureWorker(\n resolved: { command: string; args: string[] },\n projectDir: string,\n notify?: (line: string) => void,\n signal?: AbortSignal,\n): Promise<Socket> {\n const path = workerSocketPath(resolved.command, projectDir);\n try {\n return await connectOnce(path);\n } catch {}\n // Honor a cancel that arrived during the (possibly slow) cold start; the\n // detached worker keeps loading and stays warm for the next fit.\n if (signal?.aborted) throw new FitCancelledError();\n\n let spawnFailure: Error | undefined;\n const startedHere = acquireStartLock(path);\n if (startedHere) {\n try {\n rmSync(path, { force: true });\n notify?.(\"starting the Julia worker (first use loads Turing, can take a minute)...\");\n const child = spawn(\n resolved.command,\n [...resolved.args, \"--startup-file=no\", `--project=${projectDir}`, workerPath(), path],\n { detached: true, stdio: \"ignore\" },\n );\n child.on(\"error\", (error) => {\n spawnFailure = error;\n });\n child.on(\"exit\", (code) => {\n if (code !== 0 && code !== null) {\n spawnFailure = new Error(`the worker exited with code ${code} before serving`);\n }\n });\n child.unref();\n } catch (error) {\n releaseStartLock(path);\n throw error;\n }\n }\n\n try {\n const deadline = Date.now() + START_WAIT_MS;\n for (;;) {\n if (signal?.aborted) throw new FitCancelledError();\n if (spawnFailure) throw spawnFailure;\n try {\n return await connectOnce(path);\n } catch {}\n if (Date.now() > deadline) throw new Error(\"the Julia worker did not start in time\");\n await delay(250);\n }\n } finally {\n if (startedHere) releaseStartLock(path);\n }\n}\n\n/**\n * Streams progress lines to onProgress and resolves with the final result\n * line. The inactivity deadline (reset by every byte the worker sends, so\n * healthy long fits survive on their progress stream) rejects with\n * WorkerTimeoutError rather than hanging forever on a wedged worker.\n */\nfunction readWorkerResponse(\n sock: Socket,\n onProgress?: FitIo[\"onProgress\"],\n onDraws?: FitIo[\"onDraws\"],\n signal?: AbortSignal,\n inactivityMs = fitInactivityTimeoutMs(),\n): Promise<Record<string, unknown>> {\n return new Promise((resolve, reject) => {\n let pending = \"\";\n let settled = false;\n const onAbort = () => {\n settle(() => {\n sock.destroy();\n reject(new FitCancelledError());\n });\n };\n const settle = (fn: () => void) => {\n if (settled) return;\n settled = true;\n sock.setTimeout(0);\n signal?.removeEventListener(\"abort\", onAbort);\n fn();\n };\n if (signal) {\n if (signal.aborted) onAbort();\n else signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n sock.setTimeout(inactivityMs, () => {\n const error = new WorkerTimeoutError(\n `the worker sent nothing for ${Math.round(inactivityMs / 60_000)} minutes`,\n );\n settle(() => {\n sock.destroy();\n reject(error);\n });\n });\n sock.on(\"data\", (chunk: Buffer) => {\n pending += chunk.toString(\"utf8\");\n for (;;) {\n const at = pending.indexOf(\"\\n\");\n if (at === -1) break;\n const line = pending.slice(0, at).trim();\n pending = pending.slice(at + 1);\n if (!line) continue;\n const progress = parseProgressLine(line);\n if (progress) {\n onProgress?.(progress);\n continue;\n }\n const batch = parseDrawBatchLine(line);\n if (batch) {\n onDraws?.(batch);\n continue;\n }\n try {\n const doc = JSON.parse(line) as Record<string, unknown>;\n settle(() => {\n sock.end();\n resolve(doc);\n });\n return;\n } catch {}\n }\n });\n sock.on(\"error\", (error) => settle(() => reject(error)));\n sock.on(\"close\", () => settle(() => reject(new Error(\"worker closed the connection\"))));\n });\n}\n\n/** Runs one fit through the persistent worker. Throws on worker-infrastructure failure. */\nexport async function runFitViaWorker(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: FitIo & { notify?: (line: string) => void },\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n if (io.signal?.aborted) {\n return { status: \"cancelled\", runtimeRequested: spec.backend.version, elapsedMs: 0 };\n }\n let sock: Socket;\n try {\n sock = await ensureWorker(resolved, io.projectDir, io.notify, io.signal);\n } catch (error) {\n // Cancelled during the cold start: the worker (if any) is still idle and\n // stays warm; no fit was dispatched, so just report cancelled.\n if (error instanceof FitCancelledError) {\n return {\n status: \"cancelled\",\n runtimeRequested: spec.backend.version,\n elapsedMs: Math.round(performance.now() - start),\n };\n }\n throw error;\n }\n if (io.signal?.aborted) {\n // Aborted in the gap before dispatch; drop the connection, leave the worker\n // idle and warm. The worker reads an empty line and loops back to accept.\n sock.destroy();\n return {\n status: \"cancelled\",\n runtimeRequested: spec.backend.version,\n elapsedMs: Math.round(performance.now() - start),\n };\n }\n sock.write(\n `${JSON.stringify(fitRequest(spec, io.outPath, { streamDraws: io.onDraws !== undefined, drawBatchSize: io.drawBatchSize }))}\\n`,\n );\n let final: Record<string, unknown>;\n try {\n final = await readWorkerResponse(sock, io.onProgress, io.onDraws, io.signal);\n } catch (error) {\n if (error instanceof FitCancelledError) {\n // The worker is mid-sample and cannot answer a polite stop; kill it so it\n // stops promptly and the next fit cold-starts a fresh one.\n killWorker(workerSocketPath(resolved.command, io.projectDir));\n return {\n status: \"cancelled\",\n runtimeRequested: spec.backend.version,\n elapsedMs: Math.round(performance.now() - start),\n };\n }\n throw error;\n }\n const elapsedMs = Math.round(performance.now() - start);\n\n if (final.ok !== true) {\n // \"worker\" is the worker's own protocol failure, not a model failure;\n // throwing hands the fit to the one-shot driver.\n if (final.stage === \"worker\") throw new Error(String(final.error ?? \"worker error\"));\n return {\n status: \"error\",\n runtimeRequested: spec.backend.version,\n elapsedMs,\n stage: toStage(final.stage),\n error: String(final.error ?? \"worker error\"),\n };\n }\n return finalizeOkFit(\n spec,\n resolved,\n io,\n final.provenance as Record<string, unknown> | undefined,\n startedAt,\n elapsedMs,\n );\n}\n\n/**\n * Runs a fit through the worker when asked (and possible), falling back to the\n * one-shot driver on worker-infrastructure failures. Two exceptions never fall\n * back: a fit that genuinely failed (model error) is returned, and a hung\n * worker (timeout) is reported rather than silently re-run for another\n * half hour.\n */\nexport async function runFitAuto(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: FitIo & { daemon?: boolean; notify?: (line: string) => void },\n): Promise<FitResult> {\n if (io.signal?.aborted) {\n return { status: \"cancelled\", runtimeRequested: spec.backend.version, elapsedMs: 0 };\n }\n if (io.daemon && process.platform !== \"win32\") {\n const start = performance.now();\n try {\n return await runFitViaWorker(spec, resolved, io);\n } catch (error) {\n if (error instanceof WorkerTimeoutError) {\n return {\n status: \"error\",\n runtimeRequested: spec.backend.version,\n elapsedMs: Math.round(performance.now() - start),\n stage: \"worker\",\n error: `${error.message}; the worker may be wedged, try mcmc daemon stop`,\n };\n }\n io.notify?.(\n `worker unavailable (${(error as Error).message}); falling back to a one-shot run`,\n );\n }\n }\n return runFit(spec, resolved, io);\n}\n\nexport interface WorkerStatus {\n socket: string;\n alive: boolean;\n}\n\n/** Lists known worker sockets and whether each answers. */\nexport async function listWorkers(): Promise<WorkerStatus[]> {\n const dir = workersDir();\n const sockets = readdirSync(dir).filter((f) => f.startsWith(\"worker-\") && f.endsWith(\".sock\"));\n const statuses: WorkerStatus[] = [];\n for (const name of sockets) {\n const socket = join(dir, name);\n let alive = false;\n try {\n const sock = await connectOnce(socket);\n sock.destroy();\n alive = true;\n } catch {}\n statuses.push({ socket, alive });\n }\n return statuses;\n}\n\nexport type StopOutcome = \"stopped\" | \"stale\" | \"pending\";\n\n/**\n * Asks one worker to shut down. \"stopped\": acknowledged and gone. \"stale\": the\n * socket was dead and its file was removed. \"pending\": the worker is busy with\n * a fit; the stop request is queued and honored when the fit finishes, so the\n * live socket file is left alone.\n */\nexport async function stopWorker(socket: string): Promise<StopOutcome> {\n let sock: Socket;\n try {\n sock = await connectOnce(socket);\n } catch {\n rmSync(socket, { force: true });\n return \"stale\";\n }\n const acked = await new Promise<boolean>((resolve) => {\n const timer = setTimeout(() => resolve(false), STOP_ACK_TIMEOUT_MS);\n const finish = (ok: boolean) => {\n clearTimeout(timer);\n resolve(ok);\n };\n // Without a flowing readable side the worker's FIN is never surfaced.\n sock.resume();\n sock.on(\"close\", () => finish(true));\n sock.on(\"error\", () => finish(false));\n sock.write('{\"mcmcjs\":\"stop\"}\\n');\n });\n sock.destroy();\n if (!acked) return \"pending\";\n rmSync(socket, { force: true });\n return \"stopped\";\n}\n"],"mappings":"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","names":["import_engine","import_node_fs","import_node_path","import_node_os","import_node_path","import_node_fs","import_node_path","import_core","import_node_fs","import_node_path","import_core","import_node_fs","import_node_os","import_node_path","import_core","import_engine","import_node_path","import_core","import_node_fs","import_node_path","import_engine"]}
1
+ {"version":3,"sources":["../src/index.ts","../../../node_modules/.pnpm/tsup@8.5.1_@microsoft+api-extractor@7.58.9_@types+node@24.12.4__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/loglik.ts","../src/predict.ts","../src/project.ts","../src/run-matrix.ts","../src/setup.ts","../src/versions.ts","../src/worker.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 LogLikIo, runLogLik } from \"./loglik\";\nexport type { PredictIo } from \"./predict\";\nexport { predictData, runPredict } from \"./predict\";\nexport type { PackagePins } from \"./project\";\nexport {\n ensureProject,\n managedProjectDir,\n managedProjectReady,\n validatePins,\n validateVersionString,\n} from \"./project\";\nexport type { MatrixEntry, MatrixIo, MatrixResult } from \"./run-matrix\";\nexport { runMatrix } from \"./run-matrix\";\nexport { sharedTmpParent } from \"./runner-common\";\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\";\nexport type { WorkerStatus } from \"./worker\";\nexport { killWorker, listWorkers, runFitAuto, stopWorker } from \"./worker\";\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 under the home directory; we also fall back to\n// whatever is on PATH. $HOME is honored first so a sandbox that redirects HOME\n// (mcmc sandbox --strict) finds its own juliaup, not the user's.\nfunction candidates(binary: string): string[] {\n const home = process.env.HOME || homedir();\n return [join(home, \".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, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\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 { DrawBatch, FitProgress, FitResult, FitRunner } from \"@mcmcjs/engine\";\nimport { driverPath, lastJsonLine, sha256, sharedTmpParent, 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 /** Where the run record is written; defaults to `<outPath>.run.json`. */\n recordPath?: string;\n /** Streamed per-chain sampling progress. */\n onProgress?: (progress: FitProgress) => void;\n /** Streamed draw batches as sampling proceeds. */\n onDraws?: (batch: DrawBatch) => void;\n /** Raw console lines from the sampler as they arrive (structured progress/draws\n * lines are filtered out), for surfacing solver logs live. */\n onLog?: (line: string, stream: \"stdout\" | \"stderr\") => void;\n /** Draws per streamed batch (driver default 25); lower it when models have many leaves. */\n drawBatchSize?: number;\n /** Aborts an in-progress fit; the run then ends with a \"cancelled\" status. */\n signal?: AbortSignal;\n /** Source path when the data came from a referenced file; recorded, not copied. */\n dataFile?: string;\n /** Overrides the recorded data hash (e.g. the data file's bytes hash). */\n dataSha256?: string;\n tmpDir?: string;\n}\n\n/** A fresh request dir under the shared per-user tmp parent. */\nexport function makeRequestDir(kind: string): string {\n const parent = sharedTmpParent();\n mkdirSync(parent, { recursive: true });\n return mkdtempSync(join(parent, `${kind}-`));\n}\n\n/** The driver/worker request object for one fit. */\nexport function fitRequest(\n spec: ResolvedSpec,\n outPath: string,\n opts?: { streamDraws?: boolean; drawBatchSize?: number },\n): Record<string, unknown> {\n return {\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: outPath,\n ...(opts?.streamDraws ? { stream_draws: true } : {}),\n ...(opts?.drawBatchSize ? { draw_batch_size: opts.drawBatchSize } : {}),\n };\n}\n\n/**\n * Validates the written samples and records provenance; the success tail\n * shared by the one-shot driver and the worker paths.\n */\nexport function finalizeOkFit(\n spec: ResolvedSpec,\n resolved: { command: string },\n io: Pick<FitIo, \"outPath\" | \"recordPath\" | \"dataFile\" | \"dataSha256\">,\n provenance: Record<string, unknown> | undefined,\n startedAt: string,\n elapsedMs: number,\n): FitResult {\n const runtimeRequested = spec.backend.version;\n if (!existsSync(io.outPath)) {\n return {\n status: \"error\",\n runtimeRequested,\n elapsedMs,\n stage: \"write\",\n error: \"the runtime reported success but wrote no samples file\",\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 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: io.dataSha256 ?? sha256(canonicalJson(spec.data)),\n ...(io.dataFile ? { data_file: io.dataFile } : {}),\n samples_file: io.outPath,\n started_at: startedAt,\n elapsed_ms: elapsedMs,\n };\n writeFileSync(io.recordPath ?? `${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\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 if (io.signal?.aborted) {\n return { status: \"cancelled\", runtimeRequested, elapsedMs: 0 };\n }\n\n const ownTmp = io.tmpDir === undefined;\n const tmp = io.tmpDir ?? makeRequestDir(\"fit\");\n const requestPath = join(tmp, \"request.json\");\n writeFileSync(\n requestPath,\n JSON.stringify(\n fitRequest(spec, io.outPath, {\n streamDraws: io.onDraws !== undefined,\n drawBatchSize: io.drawBatchSize,\n }),\n ),\n );\n\n const args = [\n ...resolved.args,\n \"--startup-file=no\",\n ...(spec.sampler.parallel === \"threads\" ? [\"--threads=auto\"] : []),\n `--project=${io.projectDir}`,\n driverPath(),\n requestPath,\n ];\n let stdout: string;\n let stderr: string;\n let code: number;\n let cancelled: boolean | undefined;\n try {\n ({ stdout, stderr, code, cancelled } = await io.spawn(resolved.command, args, {\n onProgress: io.onProgress,\n onDraws: io.onDraws,\n onLog: io.onLog,\n signal: io.signal,\n }));\n } finally {\n if (ownTmp) rmSync(tmp, { recursive: true, force: true });\n }\n const elapsedMs = Math.round(performance.now() - start);\n\n if (cancelled) {\n return { status: \"cancelled\", runtimeRequested, elapsedMs };\n }\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 return finalizeOkFit(spec, resolved, io, lastJsonLine(stdout), startedAt, elapsedMs);\n}\n","import { createHash } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { FitResult } from \"@mcmcjs/engine\";\n\n/**\n * The per-user parent for all mcmcjs temp state. The uid suffix keeps users\n * on a shared /tmp out of each other's way (macOS tmpdir is per-user already,\n * Linux /tmp is not).\n */\nexport function sharedTmpParent(): string {\n const uid = typeof process.getuid === \"function\" ? `-${process.getuid()}` : \"\";\n return join(tmpdir(), `mcmcjs${uid}`);\n}\n\n// The driver scripts sit next to the bundle in the published dist/ (tsup copies\n// them there), but under src/driver/ when running from source (tests, tsx). Try\n// the bundle layout first, fall back to the source layout.\nfunction driverFile(name: string): string {\n const here = dirname(fileURLToPath(import.meta.url));\n const beside = join(here, name);\n return existsSync(beside) ? beside : join(here, \"driver\", name);\n}\n\n/** Path to the shipped Julia driver. */\nexport function driverPath(): string {\n return driverFile(\"driver.jl\");\n}\n\n/** Path to the shipped persistent worker. */\nexport function workerPath(): string {\n return driverFile(\"worker.jl\");\n}\n\n/**\n * Directory holding the shipped, resolved Julia env (Project.toml + Manifest.toml),\n * next to this module in dist/. A fresh default provision instantiates this exact\n * package set rather than re-resolving the latest compatible versions.\n */\nexport function pinnedEnvDir(): string {\n return join(dirname(fileURLToPath(import.meta.url)), \"julia-env\");\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 \"worker\",\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, readFileSync, rmSync, writeFileSync } from \"node:fs\";\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 { makeRequestDir } from \"./fit\";\nimport { driverPath, lastJsonLine, sha256, toStage } from \"./runner-common\";\n\nexport interface LogLikIo {\n /** Spawns the Julia process; injectable so runLogLik is testable without Julia. */\n spawn: FitRunner;\n projectDir: string;\n /** Where the pointwise log-likelihood file is written (samples wire, one column per observation). */\n outPath: string;\n /** The posterior samples file the log-likelihood is evaluated at. */\n samplesPath: string;\n tmpDir?: string;\n}\n\n/**\n * Computes the pointwise log-likelihood of the observed data at each posterior\n * draw: one column per observation, in the same wire format as a samples file.\n * This is the input LOO/WAIC model comparison needs.\n */\nexport async function runLogLik(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: LogLikIo,\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n const runtimeRequested = spec.backend.version;\n\n const ownTmp = io.tmpDir === undefined;\n const tmp = io.tmpDir ?? makeRequestDir(\"loglik\");\n const requestPath = join(tmp, \"request.json\");\n writeFileSync(\n requestPath,\n JSON.stringify({\n mode: \"loglik\",\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 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 let stdout: string;\n let stderr: string;\n let code: number;\n try {\n ({ stdout, stderr, code } = await io.spawn(resolved.command, args));\n } finally {\n if (ownTmp) rmSync(tmp, { recursive: true, force: true });\n }\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: `log-likelihood 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 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, readFileSync, rmSync, writeFileSync } from \"node:fs\";\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 { makeRequestDir } from \"./fit\";\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 ownTmp = io.tmpDir === undefined;\n const tmp = io.tmpDir ?? makeRequestDir(\"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 let stdout: string;\n let stderr: string;\n let code: number;\n try {\n ({ stdout, stderr, code } = await io.spawn(resolved.command, args));\n } finally {\n if (ownTmp) rmSync(tmp, { recursive: true, force: true });\n }\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 { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { canonicalJson, DEFAULT_JULIA_CHANNEL } from \"@mcmcjs/core\";\nimport { type CommandRunner, createRunner } from \"@mcmcjs/engine\";\nimport { pinnedEnvDir, sha256 } from \"./runner-common\";\n\nconst PACKAGES = [\n \"Turing\",\n \"FlexiChains\",\n \"DimensionalData\",\n \"MCMCChains\",\n \"JuliaBUGS\",\n \"AdvancedHMC\",\n \"ForwardDiff\",\n \"Mooncake\",\n \"ReverseDiff\",\n \"JSON\",\n \"StableRNGs\",\n \"StatsFuns\",\n];\n\n/** Version pins for managed packages, by name (e.g. { Turing: \"0.45\" }). */\nexport type PackagePins = Record<string, string>;\n\n// Version strings are interpolated into Julia source for Pkg.add; this allows\n// only the characters of a Julia version specifier (digits, letters, and the\n// range operators) and notably excludes `$` and backticks, which would\n// otherwise let a shared spec run arbitrary Julia via string interpolation.\nconst VERSION_RE = /^[0-9A-Za-z.+~^=<>,\\s-]+$/;\n\n/** Rejects a version string that could break out of the generated Julia literal. */\nexport function validateVersionString(name: string, version: string): void {\n if (!VERSION_RE.test(version)) {\n throw new Error(\n `invalid version \"${version}\" for package ${name}; a version may contain only digits, letters, and . + ~ ^ = < > , - and spaces`,\n );\n }\n}\n\n/** Rejects pins for unmanaged packages or with unsafe version strings. */\nexport function validatePins(pins: PackagePins | undefined): void {\n for (const [name, version] of Object.entries(pins ?? {})) {\n if (!PACKAGES.includes(name)) {\n throw new Error(\n `cannot pin unknown package \"${name}\"; managed packages are: ${PACKAGES.join(\", \")}`,\n );\n }\n validateVersionString(name, version);\n }\n}\n\nfunction hasPins(pins?: PackagePins): pins is PackagePins {\n return pins !== undefined && Object.keys(pins).length > 0;\n}\n\n/**\n * The per-user directory holding a managed Julia project (Project + Manifest).\n * Keyed by the concrete Julia version AND any package pins, so each version\n * resolves its own compatible Manifest and each distinct set of pins gets its\n * own environment: a Manifest resolved by one Julia version (or package set)\n * can pin versions that fail to precompile under another. A missing version\n * and no pins falls back to the unversioned root.\n */\nexport function managedProjectDir(version?: string, pins?: PackagePins): string {\n const base = process.env.XDG_DATA_HOME || join(homedir(), \".local\", \"share\");\n const root = join(base, \"mcmcjs\", \"julia\", \"env\");\n if (!version && !hasPins(pins)) return root;\n let leaf = (version ?? \"default\").replace(/[^A-Za-z0-9._-]/g, \"_\");\n if (hasPins(pins)) leaf += `-${sha256(canonicalJson(pins)).slice(0, 8)}`;\n return join(root, leaf);\n}\n\n// Records what a managed dir was provisioned with (package set + pins), so an\n// env from an older set is healed (Pkg.add is additive) rather than left stale.\nfunction sentinelPath(dir: string): string {\n return join(dir, \".mcmcjs-packages.json\");\n}\n\n// Bumped when the provisioning changes shape so existing envs re-provision; e.g.\n// generation 1 introduced instantiating the committed Manifest for the default,\n// which a pre-existing fresh-resolved env must pick up.\nconst PROVISION_GENERATION = 1;\n\nfunction expectedSentinel(pins?: PackagePins): string {\n return canonicalJson({\n gen: PROVISION_GENERATION,\n packages: [...PACKAGES].sort(),\n pins: pins ?? {},\n });\n}\n\nfunction provisioned(dir: string, pins?: PackagePins): boolean {\n try {\n return readFileSync(sentinelPath(dir), \"utf8\").trim() === expectedSentinel(pins);\n } catch {\n return false;\n }\n}\n\n/** Whether the managed project is present and provisioned with the current package set and pins. */\nexport function managedProjectReady(\n dir: string = managedProjectDir(),\n pins?: PackagePins,\n): boolean {\n return existsSync(join(dir, \"Project.toml\")) && provisioned(dir, pins);\n}\n\n/** The `Pkg.add` argument: a PackageSpec per managed package, version-pinned where requested. */\nfunction packageSpecsCode(pins?: PackagePins): string {\n const specs = PACKAGES.map((name) => {\n const version = pins?.[name];\n return version\n ? `Pkg.PackageSpec(name=${JSON.stringify(name)}, version=${JSON.stringify(version)})`\n : `Pkg.PackageSpec(name=${JSON.stringify(name)})`;\n });\n return `[${specs.join(\", \")}]`;\n}\n\n/**\n * Whether a provision should instantiate the shipped, resolved env (exact\n * committed package set) rather than resolving fresh: only the unpinned default\n * on the pinned Julia version, and only when the shipped env is present. Other\n * versions (a `--versions` matrix) and any package pins must resolve fresh,\n * since the committed Manifest was resolved for one specific Julia version.\n */\nfunction usesPinnedEnv(version: string | undefined, pins?: PackagePins): boolean {\n return !hasPins(pins) && version === DEFAULT_JULIA_CHANNEL && existsSync(pinnedEnvDir());\n}\n\n/**\n * Ensures the managed Julia project exists with the inference packages installed\n * (version-pinned where `pins` requests). Idempotent: returns immediately when\n * already provisioned with the current set and pins. For the default env on the\n * pinned Julia version it instantiates the shipped, resolved Manifest (the exact\n * committed package set); otherwise it resolves and adds the packages fresh. The\n * first provision 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 pins?: PackagePins,\n opts?: { version?: string },\n): Promise<string> {\n validatePins(pins);\n if (managedProjectReady(dir, pins)) return dir;\n mkdirSync(dir, { recursive: true });\n if (usesPinnedEnv(opts?.version, pins)) {\n copyFileSync(join(pinnedEnvDir(), \"Project.toml\"), join(dir, \"Project.toml\"));\n copyFileSync(join(pinnedEnvDir(), \"Manifest.toml\"), join(dir, \"Manifest.toml\"));\n await run(juliaBin, [\n \"--startup-file=no\",\n `--project=${dir}`,\n \"-e\",\n \"using Pkg; Pkg.instantiate(); Pkg.precompile()\",\n ]);\n } else {\n const code = `using Pkg; Pkg.add(${packageSpecsCode(pins)}); Pkg.precompile()`;\n await run(juliaBin, [\"--startup-file=no\", `--project=${dir}`, \"-e\", code]);\n }\n writeFileSync(sentinelPath(dir), expectedSentinel(pins));\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\" | \"cancelled\";\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 ResolvedInvocation {\n command: string;\n args: string[];\n version?: string;\n}\n\nexport interface MatrixIo {\n spawn: FitRunner;\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<ResolvedInvocation>;\n /** Provisions the managed env for a resolved version and returns its dir. */\n ensure: (resolved: ResolvedInvocation) => Promise<string>;\n /** Source path when the data came from a referenced file; recorded per version. */\n dataFile?: string;\n /** Overrides the recorded data hash (the data file's bytes hash). */\n dataSha256?: 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 projectDir = await io.ensure(resolved);\n const versioned = { ...spec, backend: { ...spec.backend, version } };\n const result = await runFit(versioned, resolved, {\n spawn: io.spawn,\n projectDir,\n outPath: join(io.outDir, `${version}.samples.json`),\n dataFile: io.dataFile,\n dataSha256: io.dataSha256,\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 // A cancelled run stops the whole matrix regardless of keepGoing.\n if (entry.status === \"cancelled\") break;\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 { DEFAULT_JULIA_CHANNEL } from \"@mcmcjs/core\";\nimport { 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 // `--default-channel` makes the installer add the pinned Julia version (not\n // just the latest \"release\") in the same step, so a clean machine lands on\n // the exact version the committed Manifest was resolved for.\n return {\n command: \"sh\",\n args: [\n \"-c\",\n `curl -fsSL ${JULIAUP_INSTALL_URL} | sh -s -- --yes --default-channel ${DEFAULT_JULIA_CHANNEL}`,\n ],\n };\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 // The pinned Julia is already the active default: nothing to do.\n if (report.julia.found && report.julia.version === DEFAULT_JULIA_CHANNEL) return [];\n if (report.juliaup.found) {\n return [\n {\n tool: \"julia\",\n label: `install the pinned Julia ${DEFAULT_JULIA_CHANNEL} via juliaup`,\n command: {\n command: report.juliaup.path ?? \"juliaup\",\n args: [\"add\", DEFAULT_JULIA_CHANNEL],\n },\n },\n ];\n }\n return [\n {\n tool: \"juliaup\",\n label: `install juliaup with the pinned Julia ${DEFAULT_JULIA_CHANNEL}`,\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 const plan = planSetup(before, platform);\n // Nothing to install only when the pinned Julia is already the active\n // default; a different installed Julia still triggers a pinned-version add.\n if (plan.length === 0) return { ...before, steps: [] };\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[]; version?: 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 ?? [], version: match.Version };\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","import { spawn } from \"node:child_process\";\nimport { mkdirSync, readdirSync, readFileSync, rmdirSync, rmSync, statSync } from \"node:fs\";\nimport { createConnection, type Socket } from \"node:net\";\nimport { join } from \"node:path\";\nimport type { ResolvedSpec } from \"@mcmcjs/core\";\nimport type { FitResult } from \"@mcmcjs/engine\";\nimport { parseDrawBatchLine, parseProgressLine } from \"@mcmcjs/engine\";\nimport { type FitIo, finalizeOkFit, fitRequest, runFit } from \"./fit\";\nimport { sha256, sharedTmpParent, toStage, workerPath } from \"./runner-common\";\n\nconst START_WAIT_MS = 180_000;\nconst CONNECT_TIMEOUT_MS = 1_000;\nconst STOP_ACK_TIMEOUT_MS = 3_000;\n\n/** Same 30-minute budget as the one-shot driver; MCMC_WORKER_TIMEOUT_MS overrides. */\nfunction fitInactivityTimeoutMs(): number {\n const fromEnv = Number(process.env.MCMC_WORKER_TIMEOUT_MS);\n return Number.isFinite(fromEnv) && fromEnv > 0 ? fromEnv : 30 * 60_000;\n}\n\n/** A hung worker is not retried; the fit is reported failed instead. */\nclass WorkerTimeoutError extends Error {}\n\n/** The caller aborted the fit; the worker is killed and the run ends cancelled. */\nclass FitCancelledError extends Error {}\n\n/** The pidfile a worker writes beside its socket so a fit can be killed cross-process. */\nfunction workerPidPath(socket: string): string {\n return `${socket}.pid`;\n}\n\n/**\n * Force-kills the worker serving `socket` (by the pid it wrote beside the\n * socket) and clears the socket and pidfile, so the next fit cold-starts a\n * fresh worker. Used to stop a worker mid-fit, which the polite stop cannot do\n * while it is busy sampling.\n */\nexport function killWorker(socket: string): void {\n const pidPath = workerPidPath(socket);\n try {\n const pid = Number(readFileSync(pidPath, \"utf8\").trim());\n if (Number.isInteger(pid) && pid > 0) {\n // The worker is a detached process-group leader, so signaling -pid takes\n // down any precompile/child processes it spawned, not just the parent.\n try {\n process.kill(-pid, \"SIGKILL\");\n } catch {\n process.kill(pid, \"SIGKILL\");\n }\n }\n } catch {}\n rmSync(socket, { force: true });\n rmSync(pidPath, { force: true });\n}\n\n/** Where worker sockets live; runtime dir when available, the shared tmp parent otherwise. */\nexport function workersDir(): string {\n const runtime = process.env.XDG_RUNTIME_DIR;\n const dir = runtime ? join(runtime, \"mcmcjs\") : join(sharedTmpParent(), \"workers\");\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n return dir;\n}\n\n/** One worker per (Julia binary, project env) pair, named by a key hash. */\nexport function workerSocketPath(command: string, projectDir: string): string {\n return join(workersDir(), `worker-${sha256(`${command}\\n${projectDir}`).slice(0, 12)}.sock`);\n}\n\nfunction connectOnce(path: string): Promise<Socket> {\n return new Promise((resolve, reject) => {\n const sock = createConnection(path);\n const timer = setTimeout(() => {\n sock.destroy();\n reject(new Error(\"connect timeout\"));\n }, CONNECT_TIMEOUT_MS);\n sock.once(\"connect\", () => {\n clearTimeout(timer);\n resolve(sock);\n });\n sock.once(\"error\", (error) => {\n clearTimeout(timer);\n reject(error);\n });\n });\n}\n\nconst delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\n/**\n * Serializes cold starts: only one invocation spawns a worker per socket path;\n * the rest poll the socket. A stale lock (a dead spawner) is taken over.\n */\nfunction acquireStartLock(socketPath: string): boolean {\n const lock = `${socketPath}.start`;\n try {\n mkdirSync(lock);\n return true;\n } catch {\n try {\n if (Date.now() - statSync(lock).mtimeMs > START_WAIT_MS) {\n rmdirSync(lock);\n mkdirSync(lock);\n return true;\n }\n } catch {}\n return false;\n }\n}\n\nfunction releaseStartLock(socketPath: string): void {\n try {\n rmdirSync(`${socketPath}.start`);\n } catch {}\n}\n\n/** Connects to the keyed worker, starting one (detached) if none answers. */\nexport async function ensureWorker(\n resolved: { command: string; args: string[] },\n projectDir: string,\n notify?: (line: string) => void,\n signal?: AbortSignal,\n): Promise<Socket> {\n const path = workerSocketPath(resolved.command, projectDir);\n try {\n return await connectOnce(path);\n } catch {}\n // Honor a cancel that arrived during the (possibly slow) cold start; the\n // detached worker keeps loading and stays warm for the next fit.\n if (signal?.aborted) throw new FitCancelledError();\n\n let spawnFailure: Error | undefined;\n const startedHere = acquireStartLock(path);\n if (startedHere) {\n try {\n rmSync(path, { force: true });\n notify?.(\"starting the Julia worker (first use loads Turing, can take a minute)...\");\n const child = spawn(\n resolved.command,\n [...resolved.args, \"--startup-file=no\", `--project=${projectDir}`, workerPath(), path],\n { detached: true, stdio: \"ignore\" },\n );\n child.on(\"error\", (error) => {\n spawnFailure = error;\n });\n child.on(\"exit\", (code) => {\n if (code !== 0 && code !== null) {\n spawnFailure = new Error(`the worker exited with code ${code} before serving`);\n }\n });\n child.unref();\n } catch (error) {\n releaseStartLock(path);\n throw error;\n }\n }\n\n try {\n const deadline = Date.now() + START_WAIT_MS;\n for (;;) {\n if (signal?.aborted) throw new FitCancelledError();\n if (spawnFailure) throw spawnFailure;\n try {\n return await connectOnce(path);\n } catch {}\n if (Date.now() > deadline) throw new Error(\"the Julia worker did not start in time\");\n await delay(250);\n }\n } finally {\n if (startedHere) releaseStartLock(path);\n }\n}\n\n/**\n * Streams progress lines to onProgress and resolves with the final result\n * line. The inactivity deadline (reset by every byte the worker sends, so\n * healthy long fits survive on their progress stream) rejects with\n * WorkerTimeoutError rather than hanging forever on a wedged worker.\n */\nfunction readWorkerResponse(\n sock: Socket,\n onProgress?: FitIo[\"onProgress\"],\n onDraws?: FitIo[\"onDraws\"],\n signal?: AbortSignal,\n inactivityMs = fitInactivityTimeoutMs(),\n): Promise<Record<string, unknown>> {\n return new Promise((resolve, reject) => {\n let pending = \"\";\n let settled = false;\n const onAbort = () => {\n settle(() => {\n sock.destroy();\n reject(new FitCancelledError());\n });\n };\n const settle = (fn: () => void) => {\n if (settled) return;\n settled = true;\n sock.setTimeout(0);\n signal?.removeEventListener(\"abort\", onAbort);\n fn();\n };\n if (signal) {\n if (signal.aborted) onAbort();\n else signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n sock.setTimeout(inactivityMs, () => {\n const error = new WorkerTimeoutError(\n `the worker sent nothing for ${Math.round(inactivityMs / 60_000)} minutes`,\n );\n settle(() => {\n sock.destroy();\n reject(error);\n });\n });\n sock.on(\"data\", (chunk: Buffer) => {\n pending += chunk.toString(\"utf8\");\n for (;;) {\n const at = pending.indexOf(\"\\n\");\n if (at === -1) break;\n const line = pending.slice(0, at).trim();\n pending = pending.slice(at + 1);\n if (!line) continue;\n const progress = parseProgressLine(line);\n if (progress) {\n onProgress?.(progress);\n continue;\n }\n const batch = parseDrawBatchLine(line);\n if (batch) {\n onDraws?.(batch);\n continue;\n }\n try {\n const doc = JSON.parse(line) as Record<string, unknown>;\n settle(() => {\n sock.end();\n resolve(doc);\n });\n return;\n } catch {}\n }\n });\n sock.on(\"error\", (error) => settle(() => reject(error)));\n sock.on(\"close\", () => settle(() => reject(new Error(\"worker closed the connection\"))));\n });\n}\n\n/** Runs one fit through the persistent worker. Throws on worker-infrastructure failure. */\nexport async function runFitViaWorker(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: FitIo & { notify?: (line: string) => void },\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n if (io.signal?.aborted) {\n return { status: \"cancelled\", runtimeRequested: spec.backend.version, elapsedMs: 0 };\n }\n let sock: Socket;\n try {\n sock = await ensureWorker(resolved, io.projectDir, io.notify, io.signal);\n } catch (error) {\n // Cancelled during the cold start: the worker (if any) is still idle and\n // stays warm; no fit was dispatched, so just report cancelled.\n if (error instanceof FitCancelledError) {\n return {\n status: \"cancelled\",\n runtimeRequested: spec.backend.version,\n elapsedMs: Math.round(performance.now() - start),\n };\n }\n throw error;\n }\n if (io.signal?.aborted) {\n // Aborted in the gap before dispatch; drop the connection, leave the worker\n // idle and warm. The worker reads an empty line and loops back to accept.\n sock.destroy();\n return {\n status: \"cancelled\",\n runtimeRequested: spec.backend.version,\n elapsedMs: Math.round(performance.now() - start),\n };\n }\n sock.write(\n `${JSON.stringify(fitRequest(spec, io.outPath, { streamDraws: io.onDraws !== undefined, drawBatchSize: io.drawBatchSize }))}\\n`,\n );\n let final: Record<string, unknown>;\n try {\n final = await readWorkerResponse(sock, io.onProgress, io.onDraws, io.signal);\n } catch (error) {\n if (error instanceof FitCancelledError) {\n // The worker is mid-sample and cannot answer a polite stop; kill it so it\n // stops promptly and the next fit cold-starts a fresh one.\n killWorker(workerSocketPath(resolved.command, io.projectDir));\n return {\n status: \"cancelled\",\n runtimeRequested: spec.backend.version,\n elapsedMs: Math.round(performance.now() - start),\n };\n }\n throw error;\n }\n const elapsedMs = Math.round(performance.now() - start);\n\n if (final.ok !== true) {\n // \"worker\" is the worker's own protocol failure, not a model failure;\n // throwing hands the fit to the one-shot driver.\n if (final.stage === \"worker\") throw new Error(String(final.error ?? \"worker error\"));\n return {\n status: \"error\",\n runtimeRequested: spec.backend.version,\n elapsedMs,\n stage: toStage(final.stage),\n error: String(final.error ?? \"worker error\"),\n };\n }\n return finalizeOkFit(\n spec,\n resolved,\n io,\n final.provenance as Record<string, unknown> | undefined,\n startedAt,\n elapsedMs,\n );\n}\n\n/**\n * Runs a fit through the worker when asked (and possible), falling back to the\n * one-shot driver on worker-infrastructure failures. Two exceptions never fall\n * back: a fit that genuinely failed (model error) is returned, and a hung\n * worker (timeout) is reported rather than silently re-run for another\n * half hour.\n */\nexport async function runFitAuto(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: FitIo & { daemon?: boolean; notify?: (line: string) => void },\n): Promise<FitResult> {\n if (io.signal?.aborted) {\n return { status: \"cancelled\", runtimeRequested: spec.backend.version, elapsedMs: 0 };\n }\n // Distributed sampling spawns worker processes and includes the model into\n // Main; the persistent worker's isolation cannot host that, so it runs one-shot.\n if (io.daemon && process.platform !== \"win32\" && spec.sampler.parallel !== \"distributed\") {\n const start = performance.now();\n try {\n return await runFitViaWorker(spec, resolved, io);\n } catch (error) {\n if (error instanceof WorkerTimeoutError) {\n return {\n status: \"error\",\n runtimeRequested: spec.backend.version,\n elapsedMs: Math.round(performance.now() - start),\n stage: \"worker\",\n error: `${error.message}; the worker may be wedged, try mcmc daemon stop`,\n };\n }\n io.notify?.(\n `worker unavailable (${(error as Error).message}); falling back to a one-shot run`,\n );\n }\n }\n return runFit(spec, resolved, io);\n}\n\nexport interface WorkerStatus {\n socket: string;\n alive: boolean;\n}\n\n/** Lists known worker sockets and whether each answers. */\nexport async function listWorkers(): Promise<WorkerStatus[]> {\n const dir = workersDir();\n const sockets = readdirSync(dir).filter((f) => f.startsWith(\"worker-\") && f.endsWith(\".sock\"));\n const statuses: WorkerStatus[] = [];\n for (const name of sockets) {\n const socket = join(dir, name);\n let alive = false;\n try {\n const sock = await connectOnce(socket);\n sock.destroy();\n alive = true;\n } catch {}\n statuses.push({ socket, alive });\n }\n return statuses;\n}\n\nexport type StopOutcome = \"stopped\" | \"stale\" | \"pending\";\n\n/**\n * Asks one worker to shut down. \"stopped\": acknowledged and gone. \"stale\": the\n * socket was dead and its file was removed. \"pending\": the worker is busy with\n * a fit; the stop request is queued and honored when the fit finishes, so the\n * live socket file is left alone.\n */\nexport async function stopWorker(socket: string): Promise<StopOutcome> {\n let sock: Socket;\n try {\n sock = await connectOnce(socket);\n } catch {\n rmSync(socket, { force: true });\n return \"stale\";\n }\n const acked = await new Promise<boolean>((resolve) => {\n const timer = setTimeout(() => resolve(false), STOP_ACK_TIMEOUT_MS);\n const finish = (ok: boolean) => {\n clearTimeout(timer);\n resolve(ok);\n };\n // Without a flowing readable side the worker's FIN is never surfaced.\n sock.resume();\n sock.on(\"close\", () => finish(true));\n sock.on(\"error\", () => finish(false));\n sock.write('{\"mcmcjs\":\"stop\"}\\n');\n });\n sock.destroy();\n if (!acked) return \"pending\";\n rmSync(socket, { force: true });\n return \"stopped\";\n}\n"],"mappings":"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","names":["import_engine","import_node_fs","import_node_path","import_node_os","import_node_path","import_node_fs","import_node_path","import_core","import_node_fs","import_node_path","import_core","import_node_fs","import_node_os","import_node_path","import_core","import_engine","import_node_path","import_core","import_node_fs","import_node_path","import_engine"]}
package/dist/index.js CHANGED
@@ -202,6 +202,7 @@ async function runFit(spec, resolved, io) {
202
202
  const args = [
203
203
  ...resolved.args,
204
204
  "--startup-file=no",
205
+ ...spec.sampler.parallel === "threads" ? ["--threads=auto"] : [],
205
206
  `--project=${io.projectDir}`,
206
207
  driverPath(),
207
208
  requestPath
@@ -979,7 +980,7 @@ async function runFitAuto(spec, resolved, io) {
979
980
  if (io.signal?.aborted) {
980
981
  return { status: "cancelled", runtimeRequested: spec.backend.version, elapsedMs: 0 };
981
982
  }
982
- if (io.daemon && process.platform !== "win32") {
983
+ if (io.daemon && process.platform !== "win32" && spec.sampler.parallel !== "distributed") {
983
984
  const start = performance.now();
984
985
  try {
985
986
  return await runFitViaWorker(spec, resolved, io);
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/loglik.ts","../src/predict.ts","../src/project.ts","../src/run-matrix.ts","../src/setup.ts","../src/versions.ts","../src/worker.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 under the home directory; we also fall back to\n// whatever is on PATH. $HOME is honored first so a sandbox that redirects HOME\n// (mcmc sandbox --strict) finds its own juliaup, not the user's.\nfunction candidates(binary: string): string[] {\n const home = process.env.HOME || homedir();\n return [join(home, \".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, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\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 { DrawBatch, FitProgress, FitResult, FitRunner } from \"@mcmcjs/engine\";\nimport { driverPath, lastJsonLine, sha256, sharedTmpParent, 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 /** Where the run record is written; defaults to `<outPath>.run.json`. */\n recordPath?: string;\n /** Streamed per-chain sampling progress. */\n onProgress?: (progress: FitProgress) => void;\n /** Streamed draw batches as sampling proceeds. */\n onDraws?: (batch: DrawBatch) => void;\n /** Raw console lines from the sampler as they arrive (structured progress/draws\n * lines are filtered out), for surfacing solver logs live. */\n onLog?: (line: string, stream: \"stdout\" | \"stderr\") => void;\n /** Draws per streamed batch (driver default 25); lower it when models have many leaves. */\n drawBatchSize?: number;\n /** Aborts an in-progress fit; the run then ends with a \"cancelled\" status. */\n signal?: AbortSignal;\n /** Source path when the data came from a referenced file; recorded, not copied. */\n dataFile?: string;\n /** Overrides the recorded data hash (e.g. the data file's bytes hash). */\n dataSha256?: string;\n tmpDir?: string;\n}\n\n/** A fresh request dir under the shared per-user tmp parent. */\nexport function makeRequestDir(kind: string): string {\n const parent = sharedTmpParent();\n mkdirSync(parent, { recursive: true });\n return mkdtempSync(join(parent, `${kind}-`));\n}\n\n/** The driver/worker request object for one fit. */\nexport function fitRequest(\n spec: ResolvedSpec,\n outPath: string,\n opts?: { streamDraws?: boolean; drawBatchSize?: number },\n): Record<string, unknown> {\n return {\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: outPath,\n ...(opts?.streamDraws ? { stream_draws: true } : {}),\n ...(opts?.drawBatchSize ? { draw_batch_size: opts.drawBatchSize } : {}),\n };\n}\n\n/**\n * Validates the written samples and records provenance; the success tail\n * shared by the one-shot driver and the worker paths.\n */\nexport function finalizeOkFit(\n spec: ResolvedSpec,\n resolved: { command: string },\n io: Pick<FitIo, \"outPath\" | \"recordPath\" | \"dataFile\" | \"dataSha256\">,\n provenance: Record<string, unknown> | undefined,\n startedAt: string,\n elapsedMs: number,\n): FitResult {\n const runtimeRequested = spec.backend.version;\n if (!existsSync(io.outPath)) {\n return {\n status: \"error\",\n runtimeRequested,\n elapsedMs,\n stage: \"write\",\n error: \"the runtime reported success but wrote no samples file\",\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 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: io.dataSha256 ?? sha256(canonicalJson(spec.data)),\n ...(io.dataFile ? { data_file: io.dataFile } : {}),\n samples_file: io.outPath,\n started_at: startedAt,\n elapsed_ms: elapsedMs,\n };\n writeFileSync(io.recordPath ?? `${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\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 if (io.signal?.aborted) {\n return { status: \"cancelled\", runtimeRequested, elapsedMs: 0 };\n }\n\n const ownTmp = io.tmpDir === undefined;\n const tmp = io.tmpDir ?? makeRequestDir(\"fit\");\n const requestPath = join(tmp, \"request.json\");\n writeFileSync(\n requestPath,\n JSON.stringify(\n fitRequest(spec, io.outPath, {\n streamDraws: io.onDraws !== undefined,\n drawBatchSize: io.drawBatchSize,\n }),\n ),\n );\n\n const args = [\n ...resolved.args,\n \"--startup-file=no\",\n `--project=${io.projectDir}`,\n driverPath(),\n requestPath,\n ];\n let stdout: string;\n let stderr: string;\n let code: number;\n let cancelled: boolean | undefined;\n try {\n ({ stdout, stderr, code, cancelled } = await io.spawn(resolved.command, args, {\n onProgress: io.onProgress,\n onDraws: io.onDraws,\n onLog: io.onLog,\n signal: io.signal,\n }));\n } finally {\n if (ownTmp) rmSync(tmp, { recursive: true, force: true });\n }\n const elapsedMs = Math.round(performance.now() - start);\n\n if (cancelled) {\n return { status: \"cancelled\", runtimeRequested, elapsedMs };\n }\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 return finalizeOkFit(spec, resolved, io, lastJsonLine(stdout), startedAt, elapsedMs);\n}\n","import { createHash } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { FitResult } from \"@mcmcjs/engine\";\n\n/**\n * The per-user parent for all mcmcjs temp state. The uid suffix keeps users\n * on a shared /tmp out of each other's way (macOS tmpdir is per-user already,\n * Linux /tmp is not).\n */\nexport function sharedTmpParent(): string {\n const uid = typeof process.getuid === \"function\" ? `-${process.getuid()}` : \"\";\n return join(tmpdir(), `mcmcjs${uid}`);\n}\n\n// The driver scripts sit next to the bundle in the published dist/ (tsup copies\n// them there), but under src/driver/ when running from source (tests, tsx). Try\n// the bundle layout first, fall back to the source layout.\nfunction driverFile(name: string): string {\n const here = dirname(fileURLToPath(import.meta.url));\n const beside = join(here, name);\n return existsSync(beside) ? beside : join(here, \"driver\", name);\n}\n\n/** Path to the shipped Julia driver. */\nexport function driverPath(): string {\n return driverFile(\"driver.jl\");\n}\n\n/** Path to the shipped persistent worker. */\nexport function workerPath(): string {\n return driverFile(\"worker.jl\");\n}\n\n/**\n * Directory holding the shipped, resolved Julia env (Project.toml + Manifest.toml),\n * next to this module in dist/. A fresh default provision instantiates this exact\n * package set rather than re-resolving the latest compatible versions.\n */\nexport function pinnedEnvDir(): string {\n return join(dirname(fileURLToPath(import.meta.url)), \"julia-env\");\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 \"worker\",\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, readFileSync, rmSync, writeFileSync } from \"node:fs\";\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 { makeRequestDir } from \"./fit\";\nimport { driverPath, lastJsonLine, sha256, toStage } from \"./runner-common\";\n\nexport interface LogLikIo {\n /** Spawns the Julia process; injectable so runLogLik is testable without Julia. */\n spawn: FitRunner;\n projectDir: string;\n /** Where the pointwise log-likelihood file is written (samples wire, one column per observation). */\n outPath: string;\n /** The posterior samples file the log-likelihood is evaluated at. */\n samplesPath: string;\n tmpDir?: string;\n}\n\n/**\n * Computes the pointwise log-likelihood of the observed data at each posterior\n * draw: one column per observation, in the same wire format as a samples file.\n * This is the input LOO/WAIC model comparison needs.\n */\nexport async function runLogLik(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: LogLikIo,\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n const runtimeRequested = spec.backend.version;\n\n const ownTmp = io.tmpDir === undefined;\n const tmp = io.tmpDir ?? makeRequestDir(\"loglik\");\n const requestPath = join(tmp, \"request.json\");\n writeFileSync(\n requestPath,\n JSON.stringify({\n mode: \"loglik\",\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 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 let stdout: string;\n let stderr: string;\n let code: number;\n try {\n ({ stdout, stderr, code } = await io.spawn(resolved.command, args));\n } finally {\n if (ownTmp) rmSync(tmp, { recursive: true, force: true });\n }\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: `log-likelihood 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 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, readFileSync, rmSync, writeFileSync } from \"node:fs\";\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 { makeRequestDir } from \"./fit\";\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 ownTmp = io.tmpDir === undefined;\n const tmp = io.tmpDir ?? makeRequestDir(\"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 let stdout: string;\n let stderr: string;\n let code: number;\n try {\n ({ stdout, stderr, code } = await io.spawn(resolved.command, args));\n } finally {\n if (ownTmp) rmSync(tmp, { recursive: true, force: true });\n }\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 { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { canonicalJson, DEFAULT_JULIA_CHANNEL } from \"@mcmcjs/core\";\nimport { type CommandRunner, createRunner } from \"@mcmcjs/engine\";\nimport { pinnedEnvDir, sha256 } from \"./runner-common\";\n\nconst PACKAGES = [\n \"Turing\",\n \"FlexiChains\",\n \"DimensionalData\",\n \"MCMCChains\",\n \"JuliaBUGS\",\n \"AdvancedHMC\",\n \"ForwardDiff\",\n \"Mooncake\",\n \"ReverseDiff\",\n \"JSON\",\n \"StableRNGs\",\n \"StatsFuns\",\n];\n\n/** Version pins for managed packages, by name (e.g. { Turing: \"0.45\" }). */\nexport type PackagePins = Record<string, string>;\n\n// Version strings are interpolated into Julia source for Pkg.add; this allows\n// only the characters of a Julia version specifier (digits, letters, and the\n// range operators) and notably excludes `$` and backticks, which would\n// otherwise let a shared spec run arbitrary Julia via string interpolation.\nconst VERSION_RE = /^[0-9A-Za-z.+~^=<>,\\s-]+$/;\n\n/** Rejects a version string that could break out of the generated Julia literal. */\nexport function validateVersionString(name: string, version: string): void {\n if (!VERSION_RE.test(version)) {\n throw new Error(\n `invalid version \"${version}\" for package ${name}; a version may contain only digits, letters, and . + ~ ^ = < > , - and spaces`,\n );\n }\n}\n\n/** Rejects pins for unmanaged packages or with unsafe version strings. */\nexport function validatePins(pins: PackagePins | undefined): void {\n for (const [name, version] of Object.entries(pins ?? {})) {\n if (!PACKAGES.includes(name)) {\n throw new Error(\n `cannot pin unknown package \"${name}\"; managed packages are: ${PACKAGES.join(\", \")}`,\n );\n }\n validateVersionString(name, version);\n }\n}\n\nfunction hasPins(pins?: PackagePins): pins is PackagePins {\n return pins !== undefined && Object.keys(pins).length > 0;\n}\n\n/**\n * The per-user directory holding a managed Julia project (Project + Manifest).\n * Keyed by the concrete Julia version AND any package pins, so each version\n * resolves its own compatible Manifest and each distinct set of pins gets its\n * own environment: a Manifest resolved by one Julia version (or package set)\n * can pin versions that fail to precompile under another. A missing version\n * and no pins falls back to the unversioned root.\n */\nexport function managedProjectDir(version?: string, pins?: PackagePins): string {\n const base = process.env.XDG_DATA_HOME || join(homedir(), \".local\", \"share\");\n const root = join(base, \"mcmcjs\", \"julia\", \"env\");\n if (!version && !hasPins(pins)) return root;\n let leaf = (version ?? \"default\").replace(/[^A-Za-z0-9._-]/g, \"_\");\n if (hasPins(pins)) leaf += `-${sha256(canonicalJson(pins)).slice(0, 8)}`;\n return join(root, leaf);\n}\n\n// Records what a managed dir was provisioned with (package set + pins), so an\n// env from an older set is healed (Pkg.add is additive) rather than left stale.\nfunction sentinelPath(dir: string): string {\n return join(dir, \".mcmcjs-packages.json\");\n}\n\n// Bumped when the provisioning changes shape so existing envs re-provision; e.g.\n// generation 1 introduced instantiating the committed Manifest for the default,\n// which a pre-existing fresh-resolved env must pick up.\nconst PROVISION_GENERATION = 1;\n\nfunction expectedSentinel(pins?: PackagePins): string {\n return canonicalJson({\n gen: PROVISION_GENERATION,\n packages: [...PACKAGES].sort(),\n pins: pins ?? {},\n });\n}\n\nfunction provisioned(dir: string, pins?: PackagePins): boolean {\n try {\n return readFileSync(sentinelPath(dir), \"utf8\").trim() === expectedSentinel(pins);\n } catch {\n return false;\n }\n}\n\n/** Whether the managed project is present and provisioned with the current package set and pins. */\nexport function managedProjectReady(\n dir: string = managedProjectDir(),\n pins?: PackagePins,\n): boolean {\n return existsSync(join(dir, \"Project.toml\")) && provisioned(dir, pins);\n}\n\n/** The `Pkg.add` argument: a PackageSpec per managed package, version-pinned where requested. */\nfunction packageSpecsCode(pins?: PackagePins): string {\n const specs = PACKAGES.map((name) => {\n const version = pins?.[name];\n return version\n ? `Pkg.PackageSpec(name=${JSON.stringify(name)}, version=${JSON.stringify(version)})`\n : `Pkg.PackageSpec(name=${JSON.stringify(name)})`;\n });\n return `[${specs.join(\", \")}]`;\n}\n\n/**\n * Whether a provision should instantiate the shipped, resolved env (exact\n * committed package set) rather than resolving fresh: only the unpinned default\n * on the pinned Julia version, and only when the shipped env is present. Other\n * versions (a `--versions` matrix) and any package pins must resolve fresh,\n * since the committed Manifest was resolved for one specific Julia version.\n */\nfunction usesPinnedEnv(version: string | undefined, pins?: PackagePins): boolean {\n return !hasPins(pins) && version === DEFAULT_JULIA_CHANNEL && existsSync(pinnedEnvDir());\n}\n\n/**\n * Ensures the managed Julia project exists with the inference packages installed\n * (version-pinned where `pins` requests). Idempotent: returns immediately when\n * already provisioned with the current set and pins. For the default env on the\n * pinned Julia version it instantiates the shipped, resolved Manifest (the exact\n * committed package set); otherwise it resolves and adds the packages fresh. The\n * first provision 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 pins?: PackagePins,\n opts?: { version?: string },\n): Promise<string> {\n validatePins(pins);\n if (managedProjectReady(dir, pins)) return dir;\n mkdirSync(dir, { recursive: true });\n if (usesPinnedEnv(opts?.version, pins)) {\n copyFileSync(join(pinnedEnvDir(), \"Project.toml\"), join(dir, \"Project.toml\"));\n copyFileSync(join(pinnedEnvDir(), \"Manifest.toml\"), join(dir, \"Manifest.toml\"));\n await run(juliaBin, [\n \"--startup-file=no\",\n `--project=${dir}`,\n \"-e\",\n \"using Pkg; Pkg.instantiate(); Pkg.precompile()\",\n ]);\n } else {\n const code = `using Pkg; Pkg.add(${packageSpecsCode(pins)}); Pkg.precompile()`;\n await run(juliaBin, [\"--startup-file=no\", `--project=${dir}`, \"-e\", code]);\n }\n writeFileSync(sentinelPath(dir), expectedSentinel(pins));\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\" | \"cancelled\";\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 ResolvedInvocation {\n command: string;\n args: string[];\n version?: string;\n}\n\nexport interface MatrixIo {\n spawn: FitRunner;\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<ResolvedInvocation>;\n /** Provisions the managed env for a resolved version and returns its dir. */\n ensure: (resolved: ResolvedInvocation) => Promise<string>;\n /** Source path when the data came from a referenced file; recorded per version. */\n dataFile?: string;\n /** Overrides the recorded data hash (the data file's bytes hash). */\n dataSha256?: 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 projectDir = await io.ensure(resolved);\n const versioned = { ...spec, backend: { ...spec.backend, version } };\n const result = await runFit(versioned, resolved, {\n spawn: io.spawn,\n projectDir,\n outPath: join(io.outDir, `${version}.samples.json`),\n dataFile: io.dataFile,\n dataSha256: io.dataSha256,\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 // A cancelled run stops the whole matrix regardless of keepGoing.\n if (entry.status === \"cancelled\") break;\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 { DEFAULT_JULIA_CHANNEL } from \"@mcmcjs/core\";\nimport { 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 // `--default-channel` makes the installer add the pinned Julia version (not\n // just the latest \"release\") in the same step, so a clean machine lands on\n // the exact version the committed Manifest was resolved for.\n return {\n command: \"sh\",\n args: [\n \"-c\",\n `curl -fsSL ${JULIAUP_INSTALL_URL} | sh -s -- --yes --default-channel ${DEFAULT_JULIA_CHANNEL}`,\n ],\n };\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 // The pinned Julia is already the active default: nothing to do.\n if (report.julia.found && report.julia.version === DEFAULT_JULIA_CHANNEL) return [];\n if (report.juliaup.found) {\n return [\n {\n tool: \"julia\",\n label: `install the pinned Julia ${DEFAULT_JULIA_CHANNEL} via juliaup`,\n command: {\n command: report.juliaup.path ?? \"juliaup\",\n args: [\"add\", DEFAULT_JULIA_CHANNEL],\n },\n },\n ];\n }\n return [\n {\n tool: \"juliaup\",\n label: `install juliaup with the pinned Julia ${DEFAULT_JULIA_CHANNEL}`,\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 const plan = planSetup(before, platform);\n // Nothing to install only when the pinned Julia is already the active\n // default; a different installed Julia still triggers a pinned-version add.\n if (plan.length === 0) return { ...before, steps: [] };\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[]; version?: 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 ?? [], version: match.Version };\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","import { spawn } from \"node:child_process\";\nimport { mkdirSync, readdirSync, readFileSync, rmdirSync, rmSync, statSync } from \"node:fs\";\nimport { createConnection, type Socket } from \"node:net\";\nimport { join } from \"node:path\";\nimport type { ResolvedSpec } from \"@mcmcjs/core\";\nimport type { FitResult } from \"@mcmcjs/engine\";\nimport { parseDrawBatchLine, parseProgressLine } from \"@mcmcjs/engine\";\nimport { type FitIo, finalizeOkFit, fitRequest, runFit } from \"./fit\";\nimport { sha256, sharedTmpParent, toStage, workerPath } from \"./runner-common\";\n\nconst START_WAIT_MS = 180_000;\nconst CONNECT_TIMEOUT_MS = 1_000;\nconst STOP_ACK_TIMEOUT_MS = 3_000;\n\n/** Same 30-minute budget as the one-shot driver; MCMC_WORKER_TIMEOUT_MS overrides. */\nfunction fitInactivityTimeoutMs(): number {\n const fromEnv = Number(process.env.MCMC_WORKER_TIMEOUT_MS);\n return Number.isFinite(fromEnv) && fromEnv > 0 ? fromEnv : 30 * 60_000;\n}\n\n/** A hung worker is not retried; the fit is reported failed instead. */\nclass WorkerTimeoutError extends Error {}\n\n/** The caller aborted the fit; the worker is killed and the run ends cancelled. */\nclass FitCancelledError extends Error {}\n\n/** The pidfile a worker writes beside its socket so a fit can be killed cross-process. */\nfunction workerPidPath(socket: string): string {\n return `${socket}.pid`;\n}\n\n/**\n * Force-kills the worker serving `socket` (by the pid it wrote beside the\n * socket) and clears the socket and pidfile, so the next fit cold-starts a\n * fresh worker. Used to stop a worker mid-fit, which the polite stop cannot do\n * while it is busy sampling.\n */\nexport function killWorker(socket: string): void {\n const pidPath = workerPidPath(socket);\n try {\n const pid = Number(readFileSync(pidPath, \"utf8\").trim());\n if (Number.isInteger(pid) && pid > 0) {\n // The worker is a detached process-group leader, so signaling -pid takes\n // down any precompile/child processes it spawned, not just the parent.\n try {\n process.kill(-pid, \"SIGKILL\");\n } catch {\n process.kill(pid, \"SIGKILL\");\n }\n }\n } catch {}\n rmSync(socket, { force: true });\n rmSync(pidPath, { force: true });\n}\n\n/** Where worker sockets live; runtime dir when available, the shared tmp parent otherwise. */\nexport function workersDir(): string {\n const runtime = process.env.XDG_RUNTIME_DIR;\n const dir = runtime ? join(runtime, \"mcmcjs\") : join(sharedTmpParent(), \"workers\");\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n return dir;\n}\n\n/** One worker per (Julia binary, project env) pair, named by a key hash. */\nexport function workerSocketPath(command: string, projectDir: string): string {\n return join(workersDir(), `worker-${sha256(`${command}\\n${projectDir}`).slice(0, 12)}.sock`);\n}\n\nfunction connectOnce(path: string): Promise<Socket> {\n return new Promise((resolve, reject) => {\n const sock = createConnection(path);\n const timer = setTimeout(() => {\n sock.destroy();\n reject(new Error(\"connect timeout\"));\n }, CONNECT_TIMEOUT_MS);\n sock.once(\"connect\", () => {\n clearTimeout(timer);\n resolve(sock);\n });\n sock.once(\"error\", (error) => {\n clearTimeout(timer);\n reject(error);\n });\n });\n}\n\nconst delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\n/**\n * Serializes cold starts: only one invocation spawns a worker per socket path;\n * the rest poll the socket. A stale lock (a dead spawner) is taken over.\n */\nfunction acquireStartLock(socketPath: string): boolean {\n const lock = `${socketPath}.start`;\n try {\n mkdirSync(lock);\n return true;\n } catch {\n try {\n if (Date.now() - statSync(lock).mtimeMs > START_WAIT_MS) {\n rmdirSync(lock);\n mkdirSync(lock);\n return true;\n }\n } catch {}\n return false;\n }\n}\n\nfunction releaseStartLock(socketPath: string): void {\n try {\n rmdirSync(`${socketPath}.start`);\n } catch {}\n}\n\n/** Connects to the keyed worker, starting one (detached) if none answers. */\nexport async function ensureWorker(\n resolved: { command: string; args: string[] },\n projectDir: string,\n notify?: (line: string) => void,\n signal?: AbortSignal,\n): Promise<Socket> {\n const path = workerSocketPath(resolved.command, projectDir);\n try {\n return await connectOnce(path);\n } catch {}\n // Honor a cancel that arrived during the (possibly slow) cold start; the\n // detached worker keeps loading and stays warm for the next fit.\n if (signal?.aborted) throw new FitCancelledError();\n\n let spawnFailure: Error | undefined;\n const startedHere = acquireStartLock(path);\n if (startedHere) {\n try {\n rmSync(path, { force: true });\n notify?.(\"starting the Julia worker (first use loads Turing, can take a minute)...\");\n const child = spawn(\n resolved.command,\n [...resolved.args, \"--startup-file=no\", `--project=${projectDir}`, workerPath(), path],\n { detached: true, stdio: \"ignore\" },\n );\n child.on(\"error\", (error) => {\n spawnFailure = error;\n });\n child.on(\"exit\", (code) => {\n if (code !== 0 && code !== null) {\n spawnFailure = new Error(`the worker exited with code ${code} before serving`);\n }\n });\n child.unref();\n } catch (error) {\n releaseStartLock(path);\n throw error;\n }\n }\n\n try {\n const deadline = Date.now() + START_WAIT_MS;\n for (;;) {\n if (signal?.aborted) throw new FitCancelledError();\n if (spawnFailure) throw spawnFailure;\n try {\n return await connectOnce(path);\n } catch {}\n if (Date.now() > deadline) throw new Error(\"the Julia worker did not start in time\");\n await delay(250);\n }\n } finally {\n if (startedHere) releaseStartLock(path);\n }\n}\n\n/**\n * Streams progress lines to onProgress and resolves with the final result\n * line. The inactivity deadline (reset by every byte the worker sends, so\n * healthy long fits survive on their progress stream) rejects with\n * WorkerTimeoutError rather than hanging forever on a wedged worker.\n */\nfunction readWorkerResponse(\n sock: Socket,\n onProgress?: FitIo[\"onProgress\"],\n onDraws?: FitIo[\"onDraws\"],\n signal?: AbortSignal,\n inactivityMs = fitInactivityTimeoutMs(),\n): Promise<Record<string, unknown>> {\n return new Promise((resolve, reject) => {\n let pending = \"\";\n let settled = false;\n const onAbort = () => {\n settle(() => {\n sock.destroy();\n reject(new FitCancelledError());\n });\n };\n const settle = (fn: () => void) => {\n if (settled) return;\n settled = true;\n sock.setTimeout(0);\n signal?.removeEventListener(\"abort\", onAbort);\n fn();\n };\n if (signal) {\n if (signal.aborted) onAbort();\n else signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n sock.setTimeout(inactivityMs, () => {\n const error = new WorkerTimeoutError(\n `the worker sent nothing for ${Math.round(inactivityMs / 60_000)} minutes`,\n );\n settle(() => {\n sock.destroy();\n reject(error);\n });\n });\n sock.on(\"data\", (chunk: Buffer) => {\n pending += chunk.toString(\"utf8\");\n for (;;) {\n const at = pending.indexOf(\"\\n\");\n if (at === -1) break;\n const line = pending.slice(0, at).trim();\n pending = pending.slice(at + 1);\n if (!line) continue;\n const progress = parseProgressLine(line);\n if (progress) {\n onProgress?.(progress);\n continue;\n }\n const batch = parseDrawBatchLine(line);\n if (batch) {\n onDraws?.(batch);\n continue;\n }\n try {\n const doc = JSON.parse(line) as Record<string, unknown>;\n settle(() => {\n sock.end();\n resolve(doc);\n });\n return;\n } catch {}\n }\n });\n sock.on(\"error\", (error) => settle(() => reject(error)));\n sock.on(\"close\", () => settle(() => reject(new Error(\"worker closed the connection\"))));\n });\n}\n\n/** Runs one fit through the persistent worker. Throws on worker-infrastructure failure. */\nexport async function runFitViaWorker(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: FitIo & { notify?: (line: string) => void },\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n if (io.signal?.aborted) {\n return { status: \"cancelled\", runtimeRequested: spec.backend.version, elapsedMs: 0 };\n }\n let sock: Socket;\n try {\n sock = await ensureWorker(resolved, io.projectDir, io.notify, io.signal);\n } catch (error) {\n // Cancelled during the cold start: the worker (if any) is still idle and\n // stays warm; no fit was dispatched, so just report cancelled.\n if (error instanceof FitCancelledError) {\n return {\n status: \"cancelled\",\n runtimeRequested: spec.backend.version,\n elapsedMs: Math.round(performance.now() - start),\n };\n }\n throw error;\n }\n if (io.signal?.aborted) {\n // Aborted in the gap before dispatch; drop the connection, leave the worker\n // idle and warm. The worker reads an empty line and loops back to accept.\n sock.destroy();\n return {\n status: \"cancelled\",\n runtimeRequested: spec.backend.version,\n elapsedMs: Math.round(performance.now() - start),\n };\n }\n sock.write(\n `${JSON.stringify(fitRequest(spec, io.outPath, { streamDraws: io.onDraws !== undefined, drawBatchSize: io.drawBatchSize }))}\\n`,\n );\n let final: Record<string, unknown>;\n try {\n final = await readWorkerResponse(sock, io.onProgress, io.onDraws, io.signal);\n } catch (error) {\n if (error instanceof FitCancelledError) {\n // The worker is mid-sample and cannot answer a polite stop; kill it so it\n // stops promptly and the next fit cold-starts a fresh one.\n killWorker(workerSocketPath(resolved.command, io.projectDir));\n return {\n status: \"cancelled\",\n runtimeRequested: spec.backend.version,\n elapsedMs: Math.round(performance.now() - start),\n };\n }\n throw error;\n }\n const elapsedMs = Math.round(performance.now() - start);\n\n if (final.ok !== true) {\n // \"worker\" is the worker's own protocol failure, not a model failure;\n // throwing hands the fit to the one-shot driver.\n if (final.stage === \"worker\") throw new Error(String(final.error ?? \"worker error\"));\n return {\n status: \"error\",\n runtimeRequested: spec.backend.version,\n elapsedMs,\n stage: toStage(final.stage),\n error: String(final.error ?? \"worker error\"),\n };\n }\n return finalizeOkFit(\n spec,\n resolved,\n io,\n final.provenance as Record<string, unknown> | undefined,\n startedAt,\n elapsedMs,\n );\n}\n\n/**\n * Runs a fit through the worker when asked (and possible), falling back to the\n * one-shot driver on worker-infrastructure failures. Two exceptions never fall\n * back: a fit that genuinely failed (model error) is returned, and a hung\n * worker (timeout) is reported rather than silently re-run for another\n * half hour.\n */\nexport async function runFitAuto(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: FitIo & { daemon?: boolean; notify?: (line: string) => void },\n): Promise<FitResult> {\n if (io.signal?.aborted) {\n return { status: \"cancelled\", runtimeRequested: spec.backend.version, elapsedMs: 0 };\n }\n if (io.daemon && process.platform !== \"win32\") {\n const start = performance.now();\n try {\n return await runFitViaWorker(spec, resolved, io);\n } catch (error) {\n if (error instanceof WorkerTimeoutError) {\n return {\n status: \"error\",\n runtimeRequested: spec.backend.version,\n elapsedMs: Math.round(performance.now() - start),\n stage: \"worker\",\n error: `${error.message}; the worker may be wedged, try mcmc daemon stop`,\n };\n }\n io.notify?.(\n `worker unavailable (${(error as Error).message}); falling back to a one-shot run`,\n );\n }\n }\n return runFit(spec, resolved, io);\n}\n\nexport interface WorkerStatus {\n socket: string;\n alive: boolean;\n}\n\n/** Lists known worker sockets and whether each answers. */\nexport async function listWorkers(): Promise<WorkerStatus[]> {\n const dir = workersDir();\n const sockets = readdirSync(dir).filter((f) => f.startsWith(\"worker-\") && f.endsWith(\".sock\"));\n const statuses: WorkerStatus[] = [];\n for (const name of sockets) {\n const socket = join(dir, name);\n let alive = false;\n try {\n const sock = await connectOnce(socket);\n sock.destroy();\n alive = true;\n } catch {}\n statuses.push({ socket, alive });\n }\n return statuses;\n}\n\nexport type StopOutcome = \"stopped\" | \"stale\" | \"pending\";\n\n/**\n * Asks one worker to shut down. \"stopped\": acknowledged and gone. \"stale\": the\n * socket was dead and its file was removed. \"pending\": the worker is busy with\n * a fit; the stop request is queued and honored when the fit finishes, so the\n * live socket file is left alone.\n */\nexport async function stopWorker(socket: string): Promise<StopOutcome> {\n let sock: Socket;\n try {\n sock = await connectOnce(socket);\n } catch {\n rmSync(socket, { force: true });\n return \"stale\";\n }\n const acked = await new Promise<boolean>((resolve) => {\n const timer = setTimeout(() => resolve(false), STOP_ACK_TIMEOUT_MS);\n const finish = (ok: boolean) => {\n clearTimeout(timer);\n resolve(ok);\n };\n // Without a flowing readable side the worker's FIN is never surfaced.\n sock.resume();\n sock.on(\"close\", () => finish(true));\n sock.on(\"error\", () => finish(false));\n sock.write('{\"mcmcjs\":\"stop\"}\\n');\n });\n sock.destroy();\n if (!acked) return \"pending\";\n rmSync(socket, { force: true });\n return \"stopped\";\n}\n"],"mappings":"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","names":["createRunner","existsSync","join","join","join","existsSync","existsSync","readFileSync","rmSync","writeFileSync","join","canonicalJson","parseSamples","RUN_RECORD_SCHEMA_VERSION","join","writeFileSync","rmSync","existsSync","parseSamples","readFileSync","RUN_RECORD_SCHEMA_VERSION","canonicalJson","existsSync","readFileSync","rmSync","writeFileSync","join","canonicalJson","parseSamples","RUN_RECORD_SCHEMA_VERSION","join","writeFileSync","rmSync","existsSync","parseSamples","readFileSync","RUN_RECORD_SCHEMA_VERSION","canonicalJson","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","join","canonicalJson","createRunner","join","homedir","canonicalJson","readFileSync","existsSync","createRunner","mkdirSync","writeFileSync","join","join","DEFAULT_JULIA_CHANNEL","DEFAULT_JULIA_CHANNEL","createRunner","mkdirSync","readFileSync","rmSync","join","readFileSync","rmSync","join","mkdirSync"]}
1
+ {"version":3,"sources":["../src/environment.ts","../src/doctor.ts","../src/engine.ts","../src/fit.ts","../src/runner-common.ts","../src/loglik.ts","../src/predict.ts","../src/project.ts","../src/run-matrix.ts","../src/setup.ts","../src/versions.ts","../src/worker.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 under the home directory; we also fall back to\n// whatever is on PATH. $HOME is honored first so a sandbox that redirects HOME\n// (mcmc sandbox --strict) finds its own juliaup, not the user's.\nfunction candidates(binary: string): string[] {\n const home = process.env.HOME || homedir();\n return [join(home, \".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, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\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 { DrawBatch, FitProgress, FitResult, FitRunner } from \"@mcmcjs/engine\";\nimport { driverPath, lastJsonLine, sha256, sharedTmpParent, 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 /** Where the run record is written; defaults to `<outPath>.run.json`. */\n recordPath?: string;\n /** Streamed per-chain sampling progress. */\n onProgress?: (progress: FitProgress) => void;\n /** Streamed draw batches as sampling proceeds. */\n onDraws?: (batch: DrawBatch) => void;\n /** Raw console lines from the sampler as they arrive (structured progress/draws\n * lines are filtered out), for surfacing solver logs live. */\n onLog?: (line: string, stream: \"stdout\" | \"stderr\") => void;\n /** Draws per streamed batch (driver default 25); lower it when models have many leaves. */\n drawBatchSize?: number;\n /** Aborts an in-progress fit; the run then ends with a \"cancelled\" status. */\n signal?: AbortSignal;\n /** Source path when the data came from a referenced file; recorded, not copied. */\n dataFile?: string;\n /** Overrides the recorded data hash (e.g. the data file's bytes hash). */\n dataSha256?: string;\n tmpDir?: string;\n}\n\n/** A fresh request dir under the shared per-user tmp parent. */\nexport function makeRequestDir(kind: string): string {\n const parent = sharedTmpParent();\n mkdirSync(parent, { recursive: true });\n return mkdtempSync(join(parent, `${kind}-`));\n}\n\n/** The driver/worker request object for one fit. */\nexport function fitRequest(\n spec: ResolvedSpec,\n outPath: string,\n opts?: { streamDraws?: boolean; drawBatchSize?: number },\n): Record<string, unknown> {\n return {\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: outPath,\n ...(opts?.streamDraws ? { stream_draws: true } : {}),\n ...(opts?.drawBatchSize ? { draw_batch_size: opts.drawBatchSize } : {}),\n };\n}\n\n/**\n * Validates the written samples and records provenance; the success tail\n * shared by the one-shot driver and the worker paths.\n */\nexport function finalizeOkFit(\n spec: ResolvedSpec,\n resolved: { command: string },\n io: Pick<FitIo, \"outPath\" | \"recordPath\" | \"dataFile\" | \"dataSha256\">,\n provenance: Record<string, unknown> | undefined,\n startedAt: string,\n elapsedMs: number,\n): FitResult {\n const runtimeRequested = spec.backend.version;\n if (!existsSync(io.outPath)) {\n return {\n status: \"error\",\n runtimeRequested,\n elapsedMs,\n stage: \"write\",\n error: \"the runtime reported success but wrote no samples file\",\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 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: io.dataSha256 ?? sha256(canonicalJson(spec.data)),\n ...(io.dataFile ? { data_file: io.dataFile } : {}),\n samples_file: io.outPath,\n started_at: startedAt,\n elapsed_ms: elapsedMs,\n };\n writeFileSync(io.recordPath ?? `${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\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 if (io.signal?.aborted) {\n return { status: \"cancelled\", runtimeRequested, elapsedMs: 0 };\n }\n\n const ownTmp = io.tmpDir === undefined;\n const tmp = io.tmpDir ?? makeRequestDir(\"fit\");\n const requestPath = join(tmp, \"request.json\");\n writeFileSync(\n requestPath,\n JSON.stringify(\n fitRequest(spec, io.outPath, {\n streamDraws: io.onDraws !== undefined,\n drawBatchSize: io.drawBatchSize,\n }),\n ),\n );\n\n const args = [\n ...resolved.args,\n \"--startup-file=no\",\n ...(spec.sampler.parallel === \"threads\" ? [\"--threads=auto\"] : []),\n `--project=${io.projectDir}`,\n driverPath(),\n requestPath,\n ];\n let stdout: string;\n let stderr: string;\n let code: number;\n let cancelled: boolean | undefined;\n try {\n ({ stdout, stderr, code, cancelled } = await io.spawn(resolved.command, args, {\n onProgress: io.onProgress,\n onDraws: io.onDraws,\n onLog: io.onLog,\n signal: io.signal,\n }));\n } finally {\n if (ownTmp) rmSync(tmp, { recursive: true, force: true });\n }\n const elapsedMs = Math.round(performance.now() - start);\n\n if (cancelled) {\n return { status: \"cancelled\", runtimeRequested, elapsedMs };\n }\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 return finalizeOkFit(spec, resolved, io, lastJsonLine(stdout), startedAt, elapsedMs);\n}\n","import { createHash } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { FitResult } from \"@mcmcjs/engine\";\n\n/**\n * The per-user parent for all mcmcjs temp state. The uid suffix keeps users\n * on a shared /tmp out of each other's way (macOS tmpdir is per-user already,\n * Linux /tmp is not).\n */\nexport function sharedTmpParent(): string {\n const uid = typeof process.getuid === \"function\" ? `-${process.getuid()}` : \"\";\n return join(tmpdir(), `mcmcjs${uid}`);\n}\n\n// The driver scripts sit next to the bundle in the published dist/ (tsup copies\n// them there), but under src/driver/ when running from source (tests, tsx). Try\n// the bundle layout first, fall back to the source layout.\nfunction driverFile(name: string): string {\n const here = dirname(fileURLToPath(import.meta.url));\n const beside = join(here, name);\n return existsSync(beside) ? beside : join(here, \"driver\", name);\n}\n\n/** Path to the shipped Julia driver. */\nexport function driverPath(): string {\n return driverFile(\"driver.jl\");\n}\n\n/** Path to the shipped persistent worker. */\nexport function workerPath(): string {\n return driverFile(\"worker.jl\");\n}\n\n/**\n * Directory holding the shipped, resolved Julia env (Project.toml + Manifest.toml),\n * next to this module in dist/. A fresh default provision instantiates this exact\n * package set rather than re-resolving the latest compatible versions.\n */\nexport function pinnedEnvDir(): string {\n return join(dirname(fileURLToPath(import.meta.url)), \"julia-env\");\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 \"worker\",\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, readFileSync, rmSync, writeFileSync } from \"node:fs\";\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 { makeRequestDir } from \"./fit\";\nimport { driverPath, lastJsonLine, sha256, toStage } from \"./runner-common\";\n\nexport interface LogLikIo {\n /** Spawns the Julia process; injectable so runLogLik is testable without Julia. */\n spawn: FitRunner;\n projectDir: string;\n /** Where the pointwise log-likelihood file is written (samples wire, one column per observation). */\n outPath: string;\n /** The posterior samples file the log-likelihood is evaluated at. */\n samplesPath: string;\n tmpDir?: string;\n}\n\n/**\n * Computes the pointwise log-likelihood of the observed data at each posterior\n * draw: one column per observation, in the same wire format as a samples file.\n * This is the input LOO/WAIC model comparison needs.\n */\nexport async function runLogLik(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: LogLikIo,\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n const runtimeRequested = spec.backend.version;\n\n const ownTmp = io.tmpDir === undefined;\n const tmp = io.tmpDir ?? makeRequestDir(\"loglik\");\n const requestPath = join(tmp, \"request.json\");\n writeFileSync(\n requestPath,\n JSON.stringify({\n mode: \"loglik\",\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 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 let stdout: string;\n let stderr: string;\n let code: number;\n try {\n ({ stdout, stderr, code } = await io.spawn(resolved.command, args));\n } finally {\n if (ownTmp) rmSync(tmp, { recursive: true, force: true });\n }\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: `log-likelihood 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 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, readFileSync, rmSync, writeFileSync } from \"node:fs\";\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 { makeRequestDir } from \"./fit\";\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 ownTmp = io.tmpDir === undefined;\n const tmp = io.tmpDir ?? makeRequestDir(\"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 let stdout: string;\n let stderr: string;\n let code: number;\n try {\n ({ stdout, stderr, code } = await io.spawn(resolved.command, args));\n } finally {\n if (ownTmp) rmSync(tmp, { recursive: true, force: true });\n }\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 { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { canonicalJson, DEFAULT_JULIA_CHANNEL } from \"@mcmcjs/core\";\nimport { type CommandRunner, createRunner } from \"@mcmcjs/engine\";\nimport { pinnedEnvDir, sha256 } from \"./runner-common\";\n\nconst PACKAGES = [\n \"Turing\",\n \"FlexiChains\",\n \"DimensionalData\",\n \"MCMCChains\",\n \"JuliaBUGS\",\n \"AdvancedHMC\",\n \"ForwardDiff\",\n \"Mooncake\",\n \"ReverseDiff\",\n \"JSON\",\n \"StableRNGs\",\n \"StatsFuns\",\n];\n\n/** Version pins for managed packages, by name (e.g. { Turing: \"0.45\" }). */\nexport type PackagePins = Record<string, string>;\n\n// Version strings are interpolated into Julia source for Pkg.add; this allows\n// only the characters of a Julia version specifier (digits, letters, and the\n// range operators) and notably excludes `$` and backticks, which would\n// otherwise let a shared spec run arbitrary Julia via string interpolation.\nconst VERSION_RE = /^[0-9A-Za-z.+~^=<>,\\s-]+$/;\n\n/** Rejects a version string that could break out of the generated Julia literal. */\nexport function validateVersionString(name: string, version: string): void {\n if (!VERSION_RE.test(version)) {\n throw new Error(\n `invalid version \"${version}\" for package ${name}; a version may contain only digits, letters, and . + ~ ^ = < > , - and spaces`,\n );\n }\n}\n\n/** Rejects pins for unmanaged packages or with unsafe version strings. */\nexport function validatePins(pins: PackagePins | undefined): void {\n for (const [name, version] of Object.entries(pins ?? {})) {\n if (!PACKAGES.includes(name)) {\n throw new Error(\n `cannot pin unknown package \"${name}\"; managed packages are: ${PACKAGES.join(\", \")}`,\n );\n }\n validateVersionString(name, version);\n }\n}\n\nfunction hasPins(pins?: PackagePins): pins is PackagePins {\n return pins !== undefined && Object.keys(pins).length > 0;\n}\n\n/**\n * The per-user directory holding a managed Julia project (Project + Manifest).\n * Keyed by the concrete Julia version AND any package pins, so each version\n * resolves its own compatible Manifest and each distinct set of pins gets its\n * own environment: a Manifest resolved by one Julia version (or package set)\n * can pin versions that fail to precompile under another. A missing version\n * and no pins falls back to the unversioned root.\n */\nexport function managedProjectDir(version?: string, pins?: PackagePins): string {\n const base = process.env.XDG_DATA_HOME || join(homedir(), \".local\", \"share\");\n const root = join(base, \"mcmcjs\", \"julia\", \"env\");\n if (!version && !hasPins(pins)) return root;\n let leaf = (version ?? \"default\").replace(/[^A-Za-z0-9._-]/g, \"_\");\n if (hasPins(pins)) leaf += `-${sha256(canonicalJson(pins)).slice(0, 8)}`;\n return join(root, leaf);\n}\n\n// Records what a managed dir was provisioned with (package set + pins), so an\n// env from an older set is healed (Pkg.add is additive) rather than left stale.\nfunction sentinelPath(dir: string): string {\n return join(dir, \".mcmcjs-packages.json\");\n}\n\n// Bumped when the provisioning changes shape so existing envs re-provision; e.g.\n// generation 1 introduced instantiating the committed Manifest for the default,\n// which a pre-existing fresh-resolved env must pick up.\nconst PROVISION_GENERATION = 1;\n\nfunction expectedSentinel(pins?: PackagePins): string {\n return canonicalJson({\n gen: PROVISION_GENERATION,\n packages: [...PACKAGES].sort(),\n pins: pins ?? {},\n });\n}\n\nfunction provisioned(dir: string, pins?: PackagePins): boolean {\n try {\n return readFileSync(sentinelPath(dir), \"utf8\").trim() === expectedSentinel(pins);\n } catch {\n return false;\n }\n}\n\n/** Whether the managed project is present and provisioned with the current package set and pins. */\nexport function managedProjectReady(\n dir: string = managedProjectDir(),\n pins?: PackagePins,\n): boolean {\n return existsSync(join(dir, \"Project.toml\")) && provisioned(dir, pins);\n}\n\n/** The `Pkg.add` argument: a PackageSpec per managed package, version-pinned where requested. */\nfunction packageSpecsCode(pins?: PackagePins): string {\n const specs = PACKAGES.map((name) => {\n const version = pins?.[name];\n return version\n ? `Pkg.PackageSpec(name=${JSON.stringify(name)}, version=${JSON.stringify(version)})`\n : `Pkg.PackageSpec(name=${JSON.stringify(name)})`;\n });\n return `[${specs.join(\", \")}]`;\n}\n\n/**\n * Whether a provision should instantiate the shipped, resolved env (exact\n * committed package set) rather than resolving fresh: only the unpinned default\n * on the pinned Julia version, and only when the shipped env is present. Other\n * versions (a `--versions` matrix) and any package pins must resolve fresh,\n * since the committed Manifest was resolved for one specific Julia version.\n */\nfunction usesPinnedEnv(version: string | undefined, pins?: PackagePins): boolean {\n return !hasPins(pins) && version === DEFAULT_JULIA_CHANNEL && existsSync(pinnedEnvDir());\n}\n\n/**\n * Ensures the managed Julia project exists with the inference packages installed\n * (version-pinned where `pins` requests). Idempotent: returns immediately when\n * already provisioned with the current set and pins. For the default env on the\n * pinned Julia version it instantiates the shipped, resolved Manifest (the exact\n * committed package set); otherwise it resolves and adds the packages fresh. The\n * first provision 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 pins?: PackagePins,\n opts?: { version?: string },\n): Promise<string> {\n validatePins(pins);\n if (managedProjectReady(dir, pins)) return dir;\n mkdirSync(dir, { recursive: true });\n if (usesPinnedEnv(opts?.version, pins)) {\n copyFileSync(join(pinnedEnvDir(), \"Project.toml\"), join(dir, \"Project.toml\"));\n copyFileSync(join(pinnedEnvDir(), \"Manifest.toml\"), join(dir, \"Manifest.toml\"));\n await run(juliaBin, [\n \"--startup-file=no\",\n `--project=${dir}`,\n \"-e\",\n \"using Pkg; Pkg.instantiate(); Pkg.precompile()\",\n ]);\n } else {\n const code = `using Pkg; Pkg.add(${packageSpecsCode(pins)}); Pkg.precompile()`;\n await run(juliaBin, [\"--startup-file=no\", `--project=${dir}`, \"-e\", code]);\n }\n writeFileSync(sentinelPath(dir), expectedSentinel(pins));\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\" | \"cancelled\";\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 ResolvedInvocation {\n command: string;\n args: string[];\n version?: string;\n}\n\nexport interface MatrixIo {\n spawn: FitRunner;\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<ResolvedInvocation>;\n /** Provisions the managed env for a resolved version and returns its dir. */\n ensure: (resolved: ResolvedInvocation) => Promise<string>;\n /** Source path when the data came from a referenced file; recorded per version. */\n dataFile?: string;\n /** Overrides the recorded data hash (the data file's bytes hash). */\n dataSha256?: 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 projectDir = await io.ensure(resolved);\n const versioned = { ...spec, backend: { ...spec.backend, version } };\n const result = await runFit(versioned, resolved, {\n spawn: io.spawn,\n projectDir,\n outPath: join(io.outDir, `${version}.samples.json`),\n dataFile: io.dataFile,\n dataSha256: io.dataSha256,\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 // A cancelled run stops the whole matrix regardless of keepGoing.\n if (entry.status === \"cancelled\") break;\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 { DEFAULT_JULIA_CHANNEL } from \"@mcmcjs/core\";\nimport { 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 // `--default-channel` makes the installer add the pinned Julia version (not\n // just the latest \"release\") in the same step, so a clean machine lands on\n // the exact version the committed Manifest was resolved for.\n return {\n command: \"sh\",\n args: [\n \"-c\",\n `curl -fsSL ${JULIAUP_INSTALL_URL} | sh -s -- --yes --default-channel ${DEFAULT_JULIA_CHANNEL}`,\n ],\n };\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 // The pinned Julia is already the active default: nothing to do.\n if (report.julia.found && report.julia.version === DEFAULT_JULIA_CHANNEL) return [];\n if (report.juliaup.found) {\n return [\n {\n tool: \"julia\",\n label: `install the pinned Julia ${DEFAULT_JULIA_CHANNEL} via juliaup`,\n command: {\n command: report.juliaup.path ?? \"juliaup\",\n args: [\"add\", DEFAULT_JULIA_CHANNEL],\n },\n },\n ];\n }\n return [\n {\n tool: \"juliaup\",\n label: `install juliaup with the pinned Julia ${DEFAULT_JULIA_CHANNEL}`,\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 const plan = planSetup(before, platform);\n // Nothing to install only when the pinned Julia is already the active\n // default; a different installed Julia still triggers a pinned-version add.\n if (plan.length === 0) return { ...before, steps: [] };\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[]; version?: 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 ?? [], version: match.Version };\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","import { spawn } from \"node:child_process\";\nimport { mkdirSync, readdirSync, readFileSync, rmdirSync, rmSync, statSync } from \"node:fs\";\nimport { createConnection, type Socket } from \"node:net\";\nimport { join } from \"node:path\";\nimport type { ResolvedSpec } from \"@mcmcjs/core\";\nimport type { FitResult } from \"@mcmcjs/engine\";\nimport { parseDrawBatchLine, parseProgressLine } from \"@mcmcjs/engine\";\nimport { type FitIo, finalizeOkFit, fitRequest, runFit } from \"./fit\";\nimport { sha256, sharedTmpParent, toStage, workerPath } from \"./runner-common\";\n\nconst START_WAIT_MS = 180_000;\nconst CONNECT_TIMEOUT_MS = 1_000;\nconst STOP_ACK_TIMEOUT_MS = 3_000;\n\n/** Same 30-minute budget as the one-shot driver; MCMC_WORKER_TIMEOUT_MS overrides. */\nfunction fitInactivityTimeoutMs(): number {\n const fromEnv = Number(process.env.MCMC_WORKER_TIMEOUT_MS);\n return Number.isFinite(fromEnv) && fromEnv > 0 ? fromEnv : 30 * 60_000;\n}\n\n/** A hung worker is not retried; the fit is reported failed instead. */\nclass WorkerTimeoutError extends Error {}\n\n/** The caller aborted the fit; the worker is killed and the run ends cancelled. */\nclass FitCancelledError extends Error {}\n\n/** The pidfile a worker writes beside its socket so a fit can be killed cross-process. */\nfunction workerPidPath(socket: string): string {\n return `${socket}.pid`;\n}\n\n/**\n * Force-kills the worker serving `socket` (by the pid it wrote beside the\n * socket) and clears the socket and pidfile, so the next fit cold-starts a\n * fresh worker. Used to stop a worker mid-fit, which the polite stop cannot do\n * while it is busy sampling.\n */\nexport function killWorker(socket: string): void {\n const pidPath = workerPidPath(socket);\n try {\n const pid = Number(readFileSync(pidPath, \"utf8\").trim());\n if (Number.isInteger(pid) && pid > 0) {\n // The worker is a detached process-group leader, so signaling -pid takes\n // down any precompile/child processes it spawned, not just the parent.\n try {\n process.kill(-pid, \"SIGKILL\");\n } catch {\n process.kill(pid, \"SIGKILL\");\n }\n }\n } catch {}\n rmSync(socket, { force: true });\n rmSync(pidPath, { force: true });\n}\n\n/** Where worker sockets live; runtime dir when available, the shared tmp parent otherwise. */\nexport function workersDir(): string {\n const runtime = process.env.XDG_RUNTIME_DIR;\n const dir = runtime ? join(runtime, \"mcmcjs\") : join(sharedTmpParent(), \"workers\");\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n return dir;\n}\n\n/** One worker per (Julia binary, project env) pair, named by a key hash. */\nexport function workerSocketPath(command: string, projectDir: string): string {\n return join(workersDir(), `worker-${sha256(`${command}\\n${projectDir}`).slice(0, 12)}.sock`);\n}\n\nfunction connectOnce(path: string): Promise<Socket> {\n return new Promise((resolve, reject) => {\n const sock = createConnection(path);\n const timer = setTimeout(() => {\n sock.destroy();\n reject(new Error(\"connect timeout\"));\n }, CONNECT_TIMEOUT_MS);\n sock.once(\"connect\", () => {\n clearTimeout(timer);\n resolve(sock);\n });\n sock.once(\"error\", (error) => {\n clearTimeout(timer);\n reject(error);\n });\n });\n}\n\nconst delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\n/**\n * Serializes cold starts: only one invocation spawns a worker per socket path;\n * the rest poll the socket. A stale lock (a dead spawner) is taken over.\n */\nfunction acquireStartLock(socketPath: string): boolean {\n const lock = `${socketPath}.start`;\n try {\n mkdirSync(lock);\n return true;\n } catch {\n try {\n if (Date.now() - statSync(lock).mtimeMs > START_WAIT_MS) {\n rmdirSync(lock);\n mkdirSync(lock);\n return true;\n }\n } catch {}\n return false;\n }\n}\n\nfunction releaseStartLock(socketPath: string): void {\n try {\n rmdirSync(`${socketPath}.start`);\n } catch {}\n}\n\n/** Connects to the keyed worker, starting one (detached) if none answers. */\nexport async function ensureWorker(\n resolved: { command: string; args: string[] },\n projectDir: string,\n notify?: (line: string) => void,\n signal?: AbortSignal,\n): Promise<Socket> {\n const path = workerSocketPath(resolved.command, projectDir);\n try {\n return await connectOnce(path);\n } catch {}\n // Honor a cancel that arrived during the (possibly slow) cold start; the\n // detached worker keeps loading and stays warm for the next fit.\n if (signal?.aborted) throw new FitCancelledError();\n\n let spawnFailure: Error | undefined;\n const startedHere = acquireStartLock(path);\n if (startedHere) {\n try {\n rmSync(path, { force: true });\n notify?.(\"starting the Julia worker (first use loads Turing, can take a minute)...\");\n const child = spawn(\n resolved.command,\n [...resolved.args, \"--startup-file=no\", `--project=${projectDir}`, workerPath(), path],\n { detached: true, stdio: \"ignore\" },\n );\n child.on(\"error\", (error) => {\n spawnFailure = error;\n });\n child.on(\"exit\", (code) => {\n if (code !== 0 && code !== null) {\n spawnFailure = new Error(`the worker exited with code ${code} before serving`);\n }\n });\n child.unref();\n } catch (error) {\n releaseStartLock(path);\n throw error;\n }\n }\n\n try {\n const deadline = Date.now() + START_WAIT_MS;\n for (;;) {\n if (signal?.aborted) throw new FitCancelledError();\n if (spawnFailure) throw spawnFailure;\n try {\n return await connectOnce(path);\n } catch {}\n if (Date.now() > deadline) throw new Error(\"the Julia worker did not start in time\");\n await delay(250);\n }\n } finally {\n if (startedHere) releaseStartLock(path);\n }\n}\n\n/**\n * Streams progress lines to onProgress and resolves with the final result\n * line. The inactivity deadline (reset by every byte the worker sends, so\n * healthy long fits survive on their progress stream) rejects with\n * WorkerTimeoutError rather than hanging forever on a wedged worker.\n */\nfunction readWorkerResponse(\n sock: Socket,\n onProgress?: FitIo[\"onProgress\"],\n onDraws?: FitIo[\"onDraws\"],\n signal?: AbortSignal,\n inactivityMs = fitInactivityTimeoutMs(),\n): Promise<Record<string, unknown>> {\n return new Promise((resolve, reject) => {\n let pending = \"\";\n let settled = false;\n const onAbort = () => {\n settle(() => {\n sock.destroy();\n reject(new FitCancelledError());\n });\n };\n const settle = (fn: () => void) => {\n if (settled) return;\n settled = true;\n sock.setTimeout(0);\n signal?.removeEventListener(\"abort\", onAbort);\n fn();\n };\n if (signal) {\n if (signal.aborted) onAbort();\n else signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n sock.setTimeout(inactivityMs, () => {\n const error = new WorkerTimeoutError(\n `the worker sent nothing for ${Math.round(inactivityMs / 60_000)} minutes`,\n );\n settle(() => {\n sock.destroy();\n reject(error);\n });\n });\n sock.on(\"data\", (chunk: Buffer) => {\n pending += chunk.toString(\"utf8\");\n for (;;) {\n const at = pending.indexOf(\"\\n\");\n if (at === -1) break;\n const line = pending.slice(0, at).trim();\n pending = pending.slice(at + 1);\n if (!line) continue;\n const progress = parseProgressLine(line);\n if (progress) {\n onProgress?.(progress);\n continue;\n }\n const batch = parseDrawBatchLine(line);\n if (batch) {\n onDraws?.(batch);\n continue;\n }\n try {\n const doc = JSON.parse(line) as Record<string, unknown>;\n settle(() => {\n sock.end();\n resolve(doc);\n });\n return;\n } catch {}\n }\n });\n sock.on(\"error\", (error) => settle(() => reject(error)));\n sock.on(\"close\", () => settle(() => reject(new Error(\"worker closed the connection\"))));\n });\n}\n\n/** Runs one fit through the persistent worker. Throws on worker-infrastructure failure. */\nexport async function runFitViaWorker(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: FitIo & { notify?: (line: string) => void },\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n if (io.signal?.aborted) {\n return { status: \"cancelled\", runtimeRequested: spec.backend.version, elapsedMs: 0 };\n }\n let sock: Socket;\n try {\n sock = await ensureWorker(resolved, io.projectDir, io.notify, io.signal);\n } catch (error) {\n // Cancelled during the cold start: the worker (if any) is still idle and\n // stays warm; no fit was dispatched, so just report cancelled.\n if (error instanceof FitCancelledError) {\n return {\n status: \"cancelled\",\n runtimeRequested: spec.backend.version,\n elapsedMs: Math.round(performance.now() - start),\n };\n }\n throw error;\n }\n if (io.signal?.aborted) {\n // Aborted in the gap before dispatch; drop the connection, leave the worker\n // idle and warm. The worker reads an empty line and loops back to accept.\n sock.destroy();\n return {\n status: \"cancelled\",\n runtimeRequested: spec.backend.version,\n elapsedMs: Math.round(performance.now() - start),\n };\n }\n sock.write(\n `${JSON.stringify(fitRequest(spec, io.outPath, { streamDraws: io.onDraws !== undefined, drawBatchSize: io.drawBatchSize }))}\\n`,\n );\n let final: Record<string, unknown>;\n try {\n final = await readWorkerResponse(sock, io.onProgress, io.onDraws, io.signal);\n } catch (error) {\n if (error instanceof FitCancelledError) {\n // The worker is mid-sample and cannot answer a polite stop; kill it so it\n // stops promptly and the next fit cold-starts a fresh one.\n killWorker(workerSocketPath(resolved.command, io.projectDir));\n return {\n status: \"cancelled\",\n runtimeRequested: spec.backend.version,\n elapsedMs: Math.round(performance.now() - start),\n };\n }\n throw error;\n }\n const elapsedMs = Math.round(performance.now() - start);\n\n if (final.ok !== true) {\n // \"worker\" is the worker's own protocol failure, not a model failure;\n // throwing hands the fit to the one-shot driver.\n if (final.stage === \"worker\") throw new Error(String(final.error ?? \"worker error\"));\n return {\n status: \"error\",\n runtimeRequested: spec.backend.version,\n elapsedMs,\n stage: toStage(final.stage),\n error: String(final.error ?? \"worker error\"),\n };\n }\n return finalizeOkFit(\n spec,\n resolved,\n io,\n final.provenance as Record<string, unknown> | undefined,\n startedAt,\n elapsedMs,\n );\n}\n\n/**\n * Runs a fit through the worker when asked (and possible), falling back to the\n * one-shot driver on worker-infrastructure failures. Two exceptions never fall\n * back: a fit that genuinely failed (model error) is returned, and a hung\n * worker (timeout) is reported rather than silently re-run for another\n * half hour.\n */\nexport async function runFitAuto(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: FitIo & { daemon?: boolean; notify?: (line: string) => void },\n): Promise<FitResult> {\n if (io.signal?.aborted) {\n return { status: \"cancelled\", runtimeRequested: spec.backend.version, elapsedMs: 0 };\n }\n // Distributed sampling spawns worker processes and includes the model into\n // Main; the persistent worker's isolation cannot host that, so it runs one-shot.\n if (io.daemon && process.platform !== \"win32\" && spec.sampler.parallel !== \"distributed\") {\n const start = performance.now();\n try {\n return await runFitViaWorker(spec, resolved, io);\n } catch (error) {\n if (error instanceof WorkerTimeoutError) {\n return {\n status: \"error\",\n runtimeRequested: spec.backend.version,\n elapsedMs: Math.round(performance.now() - start),\n stage: \"worker\",\n error: `${error.message}; the worker may be wedged, try mcmc daemon stop`,\n };\n }\n io.notify?.(\n `worker unavailable (${(error as Error).message}); falling back to a one-shot run`,\n );\n }\n }\n return runFit(spec, resolved, io);\n}\n\nexport interface WorkerStatus {\n socket: string;\n alive: boolean;\n}\n\n/** Lists known worker sockets and whether each answers. */\nexport async function listWorkers(): Promise<WorkerStatus[]> {\n const dir = workersDir();\n const sockets = readdirSync(dir).filter((f) => f.startsWith(\"worker-\") && f.endsWith(\".sock\"));\n const statuses: WorkerStatus[] = [];\n for (const name of sockets) {\n const socket = join(dir, name);\n let alive = false;\n try {\n const sock = await connectOnce(socket);\n sock.destroy();\n alive = true;\n } catch {}\n statuses.push({ socket, alive });\n }\n return statuses;\n}\n\nexport type StopOutcome = \"stopped\" | \"stale\" | \"pending\";\n\n/**\n * Asks one worker to shut down. \"stopped\": acknowledged and gone. \"stale\": the\n * socket was dead and its file was removed. \"pending\": the worker is busy with\n * a fit; the stop request is queued and honored when the fit finishes, so the\n * live socket file is left alone.\n */\nexport async function stopWorker(socket: string): Promise<StopOutcome> {\n let sock: Socket;\n try {\n sock = await connectOnce(socket);\n } catch {\n rmSync(socket, { force: true });\n return \"stale\";\n }\n const acked = await new Promise<boolean>((resolve) => {\n const timer = setTimeout(() => resolve(false), STOP_ACK_TIMEOUT_MS);\n const finish = (ok: boolean) => {\n clearTimeout(timer);\n resolve(ok);\n };\n // Without a flowing readable side the worker's FIN is never surfaced.\n sock.resume();\n sock.on(\"close\", () => finish(true));\n sock.on(\"error\", () => finish(false));\n sock.write('{\"mcmcjs\":\"stop\"}\\n');\n });\n sock.destroy();\n if (!acked) return \"pending\";\n rmSync(socket, { force: true });\n return \"stopped\";\n}\n"],"mappings":"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","names":["createRunner","existsSync","join","join","join","existsSync","existsSync","readFileSync","rmSync","writeFileSync","join","canonicalJson","parseSamples","RUN_RECORD_SCHEMA_VERSION","join","writeFileSync","rmSync","existsSync","parseSamples","readFileSync","RUN_RECORD_SCHEMA_VERSION","canonicalJson","existsSync","readFileSync","rmSync","writeFileSync","join","canonicalJson","parseSamples","RUN_RECORD_SCHEMA_VERSION","join","writeFileSync","rmSync","existsSync","parseSamples","readFileSync","RUN_RECORD_SCHEMA_VERSION","canonicalJson","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","join","canonicalJson","createRunner","join","homedir","canonicalJson","readFileSync","existsSync","createRunner","mkdirSync","writeFileSync","join","join","DEFAULT_JULIA_CHANNEL","DEFAULT_JULIA_CHANNEL","createRunner","mkdirSync","readFileSync","rmSync","join","readFileSync","rmSync","join","mkdirSync"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcmcjs/julia",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Julia toolchain detection and the inference runner for MCMC.js.",
5
5
  "keywords": [
6
6
  "mcmc",
@@ -46,8 +46,8 @@
46
46
  "access": "public"
47
47
  },
48
48
  "dependencies": {
49
- "@mcmcjs/engine": "0.6.0",
50
- "@mcmcjs/core": "0.10.0"
49
+ "@mcmcjs/core": "0.11.0",
50
+ "@mcmcjs/engine": "0.6.0"
51
51
  },
52
52
  "scripts": {
53
53
  "build": "tsup",