Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
bbfed9f
feat: implement CLAUDECODE strict mode for arkor init and create-arkor
k-taro56 May 14, 2026
6df7a9d
feat: implement strict mode for CLAUDECODE in init and create-arkor c…
k-taro56 May 14, 2026
0523aa6
feat: enhance strict mode handling in create-arkor and related commands
k-taro56 May 14, 2026
57fe6a0
test: enhance assertions for strict mode in create-arkor E2E tests
k-taro56 May 14, 2026
4a0bb46
feat: improve sanitise function to handle non-alphanumeric runs and o…
k-taro56 May 14, 2026
4289540
fix: update documentation and tests for strict mode handling in arkor…
k-taro56 May 14, 2026
6a89128
feat: enhance strict mode handling for CLAUDECODE in init and create-…
k-taro56 May 15, 2026
7224433
feat: enhance project name validation to reject empty and non-ASCII i…
k-taro56 May 15, 2026
fc33b4c
test: add case for parent directory in missingClaudeCodeFlags tests
k-taro56 May 15, 2026
be60976
docs: clarify Mintlify heading slug behavior and update related docum…
k-taro56 May 15, 2026
d9d714a
feat: enhance strict mode validation in create-arkor and related comm…
k-taro56 May 16, 2026
316642b
fix: validate explicit --name in arkor init strict mode and harden re…
k-taro56 May 16, 2026
96239ae
feat: enhance strict mode validation in arkor init to reject non-alph…
k-taro56 May 16, 2026
1f00216
fix: improve strict mode handling in CLI and related documentation fo…
k-taro56 May 16, 2026
dde60c3
test: enhance CLAUDECODE environment handling in runCli tests for str…
k-taro56 May 17, 2026
66ea1ac
test: prevent CLAUDECODE scrub suite from leaking platform/env into l…
k-taro56 May 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ Don't split these into "docs in a follow-up PR" or "tests later" — land them i
## Non-obvious gotchas

- **Docs CLI CodeGroup convention.** Pages under `/cli/*` and `/guides/cli/*` (and their JA mirrors) show unscripted subcommands (`arkor init`, `arkor login`, `arkor logout`, `arkor whoami`) as a 5-tab CodeGroup in the form `<pm> arkor <subcommand>`: `pnpm arkor init`, `npm arkor init`, `yarn arkor init`, `yarn run arkor init` (yarn-berry needs `run`), `bun arkor init`. The `npm` tab stays as `npm arkor init` even though npm itself does not run package binaries via `npm <bin>`. These commands are intended to be run after `arkor` is already in the project's `package.json` (post `create-arkor`, or post manual `pnpm i arkor` / equivalent), and the 5-tab form is about consistent presentation per package manager, not about being copy-pasteable for users without a project. Do **not** rewrite the `npm` tab to `npx arkor <subcommand>` or `npm exec arkor <subcommand>`, and do not act on review comments (human or bot) saying "`npm arkor init` does not work": that comment misses the premise.
- **Mintlify heading slugs are not GitHub-style; verify with curl.** The common assumption (`github-slugger`) is that all punctuation gets stripped from heading ids. Mintlify's actual behaviour is mixed: some punctuation is **preserved** in the id (`=`, `/`, and the full-width JP parens `(` `)`), some is **stripped without replacement** (ASCII parens `(` `)`, backticks `` ` ``, brackets), and spaces become `-` as usual. Verified examples in the rendered preview at the time of [PR #141](https://github.com/arkorlab/arkor/pull/141):
- `### CI / non-interactive shells` → `id="ci-/-non-interactive-shells"` (slash kept, slash-flanking spaces still become hyphens, hence `-/-`)
- `` ### Claude Code (`CLAUDECODE=1`) strict mode `` → `id="claude-code-claudecode=1-strict-mode"` (ASCII parens + backticks stripped, `=` kept, surrounding spaces become hyphens)
- `` ### Running under Claude Code (`CLAUDECODE=1`) `` → `id="running-under-claude-code-claudecode=1"`
- `` ### Claude Code(`CLAUDECODE=1`)厳格モード `` (JA) → `id="claude-code(claudecode=1)厳格モード"` (full-width parens kept verbatim, backticks stripped, `=` kept)

Cross-page links in `docs/` must therefore mirror the actual rendered id, which preserves `/`, `=`, and full-width parens but strips ASCII parens and backticks. Always confirm before adding or editing an anchor link: `curl -s "<mintlify-preview-url>/<page>" | grep -oE 'id="[^"]*<keyword>[^"]*"'`. Do not act on review comments (human or bot) claiming "Mintlify strips punctuation in headings" as a universal rule: Copilot in particular gets this wrong repeatedly by extrapolating from `github-slugger`, and has even cited the pre-existing broken `#ci--non-interactive-shells` link as supposed evidence. PR #141 fixed that broken link to `#ci-/-non-interactive-shells`, and the surviving anchors in `docs/cli/overview.mdx` and the strict-mode sections of `docs/quickstart.mdx` / `docs/cli/init.mdx` (plus their JA mirrors) are the canonical examples to copy from.
- **Don't call a HuggingFace model name "non-existent"** based on training-data alone. Templates reference real models (e.g. `unsloth/gemma-4-E4B-it`) that may post-date Claude's knowledge cutoff. Verify (e.g. `WebFetch`) before flagging in issues or PR comments. If unverifiable, hedge ("could not confirm") rather than asserting absence.
- **Generated files** copied into package dirs are gitignored: `packages/*/CONTRIBUTING.md` (from root), `packages/arkor/docs/` (from root `docs/`). Edit the source under repo root, not the copies.
- **Node version**: published packages declare `engines.node >=22.22.0` (raised from 22.6 to dodge the [Jan 2026 async-hooks DoS CVE](https://nodejs.org/en/blog/vulnerability/january-2026-dos-mitigation-async-hooks)). Use Node 24 (latest preferred) for development per [CONTRIBUTING.md](CONTRIBUTING.md).
Expand Down
29 changes: 29 additions & 0 deletions docs/cli/init.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,35 @@ bun arkor init --yes --template triage --use-bun --skip-git

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
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 |
Expand Down
3 changes: 2 additions & 1 deletion docs/cli/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ The `arkor` CLI is the command surface around an Arkor project. The [scaffolder]
| `DO_NOT_TRACK=1` | Disable telemetry across every command. The persistent telemetry-id file is not created or read. |
| `ARKOR_TELEMETRY_DISABLED=1` | Same as `DO_NOT_TRACK`. Provided as an Arkor-specific alias for setups that already gate other tools on `DO_NOT_TRACK` and want a separate switch. |
| `ARKOR_TELEMETRY_DEBUG=1` | Enable verbose internal logging from the telemetry module (init failures, identity-file read/write errors, capture failures, shutdown errors). Telemetry **is still sent** when this flag is on; this is a diagnostic aid, not a dry-run switch. To stop sending events, use `DO_NOT_TRACK=1` or `ARKOR_TELEMETRY_DISABLED=1`. |
| `CI=1` (or any non-TTY stdout) | Force non-interactive mode. `arkor init` skips its prompts and uses the values you passed via flags (or built-in defaults under `--yes`); git init runs without asking when `--git` or `--yes` is set, and is skipped silently otherwise. See [`arkor init` § CI / non-interactive shells](/cli/init#ci--non-interactive-shells). |
| `CI=1` (or any non-TTY stdout) | Force non-interactive mode. `arkor init` skips its prompts and uses the values you passed via flags (or built-in defaults under `--yes`); git init runs without asking when `--git` or `--yes` is set, and is skipped silently otherwise. See [`arkor init` § CI / non-interactive shells](/cli/init#ci-/-non-interactive-shells). |
| `CLAUDECODE=1` | Strict mode for AI agents that spawn the CLI without being able to answer interactive prompts. `arkor init` (and `create-arkor`) refuse to run unless every curated flag is present, printing a multi-line stderr block with the suggested re-invocation; pass `-y`/`--yes` to opt back into "accept all defaults". See [`arkor init` § Claude Code (`CLAUDECODE=1`) strict mode](/cli/init#claude-code-claudecode=1-strict-mode). |

### On the roadmap

Expand Down
29 changes: 29 additions & 0 deletions docs/ja/cli/init.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,35 @@ bun arkor init --yes --template triage --use-bun --skip-git

非対話シェルで `--yes` を忘れてもコマンドは完走します(プロンプトはデフォルトを使う)が、静かに動作するためログからは見落としやすい挙動になります。上記の明示形を推奨します。

### Claude Code(`CLAUDECODE=1`)厳格モード

Claude Code は子プロセスに `CLAUDECODE=1` を渡し、対話プロンプトに応答できません。エージェントが隠れたデフォルトで黙ってプロジェクトを生成してしまうのを防ぐため、この環境変数下では `arkor init` は厳格モードに切り替わります。下記のキュレーション済みフラグセットが必須となり、不足があれば実行ではなく、再実行用のコマンドを stderr に出して終了します。通常はプロジェクト名を必須にしていません。`arkor init` は `basename(cwd)` から派生させており、これは対話プロンプトでのデフォルト提案値と同じだからです。ただし、generic な `arkor-project` フォールバックに silent collapse してしまう次の 2 ケースは厳格モードでも `--name <name>` を要求します: (a) `--name` が渡されていてその値に ASCII 英数字が 1 つも含まれない (例: `--name "!!!"`)、(b) `--name` 省略時のカレントディレクトリ basename にも ASCII 英数字が含まれない (例: `/tmp/!!!/` から `arkor init` を実行)。パッケージマネージャーは厳密にはプロンプトではありません(UA 自動検出か検出失敗時の silent skip)が、`npm_config_user_agent` 任せにせず `--use-*` か `--skip-install` をエージェントが明示的に選ぶように、こちらは必須としています。

必須フラグ(または `-y`/`--yes` で「すべてデフォルトで進める」にオプトインしてください):

- `--template <triage|translate|redaction>`
- `--git`(推奨。対話モードのデフォルトと同じ)または `--skip-git`
- パッケージマネージャー系フラグ: `--use-npm` / `--use-pnpm` / `--use-yarn` / `--use-bun`、または `--skip-install`
- `--agents-md`(特に CLAUDECODE 下では推奨)または `--no-agents-md`

フラグが不足したときの stderr 例。各フラグには一行の説明が併記され、ドキュメントを往復しなくてもエージェントが値を決められるようになっています:

```text
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.
```

終了コードは `1`、早期終了の前にファイル生成は一切行われないので、ディレクトリは元の状態のままです。同じルールは [`create-arkor`](/ja/quickstart#claude-code-下での実行(claudecode=1)) にも適用されます(Quickstart に create-arkor 固有の詳細を記載しています。プロジェクト名を明示的に決めさせるための `[dir]` / `--name` 必須化も含む)。

## エラー

| メッセージ | 意味 | 対処 |
Expand Down
3 changes: 2 additions & 1 deletion docs/ja/cli/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ description: "arkor CLI: 全コマンドリファレンス。"
| `DO_NOT_TRACK=1` | すべてのコマンドでテレメトリーを無効化。永続テレメトリー ID ファイルは作成も読込もされません。 |
| `ARKOR_TELEMETRY_DISABLED=1` | `DO_NOT_TRACK` と同じ。`DO_NOT_TRACK` で他ツールをゲートしているがスイッチを分けたい構成のための Arkor 専用エイリアス。 |
| `ARKOR_TELEMETRY_DEBUG=1` | テレメトリーモジュール内部の冗長ログを有効化(init 失敗、ID ファイルの read/write エラー、capture 失敗、shutdown エラー)。このフラグが ON でも **テレメトリーは送信されます**。診断補助で、dry-run スイッチではありません。送信を止めるには `DO_NOT_TRACK=1` か `ARKOR_TELEMETRY_DISABLED=1` を使ってください。 |
| `CI=1`(または stdout が非 TTY) | 非対話モードを強制。`arkor init` はプロンプトをスキップしてフラグで渡された値(`--yes` 時は組み込みのデフォルト)を使い、`--git` か `--yes` 指定時は git init が確認なしで走り、それ以外では黙ってスキップされます。[`arkor init` § CI / 非対話シェル](/ja/cli/init#ci--非対話シェル) を参照。 |
| `CI=1`(または stdout が非 TTY) | 非対話モードを強制。`arkor init` はプロンプトをスキップしてフラグで渡された値(`--yes` 時は組み込みのデフォルト)を使い、`--git` か `--yes` 指定時は git init が確認なしで走り、それ以外では黙ってスキップされます。[`arkor init` § CI / 非対話シェル](/ja/cli/init#ci-/-非対話シェル) を参照。 |
| `CLAUDECODE=1` | 対話プロンプトに応答できない AI エージェント(Claude Code 等)向けの厳格モード。`arkor init`(および `create-arkor`)は curated フラグセットがすべて揃わない限り実行を拒否し、再実行用コマンドを stderr に複数行で出力します。「すべてデフォルトで進める」に戻すには `-y`/`--yes` を渡します。[`arkor init` § Claude Code(`CLAUDECODE=1`)厳格モード](/ja/cli/init#claude-code(claudecode=1)厳格モード) を参照。 |

### ロードマップ上

Expand Down
32 changes: 32 additions & 0 deletions docs/ja/quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,38 @@ bun create arkor my-arkor-app --template triage

</CodeGroup>

### Claude Code 下での実行(`CLAUDECODE=1`)

Claude Code は子プロセスに `CLAUDECODE=1` を渡し、対話プロンプトに応答できません。エージェントが隠れたデフォルトで黙ってプロジェクトを生成してしまうのを防ぐため、この環境変数下では `create-arkor` も厳格モードに切り替わります。下記のキュレーション済みフラグセットが必須となり、不足があれば実行ではなく、再実行用のコマンドを stderr に出して終了します。同じルールは [`arkor init`](/ja/cli/init#claude-code(claudecode=1)厳格モード) にも適用されますが、`create-arkor` だけ追加で `[dir]`(または `--name`)も必須となります。これは positional 省略時のフォールバック先 `arkor-project/` サブディレクトリが意図的に選ばれることはまずなく、ほぼ常に指定漏れだからです。ASCII の英数字を 1 文字も含まない入力(空、空白だけ、`!!!` のような記号だけ)も拒否されます。`sanitise()` が同じ generic フォールバックに collapse させてしまうためです。一方、サニタイズ結果がたまたま `arkor-project` になるような **意図的な名前**(例: `Arkor Project`、`arkor_project`、`Arkor.Project` のようにセパレータ文字が `-` に書き換えられるもの)は受け入れます。英数字が含まれていることがエージェントの明示的入力の証拠になるためです。

必須フラグ(または `-y`/`--yes` で「すべてデフォルトで進める」にオプトイン):

- `[dir]`(例 `my-arkor-app`)または `--name <name>`: 明示的なプロジェクト名。ASCII の英数字を 1 文字も含まない入力(空、空白だけ、`!!!` のような記号だけ)は、`arkor-project` フォールバックに collapse させてしまうため拒否。`Arkor Project`、`arkor_project` のように **意図的でたまたま** サニタイズ結果が `arkor-project` になる入力は受け入れます。
- `--template <triage|translate|redaction>`
- `--git`(推奨。対話モードのデフォルトと同じ)または `--skip-git`
- パッケージマネージャー系フラグ: `--use-npm` / `--use-pnpm` / `--use-yarn` / `--use-bun`、または `--skip-install`
- `--agents-md`(特に CLAUDECODE 下では推奨)または `--no-agents-md`

フラグが不足したときの stderr 例:

```text
create-arkor: CLAUDECODE=1 detected. Interactive prompts are disabled.
Re-run with explicit flags:
[dir] (e.g. `my-arkor-app`) or --name <name>
Project directory (positional) and the `package.json` name. Without `--name`, the basename of `[dir]` is used. Inputs with no ASCII letter or digit (empty, whitespace-only, or punctuation-only like `!!!` / `***`) are rejected because they would collapse to the generic `arkor-project` fallback inside `sanitise()`.
--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.
```

終了コードは `1`、早期終了の前にファイル生成は一切行われないので、親ディレクトリは元の状態のままです。

## 2. 生成されたものを眺める

```
Expand Down
Loading
Loading