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 runs the same scaffolder one directory up).
Synopsis
Options
--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 rungit 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:
--use-npm/--use-yarn/--use-bunis 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 breakworkspace:*resolution above).
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:
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
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:
- If the current directory is already inside a git repo, skip (and log it).
- If
--skip-gitis passed, skip. - If
--gitor-yis passed, run without asking. - In an interactive shell, prompt (default: yes).
- In a non-interactive shell with no flag, skip.
<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
Whenprocess.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:
--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
1 and no scaffold work happens before the early exit, so the directory stays pristine. The same rule applies to create-arkor (Quickstart documents the create-arkor specifics, including the additional [dir] / --name requirement to make the project name an explicit decision).
Errors
Examples
Interactive: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:
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 for the greenfield scaffolding flow
- Project structure for what each generated file is for
arkor devfor the next step after init