diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 000000000..ce5d2734a --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,5 @@ +{ + "attribution": { + "commit": "" + } +} diff --git a/CLAUDE.md b/CLAUDE.md index 9e654b2ee..d2bdb8a73 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -14,55 +14,19 @@ StartOS is an open-source Linux distribution for running personal servers. It ma - API: JSON-RPC via rpc-toolkit (see `agents/rpc-toolkit.md`) - Auth: Password + session cookie, public/private key signatures, local authcookie (see `core/src/middleware/auth/`) -## Build Commands +## Build & Development +See [CONTRIBUTING.md](CONTRIBUTING.md) for: +- Environment setup and requirements +- Build commands and make targets +- Testing and formatting commands +- Environment variables + +**Quick reference:** ```bash -# Set platform (x86_64, aarch64, riscv64, raspberrypi, x86_64-nonfree, aarch64-nonfree) -# Can export or set inline. Most recent platform is remembered if not specified. -export PLATFORM=x86_64 -# or: PLATFORM=x86_64 make iso - -# Development mode - sets dev environment, prevents rebuilds on git hash changes -. ./devmode.sh - -# Full ISO build -make iso - -# Faster development iterations (same network) -make update-startbox REMOTE=start9@ # Binary + UI only (fastest, no container runtime) -make update-deb REMOTE=start9@ # Full Debian package -make update REMOTE=start9@ # OTA-style update - -# Remote device updates (different network, uses magic-wormhole) -make wormhole # Send startbox binary -make wormhole-deb # Send Debian package -make wormhole-squashfs # Send squashfs image - -# Build specific components -make all # All Rust binaries -make uis # All web UIs -make ui # Main UI only -make deb # Debian package -``` - -## Testing - -```bash -make test # All tests -make test-core # Rust tests (via ./core/run-tests.sh) -make test-sdk # SDK tests -make test-container-runtime # Container runtime tests - -# Run specific Rust test -cd core && cargo test --features=test -``` - -## Code Formatting - -```bash -make format # Rust (requires nightly) -cd web && npm run check # TypeScript type checking -cd web && npm run format # TypeScript/HTML/SCSS formatting (prettier) +. ./devmode.sh # Enable dev mode +make update-startbox REMOTE=start9@ # Fastest iteration (binary + UI) +make test-core # Run Rust tests ``` ## Architecture @@ -129,7 +93,7 @@ The container runtime communicates with the host via JSON-RPC over Unix socket. | `rpc/service.sock` | RPC socket (container runtime listens here) | | `rpc/host.sock` | Host RPC socket (for effects callbacks to host) | -**S9PK Structure:** See `agents/s9pk-structure.md` (TODO: create this doc) +**S9PK Structure:** See `agents/s9pk-structure.md` ### SDK (`/sdk`) TypeScript SDK for packaging services (`@start9labs/start-sdk`). @@ -156,35 +120,11 @@ Git submodule providing diff-based state synchronization. Changes to `db/model/p - `.mutate(|v| ...)` - Deserialize, mutate, reserialize - For maps: `.keys()`, `.as_idx(&key)`, `.as_idx_mut(&key)`, `.insert()`, `.remove()`, `.contains_key()` -## Environment Variables - -- `PLATFORM` - Target platform -- `ENVIRONMENT` - Feature flags (comma-separated): - - `dev` - Enables password SSH before setup, other developer conveniences - - `unstable` - Adds debugging with performance penalty, enables throwing in non-prod scenarios - - `console` - Enables tokio-console for async debugging -- `PROFILE` - Build profile (`release`, `dev`) -- `GIT_BRANCH_AS_HASH` - Use git branch as version hash - -## TypeScript Bindings - -Rust types export to TypeScript via ts-rs: -```bash -make ts-bindings # Generates core/bindings/, copies to sdk/base/lib/osBindings/ -``` - -## Multi-Platform Support - -Platforms: `x86_64`, `x86_64-nonfree`, `aarch64`, `aarch64-nonfree`, `riscv64`, `raspberrypi` - -The `-nonfree` variants include non-free firmware and drivers. Some platforms like `raspberrypi` also include non-free components by necessity. - -The build system uses cross-compilation with zig for musl targets. Platform-specific code checks `PLATFORM` constant. - ## Supplementary Documentation -The `agents/` directory contains detailed documentation and task tracking for AI assistants: +The `agents/` directory contains detailed documentation for AI assistants: - `TODO.md` - Pending tasks for AI agents (check this first, remove items when completed) - `rpc-toolkit.md` - JSON-RPC patterns and handler configuration - `core-rust-patterns.md` - Common utilities and patterns for Rust code in `/core` (guard pattern, mount guards, etc.) +- `s9pk-structure.md` - S9PK package format structure diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b81e9ce82..64fccd5ad 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,123 +11,188 @@ This guide is for contributing to the StartOS. If you are interested in packagin ```bash / -├── assets/ -├── container-runtime/ -├── core/ -├── build/ -├── debian/ -├── web/ -├── image-recipe/ -├── patch-db -└── sdk/ +├── assets/ # Screenshots for README +├── build/ # Auxiliary files and scripts for deployed images +├── container-runtime/ # Node.js program managing package containers +├── core/ # Rust backend: API, daemon (startd), CLI (start-cli) +├── debian/ # Debian package maintainer scripts +├── image-recipe/ # Scripts for building StartOS images +├── patch-db/ # (submodule) Diff-based data store for frontend sync +├── sdk/ # TypeScript SDK for building StartOS packages +└── web/ # Web UIs (Angular) ``` -#### assets - -screenshots for the StartOS README - -#### container-runtime - -A NodeJS program that dynamically loads maintainer scripts and communicates with the OS to manage packages - -#### core - -An API, daemon (startd), and CLI (start-cli) that together provide the core functionality of StartOS. - -#### build - -Auxiliary files and scripts to include in deployed StartOS images - -#### debian - -Maintainer scripts for the StartOS Debian package - -#### web - -Web UIs served under various conditions and used to interact with StartOS APIs. - -#### image-recipe - -Scripts for building StartOS images - -#### patch-db (submodule) - -A diff based data store used to synchronize data between the web interfaces and server. - -#### sdk - -A typescript sdk for building start-os packages +See component READMEs for details: +- [`core`](core/README.md) +- [`web`](web/README.md) +- [`build`](build/README.md) +- [`patch-db`](https://github.com/Start9Labs/patch-db) ## Environment Setup -#### Clone the StartOS repository - ```sh git clone https://github.com/Start9Labs/start-os.git --recurse-submodules cd start-os ``` -#### Continue to your project of interest for additional instructions: +### Development Mode -- [`core`](core/README.md) -- [`web-interfaces`](web-interfaces/README.md) -- [`build`](build/README.md) -- [`patch-db`](https://github.com/Start9Labs/patch-db) +For faster iteration during development: + +```sh +. ./devmode.sh +``` + +This sets `ENVIRONMENT=dev` and `GIT_BRANCH_AS_HASH=1` to prevent rebuilds on every commit. ## Building -This project uses [GNU Make](https://www.gnu.org/software/make/) to build its components. To build any specific component, simply run `make ` replacing `` with the name of the target you'd like to build +This project uses [GNU Make](https://www.gnu.org/software/make/) to build its components. ### Requirements - [GNU Make](https://www.gnu.org/software/make/) -- [Docker](https://docs.docker.com/get-docker/) +- [Docker](https://docs.docker.com/get-docker/) or [Podman](https://podman.io/) - [NodeJS v20.16.0](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) -- [sed](https://www.gnu.org/software/sed/) -- [grep](https://www.gnu.org/software/grep/) -- [awk](https://www.gnu.org/software/gawk/) +- [Rust](https://rustup.rs/) (nightly for formatting) +- [sed](https://www.gnu.org/software/sed/), [grep](https://www.gnu.org/software/grep/), [awk](https://www.gnu.org/software/gawk/) - [jq](https://jqlang.github.io/jq/) -- [gzip](https://www.gnu.org/software/gzip/) -- [brotli](https://github.com/google/brotli) +- [gzip](https://www.gnu.org/software/gzip/), [brotli](https://github.com/google/brotli) -### Environment variables +### Environment Variables -- `PLATFORM`: which platform you would like to build for. Must be one of `x86_64`, `x86_64-nonfree`, `aarch64`, `aarch64-nonfree`, `raspberrypi` - - NOTE: `nonfree` images are for including `nonfree` firmware packages in the built ISO -- `ENVIRONMENT`: a hyphen separated set of feature flags to enable - - `dev`: enables password ssh (INSECURE!) and does not compress frontends - - `unstable`: enables assertions that will cause errors on unexpected inconsistencies that are undesirable in production use either for performance or reliability reasons - - `docker`: use `docker` instead of `podman` -- `GIT_BRANCH_AS_HASH`: set to `1` to use the current git branch name as the git hash so that the project does not need to be rebuilt on each commit +| Variable | Description | +|----------|-------------| +| `PLATFORM` | Target platform: `x86_64`, `x86_64-nonfree`, `aarch64`, `aarch64-nonfree`, `riscv64`, `raspberrypi` | +| `ENVIRONMENT` | Hyphen-separated feature flags (see below) | +| `PROFILE` | Build profile: `release` (default) or `dev` | +| `GIT_BRANCH_AS_HASH` | Set to `1` to use git branch name as version hash (avoids rebuilds) | -### Useful Make Targets +**ENVIRONMENT flags:** +- `dev` - Enables password SSH before setup, skips frontend compression +- `unstable` - Enables assertions and debugging with performance penalty +- `console` - Enables tokio-console for async debugging + +**Platform notes:** +- `-nonfree` variants include proprietary firmware and drivers +- `raspberrypi` includes non-free components by necessity +- Platform is remembered between builds if not specified + +### Make Targets + +#### Building + +| Target | Description | +|--------|-------------| +| `iso` | Create full `.iso` image (Debian only, not for raspberrypi) | +| `img` | Create full `.img` image (Debian only, raspberrypi only) | +| `deb` | Build Debian package | +| `all` | Build all Rust binaries | +| `uis` | Build all web UIs | +| `ui` | Build main UI only | +| `ts-bindings` | Generate TypeScript bindings from Rust types | + +#### Deploying to Device + +For devices on the same network: + +| Target | Description | +|--------|-------------| +| `update-startbox REMOTE=start9@` | Deploy binary + UI only (fastest) | +| `update-deb REMOTE=start9@` | Deploy full Debian package | +| `update REMOTE=start9@` | OTA-style update | +| `reflash REMOTE=start9@` | Reflash as if using live ISO | +| `update-overlay REMOTE=start9@` | Deploy to in-memory overlay (reverts on reboot) | + +For devices on different networks (uses [magic-wormhole](https://github.com/magic-wormhole/magic-wormhole)): + +| Target | Description | +|--------|-------------| +| `wormhole` | Send startbox binary | +| `wormhole-deb` | Send Debian package | +| `wormhole-squashfs` | Send squashfs image | + +#### Other + +| Target | Description | +|--------|-------------| +| `format` | Run code formatting (Rust nightly required) | +| `test` | Run all automated tests | +| `test-core` | Run Rust tests | +| `test-sdk` | Run SDK tests | +| `test-container-runtime` | Run container runtime tests | +| `clean` | Delete all compiled artifacts | + +## Testing + +```bash +make test # All tests +make test-core # Rust tests (via ./core/run-tests.sh) +make test-sdk # SDK tests +make test-container-runtime # Container runtime tests + +# Run specific Rust test +cd core && cargo test --features=test +``` + +## Code Formatting + +```bash +# Rust (requires nightly) +make format + +# TypeScript/HTML/SCSS (web) +cd web && npm run format +``` + +## Code Style Guidelines + +### Formatting + +Run the formatters before committing. Configuration is handled by `rustfmt.toml` (Rust) and prettier configs (TypeScript). + +### Documentation & Comments + +**Rust:** +- Add doc comments (`///`) to public APIs, structs, and non-obvious functions +- Use `//` comments sparingly for complex logic that isn't self-evident +- Prefer self-documenting code (clear naming, small functions) over comments + +**TypeScript:** +- Document exported functions and complex types with JSDoc +- Keep comments focused on "why" rather than "what" + +**General:** +- Don't add comments that just restate the code +- Update or remove comments when code changes +- TODOs should include context: `// TODO(username): reason` + +### Commit Messages + +Use [Conventional Commits](https://www.conventionalcommits.org/): + +``` +(): + +[optional body] + +[optional footer] +``` + +**Types:** +- `feat` - New feature +- `fix` - Bug fix +- `docs` - Documentation only +- `style` - Formatting, no code change +- `refactor` - Code change that neither fixes a bug nor adds a feature +- `test` - Adding or updating tests +- `chore` - Build process, dependencies, etc. + +**Examples:** +``` +feat(web): add dark mode toggle +fix(core): resolve race condition in service startup +docs: update CONTRIBUTING.md with style guidelines +refactor(sdk): simplify package validation logic +``` -- `iso`: Create a full `.iso` image - - Only possible from Debian - - Not available for `PLATFORM=raspberrypi` - - Additional Requirements: - - [debspawn](https://github.com/lkhq/debspawn) -- `img`: Create a full `.img` image - - Only possible from Debian - - Only available for `PLATFORM=raspberrypi` - - Additional Requirements: - - [debspawn](https://github.com/lkhq/debspawn) -- `format`: Run automatic code formatting for the project - - Additional Requirements: - - [rust](https://rustup.rs/) -- `test`: Run automated tests for the project - - Additional Requirements: - - [rust](https://rustup.rs/) -- `update`: Deploy the current working project to a device over ssh as if through an over-the-air update - - Requires an argument `REMOTE` which is the ssh address of the device, i.e. `start9@192.168.122.2` -- `reflash`: Deploy the current working project to a device over ssh as if using a live `iso` image to reflash it - - Requires an argument `REMOTE` which is the ssh address of the device, i.e. `start9@192.168.122.2` -- `update-overlay`: Deploy the current working project to a device over ssh to the in-memory overlay without restarting it - - WARNING: changes will be reverted after the device is rebooted - - WARNING: changes to `init` will not take effect as the device is already initialized - - Requires an argument `REMOTE` which is the ssh address of the device, i.e. `start9@192.168.122.2` -- `wormhole`: Deploy the `startbox` to a device using [magic-wormhole](https://github.com/magic-wormhole/magic-wormhole) - - When the build it complete will emit a command to paste into the shell of the device to upgrade it - - Additional Requirements: - - [magic-wormhole](https://github.com/magic-wormhole/magic-wormhole) -- `clean`: Delete all compiled artifacts diff --git a/sdk/base/package.json b/sdk/base/package.json index 6d1997174..1eda223bf 100644 --- a/sdk/base/package.json +++ b/sdk/base/package.json @@ -34,7 +34,7 @@ "trailingComma": "all", "tabWidth": 2, "semi": false, - "singleQuote": false + "singleQuote": true }, "devDependencies": { "@types/jest": "^29.4.0", diff --git a/sdk/package/package.json b/sdk/package/package.json index ffeb9f7c2..d7c5a8b7e 100644 --- a/sdk/package/package.json +++ b/sdk/package/package.json @@ -46,7 +46,7 @@ "trailingComma": "all", "tabWidth": 2, "semi": false, - "singleQuote": false + "singleQuote": true }, "devDependencies": { "@types/jest": "^29.4.0",