Skip to main content

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

OptionDescription
--harness <harness>Which harness to configure: claude | opencode | both (default: both)
--removeRemove the global Era setup (reverses exactly what the manifest recorded; leaves ~/.era/memory and the shared asset store in place)
--no-happySkip the optional Happy (mobile control) onboarding step
-q, --quietSuppress output (warnings still surface)

Examples

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:

  1. Install — installs happy globally (npm i -g happy) if it isn't already on PATH.
  2. Authenticate — runs happy auth login to pair with the mobile app.
  3. 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.
  4. Shell shortcuts — writes an # ERA:MANAGED:START (happy-claude) block into your shell rc (~/.zshrc and/or ~/.bashrc, matching $SHELL), defining:
    • claude() — overrides bare claude to launch through Happy with --yolo. Run Claude Code raw (with prompts) via command claude.
    • era-claude() — Era-provisioned launch: routes through Happy when its daemon is running (~/.happy/daemon.state.json pid alive), otherwise era-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 --remove strips the managed rc block.

What It Does

  1. 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.
  2. Installs global governance memory — writes ~/.era/memory/ (constitution, universal upstream directives, and the assembled DIRECTIVES.md).
  3. Configures OpenCode globally (unless --harness claude) — symlinks the global resource dirs into ~/.config/opencode/ and merges opencode.json non-destructively.
  4. 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 the claude CLI.
  5. Records a manifest~/.era/global-setup-manifest.json tracks every entry created/modified so --remove can 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

PathHarnessContents
~/.era/memory/Bothconstitution.md, the universal upstream directives/ pack, and the assembled DIRECTIVES.md
~/.config/opencode/{agents,commands,skills,plugins,_shared}OpenCodeSymlinks to the global store ~/.era/era-code/opencode/*
~/.config/opencode/opencode.jsonOpenCodeMerged instructions (absolute paths to the governance memory + _shared), mcp, and permission (sensitive-read denies); unknown user keys preserved
~/.claude/{agents,commands,skills}Claude CodePer-item symlinks into the global Claude store (the dir is not symlinked, to preserve any user files alongside)
~/.claude/era-sharedClaude CodeDir symlink to the shared context files (Era owns this name)
~/.claude/settings.jsonClaude CodeMerged: union of deny globs (**/*.env, **/*.env.*, **/*.pem, **/*.key) plus governance hooks (PreToolUseera-code hook governance, SessionStartera-code hook session-start); existing user keys preserved
~/.claude/CLAUDE.mdClaude CodeAn 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 MCPClaude CodeRegistered 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/plugins links 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 setup writes 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 init writes 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 / ~/.bashrc if present, preserving the rest of the file. (Happy itself, its auth, and its sandbox config are left in place — remove those with npm 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.