This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
SwiftStanLibrary is a library-only Swift package (no CLI, no executable) that exposes 14 public commands and a Swift result-builder DSL for interacting with cmdstan. macOS 14+; Swift 6; no external dependencies.
Extracted from SwiftStan. The canonical SwiftStan package (with CLI) is at ../SwiftStan; this package is the curation of its library layer for downstream consumers.
The design rationale lives in ../SwiftStan/Docs/SwiftStanServer-Plan.md.
swift build
# Unit tests only (portable, no cmdstan needed)
swift test
# Unit + integration tests
CMDSTAN=/path/to/cmdstan swift testIntegration test suites (under Tests/SwiftStanLibraryTests/Integration/) are gated with .enabled(if: ProcessInfo.processInfo.environment["CMDSTAN"] != nil, ...) — they skip automatically when $CMDSTAN is unset.
The module name is SwiftStan (package name is SwiftStanLibrary), so consumers write import SwiftStan and existing imports in servers/apps that used the original SwiftStan library work unchanged.
Commands/— 12 public command functions (top-level free functions). This is the primary public API.Methods/— internal low-level cmdstan argument builders / shell-out wrappers (called by Commands, not entry points).Support/— mixed:CasePaths,RunInfoIO,StanSchemaare public (useful to consumers navigating the case layout or reading run output); the rest is internal post-processing plumbing.Helpers/— internal bootstrap helpers (install example files).Ulam/— the DSL and codegen engine:AST/,Builder/,Data/— all public (the result-builder DSL contract).Generator/—StanCodeGeneratoris internal; the public entry isstancode(_ model: UlamModel) throws -> String.Ulam.swift— two additional public orchestrators:ulam(_ model: UlamModel, ...)(V1 in-memory DSL→compile→sample) andulamPipeline(model: String, ...)(V2 file-based alist→Stan→compile→sample). These bring the total public command count to 14.Alist/,Stan2Alist/— internal (parser/emitter pipeline types).
dsl2stan is not in this library — it recompiles the package's own Ulam/ source tree via swiftc, which is not viable in a distributed binary. Use stancode (in-process, fast) instead; if you need a smoke driver for prototyping, use alist2dsl first, then hand it to the original SwiftStan CLI.
The cmdstan-backed commands return (status, errorOrEmpty):
.0— human-readable status line..1— error message (""on success). Callers branch on.1 == "".
This is the same convention as the original SwiftStan CLI; don't replace it with throws piecemeal.
Support/CasePaths.swift owns the $STAN_CASES → ~/Documents/StanCases/ default resolution. The internal caseRootOverride global redirects tests to a _Test sibling dir (accessed via @testable import SwiftStan in the test target only — it is not part of the public API).
- macOS 14+; Swift 6. No external dependencies.
- Do not add
swift-argument-parser— the library must stay dependency-free. The CLI lives in../SwiftStan. - Do not re-expose
caseRootOverrideaspublic. It is internal on purpose. - Keep access levels:
Commands/entry points and DSL types public;Methods/,Helpers/, support plumbing internal. - When syncing from upstream
../SwiftStan/Sources/SwiftStan/:rsync -a --delete ../SwiftStan/Sources/SwiftStan/ Sources/SwiftStan/- Re-delete
Sources/SwiftStan/Commands/Dsl2Stan.swift - Re-apply the access-level demotions (see CHANGELOG.md for the full list)
- Re-apply the
caseRootOverridedemotion inSupport/CasePaths.swift - Re-apply the
dsl2stanfallback removal inUlam/Ulam.swift swift buildto verify
Tests/SwiftStanLibraryTests/:
Unit/— 183 portable pure-Swift tests. No cmdstan. Green on any machine.Integration/— cmdstan shell-out tests. Skipped when$CMDSTANis unset.Resources/— bundled test fixtures (CSV, alist.R, ulam.swift); loaded viaBundle.module.TestCaseRootBootstrap.swift— redirectscasePaths(for:)to a_Testsibling dir.TestFixtureStaging.swift— copies bundled fixtures into the_Testcase dirs.
Every @Suite struct's init() must start with _ = TestCaseRootBootstrap.install.