claude-computer · reference
What's inside
A plain list of what you get when you create an instance from claude-computer: every package it installs, every service it talks to, where files go, what each script does, and what runs without being asked.
Each line is in the repo — Brewfile, setup-tools.sh,
vscode-extensions.txt, bin/, claude-global/, docs/. If the two ever disagree,
tools/check_inventory.py in the site repo fails and the page is wrong.
- 68packages
- 17services
- 5machines
- 37scripts
- 12commands
- 4hooks
- 9jobs
On this page 8 sections
What it installs#
Packages come in three Homebrew layers. Brewfile goes on every machine; Brewfile.dev adds the
build-machine tools; Brewfile.server is for headless Macs. Anything installed beyond these layers
belongs in that machine's file, or map-check reports drift.
Needed by the setup itself#
domt4/autoupdateHomebrew tapdailybrew autoupdatekeeps packages currentghGitHub CLIrepos, keys and PRs without a browseragefile encryptionone key per machine opens the secrets storesopsencrypted config filessecrets/secrets.yaml: names in clear, values notgitleakssecret scannerpre-commit backstop in every reporcloneobject-storage syncarchive, camera cold copy, encrypted resourcesmasMac App Store CLIinstalls Xcode on build machinesjqJSON processorevery hook parses its input with itcoreutilsGNU utilitiesgtimeout, used by the session-start and stop hooks
Claude uses these from its shell#
ripgreptext searchthe default way Claude searches; one config caps linesfdfiles by namereads.gitignoreand.ignore, likergast-grepstructural code searchmatches syntax, not text — skips comments and stringsyqYAML processorjqfor frontmatter and config filesshellcheckshell linterlint for every bash script, including Claude'sjustcommand runnerone name per project task:just --listtreedirectory treea directory's layout in one call
Languages and runtimes#
miseversion managerone manager for Python and Node versionsuvPython packages, scriptsuv run --scriptruns the Python inbin/pnpmJS packagesno npm, no yarn
For you at the terminal — Claude doesn't use these#
starshipprompta powerlevel10k-style line, from a fileherdragent workspacesevery Ghostty window shares one sessionzsh-autosuggestionszsh suggestionsfewer keystrokeszsh-syntax-highlightingzsh highlightingcatch a typo before you run itfzffuzzy finderinteractive picking in the shellzoxidesmartercdz <dir>; never aliased overcddirenvper-folder envloads a project's.envrcwhen youcdinlazygitgit TUIlg, for reviewing a messy tree by handbatcatwith highlightingreadable file output; never aliased overcatezamodernlsll; never aliased overlsgit-deltagit diff pagergit's pager for you; plain when pipedtlrctldr clientshort examples instead of man pages
None of these is aliased over a standard command. Claude Code copies shell aliases into its own
shell, where a model's ls -lt or cat -A would run a tool that reads those flags differently.
Ghostty opens every window, and the ⌥Space quick terminal, into one herdr session. Its sidebar shows each Claude Code session as working, blocked, done or idle; macOS tells you when one finishes or needs you, and ⌘J jumps to it. Ghostty's ⌘ shortcuts drive herdr's tabs and panes.
Ops and networking#
btopprocess monitorwhat is eating the machinetmuxterminal multiplexerlong jobs that outlive a windowwatchrepeat a commandwatching a job change somethingnaabuport scanneranswering "why is this port open"mtrtraceroute + pingdiagnosing a flaky link to a boxwgetfile downloaderfetching a file in a script
Media and documents#
ffmpegaudio and videotranscode, trim, extract audioimagemagickimage conversionresize and convert in scriptspandocdocument conversionmarkdown to anythingpopplerPDF toolstext and pages out of PDFsexiftoolmetadata readerthe camera brain finds photos by metadataocrmypdfOCR for PDFsscanned family documents become searchable
Apps#
14 apps and fonts
claude-codeClaude Codethe operator; installed first, listed for rebuildsghosttyterminalits config is a text file the brain can owntailscale-appprivate networkhow a manager machine reaches a headless boxgoogle-chromebrowserthe human's browser, never the headless onevisual-studio-codeeditorfor the times you read code yourselfobsidiannotesthe second brain is plain markdown in a repoclaudeClaude desktop appthe chat window beside the terminaltelegrammessagingwheretg-sendlandsiinamedia playerplaying what the camera brain ingestslibreofficeoffice suitesoffice --headlessconverts generated documentsmacparakeeton-device dictationtranscripts without anything leaving the Macfont-meslo-lg-nerd-fontmonospace fontthe terminal font, with the prompt's glyphsqlmarkdownQuick Look: markdownspacebar on a note shows the notesyntax-highlightQuick Look: sourcespacebar on code shows code
macparakeet is Apple-silicon only (macOS 14+); the Brewfile skips it on Intel, and the dictation
and transcript pipeline goes with it.
The dev-machine layer#
orbstackcontainers on macOSDocker for Python services and self-hostingcalibreebook librarybooks and comics inlibrary/cloudflare-wranglerCloudflare CLI, run aswranglerWorkers, D1, R2 and DNS from the terminalbiomeJS/TS lint and formatone tool instead of ESLint plus PrettierruffPython lint and formatthe Python half of the same rulepyrightPython typestype hints checked; Claude's Python LSPtypescript-language-serverTypeScript language serverClaude's TypeScript LSPmermaid-clidiagram renderermmdcfor quick diagramsccusageClaude Code usageseeing what all-day sessions costXcodeApple toolchain (viamas)iOS builds; needs an Apple ID in the App Store
darktable, for the camera brain, is an optional manual install: Homebrew disabled its cask because
the macOS build fails Gatekeeper, so /setup asks, and on a yes you download it from darktable.org
and choose Open Anyway.
claude-global/settings.json turns on the official pyright-lsp and typescript-lsp plugins, so
Claude navigates Python and TypeScript by symbol — definitions, references — instead of by text, and
sees type errors after each edit. The two servers above are what they talk to.
The server layer#
cloudflaredCloudflare Tunnelexposing a service without opening a port
orbstack is in this layer too, for Bugsink and other self-hosted containers.
VS Code extensions#
Installed from vscode-extensions.txt by setup-tools.sh. Extras on one machine go in that
machine's file.
17 extensions
anthropic.claude-codeClaude Code in VS Codethe same operator, in the editorms-vscode-remote.remote-sshremote editingediting on a headless boxeamodio.gitlensgit blame and historywho changed this line, and whenms-python.pythonPython supportone of the two languagesms-python.vscode-pylancePython language servercompletions and typescharliermarsh.ruffRuff in the editorsame linter as the command linebiomejs.biomeBiome in the editorsame formatter as the command lineredhat.vscode-yamlYAML supportconfig and CI filestamasfe.even-better-tomlTOML supportpyproject.toml,starship.tomltimonwong.shellcheckShellCheck in-editorbin/is bashyzhang.markdown-all-in-onemarkdown editingbrains and notes are markdowndavidanson.vscode-markdownlintmarkdown lintingkeeps the docs consistentmechatroner.rainbow-csvCSV viewerreading exports without a spreadsheetusernamehw.errorlensinline errorsproblems where they happeneditorconfig.editorconfigEditorConfigone indent rule across editorsstreetsidesoftware.code-spell-checkerspell checkthe docs are the product heregruntfuggly.todo-treeTODO indexfinding what you left behind
What Homebrew can't install#
setup-tools.sh handles the rest, in idempotent steps you can run one at a time with --only.
oh-my-zshthe zsh framework, keeping the linked~/.zshrcruntimesmise use --global [email protected] node@ltsplaywrightthe pinned Playwright CLI and its bundled Chromium, profiles 700agent-reachAgent Reach from a pinned commit, withyt-dlpandmcporter, and its Claude skillmacparakeetlinksmacparakeet-clifrom the app bundle ontoPATHvscodethe extensions aboveautoupdatethe dailybrew autoupdateagent (upgrade and cleanup)
Agent Reach covers the platforms the bin/ wrappers
don't: YouTube transcripts, GitHub, RSS, and social channels if you opt in. It installs upstream
tools and one skill that tells Claude which to call; agent-reach doctor says which channels work.
Only the channels that need no login are installed. One that needs a cookie or a key keeps it in
~/.agent-reach/config.yaml, outside the secrets store, so adding it is yours to do:
agent-reach configure, run yourself.
Also linked or applied by /setup, not installed: dotfiles/ (zshrc, zshenv, ripgreprc,
starship.toml, ghostty.config, herdr.toml, gitconfig, gitignore_global, editorconfig) and
macos-defaults.sh (keyboard repeat, Finder, Dock, hot corner, screenshots to
~/Pictures/Screenshots, ask for password on wake). ripgreprc caps each line rg prints at 200
bytes and changes nothing about what matches; zshenv points every shell at it, including the
non-interactive ones agents run, which never read zshrc. zshrc titles each terminal tab after
the client, project or product the shell is in, and a wt worktree as <name> ⎇ <branch>.
Services it uses#
Accounts come first, before you touch the machine, because every later step that needs a login stalls without one. Costs are only listed where the repo states them, and they were true at time of writing. A dash means the repo names nothing there.
Required6
Claude Max
required
Claude Code itself — the operator
Cost paid subscription
Could be replaced by nothing; this is Claude Code
GitHub
required
every repo, the SSH key, PRs, Actions
Homebrew
required
packages on every Mac
Cost free
Tailscale
requiredfor more than one machine
the tailnet a manager uses to reach a box
Could be replaced by a swap invited by CONTRIBUTING
Cloudflare R2
requiredto use those folders
archive, camera cold copy, encrypted resources
Cost cheap, no egress fees
Could be replaced by S3
Telegram bot
requiredfor notifications
tg-sendwhen a job ends;capturefrom your phoneCost free
Optional11
Cloudflare (Workers, D1, Pages, DNS)
optional
shipping projects (Next.js via OpenNext), DNS
Cost not stated; set a spend alert
Could be replaced by Vercel; Fly.io or Railway for Python
Tavily
optional
tavilyweb searchCould be replaced by
exa,jina,firecrawlExa
optional
exasemantic searchCould be replaced by
tavily,jinaFirecrawl
optional
firecrawlpage to markdown; feed full textCould be replaced by
jina, orbrowseJina Reader
optional
jinapage or search as markdownCost works keyless at a low rate limit
Could be replaced by
firecrawl,browseGoogle Cloud OAuth
optionaladded later
gcal,gmail,gdrive,gtasks,analyticsPostHog
optional
analytics, replay, flags, errors in projects
Cost free tier: 1M events, 5K recordings, 100K exceptions a month
Could be replaced by self-hosted Bugsink
Turso
optional
SQLite off Cloudflare, embedded replicas
Cost free plan: 100 databases, 5 GB
Could be replaced by Cloudflare D1, a plain file, Supabase
Resend
optional
transactional email from a project
Expo EAS
optional
mobile builds and submissions
Mac App Store (Apple ID)
optionalbuild machines
Xcode through
masCost free
Could be replaced by downloading Xcode yourself
MacParakeet transcribes on the machine; nothing leaves the Mac. There is no Dropbox, no Syncthing and
no iCloud Drive on working folders: every job they would do is already covered, and a second sync
engine brings its own idea of what "deleted" means. A folder of git repos is worse — two machines
writing the same .git through a two-way sync can corrupt it, and a deletion on one machine is a
deletion on all of them.
There is no secrets service. Every key above lives in secrets/secrets.yaml in your private
instance as <name>.<field> — names in clear, values encrypted with sops to an age key on each
manager machine and to a paper backup key. The bin/ wrappers decrypt one value at a time; Claude
never decrypts anything, and you type every value yourself with secrets set. docs/SECRETS.md
lists each one and how to get it. Losing r2-crypt.password means losing ~/resources in R2; it
cannot be recovered from the bucket. Website logins stay in your own password manager — Apple
Passwords is enough.
My fleet#
Five machines and a camera, in two kinds. A manager machine runs Claude Code and keeps a clone of the brain at
~/claude-computer; it writes its own docs/machines/<host>.md and nobody else's. A headless box
has no brain: a manager reaches it over Tailscale and SSH, and afterwards writes that box's file onto
it at /etc/claude-computer/machine.md, so the box can still say what it is if the repo goes stale.
Every one of my manager machines clones the same private repo — I called mine sys-admin. What makes
a machine itself isn't the repo name, it's the hostname: Claude reads scutil --get LocalHostName and
keeps docs/machines/<host>.md for it, and tags every commit [<host>]. So name your machines what
you want to see in that path — sudo scutil --set LocalHostName mini — and keep the clone at
~/claude-computer on every one of them, because the hooks and permission rules assume that path. See
docs/INSTALL.md § One repo for the whole fleet.
That's my fleet; yours will differ. A machine that is not in docs/FLEET.md is out of scope until
you add it — nothing is managed implicitly.
One more thing on the fleet that has no operating system:
Folder structure#
~/claude-computer/the fleet brain — repoclients/<name>/one private repo per client — brief/ is trackedprojects/active work — one repo per project (+ _scratch/, disposable)products/projects that graduated to production — one repo eachpersonal/finance, personal projects — one repo eachvault/Obsidian second brain — repoarchive/cold storage staging — pushed to object storage, then removedlibrary/camera (RAW workflow), books and comics (Calibre)resources/<person>/family key documents — encrypted two-way sync
Top-level folders are containers, not repos (except claude-computer and vault). Repos live
one level down; a folder there with no CLAUDE.md may group the repos of one thing — a product with
a site and an API.
A client folder is a repo of its own, so the client's documents in brief/ are versioned and
backed up like code, and never live on one machine only. Code built for that client is a separate
repo inside the client's folder, which the client repo ignores. new-client
<name> makes one; new-app <type> <name> --dir ~/clients/<client> adds the code.
Any folder that needs automation gets a CLAUDE.md — a brain — and a TASKS.md. Folders that just
hold files have no brain. The vault is laid out for cheap capture and for Claude's retrieval, not
for browsing — the second brain has its own section below.
The repo itself#
CLAUDE.mdthe fleet brain's operating instructionsinstall.shthe one-liner that puts the operator on a new Macbin/every script; each answers--helpand returns exit codeslib/common.shthecc_*helpers andEX_*exit codes every bash script sourceslib/cc.py,lib/google_auth.pythe same for theuv run --scriptscripts; Google OAuthlib/dashboard/,lib/docs/the page shells fordashboardanddocs-buildclaude-global/linked into~/.claude— globalCLAUDE.md, hooks, commandsclaude-global/settings.jsonthe template's permissions and hooks; you never edit itclaude-global/settings.overlay.jsonyours: rules added, rules removed with a reason, preferencessecrets/the sops-encrypted store, its example, and the backup key's.pubBrewfile,Brewfile.dev,Brewfile.serverpackages, layered by rolesetup-tools.shwhat Homebrew cannot installvscode-extensions.txtthe editor extension listdotfiles/shell, prompt, terminal, git — linked by/setupmacos-defaults.shdefaults writefor a new Mactemplates/scaffolds for apps, theirdocs/, and the other brains.githooks/pre-committhe gitleaks scan; enabled withgit config core.hooksPath .githookstests/what CI runs beyond ShellCheck, including aninstall.shdry rundocs/INSTALL.mdthe one-line install, and how to read it before you run itdocs/FIRST-PROMPT.mdthe prompt a new user pastesdocs/DEV-GUIDELINES.mdhow every project is builtdocs/SECRETS.mdevery secret the scripts expect, how to get each value, and the age keysdocs/FLEET.mdindex of machinesdocs/DECISIONS.mdappend-only decision log,[host] [date]taggeddocs/TEMPLATE-DECISIONS.mdwhy the template is built this waydocs/machines/one file per machine, written only by that machinedocs/diagrams/render.pythe hand-laid SVGs in the READMEUPSTREAMthe template's URL, for the fetch-only remote.template-versionthe template release this instance is on;template-pullupdates itCHANGELOG.mdwhat changed in each release, and the steps to move an instance across
The second brain#
Obsidian, over a git repo, with Claude doing the filing. Capture is free; filing, linking and
retrieval are Claude's job. The vault has two layers: notes/ and daily/ are yours, in your own
words; memory/ is Claude's graph of people, orgs, meetings, decisions, commitments, topics and
projects, built only from evidence in sources/, every fact a dated log line that cites its source.
vault/inbox/everything lands here — dictation, clips, phone and email, transcriptsdaily/one note per day, drafted from tasks — yoursnotes/flat. your own ideas, one per note — yourssources/evidence: transcripts, clips, emails, repo snapshots, confirmationsmemory/Claude's graph, every fact cited from sources/people/one note per person, with dated tiesorgs/companies, clients, communitiesmeetings/one note per meeting, by yeardecisions/what was decided, and what superseded itcommitments/who owes whom what, open until closedtopics/themes three or more notes shareprojects/one hub per repo, kept after the checkout is gone
maps/all tasks, weekly reviewsHome.mdopen commitments, recent meetings, people — live Dataview views_templates/one Templater template per type
Structure lives in properties, not folders. Every note has type and created, and each type its
own required properties. The schema is the vault's own CLAUDE.md, and
vault-lint checks every note in memory/ against it before anything lands. A
missing property is an error; a property the type doesn't define is a warning with a guess — a
commitment's dropped_on gets "did you mean done_on?" — and never fails the lint. Keys you add on
purpose go in the vault's .vault-lint.yaml.
notenotes/nothing; links to topics, people, projects, sourcesdailydaily/nothingpersonmemory/people/name;relationshipnow,tiesover time; on your own note,githubandgit_authorsorgmemory/orgs/namemeetingmemory/meetings/YYYY/date,attendees,transcriptdecisionmemory/decisions/date,status(made, superseded, reversed), sourcescommitmentmemory/commitments/from,to,status(open, done, dropped),made_intopicmemory/topics/nameprojectmemory/projects/status,reposourcesources/kind: transcript, clip, email, repo, confirmation …
How things get in#
Capture is one move; the route and what runs on it are Claude's problem.
CaptureRouteScript or command
- A thought, a to-dodictate into
inbox/quick.mdnone — the cheapest capture wins - A meetingrecord it in MacParakeet
transcripts-sync - A file, a URL, a podcast
macparakeet-cli transcribe … --no-historynone — it stays out of the database - A message, photo or voice notesend it to your Telegram bot
capture, every 5 minutes - An emaillabel it
vaultin Gmailcapture, every 5 minutes - A web pageObsidian Web Clipper, saving to
inbox/none - RSS and newsletters
sources/feeds/feeds.txtfeeds-sync, daily 06:00 - A GitHub repo
project-import <owner/repo>, or--cataloguefor all of thema snapshot insources/repos/, no clone
What Claude does with it#
/transcripts— each recording becomes a meeting note, matched to its calendar event withgcal at: five summary lines, what was discussed, decided and left open; the people and orgs linked or created; decisions and commitments as notes of their own; action items routed to the brain that owns them; the raw transcript filed insources/./inbox— transcripts first, then every capture: your own thinking intonotes/, material from elsewhere intosources/, people and decisions pulled out of both.commitments— lists what is owed, yours first;commitments briefpicks what is overdue or due this week and who you met yesterday; and it closes or reopens one with your word as the evidence, filed as a dated confirmation./today— the daily note, drafted from every brain's tasks and fromcommitments briefrather than the calendar: Now, Commitments, Met yesterday, Due this week. The night shift's## Overnightstays at the top./review— the weekly pass: it empties## Unassigned, hands each new Google Task to a brain, proposes done, dropped or a new date for every commitment past due, and a status for the hubs of projects whose checkout is gone.
The night shift#
vault-nightly runs at 04:30 on the vault's home machine and does the filing with
nobody watching: it runs /inbox with claude -p over the day's transcripts and captures, and
writes a few project hubs from fresh repo snapshots. It is fenced. Claude works in a git worktree of
the vault, never the vault itself, with --permission-mode dontAsk and a short list of allowed
tools, so anything else is refused rather than asked. Tasks for other brains go to a file the script
validates before it writes them. The result merges only past a gate — vault-lint clean, nothing
deleted outside inbox/, nothing uncommitted — and a failed run leaves the vault and its inbox
exactly as they were, and says so on Telegram. What it did is under ## Overnight in the next
daily note, every item linked and every commit revertible.
Rules that keep it sane#
- Every fact in
memory/cites evidence. No source, no fact. A changed fact gets a new dated log line; nothing true at the time is overwritten. - Your words are never rewritten. In
notes/anddaily/, Claude adds properties and links; the text stays yours. If you edit amemory/note, your edit wins over Claude's next pass. - Tasks live with their brain; the vault gets copies.
tasks-syncwrites read-only copies intomaps/tasks.mdand a block in each hub inmemory/projects/. Ticking a box in Obsidian changes nothing — you change a task by telling the brain that owns it. - Generated and authored content never mix. Scripts write only between their markers or in
notes marked
generated. Everything else is yours, and no script overwrites it. - A hub is keyed by its repo, not a checkout. When a checkout goes, its hub's task block is
frozen and
/reviewdecides whether the project is done, archived or abandoned. ## Unassignedhas an exit. Action items no brain owns sit at the top of the task map; every weekly review gives each one an owner or drops it to## Later; once there are more than ten,tasks-syncsends one Telegram alert a day.- Nothing leaves the Mac to become text. MacParakeet transcribes on the machine, voice notes from your phone included.
Why not PARA#
PARA was designed for a human doing the filing. It asked me to decide where a note belonged at the moment I had the least context to decide. With Claude filing, the right structure is an inbox, a flat notes folder, a graph Claude keeps and properties — and the discipline moves from "file correctly" to "capture everything."
What it needs#
The obsidian cask, and macparakeet (Apple silicon, macOS 14+ — the Brewfile skips it on Intel,
and without it there is no dictation or transcript pipeline). vault-setup creates
the vault and installs Obsidian Git, Dataview and Templater (third-party code; versions recorded), and
on a second machine restores the plugin code a fresh clone is missing. The Web Clipper is a browser
extension: install it by hand and point it at inbox/. capture needs a Telegram bot and, for
email, the Google sign-in; run it on one machine only.
Every script#
Everything in bin/ is on the PATH, answers --help, and returns an exit code rather than prose:
0 ok, 1 failed, 2 usage, 3 a tool is missing, 4 no age key or this machine can't open the
secrets store, 5 missing config or secret.
You run it8
analytics#set up GA4 and Tag Manager from a project'sanalytics.yaml; funnels, reportsyou or Claude;publishonly when you sayarchive-pull#search the R2 archive index and restore a file or folderyou, or/retrievearchive-push#move a folder from~/archiveto R2, verify, rebuildINDEX.mdyou, or/archivecamera-ingest#copy a memory card into the camera library, verified, then push to R2you, when a card goes inschedule#install, remove and list the fleet's launchd jobsyou, during/setupsecrets#the sops + age store: status, set, admit a machine, run a project with keysyou; Claude only for status and checkstemplate-pull#apply a template release file by file, three-way;--dry-runfirstyou, when a release is outwt#create a git worktree for a branch and open a session in ityou
Claude, mid-session12
browse#load a page in Playwright's Chromium: markdown, screenshot or PDFClaude,feeds-synccommitments#open commitments, yours first;brieffor the day; close or reopen one on your wordClaude,vault-nightly, youdashboard#a live progress page for a long task: tasks, questions, deliverables, blockersClaude, before any task of more than five stepsexa#semantic web search, markdown outClaudefirecrawl#scrape a URL to clean markdownClaude,feeds-syncgcal#today, a given day, what overlapped a time, search and add — every calendarClaude,/transcriptsgdrive#search, download, upload and share Google Drive filesClaudegmail#search, read, draft, send and label Gmail, save attachments;sendasks firstClaude,feeds-syncjina#read a URL as markdown, or search, via Jina ReaderClaudeproject-import#snapshot a GitHub repo into the vault throughgh api, no cloneClaude,vault-nightly, youtavily#web search, markdown outClaudetg-send#send one plain-text Telegram line, prefixed with the machine namehooks,map-check, Claude
A slash command8
gtasks#Google Tasks: list, hand a task to a brain, mark it done/review, Claudehttps-check#check that a public domain redirectshttp://tohttps://;--fixon Cloudflare/graduate,/review, younew-app#scaffold a project, init git, create a private GitHub repo/new-appnew-client#make~/clients/<name>a private repo, new or adopted/new-clientsecurity-check#check FileVault, firewall, sshd, browse profiles, Tailscale, private reposmap-check,/setupsettings-build#build~/.claude/settings.jsonfrom the template's base and your overlay/setup,map-check, youvault-lint#check vault notes against the vault's schema; warn on an unknown property/transcripts,/inbox,vault-nightlyvault-setup#create~/vaultfrom the template and install its three Obsidian plugins/setup, or you
A hook2
A schedule7
capture#your Telegram messages and Gmail'svaultlabel into the vault inboxschedule, every 5 minutes, on one machinefeeds-sync#build today's reading digest from RSS and newsletter emailschedule, daily 06:00library-push#copy~/library/booksand~/library/comicsto R2, verified, never deletingschedule weekly, or youmap-check#diff packages, extensions, launchd jobs, ports and settings against the mapschedule daily 09:00,/setup,/reviewresources-sync#two-way encrypted sync of~/resourceswith R2schedule, hourlytranscripts-sync#export completed MacParakeet transcriptions into the vault inboxlaunchd watch on the database, SessionStart hookvault-nightly#the night shift:/inboxunattended, landed only past thevault-lintgateschedule, daily 04:30
The process#
Four forms, one rule: if it can be a script, it is a script. A slash command is for a step that needs judgment; it orchestrates scripts rather than reimplementing them. A hook is for what must happen every time without asking. A scheduled job is for what must happen with no session open.
Slash commands#
Linked into ~/.claude/commands/ from claude-global/commands/.
Hooks#
These run every session, without asking. That is the point: the syncing does not depend on discipline.
Permissions come from the same folder, but ~/.claude/settings.json is built, not linked.
settings-build writes it from the template's claude-global/settings.json and
your own claude-global/settings.overlay.json, so your rules survive every release instead of
conflicting with it. The base sets defaultMode: auto and puts git push, rm, brew uninstall,
sudo, every rclone verb that writes, configures or serves (and rclone -*, for a flag before
the verb), archive-push, resources-sync, library-push, new-app, new-client,
agent-reach configure and every secrets command that writes (init, set, import-env,
admit, revoke, push, exec) on the ask list. It puts force-push, every sops command
that prints or edits a value, age -d, secrets env, the age key itself, the Keychain commands,
.env files, SSH private keys, rclone.conf, the browse profiles and Agent Reach's config.yaml
on the deny list. Read-only work is allowed outright: rclone listings (lsf, lsjson, lsl,
size, check), vault-lint, gmail search and get, launchctl list, defaults read. Ask
prompts even in auto mode; deny blocks in every mode. Neither is a sandbox.
The overlay adds rules, sets preferences, and removes a template rule only with a written why; it
cannot remove a deny rule or an ask that guards secrets. It is committed with the rest of your
instance, and CI checks that it builds on the template's base. When Claude Code changes
~/.claude/settings.json itself — "don't ask again", /model, /config — map-check reports the
drift, settings-build --adopt keeps it in the overlay and --force drops it.
hooks/rm-guard.py ships as an optional PreToolUse hook: wired in through the overlay, with rm
taken off the ask list, it lets a plain rm inside /tmp or $TMPDIR run unprompted and asks
about every other rm. The base also sets PAGER=cat and NO_COLOR=1 for every command Claude
runs, so nothing pages and no colour codes reach the context.
Scheduled jobs#
Installed as launchd user agents by bin/schedule, prefixed local.claude-computer., logging to
~/Library/Logs/claude-computer/. map-check treats an unrecorded job as drift.
Through the day4
daily 04:30
vault-nightly#the night shift: files transcripts and captures into the memory graph
daily 06:00
feeds-sync#writes today's reading digest into the vault
daily 06:30
daily-note#drafts today's note with
claude -p, fenced to~/vaultand a short tool listdaily 09:00
map-check#drift report; sends Telegram only when there is drift
Every few minutes1
every 5 minutes, on one machine
capture#your Telegram messages and
vault-labelled email into the vault inbox
Every hour2
Once a week1
weekly, Sunday 03:00
library-push#cold copy of the Calibre libraries to R2;
rclone copy, neversync
When something changes1
when MacParakeet's database changes
transcripts-sync#exports finished transcriptions to the vault inbox
library-push is the one job most machines have nothing to do for: it skips a folder that isn't
there rather than failing, so it is harmless on a machine with no Calibre library.
daily-note and vault-nightly are the two jobs that run Claude with nobody to answer a prompt,
so each is fenced. daily-note has ~/vault as its working directory and the only tree it can
edit, and --allowedTools is Read, Edit, Write, Glob, Grep, the read-only
commitments brief and git status/add/commit.
vault-nightly works in a throwaway worktree of the vault with --permission-mode dontAsk, and
lands nothing unless vault-lint passes (the night shift). Everything else is
refused outright.
capture runs on one machine only: Telegram hands each message to whichever machine asks first.
A normal day#
04:30
vault-nightlyfiles yesterday's transcripts and captures into the memory graph, in a worktree, and merges only ifvault-lintpasses.06:00
feeds-syncwrites the reading digest intovault/sources/feeds/.06:30
daily-notedraftsvault/daily/<today>.mdfrom the task picture, unattended, under the night shift's## Overnight.You open a session.
TheSessionStarthook pulls the fleet repo, reports whether the secrets store can be opened, exports any new transcript, and refreshes the vault's task copies./todayreview the draft, add what you know, and every task you mention goes to theTASKS.mdof the brain that owns it, not into the note.Work.
Claude reads the machine file first, uses thebin/wrappers instead of MCP servers, and asks before anything destructive, credential-touching or billable. A long task gets adashboardfirst; questions go on it with a proposed default, and the work carries on with whatever doesn't depend on the answer.09:00
map-checkruns; if the machine and the map disagree, Telegram says so, and fixing it is this session's job.Through the day
a thought sent to your Telegram bot, or an email labelledvault, is in the inbox within five minutes. After a meeting,transcripts-syncdrops the transcript there too;/transcriptswrites the meeting note, links the people and routes every action item to an owning brain — or the night shift does it at 04:30.Every turn ends
with theStophook committing and pushingdocs/, so the next machine starts from a true picture. Once a week,/reviewempties## Unassigned.
Getting it#
The template is on GitHub: narendranag/claude-computer. You need a Mac, a GitHub account and a Claude Max subscription; the quick start is the short version. One line, pasted into Terminal:
/bin/bash -c "$(curl -fsSL https://claude-computer.com/install.sh)"
It asks one question — what your private repo should be called — then installs whatever you're
missing and hands over. Want a different name, the same on every machine? Pass it explicitly:
-- --name sys-admin --dir ~/claude-computer. docs/INSTALL.md covers the installer end to end —
flags, exit codes, and the by-hand equivalent — and how to read it before you run it. What the setup
does not protect against is written down too — the
Trust section of the README is the part to
read closely.
Staying current is one script. An instance made with "Use this template" shares no history with the
template, so git merge refuses; template-pull lists the releases, and
template-pull <tag> applies the template's own diff from the release you are on
(.template-version) to the one you name, deciding each file on its own: a file you never
touched takes the template's version, one you both changed merges three-way, and one that can't be
merged is left as yours and listed with the command that takes the template's. The rest of the
release applies either way. --dry-run reports the same lists from a throwaway worktree. It
commits nothing, and
ends with the CHANGELOG for those releases — read each "Migrating from" section, because some steps
happen on every machine.