> ## Documentation Index
> Fetch the complete documentation index at: https://arkor-92aeef0e-eng-615.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# arkor init

> Scaffold an Arkor project in the current directory.

# `arkor init`

Scaffolds `src/arkor/index.ts`, `src/arkor/trainer.ts`, `arkor.config.ts`, and a starter `package.json` in the **current directory**. Use this when you want to add Arkor to an existing repo (the [Quickstart scaffolding flow](/quickstart#1-scaffold-a-project) runs the same scaffolder one directory up).

## Synopsis

```
arkor init [options]
```

<CodeGroup>
  ```bash pnpm theme={null}
  pnpm arkor init
  ```

  ```bash npm theme={null}
  npm arkor init
  ```

  ```bash yarn theme={null}
  yarn arkor init
  ```

  ```bash yarn-berry theme={null}
  yarn run arkor init
  ```

  ```bash bun theme={null}
  bun arkor init
  ```
</CodeGroup>

## Options

| Flag              | Description                                                                                                                                                                                                                                                                            |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `-y, --yes`       | Accept defaults instead of prompting (project name from the directory name, template `triage`).                                                                                                                                                                                        |
| `--name <name>`   | Project name. Defaults to the current directory's name (`arkor-project` if the path has no basename, e.g. `/`). The value is sanitised before it lands in `package.json`.                                                                                                              |
| `--template <id>` | Starter template. Options: `triage`, `translate`, `redaction`. Unknown ids throw before any filesystem work.                                                                                                                                                                           |
| `--skip-install`  | Skip running the package manager's `install` step after scaffolding.                                                                                                                                                                                                                   |
| `--use-npm`       | Force npm as the package manager.                                                                                                                                                                                                                                                      |
| `--use-pnpm`      | Force pnpm as the package manager.                                                                                                                                                                                                                                                     |
| `--use-yarn`      | Force yarn as the package manager.                                                                                                                                                                                                                                                     |
| `--use-bun`       | Force bun as the package manager. Known limitation on Windows: `arkor init --use-bun` populates `node_modules` but does not produce `bun.lock`, so the initial commit will not include a lockfile. Running `bun install` directly and using `create-arkor --use-bun` are not affected. |
| `--git`           | Initialise a git repo and create an initial commit, without asking.                                                                                                                                                                                                                    |
| `--skip-git`      | Skip git init silently.                                                                                                                                                                                                                                                                |
| `--allow-builds`  | Opt esbuild's `postinstall` script into running on `pnpm install`. pnpm-only (yarn / npm / bun ignore the workspace yaml). Default: deny. See [Postinstall scripts (pnpm 11+)](#postinstall-scripts-pnpm-11) below.                                                                    |
| `--agents-md`     | Write `AGENTS.md` and `CLAUDE.md` to brief AI coding agents that arkor post-dates their training data. Default.                                                                                                                                                                        |
| `--no-agents-md`  | Skip generating `AGENTS.md` / `CLAUDE.md`. An existing user-authored `AGENTS.md` is always preserved; the arkor-managed block (delimited by `<!-- BEGIN:arkor-agent-rules -->` / `<!-- END:arkor-agent-rules -->`) is appended on first run and replaced in place on re-scaffold.      |

`--git` and `--skip-git` are mutually exclusive; passing both throws. The same goes for `--agents-md` and `--no-agents-md`.

## Behavior

### Default flow

By default, the command is partly interactive: it prompts for a project name, a starter template, and (when not in a git repo) whether to run `git init`, and only then starts the package manager's `install` step (no confirmation prompt) unless `--skip-install` is set. The `git init` confirmation is surfaced before install so you can answer every prompt upfront and walk away while install runs unattended; the actual `git init` + initial commit still execute after install so the generated lockfile lands in the initial commit. If no package manager can be resolved (no `--use-*` flag and detection from `npm_config_user_agent` fails), the install step is skipped and the outro prints a manual install hint.

### Postinstall scripts (pnpm 11+)

When the chosen package manager is pnpm (explicitly via `--use-pnpm`, detected as pnpm from `npm_config_user_agent` such as `pnpm arkor init`, or implicitly because pm detection didn't resolve and the target is a fresh empty directory), the scaffold writes a small `pnpm-workspace.yaml` alongside `package.json`:

```yaml theme={null}
packages: []
allowBuilds:
  esbuild: false
```

The file is **not** written when:

* `--use-npm` / `--use-yarn` / `--use-bun` is set (those toolchains don't read it).
* The target directory already contains files and no `--use-*` flag is set (we don't drop workspace-level config into someone else's project on a guess).
* An ancestor directory already has a `pnpm-workspace.yaml` (the parent monorepo workspace governs; creating a nested one here would shadow it and break `workspace:*` resolution above).

If `pnpm-workspace.yaml` already exists at the target AND pnpm is plausible (the same `--use-pnpm` / UA-detected pnpm / unresolved-detection conditions that gate fresh creation above; `--use-npm` / `--use-yarn` / `--use-bun` runs leave any existing file untouched), the scaffold patches it: it appends `esbuild: false` (or `esbuild: true` if `--allow-builds` is set) to the existing top-level `allowBuilds:` block (or creates one) without touching unrelated keys, and bows out as a no-op for the `allowBuilds` decision when esbuild is already pinned (allow or deny) or when the file uses the global scalar form `allowBuilds: false` / `allowBuilds: true`. Note that an `allowBuilds`-no-op run can still modify the file in one other way: a top-level `packages:` key is backfilled as `packages: []` if missing, since pnpm 9 errors with "packages field missing or empty" against a `pnpm-workspace.yaml` that has no `packages:` declaration. The `allowBuilds.esbuild` decision is what's preserved; the file itself may pick up that one structural key.

pnpm 11 changed the default for postinstall scripts to "deny unless explicitly approved", and exits with `ERR_PNPM_IGNORED_BUILDS` (code 1) when an unapproved script is encountered. esbuild ships such a script (`node install.js`, which verifies/downloads the platform-specific binary), so a vanilla `pnpm install` against a freshly scaffolded project would otherwise fail.

The scaffolded `allowBuilds: { esbuild: false }` is an explicit deny: pnpm sees a decision and silently skips the script instead of erroring. esbuild itself still works, because pnpm already installs `@esbuild/<platform>` as an `optionalDependency`. yarn / npm / bun all ignore `pnpm-workspace.yaml`, so the file is inert under those package managers.

If you genuinely need esbuild's postinstall to run (rare; usually a broken installer or unusual platform), pass `--allow-builds`:

```bash theme={null}
pnpm arkor init --yes --use-pnpm --allow-builds
```

Or flip the entry to `true` in `pnpm-workspace.yaml` after the fact. The flag is only consulted on runs that actually emit or patch `pnpm-workspace.yaml`, so passing it under `--use-npm` / `--use-yarn` / `--use-bun` is a no-op (those runs don't touch the file at all). Re-run `arkor init --use-pnpm --allow-builds` later if you switch to pnpm.

### Templates

| Template    | Task                   | Output shape                                 |
| ----------- | ---------------------- | -------------------------------------------- |
| `triage`    | Support triage         | `{ category, urgency, summary, nextAction }` |
| `translate` | 9-language translation | `{ translation, detectedLanguage }`          |
| `redaction` | PII redaction          | `{ redactedText, redactedCount, tags }`      |

All three pair the same small open-weight base (`gemma-4-E4B-it`) with a curated public dataset on HuggingFace.

### Package manager detection

When no `--use-*` flag is passed, the CLI inspects `npm_config_user_agent` to detect the package manager that invoked it (this is the standard mechanism `corepack` uses, so `pnpm dlx`, `yarn dlx`, `bunx`, etc. all work).

If detection fails and no flag is passed, the install step is skipped and the outro prints a manual install hint.

### Git policy

`arkor init` decides whether to run `git init` + initial commit by walking these rules in order:

1. If the current directory is already inside a git repo, skip (and log it).
2. If `--skip-git` is passed, skip.
3. If `--git` or `-y` is passed, run without asking.
4. In an interactive shell, prompt (default: yes).
5. In a non-interactive shell with no flag, skip.

The interactive confirmation is shown **before** install (so you don't sit at a prompt after a multi-minute `<pm> install`), but `git init` execution still runs **after** install so the lockfile generated by the package manager is part of the initial commit. If commit signing fails (e.g. GPG agent isn't running), the CLI falls back to an unsigned commit and warns; you can re-sign with `git commit --amend -S` later.

### CI / non-interactive shells

When `process.stdout` is not a TTY, or `CI` is set in the environment, `arkor init` is non-interactive: prompts skip with their default values and never block waiting for input. To get a deterministic scaffold from CI:

<CodeGroup>
  ```bash pnpm theme={null}
  pnpm arkor init --yes --template triage --use-pnpm --skip-git
  ```

  ```bash npm theme={null}
  npm arkor init --yes --template triage --use-npm --skip-git
  ```

  ```bash yarn theme={null}
  yarn arkor init --yes --template triage --use-yarn --skip-git
  ```

  ```bash yarn-berry theme={null}
  yarn run arkor init --yes --template triage --use-yarn --skip-git
  ```

  ```bash bun theme={null}
  bun arkor init --yes --template triage --use-bun --skip-git
  ```
</CodeGroup>

`--yes` accepts the project-name and template defaults (the directory's basename and `triage`), `--use-pnpm` (or the matching `--use-<pm>`) short-circuits package-manager detection, and `--skip-git` opts out of git init. Pass `--skip-install` as well if your CI image already has `node_modules/`.

If you forget `--yes` in a non-interactive shell, the command still completes (prompts use their defaults) but the experience is silent and easy to miss in logs. Prefer the explicit form above.

### Claude Code (`CLAUDECODE=1`) strict mode

Claude Code spawns child processes with `CLAUDECODE=1`, and it cannot answer interactive prompts. To prevent the agent from silently scaffolding with hidden defaults, `arkor init` flips into a strict mode under this env var: a curated set of flags becomes required (see the list below), and a missing one produces a stderr message listing the suggested re-invocation rather than running. Project name is intentionally not required here in the common case: `arkor init` derives it from `basename(cwd)`, which is the same value the interactive prompt would have suggested. The strict-mode validator still asks for `--name <name>` in two narrow cases that would otherwise silently fall back to the generic `arkor-project` slug, namely (a) when `--name` *was* passed but its value has no ASCII letter or digit (e.g. `--name "!!!"`) and (b) when `--name` was omitted and the current directory's basename has no ASCII letter or digit either (e.g. running `arkor init` from `/tmp/!!!/`). The package-manager flag is required even though it isn't strictly a prompt, so the agent picks `--use-*` vs. `--skip-install` deliberately rather than relying on `npm_config_user_agent` detection.

Required flags (or pass `-y`/`--yes` to opt back into "accept all defaults"):

* `--template <triage|translate|redaction>`
* `--git` (recommended; matches the interactive default) or `--skip-git`
* A package-manager flag: `--use-npm` / `--use-pnpm` / `--use-yarn` / `--use-bun`, or `--skip-install`
* `--agents-md` (recommended, especially under CLAUDECODE) or `--no-agents-md`

Sample stderr when a flag is missing. Each flag is paired with a one-line description so the agent can pick a value without round-tripping to the docs:

```text theme={null}
arkor init: CLAUDECODE=1 detected. Interactive prompts are disabled.
Re-run with explicit flags:
  --template <triage|translate|redaction>
      Starter template: `triage` (support routing), `translate` (9-language translation), or `redaction` (PII removal).
  --git (recommended) or --skip-git
      `--git` runs `git init` and creates an initial commit (matches the interactive default); `--skip-git` leaves git setup to the user.
  --use-pnpm (or --use-npm / --use-yarn / --use-bun, or --skip-install)
      Which package manager to run `install` with after scaffolding. `--skip-install` leaves the install step to the user.
  --agents-md (recommended) or --no-agents-md
      `--agents-md` writes `AGENTS.md` + `CLAUDE.md` to brief AI coding agents that arkor post-dates their training data (recommended, especially under CLAUDECODE); `--no-agents-md` skips them.
Or pass -y/--yes to accept all defaults.
```

The exit code is `1` and no scaffold work happens before the early exit, so the directory stays pristine. The same rule applies to [`create-arkor`](/quickstart#running-under-claude-code-claudecode=1) (Quickstart documents the create-arkor specifics, including the additional `[dir]` / `--name` requirement to make the project name an explicit decision).

## Errors

| Message                                                            | What it means                                                        | Fix                                                                                                |
| ------------------------------------------------------------------ | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `Pick one of --git / --skip-git, not both.`                        | Both git flags were passed.                                          | Pass at most one.                                                                                  |
| `Unknown template "<id>". Available: triage, translate, redaction` | `--template` value did not match any registered template id.         | Use one of the listed ids.                                                                         |
| `Commit signing failed: created an unsigned commit.`               | `git init` succeeded but the initial commit could not be GPG-signed. | Re-sign with `git commit --amend -S` once your signing setup is fixed. The repo is otherwise fine. |

## Examples

Interactive:

<CodeGroup>
  ```bash pnpm theme={null}
  pnpm arkor init
  ```

  ```bash npm theme={null}
  npm arkor init
  ```

  ```bash yarn theme={null}
  yarn arkor init
  ```

  ```bash yarn-berry theme={null}
  yarn run arkor init
  ```

  ```bash bun theme={null}
  bun arkor init
  ```
</CodeGroup>

Accept defaults, skip install, skip git:

<CodeGroup>
  ```bash pnpm theme={null}
  pnpm arkor init --yes --skip-install --skip-git
  ```

  ```bash npm theme={null}
  npm arkor init --yes --skip-install --skip-git
  ```

  ```bash yarn theme={null}
  yarn arkor init --yes --skip-install --skip-git
  ```

  ```bash yarn-berry theme={null}
  yarn run arkor init --yes --skip-install --skip-git
  ```

  ```bash bun theme={null}
  bun arkor init --yes --skip-install --skip-git
  ```
</CodeGroup>

Pin the template and force the package manager:

<CodeGroup>
  ```bash pnpm theme={null}
  pnpm arkor init --template translate --use-pnpm
  ```

  ```bash npm theme={null}
  npm arkor init --template translate --use-npm
  ```

  ```bash yarn theme={null}
  yarn arkor init --template translate --use-yarn
  ```

  ```bash yarn-berry theme={null}
  yarn run arkor init --template translate --use-yarn
  ```

  ```bash bun theme={null}
  bun arkor init --template translate --use-bun
  ```
</CodeGroup>

## What gets written

The scaffolder touches up to ten paths: six unconditional plus two AGENTS.md-related plus two conditional package-manager configs. None of them overwrites existing user content:

| Path                   | Behavior                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `src/arkor/index.ts`   | **Created** with `createArkor({ trainer })` if missing. **Kept** untouched if the file already exists.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `src/arkor/trainer.ts` | **Created** with the chosen template's `createTrainer({...})` if missing. **Kept** untouched if it exists.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `arkor.config.ts`      | **Created** as a placeholder export if missing. **Kept** untouched if it exists. See [Project structure](/concepts/project-structure).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `README.md`            | **Created** with a starter README if missing. **Kept** untouched if it exists.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `.gitignore`           | **Created** with `node_modules/`, `dist/`, `.arkor/` if missing. **Patched** by appending `.arkor/` if the file exists but does not already list it. **Ok** (no change) if `.arkor/` is already there.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `package.json`         | **Created** with name / `private` / `type: "module"` / starter `dev`+`build`+`start` scripts / `devDependencies.arkor` if missing. **Patched** to add any of those scripts that are absent and to add `arkor` under `devDependencies` if absent; existing values (e.g. a custom `dev` script) are **not** overwritten. **Ok** (no change) if everything is already in place.                                                                                                                                                                                                                                                                                                                |
| `AGENTS.md`            | **Created** with the arkor-managed block if missing (default; skip with `--no-agents-md`). If the file exists, the arkor-managed block (delimited by `<!-- BEGIN:arkor-agent-rules -->` / `<!-- END:arkor-agent-rules -->`) is **patched** in place (appended on first run, replaced inline on re-scaffold), and any user content outside the markers is preserved. **Ok** (no change) if the canonical block is already present and up-to-date. **Kept** with a warning, instead of patched, when the file contains more than one canonical managed block: auto-picking either copy is unsafe, so the scaffolder leaves the file alone and asks you to dedupe before the next re-scaffold. |
| `CLAUDE.md`            | **Created** with `@AGENTS.md` (the Claude Code import directive) if missing (default; skip with `--no-agents-md`). **Kept** untouched if the file already exists, so a project-specific `CLAUDE.md` is never overwritten. **Skipped** with a warning when `AGENTS.md` was kept due to duplicate managed blocks: creating the `@AGENTS.md` shim in that state would auto-import the unresolved duplicate rules into Claude Code's context. The next re-scaffold creates the file once you dedupe `AGENTS.md`.                                                                                                                                                                                |
| `pnpm-workspace.yaml`  | *Conditional.* See [Postinstall scripts (pnpm 11+)](#postinstall-scripts-pnpm-11) for the full conditions. **Created** with `packages: []` + `allowBuilds.esbuild: false` (or `: true` with `--allow-builds`) when pnpm is plausible AND no ancestor already declares one. **Patched** when the file already exists AND pnpm is plausible: appends `esbuild: <bool>` to `allowBuilds:` only if esbuild isn't already pinned. **Skipped** for explicit `--use-npm` / `--use-yarn` / `--use-bun` and inside pnpm monorepo subdirs.                                                                                                                                                            |
| `.yarnrc.yml`          | *Conditional.* See `packages/cli-internal/src/scaffold.ts` for the full layered yarn-config policy. **Created** with `nodeLinker: node-modules` on fresh scaffolds where yarn is plausible (`--use-yarn`, UA-detected yarn, or no `--use-*` flag with UA detection failing). **Kept** untouched if it exists; non-default `nodeLinker:` produces a conflict warning, missing `nodeLinker:` surfaces a yarn-berry caveat. **Skipped** for explicit non-yarn pms and for `--use-yarn` against an existing non-empty dir without a positive yarn-berry signal.                                                                                                                                 |

The CLI prints the file list as a "Files" note before installing, with an `action` (`created` / `kept` / `patched` / `ok` / `skipped`) per path so you can see exactly what changed.

### Editing your AGENTS.md alongside the managed block

The arkor-managed block is identified by the BEGIN / END markers **plus** a signature first line (`# arkor is newer than your training data`). The detector requires all three on their own lines, so inline marker mentions inside backticks are safe, but a fenced code block whose body literally contains the markers and that signature heading on their own lines will look identical to a real managed block. To avoid having a re-scaffold misidentify and overwrite a documentation example you wrote yourself, follow these conventions when editing `AGENTS.md`:

* **Quote markers inline with backticks**, e.g. `` `<!-- BEGIN:arkor-agent-rules -->` ``, rather than putting them on their own lines outside the real managed block.
* If you must show the markers as a verbatim block (for example when documenting the spec for other tooling), **change at least one character of the signature line** in your example (e.g. `# arkor is newer than YOUR training data`) so the detector does not match it.
* The scaffolder also refuses to patch (and emits a warning) when it finds **two or more** signature-matching blocks in the file. If you see that warning, dedupe the file: typically that means deleting the older, hand-edited copy of the canonical block and letting the re-scaffold update the surviving one in place.

## See also

* [Quickstart](/quickstart) for the greenfield scaffolding flow
* [Project structure](/concepts/project-structure) for what each generated file is for
* [`arkor dev`](/cli/dev) for the next step after init
