From 7d0d69e5b5ac3c67610df9163b4e03e219c0c428 Mon Sep 17 00:00:00 2001 From: Guillaume ARM Date: Thu, 11 Jun 2026 19:35:23 +0200 Subject: [PATCH] chore(agents): adopt agents guidance --- CLAUDE.md => AGENTS.md | 2 +- .../adr-0005-craftos-pc-harness-and-probes.md | 6 +- docs/periphemu.md | 2 +- just/check.just | 96 +++++++++++++++++-- manifest.json | 2 +- packages/index.json | 4 +- packages/trapos-ai/ccpm.json | 2 +- packages/trapos/ccpm.json | 10 +- 8 files changed, 106 insertions(+), 18 deletions(-) rename CLAUDE.md => AGENTS.md (99%) diff --git a/CLAUDE.md b/AGENTS.md similarity index 99% rename from CLAUDE.md rename to AGENTS.md index 1b4fbc0..84c0d72 100644 --- a/CLAUDE.md +++ b/AGENTS.md @@ -1,4 +1,4 @@ -# CLAUDE.md +# AGENTS / CLAUDE.md Concise guidance for agents working in this repository. diff --git a/docs/adrs/adr-0005-craftos-pc-harness-and-probes.md b/docs/adrs/adr-0005-craftos-pc-harness-and-probes.md index 389d0b7..b5f2be8 100644 --- a/docs/adrs/adr-0005-craftos-pc-harness-and-probes.md +++ b/docs/adrs/adr-0005-craftos-pc-harness-and-probes.md @@ -15,9 +15,9 @@ This repository targets CC:Tweaked on Minecraft 1.21. The Lua we ship runs insid Contributors have been running the code in two places: - In-game on a real Minecraft server, which is slow to iterate on. -- In **CraftOS-PC** (https://www.craftos-pc.cc/), a desktop emulator that ships the same ROM/BIOS as CC:Tweaked, supports modem peripherals via `periphemu`, and can run fully headless (`--cli --headless --script `). +- In **CraftOS-PC** (), a desktop emulator that ships the same ROM/BIOS as CC:Tweaked, supports modem peripherals via `periphemu`, and can run fully headless (`--cli --headless --script `). -CraftOS-PC was the *de facto* local harness for months but lived only as a single line in [`CLAUDE.md`](../../CLAUDE.md). There was no install guide, no minimum version, and `just install` did not check the binary was present. Two related concerns emerged on top of that: +CraftOS-PC was the *de facto* local harness for months but lived only as a single line in [`AGENTS.md`](../../AGENTS.md). There was no install guide, no minimum version, and `just install` did not check the binary was present. Two related concerns emerged on top of that: - `startup/servers.lua` historically called `periphemu.create` four times on computer 0 (a top modem, two `computer` peers at ids 1 and 2 both labelled `Trap`, and a router peer at id 10). In CraftOS-PC GUI mode this opened **four windows** on every launch, and the duplicate `Trap` label plus persistent per-id state across versions caused recurring confusion. - Headless CraftOS-PC is also a cheap, deterministic *interactive* tool: it boots the emulator, runs an arbitrary Lua snippet against the real CC:Tweaked ROM, prints output, and exits in well under a second. Humans and agents can use it to verify hypotheses about CC:Tweaked behavior *before* writing code or tests. That usage was implicit; no document framed headless exec recipes as the recommended first move when an agent is unsure about CC:Tweaked behavior. @@ -34,7 +34,7 @@ CraftOS-PC was the *de facto* local harness for months but lived only as a singl - **Vanilla launch.** `just craftos` launches CraftOS-PC under `.craftos-vanilla/` with no mounts and no startup, for probes that should not see TrapOS files and for the `just trapos-install` end-to-end install verification. - **`just ci` is the local verification entry point.** It runs `check-craftos`, `check`, and `test`. Local Git hooks are installed by `just install`; see [ADR-0011](adr-0011-repo-conventions.md) for the commit/push split. -The existing [`CLAUDE.md`](../../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. +The existing [`AGENTS.md`](../../AGENTS.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. ### 2. Periphemu bootstrap stays minimal diff --git a/docs/periphemu.md b/docs/periphemu.md index a4fed63..ab53c46 100644 --- a/docs/periphemu.md +++ b/docs/periphemu.md @@ -63,7 +63,7 @@ Call `periphemu.names()` from a CraftOS-PC shell to confirm what the current bui ## Caveats -- **CC:T has no `periphemu`.** Always guard with `if periphemu then`. CLAUDE.md and [ADR-0005](adrs/adr-0005-craftos-pc-harness-and-probes.md) treat that guard as mandatory. +- **CC:T has no `periphemu`.** Always guard with `if periphemu then`. [AGENTS.md](./../AGENTS.md) and [ADR-0005](adrs/adr-0005-craftos-pc-harness-and-probes.md) treat that guard as mandatory. - **Speaker `playAudio` differs from CC:T** unless [standards mode](https://www.craftos-pc.cc/docs/standards) is on — CraftOS-PC queues audio without ever returning `false`. - **Modem network id** segregates emulated networks. Two modems with different ids will not see each other; useful for testing the [router](../programs/router.lua) against a sealed network. - **Persisted per-computer state** lives at `~/Library/Application Support/CraftOS-PC/computer//` and `config/.json` (labels stored base64-encoded). Spawning a new id leaves that state behind across sessions. diff --git a/just/check.just b/just/check.just index ff2248b..3f28e05 100644 --- a/just/check.just +++ b/just/check.just @@ -4,12 +4,23 @@ check: check-luacheck check-lychee npm-check @just lint-markdown # Validate package descriptors and require version bumps for changed package files. -check-packages: check-jq +check-packages *args: check-jq #!/usr/bin/env bash set -euo pipefail repo='{{justfile_directory()}}' cd "$repo" + fix=0 + for arg in {{args}}; do + case "$arg" in + --fix) fix=1 ;; + *) + printf '%s\n' "FAIL: unknown check-packages option: $arg" >&2 + exit 2 + ;; + esac + done + semver_gt() { local a_major a_minor a_patch b_major b_minor b_patch IFS=. read -r a_major a_minor a_patch <<<"$1" @@ -21,6 +32,55 @@ check-packages: check-jq [ "${a_patch:-0}" -gt "${b_patch:-0}" ] } + bump_patch() { + local version major minor patch + version="$1" + IFS=. read -r major minor patch <<<"$version" + printf '%s.%s.%s\n' "${major:-0}" "${minor:-0}" "$(( ${patch:-0} + 1 ))" + } + + set_json_version() { + local path version tmp + path="$1" + version="$2" + tmp="$(mktemp)" + while IFS= read -r line; do + if [[ "$line" =~ ^([[:space:]]*\"version\"[[:space:]]*:[[:space:]]*\")[^\"]*(\".*)$ ]]; then + printf '%s%s%s\n' "${BASH_REMATCH[1]}" "$version" "${BASH_REMATCH[2]}" + else + printf '%s\n' "$line" + fi + done <"$path" >"$tmp" + mv "$tmp" "$path" + } + + set_index_version() { + local name version tmp + name="$1" + version="$2" + tmp="$(mktemp)" + jq --arg name "$name" --arg version "$version" '.packages[$name] = $version' packages/index.json >"$tmp" + mv "$tmp" packages/index.json + } + + bump_package() { + local name desc old_version current_version new_version + name="$1" + desc="$2" + old_version="$3" + current_version="$(jq -r '.version // empty' "$desc")" + if semver_gt "$current_version" "$old_version"; then + return 0 + fi + new_version="$(bump_patch "$old_version")" + set_json_version "$desc" "$new_version" + set_index_version "$name" "$new_version" + if [ "$name" = trapos ]; then + set_json_version manifest.json "$new_version" + fi + printf '%s\n' "FIX: bumped $name from $current_version to $new_version" + } + fail=0 packages=() while IFS= read -r name; do packages+=("$name"); done < <(jq -r '.packages | keys[]' packages/index.json | sort) @@ -55,9 +115,15 @@ check-packages: check-jq while IFS= read -r file; do files+=("$file"); done < <(jq -r '.files[]?' "$desc") if [ "${#files[@]}" -gt 0 ] && ! git diff --quiet "$last_desc_commit" -- "${files[@]}"; then if ! semver_gt "$desc_version" "$old_version"; then - printf '%s\n' "FAIL: $name package files changed since $desc was last bumped ($old_version); bump $desc and packages/index.json" >&2 - git diff --name-only "$last_desc_commit" -- "${files[@]}" >&2 - fail=1 + if [ "$fix" -eq 1 ]; then + bump_package "$name" "$desc" "$old_version" + desc_version="$(jq -r '.version // empty' "$desc")" + index_version="$(jq -r --arg name "$name" '.packages[$name] // empty' packages/index.json)" + else + printf '%s\n' "FAIL: $name package files changed since $desc was last bumped ($old_version); bump $desc and packages/index.json" >&2 + git diff --name-only "$last_desc_commit" -- "${files[@]}" >&2 + fail=1 + fi fi fi done @@ -80,13 +146,29 @@ check-packages: check-jq while IFS= read -r dep; do deps+=("packages/$dep/ccpm.json"); done < <(jq -r '.dependencies[]?' "$trapos_desc") if [ "${#deps[@]}" -gt 0 ] && ! git diff --quiet "$trapos_commit" -- "${deps[@]}"; then if ! semver_gt "$trapos_version" "$old_trapos_version"; then - printf '%s\n' "FAIL: trapos dependencies changed since trapos was last bumped ($old_trapos_version); bump $trapos_desc and packages/index.json" >&2 - git diff --name-only "$trapos_commit" -- "${deps[@]}" >&2 - fail=1 + if [ "$fix" -eq 1 ]; then + bump_package trapos "$trapos_desc" "$old_trapos_version" + else + printf '%s\n' "FAIL: trapos dependencies changed since trapos was last bumped ($old_trapos_version); bump $trapos_desc and packages/index.json" >&2 + git diff --name-only "$trapos_commit" -- "${deps[@]}" >&2 + fail=1 + fi fi fi fi + trapos_version="$(jq -r '.version // empty' "$trapos_desc")" + manifest_version="$(jq -r '.version // empty' manifest.json)" + if [ "$manifest_version" != "$trapos_version" ]; then + if [ "$fix" -eq 1 ]; then + set_json_version manifest.json "$trapos_version" + printf '%s\n' "FIX: synced manifest.json from $manifest_version to $trapos_version" + else + printf '%s\n' "FAIL: manifest.json version ($manifest_version) differs from trapos package ($trapos_version)" >&2 + fail=1 + fi + fi + if [ "$fail" -ne 0 ]; then exit 1; fi printf '%s\n' 'OK: package versions aligned' diff --git a/manifest.json b/manifest.json index da0e5f3..7493b8a 100644 --- a/manifest.json +++ b/manifest.json @@ -1,6 +1,6 @@ { "name": "TrapOS", - "version": "0.8.9", + "version": "0.8.10", "branch": "next", "packages": [ "trapos" diff --git a/packages/index.json b/packages/index.json index 1a003a9..a753677 100644 --- a/packages/index.json +++ b/packages/index.json @@ -5,8 +5,8 @@ "trapos-boot": "0.3.2", "trapos-net": "0.3.0", "trapos-ui": "0.2.2", - "trapos-ai": "0.6.7", + "trapos-ai": "0.6.8", "trapos-sandbox": "0.2.1", - "trapos": "0.8.9" + "trapos": "0.8.10" } } diff --git a/packages/trapos-ai/ccpm.json b/packages/trapos-ai/ccpm.json index 79379e9..709cabd 100644 --- a/packages/trapos-ai/ccpm.json +++ b/packages/trapos-ai/ccpm.json @@ -1,6 +1,6 @@ { "name": "trapos-ai", - "version": "0.6.7", + "version": "0.6.8", "description": "TrapOS AI client for opencode serve", "dependencies": ["trapos-core"], "files": [ diff --git a/packages/trapos/ccpm.json b/packages/trapos/ccpm.json index 6d7ae14..53c5a9d 100644 --- a/packages/trapos/ccpm.json +++ b/packages/trapos/ccpm.json @@ -1,8 +1,14 @@ { "name": "trapos", - "version": "0.8.9", + "version": "0.8.10", "description": "TrapOS full install meta-package", - "dependencies": ["trapos-boot", "trapos-net", "trapos-ui", "trapos-test", "trapos-ai"], + "dependencies": [ + "trapos-boot", + "trapos-net", + "trapos-ui", + "trapos-test", + "trapos-ai" + ], "files": [], "autostart": [] }