Skip to content
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b65b9dc
feat: add `runok init` subcommand for guided setup
fohte Mar 2, 2026
2413d50
fix(init): remove incorrect colon-to-space conversion for Bash patterns
fohte Mar 2, 2026
78842fa
refactor(init): improve boilerplate template and test assertions
fohte Mar 2, 2026
3f86675
fix(init): use correct Claude Code hook object format
fohte Mar 3, 2026
e1eac00
fix(init): revert docs hook format change
fohte Mar 3, 2026
b1af763
refactor(init): improve output readability
fohte Mar 3, 2026
e068822
feat(init): show settings.json diff before confirmation prompts
fohte Mar 3, 2026
74bf7e8
fix(init): normalize JSON before diffing to avoid indentation noise
fohte Mar 3, 2026
dffe302
refactor(init): unify confirmation into single prompt with step preview
fohte Mar 3, 2026
3a8e9cd
refactor(init): split wizard.rs into wizard/ directory module and imp…
fohte Mar 4, 2026
281b42b
init: simplify wizard UX with scope select and batch confirmation
fohte Mar 4, 2026
acdd6cb
init: add scope-specific hook and migration policies
fohte Mar 4, 2026
4d7ec2a
init: convert Claude Code prefix-match syntax to runok glob
fohte Mar 4, 2026
e3fe40e
init: remove --force flag and ask migration for all scopes
fohte Mar 4, 2026
ef43b3c
init: show "Detected" message before migration prompt
fohte Mar 4, 2026
01e9317
init: add assert_exhausted to integration tests for prompt count
fohte Mar 4, 2026
ba9efb6
init: always create runok.yml even when migration is declined
fohte Mar 4, 2026
748225c
init: remove assert_exhausted from integration tests
fohte Mar 4, 2026
4ae4b74
init: do not create runok.yml when user declines all Claude Code changes
fohte Mar 4, 2026
8721d70
init: rewrite integration tests to cover all 23 setup_scope patterns
fohte Mar 4, 2026
9567f67
init: improve pattern table readability with N/A markers and grouping
fohte Mar 4, 2026
d7a011d
init: expand integration tests from 23 to 46 patterns with existing c…
fohte Mar 4, 2026
be3af3b
init: spell out "Existing config" column header in pattern table
fohte Mar 4, 2026
ac4c47c
init: prompt before overwriting existing runok.yml
fohte Mar 4, 2026
4454d15
docs: add `runok init` to documentation
fohte Mar 5, 2026
9dc0acf
fix(init): clear XDG env vars in E2E tests for isolation
fohte Mar 5, 2026
d8e83c5
fix(init): escape single quotes in converted permission patterns
fohte Mar 5, 2026
5ba27e4
refactor(init): use concat! for multiline YAML fragment test strings
fohte Mar 5, 2026
56bbee0
fix(init): address review feedback for hook detection, permission cle…
fohte Mar 5, 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
145 changes: 140 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ seccompiler = "=0.5.0"
anyhow = "=1.0.102"
cel-interpreter = "=0.10.0"
clap = { version = "=4.5.60", features = ["derive"] }
dialoguer = "=0.11.0"
schemars = { version = "=1.2.1", optional = true }
serde = { version = "=1.0.228", features = ["derive"] }
serde-saphyr = "=0.0.20"
serde_json = "=1.0.149"
sha2 = "=0.10.9"
shlex = "=1.3.0"
similar = { version = "=2.7.0", features = ["unicode"] }
thiserror = "=2.0.18"
tree-sitter = "=0.26.5"
tree-sitter-bash = "=0.25.1"
Expand Down
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,15 @@ Pre-built binaries are also available on [GitHub Releases](https://github.com/fo

### Configure

Create `~/.config/runok/runok.yml`:
The fastest way to get started is with the interactive setup wizard:

```sh
runok init
```

This creates a `runok.yml`, and if you have Claude Code configured, migrates your Bash permissions to runok rules and registers the PreToolUse hook automatically.

You can also configure manually. Create `~/.config/runok/runok.yml`:

```yaml
rules:
Expand All @@ -96,9 +104,7 @@ defaults:
action: ask
```

### Integrate with Claude Code

Add runok as a PreToolUse hook in `.claude/settings.json`:
And add runok as a PreToolUse hook in `.claude/settings.json`:

```json
{
Expand Down
64 changes: 64 additions & 0 deletions docs/src/content/docs/cli/init.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
title: runok init
description: Initialize runok configuration with an interactive setup wizard.
sidebar:
order: 4
---

`runok init` creates a `runok.yml` configuration file through an interactive setup wizard. It can also detect existing Claude Code Bash permissions and migrate them to runok rules.

## Usage

```sh
runok init [options]
```

## Flags

### `--scope <scope>`

Configuration scope. Available values:

- `user` — Create `~/.config/runok/runok.yml` for global rules that apply to all projects. Also registers the runok PreToolUse hook in `~/.claude/settings.json` if Claude Code is detected.
- `project` — Create `runok.yml` in the current directory for project-specific rules.

When omitted, the wizard prompts you to choose.

### `-y`, `--yes`

Accept all defaults without prompting. Useful for scripted setups.

## What the wizard does

1. **Scope selection** — Choose `user` or `project` scope (skipped if `--scope` is given).
2. **Claude Code detection** — If a `.claude/settings.json` exists with Bash permissions or a missing runok hook, the wizard offers to:
- **Migrate Bash permissions** — Convert `permissions.allow` and `permissions.deny` entries for `Bash(...)` patterns into runok rules, and remove them from `settings.json`.
- **Register the hook** — Add the `runok check` PreToolUse hook to `settings.json` (user scope only).
3. **Preview and confirm** — Show a unified diff of all proposed changes and ask for confirmation.
4. **Create `runok.yml`** — Write the configuration file with migrated rules (if any) or a boilerplate template.

## Examples

Interactive setup (prompts for scope and options):

```sh
runok init
```

Set up user-global configuration non-interactively:

```sh
runok init --scope user -y
```

Set up project-local configuration:

```sh
runok init --scope project
```

## Related

- [Quick Start](/getting-started/quickstart/) — Getting started with runok.
- [Claude Code Integration](/getting-started/claude-code/) — Manual hook setup and sandbox configuration.
- [Configuration](/configuration/schema/) — Full configuration reference.
6 changes: 5 additions & 1 deletion docs/src/content/docs/cli/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ sidebar:
order: 1
---

runok provides two main subcommands for evaluating and executing commands against your permission rules.
runok provides subcommands for initializing configuration, evaluating commands, and executing them against your permission rules.

## Commands

### [`runok init`](/cli/init/)

Initialize runok configuration with an interactive setup wizard. Detects existing Claude Code Bash permissions and offers to migrate them to runok rules.

### [`runok check`](/cli/check/)

Evaluate a command against your rules and report the decision — without executing it. Useful for previewing what runok would do, or for integrating with external tools like [Claude Code hooks](/getting-started/claude-code/).
Expand Down
4 changes: 4 additions & 0 deletions docs/src/content/docs/getting-started/claude-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ runok integrates with [Claude Code](https://docs.anthropic.com/en/docs/claude-co

If you haven't already, follow the [Quick Start](/getting-started/quickstart/) to install runok and create a `runok.yml`.

:::tip
[`runok init --scope user`](/cli/init/) can automate steps 1 and 2: it creates a `runok.yml`, migrates existing Claude Code Bash permissions, and registers the hook — all in one command.
:::

## Step 2: Configure the PreToolUse hook

Add the runok hook to your Claude Code settings file (`.claude/settings.json`):
Expand Down
Loading
Loading