4.2 KiB
4.2 KiB
ADR 0004: TrapOS Branding And Manifest-Driven Installs
Status
Accepted
Date
2026-06-07
Context
The project started as a loose collection of ComputerCraft / CC:Tweaked APIs and programs. As the surface area grew (eventloop, net, router, ping, events, upgrade) and the install/upgrade flow gained a beta channel, three pain points emerged:
install.luacarries a hardcodedLIST_FILEStable that has to be edited every time a file is added or removed. Adding a single shipped file means editing the file itself, the installer, and sometimesstartup/servers.lua.- The
--betaflag is not persisted. The user has to remember to pass it on everyupgrade, which makes the beta channel awkward to live on. - The system has no visible identity at boot. There is no name, no version line, nothing that confirms which branch is installed.
At the same time, the codebase has outgrown the "Trap's ComputerCraft APIs" framing. It is closer to a small in-game operating system than a library, and treating it as one unlocks a clearer story (a name, a version, a manifest, a boot banner).
Decision
Adopt the name TrapOS and a manifest-driven install architecture.
- A single
manifest.jsonat the repo root is the source of truth for the project: name, version, branch, list of shipped files, and the list of servers to autostart at boot. Parsed withtextutils.unserializeJSON/textutils.serializeJSON(built-in to CC:Tweaked). - A local copy of that manifest is written to
/trapos/manifest.jsonat the end of every install. This local file is the authoritative system state on the computer:branchis the persisted beta opt-in. Once a user installs with--beta(and confirms a one-time(y/N)prompt), subsequentupgradecalls auto-target thenextbranch with no flag needed.versionis what the boot MOTD displays.filesandautostartdrive the next install and the boot sequence.
- A new
startup/motd.luaprints a coloredTrapOS v<version>line at boot — lime for stable, orange with a[BETA]tag for beta. Guarded onterm.isColor()so monochrome terminals still get the text. startup/servers.luareadsautostartfrom the local manifest instead of carrying its own hardcoded list.- The shipped install URL stays at
https://raw.githubusercontent.com/guillaumearm/cc-libs/...for now. Renaming the GitHub repository is a follow-up, tracked in the "Future Work" section below.
Consequences
- Adding a new file or autostart server is now a one-line edit to
manifest.json. Bothinstall.luaandstartup/servers.luapick it up automatically. - The beta channel becomes a real opt-in: a single confirmed
upgrade --betais enough to live onnext. A new--stableflag exists for the symmetric opt-out. - The boot banner gives users an immediate sanity check ("am I on the right branch, the right version?").
- The system gains an explicit local state directory (
/trapos/) and a clear contract for what lives there. - The installer takes a hard dependency on
textutils.serializeJSON/unserializeJSON, which require CC:Tweaked ≥ 1.79. This is well within any reasonable target version for Minecraft 1.21. - Existing computers running the old installer still upgrade cleanly: the old
upgradefetches the newinstall.lua, which then creates/trapos/manifest.jsonfrom the manifest it just downloaded.
Future Work
- Repository rename. Once the install flow has stabilized on
TrapOS, the GitHub repository will be renamed fromcc-libsto a name that matches (likelytrapos). The install URL insideinstall.luaandprograms/upgrade.luawill be updated in the same PR, and a redirect at the old URL is sufficient for in-the-wild installs. - Package manager. The longer-term direction floated during planning was a small package manager where each directory in the repo is a package. The current manifest is a deliberate step toward that — same shape (name, version, files), single-package case — and can grow into multi-manifest discovery without changing the install/upgrade contract.
- Per-version migration system. Today the installer carries a static list of legacy files to delete. A future change can replace this with a per-version migration block driven by the manifest.