Install and run
The factory runs in a T3 server started by a macOS LaunchAgent. The desktop app is optional: it is a window onto that server. Both are built from a clone of this repo on an Apple silicon Mac.
Before you start
Clone original-solutions/t3code-factory and run
vp iin it.Install current stable Rust (
rustup update stable). The build compiles a small native helper.Log in a GitHub CLI config directory as the login the factory will act as:
shGH_CONFIG_DIR=~/.config/t3fac/gh gh auth login GH_CONFIG_DIR=~/.config/t3fac/gh gh api user --jq .loginThe LaunchAgent sets
GH_CONFIG_DIRto this directory, so the server's own GitHub calls and its agent sessions act as this login. Gate commands don't inheritGH_CONFIG_DIR(Add a repo); a gate that callsghmust set it itself.
Install the server
From a clean checkout, build and install in one step:
factory/scripts/deploy.shIt builds release/t3fac-<version>-darwin-arm64.tar.gz, smoke-tests it, then installs it: the archive is unpacked under ~/.local/share/t3fac/versions/, ~/.local/share/t3fac/current points at it, and the LaunchAgent io.github.rawphp.t3fac restarts the server on port 3876 with its data in ~/.config/t3fac. A second LaunchAgent, io.github.rawphp.t3fac.logrotate, rotates the log.
deploy.sh reuses an archive already built for the same commit. Pass --rebuild to build again, or --build-only to stop before installing. Scripts lists every script and its exit codes.
The install waits up to 90 seconds for the server to answer on port 3876 and to log factory started or no factory config. If it doesn't, the install rolls back to the previous version and exits 1. With no machine config yet, the server logs no factory config and the factory stays idle.
Tools the server can see
launchd gives the server only the PATH its plist sets, which covers Homebrew, /usr/bin and vp. Gates and sessions often need more, such as claude, cargo, php or composer. Put those in ~/.config/t3fac/env, which the job sources before it starts the server:
PATH="$PATH:$HOME/.cargo/bin"
export PATHCheck what the running job has with launchctl print gui/$(id -u)/io.github.rawphp.t3fac.
Install the desktop app
vp run dist:desktop:dmg:arm64The dmg lands under release/. It is unsigned, so the first time you open the app, right-click it and choose Open. It installs beside upstream T3 Code as T3 Code Factory and shares no data with it or with the LaunchAgent server.
The app's built-in server has no machine config, so its factory stays idle. Keep it that way: before you save Settings → Factory in the app, pick the LaunchAgent server's environment. Saving the form for the built-in server would start a second factory on this Mac that claims the same issues. To see the factory in the app, pair the LaunchAgent server as an environment in Settings → Connections, with a pairing link from:
~/.local/share/t3fac/current/t3 pair --base-dir ~/.config/t3facAdd --tailscale for a link that works over your tailnet, for example from a phone's browser. The Factory pages are part of the fork's web app, so any browser paired with the server can open them. A connection through T3 Connect (the relay) doesn't reach them yet. Remote access covers pairing in general.
Logs
| File | What it holds |
|---|---|
~/Library/Logs/t3fac/t3fac.log | The server's output, including each factory pass. Rotated at 20 MB, five copies kept. |
~/Library/Logs/t3fac/logrotate.log | One line per rotation. |
~/.config/t3fac/factory/events.jsonl | The factory's machine log: passes, skipped repos, errors, server starts and stops. |
~/.config/t3fac/factory/runs/<run id>.jsonl | One ledger per run. The run's page shows it. |
To tell whether the server is up:
launchctl print gui/$(id -u)/io.github.rawphp.t3fac
tail -n 50 ~/Library/Logs/t3fac/t3fac.logNo pid line means the job isn't running. A non-zero last exit code with a growing runs count is a crash loop. A config error is logged as <file>: <field>: <message>, and the factory stays idle until it is fixed.
Roll back
factory/scripts/rollback.shIt points current back at the previous version, restarts the server and runs the same health check. With no previous version it exits 1; install an older archive from release/ with factory/scripts/install.sh <archive> instead.
Restart without installing
A paired session with the environment:maintain scope can restart the server:
curl -X POST -H "Authorization: Bearer <token>" http://127.0.0.1:3876/api/factory/restartlaunchd starts it again about 10 seconds later, on the version current points at. A gate that was running is killed, and the next pass runs it again from a fresh checkout.