@gatebolt/cli 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,64 +0,0 @@
1
- # GateBolt × Claude Code — declare → observe recipe
2
-
3
- Files you copy into the repo your agent works in so a Claude Code session runs
4
- the GateBolt loop on its own: the agent **declares** the files it plans to touch
5
- before editing, and each turn's diff is **observed** and reconciled when the turn
6
- ends. Drives the [`gatebolt` CLI](../../README.md) — read that for what `declare`
7
- and `observe` do.
8
-
9
- ## What's in here
10
-
11
- | File | Copies to | Role |
12
- | --------------------------- | ------------------------------ | --------------------------------------------------- |
13
- | `settings.json` | `<repo>/.claude/settings.json` | Wires the `PreToolUse` guard + `Stop` observe hook |
14
- | `hooks/gatebolt-guard.sh` | `<repo>/.claude/hooks/` | Strict mode: deny `Edit`/`Write` until declared |
15
- | `hooks/gatebolt-observe.sh` | `<repo>/.claude/hooks/` | `Stop`: run `gatebolt observe` when a turn ends |
16
- | `hooks/pre-push` | `<repo>/.git/hooks/pre-push` | Backstop: refuse to push an un-observed declaration |
17
-
18
- Merge the `hooks` block if the repo already has a `.claude/settings.json`.
19
-
20
- ## Setup
21
-
22
- ```sh
23
- # 1. Copy the recipe in.
24
- cp hooks/gatebolt-*.sh <repo>/.claude/hooks/
25
- cp settings.json <repo>/.claude/settings.json
26
- cp hooks/pre-push <repo>/.git/hooks/pre-push
27
- chmod +x <repo>/.claude/hooks/gatebolt-*.sh <repo>/.git/hooks/pre-push
28
-
29
- # 2. Save a GateBolt profile for this repo once — paste the key when prompted.
30
- # The hooks call `gatebolt` with no flags; the profile is resolved automatically.
31
- npx @gatebolt/cli configure --profile <repo-slug> \
32
- --url https://your-gatebolt.app --repo <repo-slug>
33
-
34
- # 3. Launch Claude Code.
35
- export GATEBOLT_ENFORCE="strict" # or omit for lenient
36
- export GATEBOLT_CLI="npx @gatebolt/cli" # optional — omit if `gatebolt` is on PATH
37
- cd <repo> && claude
38
- ```
39
-
40
- **Prereqs:** `git`, `jq`, and the [`@gatebolt/cli`](../../README.md) client
41
- (`npm i -g @gatebolt/cli`). `GATEBOLT_CLI` is a command _prefix_ the hooks append
42
- to, defaulting to `gatebolt`; set it to `npx @gatebolt/cli` if you didn't install
43
- globally.
44
-
45
- ## The two modes (`GATEBOLT_ENFORCE`)
46
-
47
- - **`strict`** — the guard **denies** every `Edit`/`Write` until a declaration
48
- exists (holds even under `--dangerously-skip-permissions`) and tells the agent
49
- to run `gatebolt declare` first. That `Bash` call isn't blocked, so the agent
50
- declares, then edits go through.
51
- - **`lenient`** (default) — no block; declaring is an instructed step (e.g. a
52
- line in the repo's `CLAUDE.md`). The pre-push backstop guarantees nothing lands
53
- undeclared.
54
-
55
- ## Notes and limits
56
-
57
- - **One turn ≈ one change.** `Stop` fires every turn, so `observe` reconciles and
58
- clears the session each turn; strict mode re-declares next turn.
59
- - **Rate limit.** Two API calls per change, and the default key limit is low
60
- (10/day today, surfacing as `401` when hit). Use a fresh key when iterating.
61
- - **Backstop is v1.** Catches only an open, un-observed declaration (the
62
- Esc-interrupt case), not work that was never declared — a follow-up.
63
- - **Watch over-broad declarations.** Declaring `src/**` to dodge the block kills
64
- the drift signal, like an empty declaration. The deny asks for specific paths.
@@ -1,48 +0,0 @@
1
- #!/usr/bin/env bash
2
- # GateBolt strict-mode PreToolUse guard — blocks Edit/Write until a declaration
3
- # exists for this change. Opt-in via GATEBOLT_ENFORCE=strict.
4
- set -u
5
-
6
- # Drain stdin so the hook's pipe doesn't block; we don't need the payload.
7
- cat >/dev/null
8
-
9
- [ "${GATEBOLT_ENFORCE:-lenient}" = "strict" ] || exit 0
10
-
11
- project_dir="${CLAUDE_PROJECT_DIR:-$PWD}"
12
- git_dir=$(git -C "$project_dir" rev-parse --git-dir 2>/dev/null) || exit 0
13
- case "$git_dir" in
14
- /*) ;;
15
- *) git_dir="$project_dir/$git_dir" ;;
16
- esac
17
-
18
- # session.json exists = already declared → allow the edit.
19
- [ -f "$git_dir/gatebolt/session.json" ] && exit 0
20
-
21
- cli="${GATEBOLT_CLI:-gatebolt}"
22
- reason="GateBolt strict mode: declare the files you plan to touch before editing.
23
- Run this in Bash first, listing EVERY file you plan to create or modify for this
24
- task — specific repo-relative paths, not broad globs like src/** :
25
-
26
- $cli declare \\
27
- --task \"<one line describing the task>\" \\
28
- --vendor claude_code --name \"Claude Code\" --model <your-model-id> \\
29
- --file <path> [--file <path> ...]
30
-
31
- GBOLT_KEY, GBOLT_URL and GBOLT_REPO are already set in your environment. Once it
32
- prints \"Declared change …\", retry the edit."
33
-
34
- # JSON deny holds even under --dangerously-skip-permissions; without jq we fall
35
- # back to exit-2, which re-prompts but isn't guaranteed under bypass.
36
- if command -v jq >/dev/null 2>&1; then
37
- jq -n --arg r "$reason" '{
38
- hookSpecificOutput: {
39
- hookEventName: "PreToolUse",
40
- permissionDecision: "deny",
41
- permissionDecisionReason: $r
42
- }
43
- }'
44
- exit 0
45
- fi
46
-
47
- printf '%s\n' "$reason" >&2
48
- exit 2
@@ -1,24 +0,0 @@
1
- #!/usr/bin/env bash
2
- # GateBolt Stop hook — runs `gatebolt observe` to reconcile the diff when a turn
3
- # ends. Advisory; never blocks the turn.
4
- set -u
5
-
6
- # Drain stdin; observe reads its target from the session file.
7
- cat >/dev/null
8
-
9
- cd "${CLAUDE_PROJECT_DIR:-$PWD}" || exit 0
10
-
11
- git_dir=$(git rev-parse --git-dir 2>/dev/null) || exit 0
12
- case "$git_dir" in
13
- /*) ;;
14
- *) git_dir="$PWD/$git_dir" ;;
15
- esac
16
-
17
- # Stop fires every turn; only reconcile when a declaration is actually open.
18
- [ -f "$git_dir/gatebolt/session.json" ] || exit 0
19
-
20
- cli="${GATEBOLT_CLI:-gatebolt}"
21
- # GATEBOLT_CLI is a command prefix; word-splitting is intentional.
22
- # shellcheck disable=SC2086
23
- $cli observe 2>&1 || true
24
- exit 0
@@ -1,23 +0,0 @@
1
- #!/usr/bin/env bash
2
- # GateBolt pre-push backstop — refuses to push while a declaration is still open
3
- # but un-observed (the Esc-interrupt case Stop misses). Needs gatebolt's env
4
- # (GBOLT_KEY / GBOLT_URL / GATEBOLT_CLI) exported in the shell you push from.
5
- set -u
6
-
7
- git_dir=$(git rev-parse --git-dir 2>/dev/null) || exit 0
8
- case "$git_dir" in
9
- /*) ;;
10
- *) git_dir="$PWD/$git_dir" ;;
11
- esac
12
-
13
- [ -f "$git_dir/gatebolt/session.json" ] || exit 0
14
-
15
- cli="${GATEBOLT_CLI:-gatebolt}"
16
- echo "GateBolt: an un-observed declaration is still open; reconciling before push…" >&2
17
- # shellcheck disable=SC2086
18
- if ! $cli observe >&2; then
19
- echo "GateBolt: observe failed — refusing to push unreconciled work." >&2
20
- echo "Resolve the error above (or run '$cli observe' yourself), then push again." >&2
21
- exit 1
22
- fi
23
- exit 0
@@ -1,25 +0,0 @@
1
- {
2
- "hooks": {
3
- "PreToolUse": [
4
- {
5
- "matcher": "Edit|Write",
6
- "hooks": [
7
- {
8
- "type": "command",
9
- "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/gatebolt-guard.sh"
10
- }
11
- ]
12
- }
13
- ],
14
- "Stop": [
15
- {
16
- "hooks": [
17
- {
18
- "type": "command",
19
- "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/gatebolt-observe.sh"
20
- }
21
- ]
22
- }
23
- ]
24
- }
25
- }