chore(agents): adopt agents guidance

This commit is contained in:
Guillaume ARM 2026-06-11 19:35:23 +02:00
parent 5a950de0ba
commit 7d0d69e5b5
8 changed files with 106 additions and 18 deletions

View File

@ -1,4 +1,4 @@
# CLAUDE.md
# AGENTS / CLAUDE.md
Concise guidance for agents working in this repository.

View File

@ -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 <file>`).
- 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 <file>`).
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

View File

@ -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/<id>/` and `config/<id>.json` (labels stored base64-encoded). Spawning a new id leaves that state behind across sessions.

View File

@ -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,11 +115,17 @@ 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
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
for desc in packages/*/ccpm.json; do
@ -80,12 +146,28 @@ 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
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'

View File

@ -1,6 +1,6 @@
{
"name": "TrapOS",
"version": "0.8.9",
"version": "0.8.10",
"branch": "next",
"packages": [
"trapos"

View File

@ -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"
}
}

View File

@ -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": [

View File

@ -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": []
}