Skip to content
Apothem
CLI reference

install

CLI reference for the apothem install command.

Install a harness adapter configuration from the shared profile.

Synopsis

apothem install --harness NAME|all [--profile PATH] [--dry-run]
                 [--clean|--fresh] [--yes] [--project PATH]
                 [--quiet|-q] [--verbose|-v]
                 [--format plain|json] [--json] [--no-color]

Loads and validates the shared profile, selects a named adapter or the registry-wide all set, validates the materialization plan, and writes harness-native configuration plus support cohorts. Project-scope adapters require --project PATH.

The continuous-form alias apothem installing (also accepted as apothem Installing) resolves to the same handler.

First run without a profile

When --profile is omitted and no profile exists at the default path (~/.config/apothem/profile.yaml), install writes the starter profile there first, prints Created a starter profile at <path>, and continues. The starter profile carries placeholder identity fields, so the install also prints the placeholder-identity note; personalize the profile, then run update to apply it. Under --json the creation is reported as a warnings entry with "operation": "profile_created".

  • --dry-run never writes the profile: the preview uses the starter profile in memory and reports "operation": "profile_scaffold_preview".
  • An explicit --profile PATH that does not exist is never created; the command exits 1 with profile.not_found.

Blast-radius preview

install --harness all fans out into mixed scopes: project-scope adapters write under the supplied --project root, while user-scope adapters write under your home directory — outside that root. Before the install writes any file, the command prints the concrete targets grouped under two headings: those inside the project root and those under your home directory. A third heading lists the shared folders in your home directory that the project-scope adapters write, outside --project: the skills folder and ~/.config/apothem/ (see Folders in your home directory). The one exception is --clean: its clean-slate step runs before this preview and writes a backup and removes prior targets, as described below.

When the selection writes outside the project root, whether to a home-rooted adapter's folder or to a shared folder, an interactive confirmation guards the home-rooted writes. --yes, a non-interactive shell (no TTY), --dry-run, and --format json each proceed without prompting. Only --dry-run writes nothing; --format json skips the preview and the confirmation prompt but still performs the writes. Declining the home-directory prompt aborts before the install writes. With --clean, the clean-slate step runs first under its own per-target confirmation: it writes a backup under ~/.apothem/backups and removes the targets it confirms. Those removals and the backup stay in place when the install prompt is declined.

Folders in your home directory

Seven project-scope adapters write Apothem's skills, and the rules and templates the skills cite, to folders in your user home:

cursor, github-copilot, windsurf, zed  ->  ~/.agents/skills/ (codex writes it too)
codebuddy                               ->  ~/.codebuddy/skills/
kiro                                    ->  ~/.kiro/skills/
trae                                    ->  ~/.trae/skills/
all seven                               ->  ~/.config/apothem/rules/ and templates/ (codex uses them too)
  • --project selects the rules file and the project the install belongs to. It does not change where the skills go: an install with --project A and one with --project B write the same folders.
  • Every install that names a folder writes the same files. A second install finds them and reports unchanged, and the order you install in does not matter.
  • The home folders are written before anything in the project. If a write there fails, the adapter's install stops with the error and the project is unchanged. The error names the path in the way, for example a file called ~/.agents where the folder belongs.
  • Each skill folder is written to a hidden .<name>.apothem-staging folder beside it and renamed into place when complete, so a failed or interrupted write never leaves a half-written skill folder under its final name. Run the install again to finish; it replaces a leftover staging folder.
  • A symbolic link at or above one of these folders, as dotfile managers create for ~/.config or ~/.agents, is followed when it leads to somewhere inside your home directory. A link that leaves your home directory stops the install with target escapes the allowed materialization root, and so does a link inside a skill folder.
  • The install adds no skill or rule file to your repository. The project gets the adapter's rules file, plus the .apothem/ data folder every project install creates.
  • A skill folder that has an Apothem skill's name and that Apothem did not write is skipped. The install prints a Warning: line and the --format json envelope carries a warnings entry with "outcome": "warning" and "operation": "skill_conflict" that names the folder. Rename or move the folder, then run update.
  • Every such install, update, and dry run prints a Note: that names the folders it writes outside --project. In the JSON envelope it is a warnings entry with "operation": "user_level_write" and a paths list.

Capability notes

Each adapter projects only the capabilities its harness supports natively; capabilities with no native surface are reported, not silently dropped. In plain mode this is a single grouped note per harness (for example Note: <harness> - 9 capabilities not projected; pass --verbose for detail); under --verbose each capability prints its own rationale line. Any other adapter warning prints on its own Warning: line in plain mode too, for example the Zed warning that names an instruction file the new .rules hides. The --format json envelope always carries the full warnings array regardless of verbosity.

Install and update also print advisories as Note: lines. An advisory never changes what the install writes. When an install writes a shared root, a path other tools also load (for example the skills folder ~/.agents/skills/), the note names those tools, and puts a tool that loads the path only under a condition in parentheses, for example Open-Claw (only under its default state directory). An install that writes a folder other installs write too (the holder role) says the folder stays until the last Apothem install that uses it is uninstalled, and names the installs that use it now. When an install targets a tool that already loads Apothem content from another install's shared root, the note names the install that placed it: the registered owner while it still uses the folder, otherwise the oldest install that does. In the --format json envelope each advisory is a warnings entry with "outcome": "advisory" and "operation": "shared_root"; its role is owner, holder, or reader, holders lists the installs using the folder, and owner_of_record names the owner of record.

An install that registers hooks also prints notes about the hook file. A hook_review advisory names the step the tool needs before it runs the hooks (a restart and a review, or trusting the workspace), or the hazard of a hook file that a repository commits and that names this machine's interpreter. A hook_import advisory appears for a tool that also runs the hooks in Claude Code's settings files, such as those the Apothem install for Claude Code writes, and names the tool's own switch for turning that import off and what the switch also stops. Each is a warnings entry with "outcome": "advisory", the harness, the path of the hook file and a message.

A hook command holds the project path and the interpreter path inside double quotes, which sh, Git Bash and PowerShell each read. A path that contains $, a backtick, a double quote or a backslash would make the command run a different file, so the install (and --dry-run) stops with an error that names the path and writes nothing; move or rename the project and run it again. A space or an apostrophe in a path is fine.

The profile's MCP servers get three advisories, each naming the profile field:

OperationConditionFix
mcp_deprecated_transporttransport: sse (the MCP specification deprecates HTTP+SSE)Use streamable-http when the server supports it.
mcp_plain_httpan http:// URL to a host that is not loopbackUse an https:// URL.
mcp_literal_credentiala headers or env value shaped like a token (ghp_, gho_, ghu_, ghs_, ghr_, github_pat_, sk-, xoxa-, xoxb-, xoxo-, xoxp-, xoxr-, xoxs-, or Bearer with a long token)Keep the secret in an environment variable and write ${GITHUB_TOKEN}-style references.

The credential advisory never prints the value it found. A value that contains a ${...} reference is never flagged.

Operator configs with comments

Some harness configs are files you also edit, such as settings.json, opencode.json (which may be JSONC), openclaw.json (JSON5), and config.yaml. Install merges its keys into these files and keeps every key you added.

A merge rewrites the file as plain JSON or YAML, which would drop comments, trailing commas, and JSON5 syntax. So:

  • When the merge would not change any value (for example, you already added Apothem's keys yourself), the file is left byte-for-byte as it is.
  • When the merge must change a value in a file that carries comments or JSON5 syntax, or in a file that does not parse at all, install writes nothing for that harness and exits 1 with the error code config.unparseable. The fix field names the keys install would add, so you can convert the file to plain JSON or YAML, or add those keys by hand and re-run.
  • When a key install fills with a mapping or a list (for example skills.external_dirs in config.yaml) holds a scalar value, or the other container shape, in your file, install writes nothing for that harness and exits 1 with the same error code, because filling the key would discard your value. The error names the key; change it to the shape it names, or remove it, and re-run. A key you left empty (skills: with nothing under it) is filled.

Options

OptionDescription
--harness NAMEHarness adapter to install, or all for the registry-wide set (required). With all, harnesses listed in the profile's exclude_harnesses are skipped, but a harness named explicitly is installed even when listed. Run apothem harnesses list for registered names.
--profile PATHPath to shared profile YAML. Defaults to ~/.config/apothem/profile.yaml.
--dry-runPreview install without writing files.
--clean, --freshOpt-in clean slate: back up and remove the prior per-harness install state before installing.
--yesSkip per-target confirmation during a clean-slate removal (required for non-interactive --clean runs).
--project PATHProject root for project-scope harnesses.
--quiet, -qSuppress informational output; only errors are emitted.
--verbose, -vPrint each non-projected capability's rationale instead of the grouped per-harness note.
--format plain|jsonOutput format (default: plain).
--jsonShorthand for --format json.
--no-colorDisable ANSI color codes in output.
-h, --helpShow help and exit.

JSON output

When --json (or --format json) is supplied, a single JSON document is written to stdout:

{
  "schema_version": 1,
  "status": "success",
  "command": "install",
  "action": "installed",
  "harness": "claude-code",
  "profile_path": "C:\\Users\\Example\\.config\\apothem\\profile.yaml",
  "project": null,
  "files_written": ["C:\\Users\\Example\\.claude\\settings.json"],
  "results": [],
  "warnings": [],
  "error": null,
  "output_path": "C:\\Users\\Example\\.claude\\settings.json"
}

For --dry-run, nothing is written and results lists every path the install would write, each with the outcome it would have (created, updated or unchanged) and, for a file you also edit, the unified diff in detail.diff — the same plan apothem diff shows:

{
  "schema_version": 1,
  "status": "dry_run",
  "command": "install",
  "action": "dry_run",
  "harness": "claude-code",
  "files_written": [],
  "results": [
    {
      "harness": "claude-code",
      "outcome": "created",
      "operation": "write_text",
      "path": "C:\\Users\\Example\\.claude\\settings.json",
      "message": "dry run: no filesystem changes made"
    }
  ],
  "warnings": [],
  "error": null
}

When --clean is supplied, the envelope additionally carries a clean object describing the removal phase — the per-target disposition list, whether the run was a preview, and the timestamped backup directory (null in a dry run):

{
  "clean": {
    "dry_run": true,
    "backup_dir": null,
    "targets": [
      {
        "path": "C:\\Users\\Example\\.claude",
        "present": true,
        "removed": false,
        "skipped_reason": null
      }
    ]
  }
}

A clean dry run previews both phases in one document: the removal preview under clean and the fresh-write preview under results.

Expected validation errors use the same envelope and include an error object:

{
  "schema_version": 1,
  "status": "error",
  "command": "install",
  "harness": "all",
  "files_written": [],
  "error": {
    "code": "project.required",
    "field": "project",
    "reason": "project-scope harnesses require --project: cursor, gemini-cli, github-copilot, kimi-code, windsurf, codebuddy, kiro, trae, zed, glm.",
    "fix": "Pass --project PATH or select only user-scope harnesses."
  }
}

Examples

apothem install --harness claude-code
apothem install --harness claude-code --dry-run
apothem install --harness cursor --project . --profile ~/profile.yaml --json
apothem install --harness all --project . --dry-run --json
apothem installing --harness claude-code   # continuous-form alias
apothem Installing --harness claude-code   # capitalized variant

Exit codes

CodeMeaning
0Adapter installed successfully or dry-run planned cleanly
1Expected validation, profile, harness, project, or adapter error
2Partial batch materialization after at least one write
64Usage error: an unknown option or command, or a missing or invalid option value. Under --json the error is a JSON envelope with code cli.usage.

See also

  • apothem installing — continuous-form alias for this command (documented here; the CLI accepts both forms)
  • apothem update — re-apply current profile to a harness
  • apothem verify — confirm adapter is live
  • Getting Started — full installation guide

On this page