Install
A node is a daemon, a worker beside it, and a directory of its own, ~/.pac.
Download it, open it, answer three questions. It carries Node, npm and pi.
npm install -g @projectpac/cli, then pac onboard. The install script does both.
Paste one prompt into Claude Code or Codex. It installs the node and wires itself to it.
The constellation on your machine, for changing PAC rather than running it.
The app
v0.6.0 is a pre-release; releases has every build. The Mac build is signed and notarized, and updates itself from the zip beside the dmg. The .deb installs with sudo apt install ./PAC-0.6.0-amd64.deb.
Pick what you use for models, and test it
Anthropic is the claude on this machine. OpenAI and Other go through pi, signed in to your own account; the app stores no credential. Test it runs one turn, and Continue stays locked until it answers.
The terminal
Install the cli
Needs Node 24.0 or newer, npm or pnpm, and git.
install.sh is the npm line with the checks in front, and it runs the next step for you. pnpm needs --allow-build, because pnpm 10 stopped running a dependency's install script unless it is named, and without it the SQLite binding is never built.
Run onboarding
pac onboardIt asks what you use for models: Anthropic is the claude on this machine, OpenAI and Other run pi signed in to your own provider. Then whether to join the network, and whether to capture. With no terminal to answer on, every answer is a flag:
pac onboard --non-interactive --join https://node-directory.projectpac.netCheck it
pac status # what is running, and where
pac health # identity, plugins, liveness
pac ui # the same node, in a browser~/.pac/pac.log is the daemon's own account when something is wrong.
Connect your agent
claude mcp add pac -- npx -y @projectpac/mcpIt finds the node through PAC_HOME and reads the token there, never through the agent (mcp/README.md).
Underneath, onboarding shows the commands it runs: pac setup --command <cmd> makes what a node is, and pac start, pac join <url> and pac capture <ids> are requests to a node already answering, so each stands alone later. INSTALL.md is the reference.
Your agent
Paste this into Claude Code, Codex, or anything else that runs commands:
Read https://raw.githubusercontent.com/project-pac/pac-ux/main/INSTALL.md,
install and start a pac node joined to https://node-directory.projectpac.net, and
configure the pac MCP server for this agent if supported.
The document has it set the node up on the account you already have with whoever runs it (--harness anthropic, openai or other), ask before anything that writes, and add the MCP server above. What your agent can then do is what you can: holding the token is the whole of the permission.
What you have now
| what | where it comes from |
|---|---|
| the meta flow | joining installs the set in defaults.json: the iroh transport, the directory adapter, records, results, sources, negotiation, jc-box-run, artifacts-git, packages-npm, operation-tsc, operation-llm, operation-jc-box, and @projectpac/flow-meta. Some fifteen installs over npm. pac intent "...", and this node's agent and a peer's write the flow, install it on both, and run it (how a draft is gated) |
| the directory | https://node-directory.projectpac.net: presence and advertisements go there, and peers come from it. Presence is a 5-minute TTL (presenceTtlMs), so a stopped node stops being found. --join <url> or the app's PAC_DIRECTORY name another; https or loopback only |
| the plugin list | https://plugin-registry.projectpac.net, what the app's Plugins tab shows: curl -s https://plugin-registry.projectpac.net/plugins |
| the box | jc-tee-vm in dstack mode: a confidential VM on Intel TDX, hosted on Phala Cloud. Its endpoint and measurement pins (box.expectedMrtd, box.expectedRtmr3) live in defaults.json and change on redeploy, and the node checks them through RA-TLS on every session. box.egress (openrouter.ai, api.pinference.ai) is every host a program in it may reach. PAC_BOX=<https url> at pac join names another |
A node that said --no-join has none of this.
Add sources
A joined node offers a peer nothing until you add sources, and a peer sees names and a sentence each, never contents. The meta flow stakes five kinds, its sources config: skills, webExports, models, conversationNotes, agentHistory. Each plugin keeps its material under ~/.pac/data/<id>/.
Let it read what you have already done
pac capture agent-history,conversation-notes # or yes at onboarding
pac api POST /flows/agent-history/profile # a model reads ~/.claude; a pass on your own modelintents comes with either capture: what you want done, extracted when the material moves and handed to the meta flow itself. Conversation notes need the daily-profile skill from its README running inside Claude, writing one note per run into ~/.pac/data/conversation-notes/notes/.
Exported data
cp spotify_songs.json ~/.pac/data/source-web-exports/
pac plugins add --package @projectpac/source-web-exports --config exports.jsonOne row per file: name, file, note, and shape, which is required, because two agents planning over data neither will see have nothing else.
Model access
pac plugins add --package @projectpac/source-llm --config models.jsonRows of name, host, model, key, where the key is a file at ~/.pac/data/source-llm/keys/<key>. A peer is shown the host, never the key.
In the app, the Plugins tab lists the same sources, and each card's config box takes the same rows.
From source
For changing PAC rather than running it. Get the constellation as the repositories page says, then in pac-ux:
node cli/src/main.tsispacfrom the checkout. It spawns the daemon and worker from the pac-node checkout beside it (cli/src/lifecycle.ts), and installs plugins from npm unlesspac setup --package-sourcenames the checkouts source. Thenode-setup-atrecipe in the justfile is the worked example.just dev-first-runis the app's wizard on the checkouts,just try-terminalthe install script against loopback services,just dev-twotwo nodes, two windows and a mock box. All run a directory and a registry on this machine, into a throwaway home.- The app:
pnpm packageindesktop/vendors the interpreter, stages a node, builds, and packs it unsigned.node scripts/stage.ts --from <dir>carries the checkout instead (desktop/README.md).