The problem
Once there are more than a few utilities, it is no longer clear which copy is real. Code lives on the VM, some of it on GitHub, some was edited by hand on the droplet; each utility has its own way to run, deploy and back up; and an AI agent working in the wrong folder can change or break a neighbouring utility. Every new utility also needs its own repository, server set-up, route, database and backup, which turns a one-hour idea into an afternoon of plumbing.
Features
- Three mirrors, one truth: the same folder name on the VM (C:\HiveCode-Utilities\name), in GitHub (utilities/name) and on the droplet (/opt/xgapps/apps/name); GitHub is the source of truth and the droplet only ever runs a commit from it
- One VS Code window: a multi-root workspace shows every utility as its own root, with Claude Code at the master folder for cross-utility work or in one utility's folder for focused work, plus tasks for run, deploy and logs
- Many projects, one VS Code window: every utility is its own root in a multi-root workspace with its own settings, interpreter, tasks, debugger, terminal and Claude Code session; a HiveCode Utilities side panel lists them all with run, deploy, logs and status, and a focus mode keeps the window fast when there are dozens
- xg new name creates everything in one step: the folder from a template (stack and database chosen by you, with a recommended choice shown), its CLAUDE.md and README, the workspace entry, the GitHub commit, the droplet app through xgapp and its address, then a first health-checked deploy
- Hard separation for people and agents: each utility has its own folder, container, memory limit, database, secrets and Linux user on the droplet; on the VM, per-folder Claude Code permission rules keep an agent inside the utility it was asked to work on
- Foolproof by layers: a mistake has to get past four guards before a user sees it (a Claude Code hook that refuses edits outside the session's utility, a pre-commit scope and secret check, pull request checks that repeat both plus tests and a preflight, and the health check after deploy), and xg undo name puts back the previous code and the data backup taken just before that deploy in one command
- Push to deploy only what changed: GitHub Actions with path filters deploy just the changed utility folders through a restricted deploy key; each deploy is health-checked and rolls back on failure
- A status board for every utility across all three places: VM commit, GitHub commit and the commit running on the droplet, marked in sync, ahead, behind or drifted (a hand edit on the droplet), with health, memory, visits and last deploy
- Run and test locally on the VM first with the same settings file the droplet uses, so 'works on my VM' means 'works on the droplet'
- Nightly restore-tested backups of each utility's data on the droplet with a copy in DigitalOcean Spaces; code is already safe in GitHub, so a lost droplet or VM is rebuilt from the repository plus the last backup
- Telegram alerts for a failed deploy, a down utility, a drifted folder or low memory; optional sign-in in front of private utilities; previews at a temporary address before going live
How it works
Layout
- VM: C:\HiveCode-Utilities\ holds CLAUDE.md (shared rules), HiveCode-Utilities.code-workspace, templates\, .github\workflows\ and one folder per utility
- Each utility folder: CLAUDE.md (its own contract and notes), xgapp.toml (stack, database, address, memory), src\, tests\, .env.example and a README; real secrets never enter git
- GitHub: one repository with the same tree; main changes only through pull requests with passing checks (see Foolproof below); the workflow maps changed paths to utility names
- Droplet: /opt/xgapps/apps/name/code receives only that folder; data, backups and .env live beside it and never in git
How a change flows
- Claude Code edits C:\HiveCode-Utilities\name and runs its tests and a local run on the VM
- Commit and push from the same VS Code window; the workflow deploys only name to the droplet
- xgapp builds, health-checks, switches over or rolls back, then reports the deployed commit back to the status board
- If someone edits on the droplet directly, the board shows drift and offers to pull the change into git or overwrite it from GitHub
Many projects in one VS Code window
- The workspace file HiveCode-Utilities.code-workspace lists every utility folder as a named root (mail-lens, invoice-check, price-watch and so on) plus a shared root for templates and design tokens; xg new adds the root automatically
- Each root carries its own .vscode folder: settings (Python interpreter, Node or .NET version, formatter), recommended extensions, tasks and launch configurations, so switching from a Python utility to a .NET one needs no manual change
- Workspace-level tasks use the current file's folder, so one shortcut runs, tests, deploys or opens the logs of whichever utility you are editing; a compound launch runs two utilities together when one calls the other
- Each utility has a fixed local port from its xgapp.toml (8101, 8102 and onwards), so several run side by side on the VM without clashing
- Terminals open in the chosen root and are named after the utility; a Claude Code session started in a utility's terminal reads that folder's CLAUDE.md plus the shared root CLAUDE.md, and its .claude/settings.json permission rules keep edits inside that folder
- Cross-utility work, such as updating the shared footer everywhere, uses one Claude Code session at the master folder with the shared rules; focused work uses one session per utility, several running in parallel
- Parallel sessions on the same repository each work in their own git worktree and branch, so two agents never edit the same files at once; each merges back through a pull request that deploys only its folder
- xg work mail-lens fix-quota (or New task in the side panel) does the whole parallel set-up in one step: it makes the git worktree and branch, opens a terminal named mail-lens / fix-quota in it and starts Claude Code there with that utility's rules; xg done fix-quota commits, opens the pull request and removes the worktree once it is merged, so no git commands are typed by hand
- One repository means one Source Control list; the panel groups changes by utility and commits each utility separately, so history and deploys stay per utility
- The HiveCode Utilities side panel (a small VS Code extension) shows every utility with its VM, GitHub and droplet status, local port and health, with buttons for Run, Test, Deploy, Logs, Open address and Start Claude here; the status bar shows the utility of the open file and its droplet health
- Focus mode for scale: with 30 or more utilities, xg focus mail-lens invoice-check rewrites the workspace to the few in hand (others hidden from search and file watching), and xg focus all brings them back
What is automatic and what you do
- Automatic: new project set-up (xg new makes the folder, workspace root, settings, tasks, debugger, CLAUDE.md, permission rules, port, GitHub folder, droplet folder and web address)
- Automatic: switching projects (each root's own settings and interpreter apply to the open file), run, test, deploy and logs from the side panel, fixed ports, named terminals
- Automatic: parallel work (xg work makes the worktree, branch, terminal and Claude Code session; xg done opens the pull request and cleans up), per-utility commits and deploys, focus mode
- You, once: install VS Code, the HiveCode Utilities extension and Claude Code, sign in to GitHub, give the VM its SSH key to the droplet
- You, every day: open the one VS Code window and tell each Claude Code session what to build or fix
- You, always: review and approve changes and pull requests before they deploy, and decide which version wins when two branches change the same shared file; these stay with you on purpose
Foolproof: a guard at every step
- Create: xg new refuses a name that is invalid, reserved (admin, api, caddy, cloud, db, download, packages, platform, v1, vpn, x) or taken, a route already in use, or a memory size that would leave the droplet under 512 MiB free; nothing is chosen for you, a recommended choice is shown with Use recommended
- Edit: each utility folder has .claude/settings.json deny rules plus a PreToolUse hook that refuses any Edit or Write outside that folder and says which xg work command to use instead; the shared folder is read-only to utility sessions
- Commit: a git pre-commit hook (installed by xg doctor, re-checked every run) refuses a commit that touches more than one utility folder unless the branch is shared/..., runs gitleaks for secrets, and checks that generated files were not hand-edited
- Pull request: the check workflow repeats the scope and secret checks server-side (so --no-verify does not help), runs the utility's tests and the xg check preflight, and posts a plain-English summary of what will deploy
- Merge: merging is the approval. GitHub does not let you approve your own pull request, so the rule is a pull request with passing checks; with a ruleset (GitHub Pro or Team on a private repository) main cannot be pushed to directly, and without one the deploy job itself refuses any commit whose checks did not pass
- Deploy: one deploy per utility at a time (a concurrency group and a lock on the droplet), a data backup first, migrations tried on a copy of the database first, the new container must pass /health within 120 seconds or the previous image and data come back, and a Telegram alert either way
- Run: the code folder on the droplet is read-only inside the container, each utility runs as its own Linux user with its own memory limit, and logs rotate with a size cap so one utility cannot fill the disk
- Recover: xg undo, nightly restore-tested backups with a copy in DigitalOcean Spaces, and xg rebuild droplet or xg rebuild vm from GitHub and Spaces, rehearsed on a throwaway droplet
When something goes wrong
- Claude Code edits another utility's file: the hook refuses it; if a shell command does it anyway, the pre-commit check refuses the commit; if that is skipped, the pull request check fails and the deploy job will not run it
- A secret is pasted into code: gitleaks stops the commit; if it reached GitHub, the check fails, the panel shows Rotate this key, and the deploy does not run
- The new version will not start: the health check fails, the previous image and the pre-deploy data backup come back, and the alert names the commit and shows the last 25 log lines
- A migration fails halfway: it already failed on the copy, so the live database was never touched; if the copy passed and the real one fails, the pre-deploy backup is restored with the old image
- The droplet is nearly out of memory: the deploy is refused before it starts, with what to stop or shrink; the 512 MiB reserve for the VPN and the main stack is never used
- The disk passes 80%: an alert, old images pruned, backups beyond 14 per utility removed oldest first, never the newest restore-tested one
- A route is wrong: Caddy validates the new configuration before reloading and keeps the old one if it fails, so the website and the other utilities stay up
- GitHub is down: nothing deploys and every running utility keeps running; there is deliberately no way to deploy around GitHub, because the droplet only runs GitHub commits
- The droplet is lost: xg rebuild droplet makes a new one, installs xgapp, deploys each utility at its GitHub commit and restores its data from Spaces; the time is measured in every rehearsal
- The dev VM is lost: xg rebuild vm clones the repository and regenerates the workspace, hooks and tasks, and every utility is back in VS Code; only work not yet pushed lived on the VM alone, and xg status warns about that daily
- A shared change breaks something: each utility pins a shared version in xgapp.toml, so a shared change reaches a utility only when xg bump name moves it in its own pull request with its own tests
Generated, never hand-edited
- xg writes and owns: HiveCode-Utilities.code-workspace, xg.lock.json (names, local ports, routes, memory, pinned shared versions), each utility's .vscode tasks and launch files, the hook files, the workflow path map and the Caddy route files on the droplet
- xg doctor regenerates them in memory and shows any difference; xg doctor --fix writes them back. The pre-commit and pull request checks fail if a generated file was edited by hand
- Each generated file starts with a one-line header saying it is generated and which command changes it, so neither a person nor Claude Code edits it by mistake
The xg commands
- xg doctor [--fix]: checks git, gh, the SSH key, runtimes, VS Code, the HiveCode Utilities extension, Claude Code, hooks and generated files; changes nothing without --fix
- xg new name: folder, workspace root, port, CLAUDE.md, rules, tasks, GitHub pull request and the droplet app; xg retire name: final backup, route removed, folder archived, history kept
- xg run name, xg test name, xg check name (the full preflight, the same one the pull request runs)
- xg work name task, xg done task, xg ship task (merges when checks pass and follows the deploy until the health check answers)
- xg status [name], xg logs name, xg sync name (fix drift), xg undo name, xg backup name, xg restore name [--at time]
- xg focus name... and xg focus all, xg bump name (move to a newer shared version), xg rebuild vm or xg rebuild droplet
- Every command that changes something supports --dry-run, prints a plain-English summary first, is safe to run twice, and resumes or rolls back if interrupted
Who it is for
HiveCode owner
A new idea on a Saturday
xg new invoice-check makes the folder on the VM, the GitHub folder and the droplet app; Claude Code builds it in that folder only, the push deploys just invoice-check, the health check passes, and it is live and backed up by lunch.
HiveCode owner
The hand edit nobody remembered
The status board marks price-watch as drifted because a file was changed on the droplet; one click pulls the change into the VM folder and GitHub, so the three copies match again.
HiveCode owner
Three projects before lunch
In one VS Code window, a Claude Code session fixes a bug in mail-lens in its own terminal and worktree while a second session builds invoice-check; the panel shows both running locally on ports 8101 and 8102, each is committed and deployed on its own, and price-watch is untouched.
HiveCode owner
The agent wandered
While fixing invoice-check, Claude Code tries to change the shared footer. The hook refuses and suggests xg work shared footer-fix; the owner runs it, the change goes through its own pull request, and invoice-check's fix ships on its own.
HiveCode owner
The 2 a.m. deploy
A merge to price-watch deploys at night. The new version fails its health check, the previous image and the backup taken a minute earlier come back, and a Telegram alert names the commit with the last log lines. Nothing else on the droplet noticed.
HiveCode owner
The droplet is gone
The droplet is destroyed in a rehearsal. xg rebuild droplet creates a new one, deploys every utility at its GitHub commit and restores its data from Spaces; the status board turns green and the measured time goes into the runbook.
Benefits
- Every project in one VS Code window, each kept separate
- VM, GitHub and droplet always in step
- A new utility live in minutes, safely separated
- Mistakes stopped before they go live, and one-command undo
Built to be trusted
- The droplet only ever runs a commit that exists in GitHub, so every running utility can be rebuilt
- A failed deploy never replaces a working one: health check first, automatic rollback
- A utility, or an agent working on one, can never read or change another utility's files, database or secrets
- Backups are restore-tested, not just written, and a copy lives off the droplet
- Two Claude Code sessions never share a working tree: parallel work uses separate git worktrees and branches
- xg done never deletes a worktree that has changes not yet in a pull request
- Only one deploy per utility runs at a time, and every deploy takes a data backup first, so undo restores both code and data
- A migration runs on a copy of the database before the real one
- Generated files are regenerated by xg, never hand-edited, and checks fail if they were
- Every changing command has a dry run, is safe to run twice and resumes or rolls back after an interruption
- A restore of every utility is rehearsed weekly into a scratch container, and a full droplet rebuild is rehearsed before each xgapp release
Good to know
The droplet half already exists as xgapp 0.1.0, smoke-tested across seven stack and database combinations including restore after delete, and Mail Lens runs on it. The master folder, the GitHub monorepo and its deploy workflow, the xg helper, the status board, off-droplet backups and the Claude Code permission rules are still to build. The dev VM cannot run Docker, so local runs use each stack's own runtime, which is close to but not identical with the droplet's containers. Claude Code permission rules keep an agent in its folder in normal use, but they are guard rails, not a security boundary; the real boundary is the separate Linux user and container on the droplet. One droplet is still one point of failure, and Coolify, Dokku and the managed platforms are more mature. Multi-root workspaces slow down with very many large folders, which is why focus mode exists. Claude Code permission rules and worktrees keep parallel sessions apart in normal use; they are guard rails, and the per-utility commits and reviews are what keep the history clean. Foolproof here means layered, not perfect: a hook cannot understand every shell command, a ruleset on a private repository needs GitHub Pro or Team, and GitHub's own secret scanning on private repositories is a paid add-on, which is why gitleaks runs in the hook and in CI. GitHub Actions on a private repository has a monthly free minute allowance; short SSH deploys stay well inside it.
Under the hood
For technical readers
- Master folder on the dev VM (recommended C:\HiveCode-Utilities) with one sub-folder per utility, a root CLAUDE.md, shared templates and a VS Code multi-root workspace file
- One GitHub monorepo (recommended HiveCode/utilities) with the same folders; GitHub Actions with path filters, so a push deploys only the utility folders that changed
- xgapp on the droplet (new, deploy, rollback, backup, restore, doctor): /opt/xgapps/apps/{name} per utility, Docker Compose per utility and Caddy routes with automatic HTTPS
- A deploy key on the droplet that can run only the xgapp deploy command (forced command in authorized_keys), never a shell
- An xg helper for the VM (PowerShell module plus VS Code tasks): new, run, status, deploy, logs, open; it drives git, gh and xgapp over SSH
- Local runs on the VM with each stack's own runtime (Python, Node.js, .NET or static) and SQLite or a portable PostgreSQL, because the dev VM cannot run Docker
- Claude Code in VS Code: one session at the master folder, or one per utility folder, with per-folder .claude/settings.json permission rules; DigitalOcean Spaces for off-droplet backups; Alerts engine for Telegram
- VS Code multi-root workspace (.code-workspace with named folders, per-folder .vscode settings, tasks and launch, ${fileWorkspaceFolder} in tasks) and a small HiveCode Utilities extension (tree view, status bar item, commands) that calls the xg helper
- Guard layers: Claude Code PreToolUse hooks and per-folder deny rules; a git pre-commit hook with gitleaks; a GitHub check workflow (scope, tests, secrets, preflight) and a ruleset on main where the plan allows; a deploy concurrency group per utility; xgapp extended with a deploy lock, pre-deploy backup, migration on a copy and a weekly restore drill