@gatebolt/cli 0.4.0 → 0.6.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.
- package/README.md +60 -17
- package/dist/agents/claude-code.js +183 -0
- package/dist/commands/configure.js +8 -11
- package/dist/commands/declare.js +50 -9
- package/dist/commands/hook.js +128 -0
- package/dist/commands/init.js +222 -0
- package/dist/commands/link.js +59 -0
- package/dist/commands/login.js +317 -0
- package/dist/commands/observe.js +16 -10
- package/dist/config.js +48 -12
- package/dist/contracts.js +6 -0
- package/dist/diff.js +2 -1
- package/dist/errors.js +10 -8
- package/dist/git.js +17 -0
- package/dist/help.js +81 -14
- package/dist/index.js +12 -0
- package/dist/profiles.js +68 -15
- package/dist/rest.js +49 -0
- package/dist/session.js +2 -1
- package/dist/transport.js +32 -12
- package/package.json +2 -3
- package/recipes/claude-code/README.md +0 -64
- package/recipes/claude-code/hooks/gatebolt-guard.sh +0 -48
- package/recipes/claude-code/hooks/gatebolt-observe.sh +0 -24
- package/recipes/claude-code/hooks/pre-push +0 -23
- package/recipes/claude-code/settings.json +0 -25
|
@@ -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
|
-
}
|