diff --git a/.gitignore b/.gitignore index d73230c..af82f2d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1 @@ -.cuberc -.cubestartup -.cubeboot +.craftos diff --git a/CLAUDE.md b/CLAUDE.md index 0a6df78..c3018ce 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -11,6 +11,7 @@ Use `docs/README.md` as the entrypoint for CC:Tweaked, CraftOS-PC, Advanced Peri ## Constraints - Do not add a standalone Lua test harness unless asked. Local execution happens through the CraftOS-PC harness (see `docs/install-craftos-pc.md`, `docs/craftos_pc_glossary.md`, and ADR-0005); code otherwise executes in-game. +- Do not run `just repl` as an LLM agent; it is a human-only interactive CraftOS-PC wrapper. Use `just craftos --headless ...` for automated probes. - After editing Lua, run `just check` and fix all `luacheck` warnings. - Use 2-space indent, semicolons, and `local function`. - `require` paths are absolute ComputerCraft paths, for example `require('/apis/net')()`. diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 674e042..84822ea 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -2,6 +2,7 @@ Requirements: - `just` +- `jq` - `luacheck` - [CraftOS-PC](docs/install-craftos-pc.md) ≥ v2.8.3 — local harness for the CC:Tweaked sandbox; see [`docs/craftos_pc_glossary.md`](docs/craftos_pc_glossary.md) for CLI flags, mounting, `periphemu`, save data, and troubleshooting references. @@ -13,4 +14,4 @@ just install This installs the local Git hooks, including a pre-commit hook that runs `just ci`. -`just ci` is the local verification entry point. Today it verifies that `craftos --version` reports v2.8.3 or newer, runs `just check` for `luacheck`, and runs `just test` for CraftOS-PC headless smoke tests. Use the CraftOS-PC glossary when adjusting `--headless`, `--exec`, `--script`, `--rom`, or `--mount-*` usage. +`just ci` is the local verification entry point. Today it verifies that `craftos --version` reports v2.8.3 or newer, runs `just check` for `luacheck`, and runs `just test` for CraftOS-PC headless smoke tests. Use `just craftos` to launch CraftOS-PC with repo-local save data under `.craftos` and read-only mounts for `/trapos`, `/apis`, `/programs`, `/servers`, and `/startup`. `just repl` opens the same environment with `--cli` for human interactive use only; LLM agents must not run it. Use the CraftOS-PC glossary when adjusting `--headless`, `--exec`, `--script`, `--rom`, or `--mount-*` usage. diff --git a/Justfile b/Justfile index 0d06649..d6f7ac8 100644 --- a/Justfile +++ b/Justfile @@ -6,7 +6,7 @@ default: @just --list # Install local development tooling. -install: install-git-hooks check-craftos +install: install-git-hooks check-install # Install Git hooks for this repository. install-git-hooks: @@ -51,6 +51,45 @@ check-craftos: exit 1; \ fi +# Verify jq is installed. +check-jq: + @command -v jq >/dev/null 2>&1 || { \ + printf '%s\n' 'jq not found on $PATH. See DEVELOPMENT.md.' >&2; \ + exit 1; \ + } + +# Verify luacheck is installed. +check-luacheck: + @command -v luacheck >/dev/null 2>&1 || { \ + printf '%s\n' 'luacheck not found on $PATH. See DEVELOPMENT.md.' >&2; \ + exit 1; \ + } + +# Verify tools needed for local installation and CraftOS-PC launch recipes. +check-install: check-craftos check-jq check-luacheck + +# Pass args through to `craftos`, for example: +# just craftos --headless --exec 'print("__READY__"); os.shutdown()' +# Launch CraftOS-PC with repo-local data and read-only repo mounts. +[positional-arguments] +craftos *args: check-install + #!/usr/bin/env bash + set -euo pipefail + repo='{{justfile_directory()}}' + argv=(--directory "$repo/.craftos") + if [ "$(uname -s)" = "Darwin" ]; then + argv+=(--rom /Applications/CraftOS-PC.app/Contents/Resources) + fi + argv+=(--mount-ro "/trapos=$repo") + while IFS= read -r dir; do + argv+=(--mount-ro "/$dir=$repo/$dir") + done < <(jq -r '.files[] | split("/")[0]' "$repo/manifest.json" | sort -u) + exec craftos "${argv[@]}" "$@" + +# Human-only interactive REPL. LLM agents must not execute this command. +repl: + @just craftos --cli + # Local CI entry point used by Git hooks. Pass args through to `test`. ci *args: check-craftos check @just test {{args}} @@ -75,5 +114,5 @@ test *args: printf '%s\n' 'OK: smoke tests passed' # Lint all Lua source with luacheck. -check: +check: check-luacheck luacheck . diff --git a/docs/adrs/adr-0005-craftos-pc-harness.md b/docs/adrs/adr-0005-craftos-pc-harness.md index 77a06e8..e6a953b 100644 --- a/docs/adrs/adr-0005-craftos-pc-harness.md +++ b/docs/adrs/adr-0005-craftos-pc-harness.md @@ -26,7 +26,8 @@ Treat CraftOS-PC as a first-class local development dependency. - **Minimum version `v2.8.3`** — recent enough to have the current CC:Tweaked ROM, old enough that contributors already on a 2.8.x build will not be forced to upgrade again immediately. - **Documented install** in [`docs/install-craftos-pc.md`](../install-craftos-pc.md), with a SHA-256-verified macOS flow and pointers to the official Windows/Linux artifacts. - **Documented upstream navigation** in [`docs/craftos_pc_glossary.md`](../craftos_pc_glossary.md), covering CLI flags, mounts, `periphemu`, save data, and troubleshooting pages. -- **Verified by `just install`** via a `check-craftos` recipe that runs `craftos --version` and requires v2.8.3 or newer. Failure prints a one-line pointer to the install guide instead of a long stack trace. +- **Verified by `just install`** via `check-install`, which checks `craftos`, `jq`, and `luacheck`. `check-craftos` runs `craftos --version` and requires v2.8.3 or newer. Failure prints a one-line pointer to the install guide instead of a long stack trace. +- **Repository-local launch recipe.** `just craftos` runs CraftOS-PC with `--directory .craftos`, keeps the macOS `--rom /Applications/CraftOS-PC.app/Contents/Resources` workaround, mounts the repository root read-only at `/trapos`, and mounts each manifest top-level directory read-only at its ComputerCraft root path. - **`just ci` is the local verification entry point.** Today it runs `check-craftos`, `check`, and `test`. The installed pre-commit hook invokes `just ci` directly, and `just test` owns CraftOS-PC-driven smoke tests. The existing `CLAUDE.md` constraint ("Do not run Lua locally or add a test harness unless asked") is reframed rather than removed: there is still no standalone Lua harness, and we are not adding a Busted-style test runner. The harness *is* CraftOS-PC, invoked deliberately. @@ -37,11 +38,13 @@ The existing `CLAUDE.md` constraint ("Do not run Lua locally or add a test harne - Contributors should use the local CraftOS-PC glossary first when researching emulator behavior, then follow the linked upstream pages for details. - Headless smoke tests live under `tests/` and are driven by `just test`. Today there are two: `tests/boot.lua` (prints a marker and shuts down — proves the BIOS started) and `tests/ready.lua` (round-trips a `craftos-ready` event through `os.queueEvent` / `os.pullEventRaw` — proves the CC event queue works). Each is invoked as `craftos --headless --script ` and its stdout is grepped for `__READY__`. Adding a third test means dropping a Lua file in `tests/` and adding it to the loop in the `test:` recipe. - The macOS install symlinks the binary into `/usr/local/bin`, which makes CraftOS-PC unable to auto-discover the ROM that ships inside the `.app` bundle (`Could not mount ROM`). The `test:` recipe works around this by passing `--rom /Applications/CraftOS-PC.app/Contents/Resources` on Darwin. Linux (AppImage) and Windows (installer) auto-discover correctly, so no flag is passed there. +- `just craftos` uses repository-local save data under `.craftos/config/` and `.craftos/computer/`. This keeps emulator state out of `~/Library/Application Support/CraftOS-PC` during repository work and keeps repo files visible through read-only mounts instead of copying them into the VM save. +- `just repl` is a human-only interactive wrapper around `just craftos --cli`; automation and LLM agents must use headless `just craftos ...` invocations instead. - The harness version becomes a project-level concern. When CC:Tweaked ships breaking changes that require a newer CraftOS-PC build, we bump the minimum version in `docs/install-craftos-pc.md` and `check-craftos` keeps contributors honest. - No CI integration yet. Running CraftOS-PC headless in GitHub Actions is feasible (the AppImage works on Ubuntu runners) but is out of scope here; the contract is local-only for now. ## Future Work -- **API-loading smoke test.** Extend the `tests/` set with a script that mounts the repo into the VM (`--mount-ro /cc-libs=.`) and `require`s `/apis/eventloop`, `/apis/net`, and the router, asserting the wiring loads without errors. Today's smokes only prove CraftOS-PC itself works, not that our code loads inside it. +- **API-loading smoke test.** Extend the `tests/` set with a script that runs through `just craftos` and `require`s `/apis/eventloop`, `/apis/net`, and the router, asserting the wiring loads without errors. Today's smokes only prove CraftOS-PC itself works, not that our code loads inside it. - **CI.** Run `just test` on push using the Linux AppImage. - **Pinned ROM.** CraftOS-PC ships its own copy of the CC:Tweaked ROM per release. If we ever need to test against a specific in-game version, point CraftOS-PC at a vendored ROM via `--rom` (the same flag we already pass on macOS for a different reason). diff --git a/docs/install-craftos-pc.md b/docs/install-craftos-pc.md index e77e1e3..25c44ba 100644 --- a/docs/install-craftos-pc.md +++ b/docs/install-craftos-pc.md @@ -4,7 +4,7 @@ CraftOS-PC is the local harness used to run this repo's Lua outside of Minecraft CraftOS-PC is the emulator; `craftos` is the command-line executable it installs. For the broader upstream documentation index, see [`craftos_pc_glossary.md`](craftos_pc_glossary.md). -Minimum version: **v2.8.3**. `just install` runs `craftos --version` to verify it is on `$PATH` and recent enough. +Minimum version: **v2.8.3**. `just install` runs `craftos --version` to verify it is on `$PATH` and recent enough; it also checks that `jq` and `luacheck` are installed. The upstream installation page is . The notes below pin the version we test against and add a SHA-256 verification step. @@ -84,6 +84,20 @@ On macOS, use the `--rom` form shown above if the command fails with `Could not `just test` runs the headless smoke tests in `tests/` through CraftOS-PC. On macOS the recipe passes `--rom /Applications/CraftOS-PC.app/Contents/Resources` because the `/usr/local/bin/craftos` symlink loses ROM auto-discovery; on Linux and Windows no flag is needed. `just ci` runs the same tests after `luacheck`. +## Repository-local launches + +`just craftos` launches CraftOS-PC with persistent save data rooted at `.craftos` instead of the platform default user-data directory. Generated files live under `.craftos/config/` and `.craftos/computer/`, while the root `.gitignore` keeps that state untracked. + +The recipe mounts the repository root read-only at `/trapos` so code can read `/trapos/manifest.json`. It also uses `jq` to read `manifest.json` and mount each shipped top-level directory read-only at its ComputerCraft root path, such as `/apis`, `/programs`, `/servers`, and `/startup`. + +Pass CraftOS-PC flags directly after the recipe name, for example: + +```sh +just craftos --headless --exec 'print("__READY__"); os.shutdown()' +``` + +`just repl` delegates to `just craftos --cli` for human interactive use only. LLM agents must not run `just repl`. + See [Command-Line Flags](https://www.craftos-pc.cc/docs/cli) for `--headless`, `--exec`, `--script`, `--rom`, and `--mount-*`. See [Error Messages](https://www.craftos-pc.cc/docs/error-messages) for `Could not mount ROM` and other boot-time failures. ## Updating