@mcmcjs/julia 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/environment.ts","../src/doctor.ts","../src/setup.ts"],"sourcesContent":["export type { DoctorReport } from \"./doctor\";\nexport { runDoctor } from \"./doctor\";\nexport type { CommandRunner, ToolInfo } from \"./environment\";\nexport { detectJulia, detectJuliaup } from \"./environment\";\nexport type {\n InstallCommand,\n SetupOptions,\n SetupResult,\n SetupStep,\n SetupStepResult,\n StepStatus,\n} from \"./setup\";\nexport { juliaupInstallCommand, planSetup, runSetup } from \"./setup\";\n","import { execFile } from \"node:child_process\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\n/** Information about a detected command-line tool. */\nexport interface ToolInfo {\n found: boolean;\n version?: string;\n path?: string;\n}\n\n/** Runs a command and resolves its stdout. Injectable so detection is testable. */\nexport type CommandRunner = (command: string, args: string[]) => Promise<string>;\n\n/** Creates a runner backed by execFile with the given timeout in milliseconds. */\nexport function createRunner(timeoutMs = 10_000): CommandRunner {\n return async (command, args) => {\n const { stdout } = await execFileAsync(command, args, {\n timeout: timeoutMs,\n maxBuffer: 16 * 1024 * 1024,\n });\n return stdout;\n };\n}\n\nconst defaultRunner = createRunner();\n\n// juliaup installs its shims here; we also fall back to whatever is on PATH.\nfunction candidates(binary: string): string[] {\n return [join(homedir(), \".juliaup\", \"bin\", binary), binary];\n}\n\nasync function detect(\n binary: string,\n parseVersion: (stdout: string) => string | undefined,\n runner: CommandRunner,\n): Promise<ToolInfo> {\n for (const path of candidates(binary)) {\n try {\n const version = parseVersion(await runner(path, [\"--version\"]));\n if (version) return { found: true, version, path };\n } catch {\n // not available at this path; try the next candidate\n }\n }\n return { found: false };\n}\n\nconst versionNumber = (stdout: string): string | undefined => stdout.match(/(\\d+\\.\\d+\\.\\d+)/)?.[1];\n\n/** Detects the Julia runtime via `julia --version`. */\nexport function detectJulia(runner: CommandRunner = defaultRunner): Promise<ToolInfo> {\n return detect(\"julia\", versionNumber, runner);\n}\n\n/** Detects the juliaup version manager via `juliaup --version`. */\nexport function detectJuliaup(runner: CommandRunner = defaultRunner): Promise<ToolInfo> {\n return detect(\"juliaup\", versionNumber, runner);\n}\n","import { type CommandRunner, detectJulia, detectJuliaup, type ToolInfo } from \"./environment\";\n\n/** A summary of the Julia toolchain available for inference. */\nexport interface DoctorReport {\n juliaup: ToolInfo;\n julia: ToolInfo;\n /** True when Julia itself is available (the minimum needed to run inference). */\n ready: boolean;\n}\n\n/** Detects the installed Julia toolchain and reports whether inference can run. */\nexport async function runDoctor(runner?: CommandRunner): Promise<DoctorReport> {\n const [juliaup, julia] = await Promise.all([detectJuliaup(runner), detectJulia(runner)]);\n return { juliaup, julia, ready: julia.found };\n}\n","import { type DoctorReport, runDoctor } from \"./doctor\";\nimport { type CommandRunner, createRunner, type ToolInfo } from \"./environment\";\n\n/** The official juliaup install script, piped to a shell by the install step. */\nconst JULIAUP_INSTALL_URL = \"https://install.julialang.org\";\n\n/** An executable and its arguments, run directly (no shell word-splitting). */\nexport interface InstallCommand {\n command: string;\n args: string[];\n}\n\n/**\n * The command that installs juliaup on the given platform, or null when\n * automatic install is not yet supported there.\n */\nexport function juliaupInstallCommand(platform: NodeJS.Platform): InstallCommand | null {\n if (platform === \"win32\") {\n // TODO: install juliaup on Windows via winget or the Microsoft Store.\n return null;\n }\n return { command: \"sh\", args: [\"-c\", `curl -fsSL ${JULIAUP_INSTALL_URL} | sh -s -- --yes`] };\n}\n\n/** A single provisioning step needed to make the toolchain ready. */\nexport interface SetupStep {\n tool: \"juliaup\" | \"julia\";\n /** A short description of what the step does. */\n label: string;\n /** The command to run, or null when the step cannot be performed automatically. */\n command: InstallCommand | null;\n}\n\n/** The ordered steps needed to reach a ready toolchain, given the current state. */\nexport function planSetup(report: DoctorReport, platform: NodeJS.Platform): SetupStep[] {\n if (report.julia.found) return [];\n if (report.juliaup.found) {\n return [\n {\n tool: \"julia\",\n label: \"install the latest stable Julia via juliaup\",\n command: { command: report.juliaup.path ?? \"juliaup\", args: [\"add\", \"release\"] },\n },\n ];\n }\n return [\n {\n tool: \"juliaup\",\n label: \"install juliaup (this also installs Julia)\",\n command: juliaupInstallCommand(platform),\n },\n ];\n}\n\nexport type StepStatus = \"ran\" | \"skipped\" | \"failed\" | \"unsupported\";\n\nexport interface SetupStepResult extends SetupStep {\n status: StepStatus;\n /** Error detail when the step failed. */\n detail?: string;\n}\n\nexport interface SetupResult {\n juliaup: ToolInfo;\n julia: ToolInfo;\n /** True when Julia is available after setup. */\n ready: boolean;\n steps: SetupStepResult[];\n}\n\nexport interface SetupOptions {\n /** Runs detection commands. Injectable for tests. */\n runner?: CommandRunner;\n /** Runs install steps, which may take several minutes. Injectable for tests. */\n installer?: CommandRunner;\n /** Target platform; defaults to the current process platform. */\n platform?: NodeJS.Platform;\n /** Plan the steps but do not run them. */\n dryRun?: boolean;\n}\n\n/** Installs the Julia toolchain (juliaup and Julia) needed for inference. */\nexport async function runSetup(options: SetupOptions = {}): Promise<SetupResult> {\n const {\n runner,\n installer = createRunner(15 * 60_000),\n platform = process.platform,\n dryRun = false,\n } = options;\n\n const before = await runDoctor(runner);\n if (before.ready) return { ...before, steps: [] };\n\n const plan = planSetup(before, platform);\n\n if (dryRun) {\n return {\n ...before,\n steps: plan.map((step) => ({ ...step, status: step.command ? \"skipped\" : \"unsupported\" })),\n };\n }\n\n const steps: SetupStepResult[] = [];\n for (const step of plan) {\n if (!step.command) {\n steps.push({ ...step, status: \"unsupported\" });\n continue;\n }\n try {\n await installer(step.command.command, step.command.args);\n steps.push({ ...step, status: \"ran\" });\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n steps.push({ ...step, status: \"failed\", detail });\n }\n }\n\n const after = await runDoctor(runner);\n return { juliaup: after.juliaup, julia: after.julia, ready: after.ready, steps };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.15_typescript@6.0.3/node_modules/tsup/assets/cjs_shims.js","../src/environment.ts","../src/doctor.ts","../src/engine.ts","../src/fit.ts","../src/runner-common.ts","../src/predict.ts","../src/project.ts","../src/run-matrix.ts","../src/setup.ts","../src/versions.ts"],"sourcesContent":["export type { DoctorReport } from \"./doctor\";\nexport { runDoctor } from \"./doctor\";\nexport { juliaEngine } from \"./engine\";\nexport type { CommandRunner, ToolInfo } from \"./environment\";\nexport { detectJulia, detectJuliaup } from \"./environment\";\nexport type { FitIo } from \"./fit\";\nexport { runFit } from \"./fit\";\nexport type { PredictIo } from \"./predict\";\nexport { predictData, runPredict } from \"./predict\";\nexport { ensureProject, managedProjectDir, managedProjectReady } from \"./project\";\nexport type { MatrixEntry, MatrixIo, MatrixResult } from \"./run-matrix\";\nexport { runMatrix } from \"./run-matrix\";\nexport type {\n InstallCommand,\n SetupOptions,\n SetupResult,\n SetupStep,\n SetupStepResult,\n StepStatus,\n} from \"./setup\";\nexport { juliaupInstallCommand, planSetup, runSetup } from \"./setup\";\nexport {\n addVersion,\n assertVersionsInstalled,\n gcVersions,\n listVersions,\n removeVersion,\n resolveVersion,\n setDefaultVersion,\n updateVersion,\n} from \"./versions\";\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { type CommandRunner, createRunner, type ToolInfo } from \"@mcmcjs/engine\";\n\nexport type { CommandRunner, ToolInfo } from \"@mcmcjs/engine\";\nexport { createRunner } from \"@mcmcjs/engine\";\n\nconst defaultRunner = createRunner();\n\n// juliaup installs its shims here; we also fall back to whatever is on PATH.\nfunction candidates(binary: string): string[] {\n return [join(homedir(), \".juliaup\", \"bin\", binary), binary];\n}\n\nasync function detect(\n binary: string,\n parseVersion: (stdout: string) => string | undefined,\n runner: CommandRunner,\n): Promise<ToolInfo> {\n for (const path of candidates(binary)) {\n try {\n const version = parseVersion(await runner(path, [\"--version\"]));\n if (version) return { found: true, version, path };\n } catch {\n // not available at this path; try the next candidate\n }\n }\n return { found: false };\n}\n\nconst versionNumber = (stdout: string): string | undefined => stdout.match(/(\\d+\\.\\d+\\.\\d+)/)?.[1];\n\n/** Detects the Julia runtime via `julia --version`. */\nexport function detectJulia(runner: CommandRunner = defaultRunner): Promise<ToolInfo> {\n return detect(\"julia\", versionNumber, runner);\n}\n\n/** Detects the juliaup version manager via `juliaup --version`. */\nexport function detectJuliaup(runner: CommandRunner = defaultRunner): Promise<ToolInfo> {\n return detect(\"juliaup\", versionNumber, runner);\n}\n","import { type CommandRunner, detectJulia, detectJuliaup, type ToolInfo } from \"./environment\";\n\n/** A summary of the Julia toolchain available for inference. */\nexport interface DoctorReport {\n juliaup: ToolInfo;\n julia: ToolInfo;\n /** True when Julia itself is available (the minimum needed to run inference). */\n ready: boolean;\n}\n\n/** Detects the installed Julia toolchain and reports whether inference can run. */\nexport async function runDoctor(runner?: CommandRunner): Promise<DoctorReport> {\n const [juliaup, julia] = await Promise.all([detectJuliaup(runner), detectJulia(runner)]);\n return { juliaup, julia, ready: julia.found };\n}\n","import type { Engine, EngineContext, HealthReport } from \"@mcmcjs/engine\";\nimport { runDoctor } from \"./doctor\";\n\nconst JULIAUP_URL = \"https://github.com/JuliaLang/juliaup\";\n\nexport const juliaEngine: Engine = {\n id: \"julia\",\n displayName: \"Julia\",\n capabilities: { setup: true, versions: true, fit: true, predict: true },\n async doctor(ctx: EngineContext): Promise<HealthReport> {\n const report = await runDoctor(ctx.run);\n return {\n engineId: \"julia\",\n ready: report.ready,\n tools: [\n { name: \"juliaup\", ...report.juliaup },\n { name: \"julia\", ...report.julia },\n ],\n hint: report.ready\n ? undefined\n : `Julia not found. Install it with juliaup (${JULIAUP_URL}), or run \\`mcmc setup\\`.`,\n };\n },\n};\n","import { existsSync, mkdtempSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n canonicalJson,\n parseSamples,\n type ResolvedSpec,\n RUN_RECORD_SCHEMA_VERSION,\n type RunRecord,\n} from \"@mcmcjs/core\";\nimport type { FitResult, FitRunner } from \"@mcmcjs/engine\";\nimport { driverPath, lastJsonLine, sha256, toStage } from \"./runner-common\";\n\nexport interface FitIo {\n /** Spawns the Julia process; injectable so runFit is testable without Julia. */\n spawn: FitRunner;\n /** The managed Julia project directory passed as --project. */\n projectDir: string;\n /** Where the samples file is written. */\n outPath: string;\n tmpDir?: string;\n}\n\n/** Runs one inference for a resolved spec on a resolved runtime invocation. */\nexport async function runFit(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: FitIo,\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n const runtimeRequested = spec.backend.version;\n\n const tmp = io.tmpDir ?? mkdtempSync(join(tmpdir(), \"mcmcjs-fit-\"));\n const requestPath = join(tmp, \"request.json\");\n writeFileSync(\n requestPath,\n JSON.stringify({\n schema_version: spec.schema_version,\n backend: { id: spec.backend.id },\n model: { file: spec.modelPath, entry: spec.model.entry },\n data: spec.data,\n sampler: spec.sampler,\n seed: spec.seed,\n out: io.outPath,\n }),\n );\n\n const args = [\n ...resolved.args,\n \"--startup-file=no\",\n `--project=${io.projectDir}`,\n driverPath(),\n requestPath,\n ];\n const { stdout, stderr, code } = await io.spawn(resolved.command, args);\n const elapsedMs = Math.round(performance.now() - start);\n\n if (code !== 0 || !existsSync(io.outPath)) {\n const failure = lastJsonLine(stderr);\n const stage = toStage(failure?.stage);\n const error =\n (failure?.error as string) ??\n stderr.trim().split(\"\\n\").pop() ??\n `julia exited with code ${code}`;\n return { status: \"error\", runtimeRequested, elapsedMs, stage, error };\n }\n\n try {\n parseSamples(readFileSync(io.outPath, \"utf8\"));\n } catch (error) {\n return {\n status: \"error\",\n runtimeRequested,\n elapsedMs,\n stage: \"write\",\n error: `samples file did not parse: ${(error as Error).message}`,\n };\n }\n\n const provenance = lastJsonLine(stdout);\n const julia = provenance?.julia_version as string | undefined;\n const record: RunRecord = {\n schema_version: RUN_RECORD_SCHEMA_VERSION,\n spec_hash: spec.specHash,\n seed: spec.seed,\n backend: { id: spec.backend.id, runtime: spec.backend.runtime },\n runtime: { requested: runtimeRequested, actual: julia, path: resolved.command },\n manifest_sha256: provenance?.manifest_sha256 as string | undefined,\n packages: provenance?.packages as Record<string, string> | undefined,\n model_sha256: existsSync(spec.modelPath)\n ? sha256(readFileSync(spec.modelPath, \"utf8\"))\n : undefined,\n data_sha256: sha256(canonicalJson(spec.data)),\n samples_file: io.outPath,\n started_at: startedAt,\n elapsed_ms: elapsedMs,\n };\n writeFileSync(`${io.outPath}.run.json`, `${JSON.stringify(record, null, 2)}\\n`);\n\n return {\n status: \"ok\",\n samplesFile: io.outPath,\n runtimeRequested,\n runtimeActual: julia,\n elapsedMs,\n };\n}\n","import { createHash } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { FitResult } from \"@mcmcjs/engine\";\n\n/** Path to the shipped Julia driver, resolved next to this module in dist/. */\nexport function driverPath(): string {\n return join(dirname(fileURLToPath(import.meta.url)), \"driver.jl\");\n}\n\nexport function sha256(text: string): string {\n return createHash(\"sha256\").update(text).digest(\"hex\");\n}\n\n/** Parses the last JSON-object line of text (the driver's provenance or error line). */\nexport function lastJsonLine(text: string): Record<string, unknown> | undefined {\n for (const line of text.trimEnd().split(\"\\n\").reverse()) {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"{\")) continue;\n try {\n return JSON.parse(trimmed) as Record<string, unknown>;\n } catch {\n return undefined;\n }\n }\n return undefined;\n}\n\nconst STAGES = new Set<NonNullable<FitResult[\"stage\"]>>([\n \"compile\",\n \"sample\",\n \"load_samples\",\n \"predict\",\n \"write\",\n \"spawn\",\n]);\n\n/** Narrows a driver-reported stage string to the known set. */\nexport function toStage(value: unknown): FitResult[\"stage\"] {\n return typeof value === \"string\" && STAGES.has(value as NonNullable<FitResult[\"stage\"]>)\n ? (value as FitResult[\"stage\"])\n : undefined;\n}\n","import { existsSync, mkdtempSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n canonicalJson,\n parseSamples,\n type ResolvedSpec,\n RUN_RECORD_SCHEMA_VERSION,\n type RunRecord,\n} from \"@mcmcjs/core\";\nimport type { FitResult, FitRunner } from \"@mcmcjs/engine\";\nimport { driverPath, lastJsonLine, sha256, toStage } from \"./runner-common\";\n\nexport interface PredictIo {\n /** Spawns the Julia process; injectable so runPredict is testable without Julia. */\n spawn: FitRunner;\n projectDir: string;\n /** Where the posterior-predictive samples file is written. */\n outPath: string;\n /** The posterior samples file fed to prediction. */\n samplesPath: string;\n tmpDir?: string;\n}\n\n/** The prediction data: [data] with [predict].data overrides, target outcomes blanked to nulls. */\nexport function predictData(spec: ResolvedSpec): Record<string, unknown> {\n const predict = spec.predict;\n if (!predict) throw new Error(\"spec has no [predict] block\");\n const data: Record<string, unknown> = { ...spec.data, ...(predict.data ?? {}) };\n // Blank a target to null, preserving array shape so the driver maps it to a\n // matching shape of `missing` (a multidimensional outcome stays nested).\n const blank = (value: unknown): unknown => (Array.isArray(value) ? value.map(blank) : null);\n for (const target of predict.targets) {\n data[target] = blank(data[target]);\n }\n return data;\n}\n\n/** Draws posterior-predictive samples from a fitted model and its posterior samples file. */\nexport async function runPredict(\n spec: ResolvedSpec,\n resolved: { command: string; args: string[] },\n io: PredictIo,\n): Promise<FitResult> {\n const startedAt = new Date().toISOString();\n const start = performance.now();\n const runtimeRequested = spec.backend.version;\n const data = predictData(spec);\n\n const tmp = io.tmpDir ?? mkdtempSync(join(tmpdir(), \"mcmcjs-predict-\"));\n const requestPath = join(tmp, \"request.json\");\n writeFileSync(\n requestPath,\n JSON.stringify({\n mode: \"predict\",\n schema_version: spec.schema_version,\n backend: { id: spec.backend.id },\n model: { file: spec.modelPath, entry: spec.model.entry },\n data,\n predict: { targets: spec.predict?.targets ?? [] },\n samples: io.samplesPath,\n seed: spec.seed,\n out: io.outPath,\n }),\n );\n\n const args = [\n ...resolved.args,\n \"--startup-file=no\",\n `--project=${io.projectDir}`,\n driverPath(),\n requestPath,\n ];\n const { stdout, stderr, code } = await io.spawn(resolved.command, args);\n const elapsedMs = Math.round(performance.now() - start);\n\n if (code !== 0 || !existsSync(io.outPath)) {\n const failure = lastJsonLine(stderr);\n const error =\n (failure?.error as string) ??\n stderr.trim().split(\"\\n\").pop() ??\n `julia exited with code ${code}`;\n return { status: \"error\", runtimeRequested, elapsedMs, stage: toStage(failure?.stage), error };\n }\n\n try {\n parseSamples(readFileSync(io.outPath, \"utf8\"));\n } catch (error) {\n return {\n status: \"error\",\n runtimeRequested,\n elapsedMs,\n stage: \"write\",\n error: `samples file did not parse: ${(error as Error).message}`,\n };\n }\n\n const provenance = lastJsonLine(stdout);\n const julia = provenance?.julia_version as string | undefined;\n const record: RunRecord = {\n schema_version: RUN_RECORD_SCHEMA_VERSION,\n spec_hash: spec.specHash,\n seed: spec.seed,\n backend: { id: spec.backend.id, runtime: spec.backend.runtime },\n runtime: { requested: runtimeRequested, actual: julia, path: resolved.command },\n manifest_sha256: provenance?.manifest_sha256 as string | undefined,\n packages: provenance?.packages as Record<string, string> | undefined,\n model_sha256: existsSync(spec.modelPath)\n ? sha256(readFileSync(spec.modelPath, \"utf8\"))\n : undefined,\n data_sha256: sha256(canonicalJson(data)),\n posterior_samples: io.samplesPath,\n posterior_samples_sha256: existsSync(io.samplesPath)\n ? sha256(readFileSync(io.samplesPath, \"utf8\"))\n : undefined,\n samples_file: io.outPath,\n started_at: startedAt,\n elapsed_ms: elapsedMs,\n };\n writeFileSync(`${io.outPath}.run.json`, `${JSON.stringify(record, null, 2)}\\n`);\n\n return {\n status: \"ok\",\n samplesFile: io.outPath,\n runtimeRequested,\n runtimeActual: julia,\n elapsedMs,\n };\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { type CommandRunner, createRunner } from \"@mcmcjs/engine\";\n\nconst PACKAGES = [\n \"Turing\",\n \"FlexiChains\",\n \"DimensionalData\",\n \"MCMCChains\",\n \"JuliaBUGS\",\n \"AdvancedHMC\",\n \"ForwardDiff\",\n \"JSON\",\n \"StableRNGs\",\n];\n\n/** The per-user directory holding the managed Julia project (Project + Manifest). */\nexport function managedProjectDir(): string {\n const base = process.env.XDG_DATA_HOME || join(homedir(), \".local\", \"share\");\n return join(base, \"mcmcjs\", \"julia\", \"env\");\n}\n\n// Records the package set a managed dir was provisioned with, so an env from an\n// older package set is healed (Pkg.add is additive) rather than left incomplete.\nfunction sentinelPath(dir: string): string {\n return join(dir, \".mcmcjs-packages.json\");\n}\n\nfunction provisioned(dir: string): boolean {\n try {\n return readFileSync(sentinelPath(dir), \"utf8\").trim() === JSON.stringify([...PACKAGES].sort());\n } catch {\n return false;\n }\n}\n\n/** Whether the managed project is present and provisioned with the current package set. */\nexport function managedProjectReady(dir: string = managedProjectDir()): boolean {\n return existsSync(join(dir, \"Project.toml\")) && provisioned(dir);\n}\n\n/**\n * Ensures the managed Julia project exists with the inference packages installed.\n * Idempotent: returns immediately when already provisioned with the current set,\n * otherwise adds (and precompiles) the missing packages. The first run resolves\n * and precompiles the project, which can take several minutes.\n */\nexport async function ensureProject(\n juliaBin: string,\n run: CommandRunner = createRunner(30 * 60_000),\n dir: string = managedProjectDir(),\n): Promise<string> {\n if (managedProjectReady(dir)) return dir;\n mkdirSync(dir, { recursive: true });\n const code = `using Pkg; Pkg.add(${JSON.stringify(PACKAGES)}); Pkg.precompile()`;\n await run(juliaBin, [\"--startup-file=no\", `--project=${dir}`, \"-e\", code]);\n writeFileSync(sentinelPath(dir), JSON.stringify([...PACKAGES].sort()));\n return dir;\n}\n","import { join } from \"node:path\";\nimport type { ResolvedSpec } from \"@mcmcjs/core\";\nimport type { FitResult, FitRunner } from \"@mcmcjs/engine\";\nimport { runFit } from \"./fit\";\n\nexport interface MatrixEntry {\n version: string;\n status: \"ok\" | \"error\";\n samplesFile?: string;\n runtimeActual?: string;\n elapsedMs: number;\n stage?: FitResult[\"stage\"];\n error?: string;\n}\n\nexport interface MatrixResult {\n entries: MatrixEntry[];\n /** True only when every requested version ran and succeeded. */\n ok: boolean;\n}\n\nexport interface MatrixIo {\n spawn: FitRunner;\n projectDir: string;\n /** Directory the per-version samples files are written into. */\n outDir: string;\n /** Resolves a version/channel to a concrete invocation; injectable for tests. */\n resolve: (version: string) => Promise<{ command: string; args: string[] }>;\n /** Continue after a version fails instead of stopping. */\n keepGoing?: boolean;\n}\n\n/** Runs the same spec across several Julia versions, one samples file per version. */\nexport async function runMatrix(\n spec: ResolvedSpec,\n versions: string[],\n io: MatrixIo,\n): Promise<MatrixResult> {\n const entries: MatrixEntry[] = [];\n for (const version of versions) {\n let entry: MatrixEntry;\n try {\n const resolved = await io.resolve(version);\n const versioned = { ...spec, backend: { ...spec.backend, version } };\n const result = await runFit(versioned, resolved, {\n spawn: io.spawn,\n projectDir: io.projectDir,\n outPath: join(io.outDir, `${version}.samples.json`),\n });\n entry = {\n version,\n status: result.status,\n samplesFile: result.samplesFile,\n runtimeActual: result.runtimeActual,\n elapsedMs: result.elapsedMs,\n stage: result.stage,\n error: result.error,\n };\n } catch (error) {\n entry = { version, status: \"error\", elapsedMs: 0, error: (error as Error).message };\n }\n entries.push(entry);\n if (entry.status === \"error\" && !io.keepGoing) break;\n }\n return {\n entries,\n ok: entries.length === versions.length && entries.every((e) => e.status === \"ok\"),\n };\n}\n","import { type DoctorReport, runDoctor } from \"./doctor\";\nimport { type CommandRunner, createRunner, type ToolInfo } from \"./environment\";\n\n/** The official juliaup install script, piped to a shell by the install step. */\nconst JULIAUP_INSTALL_URL = \"https://install.julialang.org\";\n\n/** An executable and its arguments, run directly (no shell word-splitting). */\nexport interface InstallCommand {\n command: string;\n args: string[];\n}\n\n/**\n * The command that installs juliaup on the given platform, or null when\n * automatic install is not yet supported there.\n */\nexport function juliaupInstallCommand(platform: NodeJS.Platform): InstallCommand | null {\n if (platform === \"win32\") {\n // TODO: install juliaup on Windows via winget or the Microsoft Store.\n return null;\n }\n return { command: \"sh\", args: [\"-c\", `curl -fsSL ${JULIAUP_INSTALL_URL} | sh -s -- --yes`] };\n}\n\n/** A single provisioning step needed to make the toolchain ready. */\nexport interface SetupStep {\n tool: \"juliaup\" | \"julia\";\n /** A short description of what the step does. */\n label: string;\n /** The command to run, or null when the step cannot be performed automatically. */\n command: InstallCommand | null;\n}\n\n/** The ordered steps needed to reach a ready toolchain, given the current state. */\nexport function planSetup(report: DoctorReport, platform: NodeJS.Platform): SetupStep[] {\n if (report.julia.found) return [];\n if (report.juliaup.found) {\n return [\n {\n tool: \"julia\",\n label: \"install the latest stable Julia via juliaup\",\n command: { command: report.juliaup.path ?? \"juliaup\", args: [\"add\", \"release\"] },\n },\n ];\n }\n return [\n {\n tool: \"juliaup\",\n label: \"install juliaup (this also installs Julia)\",\n command: juliaupInstallCommand(platform),\n },\n ];\n}\n\nexport type StepStatus = \"ran\" | \"skipped\" | \"failed\" | \"unsupported\";\n\nexport interface SetupStepResult extends SetupStep {\n status: StepStatus;\n /** Error detail when the step failed. */\n detail?: string;\n}\n\nexport interface SetupResult {\n juliaup: ToolInfo;\n julia: ToolInfo;\n /** True when Julia is available after setup. */\n ready: boolean;\n steps: SetupStepResult[];\n}\n\nexport interface SetupOptions {\n /** Runs detection commands. Injectable for tests. */\n runner?: CommandRunner;\n /** Runs install steps, which may take several minutes. Injectable for tests. */\n installer?: CommandRunner;\n /** Target platform; defaults to the current process platform. */\n platform?: NodeJS.Platform;\n /** Plan the steps but do not run them. */\n dryRun?: boolean;\n}\n\n/** Installs the Julia toolchain (juliaup and Julia) needed for inference. */\nexport async function runSetup(options: SetupOptions = {}): Promise<SetupResult> {\n const {\n runner,\n installer = createRunner(15 * 60_000),\n platform = process.platform,\n dryRun = false,\n } = options;\n\n const before = await runDoctor(runner);\n if (before.ready) return { ...before, steps: [] };\n\n const plan = planSetup(before, platform);\n\n if (dryRun) {\n return {\n ...before,\n steps: plan.map((step) => ({ ...step, status: step.command ? \"skipped\" : \"unsupported\" })),\n };\n }\n\n const steps: SetupStepResult[] = [];\n for (const step of plan) {\n if (!step.command) {\n steps.push({ ...step, status: \"unsupported\" });\n continue;\n }\n try {\n await installer(step.command.command, step.command.args);\n steps.push({ ...step, status: \"ran\" });\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n steps.push({ ...step, status: \"failed\", detail });\n }\n }\n\n const after = await runDoctor(runner);\n return { juliaup: after.juliaup, julia: after.julia, ready: after.ready, steps };\n}\n","import type { CommandRunner, RuntimeVersion } from \"@mcmcjs/engine\";\n\ninterface ChannelInfo {\n Name: string;\n File: string;\n Args?: string[];\n Version?: string;\n Arch?: string;\n}\n\ninterface Getconfig1 {\n DefaultChannel: ChannelInfo | null;\n OtherChannels: ChannelInfo[];\n}\n\nfunction parseChannel(value: unknown): ChannelInfo {\n const c = value as Record<string, unknown>;\n if (!c || typeof c.Name !== \"string\" || typeof c.File !== \"string\") {\n throw new Error(\"unexpected `juliaup api getconfig1` channel shape\");\n }\n return {\n Name: c.Name,\n File: c.File,\n Args: Array.isArray(c.Args) ? (c.Args as string[]) : undefined,\n Version: typeof c.Version === \"string\" ? c.Version : undefined,\n Arch: typeof c.Arch === \"string\" ? c.Arch : undefined,\n };\n}\n\nfunction parseGetconfig1(raw: string): Getconfig1 {\n let data: unknown;\n try {\n data = JSON.parse(raw);\n } catch {\n throw new Error(\"could not parse `juliaup api getconfig1` output as JSON\");\n }\n const obj = data as Record<string, unknown>;\n if (!obj || typeof obj !== \"object\" || !Array.isArray(obj.OtherChannels)) {\n throw new Error(\"unexpected `juliaup api getconfig1` output\");\n }\n return {\n DefaultChannel: obj.DefaultChannel ? parseChannel(obj.DefaultChannel) : null,\n OtherChannels: obj.OtherChannels.map(parseChannel),\n };\n}\n\nfunction toVersion(channel: ChannelInfo, isDefault: boolean): RuntimeVersion {\n return { id: channel.Name, version: channel.Version, path: channel.File || undefined, isDefault };\n}\n\n/** Lists the installed Julia versions, marking the default channel. */\nexport async function listVersions(bin: string, run: CommandRunner): Promise<RuntimeVersion[]> {\n const config = parseGetconfig1(await run(bin, [\"api\", \"getconfig1\"]));\n const versions: RuntimeVersion[] = [];\n if (config.DefaultChannel) versions.push(toVersion(config.DefaultChannel, true));\n for (const channel of config.OtherChannels) versions.push(toVersion(channel, false));\n return versions;\n}\n\nexport async function addVersion(\n bin: string,\n channel: string,\n opts: { default?: boolean },\n run: CommandRunner,\n): Promise<void> {\n await run(bin, [\"add\", channel]);\n if (opts.default) await run(bin, [\"default\", channel]);\n}\n\nexport async function removeVersion(\n bin: string,\n channel: string,\n run: CommandRunner,\n): Promise<void> {\n await run(bin, [\"remove\", channel]);\n}\n\nexport async function setDefaultVersion(\n bin: string,\n channel: string,\n run: CommandRunner,\n): Promise<void> {\n await run(bin, [\"default\", channel]);\n}\n\nexport async function updateVersion(\n bin: string,\n channel: string | undefined,\n run: CommandRunner,\n): Promise<void> {\n await run(bin, channel ? [\"update\", channel] : [\"update\"]);\n}\n\nexport async function gcVersions(bin: string, run: CommandRunner): Promise<void> {\n await run(bin, [\"gc\"]);\n}\n\n/** Resolves a channel to a concrete invocation, preferring its absolute binary path. */\nexport async function resolveVersion(\n bin: string,\n channel: string,\n run: CommandRunner,\n): Promise<{ command: string; args: string[] }> {\n const config = parseGetconfig1(await run(bin, [\"api\", \"getconfig1\"]));\n const all = config.DefaultChannel\n ? [config.DefaultChannel, ...config.OtherChannels]\n : config.OtherChannels;\n const match = all.find((c) => c.Name === channel);\n if (!match?.File) {\n throw new Error(\n `Julia version \"${channel}\" is not installed. Add it with: mcmc julia version add ${channel}`,\n );\n }\n return { command: match.File, args: match.Args ?? [] };\n}\n\n/** Throws with an actionable message if any requested channel is not installed. */\nexport function assertVersionsInstalled(channels: string[], installed: RuntimeVersion[]): void {\n const have = new Set(installed.map((v) => v.id));\n const missing = channels.filter((c) => !have.has(c));\n if (missing.length > 0) {\n const fixes = missing.map((m) => `mcmc julia version add ${m}`).join(\"; \");\n throw new Error(\n `Julia version(s) not installed: ${missing.join(\", \")}. Install with: ${fixes}`,\n );\n }\n}\n"],"mappings":"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","names":["import_engine","import_node_os","import_node_path","import_node_path","import_node_fs","import_node_os","import_node_path","import_core","import_node_fs","import_node_os","import_node_path","import_engine","import_node_path"]}
package/dist/index.d.cts CHANGED
@@ -1,11 +1,7 @@
1
- /** Information about a detected command-line tool. */
2
- interface ToolInfo {
3
- found: boolean;
4
- version?: string;
5
- path?: string;
6
- }
7
- /** Runs a command and resolves its stdout. Injectable so detection is testable. */
8
- type CommandRunner = (command: string, args: string[]) => Promise<string>;
1
+ import { CommandRunner, ToolInfo, Engine, FitRunner, FitResult, RuntimeVersion } from '@mcmcjs/engine';
2
+ export { CommandRunner, ToolInfo } from '@mcmcjs/engine';
3
+ import { ResolvedSpec } from '@mcmcjs/core';
4
+
9
5
  /** Detects the Julia runtime via `julia --version`. */
10
6
  declare function detectJulia(runner?: CommandRunner): Promise<ToolInfo>;
11
7
  /** Detects the juliaup version manager via `juliaup --version`. */
@@ -21,6 +17,83 @@ interface DoctorReport {
21
17
  /** Detects the installed Julia toolchain and reports whether inference can run. */
22
18
  declare function runDoctor(runner?: CommandRunner): Promise<DoctorReport>;
23
19
 
20
+ declare const juliaEngine: Engine;
21
+
22
+ interface FitIo {
23
+ /** Spawns the Julia process; injectable so runFit is testable without Julia. */
24
+ spawn: FitRunner;
25
+ /** The managed Julia project directory passed as --project. */
26
+ projectDir: string;
27
+ /** Where the samples file is written. */
28
+ outPath: string;
29
+ tmpDir?: string;
30
+ }
31
+ /** Runs one inference for a resolved spec on a resolved runtime invocation. */
32
+ declare function runFit(spec: ResolvedSpec, resolved: {
33
+ command: string;
34
+ args: string[];
35
+ }, io: FitIo): Promise<FitResult>;
36
+
37
+ interface PredictIo {
38
+ /** Spawns the Julia process; injectable so runPredict is testable without Julia. */
39
+ spawn: FitRunner;
40
+ projectDir: string;
41
+ /** Where the posterior-predictive samples file is written. */
42
+ outPath: string;
43
+ /** The posterior samples file fed to prediction. */
44
+ samplesPath: string;
45
+ tmpDir?: string;
46
+ }
47
+ /** The prediction data: [data] with [predict].data overrides, target outcomes blanked to nulls. */
48
+ declare function predictData(spec: ResolvedSpec): Record<string, unknown>;
49
+ /** Draws posterior-predictive samples from a fitted model and its posterior samples file. */
50
+ declare function runPredict(spec: ResolvedSpec, resolved: {
51
+ command: string;
52
+ args: string[];
53
+ }, io: PredictIo): Promise<FitResult>;
54
+
55
+ /** The per-user directory holding the managed Julia project (Project + Manifest). */
56
+ declare function managedProjectDir(): string;
57
+ /** Whether the managed project is present and provisioned with the current package set. */
58
+ declare function managedProjectReady(dir?: string): boolean;
59
+ /**
60
+ * Ensures the managed Julia project exists with the inference packages installed.
61
+ * Idempotent: returns immediately when already provisioned with the current set,
62
+ * otherwise adds (and precompiles) the missing packages. The first run resolves
63
+ * and precompiles the project, which can take several minutes.
64
+ */
65
+ declare function ensureProject(juliaBin: string, run?: CommandRunner, dir?: string): Promise<string>;
66
+
67
+ interface MatrixEntry {
68
+ version: string;
69
+ status: "ok" | "error";
70
+ samplesFile?: string;
71
+ runtimeActual?: string;
72
+ elapsedMs: number;
73
+ stage?: FitResult["stage"];
74
+ error?: string;
75
+ }
76
+ interface MatrixResult {
77
+ entries: MatrixEntry[];
78
+ /** True only when every requested version ran and succeeded. */
79
+ ok: boolean;
80
+ }
81
+ interface MatrixIo {
82
+ spawn: FitRunner;
83
+ projectDir: string;
84
+ /** Directory the per-version samples files are written into. */
85
+ outDir: string;
86
+ /** Resolves a version/channel to a concrete invocation; injectable for tests. */
87
+ resolve: (version: string) => Promise<{
88
+ command: string;
89
+ args: string[];
90
+ }>;
91
+ /** Continue after a version fails instead of stopping. */
92
+ keepGoing?: boolean;
93
+ }
94
+ /** Runs the same spec across several Julia versions, one samples file per version. */
95
+ declare function runMatrix(spec: ResolvedSpec, versions: string[], io: MatrixIo): Promise<MatrixResult>;
96
+
24
97
  /** An executable and its arguments, run directly (no shell word-splitting). */
25
98
  interface InstallCommand {
26
99
  command: string;
@@ -67,4 +140,21 @@ interface SetupOptions {
67
140
  /** Installs the Julia toolchain (juliaup and Julia) needed for inference. */
68
141
  declare function runSetup(options?: SetupOptions): Promise<SetupResult>;
69
142
 
70
- export { type CommandRunner, type DoctorReport, type InstallCommand, type SetupOptions, type SetupResult, type SetupStep, type SetupStepResult, type StepStatus, type ToolInfo, detectJulia, detectJuliaup, juliaupInstallCommand, planSetup, runDoctor, runSetup };
143
+ /** Lists the installed Julia versions, marking the default channel. */
144
+ declare function listVersions(bin: string, run: CommandRunner): Promise<RuntimeVersion[]>;
145
+ declare function addVersion(bin: string, channel: string, opts: {
146
+ default?: boolean;
147
+ }, run: CommandRunner): Promise<void>;
148
+ declare function removeVersion(bin: string, channel: string, run: CommandRunner): Promise<void>;
149
+ declare function setDefaultVersion(bin: string, channel: string, run: CommandRunner): Promise<void>;
150
+ declare function updateVersion(bin: string, channel: string | undefined, run: CommandRunner): Promise<void>;
151
+ declare function gcVersions(bin: string, run: CommandRunner): Promise<void>;
152
+ /** Resolves a channel to a concrete invocation, preferring its absolute binary path. */
153
+ declare function resolveVersion(bin: string, channel: string, run: CommandRunner): Promise<{
154
+ command: string;
155
+ args: string[];
156
+ }>;
157
+ /** Throws with an actionable message if any requested channel is not installed. */
158
+ declare function assertVersionsInstalled(channels: string[], installed: RuntimeVersion[]): void;
159
+
160
+ export { type DoctorReport, type FitIo, type InstallCommand, type MatrixEntry, type MatrixIo, type MatrixResult, type PredictIo, type SetupOptions, type SetupResult, type SetupStep, type SetupStepResult, type StepStatus, addVersion, assertVersionsInstalled, detectJulia, detectJuliaup, ensureProject, gcVersions, juliaEngine, juliaupInstallCommand, listVersions, managedProjectDir, managedProjectReady, planSetup, predictData, removeVersion, resolveVersion, runDoctor, runFit, runMatrix, runPredict, runSetup, setDefaultVersion, updateVersion };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,7 @@
1
- /** Information about a detected command-line tool. */
2
- interface ToolInfo {
3
- found: boolean;
4
- version?: string;
5
- path?: string;
6
- }
7
- /** Runs a command and resolves its stdout. Injectable so detection is testable. */
8
- type CommandRunner = (command: string, args: string[]) => Promise<string>;
1
+ import { CommandRunner, ToolInfo, Engine, FitRunner, FitResult, RuntimeVersion } from '@mcmcjs/engine';
2
+ export { CommandRunner, ToolInfo } from '@mcmcjs/engine';
3
+ import { ResolvedSpec } from '@mcmcjs/core';
4
+
9
5
  /** Detects the Julia runtime via `julia --version`. */
10
6
  declare function detectJulia(runner?: CommandRunner): Promise<ToolInfo>;
11
7
  /** Detects the juliaup version manager via `juliaup --version`. */
@@ -21,6 +17,83 @@ interface DoctorReport {
21
17
  /** Detects the installed Julia toolchain and reports whether inference can run. */
22
18
  declare function runDoctor(runner?: CommandRunner): Promise<DoctorReport>;
23
19
 
20
+ declare const juliaEngine: Engine;
21
+
22
+ interface FitIo {
23
+ /** Spawns the Julia process; injectable so runFit is testable without Julia. */
24
+ spawn: FitRunner;
25
+ /** The managed Julia project directory passed as --project. */
26
+ projectDir: string;
27
+ /** Where the samples file is written. */
28
+ outPath: string;
29
+ tmpDir?: string;
30
+ }
31
+ /** Runs one inference for a resolved spec on a resolved runtime invocation. */
32
+ declare function runFit(spec: ResolvedSpec, resolved: {
33
+ command: string;
34
+ args: string[];
35
+ }, io: FitIo): Promise<FitResult>;
36
+
37
+ interface PredictIo {
38
+ /** Spawns the Julia process; injectable so runPredict is testable without Julia. */
39
+ spawn: FitRunner;
40
+ projectDir: string;
41
+ /** Where the posterior-predictive samples file is written. */
42
+ outPath: string;
43
+ /** The posterior samples file fed to prediction. */
44
+ samplesPath: string;
45
+ tmpDir?: string;
46
+ }
47
+ /** The prediction data: [data] with [predict].data overrides, target outcomes blanked to nulls. */
48
+ declare function predictData(spec: ResolvedSpec): Record<string, unknown>;
49
+ /** Draws posterior-predictive samples from a fitted model and its posterior samples file. */
50
+ declare function runPredict(spec: ResolvedSpec, resolved: {
51
+ command: string;
52
+ args: string[];
53
+ }, io: PredictIo): Promise<FitResult>;
54
+
55
+ /** The per-user directory holding the managed Julia project (Project + Manifest). */
56
+ declare function managedProjectDir(): string;
57
+ /** Whether the managed project is present and provisioned with the current package set. */
58
+ declare function managedProjectReady(dir?: string): boolean;
59
+ /**
60
+ * Ensures the managed Julia project exists with the inference packages installed.
61
+ * Idempotent: returns immediately when already provisioned with the current set,
62
+ * otherwise adds (and precompiles) the missing packages. The first run resolves
63
+ * and precompiles the project, which can take several minutes.
64
+ */
65
+ declare function ensureProject(juliaBin: string, run?: CommandRunner, dir?: string): Promise<string>;
66
+
67
+ interface MatrixEntry {
68
+ version: string;
69
+ status: "ok" | "error";
70
+ samplesFile?: string;
71
+ runtimeActual?: string;
72
+ elapsedMs: number;
73
+ stage?: FitResult["stage"];
74
+ error?: string;
75
+ }
76
+ interface MatrixResult {
77
+ entries: MatrixEntry[];
78
+ /** True only when every requested version ran and succeeded. */
79
+ ok: boolean;
80
+ }
81
+ interface MatrixIo {
82
+ spawn: FitRunner;
83
+ projectDir: string;
84
+ /** Directory the per-version samples files are written into. */
85
+ outDir: string;
86
+ /** Resolves a version/channel to a concrete invocation; injectable for tests. */
87
+ resolve: (version: string) => Promise<{
88
+ command: string;
89
+ args: string[];
90
+ }>;
91
+ /** Continue after a version fails instead of stopping. */
92
+ keepGoing?: boolean;
93
+ }
94
+ /** Runs the same spec across several Julia versions, one samples file per version. */
95
+ declare function runMatrix(spec: ResolvedSpec, versions: string[], io: MatrixIo): Promise<MatrixResult>;
96
+
24
97
  /** An executable and its arguments, run directly (no shell word-splitting). */
25
98
  interface InstallCommand {
26
99
  command: string;
@@ -67,4 +140,21 @@ interface SetupOptions {
67
140
  /** Installs the Julia toolchain (juliaup and Julia) needed for inference. */
68
141
  declare function runSetup(options?: SetupOptions): Promise<SetupResult>;
69
142
 
70
- export { type CommandRunner, type DoctorReport, type InstallCommand, type SetupOptions, type SetupResult, type SetupStep, type SetupStepResult, type StepStatus, type ToolInfo, detectJulia, detectJuliaup, juliaupInstallCommand, planSetup, runDoctor, runSetup };
143
+ /** Lists the installed Julia versions, marking the default channel. */
144
+ declare function listVersions(bin: string, run: CommandRunner): Promise<RuntimeVersion[]>;
145
+ declare function addVersion(bin: string, channel: string, opts: {
146
+ default?: boolean;
147
+ }, run: CommandRunner): Promise<void>;
148
+ declare function removeVersion(bin: string, channel: string, run: CommandRunner): Promise<void>;
149
+ declare function setDefaultVersion(bin: string, channel: string, run: CommandRunner): Promise<void>;
150
+ declare function updateVersion(bin: string, channel: string | undefined, run: CommandRunner): Promise<void>;
151
+ declare function gcVersions(bin: string, run: CommandRunner): Promise<void>;
152
+ /** Resolves a channel to a concrete invocation, preferring its absolute binary path. */
153
+ declare function resolveVersion(bin: string, channel: string, run: CommandRunner): Promise<{
154
+ command: string;
155
+ args: string[];
156
+ }>;
157
+ /** Throws with an actionable message if any requested channel is not installed. */
158
+ declare function assertVersionsInstalled(channels: string[], installed: RuntimeVersion[]): void;
159
+
160
+ export { type DoctorReport, type FitIo, type InstallCommand, type MatrixEntry, type MatrixIo, type MatrixResult, type PredictIo, type SetupOptions, type SetupResult, type SetupStep, type SetupStepResult, type StepStatus, addVersion, assertVersionsInstalled, detectJulia, detectJuliaup, ensureProject, gcVersions, juliaEngine, juliaupInstallCommand, listVersions, managedProjectDir, managedProjectReady, planSetup, predictData, removeVersion, resolveVersion, runDoctor, runFit, runMatrix, runPredict, runSetup, setDefaultVersion, updateVersion };