Story Kit
This app runs as a single Rust web server binary that serves the Vite/React frontend and exposes APIs.
The frontend lives in the frontend/ directory.
You can also run the frontend and backend separately in development (Vite dev server + Rust API).
Running it in development
# Build the frontend
cd frontend
npm install
npm run dev
# In another terminal - run the server (serves embedded frontend/dist/)
cargo run
Production
# Build the release binary (also builds the frontend via build.rs)
cargo build --release
# Run the server (serves embedded frontend/dist/)
./target/release/storkit
Cross-Platform Distribution
Story Kit ships as a single self-contained binary with the React frontend embedded via
rust-embed. No Rust toolchain, Node.js, or extra libraries are required on the target machine.
macOS
# Native build – no extra tools required beyond Rust + npm
make build-macos
# Output: target/release/storkit
# Verify only system frameworks are linked (Security.framework, libSystem.B.dylib, etc.)
otool -L target/release/storkit
Linux (static x86_64, zero dynamic deps)
The Linux build uses the x86_64-unknown-linux-musl target to produce a fully static binary.
Prerequisites:
# Install cross – a Rust cross-compilation tool backed by Docker
cargo install cross
# Ensure Docker Desktop (or Docker Engine) is running
Build:
make build-linux
# Output: target/x86_64-unknown-linux-musl/release/storkit
# Verify the binary is statically linked
file target/x86_64-unknown-linux-musl/release/storkit
# Expected: ELF 64-bit LSB executable, x86-64, statically linked
ldd target/x86_64-unknown-linux-musl/release/storkit
# Expected: not a dynamic executable
Running on any Linux x86_64 machine:
# No Rust, Node, glibc, or any other library needed – just copy and run
./storkit
Running in Docker (with gVisor sandboxing)
The docker/docker-compose.yml runs the container under gVisor
(runtime: runsc). gVisor intercepts all container syscalls in userspace, providing an
extra layer of isolation so that even a compromised workload cannot make raw syscalls to
the host kernel.
Host setup (Linux only)
gVisor is a Linux technology. On macOS (OrbStack, Docker Desktop) you must remove
runtime: runsc from docker/docker-compose.yml — gVisor is not available there.
1. Install gVisor (Debian/Ubuntu):
curl -fsSL https://gvisor.dev/archive.key | sudo gpg --dearmor -o /usr/share/keyrings/gvisor-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/gvisor-archive-keyring.gpg] \
https://storage.googleapis.com/gvisor/releases release main" \
| sudo tee /etc/apt/sources.list.d/gvisor.list
sudo apt-get update && sudo apt-get install -y runsc
2. Register runsc with Docker (/etc/docker/daemon.json):
{
"runtimes": {
"runsc": { "path": "/usr/bin/runsc" }
}
}
3. Restart Docker and verify:
sudo systemctl restart docker
docker run --runtime=runsc hello-world
4. Launch storkit:
GIT_USER_NAME="Your Name" GIT_USER_EMAIL="you@example.com" \
PROJECT_PATH=/path/to/your/repo \
docker compose -f docker/docker-compose.yml up
gVisor compatibility notes
The following storkit subsystems have been verified to work under runsc:
- PTY-based agent spawning (
portable_pty/openpty) – gVisor implements the full POSIX PTY interface (/dev/ptmx,TIOCGWINSZ, etc.). rebuild_and_restart– usesexecve()to replace the server process, which gVisor fully supports.- Rust compilation –
cargo buildinside the container invokes standard fork/exec primitives, all of which gVisor implements.
Releasing
Builds both macOS and Linux binaries locally, tags the repo, and publishes a Gitea release with a changelog.
One-time setup:
- Create a Gitea API token at
https://code.crashlabs.io/user/settings/applications(needs repository read/write) - Add it to
.env(gitignored):GITEA_TOKEN=your_token - Ensure
crossis installed (cargo install cross) and Docker is running
To release:
make release V=0.2.0
This will:
- Build macOS arm64 (native) and Linux amd64 (static musl via cross/Docker)
- Generate a changelog from commits since the last tag
- Tag the repo as
v0.2.0and push the tag - Create a Gitea release with both binaries and the changelog attached
Testing
Frontend Tests
The frontend uses Vitest for unit tests and Playwright for end-to-end tests.
cd frontend
# Run unit tests
npm test
# Run end-to-end tests
npm run test:e2e
Backend Tests
This project uses nextest for running tests and cargo-llvm-cov for code coverage.
Install Tools
cargo install cargo-nextest cargo-llvm-cov
Run Tests
# Run all tests
cargo nextest run
# Run specific module
cargo nextest run search_files
# Run with verbose output
cargo nextest run --no-capture
Generate Coverage
# HTML report (opens in browser)
cargo llvm-cov nextest --html --open
# Terminal output
cargo llvm-cov nextest
# LCOV format (for CI)
cargo llvm-cov nextest --lcov --output-path lcov.info
# Clean coverage data
cargo llvm-cov clean
Configuration
- Nextest config:
.config/nextest.toml - Coverage output:
target/llvm-cov/html/index.html
Current Coverage (search_files module)
Module: commands/search.rs
├── Region Coverage: 75.36%
├── Function Coverage: 69.05%
└── Line Coverage: 72.55%
Available Test Profiles
# Development (default)
cargo nextest run
# CI with retries
cargo nextest run --profile ci
# Coverage optimized
cargo nextest run --profile coverage