@mcmcjs/stan 0.1.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/LICENSE +21 -0
- package/README.md +30 -0
- package/dist/index.cjs +1000 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +263 -0
- package/dist/index.d.ts +263 -0
- package/dist/index.js +976 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/compile.ts","../src/environment.ts","../src/csv.ts","../src/doctor.ts","../src/engine.ts","../src/fit.ts","../src/runner.ts","../src/matrix.ts","../src/predict.ts","../src/setup.ts","../src/versions.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, join } from \"node:path\";\nimport type { CommandRunner } from \"@mcmcjs/engine\";\nimport { createRunner } from \"@mcmcjs/engine\";\nimport type { CmdStanInstall } from \"./environment\";\nimport { managedStanRoot } from \"./environment\";\n\nexport interface CompiledModel {\n /** Path to the compiled model executable. */\n binaryPath: string;\n /** True when a previously compiled binary was reused. */\n cached: boolean;\n}\n\nexport interface CompileOptions {\n /** Runs make; injectable for tests. Compiles can take minutes. */\n runner?: CommandRunner;\n /** Cache root; defaults to `<managed>/models`. */\n cacheRoot?: string;\n}\n\n/**\n * Concatenates the source with any #include'd files (resolved against the\n * model's directory) so include edits invalidate the compile cache. Nested\n * includes resolve a few levels deep; unresolvable paths are left to stanc.\n */\nexport function cacheKeySource(source: string, modelDir: string, depth = 4): string {\n if (depth === 0) return source;\n const parts = [source];\n for (const match of source.matchAll(/^\\s*#include\\s+[<\"']?([^>\"'\\s]+)[>\"']?/gm)) {\n const file = match[1];\n if (!file) continue;\n try {\n const included = readFileSync(isAbsolute(file) ? file : join(modelDir, file), \"utf8\");\n parts.push(cacheKeySource(included, modelDir, depth - 1));\n } catch {\n // stanc reports missing includes with a proper error at compile time\n }\n }\n return parts.join(\"\\n\");\n}\n\n/** The compile cache directory for a model source on a CmdStan version. */\nexport function modelCacheDir(source: string, version: string, cacheRoot?: string): string {\n const key = createHash(\"sha256\").update(`${version}\\n${source}`).digest(\"hex\").slice(0, 16);\n return join(cacheRoot ?? join(managedStanRoot(), \"models\"), key);\n}\n\n/**\n * Compiles a Stan model to an executable through CmdStan's make, cached by\n * source content and CmdStan version so edits recompile and reruns are instant.\n */\nexport async function compileModel(\n install: CmdStanInstall,\n modelPath: string,\n options: CompileOptions = {},\n): Promise<CompiledModel> {\n const { runner = createRunner(10 * 60_000), cacheRoot } = options;\n const source = readFileSync(modelPath, \"utf8\");\n const modelDir = dirname(modelPath);\n const dir = modelCacheDir(cacheKeySource(source, modelDir), install.version, cacheRoot);\n const binaryPath = join(dir, \"model\");\n // The sentinel is written only after a successful make, so an interrupted\n // compile never gets reused as a valid binary.\n const okPath = join(dir, \".ok\");\n if (existsSync(okPath) && existsSync(binaryPath)) return { binaryPath, cached: true };\n\n mkdirSync(dir, { recursive: true });\n writeFileSync(join(dir, \"model.stan\"), source);\n // CmdStan's pattern rules build targets outside its tree by absolute path;\n // includes still resolve against the original model's directory.\n await runner(\"make\", [\"-C\", install.home, `STANCFLAGS=--include-paths=${modelDir}`, binaryPath]);\n if (!existsSync(binaryPath)) {\n throw new Error(\"make reported success but produced no model executable\");\n }\n writeFileSync(okPath, \"\");\n return { binaryPath, cached: false };\n}\n","import { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { basename, 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\nimport { DEFAULT_CMDSTAN_CHANNEL } from \"@mcmcjs/core\";\n\n/** The spec channel meaning \"use whatever CmdStan is installed locally\". */\nexport const INSTALLED_CMDSTAN_CHANNEL = DEFAULT_CMDSTAN_CHANNEL;\n\n/** The CmdStan version `mcmc setup --engine stan` provisions. */\nexport const PINNED_CMDSTAN_VERSION = \"2.39.0\";\n\n/** A CmdStan installation found on this machine. */\nexport interface CmdStanInstall {\n version: string;\n /** The cmdstan home directory (contains makefile, bin/stanc, examples/). */\n home: string;\n}\n\n/** The managed root for CmdStan installs: `<data>/mcmcjs/stan`. */\nexport function managedStanRoot(): string {\n const home = process.env.HOME || homedir();\n const dataHome = process.env.XDG_DATA_HOME || join(home, \".local\", \"share\");\n return join(dataHome, \"mcmcjs\", \"stan\");\n}\n\n/** A directory is a usable CmdStan home when the makefile and stanc are present. */\nexport function isCmdStanHome(dir: string): boolean {\n return existsSync(join(dir, \"makefile\")) && existsSync(join(dir, \"bin\", \"stanc\"));\n}\n\nfunction versionFromDirName(dir: string): string | undefined {\n return basename(dir).match(/^cmdstan-(\\d+\\.\\d+\\.\\d+(?:-rc\\d+)?)$/)?.[1];\n}\n\nfunction versionFromMakefile(home: string): string | undefined {\n try {\n const makefile = readFileSync(join(home, \"makefile\"), \"utf8\");\n return makefile.match(/CMDSTAN_VERSION\\s*:?=\\s*(\\S+)/)?.[1];\n } catch {\n return undefined;\n }\n}\n\nfunction installAt(home: string): CmdStanInstall | undefined {\n if (!isCmdStanHome(home)) return undefined;\n const version = versionFromDirName(home) ?? versionFromMakefile(home);\n return version ? { version, home } : undefined;\n}\n\nfunction scanRoot(root: string): CmdStanInstall[] {\n let entries: string[];\n try {\n entries = readdirSync(root);\n } catch {\n return [];\n }\n const installs: CmdStanInstall[] = [];\n for (const name of entries) {\n if (!name.startsWith(\"cmdstan-\")) continue;\n const install = installAt(join(root, name));\n if (install) installs.push(install);\n }\n return installs;\n}\n\nfunction compareVersions(a: string, b: string): number {\n const parse = (v: string) => {\n const [core, rc] = v.split(\"-rc\");\n const nums = (core ?? \"\").split(\".\").map((p) => Number.parseInt(p, 10) || 0);\n // A release candidate sorts before its final release.\n return { nums, rc: rc === undefined ? Number.POSITIVE_INFINITY : Number.parseInt(rc, 10) || 0 };\n };\n const pa = parse(a);\n const pb = parse(b);\n for (let i = 0; i < Math.max(pa.nums.length, pb.nums.length); i++) {\n const d = (pa.nums[i] ?? 0) - (pb.nums[i] ?? 0);\n if (d !== 0) return d;\n }\n if (pa.rc === pb.rc) return 0;\n return pa.rc < pb.rc ? -1 : 1;\n}\n\n/**\n * Every CmdStan install visible to mcmcjs, newest first: an explicit\n * MCMCJS_CMDSTAN/CMDSTAN home wins, then the managed root, then the\n * conventional `~/.cmdstan` used by other Stan interfaces.\n */\nexport function listCmdStanInstalls(): CmdStanInstall[] {\n const explicit = process.env.MCMCJS_CMDSTAN || process.env.CMDSTAN;\n if (explicit) {\n const install = installAt(explicit);\n if (!install) {\n throw new Error(\n `MCMCJS_CMDSTAN/CMDSTAN points at ${explicit}, which is not a CmdStan directory (expected a makefile and bin/stanc); unset it or point it at a CmdStan home.`,\n );\n }\n return [install];\n }\n const home = process.env.HOME || homedir();\n const installs = [...scanRoot(managedStanRoot()), ...scanRoot(join(home, \".cmdstan\"))];\n return installs.sort((a, b) => compareVersions(b.version, a.version));\n}\n\n/**\n * Resolves the CmdStan install a fit runs on. `installed` (the default channel)\n * takes the newest local install; an explicit version must match exactly.\n */\nexport function resolveCmdStan(requested: string = INSTALLED_CMDSTAN_CHANNEL): CmdStanInstall {\n const installs = listCmdStanInstalls();\n if (requested === INSTALLED_CMDSTAN_CHANNEL) {\n const newest = installs[0];\n if (newest) return newest;\n throw new Error(\n \"CmdStan not found. Run `mcmc setup --engine stan`, or point MCMCJS_CMDSTAN at a CmdStan directory.\",\n );\n }\n const match = installs.find((i) => i.version === requested);\n if (match) return match;\n throw new Error(\n `CmdStan ${requested} not found. Run \\`mcmc setup --engine stan --stan-version ${requested}\\`, or point MCMCJS_CMDSTAN at a CmdStan directory.`,\n );\n}\n\nasync function detect(\n command: string,\n args: string[],\n parseVersion: (stdout: string) => string | undefined,\n runner: CommandRunner,\n): Promise<ToolInfo> {\n try {\n const version = parseVersion(await runner(command, args));\n if (version) return { found: true, version, path: command };\n } catch {\n // not available; fall through\n }\n return { found: false };\n}\n\nconst versionNumber = (stdout: string): string | undefined =>\n stdout.match(/(\\d+\\.\\d+(?:\\.\\d+)?)/)?.[1];\n\n/** Detects GNU Make. */\nexport function detectMake(runner: CommandRunner = defaultRunner): Promise<ToolInfo> {\n return detect(\"make\", [\"--version\"], versionNumber, runner);\n}\n\n/** Detects a C++ compiler (g++ first, then clang++). */\nexport async function detectCxx(runner: CommandRunner = defaultRunner): Promise<ToolInfo> {\n for (const command of [\"g++\", \"clang++\"]) {\n const info = await detect(command, [\"--version\"], versionNumber, runner);\n if (info.found) return info;\n }\n return { found: false };\n}\n\n/** Probes `bin/stanc --version` of an install. */\nexport async function detectStanc(\n install: CmdStanInstall | undefined,\n runner: CommandRunner = defaultRunner,\n): Promise<ToolInfo> {\n if (!install) return { found: false };\n const stanc = join(install.home, \"bin\", \"stanc\");\n return detect(stanc, [\"--version\"], versionNumber, runner);\n}\n","import { closeSync, openSync, readSync } from \"node:fs\";\nimport { fromStanName } from \"@mcmcjs/core\";\nimport type { DrawBatch } from \"@mcmcjs/engine\";\n\n// Mirrors the sampler-column renames applied by @mcmcjs/core's Stan CSV parser\n// (packages/core/src/parsers/stan.ts) so streamed leaves match the samples file.\nconst STAT_RENAME: Record<string, string> = {\n lp__: \"lp\",\n energy__: \"energy\",\n divergent__: \"diverging\",\n treedepth__: \"tree_depth\",\n n_leapfrog__: \"n_steps\",\n accept_stat__: \"acceptance_rate\",\n stepsize__: \"step_size\",\n};\n\n/** Stan CSV column -> streamed leaf name; null for dropped diagnostic columns. */\nexport function columnToLeaf(column: string): string | null {\n if (column.endsWith(\"__\")) return STAT_RENAME[column] ?? null;\n return fromStanName(column);\n}\n\n/** CmdStan prints C++ formatting for non-finite doubles: inf, -inf, nan. */\nfunction parseStanNumber(field: string): number {\n const value = Number(field);\n if (!Number.isNaN(value) || field === \"nan\") return value;\n if (field === \"inf\" || field === \"+inf\") return Number.POSITIVE_INFINITY;\n if (field === \"-inf\") return Number.NEGATIVE_INFINITY;\n return value;\n}\n\nexport interface StanCsvTail {\n /** Reads newly appended rows and emits any full batches. */\n poll(): void;\n /** Final poll plus a flush of the remaining partial batch. */\n finish(): void;\n}\n\n/**\n * Incrementally tails one growing CmdStan CSV, batching completed draws into\n * DrawBatch messages. Comment lines (the config echo, adaptation block, and\n * timing footer) are skipped; the first non-comment line is the header. A\n * trailing line without its newline is left buffered until it completes, and a\n * row is only accepted when its field count matches the header.\n */\nexport function createStanCsvTail(\n filePath: string,\n opts: {\n /** 0-based chain index reported in batches. */\n chain: number;\n /** Draws per batch. */\n batchSize: number;\n onBatch: (batch: DrawBatch) => void;\n },\n): StanCsvTail {\n let position = 0;\n let pending = \"\";\n let leaves: (string | null)[] | undefined;\n let seq = 0;\n const rows: number[][] = [];\n\n const emit = (count: number) => {\n if (count === 0 || !leaves) return;\n const draws: Record<string, number[]> = {};\n for (let c = 0; c < leaves.length; c++) {\n const leaf = leaves[c];\n if (!leaf) continue;\n const values = new Array<number>(count);\n for (let r = 0; r < count; r++) values[r] = rows[r]?.[c] ?? Number.NaN;\n draws[leaf] = values;\n }\n rows.splice(0, count);\n opts.onBatch({ chain: opts.chain, seq, iteration: null, draws });\n seq += 1;\n };\n\n const consume = (line: string) => {\n const trimmed = line.trim();\n if (trimmed.length === 0 || trimmed.startsWith(\"#\")) return;\n if (!leaves) {\n leaves = trimmed.split(\",\").map(columnToLeaf);\n return;\n }\n const fields = trimmed.split(\",\");\n if (fields.length !== leaves.length) return;\n rows.push(fields.map(parseStanNumber));\n if (rows.length >= opts.batchSize) emit(opts.batchSize);\n };\n\n const poll = () => {\n let fd: number;\n try {\n fd = openSync(filePath, \"r\");\n } catch {\n return; // not created yet\n }\n try {\n const chunk = Buffer.alloc(1 << 16);\n for (;;) {\n const read = readSync(fd, chunk, 0, chunk.length, position);\n if (read <= 0) break;\n position += read;\n pending += chunk.toString(\"utf8\", 0, read);\n for (;;) {\n const nl = pending.indexOf(\"\\n\");\n if (nl < 0) break;\n consume(pending.slice(0, nl));\n pending = pending.slice(nl + 1);\n }\n }\n } finally {\n closeSync(fd);\n }\n };\n\n return {\n poll,\n finish() {\n poll();\n emit(rows.length);\n },\n };\n}\n","import type { CommandRunner, ToolInfo } from \"@mcmcjs/engine\";\nimport {\n type CmdStanInstall,\n detectCxx,\n detectMake,\n detectStanc,\n listCmdStanInstalls,\n} from \"./environment\";\n\n/** A summary of the Stan toolchain available for inference. */\nexport interface StanDoctorReport {\n cmdstan: ToolInfo;\n stanc: ToolInfo;\n make: ToolInfo;\n cxx: ToolInfo;\n /** The install a fit would use, when one exists. */\n install?: CmdStanInstall;\n /** True when a fit can compile and sample: CmdStan plus the build toolchain. */\n ready: boolean;\n}\n\n/** Detects the installed Stan toolchain and reports whether inference can run. */\nexport async function runDoctor(runner?: CommandRunner): Promise<StanDoctorReport> {\n const install = listCmdStanInstalls()[0];\n const cmdstan: ToolInfo = install\n ? { found: true, version: install.version, path: install.home }\n : { found: false };\n const [stanc, make, cxx] = await Promise.all([\n detectStanc(install, runner),\n detectMake(runner),\n detectCxx(runner),\n ]);\n return {\n cmdstan,\n stanc,\n make,\n cxx,\n install,\n ready: cmdstan.found && make.found && cxx.found,\n };\n}\n","import type { Engine, EngineContext, HealthReport } from \"@mcmcjs/engine\";\nimport { runDoctor } from \"./doctor\";\n\nexport const stanEngine: Engine = {\n id: \"stan\",\n displayName: \"Stan (CmdStan)\",\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 const missingToolchain = !report.make.found || !report.cxx.found;\n return {\n engineId: \"stan\",\n ready: report.ready,\n tools: [\n { name: \"cmdstan\", ...report.cmdstan },\n { name: \"stanc\", ...report.stanc },\n { name: \"make\", ...report.make },\n { name: \"c++\", ...report.cxx },\n ],\n hint: report.ready\n ? undefined\n : missingToolchain\n ? \"Stan models compile with the system toolchain; install make and a C++ compiler (g++ or clang++), then run `mcmc setup --engine stan`.\"\n : \"CmdStan not found. Run `mcmc setup --engine stan`.\",\n };\n },\n};\n","import { createHash } from \"node:crypto\";\nimport {\n existsSync,\n mkdirSync,\n mkdtempSync,\n readFileSync,\n renameSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n canonicalJson,\n fromStanCSVFiles,\n parseSamples,\n type ResolvedSpec,\n RUN_RECORD_SCHEMA_VERSION,\n type RunRecord,\n toMCMCChainsJson,\n} from \"@mcmcjs/core\";\nimport type { DrawBatch, FitProgress, FitResult } from \"@mcmcjs/engine\";\nimport { type CompileOptions, compileModel } from \"./compile\";\nimport { createStanCsvTail } from \"./csv\";\nimport type { CmdStanInstall } from \"./environment\";\nimport { createStanSpawn, parseIterationLine, type StanSpawn } from \"./runner\";\n\nexport interface StanFitIo {\n /** Spawns CmdStan processes; injectable so runFit is testable without CmdStan. */\n spawn?: StanSpawn;\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 /** Draws per streamed batch (default 25). */\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 /** Model compile pass-through, injectable for tests. */\n compile?: CompileOptions;\n tmpDir?: string;\n}\n\nfunction sha256(text: string): string {\n return createHash(\"sha256\").update(text).digest(\"hex\");\n}\n\nfunction tmpParent(): string {\n const uid = typeof process.getuid === \"function\" ? `-${process.getuid()}` : \"\";\n return join(tmpdir(), `mcmcjs${uid}`);\n}\n\n/** The per-chain CmdStan invocation. Chains share one seed; `id` varies the stream. */\nexport function chainArgs(\n spec: ResolvedSpec,\n chain1: number,\n dataPath: string,\n csvPath: string,\n): string[] {\n const s = spec.sampler;\n const total = s.draws + s.warmup;\n // Progress at roughly 1% granularity without flooding stdout on long runs.\n const refresh = Math.max(1, Math.floor(total / 100));\n return [\n \"sample\",\n `num_samples=${s.draws}`,\n `num_warmup=${s.warmup}`,\n \"adapt\",\n `delta=${s.adapt_delta}`,\n \"data\",\n `file=${dataPath}`,\n \"random\",\n `seed=${spec.seed}`,\n `id=${chain1}`,\n \"output\",\n `file=${csvPath}`,\n `refresh=${refresh}`,\n ];\n}\n\nfunction errorTail(stderr: string): string | undefined {\n const lines = stderr\n .trim()\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter(Boolean);\n return lines.at(-1);\n}\n\n/** Runs one Stan inference on a resolved CmdStan install. */\nexport async function runFit(\n spec: ResolvedSpec,\n install: CmdStanInstall,\n io: StanFitIo,\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n const runtimeRequested = spec.backend.version;\n const fail = (stage: FitResult[\"stage\"], error: string): FitResult => ({\n status: \"error\",\n runtimeRequested,\n elapsedMs: Math.round(performance.now() - start),\n stage,\n error,\n });\n\n if (io.signal?.aborted) {\n return { status: \"cancelled\", runtimeRequested, elapsedMs: 0 };\n }\n\n let binaryPath: string;\n try {\n ({ binaryPath } = await compileModel(install, spec.modelPath, io.compile));\n } catch (error) {\n return fail(\"compile\", (error as Error).message);\n }\n if (io.signal?.aborted) {\n return {\n status: \"cancelled\",\n runtimeRequested,\n elapsedMs: Math.round(performance.now() - start),\n };\n }\n\n const ownTmp = io.tmpDir === undefined;\n let tmp: string;\n if (io.tmpDir === undefined) {\n mkdirSync(tmpParent(), { recursive: true });\n tmp = mkdtempSync(join(tmpParent(), \"stan-fit-\"));\n } else {\n tmp = io.tmpDir;\n }\n\n try {\n const dataPath = join(tmp, \"data.json\");\n writeFileSync(dataPath, JSON.stringify(spec.data));\n\n const chains = spec.sampler.chains;\n const spawn = io.spawn ?? createStanSpawn();\n const csvPaths = Array.from({ length: chains }, (_, i) => join(tmp, `chain_${i + 1}.csv`));\n\n const tails = io.onDraws\n ? csvPaths.map((path, i) =>\n createStanCsvTail(path, {\n chain: i,\n batchSize: io.drawBatchSize ?? 25,\n onBatch: io.onDraws as (batch: DrawBatch) => void,\n }),\n )\n : [];\n const pollTimer =\n tails.length > 0\n ? setInterval(() => {\n for (const tail of tails) tail.poll();\n }, 150)\n : undefined;\n pollTimer?.unref?.();\n\n let results: { code: number; stderr: string; cancelled?: boolean }[];\n try {\n results = await Promise.all(\n csvPaths.map((csvPath, i) => {\n const onProgress = io.onProgress;\n return spawn(binaryPath, chainArgs(spec, i + 1, dataPath, csvPath), {\n signal: io.signal,\n onStdoutLine: onProgress\n ? (line) => {\n const p = parseIterationLine(line);\n if (!p) return;\n onProgress({\n chain: i + 1,\n of: chains,\n fraction: p.total > 0 ? p.iteration / p.total : 0,\n done: p.iteration === p.total,\n });\n }\n : undefined,\n });\n }),\n );\n } finally {\n if (pollTimer) clearInterval(pollTimer);\n }\n for (const tail of tails) tail.finish();\n\n const elapsedMs = Math.round(performance.now() - start);\n if (io.signal?.aborted || results.some((r) => r.cancelled)) {\n return { status: \"cancelled\", runtimeRequested, elapsedMs };\n }\n const failed = results.findIndex((r) => r.code !== 0);\n if (failed >= 0) {\n const r = results[failed];\n return fail(\n \"sample\",\n `chain ${failed + 1} exited with code ${r?.code}${\n r && errorTail(r.stderr) ? `: ${errorTail(r.stderr)}` : \"\"\n }`,\n );\n }\n\n let samplesJson: string;\n try {\n const texts = csvPaths.map((path) => readFileSync(path, \"utf8\"));\n samplesJson = JSON.stringify(toMCMCChainsJson(fromStanCSVFiles(texts)));\n parseSamples(samplesJson);\n } catch (error) {\n return fail(\"load_samples\", `could not read CmdStan output: ${(error as Error).message}`);\n }\n\n try {\n const partial = `${io.outPath}.tmp`;\n writeFileSync(partial, samplesJson);\n renameSync(partial, io.outPath);\n } catch (error) {\n return fail(\"write\", (error as Error).message);\n }\n\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: install.version, path: install.home },\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: Math.round(performance.now() - start),\n };\n try {\n writeFileSync(\n io.recordPath ?? `${io.outPath}.run.json`,\n `${JSON.stringify(record, null, 2)}\\n`,\n );\n } catch (error) {\n return fail(\"write\", `could not write the run record: ${(error as Error).message}`);\n }\n\n return {\n status: \"ok\",\n samplesFile: io.outPath,\n runtimeRequested,\n runtimeActual: install.version,\n elapsedMs: Math.round(performance.now() - start),\n };\n } finally {\n if (ownTmp) rmSync(tmp, { recursive: true, force: true });\n }\n}\n","import { type ChildProcess, spawn } from \"node:child_process\";\nimport { killTree } from \"@mcmcjs/engine\";\n\nconst DETACHED = process.platform !== \"win32\";\n\nexport interface StanSpawnResult {\n code: number;\n stderr: string;\n cancelled?: boolean;\n}\n\nexport interface StanSpawnOptions {\n /** Called once per complete stdout line (CmdStan prints progress there). */\n onStdoutLine?: (line: string) => void;\n signal?: AbortSignal;\n timeoutMs?: number;\n}\n\n/** Spawns one CmdStan process, streaming stdout lines to the caller. */\nexport type StanSpawn = (\n command: string,\n args: string[],\n opts?: StanSpawnOptions,\n) => Promise<StanSpawnResult>;\n\nconst STDERR_LIMIT = 1 << 22;\n\n/**\n * The production StanSpawn: detached on POSIX so cancellation kills the whole\n * process group, stdout parsed line-by-line for progress, stderr captured for\n * error reporting.\n */\nexport function createStanSpawn(defaultTimeoutMs = 30 * 60_000): StanSpawn {\n return (command, args, opts = {}) =>\n new Promise((resolve) => {\n const child: ChildProcess = spawn(command, args, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: DETACHED,\n });\n\n let stderr = \"\";\n let stdoutPending = \"\";\n let cancelled = false;\n let settled = false;\n\n const timeoutMs = opts.timeoutMs ?? defaultTimeoutMs;\n const timer = setTimeout(() => {\n stderr += \"process timed out and was killed\\n\";\n killTree(child);\n }, timeoutMs);\n timer.unref?.();\n\n const onAbort = () => {\n cancelled = true;\n killTree(child);\n };\n if (opts.signal) {\n if (opts.signal.aborted) onAbort();\n else opts.signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n\n child.stdout?.on(\"data\", (data: Buffer) => {\n stdoutPending += data.toString(\"utf8\");\n for (;;) {\n const nl = stdoutPending.indexOf(\"\\n\");\n if (nl < 0) break;\n opts.onStdoutLine?.(stdoutPending.slice(0, nl));\n stdoutPending = stdoutPending.slice(nl + 1);\n }\n });\n child.stderr?.on(\"data\", (data: Buffer) => {\n if (stderr.length < STDERR_LIMIT) stderr += data.toString(\"utf8\");\n });\n\n const settle = (code: number) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n opts.signal?.removeEventListener(\"abort\", onAbort);\n if (stdoutPending.length > 0) opts.onStdoutLine?.(stdoutPending);\n resolve({ code, stderr, cancelled: cancelled || undefined });\n };\n\n child.on(\"error\", (error) => {\n stderr = stderr || error.message;\n settle(1);\n });\n child.on(\"close\", (code) => settle(code ?? 1));\n });\n}\n\n/** Parses one CmdStan progress line; null when the line is not progress. */\nexport function parseIterationLine(\n line: string,\n): { iteration: number; total: number; warmup: boolean } | null {\n const match = line.match(/Iteration:\\s*(\\d+)\\s*\\/\\s*(\\d+)\\s*\\[\\s*\\d+%\\]\\s*\\((Warmup|Sampling)\\)/);\n if (!match) return null;\n return {\n iteration: Number.parseInt(match[1] ?? \"0\", 10),\n total: Number.parseInt(match[2] ?? \"0\", 10),\n warmup: match[3] === \"Warmup\",\n };\n}\n","import { join } from \"node:path\";\nimport type { ResolvedSpec } from \"@mcmcjs/core\";\nimport type { FitResult } from \"@mcmcjs/engine\";\nimport { resolveCmdStan } from \"./environment\";\nimport { runFit, type StanFitIo } from \"./fit\";\n\n// Structurally identical to the Julia engine's matrix shapes, so the CLI's\n// matrix rendering works with either engine's result.\nexport interface StanMatrixEntry {\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 StanMatrixResult {\n entries: StanMatrixEntry[];\n /** True only when every requested version ran and succeeded. */\n ok: boolean;\n}\n\nexport interface StanMatrixIo {\n /** Directory the per-version samples files are written into. */\n outDir: string;\n dataFile?: string;\n dataSha256?: string;\n /** Continue after a version fails instead of stopping. */\n keepGoing?: boolean;\n signal?: AbortSignal;\n /** Fit pass-through, injectable for tests. */\n fit?: Pick<StanFitIo, \"spawn\" | \"compile\">;\n}\n\n/** Runs one spec across several installed CmdStan versions. */\nexport async function runMatrix(\n spec: ResolvedSpec,\n versions: string[],\n io: StanMatrixIo,\n): Promise<StanMatrixResult> {\n const entries: StanMatrixEntry[] = [];\n for (const version of versions) {\n let entry: StanMatrixEntry;\n try {\n const install = resolveCmdStan(version);\n const result = await runFit({ ...spec, backend: { ...spec.backend, version } }, install, {\n ...io.fit,\n outPath: join(io.outDir, `${version}.samples.json`),\n dataFile: io.dataFile,\n dataSha256: io.dataSha256,\n signal: io.signal,\n });\n entry = {\n version,\n status: result.status,\n samplesFile: result.samplesFile,\n runtimeActual: result.runtimeActual,\n elapsedMs: result.elapsedMs,\n stage: result.stage,\n error: result.error,\n };\n } catch (error) {\n entry = { version, status: \"error\", elapsedMs: 0, error: (error as Error).message };\n }\n entries.push(entry);\n if (entry.status === \"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 { createHash } from \"node:crypto\";\nimport {\n existsSync,\n mkdirSync,\n mkdtempSync,\n readFileSync,\n renameSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n canonicalJson,\n fromStanCSVFiles,\n parseSamples,\n type ResolvedSpec,\n RUN_RECORD_SCHEMA_VERSION,\n type RunRecord,\n type Samples,\n toMCMCChainsJson,\n toStanName,\n} from \"@mcmcjs/core\";\nimport type { FitResult } from \"@mcmcjs/engine\";\nimport { type CompileOptions, compileModel } from \"./compile\";\nimport type { CmdStanInstall } from \"./environment\";\nimport { createStanSpawn, type StanSpawn } from \"./runner\";\n\nexport interface StanPredictIo {\n /** Where the posterior-predictive samples file is written. */\n outPath: string;\n /** The posterior samples file fed to prediction. */\n samplesPath: string;\n /** Spawns CmdStan processes; injectable so runPredict is testable without CmdStan. */\n spawn?: StanSpawn;\n /** Model compile pass-through, injectable for tests. */\n compile?: CompileOptions;\n signal?: AbortSignal;\n tmpDir?: string;\n}\n\n/**\n * The prediction data: [data] with [predict].data overrides. Unlike the Julia\n * engines, targets are not blanked; Stan predictions come from the model's own\n * generated quantities block, which reads the data as-is.\n */\nexport function predictData(spec: ResolvedSpec): Record<string, unknown> {\n if (!spec.predict) throw new Error(\"spec has no [predict] block\");\n return { ...spec.data, ...(spec.predict.data ?? {}) };\n}\n\n/**\n * One Stan-CSV of fitted parameters per chain, rebuilt from the samples file.\n * CmdStan's generate_quantities reads parameters by header name and ignores\n * extra columns, so a header plus the parameter draws is sufficient.\n */\nexport function fittedParamsCsv(samples: Samples, chain: number): string {\n const names = samples.variables;\n const header = names.map(toStanName).join(\",\");\n const columns = names.map((name) => samples.draws.get(name) as Float64Array);\n const start = chain * samples.nDraws;\n const rows: string[] = [header];\n for (let i = 0; i < samples.nDraws; i++) {\n rows.push(columns.map((col) => stanCell(col[start + i] ?? Number.NaN)).join(\",\"));\n }\n return `${rows.join(\"\\n\")}\\n`;\n}\n\nfunction stanCell(value: number): string {\n if (Number.isFinite(value)) return String(value);\n if (Number.isNaN(value)) return \"nan\";\n return value > 0 ? \"inf\" : \"-inf\";\n}\n\n/** Whether a scalarized variable name belongs to a predict target base name. */\nexport function matchesTarget(name: string, targets: readonly string[]): boolean {\n return targets.some((t) => name === t || name.startsWith(`${t}[`));\n}\n\nfunction filterToTargets(all: Samples, targets: readonly string[]): Samples {\n const draws = new Map<string, Float64Array>();\n for (const name of all.variables) {\n if (matchesTarget(name, targets)) {\n draws.set(name, all.draws.get(name) as Float64Array);\n }\n }\n return {\n variables: [...draws.keys()],\n nChains: all.nChains,\n nDraws: all.nDraws,\n draws,\n sampleStats: new Map(),\n };\n}\n\nfunction baseNames(variables: readonly string[]): string[] {\n return [...new Set(variables.map((v) => v.replace(/\\[.*$/, \"\")))];\n}\n\nfunction sha256(text: string): string {\n return createHash(\"sha256\").update(text).digest(\"hex\");\n}\n\nfunction tmpParent(): string {\n const uid = typeof process.getuid === \"function\" ? `-${process.getuid()}` : \"\";\n return join(tmpdir(), `mcmcjs${uid}`);\n}\n\n/**\n * Draws posterior-predictive samples through CmdStan's generate_quantities:\n * the model's generated quantities block re-runs once per posterior draw, and\n * the columns matching [predict].targets become the predictive samples file.\n */\nexport async function runPredict(\n spec: ResolvedSpec,\n install: CmdStanInstall,\n io: StanPredictIo,\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n const runtimeRequested = spec.backend.version;\n const elapsed = () => Math.round(performance.now() - start);\n const fail = (stage: FitResult[\"stage\"], error: string): FitResult => ({\n status: \"error\",\n runtimeRequested,\n elapsedMs: elapsed(),\n stage,\n error,\n });\n\n const targets = spec.predict?.targets;\n if (!targets || targets.length === 0) {\n return fail(\"predict\", \"spec has no [predict] block\");\n }\n if (io.signal?.aborted) {\n return { status: \"cancelled\", runtimeRequested, elapsedMs: 0 };\n }\n\n let posterior: Samples;\n try {\n posterior = parseSamples(readFileSync(io.samplesPath, \"utf8\"));\n } catch (error) {\n return fail(\"load_samples\", `posterior samples did not parse: ${(error as Error).message}`);\n }\n\n let binaryPath: string;\n try {\n ({ binaryPath } = await compileModel(install, spec.modelPath, io.compile));\n } catch (error) {\n return fail(\"compile\", (error as Error).message);\n }\n\n const ownTmp = io.tmpDir === undefined;\n let tmp: string;\n if (io.tmpDir === undefined) {\n mkdirSync(tmpParent(), { recursive: true });\n tmp = mkdtempSync(join(tmpParent(), \"stan-predict-\"));\n } else {\n tmp = io.tmpDir;\n }\n\n try {\n const data = predictData(spec);\n const dataPath = join(tmp, \"data.json\");\n writeFileSync(dataPath, JSON.stringify(data));\n\n const spawn = io.spawn ?? createStanSpawn();\n const chains = posterior.nChains;\n // CmdStan rejects a fitted_params name that is a substring of the output\n // name, so the two use unrelated stems.\n const results = await Promise.all(\n Array.from({ length: chains }, (_, i) => {\n const fittedPath = join(tmp, `fitted_${i + 1}.csv`);\n writeFileSync(fittedPath, fittedParamsCsv(posterior, i));\n return spawn(\n binaryPath,\n [\n \"generate_quantities\",\n `fitted_params=${fittedPath}`,\n \"data\",\n `file=${dataPath}`,\n \"random\",\n `seed=${spec.seed}`,\n `id=${i + 1}`,\n \"output\",\n `file=${join(tmp, `gq_${i + 1}.csv`)}`,\n ],\n { signal: io.signal },\n );\n }),\n );\n\n if (io.signal?.aborted || results.some((r) => r.cancelled)) {\n return { status: \"cancelled\", runtimeRequested, elapsedMs: elapsed() };\n }\n const failed = results.findIndex((r) => r.code !== 0);\n if (failed >= 0) {\n const stderr = results[failed]?.stderr ?? \"\";\n if (/doesn't generate any quantities/i.test(stderr)) {\n return fail(\n \"predict\",\n `the Stan model has no generated quantities block; add one that computes ${targets.join(\", \")}`,\n );\n }\n const tail = stderr.trim().split(\"\\n\").filter(Boolean).at(-1);\n return fail(\n \"predict\",\n `generate_quantities failed for chain ${failed + 1}${tail ? `: ${tail}` : \"\"}`,\n );\n }\n\n let predictive: Samples;\n try {\n const texts = Array.from({ length: chains }, (_, i) =>\n readFileSync(join(tmp, `gq_${i + 1}.csv`), \"utf8\"),\n );\n predictive = filterToTargets(fromStanCSVFiles(texts), targets);\n } catch (error) {\n return fail(\n \"load_samples\",\n `could not read generate_quantities output: ${(error as Error).message}`,\n );\n }\n if (predictive.variables.length === 0) {\n const available = baseNames(fromStanCSVFilesNames(tmp, chains));\n return fail(\n \"predict\",\n `no generated quantity matches targets ${targets.join(\", \")}; the model generates: ${\n available.length > 0 ? available.join(\", \") : \"(nothing)\"\n }`,\n );\n }\n\n try {\n const json = JSON.stringify(toMCMCChainsJson(predictive));\n parseSamples(json);\n const partial = `${io.outPath}.tmp`;\n writeFileSync(partial, json);\n renameSync(partial, io.outPath);\n } catch (error) {\n return fail(\"write\", (error as Error).message);\n }\n\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: install.version, path: install.home },\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: sha256(readFileSync(io.samplesPath, \"utf8\")),\n samples_file: io.outPath,\n started_at: startedAt,\n elapsed_ms: elapsed(),\n };\n try {\n writeFileSync(`${io.outPath}.run.json`, `${JSON.stringify(record, null, 2)}\\n`);\n } catch (error) {\n return fail(\"write\", `could not write the run record: ${(error as Error).message}`);\n }\n\n return {\n status: \"ok\",\n samplesFile: io.outPath,\n runtimeRequested,\n runtimeActual: install.version,\n elapsedMs: elapsed(),\n };\n } finally {\n if (ownTmp) rmSync(tmp, { recursive: true, force: true });\n }\n}\n\nfunction fromStanCSVFilesNames(tmp: string, chains: number): string[] {\n try {\n const texts = Array.from({ length: chains }, (_, i) =>\n readFileSync(join(tmp, `gq_${i + 1}.csv`), \"utf8\"),\n );\n return [...fromStanCSVFiles(texts).variables];\n } catch {\n return [];\n }\n}\n","import { existsSync } from \"node:fs\";\nimport { cpus } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { CommandRunner, ToolInfo } from \"@mcmcjs/engine\";\nimport { createRunner } from \"@mcmcjs/engine\";\nimport { runDoctor, type StanDoctorReport } from \"./doctor\";\nimport { managedStanRoot, PINNED_CMDSTAN_VERSION } from \"./environment\";\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/** A single provisioning step needed to make the toolchain ready. */\nexport interface SetupStep {\n tool: \"toolchain\" | \"cmdstan\" | \"build\";\n label: string;\n /** The command to run, or null when the step cannot be performed automatically. */\n command: InstallCommand | null;\n}\n\nfunction releaseUrl(version: string): string {\n return `https://github.com/stan-dev/cmdstan/releases/download/v${version}/cmdstan-${version}.tar.gz`;\n}\n\n/** POSIX single-quoting: safe against $, backticks, spaces, and quotes. */\nfunction shq(value: string): string {\n return `'${value.replaceAll(\"'\", `'\\\\''`)}'`;\n}\n\n/** The managed home a given CmdStan version installs into. */\nexport function managedCmdStanHome(version: string): string {\n return join(managedStanRoot(), `cmdstan-${version}`);\n}\n\n/** The ordered steps needed to reach a ready toolchain, given the current state. */\nexport function planSetup(\n report: StanDoctorReport,\n platform: NodeJS.Platform,\n version: string = PINNED_CMDSTAN_VERSION,\n): SetupStep[] {\n const steps: SetupStep[] = [];\n\n if (!report.make.found || !report.cxx.found) {\n const missing = [\n ...(report.make.found ? [] : [\"make\"]),\n ...(report.cxx.found ? [] : [\"a C++ compiler (g++ or clang++)\"]),\n ].join(\" and \");\n // System package managers vary too much to script; report what is missing.\n steps.push({\n tool: \"toolchain\",\n label: `install ${missing} with your system package manager`,\n command: null,\n });\n }\n\n if (report.cmdstan.found && report.cmdstan.version === version) return steps;\n\n const home = managedCmdStanHome(version);\n const posix = platform !== \"win32\";\n // The tarball extracts into a staging dir and moves into place atomically, so\n // a partial download is never mistaken for an install on the next run.\n if (!existsSync(join(home, \"makefile\"))) {\n const root = shq(managedStanRoot());\n const staging = shq(join(managedStanRoot(), `.download-${version}`));\n const finalHome = shq(home);\n const extracted = shq(join(managedStanRoot(), `.download-${version}`, `cmdstan-${version}`));\n steps.push({\n tool: \"cmdstan\",\n label: `download CmdStan ${version}`,\n command: posix\n ? {\n command: \"sh\",\n args: [\n \"-c\",\n `rm -rf ${staging} && mkdir -p ${staging} && curl -fsSL ${shq(releaseUrl(version))} | tar -xz -C ${staging} && rm -rf ${finalHome} && mv ${extracted} ${finalHome} && rm -rf ${staging} && mkdir -p ${root}`,\n ],\n }\n : null,\n });\n }\n // `make build` compiles stanc/main.o/precompiled headers; it is idempotent,\n // so a partially built install just resumes. stansummary is one of the last\n // artifacts, so its presence marks a completed build.\n if (!existsSync(join(home, \"bin\", \"stansummary\"))) {\n steps.push({\n tool: \"build\",\n label: `build CmdStan ${version} (one-time, a few minutes)`,\n command: posix\n ? { command: \"make\", args: [\"-C\", home, \"build\", `-j${cpus().length}`] }\n : null,\n });\n }\n return steps;\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 StanSetupResult {\n cmdstan: ToolInfo;\n stanc: ToolInfo;\n make: ToolInfo;\n cxx: ToolInfo;\n /** True when a Stan fit can run after setup. */\n ready: boolean;\n steps: SetupStepResult[];\n}\n\nexport interface StanSetupOptions {\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 /** CmdStan version to provision; defaults to the pinned version. */\n version?: string;\n}\n\nfunction validateVersion(version: string): void {\n if (!/^\\d+\\.\\d+\\.\\d+(-rc\\d+)?$/.test(version)) {\n throw new Error(\n `invalid CmdStan version: \"${version}\" (expected e.g. ${PINNED_CMDSTAN_VERSION})`,\n );\n }\n}\n\n/** Installs the CmdStan toolchain needed for Stan inference. */\nexport async function runSetup(options: StanSetupOptions = {}): Promise<StanSetupResult> {\n const {\n runner,\n installer = createRunner(30 * 60_000),\n platform = process.platform,\n dryRun = false,\n version = PINNED_CMDSTAN_VERSION,\n } = options;\n validateVersion(version);\n\n const before = await runDoctor(runner);\n const plan = planSetup(before, platform, version);\n const strip = ({ install: _install, ...report }: StanDoctorReport) => report;\n if (plan.length === 0) return { ...strip(before), steps: [] };\n\n if (dryRun) {\n return {\n ...strip(before),\n steps: plan.map((step) => ({ ...step, status: step.command ? \"skipped\" : \"unsupported\" })),\n };\n }\n\n const steps: SetupStepResult[] = [];\n let failed = false;\n for (const step of plan) {\n if (!step.command) {\n steps.push({ ...step, status: \"unsupported\" });\n failed = failed || step.tool === \"toolchain\";\n continue;\n }\n if (failed) {\n steps.push({ ...step, status: \"skipped\" });\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 failed = true;\n }\n }\n\n const after = await runDoctor(runner);\n return { ...strip(after), steps };\n}\n","import { rmSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { RuntimeVersion } from \"@mcmcjs/engine\";\nimport { listCmdStanInstalls, managedStanRoot } from \"./environment\";\nimport { runSetup, type StanSetupOptions, type StanSetupResult } from \"./setup\";\n\n/**\n * Lists the installed CmdStan versions, newest first. The newest is the\n * default: the `installed` channel resolves to it.\n */\nexport function listVersions(): RuntimeVersion[] {\n return listCmdStanInstalls().map((install, index) => ({\n id: install.version,\n version: install.version,\n path: install.home,\n isDefault: index === 0,\n }));\n}\n\n/** Installs a CmdStan version into the managed root. */\nexport function addVersion(\n version: string,\n options: Omit<StanSetupOptions, \"version\"> = {},\n): Promise<StanSetupResult> {\n return runSetup({ ...options, version });\n}\n\n/**\n * Removes a managed CmdStan install. Only versions under the managed root are\n * removable; `~/.cmdstan` installs and explicit env-var homes are never touched.\n */\nexport function removeVersion(version: string): void {\n const install = listCmdStanInstalls().find((i) => i.version === version);\n if (!install) {\n throw new Error(`CmdStan ${version} is not installed`);\n }\n const managedHome = join(managedStanRoot(), `cmdstan-${version}`);\n if (install.home !== managedHome) {\n throw new Error(\n `CmdStan ${version} at ${install.home} is not managed by mcmcjs; remove it yourself if intended`,\n );\n }\n rmSync(managedHome, { recursive: true, force: true });\n}\n"],"mappings":"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","names":["existsSync","readFileSync","join","createRunner","createRunner","readFileSync","join","createRunner","existsSync","createHash","existsSync","mkdirSync","readFileSync","writeFileSync","join","createHash","join","mkdirSync","writeFileSync","spawn","readFileSync","existsSync","join","join","createHash","existsSync","mkdirSync","mkdtempSync","readFileSync","renameSync","rmSync","writeFileSync","tmpdir","join","canonicalJson","fromStanCSVFiles","parseSamples","RUN_RECORD_SCHEMA_VERSION","toMCMCChainsJson","sha256","createHash","tmpParent","join","tmpdir","parseSamples","readFileSync","mkdirSync","mkdtempSync","writeFileSync","spawn","fromStanCSVFiles","toMCMCChainsJson","renameSync","RUN_RECORD_SCHEMA_VERSION","existsSync","canonicalJson","rmSync","existsSync","join","createRunner","join","existsSync","createRunner","rmSync","join","join","rmSync"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mcmcjs/stan",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Stan runtime engine for MCMC.js: provisions CmdStan, compiles models, and runs NUTS with streamed progress and draws.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mcmc",
|
|
7
|
+
"bayesian",
|
|
8
|
+
"inference",
|
|
9
|
+
"stan",
|
|
10
|
+
"cmdstan",
|
|
11
|
+
"nuts"
|
|
12
|
+
],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"author": {
|
|
15
|
+
"name": "Shravan Goswami",
|
|
16
|
+
"email": "contact@shravangoswami.com",
|
|
17
|
+
"url": "https://shravangoswami.com"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://github.com/mcmcjs/mcmcjs/tree/main/packages/stan#readme",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/mcmcjs/mcmcjs.git",
|
|
23
|
+
"directory": "packages/stan"
|
|
24
|
+
},
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/mcmcjs/mcmcjs/issues"
|
|
27
|
+
},
|
|
28
|
+
"type": "module",
|
|
29
|
+
"main": "./dist/index.cjs",
|
|
30
|
+
"module": "./dist/index.js",
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"import": "./dist/index.js",
|
|
36
|
+
"require": "./dist/index.cjs"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist"
|
|
41
|
+
],
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=22"
|
|
44
|
+
},
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsup",
|
|
50
|
+
"typecheck": "tsc --noEmit"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@mcmcjs/core": "workspace:*",
|
|
54
|
+
"@mcmcjs/engine": "workspace:*"
|
|
55
|
+
}
|
|
56
|
+
}
|