The extension Tracy installs so an AI assistant can read a site and apply the changes you approve. Token-gated, and every change can be put back. Joomla and WordPress; Shopify to come.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
The extension Tracy installs on a site so an AI assistant can work on it — read its database, its
files and what it has installed, and apply an approved change back to it — over one
token-authenticated endpoint.
Every action is named and bounded. There is no shell, no arbitrary file write, and nothing the
extension does not implement by hand. Most of the surface reads. The write side installs a plugin,
theme or extension, edits a post or an option, and puts a file into the media library — nothing
else.檢視完整 README ↗The extension Tracy installs on a site so an AI assistant can work on it — read its database, its files and what it has installed, and apply an approved change back to it — over one token-authenticated endpoint.
Every action is named and bounded. There is no shell, no arbitrary file write, and nothing the extension does not implement by hand. Most of the surface reads. The write side installs a plugin, theme or extension, edits a post or an option, puts a file into the media library, and writes a file of the site's own template or theme over the exact bytes the caller says are there — nothing else.
Every change can be taken back. Each edit is recorded under the caller's apply_id, so one
call puts a whole deliverable back to what was there before. Installs are the exception and say so:
installing is additive, and the CMS owns the uninstall.
Going live is still a decision. Work is drafted and reviewed in a git repository your team owns before anything reaches the running site, and clearing the token revokes all of it at once.
The name is for the way of working, not for a vendor. The endpoint is plain HTTP behind a token, so Claude, ChatGPT, Gemini or something you wrote yourself all use it the same way.
| Folder | Platform | State |
|---|---|---|
joomla/ | Joomla 4 and 5 | In use |
wordpress/ | WordPress | In use |
shopify/ | Shopify | Not started |
Each platform folder holds two things a site installs: cowork/, the extension above, and the
look Tracy builds a site in — joomla/template/ (tpl_tracy) and
wordpress/theme/ (tracy). One template and one theme, each carrying 152
design inspirations as styles, so a site changes its whole look by changing one setting.
One repository rather than one per platform, and one engine per platform inside it. Each
platform owns its own lib/: they start as copies of each other and are expected to drift, because
tuning for an old WordPress must not be a change Joomla has to survive. Side by side in one
repository is what keeps the interesting decisions — how work is cut into resumable pieces, how a
cursor survives a request being killed — comparable while they diverge.
<platform>/cowork/ is the extension a customer installs on their own site, and it is the only
thing in here. update.xml and update.json sit beside it at the platform root because a site
records that address when it installs the package, so those paths are a published contract.
A second plugin used to live here — Tracy Access, the auto-login for a Tracy-hosted copy of a
site. It moved to tracy-fleet
(provision/access/) on 2026-08-17: it is installed only by provisioning, on a clone, and it
creates users and opens sessions — nothing a customer downloads should sit next to. Keeping it
here also meant maintaining a second copy in the fleet repository, which had already drifted.
joomla/template/tpl_tracy/ and wordpress/theme/tracy/ are mirrors, not sources. They are
generated in Tracy's own repository from a vendored design library — 152 token sets, 152 style
variations, the page layouts and the section markup — and copied here by
node scripts/sync-cms-themes.mjs <this checkout> over there. Nothing in those two directories is
edited here: an edit would be overwritten by the next sync, and the gate that proves the generated
files match the library does not run in this repository.
What does belong here is the release:
node scripts/release-joomla-template.mjs 0.1.1 # tag joomla-template-v0.1.1
node scripts/release-wordpress-theme.mjs 0.1.1 # tag wordpress-theme-v0.1.1
Each reads the version out of the mirrored tree and refuses when it disagrees with the number asked for — the number is decided once, in the repository that generates the tree.
Four release lines, one repository. joomla-v* and wordpress-v* are the extension;
joomla-template-v* and wordpress-theme-v* are the look. They never collide: provisioning
resolves the extension by tag prefix and version range (git ls-remote --tags 'wordpress-v0.6.*')
and a site resolves its look through the update manifest, so neither ever asks GitHub for "the
latest release" of the repository as a whole. A look release is cut with --latest=false for the
same reason: that badge is repo-wide and belongs to the extension, which is what a person coming
here installs first. It writes the
announcement (joomla/template/update.xml, wordpress/theme/update.json), builds the zip, tags,
and creates the release. A site installed with the update server recorded then finds the new
version by itself, the same way the extension does.
Nothing is pushed to main, a release included. Every change reaches it through a pull
request. The three release scripts (release-wordpress.mjs, release-wordpress-theme.mjs,
release-joomla-template.mjs, sharing scripts/release-pr.mjs) and the Joomla extension's release
by hand all take the same path, in this order, because installed sites read the announcement on
main every quarter hour and must never see a version whose zip is not downloadable yet:
release/<tag> and tag that commit;main and merge it with a merge commit (gh pr merge --merge, no
squash, no rebase, no --admin), so the tagged commit is in main's history.If the merge cannot happen — a conflict, a failing check — the script stops and says so: the
release exists, but no site is offered it until the pull request merges. Its message says how to
finish (fix it, gh pr merge <pr> --merge) or roll back (gh pr close <pr> --delete-branch,
gh release delete <tag> --cleanup-tag). --dry-run checks and builds and publishes nothing.
Tracy keeps a git repository of a site: every article, page and template as files, with a history you can read, compare and roll back. This extension is how the site gets in there, and how an approved change gets back out.
Both directions run through it, and they are not the same act. Bringing the site in happens on a schedule and needs nobody's permission. Putting a change back is one deliberate call per approved deliverable, recorded so it can be undone — coworkers draft and review in the repository first, and only an administrator decides what goes live.
GPL-2.0-or-later — see LICENSE.txt. An extension built against Joomla's own API is a derivative work of GPL code, so this is the licence it must carry rather than one picked by preference.
Claude is a trademark of Anthropic PBC. This is built by Tracy and is not affiliated with, endorsed by or sponsored by Anthropic.