setup
Install Era globally, once, for every repo — no per-repo era-code init required.
era-code setup is a global/user-scope installer. Run it a single time and every repository you open inherits the full Era baseline — agents, skills, commands, MCP servers, permissions, governance hooks, and the constitution plus the universal upstream directives — for both harnesses (OpenCode and Claude Code).
Per-repo era-code init is still available and remains optional. It layers project-specific directives on top of the global baseline; project config overrides global in both harnesses (see Global setup vs per-repo init).
Usage
era-code setup [options]
Options
| Option | Description |
|---|---|
--harness <harness> | Which harness to configure: claude | opencode | both (default: both) |
--remove | Remove the global Era setup (reverses exactly what the manifest recorded; leaves ~/.era/memory and the shared asset store in place) |
--no-happy | Skip the optional Happy (mobile control) onboarding step |
-q, --quiet | Suppress output (warnings still surface) |
Examples
Install for both harnesses (recommended)
era-code setup
Install for a single harness
era-code setup --harness claude
era-code setup --harness opencode
Remove the global setup
era-code setup --remove
Happy onboarding (optional)
When the Claude harness is configured (--harness both or claude) and setup runs interactively (a TTY, not --quiet), it offers to set up Happy — "Claude Code On the Go" — for mobile/remote control of Era-provisioned sessions. Answer no (the default) to skip, or pass --no-happy to suppress the prompt entirely.
On yes, each step is individually confirmed:
- Install — installs
happyglobally (npm i -g happy) if it isn't already on PATH. - Authenticate — runs
happy auth loginto pair with the mobile app. - Sandbox — hands off to Happy's own
happy sandbox configure. Happy already deny-reads~/.ssh,~/.aws,~/.gnupg; setup recommends also denying~/.config/gcloud,~/.era,~/.config/era-code, and**/.env. Note that filesystem reads are deny-list only — your file store stays readable except for denied paths; writes and network are allowlisted. - Shell shortcuts — writes an
# ERA:MANAGED:START (happy-claude)block into your shell rc (~/.zshrcand/or~/.bashrc, matching$SHELL), defining:claude()— overrides bareclaudeto launch through Happy with--yolo. Run Claude Code raw (with prompts) viacommand claude.era-claude()— Era-provisioned launch: routes through Happy when its daemon is running (~/.happy/daemon.state.jsonpid alive), otherwiseera-code claude --dangerously-skip-permissions.
[!WARNING] The shell shortcuts disable permission prompts (
--yolo=--dangerously-skip-permissions) — every tool call runs without confirmation, and a paired phone can trigger them remotely. Configure the sandbox (step 3) before relying on them.era-code setup --removestrips the managed rc block.
What It Does
- Ensures the asset store — version-gated: refreshes
~/.era/era-code/(agents/commands/skills/plugins, Claude tree, plugin SDK) only when the installed CLI version changed; a no-op otherwise. - Installs global governance memory — writes
~/.era/memory/(constitution, universal upstream directives, and the assembledDIRECTIVES.md). - Configures OpenCode globally (unless
--harness claude) — symlinks the global resource dirs into~/.config/opencode/and mergesopencode.jsonnon-destructively. - Configures Claude Code globally (unless
--harness opencode) — per-item symlinks into~/.claude/, merges~/.claude/settings.json, writes an Era-managed block in~/.claude/CLAUDE.md, and registers user-scope MCP servers via theclaudeCLI. - Records a manifest —
~/.era/global-setup-manifest.jsontracks every entry created/modified so--removecan subtract precisely what was added and never touch your content.
The configurator is idempotent (re-running produces identical state) and strictly non-destructive — it never clobbers user files in ~/.claude or ~/.config/opencode, and never hand-edits ~/.claude.json.
Where It Installs
| Path | Harness | Contents |
|---|---|---|
~/.era/memory/ | Both | constitution.md, the universal upstream directives/ pack, and the assembled DIRECTIVES.md |
~/.config/opencode/{agents,commands,skills,plugins,_shared} | OpenCode | Symlinks to the global store ~/.era/era-code/opencode/* |
~/.config/opencode/opencode.json | OpenCode | Merged instructions (absolute paths to the governance memory + _shared), mcp, and permission (sensitive-read denies); unknown user keys preserved |
~/.claude/{agents,commands,skills} | Claude Code | Per-item symlinks into the global Claude store (the dir is not symlinked, to preserve any user files alongside) |
~/.claude/era-shared | Claude Code | Dir symlink to the shared context files (Era owns this name) |
~/.claude/settings.json | Claude Code | Merged: union of deny globs (**/*.env, **/*.env.*, **/*.pem, **/*.key) plus governance hooks (PreToolUse → era-code hook governance, SessionStart → era-code hook session-start); existing user keys preserved |
~/.claude/CLAUDE.md | Claude Code | An Era-managed marker block with absolute @imports of the constitution, DIRECTIVES.md, and the shared context files; content outside the markers is yours |
| user-scope MCP | Claude Code | Registered via claude mcp add --scope user; skipped with a warning if the claude CLI is absent (OpenCode global MCP still covers them) |
[!NOTE] The OpenCode
agents/commands/skills/pluginslinks use plural names (the OpenCode global config convention) and point at the singular-named dirs in the global store (agent/command/skill/plugin).
Global setup vs per-repo init
The two installers layer; they are not alternatives.
era-code setupwrites the user-scope config layer + global governance memory. Both harnesses natively merge user + project config, so this baseline applies in every repo with no per-repo step.era-code initwrites a project.era/directory with project-specific directives. Both harnesses give project config precedence over global, so per-repo directives override the global baseline where they overlap.
In short: run setup once for the org-wide baseline; run init per repo only when a project needs its own directives.
Removal
era-code setup --remove reverses exactly what the manifest at ~/.era/global-setup-manifest.json recorded:
- Unlinks only the symlinks Era created (verified to still be symlinks pointing into the store).
- Removes only the user-scope Claude MCP servers Era registered.
- Subtracts only Era's deny patterns and hook entries from
~/.claude/settings.json, preserving user keys. - Strips the Era marker block from
~/.claude/CLAUDE.md, preserving user content. - Removes only Era's managed keys / MCP servers from
~/.config/opencode/opencode.json. - Strips the
# ERA:MANAGED:START (happy-claude)shell-shortcut block from~/.zshrc/~/.bashrcif present, preserving the rest of the file. (Happy itself, its auth, and its sandbox config are left in place — remove those withnpm rm -g happy/happy sandbox disable.)
The shared asset store (~/.era/era-code) and the global governance memory (~/.era/memory) are left in place — they are shared with era-code start/era-code claude and per-repo work.
Missing MCP credentials
MCP servers with no resolvable credential are skipped with a warning rather than registered in a broken state. To supply the missing tokens, run era-code mcp auth, then re-run era-code setup:
⚠ Missing credentials for: slack
Run `era-code mcp auth` to add them, then re-run `era-code setup`.
For Claude Code specifically, the user-scope MCP registration step is skipped entirely (with a warning) when the claude CLI is not on PATH — install Claude Code (npm install -g @anthropic-ai/claude-code) to enable it. OpenCode global MCP still covers those servers in the meantime.