@guilz-dev/belay 0.1.0 → 0.1.1

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 CHANGED
@@ -8,10 +8,10 @@
8
8
 
9
9
  [Documentation (日本語)](./docs/README.ja.md)
10
10
 
11
- `@guilz-dev/belay` hooks into agent runtimes (Cursor, Claude Code) and inspects
12
- each shell command, subagent launch, and file mutation *before* it runs. Most
13
- actions pass through untouched. Only the irreversible-and-catastrophic ones are
14
- held back for one-shot human approval — and every decision is written to an
11
+ `@guilz-dev/belay` hooks into agent runtimes (Cursor, Claude Code, Codex) and
12
+ inspects each shell command, subagent launch, and file mutation *before* it runs.
13
+ Most actions pass through untouched. Only the irreversible-and-catastrophic ones
14
+ are held back for one-shot human approval — and every decision is written to an
15
15
  audit log.
16
16
 
17
17
  <p align="center">
@@ -21,6 +21,30 @@ audit log.
21
21
  > **0.0.x early release** — APIs and behavior may change. Cursor and Claude Code
22
22
  > are the supported adapters; Codex is experimental.
23
23
 
24
+ ## Supported agents
25
+
26
+ Belay works across three coding agents. Each one runs the **same classifier**,
27
+ wired in through that agent's native **hook** mechanism — no agent-specific
28
+ policy to maintain.
29
+
30
+ | Agent | Status | Hook config | belay config |
31
+ |-------|--------|-------------|--------------|
32
+ | **Cursor** | Supported | `.cursor/hooks.json` | `.cursor/belay.config.json` |
33
+ | **Claude Code** | Supported | `.claude/settings.json` | `.claude/belay.config.json` |
34
+ | **Codex** | Experimental | `.codex/config.toml` | `.codex/belay.config.json` |
35
+
36
+ Pick the adapter at install time with `--adapter cursor|claude|codex` (or let
37
+ `init-wizard` prompt). Hosts use different hook event names, but Belay registers
38
+ the same runners (`belay-tool-gate`, `belay-before-submit`, `belay-audit`) at
39
+ equivalent lifecycle points:
40
+
41
+ | Role | belay hook | Cursor | Claude Code | Codex |
42
+ |------|-----------|--------|-------------|-------|
43
+ | Gate shell / tools / file mutations | `belay-tool-gate` | `beforeShellExecution`, `preToolUse` | `PreToolUse` | `PreToolUse` |
44
+ | Gate subagent launches | `belay-tool-gate` | `subagentStart` | (via `PreToolUse`) | `SubagentStart` |
45
+ | One-shot approvals | `belay-before-submit` | `beforeSubmitPrompt` | `UserPromptSubmit` | `UserPromptSubmit` |
46
+ | Audit log | `belay-audit` | `postToolUse`, `stop`, `sessionEnd` | `PostToolUse` | `PostToolUse` |
47
+
24
48
  ## Why
25
49
 
26
50
  Static denylists don't work for agents. The same command (`rm`, `curl`, a
@@ -48,6 +72,7 @@ npx @guilz-dev/belay init-wizard
48
72
 
49
73
  # Or non-interactive
50
74
  npx @guilz-dev/belay init --adapter claude # Claude Code
75
+ npx @guilz-dev/belay init --adapter codex # Codex (experimental)
51
76
  npx @guilz-dev/belay init # Cursor (default)
52
77
  ```
53
78
 
@@ -64,10 +89,10 @@ verdict and `overrides.allow` to whitelist commands you trust.
64
89
 
65
90
  ## How it works
66
91
 
67
- Belay registers hooks on the host runtime (`.cursor/hooks.json` or
68
- `.claude/settings.json`) and gates shell execution, subagent launches, and file
69
- mutations through one shared classifier. It always forms its own judgment — it
70
- does not trust an assessment supplied by the agent.
92
+ Belay registers hooks on the host runtime (`.cursor/hooks.json`,
93
+ `.claude/settings.json`, or `.codex/config.toml`) and gates shell execution,
94
+ subagent launches, and file mutations through one shared classifier. It always
95
+ forms its own judgment — it does not trust an assessment supplied by the agent.
71
96
 
72
97
  Every gated action gets one of three verdicts:
73
98
 
@@ -84,7 +109,8 @@ When an action is denied, approve the **next matching action once** by sending:
84
109
  ```
85
110
 
86
111
  Approvals are one-shot and expire after 15 minutes by default. Every decision is
87
- written to `.cursor/belay/audit.ndjson` (or `.claude/belay/audit.ndjson`).
112
+ written to `.cursor/belay/audit.ndjson`, `.claude/belay/audit.ndjson`, or
113
+ `.codex/belay/audit.ndjson` (depending on the adapter).
88
114
 
89
115
  In **audit mode** (`mode: "audit"`), would-be denials are recorded
90
116
  (`wouldBlock: true`) but execution still continues, and no approval IDs are
@@ -247,6 +273,14 @@ Belay state files are local runtime artifacts and should usually stay out of git
247
273
  .cursor/hooks/belay-*
248
274
  .cursor/skills/belay/
249
275
  .cursor/commands/belay-approve.md
276
+
277
+ .claude/belay/
278
+ .claude/belay.config.json
279
+ .claude/hooks/belay-*
280
+
281
+ .codex/belay/
282
+ .codex/belay.config.json
283
+ .codex/hooks/belay-*
250
284
  ```
251
285
 
252
286
  ## Library exports
package/dist/cli.js CHANGED
@@ -16,9 +16,16 @@ import { loadConfigFile } from './config-io.js';
16
16
  import { initProject, upgradeProject } from './installer.js';
17
17
  import { egressEnv, egressStatus, formatEgressStatusReport, startEgressProxy, stopEgressProxy, } from './services/egress-service.js';
18
18
  import { formatSandboxStatusReport, sandboxStatus } from './services/sandbox-service.js';
19
+ import { PACKAGE_VERSION } from './version.js';
19
20
  function parseArgs(argv) {
20
21
  const [command, ...rest] = argv;
21
22
  const options = {};
23
+ if (!command || command === '--help' || command === '-h') {
24
+ return { command: 'help', options };
25
+ }
26
+ if (command === '--version' || command === '-V') {
27
+ return { command: 'version', options };
28
+ }
22
29
  for (let index = 0; index < rest.length; index += 1) {
23
30
  const token = rest[index];
24
31
  if (token === '--with-skill') {
@@ -349,6 +356,10 @@ async function main() {
349
356
  printHelp();
350
357
  return;
351
358
  }
359
+ if (command === 'version') {
360
+ process.stdout.write(`${PACKAGE_VERSION}\n`);
361
+ return;
362
+ }
352
363
  if (command === 'init-wizard') {
353
364
  const { runInitWizard } = await import('./commands/init-wizard.js');
354
365
  const result = await runInitWizard({ targetDir: options.targetDir });
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const PACKAGE_VERSION = "0.0.1";
1
+ export declare const PACKAGE_VERSION = "0.1.1";
package/dist/version.js CHANGED
@@ -1 +1,2 @@
1
- export const PACKAGE_VERSION = '0.0.1';
1
+ // Generated by scripts/sync-version.mjs — do not edit.
2
+ export const PACKAGE_VERSION = '0.1.1';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guilz-dev/belay",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Belay-style approval and audit gating for agent runtimes.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -48,7 +48,9 @@
48
48
  "agent-belay-logo.png"
49
49
  ],
50
50
  "scripts": {
51
- "build": "rm -rf dist && tsc -p tsconfig.build.json && node scripts/build-runtime.mjs",
51
+ "build": "rm -rf dist && node scripts/sync-version.mjs && tsc -p tsconfig.build.json && node scripts/build-runtime.mjs",
52
+ "check:version": "node scripts/check-cli-version.mjs",
53
+ "prepublishOnly": "pnpm build && node scripts/check-cli-version.mjs",
52
54
  "lint": "biome check src package.json README.md CHANGELOG.md CONTRIBUTING.md SECURITY.md tsconfig.json tsconfig.build.json vitest.config.ts scripts docs",
53
55
  "typecheck": "tsc --noEmit",
54
56
  "test": "pnpm build && vitest run",
@@ -2,16 +2,30 @@
2
2
  name: belay
3
3
  description: >-
4
4
  Guides approval when belay blocks a high-risk shell command, subagent launch,
5
- or tool action. Use when an action is denied, blocked, or needs belay-approve, or when
6
- installing or checking belay hook health in a repository.
5
+ or tool action across Cursor, Claude Code, and Codex. Use when an action is
6
+ denied, blocked, or needs belay-approve, or when installing or checking belay
7
+ hook health in a repository.
7
8
  disable-model-invocation: true
8
9
  ---
9
10
 
10
11
  # Belay
11
12
 
12
- Belay installs repo-local hooks that gate high-risk shell commands, tool actions, and
13
- subagent launches. Enforcement lives in hooks; this skill only explains the flow and
14
- routes you to the CLI. It does not classify commands itself.
13
+ Belay is a safety gate for coding agents: it inspects each shell command,
14
+ subagent launch, and file mutation *before* it runs, lets safe-and-local actions
15
+ through, and holds back only the irreversible-and-catastrophic ones for one-shot
16
+ human approval. Every decision is written to an audit log.
17
+
18
+ It runs on **Cursor**, **Claude Code**, and **Codex (experimental)**, wiring the
19
+ same classifier into each agent through its native hooks:
20
+
21
+ | Agent | Hook config |
22
+ | --- | --- |
23
+ | Cursor | `.cursor/hooks.json` |
24
+ | Claude Code | `.claude/settings.json` |
25
+ | Codex | `.codex/config.toml` |
26
+
27
+ Enforcement lives in those hooks; this skill only explains the flow and routes
28
+ you to the CLI. It does not classify commands itself.
15
29
 
16
30
  ## Prerequisites
17
31