@scopebond/hook 0.5.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 +52 -6
- package/dist/cli.js +64 -8
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +2 -9
- package/dist/init.js.map +1 -1
- package/dist/install.d.ts +18 -1
- package/dist/install.d.ts.map +1 -1
- package/dist/install.js +84 -19
- package/dist/install.js.map +1 -1
- package/dist/map.d.ts +6 -3
- package/dist/map.d.ts.map +1 -1
- package/dist/map.js +762 -60
- package/dist/map.js.map +1 -1
- package/dist/minimize.d.ts +6 -3
- package/dist/minimize.d.ts.map +1 -1
- package/dist/minimize.js +24 -4
- package/dist/minimize.js.map +1 -1
- package/dist/runtime.d.ts +4 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +75 -9
- package/dist/runtime.js.map +1 -1
- package/dist/shell.d.ts +53 -4
- package/dist/shell.d.ts.map +1 -1
- package/dist/shell.js +737 -81
- package/dist/shell.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -23,8 +23,11 @@ scaffolds a user-level home (`~/.scopebond`, override `SCOPEBOND_HOME`) with a
|
|
|
23
23
|
signing key, a countersigning key and a starter policy, and registers the hook by
|
|
24
24
|
absolute path in your user-level `~/.claude/settings.json`, `~/.cursor/hooks.json`,
|
|
25
25
|
or `~/.codex/hooks.json`. After Codex setup, open Codex, run `/hooks`, review
|
|
26
|
-
Scopebond, and choose **Trust** once. Every project you open is then governed
|
|
27
|
-
`.scopebond
|
|
26
|
+
Scopebond, and choose **Trust** once. Every project you open is then governed by your
|
|
27
|
+
user-level policy. A project's own `.scopebond/policy.json` applies only after you trust it
|
|
28
|
+
in that project (`scopebond trust`, or `init` there), pinned to its exact contents: a
|
|
29
|
+
repository you clone, or an agent working in it, cannot swap in a weaker policy, and any
|
|
30
|
+
later edit to that file stops it applying until you trust it again.
|
|
28
31
|
|
|
29
32
|
```
|
|
30
33
|
scopebond status # home, which agents are configured, cloud, receipts
|
|
@@ -54,7 +57,8 @@ npx @scopebond/hook init --codex # Codex, then approve it once with /hooks
|
|
|
54
57
|
countersigning key, a starter policy — "protect main and production paths" — and a
|
|
55
58
|
`.gitignore` so none of it is committed) and configures `.claude/settings.json`,
|
|
56
59
|
`.cursor/hooks.json`, or `.codex/hooks.json`. Then run one safe command in the agent and see the receipt in
|
|
57
|
-
`.scopebond/receipts.db`.
|
|
60
|
+
`.scopebond/receipts.db`. `init`, `trust` and `uninstall` are meant for a person at a
|
|
61
|
+
terminal: in a script or CI, pass `--yes`.
|
|
58
62
|
|
|
59
63
|
## Connect it to your workspace (optional)
|
|
60
64
|
|
|
@@ -95,9 +99,51 @@ recorded as *not evaluated* and grant nothing. Anything unexpected fails closed
|
|
|
95
99
|
Commands are stored as a scrubbed head plus a digest; file contents are never
|
|
96
100
|
stored; common secret shapes are removed before signing.
|
|
97
101
|
|
|
98
|
-
**
|
|
99
|
-
|
|
100
|
-
|
|
102
|
+
**What a shell command is checked for.** A command line is split into every command it
|
|
103
|
+
runs (`&&`, `;`, pipes, `$( )` and backticks — also inside double quotes — `bash -c`,
|
|
104
|
+
`eval`, `trap`, `su -c`, `script -c`, `watch`, `parallel`, `cmd /c`, `pwsh -Command`
|
|
105
|
+
and `-EncodedCommand`, `find -exec`, `env -S`), with shell keywords and grouping
|
|
106
|
+
(`if … then`, `for … do`, `{ … }`, `!`, `case`) and wrappers (`sudo`, `env`, `time`,
|
|
107
|
+
`nice`, `xargs`, `timeout`, `strace`, `busybox` …, each with its own option arity)
|
|
108
|
+
stripped so the real program is seen; the wrappers are checked too. Each command is
|
|
109
|
+
checked as a program, and the files it reads or writes are checked like the Read and
|
|
110
|
+
Write tools: operands of programs that output or copy file content (`cat`, `grep`,
|
|
111
|
+
`tar`, …), copies and moves (`cp`, `mv`, `rsync`, `scp`, `Copy-Item`), writers and
|
|
112
|
+
editors (`tee`, `touch`, `sed -i`, `yq -i`, `ed`, `vim`, `Set-Content`), git's own writes
|
|
113
|
+
(`checkout -- p`, `restore`, `mv`, `rm`, `config core.hooksPath`), secrets sent or staged
|
|
114
|
+
(`curl -T`, `-d @file`, `gh gist create`, `git add`) and redirections, including
|
|
115
|
+
`x>file` without spaces. Existence and metadata checks (`ls`, `test -f`, `[ -f ]`,
|
|
116
|
+
`stat`) and a secret file's name in a string are not reads. Paths are compared
|
|
117
|
+
case-insensitively; Windows `\` paths, 8.3 short names (`CLAUDE~1`), `::$DATA` streams
|
|
118
|
+
and trailing dots are normalized; and a glob, variable or brace list that could name a
|
|
119
|
+
protected file or directory (`.scope*/agent.key`, `.*/*`, `$HOME/.ssh/id_rsa`) is
|
|
120
|
+
treated as that file. Every destination of a `git push` is checked in the common
|
|
121
|
+
spellings (`refs/heads/main`, `HEAD:main`, a second refspec, `--repo`, `--all`,
|
|
122
|
+
`--mirror`); a push whose destination is not on the command line (a git alias, a
|
|
123
|
+
configured push refspec, `send-pack`) is denied, and a tags-only push is allowed. The
|
|
124
|
+
agent running the hook's own `init`, `install`, `trust`, `uninstall` or `connect` is
|
|
125
|
+
denied, and those commands also refuse a non-interactive terminal unless `--yes` is
|
|
126
|
+
passed.
|
|
127
|
+
|
|
128
|
+
**Limits.** The hook sees the command text, not what a program does at run time. It
|
|
129
|
+
does not follow a variable whose value it cannot see (`cat $FILE`), a path assembled
|
|
130
|
+
inside a script or interpreter (`python script.py`), aliases and functions defined in
|
|
131
|
+
an earlier call, git aliases from a config file, recursive reads of a parent of a
|
|
132
|
+
protected directory (`grep -r . `, `cp -r ~ /tmp`), or deletion expressed as arguments
|
|
133
|
+
(`find -delete`, `git clean`). Commands whose written files are named only inside their
|
|
134
|
+
input — `patch`, `git apply`, `git am`, `tar x`, `unzip`, `7z x`, `cpio -i` — are
|
|
135
|
+
recorded with an unevaluated write: allowed in normal mode, denied in strict mode.
|
|
136
|
+
Reading any `*.pem` file is denied, including a public certificate, because a PEM file
|
|
137
|
+
is often a private key. For stronger guarantees, run the agent behind the Scopebond
|
|
138
|
+
gateway or in a sandbox; the hook is a guardrail for a cooperating agent, not a jail.
|
|
139
|
+
|
|
140
|
+
**Strict mode.** A shell command that cannot be parsed (an unbalanced quote) or whose
|
|
141
|
+
program is only known at run time (`$cmd`, `$(…) args`) is checked with an empty
|
|
142
|
+
program name, which the starter policy denies in every mode — edit the `safe-shell`
|
|
143
|
+
clause to change that. By default a tool with no taxonomy mapping, or a write whose
|
|
144
|
+
target the command text does not name, is recorded *not evaluated* (not blocked). Add
|
|
145
|
+
`--strict` (or `SCOPEBOND_HOOK_STRICT=1`) to deny those too — fail-closed coverage for
|
|
146
|
+
anything the taxonomy does not map.
|
|
101
147
|
|
|
102
148
|
## Library
|
|
103
149
|
|
package/dist/cli.js
CHANGED
|
@@ -5,13 +5,14 @@
|
|
|
5
5
|
// scopebond-hook claude evaluate a Claude Code PreToolUse call (stdin JSON)
|
|
6
6
|
// scopebond-hook cursor evaluate a Cursor hook event (stdin JSON)
|
|
7
7
|
// scopebond-hook codex evaluate a Codex PreToolUse call (stdin JSON)
|
|
8
|
-
// scopebond-hook init [--cursor|--codex] [--no-install]
|
|
8
|
+
// scopebond-hook init [--cursor|--codex] [--no-install] [--yes]
|
|
9
9
|
// scopebond-hook connect <url> <bundle.json> [--cursor|--codex]
|
|
10
10
|
// enroll with a Cloud workspace and start exporting
|
|
11
11
|
// scopebond-hook log [-n N] show the most recent local receipts
|
|
12
12
|
// scopebond-hook verify verify every local receipt offline against the attester key
|
|
13
13
|
// scopebond-hook test "<shell command>" show the decision for a command without recording it
|
|
14
14
|
// scopebond-hook flush deliver any queued receipts to Cloud now
|
|
15
|
+
// scopebond-hook trust [--yes] let this project's .scopebond policy govern here (pinned)
|
|
15
16
|
//
|
|
16
17
|
// Config dir: $SCOPEBOND_HOOK_DIR, else ./.scopebond
|
|
17
18
|
// Fail-closed: any error denies the action with a repair message.
|
|
@@ -24,7 +25,7 @@ import { openReceiptStore, loadOrCreateAttester } from "@scopebond/gateway/node"
|
|
|
24
25
|
import { mapClaudeToolUse, mapCodexToolUse, mapCursorEvent, fillPushBranch } from "./map.js";
|
|
25
26
|
import { createHookRuntime } from "./runtime.js";
|
|
26
27
|
import { scaffold, harnessSnippet, installHarness } from "./init.js";
|
|
27
|
-
import { userHome, userHarnessFile, resolveConfigDir, writeHarnessConfig, removeHarnessConfig, cursorDetected, codexDetected, absoluteHookCommand, isHarnessConfigured, purgeHome, } from "./install.js";
|
|
28
|
+
import { userHome, userHarnessFile, resolveConfigDir, writeHarnessConfig, removeHarnessConfig, cursorDetected, codexDetected, absoluteHookCommand, isHarnessConfigured, purgeHome, trustProjectPolicy, untrustedProjectPolicy, } from "./install.js";
|
|
28
29
|
import { connectCloud, loadConnection } from "./cloud.js";
|
|
29
30
|
import { cliCommand, hookVersion } from "./version.js";
|
|
30
31
|
import { fileURLToPath } from "node:url";
|
|
@@ -162,18 +163,43 @@ async function runCursor() {
|
|
|
162
163
|
process.stdout.write(JSON.stringify({ permission, agentMessage: message }) + "\n");
|
|
163
164
|
process.exit(0);
|
|
164
165
|
}
|
|
166
|
+
/** `init`, `trust` and `uninstall` change what governs the agent, so they are for a
|
|
167
|
+
* person at a terminal. A coding agent's shell is not interactive: without a TTY on
|
|
168
|
+
* stdin they refuse unless `--yes` is passed (for scripts and CI). The starter policy
|
|
169
|
+
* also denies the agent running them. */
|
|
170
|
+
function requireInteractive(command, args) {
|
|
171
|
+
if (process.stdin.isTTY || args.includes("--yes"))
|
|
172
|
+
return;
|
|
173
|
+
console.error(`scopebond ${command} changes what governs your coding agent, so it must be run from an interactive terminal.`);
|
|
174
|
+
console.error(`In a script or CI, pass --yes: ${cliCommand(`${command} --yes`)}`);
|
|
175
|
+
process.exit(1);
|
|
176
|
+
}
|
|
165
177
|
function runInit(args) {
|
|
178
|
+
requireInteractive("init", args);
|
|
166
179
|
const harness = selectedHarness(args);
|
|
167
180
|
const dir = configDir();
|
|
168
181
|
const { agentKid, policyPath } = scaffold(dir, { force: args.includes("--force") });
|
|
169
182
|
console.log(`Scopebond hook enrolled in ${dir}`);
|
|
170
183
|
console.log(` machine key ${agentKid}`);
|
|
171
184
|
console.log(` policy ${policyPath} (starter — edit the limits)`);
|
|
185
|
+
// With a user-level install present, a project policy governs only once trusted.
|
|
186
|
+
// Running init here is that decision, so pin this policy now.
|
|
187
|
+
if (!process.env.SCOPEBOND_HOOK_DIR && existsSync(join(userHome(), "policy.json"))) {
|
|
188
|
+
trustProjectPolicy(dir);
|
|
189
|
+
console.log(` trusted overrides ${userHome()} here; after editing it, run \`${cliCommand("trust")}\``);
|
|
190
|
+
}
|
|
172
191
|
console.log("");
|
|
173
192
|
// Configure the agent automatically by default (idempotent), so there is no
|
|
174
193
|
// hand-editing step; --no-install prints the snippet instead.
|
|
175
194
|
if (!args.includes("--no-install")) {
|
|
176
|
-
|
|
195
|
+
let file;
|
|
196
|
+
try {
|
|
197
|
+
file = installHarness(harness);
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
console.error(error.message);
|
|
201
|
+
process.exit(1);
|
|
202
|
+
}
|
|
177
203
|
console.log(`✓ ${harnessName(harness)} configured in ${file}`);
|
|
178
204
|
if (harness === "codex")
|
|
179
205
|
console.log(`\nOne last step: ${codexTrustStep}`);
|
|
@@ -374,8 +400,14 @@ function runInstall(args) {
|
|
|
374
400
|
: ["claude", ...(cursorDetected() ? ["cursor"] : []), ...(codexDetected() ? ["codex"] : [])];
|
|
375
401
|
if (!args.includes("--no-install")) {
|
|
376
402
|
for (const h of harnesses) {
|
|
377
|
-
|
|
378
|
-
|
|
403
|
+
try {
|
|
404
|
+
const file = writeHarnessConfig(userHarnessFile(h), h, absoluteHookCommand(cliPath(), h));
|
|
405
|
+
console.log(`✓ ${harnessName(h)} configured in ${file}`);
|
|
406
|
+
}
|
|
407
|
+
catch (error) {
|
|
408
|
+
console.error(`✗ ${harnessName(h)}: ${error.message}`);
|
|
409
|
+
process.exitCode = 1;
|
|
410
|
+
}
|
|
379
411
|
}
|
|
380
412
|
}
|
|
381
413
|
else {
|
|
@@ -385,7 +417,7 @@ function runInstall(args) {
|
|
|
385
417
|
if (harnesses.includes("codex"))
|
|
386
418
|
console.log(`\nOne last step for Codex: ${codexTrustStep}`);
|
|
387
419
|
console.log("");
|
|
388
|
-
console.log(
|
|
420
|
+
console.log(`A project's own .scopebond policy applies only after you trust it there (${cliCommand("trust")}).`);
|
|
389
421
|
console.log(`Check it: ${cliCommand("doctor")} · see decisions: ${cliCommand("log")}`);
|
|
390
422
|
console.log(`To send receipts to a workspace: ${cliCommand("connect <workspace-url> <enrollment>")}`);
|
|
391
423
|
}
|
|
@@ -400,7 +432,10 @@ function runStatus() {
|
|
|
400
432
|
console.log(`Scopebond hook ${hookVersion()}`);
|
|
401
433
|
console.log(` user home ${home} ${installed ? "(installed)" : "(not installed — run `scopebond install`)"}`);
|
|
402
434
|
console.log(` active config ${resolveConfigDir(process.cwd())}`);
|
|
403
|
-
|
|
435
|
+
const ignored = untrustedProjectPolicy(process.cwd());
|
|
436
|
+
if (ignored)
|
|
437
|
+
console.log(` project policy ${ignored} ignored — not trusted (run \`${cliCommand("trust")}\` to use it)`);
|
|
438
|
+
console.log(` Claude Code ${claude ? "configured" : "not configured"}`);
|
|
404
439
|
console.log(` Cursor ${cursor ? "configured" : cursorDetected() ? "detected, not configured" : "not detected"}`);
|
|
405
440
|
console.log(` Codex ${codex ? "configured (approve once with /hooks)" : codexDetected() ? "detected, not configured" : "not detected"}`);
|
|
406
441
|
console.log(` cloud workspace ${connected ? "connected" : "not connected (local only)"}`);
|
|
@@ -421,6 +456,9 @@ async function runDoctor() {
|
|
|
421
456
|
console.log(` active config ${active} ${hasPolicy ? "ok" : "no policy (run `scopebond install` or `init`)"}`);
|
|
422
457
|
if (!hasPolicy)
|
|
423
458
|
problems.push("no policy found in the active config dir");
|
|
459
|
+
const ignored = untrustedProjectPolicy(process.cwd());
|
|
460
|
+
if (ignored)
|
|
461
|
+
console.log(` project policy ${ignored} IGNORED — not trusted (never trusted, or edited since). Review it, then \`${cliCommand("trust")}\``);
|
|
424
462
|
const codex = isHarnessConfigured(userHarnessFile("codex"));
|
|
425
463
|
console.log(` Codex hook ${codex ? "configured" : codexDetected() ? "not configured — run `scopebond install --codex`" : "not detected"}`);
|
|
426
464
|
if (codex)
|
|
@@ -444,6 +482,7 @@ async function runDoctor() {
|
|
|
444
482
|
process.exitCode = problems.length ? 1 : 0;
|
|
445
483
|
}
|
|
446
484
|
function runUninstall(args) {
|
|
485
|
+
requireInteractive("uninstall", args);
|
|
447
486
|
let removed = 0;
|
|
448
487
|
for (const h of ["claude", "cursor", "codex"]) {
|
|
449
488
|
if (removeHarnessConfig(userHarnessFile(h))) {
|
|
@@ -460,6 +499,20 @@ function runUninstall(args) {
|
|
|
460
499
|
else
|
|
461
500
|
console.log(`Kept ${userHome()} (keys, policy, receipts). Use --purge to remove it too.`);
|
|
462
501
|
}
|
|
502
|
+
/** `trust` — let this project's .scopebond policy govern here instead of the user
|
|
503
|
+
* home, pinned to its current contents. Run by the user, not the agent: the file it
|
|
504
|
+
* writes lives in the user home, which the starter policy write-protects. */
|
|
505
|
+
function runTrust(args) {
|
|
506
|
+
requireInteractive("trust", args);
|
|
507
|
+
const dir = join(process.cwd(), ".scopebond");
|
|
508
|
+
if (!existsSync(join(dir, "policy.json"))) {
|
|
509
|
+
console.error(`no project policy at ${join(dir, "policy.json")}`);
|
|
510
|
+
process.exit(1);
|
|
511
|
+
}
|
|
512
|
+
const digest = trustProjectPolicy(dir);
|
|
513
|
+
console.log(`✓ trusted ${join(dir, "policy.json")} (sha256 ${digest.slice(0, 12)}…)`);
|
|
514
|
+
console.log("It governs agents in this project until it changes; after any edit, review it and run trust again.");
|
|
515
|
+
}
|
|
463
516
|
function runLogin() {
|
|
464
517
|
console.log("Device-code login is not available yet.");
|
|
465
518
|
console.log(`For now, connect with a one-time enrollment from your workspace:`);
|
|
@@ -509,8 +562,11 @@ else if (cmd === "uninstall") {
|
|
|
509
562
|
else if (cmd === "login") {
|
|
510
563
|
runLogin();
|
|
511
564
|
}
|
|
565
|
+
else if (cmd === "trust") {
|
|
566
|
+
runTrust(rest);
|
|
567
|
+
}
|
|
512
568
|
else {
|
|
513
|
-
console.error("usage: scopebond <claude|cursor|codex|init|install|connect|log|verify|test|flush|status|doctor|uninstall|login> [--cursor] [--claude] [--codex] [--force] [--strict] [--no-install] [--purge]");
|
|
569
|
+
console.error("usage: scopebond <claude|cursor|codex|init|install|connect|log|verify|test|flush|status|doctor|uninstall|login|trust> [--cursor] [--claude] [--codex] [--force] [--strict] [--no-install] [--purge] [--yes]");
|
|
514
570
|
process.exit(1);
|
|
515
571
|
}
|
|
516
572
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n// scopebond-hook — govern a coding agent's tool calls against policy, in-path,\n// before they run, with a signed local receipt.\n//\n// scopebond-hook claude evaluate a Claude Code PreToolUse call (stdin JSON)\n// scopebond-hook cursor evaluate a Cursor hook event (stdin JSON)\n// scopebond-hook codex evaluate a Codex PreToolUse call (stdin JSON)\n// scopebond-hook init [--cursor|--codex] [--no-install]\n// scopebond-hook connect <url> <bundle.json> [--cursor|--codex]\n// enroll with a Cloud workspace and start exporting\n// scopebond-hook log [-n N] show the most recent local receipts\n// scopebond-hook verify verify every local receipt offline against the attester key\n// scopebond-hook test \"<shell command>\" show the decision for a command without recording it\n// scopebond-hook flush deliver any queued receipts to Cloud now\n//\n// Config dir: $SCOPEBOND_HOOK_DIR, else ./.scopebond\n// Fail-closed: any error denies the action with a repair message.\n\nimport { readFileSync, existsSync, mkdtempSync, rmSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport { execFileSync } from \"node:child_process\";\nimport type { CloudEnrollmentBundle } from \"@scopebond/gateway\";\nimport { verifyReceipt } from \"@scopebond/gateway\";\nimport { openReceiptStore, loadOrCreateAttester } from \"@scopebond/gateway/node\";\nimport { mapClaudeToolUse, mapCodexToolUse, mapCursorEvent, fillPushBranch, type Mapped } from \"./map.js\";\nimport { createHookRuntime } from \"./runtime.js\";\nimport { scaffold, harnessSnippet, installHarness } from \"./init.js\";\nimport {\n userHome, userHarnessFile, resolveConfigDir, writeHarnessConfig, removeHarnessConfig,\n cursorDetected, codexDetected, absoluteHookCommand, isHarnessConfigured, purgeHome, type Harness,\n} from \"./install.js\";\nimport { connectCloud, loadConnection, connectionPath } from \"./cloud.js\";\nimport { cliCommand, hookVersion } from \"./version.js\";\nimport { fileURLToPath } from \"node:url\";\n\n/** The current git branch in `cwd` (best-effort). A bare `git push` pushes it, so\n * the runtime fills it in before evaluating; on failure the ref stays absent and\n * the starter policy fails closed. */\nfunction currentBranch(cwd: string): string | null {\n try {\n return execFileSync(\"git\", [\"-C\", cwd, \"symbolic-ref\", \"--quiet\", \"--short\", \"HEAD\"], {\n encoding: \"utf8\", stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim() || null;\n } catch { return null; }\n}\n\n/** Read an enrollment bundle from a file path, an inline base64 blob, or inline raw\n * JSON (the portal hands out a base64 blob so it is one clean argument). */\nfunction readBundleArg(bundleArg: string | undefined, stdin: () => string): CloudEnrollmentBundle {\n let text: string;\n if (!bundleArg) text = stdin();\n else if (existsSync(bundleArg)) text = readFileSync(bundleArg, \"utf8\");\n else if (bundleArg.trim().startsWith(\"{\")) text = bundleArg;\n else { try { text = Buffer.from(bundleArg, \"base64\").toString(\"utf8\"); } catch { text = bundleArg; } }\n return JSON.parse(text) as CloudEnrollmentBundle;\n}\n\nfunction configDir(): string {\n return process.env.SCOPEBOND_HOOK_DIR ?? join(process.cwd(), \".scopebond\");\n}\nfunction runtimePaths(dir: string) {\n const connection = loadConnection(dir);\n return {\n policyPath: join(dir, \"policy.json\"),\n keyPath: join(dir, \"agent.key\"),\n attesterPath: join(dir, \"attester.key\"),\n dbPath: join(dir, \"receipts.db\"),\n // Strict: deny (not just observe) tools with no taxonomy mapping.\n strict: process.argv.includes(\"--strict\") || process.env.SCOPEBOND_HOOK_STRICT === \"1\",\n // When connected, auto-export receipts. A short bounded flush keeps the hot path\n // fast; undelivered receipts persist in the durable outbox and flush next time\n // (or via `scopebond-hook flush`, e.g. on a session-end hook).\n ...(connection ? { cloud: { connection, flushTimeoutMs: Number(process.env.SCOPEBOND_HOOK_FLUSH_MS ?? 800) } } : {}),\n };\n}\nfunction readStdin(): string {\n try { return readFileSync(0, \"utf8\"); } catch { return \"\"; }\n}\n\nfunction denyClaude(reason: string): never {\n process.stdout.write(JSON.stringify({\n hookSpecificOutput: { hookEventName: \"PreToolUse\", permissionDecision: \"deny\", permissionDecisionReason: reason },\n }) + \"\\n\");\n process.stderr.write(`Scopebond: ${reason}\\n`);\n process.exit(2);\n}\n\n/** Codex accepts the structured deny response on a successful hook exit. Keeping\n * exit 0 lets its UI show a completed policy check instead of a failed hook while\n * still preventing the tool call. */\nfunction denyCodex(reason: string): never {\n process.stdout.write(JSON.stringify({\n hookSpecificOutput: { hookEventName: \"PreToolUse\", permissionDecision: \"deny\", permissionDecisionReason: reason },\n }) + \"\\n\");\n process.exit(0);\n}\n\nconst harnessName = (harness: Harness): string => harness === \"claude\" ? \"Claude Code\" : harness === \"cursor\" ? \"Cursor\" : \"Codex\";\nconst harnessFileName = (harness: Harness): string => harness === \"claude\" ? \".claude/settings.json\" : harness === \"cursor\" ? \".cursor/hooks.json\" : \".codex/hooks.json\";\nconst selectedHarness = (args: string[]): Harness => args.includes(\"--codex\") ? \"codex\" : args.includes(\"--cursor\") ? \"cursor\" : \"claude\";\nconst codexTrustStep = \"Open Codex, run `/hooks`, review Scopebond, and choose Trust. Then start a new task.\";\n\nasync function runPreToolUse(mapper: (input: Record<string, unknown>) => Mapped[], deny: (reason: string) => never = denyClaude): Promise<void> {\n let input: Record<string, unknown>;\n try { input = JSON.parse(readStdin()); } catch { deny(\"hook received invalid JSON on stdin\"); }\n try {\n const cwd = input?.cwd ? String(input.cwd) : process.cwd();\n const runtime = createHookRuntime(runtimePaths(resolveConfigDir(cwd)));\n const decision = await runtime.evaluate(fillPushBranch(mapper(input!), currentBranch(cwd)));\n await runtime.flush();\n if (decision.decision === \"deny\") deny(decision.reason);\n // Stay silent on allow/not_evaluated so the coding agent's normal permission\n // flow remains in charge. Scopebond blocks; it never silently approves.\n process.exit(0);\n } catch (error) {\n deny(`Scopebond hook failed closed: ${(error as Error).message}. Repair: run \\`${cliCommand(\"init\")}\\`.`);\n }\n}\n\nasync function runClaude(): Promise<void> {\n await runPreToolUse(mapClaudeToolUse);\n}\n\nasync function runCodex(): Promise<void> {\n await runPreToolUse(mapCodexToolUse, denyCodex);\n}\n\nasync function runCursor(): Promise<void> {\n let input: Record<string, unknown> = {};\n try { input = JSON.parse(readStdin()); } catch { /* fall through to fail-closed deny below */ }\n const event = String(input?.hook_event_name ?? input?.event ?? process.argv[3] ?? \"\");\n let permission: \"allow\" | \"deny\" | \"ask\" = \"deny\";\n let message = \"Scopebond hook failed closed\";\n try {\n const cwd = input?.cwd ? String(input.cwd) : process.cwd();\n const runtime = createHookRuntime(runtimePaths(resolveConfigDir(cwd)));\n const decision = await runtime.evaluate(fillPushBranch(mapCursorEvent(event, input), currentBranch(cwd)));\n await runtime.flush();\n // Only an out-of-policy action is denied outright; an allowed or unevaluated\n // action defers to Cursor's own prompt (\"ask\"), never a silent auto-allow.\n permission = decision.decision === \"deny\" ? \"deny\" : \"ask\";\n message = decision.reason;\n } catch (error) {\n permission = \"deny\";\n message = `Scopebond hook failed closed: ${(error as Error).message}. Repair: run \\`${cliCommand(\"init\")}\\`.`;\n }\n process.stdout.write(JSON.stringify({ permission, agentMessage: message }) + \"\\n\");\n process.exit(0);\n}\n\nfunction runInit(args: string[]): void {\n const harness = selectedHarness(args);\n const dir = configDir();\n const { agentKid, policyPath } = scaffold(dir, { force: args.includes(\"--force\") });\n console.log(`Scopebond hook enrolled in ${dir}`);\n console.log(` machine key ${agentKid}`);\n console.log(` policy ${policyPath} (starter — edit the limits)`);\n console.log(\"\");\n // Configure the agent automatically by default (idempotent), so there is no\n // hand-editing step; --no-install prints the snippet instead.\n if (!args.includes(\"--no-install\")) {\n const file = installHarness(harness);\n console.log(`✓ ${harnessName(harness)} configured in ${file}`);\n if (harness === \"codex\") console.log(`\\nOne last step: ${codexTrustStep}`);\n } else {\n console.log(`Add this to your ${harnessFileName(harness)}:`);\n console.log(harnessSnippet(harness));\n }\n console.log(\"\");\n // Print the runnable `npx` form: after `npx @scopebond/hook init` there is no\n // `scopebond-hook` binary on PATH, so a bare `scopebond-hook log` would fail.\n console.log(`Next: run one command in the agent, then \\`${cliCommand(\"log\")}\\` to see the receipt`);\n console.log(`and \\`${cliCommand(\"verify\")}\\` to check it offline. Try \\`${cliCommand('test \"rm -rf /\"')}\\`.`);\n console.log(`To send receipts to a workspace: ${cliCommand(\"connect <workspace-url> <enrollment>\")}`);\n}\n\nfunction decisionOf(payload: Record<string, unknown>): string {\n const rr = String(payload.realtime_result ?? \"\");\n const state = String((payload.execution as Record<string, unknown> | undefined)?.state ?? \"\");\n if (state === \"observed_not_evaluated\") return \"not_evaluated\";\n if (rr === \"deny\") return state === \"cooperative_allow\" || state === \"executed\" ? \"monitor\" : \"deny\";\n return \"allow\";\n}\n\nfunction describeIntent(payload: Record<string, unknown>): string {\n const intent = (payload.intent ?? {}) as Record<string, unknown>;\n const p = (intent.params ?? {}) as Record<string, unknown>;\n const bits = intent.action_type === \"shell.exec\" ? String(p.program ?? \"\")\n : intent.action_type === \"git.push\" ? `${p.remote ?? \"\"} ${p.ref ?? \"\"}`.trim()\n : intent.action_type === \"file.write\" || intent.action_type === \"file.read\" ? String(p.path ?? \"\")\n : intent.action_type === \"mcp.tool.call\" ? `${p.server ?? \"\"}/${p.tool ?? \"\"}`\n : intent.action_type === \"net.fetch\" ? String(p.host ?? \"\") : \"\";\n return `${String(intent.action_type ?? \"?\")}${bits ? ` ${bits}` : \"\"}`;\n}\n\nasync function runLog(args: string[]): Promise<void> {\n const dir = resolveConfigDir(process.cwd());\n const dbPath = join(dir, \"receipts.db\");\n if (!existsSync(dbPath)) { console.log(\"no receipts yet — run a command in the agent first.\"); process.exit(0); }\n const nIdx = args.indexOf(\"-n\");\n const n = nIdx >= 0 ? Math.max(1, Number(args[nIdx + 1]) || 20) : 20;\n const { store } = openReceiptStore({ db: dbPath });\n const all = await Promise.resolve(store.list());\n const recent = all.slice(-n);\n if (recent.length === 0) { console.log(\"no receipts yet.\"); process.exit(0); }\n for (const r of recent) {\n const p = r.payload as unknown as Record<string, unknown>;\n console.log(`${String(p.timestamp ?? \"\")} ${decisionOf(p).padEnd(13)} ${describeIntent(p)}`);\n }\n console.log(`\\n${recent.length} of ${all.length} receipt(s). Verify them: ${cliCommand(\"verify\")}`);\n}\n\nasync function runVerify(): Promise<void> {\n const dir = resolveConfigDir(process.cwd());\n const dbPath = join(dir, \"receipts.db\");\n const attesterPath = join(dir, \"attester.key\");\n if (!existsSync(dbPath) || !existsSync(attesterPath)) { console.log(\"nothing to verify yet (no receipts or no attester key).\"); process.exit(0); }\n const { attester } = loadOrCreateAttester({ file: attesterPath });\n const { store } = openReceiptStore({ db: dbPath });\n const all = await Promise.resolve(store.list());\n let ok = 0;\n const bad: string[] = [];\n for (const r of all) {\n const result = verifyReceipt(r, attester.publicKeyPem) as unknown as Record<string, boolean>;\n if (result.valid) ok += 1;\n else {\n const failed = Object.entries(result).filter(([k, v]) => k.endsWith(\"_valid\") && v === false).map(([k]) => k);\n bad.push(`${String((r.payload as unknown as Record<string, unknown>).timestamp ?? \"\")}: ${failed.join(\", \") || \"invalid\"}`);\n }\n }\n console.log(`${ok}/${all.length} receipt(s) verify offline against ${attesterPath}.`);\n if (bad.length) { for (const b of bad) console.error(` ✗ ${b}`); process.exit(1); }\n process.exit(0);\n}\n\nasync function runTest(args: string[]): Promise<void> {\n const command = args.find((a) => !a.startsWith(\"-\"));\n if (!command) { console.error('usage: scopebond-hook test \"<shell command>\"'); process.exit(1); }\n const dir = resolveConfigDir(process.cwd());\n if (!existsSync(join(dir, \"policy.json\"))) { console.error(\"no policy yet — run `scopebond-hook init` first.\"); process.exit(1); }\n // Evaluate against the real policy and keys, but a throwaway store, so `test`\n // never records a receipt or exports anything.\n const tmp = mkdtempSync(join(tmpdir(), \"sb-hook-test-\"));\n try {\n const runtime = createHookRuntime({\n policyPath: join(dir, \"policy.json\"), keyPath: join(dir, \"agent.key\"),\n attesterPath: join(dir, \"attester.key\"), dbPath: join(tmp, \"receipts.db\"),\n strict: process.argv.includes(\"--strict\"),\n });\n const mapped = fillPushBranch(mapClaudeToolUse({ tool_name: \"Bash\", tool_input: { command } }), currentBranch(process.cwd()));\n console.log(`command: ${command}`);\n for (const m of mapped) {\n const d = await runtime.evaluateOne(m);\n console.log(` ${describeIntent({ intent: m.intent }).padEnd(28)} → ${d.decision}${d.reason ? ` (${d.reason})` : \"\"}`);\n }\n const overall = await runtime.evaluate(mapped);\n console.log(`\\noverall: ${overall.decision}${overall.reason ? ` · ${overall.reason}` : \"\"}`);\n process.exit(overall.decision === \"deny\" ? 2 : 0);\n } finally {\n rmSync(tmp, { recursive: true, force: true });\n }\n}\n\nasync function runConnect(args: string[]): Promise<void> {\n const positional = args.filter((a) => !a.startsWith(\"--\"));\n const url = positional[0];\n const bundleArg = positional[1];\n const harness = selectedHarness(args);\n if (!url) {\n console.error(\"usage: scopebond-hook connect <workspace-url> <enrollment> [--claude|--cursor|--codex] [--no-install]\");\n process.exit(1);\n }\n const dir = configDir();\n // One command sets everything up: scaffold the key, attester and starter policy if\n // they do not exist, then enroll and persist the scoped machine credential. The\n // enrollment can be a file, an inline base64 blob (what the portal hands out) or\n // raw JSON — the user never has to save or open a JSON file.\n scaffold(dir, {});\n let bundle: CloudEnrollmentBundle;\n try { bundle = readBundleArg(bundleArg, readStdin); }\n catch { console.error(\"could not read the enrollment (expected a file, inline blob, or JSON on stdin)\"); process.exit(1); }\n try {\n const c = await connectCloud(dir, url, bundle);\n console.log(`✓ Connected to ${c.url}`);\n // Configure the agent automatically (merges into the existing config), unless the\n // caller opts out. This removes the \"paste this snippet\" step.\n if (!args.includes(\"--no-install\")) {\n const file = installHarness(harness);\n console.log(`✓ ${harnessName(harness)} configured in ${file}`);\n if (harness === \"codex\") console.log(`\\nOne last step: ${codexTrustStep}`);\n } else {\n console.log(`Add this to your ${harnessFileName(harness)}:`);\n console.log(harnessSnippet(harness));\n }\n console.log(\"\");\n console.log(\"Run your agent — the first action appears in your workspace within seconds.\");\n } catch (error) {\n console.error(`connect failed: ${(error as Error).message}`);\n process.exit(1);\n }\n}\n\nasync function runFlush(): Promise<void> {\n const dir = resolveConfigDir(process.cwd());\n if (!loadConnection(dir)) { console.error(\"not connected to a workspace; run `scopebond-hook connect` first\"); process.exit(1); }\n const runtime = createHookRuntime(runtimePaths(dir));\n await runtime.exporter?.flush();\n const status = runtime.exporter?.status();\n runtime.exporter?.stop();\n console.log(`flushed; ${status?.pending ?? 0} receipt(s) still pending${status?.lastError ? ` (last error: ${status.lastError})` : \"\"}`);\n // Let pending HTTP handles close normally (forced exit can abort on Windows).\n process.exitCode = status && status.pending > 0 ? 1 : 0;\n}\n\n/** The absolute path to this CLI file, for registering the hook by absolute path. */\nfunction cliPath(): string {\n return fileURLToPath(import.meta.url);\n}\n\n/** `install` — the once-per-machine, user-level install (SB112). Scaffolds the\n * user home and registers the hook by absolute path in the user-level agent config,\n * so every project a developer opens is governed without a per-repo `init`. */\nfunction runInstall(args: string[]): void {\n const dir = userHome();\n const { agentKid, policyPath } = scaffold(dir, { force: args.includes(\"--force\") });\n console.log(`Scopebond installed for this user in ${dir}`);\n console.log(` machine key ${agentKid}`);\n console.log(` policy ${policyPath} (starter — edit the limits)`);\n console.log(\"\");\n const harnesses: Harness[] = args.includes(\"--codex\") ? [\"codex\"]\n : args.includes(\"--cursor\") ? [\"cursor\"]\n : args.includes(\"--claude\") ? [\"claude\"]\n : [\"claude\", ...(cursorDetected() ? [\"cursor\" as const] : []), ...(codexDetected() ? [\"codex\" as const] : [])];\n if (!args.includes(\"--no-install\")) {\n for (const h of harnesses) {\n const file = writeHarnessConfig(userHarnessFile(h), h, absoluteHookCommand(cliPath(), h));\n console.log(`✓ ${harnessName(h)} configured in ${file}`);\n }\n } else {\n console.log(\"Add this to your user-level agent config:\");\n console.log(harnessSnippet(harnesses[0]));\n }\n if (harnesses.includes(\"codex\")) console.log(`\\nOne last step for Codex: ${codexTrustStep}`);\n console.log(\"\");\n console.log(\"A project-local .scopebond still takes precedence when present.\");\n console.log(`Check it: ${cliCommand(\"doctor\")} · see decisions: ${cliCommand(\"log\")}`);\n console.log(`To send receipts to a workspace: ${cliCommand(\"connect <workspace-url> <enrollment>\")}`);\n}\n\nfunction runStatus(): void {\n const home = userHome();\n const installed = existsSync(join(home, \"policy.json\"));\n const claude = isHarnessConfigured(userHarnessFile(\"claude\"));\n const cursor = isHarnessConfigured(userHarnessFile(\"cursor\"));\n const codex = isHarnessConfigured(userHarnessFile(\"codex\"));\n const connected = !!loadConnection(resolveConfigDir(process.cwd()));\n const dbPath = join(resolveConfigDir(process.cwd()), \"receipts.db\");\n console.log(`Scopebond hook ${hookVersion()}`);\n console.log(` user home ${home} ${installed ? \"(installed)\" : \"(not installed — run `scopebond install`)\"}`);\n console.log(` active config ${resolveConfigDir(process.cwd())}`);\n console.log(` Claude Code ${claude ? \"configured\" : \"not configured\"}`);\n console.log(` Cursor ${cursor ? \"configured\" : cursorDetected() ? \"detected, not configured\" : \"not detected\"}`);\n console.log(` Codex ${codex ? \"configured (approve once with /hooks)\" : codexDetected() ? \"detected, not configured\" : \"not detected\"}`);\n console.log(` cloud workspace ${connected ? \"connected\" : \"not connected (local only)\"}`);\n console.log(` local receipts ${existsSync(dbPath) ? dbPath : \"none yet\"}`);\n}\n\nasync function runDoctor(): Promise<void> {\n const problems: string[] = [];\n const [major, minor] = process.versions.node.split(\".\").map(Number);\n const nodeOk = major > 22 || (major === 22 && minor >= 13);\n console.log(`Scopebond doctor`);\n console.log(` node ${process.versions.node} ${nodeOk ? \"ok\" : \"TOO OLD (need >=22.13)\"}`);\n if (!nodeOk) problems.push(\"node >=22.13 is required (the Cloud outbox uses node:sqlite)\");\n const cli = cliPath();\n console.log(` cli ${cli} ${existsSync(cli) ? \"ok\" : \"MISSING\"}`);\n const active = resolveConfigDir(process.cwd());\n const hasPolicy = existsSync(join(active, \"policy.json\"));\n console.log(` active config ${active} ${hasPolicy ? \"ok\" : \"no policy (run `scopebond install` or `init`)\"}`);\n if (!hasPolicy) problems.push(\"no policy found in the active config dir\");\n const codex = isHarnessConfigured(userHarnessFile(\"codex\"));\n console.log(` Codex hook ${codex ? \"configured\" : codexDetected() ? \"not configured — run `scopebond install --codex`\" : \"not detected\"}`);\n if (codex) console.log(` Codex approval run /hooks in Codex and approve Scopebond once`);\n const connection = loadConnection(active);\n if (!connection) {\n console.log(` cloud not connected (local only) — receipts stay on this machine`);\n } else {\n let reachable = \"unknown\";\n try {\n const res = await fetch(new URL(\"/healthz\", connection.url).toString(), { method: \"GET\" });\n reachable = res.ok ? \"reachable\" : `unhealthy (${res.status})`;\n } catch (error) { reachable = `unreachable (${(error as Error).message})`; }\n console.log(` cloud ${connection.url} — ${reachable}`);\n }\n console.log(problems.length ? `\\n${problems.length} problem(s): ${problems.join(\"; \")}` : `\\nAll good.`);\n process.exitCode = problems.length ? 1 : 0;\n}\n\nfunction runUninstall(args: string[]): void {\n let removed = 0;\n for (const h of [\"claude\", \"cursor\", \"codex\"] as Harness[]) {\n if (removeHarnessConfig(userHarnessFile(h))) { console.log(`✓ removed the Scopebond hook from ${userHarnessFile(h)}`); removed++; }\n }\n if (removed === 0) console.log(\"no user-level harness config found.\");\n if (args.includes(\"--purge\")) { purgeHome(); console.log(`✓ purged ${userHome()} (keys, policy, receipts)`); }\n else console.log(`Kept ${userHome()} (keys, policy, receipts). Use --purge to remove it too.`);\n}\n\nfunction runLogin(): void {\n console.log(\"Device-code login is not available yet.\");\n console.log(`For now, connect with a one-time enrollment from your workspace:`);\n console.log(` ${cliCommand(\"connect <workspace-url> <enrollment>\")}`);\n process.exit(0);\n}\n\nconst [cmd, ...rest] = process.argv.slice(2);\nif (cmd === \"claude\") { await runClaude(); }\nelse if (cmd === \"cursor\") { await runCursor(); }\nelse if (cmd === \"codex\") { await runCodex(); }\nelse if (cmd === \"init\") { runInit(rest); }\nelse if (cmd === \"install\") { runInstall(rest); }\nelse if (cmd === \"connect\") { await runConnect(rest); }\nelse if (cmd === \"log\") { await runLog(rest); }\nelse if (cmd === \"verify\") { await runVerify(); }\nelse if (cmd === \"test\") { await runTest(rest); }\nelse if (cmd === \"flush\") { await runFlush(); }\nelse if (cmd === \"status\") { runStatus(); }\nelse if (cmd === \"doctor\") { await runDoctor(); }\nelse if (cmd === \"uninstall\") { runUninstall(rest); }\nelse if (cmd === \"login\") { runLogin(); }\nelse {\n console.error(\"usage: scopebond <claude|cursor|codex|init|install|connect|log|verify|test|flush|status|doctor|uninstall|login> [--cursor] [--claude] [--codex] [--force] [--strict] [--no-install] [--purge]\");\n process.exit(1);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n// scopebond-hook — govern a coding agent's tool calls against policy, in-path,\n// before they run, with a signed local receipt.\n//\n// scopebond-hook claude evaluate a Claude Code PreToolUse call (stdin JSON)\n// scopebond-hook cursor evaluate a Cursor hook event (stdin JSON)\n// scopebond-hook codex evaluate a Codex PreToolUse call (stdin JSON)\n// scopebond-hook init [--cursor|--codex] [--no-install] [--yes]\n// scopebond-hook connect <url> <bundle.json> [--cursor|--codex]\n// enroll with a Cloud workspace and start exporting\n// scopebond-hook log [-n N] show the most recent local receipts\n// scopebond-hook verify verify every local receipt offline against the attester key\n// scopebond-hook test \"<shell command>\" show the decision for a command without recording it\n// scopebond-hook flush deliver any queued receipts to Cloud now\n// scopebond-hook trust [--yes] let this project's .scopebond policy govern here (pinned)\n//\n// Config dir: $SCOPEBOND_HOOK_DIR, else ./.scopebond\n// Fail-closed: any error denies the action with a repair message.\n\nimport { readFileSync, existsSync, mkdtempSync, rmSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport { execFileSync } from \"node:child_process\";\nimport type { CloudEnrollmentBundle } from \"@scopebond/gateway\";\nimport { verifyReceipt } from \"@scopebond/gateway\";\nimport { openReceiptStore, loadOrCreateAttester } from \"@scopebond/gateway/node\";\nimport { mapClaudeToolUse, mapCodexToolUse, mapCursorEvent, fillPushBranch, type Mapped } from \"./map.js\";\nimport { createHookRuntime } from \"./runtime.js\";\nimport { scaffold, harnessSnippet, installHarness } from \"./init.js\";\nimport {\n userHome, userHarnessFile, resolveConfigDir, writeHarnessConfig, removeHarnessConfig,\n cursorDetected, codexDetected, absoluteHookCommand, isHarnessConfigured, purgeHome, type Harness,\n trustProjectPolicy, untrustedProjectPolicy,\n} from \"./install.js\";\nimport { connectCloud, loadConnection, connectionPath } from \"./cloud.js\";\nimport { cliCommand, hookVersion } from \"./version.js\";\nimport { fileURLToPath } from \"node:url\";\n\n/** The current git branch in `cwd` (best-effort). A bare `git push` pushes it, so\n * the runtime fills it in before evaluating; on failure the ref stays absent and\n * the starter policy fails closed. */\nfunction currentBranch(cwd: string): string | null {\n try {\n return execFileSync(\"git\", [\"-C\", cwd, \"symbolic-ref\", \"--quiet\", \"--short\", \"HEAD\"], {\n encoding: \"utf8\", stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim() || null;\n } catch { return null; }\n}\n\n/** Read an enrollment bundle from a file path, an inline base64 blob, or inline raw\n * JSON (the portal hands out a base64 blob so it is one clean argument). */\nfunction readBundleArg(bundleArg: string | undefined, stdin: () => string): CloudEnrollmentBundle {\n let text: string;\n if (!bundleArg) text = stdin();\n else if (existsSync(bundleArg)) text = readFileSync(bundleArg, \"utf8\");\n else if (bundleArg.trim().startsWith(\"{\")) text = bundleArg;\n else { try { text = Buffer.from(bundleArg, \"base64\").toString(\"utf8\"); } catch { text = bundleArg; } }\n return JSON.parse(text) as CloudEnrollmentBundle;\n}\n\nfunction configDir(): string {\n return process.env.SCOPEBOND_HOOK_DIR ?? join(process.cwd(), \".scopebond\");\n}\nfunction runtimePaths(dir: string) {\n const connection = loadConnection(dir);\n return {\n policyPath: join(dir, \"policy.json\"),\n keyPath: join(dir, \"agent.key\"),\n attesterPath: join(dir, \"attester.key\"),\n dbPath: join(dir, \"receipts.db\"),\n // Strict: deny (not just observe) tools with no taxonomy mapping.\n strict: process.argv.includes(\"--strict\") || process.env.SCOPEBOND_HOOK_STRICT === \"1\",\n // When connected, auto-export receipts. A short bounded flush keeps the hot path\n // fast; undelivered receipts persist in the durable outbox and flush next time\n // (or via `scopebond-hook flush`, e.g. on a session-end hook).\n ...(connection ? { cloud: { connection, flushTimeoutMs: Number(process.env.SCOPEBOND_HOOK_FLUSH_MS ?? 800) } } : {}),\n };\n}\nfunction readStdin(): string {\n try { return readFileSync(0, \"utf8\"); } catch { return \"\"; }\n}\n\nfunction denyClaude(reason: string): never {\n process.stdout.write(JSON.stringify({\n hookSpecificOutput: { hookEventName: \"PreToolUse\", permissionDecision: \"deny\", permissionDecisionReason: reason },\n }) + \"\\n\");\n process.stderr.write(`Scopebond: ${reason}\\n`);\n process.exit(2);\n}\n\n/** Codex accepts the structured deny response on a successful hook exit. Keeping\n * exit 0 lets its UI show a completed policy check instead of a failed hook while\n * still preventing the tool call. */\nfunction denyCodex(reason: string): never {\n process.stdout.write(JSON.stringify({\n hookSpecificOutput: { hookEventName: \"PreToolUse\", permissionDecision: \"deny\", permissionDecisionReason: reason },\n }) + \"\\n\");\n process.exit(0);\n}\n\nconst harnessName = (harness: Harness): string => harness === \"claude\" ? \"Claude Code\" : harness === \"cursor\" ? \"Cursor\" : \"Codex\";\nconst harnessFileName = (harness: Harness): string => harness === \"claude\" ? \".claude/settings.json\" : harness === \"cursor\" ? \".cursor/hooks.json\" : \".codex/hooks.json\";\nconst selectedHarness = (args: string[]): Harness => args.includes(\"--codex\") ? \"codex\" : args.includes(\"--cursor\") ? \"cursor\" : \"claude\";\nconst codexTrustStep = \"Open Codex, run `/hooks`, review Scopebond, and choose Trust. Then start a new task.\";\n\nasync function runPreToolUse(mapper: (input: Record<string, unknown>) => Mapped[], deny: (reason: string) => never = denyClaude): Promise<void> {\n let input: Record<string, unknown>;\n try { input = JSON.parse(readStdin()); } catch { deny(\"hook received invalid JSON on stdin\"); }\n try {\n const cwd = input?.cwd ? String(input.cwd) : process.cwd();\n const runtime = createHookRuntime(runtimePaths(resolveConfigDir(cwd)));\n const decision = await runtime.evaluate(fillPushBranch(mapper(input!), currentBranch(cwd)));\n await runtime.flush();\n if (decision.decision === \"deny\") deny(decision.reason);\n // Stay silent on allow/not_evaluated so the coding agent's normal permission\n // flow remains in charge. Scopebond blocks; it never silently approves.\n process.exit(0);\n } catch (error) {\n deny(`Scopebond hook failed closed: ${(error as Error).message}. Repair: run \\`${cliCommand(\"init\")}\\`.`);\n }\n}\n\nasync function runClaude(): Promise<void> {\n await runPreToolUse(mapClaudeToolUse);\n}\n\nasync function runCodex(): Promise<void> {\n await runPreToolUse(mapCodexToolUse, denyCodex);\n}\n\nasync function runCursor(): Promise<void> {\n let input: Record<string, unknown> = {};\n try { input = JSON.parse(readStdin()); } catch { /* fall through to fail-closed deny below */ }\n const event = String(input?.hook_event_name ?? input?.event ?? process.argv[3] ?? \"\");\n let permission: \"allow\" | \"deny\" | \"ask\" = \"deny\";\n let message = \"Scopebond hook failed closed\";\n try {\n const cwd = input?.cwd ? String(input.cwd) : process.cwd();\n const runtime = createHookRuntime(runtimePaths(resolveConfigDir(cwd)));\n const decision = await runtime.evaluate(fillPushBranch(mapCursorEvent(event, input), currentBranch(cwd)));\n await runtime.flush();\n // Only an out-of-policy action is denied outright; an allowed or unevaluated\n // action defers to Cursor's own prompt (\"ask\"), never a silent auto-allow.\n permission = decision.decision === \"deny\" ? \"deny\" : \"ask\";\n message = decision.reason;\n } catch (error) {\n permission = \"deny\";\n message = `Scopebond hook failed closed: ${(error as Error).message}. Repair: run \\`${cliCommand(\"init\")}\\`.`;\n }\n process.stdout.write(JSON.stringify({ permission, agentMessage: message }) + \"\\n\");\n process.exit(0);\n}\n\n/** `init`, `trust` and `uninstall` change what governs the agent, so they are for a\n * person at a terminal. A coding agent's shell is not interactive: without a TTY on\n * stdin they refuse unless `--yes` is passed (for scripts and CI). The starter policy\n * also denies the agent running them. */\nfunction requireInteractive(command: string, args: string[]): void {\n if (process.stdin.isTTY || args.includes(\"--yes\")) return;\n console.error(`scopebond ${command} changes what governs your coding agent, so it must be run from an interactive terminal.`);\n console.error(`In a script or CI, pass --yes: ${cliCommand(`${command} --yes`)}`);\n process.exit(1);\n}\n\nfunction runInit(args: string[]): void {\n requireInteractive(\"init\", args);\n const harness = selectedHarness(args);\n const dir = configDir();\n const { agentKid, policyPath } = scaffold(dir, { force: args.includes(\"--force\") });\n console.log(`Scopebond hook enrolled in ${dir}`);\n console.log(` machine key ${agentKid}`);\n console.log(` policy ${policyPath} (starter — edit the limits)`);\n // With a user-level install present, a project policy governs only once trusted.\n // Running init here is that decision, so pin this policy now.\n if (!process.env.SCOPEBOND_HOOK_DIR && existsSync(join(userHome(), \"policy.json\"))) {\n trustProjectPolicy(dir);\n console.log(` trusted overrides ${userHome()} here; after editing it, run \\`${cliCommand(\"trust\")}\\``);\n }\n console.log(\"\");\n // Configure the agent automatically by default (idempotent), so there is no\n // hand-editing step; --no-install prints the snippet instead.\n if (!args.includes(\"--no-install\")) {\n let file: string;\n try { file = installHarness(harness); } catch (error) { console.error((error as Error).message); process.exit(1); }\n console.log(`✓ ${harnessName(harness)} configured in ${file}`);\n if (harness === \"codex\") console.log(`\\nOne last step: ${codexTrustStep}`);\n } else {\n console.log(`Add this to your ${harnessFileName(harness)}:`);\n console.log(harnessSnippet(harness));\n }\n console.log(\"\");\n // Print the runnable `npx` form: after `npx @scopebond/hook init` there is no\n // `scopebond-hook` binary on PATH, so a bare `scopebond-hook log` would fail.\n console.log(`Next: run one command in the agent, then \\`${cliCommand(\"log\")}\\` to see the receipt`);\n console.log(`and \\`${cliCommand(\"verify\")}\\` to check it offline. Try \\`${cliCommand('test \"rm -rf /\"')}\\`.`);\n console.log(`To send receipts to a workspace: ${cliCommand(\"connect <workspace-url> <enrollment>\")}`);\n}\n\nfunction decisionOf(payload: Record<string, unknown>): string {\n const rr = String(payload.realtime_result ?? \"\");\n const state = String((payload.execution as Record<string, unknown> | undefined)?.state ?? \"\");\n if (state === \"observed_not_evaluated\") return \"not_evaluated\";\n if (rr === \"deny\") return state === \"cooperative_allow\" || state === \"executed\" ? \"monitor\" : \"deny\";\n return \"allow\";\n}\n\nfunction describeIntent(payload: Record<string, unknown>): string {\n const intent = (payload.intent ?? {}) as Record<string, unknown>;\n const p = (intent.params ?? {}) as Record<string, unknown>;\n const bits = intent.action_type === \"shell.exec\" ? String(p.program ?? \"\")\n : intent.action_type === \"git.push\" ? `${p.remote ?? \"\"} ${p.ref ?? \"\"}`.trim()\n : intent.action_type === \"file.write\" || intent.action_type === \"file.read\" ? String(p.path ?? \"\")\n : intent.action_type === \"mcp.tool.call\" ? `${p.server ?? \"\"}/${p.tool ?? \"\"}`\n : intent.action_type === \"net.fetch\" ? String(p.host ?? \"\") : \"\";\n return `${String(intent.action_type ?? \"?\")}${bits ? ` ${bits}` : \"\"}`;\n}\n\nasync function runLog(args: string[]): Promise<void> {\n const dir = resolveConfigDir(process.cwd());\n const dbPath = join(dir, \"receipts.db\");\n if (!existsSync(dbPath)) { console.log(\"no receipts yet — run a command in the agent first.\"); process.exit(0); }\n const nIdx = args.indexOf(\"-n\");\n const n = nIdx >= 0 ? Math.max(1, Number(args[nIdx + 1]) || 20) : 20;\n const { store } = openReceiptStore({ db: dbPath });\n const all = await Promise.resolve(store.list());\n const recent = all.slice(-n);\n if (recent.length === 0) { console.log(\"no receipts yet.\"); process.exit(0); }\n for (const r of recent) {\n const p = r.payload as unknown as Record<string, unknown>;\n console.log(`${String(p.timestamp ?? \"\")} ${decisionOf(p).padEnd(13)} ${describeIntent(p)}`);\n }\n console.log(`\\n${recent.length} of ${all.length} receipt(s). Verify them: ${cliCommand(\"verify\")}`);\n}\n\nasync function runVerify(): Promise<void> {\n const dir = resolveConfigDir(process.cwd());\n const dbPath = join(dir, \"receipts.db\");\n const attesterPath = join(dir, \"attester.key\");\n if (!existsSync(dbPath) || !existsSync(attesterPath)) { console.log(\"nothing to verify yet (no receipts or no attester key).\"); process.exit(0); }\n const { attester } = loadOrCreateAttester({ file: attesterPath });\n const { store } = openReceiptStore({ db: dbPath });\n const all = await Promise.resolve(store.list());\n let ok = 0;\n const bad: string[] = [];\n for (const r of all) {\n const result = verifyReceipt(r, attester.publicKeyPem) as unknown as Record<string, boolean>;\n if (result.valid) ok += 1;\n else {\n const failed = Object.entries(result).filter(([k, v]) => k.endsWith(\"_valid\") && v === false).map(([k]) => k);\n bad.push(`${String((r.payload as unknown as Record<string, unknown>).timestamp ?? \"\")}: ${failed.join(\", \") || \"invalid\"}`);\n }\n }\n console.log(`${ok}/${all.length} receipt(s) verify offline against ${attesterPath}.`);\n if (bad.length) { for (const b of bad) console.error(` ✗ ${b}`); process.exit(1); }\n process.exit(0);\n}\n\nasync function runTest(args: string[]): Promise<void> {\n const command = args.find((a) => !a.startsWith(\"-\"));\n if (!command) { console.error('usage: scopebond-hook test \"<shell command>\"'); process.exit(1); }\n const dir = resolveConfigDir(process.cwd());\n if (!existsSync(join(dir, \"policy.json\"))) { console.error(\"no policy yet — run `scopebond-hook init` first.\"); process.exit(1); }\n // Evaluate against the real policy and keys, but a throwaway store, so `test`\n // never records a receipt or exports anything.\n const tmp = mkdtempSync(join(tmpdir(), \"sb-hook-test-\"));\n try {\n const runtime = createHookRuntime({\n policyPath: join(dir, \"policy.json\"), keyPath: join(dir, \"agent.key\"),\n attesterPath: join(dir, \"attester.key\"), dbPath: join(tmp, \"receipts.db\"),\n strict: process.argv.includes(\"--strict\"),\n });\n const mapped = fillPushBranch(mapClaudeToolUse({ tool_name: \"Bash\", tool_input: { command } }), currentBranch(process.cwd()));\n console.log(`command: ${command}`);\n for (const m of mapped) {\n const d = await runtime.evaluateOne(m);\n console.log(` ${describeIntent({ intent: m.intent }).padEnd(28)} → ${d.decision}${d.reason ? ` (${d.reason})` : \"\"}`);\n }\n const overall = await runtime.evaluate(mapped);\n console.log(`\\noverall: ${overall.decision}${overall.reason ? ` · ${overall.reason}` : \"\"}`);\n process.exit(overall.decision === \"deny\" ? 2 : 0);\n } finally {\n rmSync(tmp, { recursive: true, force: true });\n }\n}\n\nasync function runConnect(args: string[]): Promise<void> {\n const positional = args.filter((a) => !a.startsWith(\"--\"));\n const url = positional[0];\n const bundleArg = positional[1];\n const harness = selectedHarness(args);\n if (!url) {\n console.error(\"usage: scopebond-hook connect <workspace-url> <enrollment> [--claude|--cursor|--codex] [--no-install]\");\n process.exit(1);\n }\n const dir = configDir();\n // One command sets everything up: scaffold the key, attester and starter policy if\n // they do not exist, then enroll and persist the scoped machine credential. The\n // enrollment can be a file, an inline base64 blob (what the portal hands out) or\n // raw JSON — the user never has to save or open a JSON file.\n scaffold(dir, {});\n let bundle: CloudEnrollmentBundle;\n try { bundle = readBundleArg(bundleArg, readStdin); }\n catch { console.error(\"could not read the enrollment (expected a file, inline blob, or JSON on stdin)\"); process.exit(1); }\n try {\n const c = await connectCloud(dir, url, bundle);\n console.log(`✓ Connected to ${c.url}`);\n // Configure the agent automatically (merges into the existing config), unless the\n // caller opts out. This removes the \"paste this snippet\" step.\n if (!args.includes(\"--no-install\")) {\n const file = installHarness(harness);\n console.log(`✓ ${harnessName(harness)} configured in ${file}`);\n if (harness === \"codex\") console.log(`\\nOne last step: ${codexTrustStep}`);\n } else {\n console.log(`Add this to your ${harnessFileName(harness)}:`);\n console.log(harnessSnippet(harness));\n }\n console.log(\"\");\n console.log(\"Run your agent — the first action appears in your workspace within seconds.\");\n } catch (error) {\n console.error(`connect failed: ${(error as Error).message}`);\n process.exit(1);\n }\n}\n\nasync function runFlush(): Promise<void> {\n const dir = resolveConfigDir(process.cwd());\n if (!loadConnection(dir)) { console.error(\"not connected to a workspace; run `scopebond-hook connect` first\"); process.exit(1); }\n const runtime = createHookRuntime(runtimePaths(dir));\n await runtime.exporter?.flush();\n const status = runtime.exporter?.status();\n runtime.exporter?.stop();\n console.log(`flushed; ${status?.pending ?? 0} receipt(s) still pending${status?.lastError ? ` (last error: ${status.lastError})` : \"\"}`);\n // Let pending HTTP handles close normally (forced exit can abort on Windows).\n process.exitCode = status && status.pending > 0 ? 1 : 0;\n}\n\n/** The absolute path to this CLI file, for registering the hook by absolute path. */\nfunction cliPath(): string {\n return fileURLToPath(import.meta.url);\n}\n\n/** `install` — the once-per-machine, user-level install (SB112). Scaffolds the\n * user home and registers the hook by absolute path in the user-level agent config,\n * so every project a developer opens is governed without a per-repo `init`. */\nfunction runInstall(args: string[]): void {\n const dir = userHome();\n const { agentKid, policyPath } = scaffold(dir, { force: args.includes(\"--force\") });\n console.log(`Scopebond installed for this user in ${dir}`);\n console.log(` machine key ${agentKid}`);\n console.log(` policy ${policyPath} (starter — edit the limits)`);\n console.log(\"\");\n const harnesses: Harness[] = args.includes(\"--codex\") ? [\"codex\"]\n : args.includes(\"--cursor\") ? [\"cursor\"]\n : args.includes(\"--claude\") ? [\"claude\"]\n : [\"claude\", ...(cursorDetected() ? [\"cursor\" as const] : []), ...(codexDetected() ? [\"codex\" as const] : [])];\n if (!args.includes(\"--no-install\")) {\n for (const h of harnesses) {\n try {\n const file = writeHarnessConfig(userHarnessFile(h), h, absoluteHookCommand(cliPath(), h));\n console.log(`✓ ${harnessName(h)} configured in ${file}`);\n } catch (error) { console.error(`✗ ${harnessName(h)}: ${(error as Error).message}`); process.exitCode = 1; }\n }\n } else {\n console.log(\"Add this to your user-level agent config:\");\n console.log(harnessSnippet(harnesses[0]));\n }\n if (harnesses.includes(\"codex\")) console.log(`\\nOne last step for Codex: ${codexTrustStep}`);\n console.log(\"\");\n console.log(`A project's own .scopebond policy applies only after you trust it there (${cliCommand(\"trust\")}).`);\n console.log(`Check it: ${cliCommand(\"doctor\")} · see decisions: ${cliCommand(\"log\")}`);\n console.log(`To send receipts to a workspace: ${cliCommand(\"connect <workspace-url> <enrollment>\")}`);\n}\n\nfunction runStatus(): void {\n const home = userHome();\n const installed = existsSync(join(home, \"policy.json\"));\n const claude = isHarnessConfigured(userHarnessFile(\"claude\"));\n const cursor = isHarnessConfigured(userHarnessFile(\"cursor\"));\n const codex = isHarnessConfigured(userHarnessFile(\"codex\"));\n const connected = !!loadConnection(resolveConfigDir(process.cwd()));\n const dbPath = join(resolveConfigDir(process.cwd()), \"receipts.db\");\n console.log(`Scopebond hook ${hookVersion()}`);\n console.log(` user home ${home} ${installed ? \"(installed)\" : \"(not installed — run `scopebond install`)\"}`);\n console.log(` active config ${resolveConfigDir(process.cwd())}`);\n const ignored = untrustedProjectPolicy(process.cwd());\n if (ignored) console.log(` project policy ${ignored} ignored — not trusted (run \\`${cliCommand(\"trust\")}\\` to use it)`);\n console.log(` Claude Code ${claude ? \"configured\" : \"not configured\"}`);\n console.log(` Cursor ${cursor ? \"configured\" : cursorDetected() ? \"detected, not configured\" : \"not detected\"}`);\n console.log(` Codex ${codex ? \"configured (approve once with /hooks)\" : codexDetected() ? \"detected, not configured\" : \"not detected\"}`);\n console.log(` cloud workspace ${connected ? \"connected\" : \"not connected (local only)\"}`);\n console.log(` local receipts ${existsSync(dbPath) ? dbPath : \"none yet\"}`);\n}\n\nasync function runDoctor(): Promise<void> {\n const problems: string[] = [];\n const [major, minor] = process.versions.node.split(\".\").map(Number);\n const nodeOk = major > 22 || (major === 22 && minor >= 13);\n console.log(`Scopebond doctor`);\n console.log(` node ${process.versions.node} ${nodeOk ? \"ok\" : \"TOO OLD (need >=22.13)\"}`);\n if (!nodeOk) problems.push(\"node >=22.13 is required (the Cloud outbox uses node:sqlite)\");\n const cli = cliPath();\n console.log(` cli ${cli} ${existsSync(cli) ? \"ok\" : \"MISSING\"}`);\n const active = resolveConfigDir(process.cwd());\n const hasPolicy = existsSync(join(active, \"policy.json\"));\n console.log(` active config ${active} ${hasPolicy ? \"ok\" : \"no policy (run `scopebond install` or `init`)\"}`);\n if (!hasPolicy) problems.push(\"no policy found in the active config dir\");\n const ignored = untrustedProjectPolicy(process.cwd());\n if (ignored) console.log(` project policy ${ignored} IGNORED — not trusted (never trusted, or edited since). Review it, then \\`${cliCommand(\"trust\")}\\``);\n const codex = isHarnessConfigured(userHarnessFile(\"codex\"));\n console.log(` Codex hook ${codex ? \"configured\" : codexDetected() ? \"not configured — run `scopebond install --codex`\" : \"not detected\"}`);\n if (codex) console.log(` Codex approval run /hooks in Codex and approve Scopebond once`);\n const connection = loadConnection(active);\n if (!connection) {\n console.log(` cloud not connected (local only) — receipts stay on this machine`);\n } else {\n let reachable = \"unknown\";\n try {\n const res = await fetch(new URL(\"/healthz\", connection.url).toString(), { method: \"GET\" });\n reachable = res.ok ? \"reachable\" : `unhealthy (${res.status})`;\n } catch (error) { reachable = `unreachable (${(error as Error).message})`; }\n console.log(` cloud ${connection.url} — ${reachable}`);\n }\n console.log(problems.length ? `\\n${problems.length} problem(s): ${problems.join(\"; \")}` : `\\nAll good.`);\n process.exitCode = problems.length ? 1 : 0;\n}\n\nfunction runUninstall(args: string[]): void {\n requireInteractive(\"uninstall\", args);\n let removed = 0;\n for (const h of [\"claude\", \"cursor\", \"codex\"] as Harness[]) {\n if (removeHarnessConfig(userHarnessFile(h))) { console.log(`✓ removed the Scopebond hook from ${userHarnessFile(h)}`); removed++; }\n }\n if (removed === 0) console.log(\"no user-level harness config found.\");\n if (args.includes(\"--purge\")) { purgeHome(); console.log(`✓ purged ${userHome()} (keys, policy, receipts)`); }\n else console.log(`Kept ${userHome()} (keys, policy, receipts). Use --purge to remove it too.`);\n}\n\n/** `trust` — let this project's .scopebond policy govern here instead of the user\n * home, pinned to its current contents. Run by the user, not the agent: the file it\n * writes lives in the user home, which the starter policy write-protects. */\nfunction runTrust(args: string[]): void {\n requireInteractive(\"trust\", args);\n const dir = join(process.cwd(), \".scopebond\");\n if (!existsSync(join(dir, \"policy.json\"))) { console.error(`no project policy at ${join(dir, \"policy.json\")}`); process.exit(1); }\n const digest = trustProjectPolicy(dir);\n console.log(`✓ trusted ${join(dir, \"policy.json\")} (sha256 ${digest.slice(0, 12)}…)`);\n console.log(\"It governs agents in this project until it changes; after any edit, review it and run trust again.\");\n}\n\nfunction runLogin(): void {\n console.log(\"Device-code login is not available yet.\");\n console.log(`For now, connect with a one-time enrollment from your workspace:`);\n console.log(` ${cliCommand(\"connect <workspace-url> <enrollment>\")}`);\n process.exit(0);\n}\n\nconst [cmd, ...rest] = process.argv.slice(2);\nif (cmd === \"claude\") { await runClaude(); }\nelse if (cmd === \"cursor\") { await runCursor(); }\nelse if (cmd === \"codex\") { await runCodex(); }\nelse if (cmd === \"init\") { runInit(rest); }\nelse if (cmd === \"install\") { runInstall(rest); }\nelse if (cmd === \"connect\") { await runConnect(rest); }\nelse if (cmd === \"log\") { await runLog(rest); }\nelse if (cmd === \"verify\") { await runVerify(); }\nelse if (cmd === \"test\") { await runTest(rest); }\nelse if (cmd === \"flush\") { await runFlush(); }\nelse if (cmd === \"status\") { runStatus(); }\nelse if (cmd === \"doctor\") { await runDoctor(); }\nelse if (cmd === \"uninstall\") { runUninstall(rest); }\nelse if (cmd === \"login\") { runLogin(); }\nelse if (cmd === \"trust\") { runTrust(rest); }\nelse {\n console.error(\"usage: scopebond <claude|cursor|codex|init|install|connect|log|verify|test|flush|status|doctor|uninstall|login|trust> [--cursor] [--claude] [--codex] [--force] [--strict] [--no-install] [--purge] [--yes]\");\n process.exit(1);\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export { mapClaudeToolUse, mapCodexToolUse, mapCursorEvent, fillPushBranch } from "./map.js";
|
|
2
2
|
export type { Mapped, NormalizedIntent } from "./map.js";
|
|
3
|
-
export { createHookRuntime, starterPolicy } from "./runtime.js";
|
|
3
|
+
export { createHookRuntime, starterPolicy, upgradeStarterPolicy } from "./runtime.js";
|
|
4
4
|
export type { RuntimeConfig, Decision } from "./runtime.js";
|
|
5
5
|
export { scaffold, harnessSnippet, installHarness } from "./init.js";
|
|
6
|
-
export { userHome, userHarnessFile, resolveConfigDir, writeHarnessConfig, removeHarnessConfig, cursorDetected, codexDetected, absoluteHookCommand, isHarnessConfigured, purgeHome, } from "./install.js";
|
|
6
|
+
export { userHome, userHarnessFile, resolveConfigDir, writeHarnessConfig, removeHarnessConfig, cursorDetected, codexDetected, absoluteHookCommand, isHarnessConfigured, purgeHome, readHarnessConfig, trustProjectPolicy, isTrustedProject, untrustedProjectPolicy, trustedProjectsFile, } from "./install.js";
|
|
7
7
|
export type { Harness } from "./install.js";
|
|
8
8
|
export { connectCloud, loadConnection, attachExporter, flushBounded, connectionPath } from "./cloud.js";
|
|
9
9
|
export type { HookConnection } from "./cloud.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC7F,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC7F,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACtF,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,EACL,QAAQ,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,mBAAmB,EACpF,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,SAAS,EAClF,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,mBAAmB,GACrG,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACxG,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
// the deterministic mapper and the check-only runtime; the `scopebond-hook`
|
|
3
3
|
// binary is the thin harness adapter over them.
|
|
4
4
|
export { mapClaudeToolUse, mapCodexToolUse, mapCursorEvent, fillPushBranch } from "./map.js";
|
|
5
|
-
export { createHookRuntime, starterPolicy } from "./runtime.js";
|
|
5
|
+
export { createHookRuntime, starterPolicy, upgradeStarterPolicy } from "./runtime.js";
|
|
6
6
|
export { scaffold, harnessSnippet, installHarness } from "./init.js";
|
|
7
|
-
export { userHome, userHarnessFile, resolveConfigDir, writeHarnessConfig, removeHarnessConfig, cursorDetected, codexDetected, absoluteHookCommand, isHarnessConfigured, purgeHome, } from "./install.js";
|
|
7
|
+
export { userHome, userHarnessFile, resolveConfigDir, writeHarnessConfig, removeHarnessConfig, cursorDetected, codexDetected, absoluteHookCommand, isHarnessConfigured, purgeHome, readHarnessConfig, trustProjectPolicy, isTrustedProject, untrustedProjectPolicy, trustedProjectsFile, } from "./install.js";
|
|
8
8
|
export { connectCloud, loadConnection, attachExporter, flushBounded, connectionPath } from "./cloud.js";
|
|
9
9
|
export { scrubSecrets, scrubParam, redactCommand, digest, sha256 } from "./minimize.js";
|
|
10
10
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,4EAA4E;AAC5E,gDAAgD;AAEhD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE7F,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,4EAA4E;AAC5E,gDAAgD;AAEhD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE7F,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEtF,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,EACL,QAAQ,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,mBAAmB,EACpF,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,SAAS,EAClF,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,mBAAmB,GACrG,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAExG,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC","sourcesContent":["// @scopebond/hook — the Claude Code, Cursor + Codex connector. The library surface is\n// the deterministic mapper and the check-only runtime; the `scopebond-hook`\n// binary is the thin harness adapter over them.\n\nexport { mapClaudeToolUse, mapCodexToolUse, mapCursorEvent, fillPushBranch } from \"./map.js\";\nexport type { Mapped, NormalizedIntent } from \"./map.js\";\nexport { createHookRuntime, starterPolicy, upgradeStarterPolicy } from \"./runtime.js\";\nexport type { RuntimeConfig, Decision } from \"./runtime.js\";\nexport { scaffold, harnessSnippet, installHarness } from \"./init.js\";\nexport {\n userHome, userHarnessFile, resolveConfigDir, writeHarnessConfig, removeHarnessConfig,\n cursorDetected, codexDetected, absoluteHookCommand, isHarnessConfigured, purgeHome,\n readHarnessConfig, trustProjectPolicy, isTrustedProject, untrustedProjectPolicy, trustedProjectsFile,\n} from \"./install.js\";\nexport type { Harness } from \"./install.js\";\nexport { connectCloud, loadConnection, attachExporter, flushBounded, connectionPath } from \"./cloud.js\";\nexport type { HookConnection } from \"./cloud.js\";\nexport { scrubSecrets, scrubParam, redactCommand, digest, sha256 } from \"./minimize.js\";\n"]}
|
package/dist/init.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAYA,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAgB9G;AAED;;;sFAGsF;AACtF,wBAAgB,cAAc,CAAC,OAAO,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,EAAE,GAAG,GAAE,MAAsB,GAAG,MAAM,CAkC1G;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,OAAO,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CA2B7E"}
|
package/dist/init.js
CHANGED
|
@@ -6,6 +6,7 @@ import { dirname, join } from "node:path";
|
|
|
6
6
|
import { loadOrCreateAttester } from "@scopebond/gateway/node";
|
|
7
7
|
import { createSigner } from "@scopebond/sdk";
|
|
8
8
|
import { starterPolicy } from "./runtime.js";
|
|
9
|
+
import { readHarnessConfig } from "./install.js";
|
|
9
10
|
import { hookCommand } from "./version.js";
|
|
10
11
|
export function scaffold(dir, opts = {}) {
|
|
11
12
|
mkdirSync(dir, { recursive: true });
|
|
@@ -34,16 +35,8 @@ export function installHarness(harness, cwd = process.cwd()) {
|
|
|
34
35
|
const file = harness === "cursor" ? join(cwd, ".cursor", "hooks.json")
|
|
35
36
|
: harness === "codex" ? join(cwd, ".codex", "hooks.json")
|
|
36
37
|
: join(cwd, ".claude", "settings.json");
|
|
38
|
+
const config = readHarnessConfig(file); // throws, leaving the file intact, if it is not a JSON object
|
|
37
39
|
mkdirSync(dirname(file), { recursive: true });
|
|
38
|
-
let config = {};
|
|
39
|
-
if (existsSync(file)) {
|
|
40
|
-
try {
|
|
41
|
-
const p = JSON.parse(readFileSync(file, "utf8"));
|
|
42
|
-
if (isRecord(p))
|
|
43
|
-
config = p;
|
|
44
|
-
}
|
|
45
|
-
catch { /* start fresh on unreadable */ }
|
|
46
|
-
}
|
|
47
40
|
const hooks = isRecord(config.hooks) ? config.hooks : (config.hooks = {});
|
|
48
41
|
const cursorCmd = hookCommand("cursor");
|
|
49
42
|
const claudeCmd = hookCommand("claude");
|