From 3d18b009ee531b902fbe576ee4f763e149588ae2 Mon Sep 17 00:00:00 2001 From: ab-10 Date: Fri, 14 Nov 2025 19:18:03 -0800 Subject: [PATCH] Add install instructions for spx --- docs/spx/index.mdx | 170 +++++++++++++++++++++++++++++++++++++++++++ docusaurus.config.ts | 9 +++ package-lock.json | 28 ------- 3 files changed, 179 insertions(+), 28 deletions(-) create mode 100644 docs/spx/index.mdx diff --git a/docs/spx/index.mdx b/docs/spx/index.mdx new file mode 100644 index 0000000..dac8386 --- /dev/null +++ b/docs/spx/index.mdx @@ -0,0 +1,170 @@ +--- +title: spx +--- + +spx enables you to define, run, and modify complex backend systems using only markdown specifications. + +:::warning Early Preview +spx is still rough around the edges. +We'd love your feedback on how the spx development workflow compares to yours. + +Hit us up on [Discord](https://discord.gg/n3SsVDAW6U) or email me on armin (at) recurse (dot) ml. +::: + +## Prerequisites + +Before using spx, ensure you have: + +- Claude Code CLI installed and available as `claude`. +- Runtime for your chosen implementation language (Python, TypeScript, or Rust). + spx uses these languages as intermediary representations (IRs) to generate your actual implementation code. + +## Quickstart + +### 1. Download the spx Binary + +Download the appropriate binary for your system architecture: + +- **Linux x64:** [linux-x64](https://storage.googleapis.com/docs-recurse-ml/spx/spx-darwin-x64/spx) +- **Linux ARM64:** [linux-arm64](https://storage.googleapis.com/docs-recurse-ml/spx/spx-linux-arm64/spx) +- **Linux x64 (musl):** [linux-x64-musl](https://storage.googleapis.com/docs-recurse-ml/spx/spx-linux-x64-musl/spx) +- **Linux ARM64 (musl):** [linux-arm64-musl](https://storage.googleapis.com/docs-recurse-ml/spx/spx-linux-arm64-musl/spx) +- **macOS Intel (x64):** [darwin-x64](https://storage.googleapis.com/docs-recurse-ml/spx/spx-darwin-x64/spx) +- **macOS Apple Silicon (ARM64):** [darwin-arm64](https://storage.googleapis.com/docs-recurse-ml/spx/spx-darwin-arm64/spx) +- **Windows x64:** [windows-x64](https://storage.googleapis.com/docs-recurse-ml/spx/spx-windows-x64/spx.exe) + +**Troubleshooting:** +1. If using MacOS Rosetta, download the binary for `darwin-arm64`. + + +**Adding to your PATH:** + +After downloading, make the binary executable and add it to your PATH: +```bash +# Linux/macOS +chmod +x spx +sudo mv spx /usr/local/bin/ + +# Or add to your user bin directory (no sudo required) +mkdir -p ~/.local/bin +mv spx ~/.local/bin/ +# Add to your shell config: export PATH="$HOME/.local/bin:$PATH" +``` + +```powershell +# Windows (PowerShell as Administrator) +# Move spx.exe to a directory like C:\Program Files\spx\ +# Add that directory to your PATH environment variable +``` + +Verify installation: +```bash +spx --version +``` + +### 2. Create a New Project + +Navigate to where you want your project and create a new directory: +```bash +mkdir my-spx-project +cd my-spx-project +spx init +``` + +This initializes a new spx project with the following structure: +``` +my-spx-project/ +├── specs/ # Your markdown specifications go here +│ └── example.md # Starter example spec +├── .spx/ # Internal spx metadata (don't edit) +│ └── prev_specs/ # Tracks changes between generations +├── out/ # Generated code appears here (auto-created on first gen) +└── .gitignore # Pre-configured to ignore generated files +``` + +**What each directory does:** + +- **`specs/`** - Where you write your system specifications in markdown. All `.md` files here are read by spx. +- **`.spx/`** - Internal tracking data used by spx to detect changes and optimize generation. +- **`out/`** - Contains generated implementation code. You can read this to understand what was generated, but don't edit it directly - changes will be overwritten. + +### 3. Build! + +#### Define Specs + +Create or edit markdown files in `specs/`. +spx reads all `.md` files in the `specs/` directory and treats them as the specification for your system. + +Principles for writing effective specs: + +1. **Be specific about end-user behavior:** clearly define the interfaces (whether CLI or API endpoints) that are exposed to your users. +2. **Managing granularity:** + you're in control of the level of granularity at which you want to work at. + For example, if the database engine and schema is important to your design, you should specify them. + But if they're not, then LLM will likely make a reasonable guess. +3. **Out of scope:** explicitly state what's out of scope for now and the limitations you're fine with at the current stage. + + +#### `spx gen` + +Once your spec is ready, generate the code: +```bash +spx gen +``` + +This command: +- Reads all markdown files from `specs/` +- Compares them with the previous generation (if any) +- Uses Claude Code CLI to generate or update code in `out/` +- Creates/updates `out/build.sh` and `out/run.sh` scripts + +**First time:** Generates everything from scratch. + +**Subsequent runs:** Only updates what changed in your specs, preserving what still matches. + +#### `spx build + +- Sets up language-specific environments (virtualenv for Python, npm install for TypeScript, etc.) +- Installs required libraries +- Compiles code if necessary (e.g., for Rust or TypeScript) + +#### `spx run` + +Executes your generated system. +Any arguments you pass to `spx run` are forwarded to your application's entry point. + +#### Iterate + +As you develop, update your specs in `specs/` and repeat the cycle. +spx tracks what changed and only updates relevant parts of your implementation. + +## How It Works + +spx is a programming language that uses traditional languages (Python, TypeScript, Rust) as intermediary representations. +You control your system architecture and behavior through specs, not by writing implementation code directly. + +## Commands Reference + +- `spx init` - Initialize a new spx project +- `spx gen` - Generate/update implementation code from specs +- `spx build` - Build the generated code and install dependencies +- `spx run [args]` - Execute your system (forwards args to your application) +- `spx clean` - Remove all generated code and build artifacts + +## Best Use Cases + +spx works best for: + +- **Web backends and APIs** - REST/GraphQL servers, microservices +- **CLI tools and scripts** - Command-line utilities, automation scripts +- **ML pipelines** - Training scripts, data processing, inference servers + +spx is designed for non-visual backend systems. For applications with significant UI components, traditional development approaches may be more suitable. + +## Getting Help + +- **Discord:** [Join our community](https://discord.gg/n3SsVDAW6U) +- **Email:** armin (at) recurse (dot) ml +- **Issues:** Share bugs, unexpected behavior, or cases where spec-level fixes weren't sufficient + +Your feedback directly shapes spx development! diff --git a/docusaurus.config.ts b/docusaurus.config.ts index f33f3b0..0c57e81 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -57,6 +57,15 @@ const config: Config = { sidebarPath: './sidebars.ts', lastVersion: 'current', }], + [ + '@docusaurus/plugin-content-docs', + { + id: 'spx', + path: 'docs/spx', + routeBasePath: 'spx', + sidebarPath: false, + lastVersion: 'current', + }], ], presets: [ diff --git a/package-lock.json b/package-lock.json index 33d5057..a607848 100644 --- a/package-lock.json +++ b/package-lock.json @@ -163,7 +163,6 @@ "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.30.0.tgz", "integrity": "sha512-puc1/LREfSqzgmrOFMY5L/aWmhYOlJ0TTpa245C0ZNMKEkdOkcimFbXTXQ8lZhzh+rlyFgR7cQGNtXJ5H0XgZg==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.30.0", "@algolia/requester-browser-xhr": "5.30.0", @@ -302,7 +301,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.7.tgz", "integrity": "sha512-BU2f9tlKQ5CAthiMIgpzAh4eDTLWo1mqi9jqE2OxMG0E/OM199VJt2q8BztTxpnSW0i1ymdwLXRJnYzvDM5r2w==", "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", @@ -2066,7 +2064,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -2089,7 +2086,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" } @@ -2170,7 +2166,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -2534,7 +2529,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -3214,7 +3208,6 @@ "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.8.1.tgz", "integrity": "sha512-ENB01IyQSqI2FLtOzqSI3qxG2B/jP4gQPahl2C3XReiLebcVh5B5cB9KYFvdoOqOWPyr5gXK4sjgTKv7peXCrA==", "license": "MIT", - "peer": true, "dependencies": { "@docusaurus/babel": "3.8.1", "@docusaurus/bundler": "3.8.1", @@ -3396,7 +3389,6 @@ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.8.1.tgz", "integrity": "sha512-oByRkSZzeGNQByCMaX+kif5Nl2vmtj2IHQI2fWjCfCootsdKZDPFLonhIp5s3IGJO7PLUfe0POyw0Xh/RrGXJA==", "license": "MIT", - "peer": true, "dependencies": { "@docusaurus/core": "3.8.1", "@docusaurus/logger": "3.8.1", @@ -3975,7 +3967,6 @@ "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.0.tgz", "integrity": "sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==", "license": "MIT", - "peer": true, "dependencies": { "@types/mdx": "^2.0.0" }, @@ -4575,7 +4566,6 @@ "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", @@ -4959,7 +4949,6 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -5292,7 +5281,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -5348,7 +5336,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -5394,7 +5381,6 @@ "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.30.0.tgz", "integrity": "sha512-ILSdPX4je0n5WUKD34TMe57/eqiXUzCIjAsdtLQYhomqOjTtFUg1s6dE7kUegc4Mc43Xr7IXYlMutU9HPiYfdw==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-abtesting": "5.30.0", "@algolia/client-analytics": "5.30.0", @@ -5848,7 +5834,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001726", "electron-to-chromium": "^1.5.173", @@ -6801,7 +6786,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -8176,7 +8160,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -12622,7 +12605,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -13152,7 +13134,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -14056,7 +14037,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -14848,7 +14828,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -14858,7 +14837,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.26.0" }, @@ -14914,7 +14892,6 @@ "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", "license": "MIT", - "peer": true, "dependencies": { "@types/react": "*" }, @@ -14943,7 +14920,6 @@ "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.12.13", "history": "^4.9.0", @@ -15634,7 +15610,6 @@ "resolved": "https://registry.npmjs.org/sass/-/sass-1.89.2.tgz", "integrity": "sha512-xCmtksBKd/jdJ9Bt9p7nPKiuqrlBMBuuGkQlkhZjjQk3Ty48lv93k5Dq6OPkKt4XwxDJ7tvlfrTa1MPA9bf+QA==", "license": "MIT", - "peer": true, "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.0.2", @@ -16820,7 +16795,6 @@ "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "devOptional": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -17162,7 +17136,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -17361,7 +17334,6 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.9.tgz", "integrity": "sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==", "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.6",