Thanks for your interest in working on SimDeck. This guide covers how to build and run the project from a source checkout, package the VS Code extension locally, preview the documentation site, and cut releases.
For a high-level tour of the codebase — including the boundary between the Rust server, the Objective-C native bridge, and the browser client — read AGENTS.md.
- macOS
- Xcode or Command Line Tools
- Node.js 18+
- Rust toolchain (
cargo)
The npm package ships a prebuilt native binary, so Rust is only required for contributors building from source.
The default build covers the native CLI and the browser client:
npm run build # alias for build:app (CLI + client)To also build the inspector packages and the simdeck-test helper, run:
npm run build:all # build:app + build:packagesGranular targets:
npm run build:cli # Rust server -> build/simdeck-bin
npm run build:client # browser bundle -> client/dist
npm run build:inspectors # nativescript + react-native inspectors
npm run build:simdeck-test # simdeck/test subpath export
npm run build:vscode-extension # alias for package:vscode-extensionscripts/build-cli.sh builds the Rust server in server/ and copies the
resulting binary to build/simdeck-bin. The default is a host-arch build for
fast iteration. Set SIMDECK_BUILD_TARGET=<rust-target-triple> to pin the
output to an explicit Rust target — the release workflow uses
SIMDECK_BUILD_TARGET=aarch64-apple-darwin for deterministic arm64 builds.
SimDeck is arm64-only by design: cli/*.m contains AArch64 inline asm
that does not compile on x86_64, and the npm package is gated by
"cpu": ["arm64"] so installs on Intel Macs fail fast.
After a successful build, run the CLI directly:
./build/simdeck list
./build/simdeck daemon start --port 4310Or install the local checkout globally so the simdeck command is on your
PATH:
npm install -g .npm run lint # prettier + clippy + client typecheck
npm run format # prettier + cargo fmt
npm run test # cargo test + client unit tests
npm run test:integration:cli
npm run test:integration:js-apiThe full CI matrix runs as npm run ci.
Package the local VS Code extension from this checkout:
npm run package:vscode-extensionThe shorter aliases npm run package:vscode and npm run package:vsix do the
same thing. This writes build/vscode/simdeck-vscode.vsix.
Install that local package into VS Code:
npm run install:vscode-extension # or: npm run install:vscodeThe install script packages the extension first if the .vsix does not exist,
then runs the VS Code CLI with --install-extension build/vscode/simdeck-vscode.vsix --force.
If the code command is not available, install it from VS Code with
Shell Command: Install 'code' command in PATH.
Then run SimDeck: Open Simulator View from the Command Palette.
For local sanity-checking what the release workflow will produce:
npm run package:npm # npm pack -> simdeck-<version>.tgz
npm run package:all # build:all + VS Code .vsix + npm packUse npm publish --dry-run from a package directory to inspect what would be
published without actually publishing.
The public docs at simdeck.nativescript.org
are built from docs/ with VitePress and deployed by
.github/workflows/docs.yml. Preview locally:
npm run docs:dev
npm run docs:build
npm run docs:previewInstall the agent skill from a source checkout with skills.sh:
npx skills add NativeScript/SimDeck --skill simdeck -a codex -gThe npm postinstall message also prints this command after a global install.
This repo includes a Codex local environment at
.codex/local-environment.toml. Use it when creating Codex worktrees for
SimDeck. The setup script runs:
npm run codex:setupThat hydrates the root node_modules, client/node_modules, and
server/target from ~/.cache/simdeck/codex-worktree-cache or a matching
existing SimDeck checkout. If either node_modules directory is still missing,
it falls back to npm ci for that package so lockfiles stay unchanged. On
macOS it also ensures the Homebrew pkgconf and x264 packages are available
for the native Rust build. Set
SIMDECK_CODEX_SKIP_BREW=1 if you want setup to report missing Homebrew
packages instead of installing them.
The cleanup script saves fresh caches with:
npm run codex:cache:saveThe environment also exposes a Build and Restart Daemon Run action:
npm run codex:runIt builds the Rust CLI and React client, saves the refreshed caches, and runs
./build/simdeck daemon restart for the current workspace.
Releases are published from the Release GitHub Actions workflow at
.github/workflows/release.yml. Trigger it
manually from the Actions tab and pick the package, bump type, and dist-tag.
The workflow:
- Bumps the chosen package's version, commits, and tags as
<slug>-v<version> - Builds a universal native binary for the root
simdeckpackage, codesigns with the team's Developer ID Application certificate, and notarizes with Apple's notary service - Publishes npm packages over OIDC trusted publishing (no NPM_TOKEN required)
- Publishes the VS Code extension via
vsceusing a stored PAT - Creates a GitHub Release with the signed binary attached
Each npm package must have a Trusted Publisher rule configured on
npmjs.com before the workflow can publish a new
version of it. The first publish of a brand-new package still needs a one-time
manual npm publish (with a token) so the package exists; after that the
trusted-publisher rule takes over.