@scopebond/hook 0.8.1 → 0.10.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 +239 -0
- package/dist/budget-load.d.ts +68 -0
- package/dist/budget-load.d.ts.map +1 -0
- package/dist/budget-load.js +164 -0
- package/dist/budget-load.js.map +1 -0
- package/dist/capabilities.d.ts +103 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +212 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/classify.d.ts +17 -0
- package/dist/classify.d.ts.map +1 -0
- package/dist/classify.js +78 -0
- package/dist/classify.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +585 -13
- package/dist/cli.js.map +1 -1
- package/dist/cloud.d.ts +8 -0
- package/dist/cloud.d.ts.map +1 -1
- package/dist/cloud.js.map +1 -1
- package/dist/dispatch-cli.d.ts +2 -0
- package/dist/dispatch-cli.d.ts.map +1 -0
- package/dist/dispatch-cli.js +128 -0
- package/dist/dispatch-cli.js.map +1 -0
- package/dist/explain.d.ts.map +1 -1
- package/dist/explain.js +2 -1
- package/dist/explain.js.map +1 -1
- package/dist/group.d.ts +12 -0
- package/dist/group.d.ts.map +1 -0
- package/dist/group.js +55 -0
- package/dist/group.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -1
- package/dist/install.d.ts +10 -0
- package/dist/install.d.ts.map +1 -1
- package/dist/install.js +56 -0
- package/dist/install.js.map +1 -1
- package/dist/managed.d.ts +69 -0
- package/dist/managed.d.ts.map +1 -0
- package/dist/managed.js +184 -0
- package/dist/managed.js.map +1 -0
- package/dist/map.d.ts +4 -0
- package/dist/map.d.ts.map +1 -1
- package/dist/map.js +29 -1
- package/dist/map.js.map +1 -1
- package/dist/obs-emitter.d.ts +132 -0
- package/dist/obs-emitter.d.ts.map +1 -0
- package/dist/obs-emitter.js +415 -0
- package/dist/obs-emitter.js.map +1 -0
- package/dist/obs-store.d.ts +160 -0
- package/dist/obs-store.d.ts.map +1 -0
- package/dist/obs-store.js +367 -0
- package/dist/obs-store.js.map +1 -0
- package/dist/obs-upload.d.ts +24 -0
- package/dist/obs-upload.d.ts.map +1 -0
- package/dist/obs-upload.js +231 -0
- package/dist/obs-upload.js.map +1 -0
- package/dist/observation.d.ts +232 -0
- package/dist/observation.d.ts.map +1 -0
- package/dist/observation.js +308 -0
- package/dist/observation.js.map +1 -0
- package/dist/paths.d.ts +15 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +79 -0
- package/dist/paths.js.map +1 -0
- package/dist/policy-load.d.ts +60 -0
- package/dist/policy-load.d.ts.map +1 -0
- package/dist/policy-load.js +151 -0
- package/dist/policy-load.js.map +1 -0
- package/dist/policy-sync.d.ts +45 -0
- package/dist/policy-sync.d.ts.map +1 -0
- package/dist/policy-sync.js +171 -0
- package/dist/policy-sync.js.map +1 -0
- package/dist/proof.d.ts +30 -0
- package/dist/proof.d.ts.map +1 -0
- package/dist/proof.js +186 -0
- package/dist/proof.js.map +1 -0
- package/dist/rules.d.ts +20 -0
- package/dist/rules.d.ts.map +1 -1
- package/dist/rules.js +50 -0
- package/dist/rules.js.map +1 -1
- package/dist/runtime.d.ts +21 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +77 -10
- package/dist/runtime.js.map +1 -1
- package/dist/scan.d.ts +7 -0
- package/dist/scan.d.ts.map +1 -0
- package/dist/scan.js +38 -0
- package/dist/scan.js.map +1 -0
- package/dist/shell.d.ts.map +1 -1
- package/dist/shell.js +12 -3
- package/dist/shell.js.map +1 -1
- package/dist/sql-classify.d.ts +11 -0
- package/dist/sql-classify.d.ts.map +1 -0
- package/dist/sql-classify.js +251 -0
- package/dist/sql-classify.js.map +1 -0
- package/dist/typed-infra.d.ts +73 -0
- package/dist/typed-infra.d.ts.map +1 -0
- package/dist/typed-infra.js +758 -0
- package/dist/typed-infra.js.map +1 -0
- package/dist/typed-ops.d.ts +140 -0
- package/dist/typed-ops.d.ts.map +1 -0
- package/dist/typed-ops.js +549 -0
- package/dist/typed-ops.js.map +1 -0
- package/dist/vectors.d.ts +40 -0
- package/dist/vectors.d.ts.map +1 -0
- package/dist/vectors.js +219 -0
- package/dist/vectors.js.map +1 -0
- package/package.json +5 -5
package/dist/cloud.d.ts
CHANGED
|
@@ -4,6 +4,14 @@ import { SqliteCloudOutbox } from "@scopebond/gateway/node";
|
|
|
4
4
|
* scoped machine credential; treat cloud.json as a secret (written 0600). */
|
|
5
5
|
export interface HookConnection extends CloudEnrollmentResult {
|
|
6
6
|
url: string;
|
|
7
|
+
/** The workspace's installation id for this machine. An enrollment answer names it
|
|
8
|
+
* `installation_id`, or (older answers) as `gateway_id`, which is the same identifier;
|
|
9
|
+
* observations use `gateway_id` when the explicit field is absent. */
|
|
10
|
+
installation_id?: string;
|
|
11
|
+
/** The installation generation the enrollment created. Only the workspace can say what it
|
|
12
|
+
* is, so there is no fallback: without it the hook reports observations unsupported
|
|
13
|
+
* rather than guessing a generation. */
|
|
14
|
+
installation_generation?: number;
|
|
7
15
|
}
|
|
8
16
|
export declare const connectionPath: (dir: string) => string;
|
|
9
17
|
/** Read the persisted connection, or null when the hook is not connected to Cloud. */
|
package/dist/cloud.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud.d.ts","sourceRoot":"","sources":["../src/cloud.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,KAAK,qBAAqB,EAAE,KAAK,qBAAqB,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAC9F,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAwB,MAAM,yBAAyB,CAAC;AAElF;8EAC8E;AAC9E,MAAM,WAAW,cAAe,SAAQ,qBAAqB;IAC3D,GAAG,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"cloud.d.ts","sourceRoot":"","sources":["../src/cloud.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,KAAK,qBAAqB,EAAE,KAAK,qBAAqB,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAC9F,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAwB,MAAM,yBAAyB,CAAC;AAElF;8EAC8E;AAC9E,MAAM,WAAW,cAAe,SAAQ,qBAAqB;IAC3D,GAAG,EAAE,MAAM,CAAC;IACZ;;2EAEuE;IACvE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;6CAEyC;IACzC,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,KAAG,MAAiC,CAAC;AAE/E,sFAAsF;AACtF,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAQjE;AAED;;wFAEwF;AACxF,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB,EAAE,SAAS,CAAC,EAAE,OAAO,KAAK,GAChF,OAAO,CAAC,cAAc,CAAC,CAOzB;AAED;oFACoF;AACpF,wBAAgB,cAAc,CAC5B,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,CAAC,EAAE,OAAO,KAAK,GAC9F;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAA;CAAE,CAI7E;AAED;kFACkF;AAClF,wBAAsB,YAAY,CAAC,QAAQ,EAAE,aAAa,EAAE,SAAS,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAK3F"}
|
package/dist/cloud.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud.js","sourceRoot":"","sources":["../src/cloud.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,iFAAiF;AACjF,oFAAoF;AACpF,qFAAqF;AACrF,oFAAoF;AAEpF,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,uBAAuB,EAAE,mBAAmB,EAAE,iBAAiB,GAEhE,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"cloud.js","sourceRoot":"","sources":["../src/cloud.ts"],"names":[],"mappings":"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","sourcesContent":["// scopebond-hook → Scopebond Cloud: enroll the machine's countersigning key with a\n// workspace and auto-export signed receipts to the hosted portal, so a connected\n// hook starts monitoring automatically. Reuses the gateway's enrollment and bounded\n// durable exporter (D40 — no new transport). The machine credential and the complete\n// receipt log stay local-first; export is best-effort and never blocks a tool call.\n\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n completeCloudEnrollment, createCloudExporter, withCloudExporter,\n type CloudEnrollmentBundle, type CloudEnrollmentResult, type CloudExporter, type ReceiptStore,\n} from \"@scopebond/gateway\";\nimport { SqliteCloudOutbox, loadOrCreateAttester } from \"@scopebond/gateway/node\";\n\n/** The persisted connection between this machine and a Cloud workspace. Holds the\n * scoped machine credential; treat cloud.json as a secret (written 0600). */\nexport interface HookConnection extends CloudEnrollmentResult {\n url: string;\n /** The workspace's installation id for this machine. An enrollment answer names it\n * `installation_id`, or (older answers) as `gateway_id`, which is the same identifier;\n * observations use `gateway_id` when the explicit field is absent. */\n installation_id?: string;\n /** The installation generation the enrollment created. Only the workspace can say what it\n * is, so there is no fallback: without it the hook reports observations unsupported\n * rather than guessing a generation. */\n installation_generation?: number;\n}\n\nexport const connectionPath = (dir: string): string => join(dir, \"cloud.json\");\n\n/** Read the persisted connection, or null when the hook is not connected to Cloud. */\nexport function loadConnection(dir: string): HookConnection | null {\n const path = connectionPath(dir);\n if (!existsSync(path)) return null;\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as Partial<HookConnection>;\n if (typeof parsed.url === \"string\" && typeof parsed.credential === \"string\") return parsed as HookConnection;\n } catch { /* fall through */ }\n return null;\n}\n\n/** Enroll the machine's attester with a workspace using the portal's one-use handoff,\n * then persist the scoped machine credential. The attester whose possession is proved\n * here is the same key the hook countersigns receipts with, so ingest accepts them. */\nexport async function connectCloud(\n dir: string, url: string, bundle: CloudEnrollmentBundle, fetchImpl?: typeof fetch,\n): Promise<HookConnection> {\n const { attester } = loadOrCreateAttester({ file: join(dir, \"attester.key\") });\n const { attester: agent } = loadOrCreateAttester({ file: join(dir, \"agent.key\") });\n const result = await completeCloudEnrollment({ url, bundle, attester, agent, fetch: fetchImpl });\n const connection: HookConnection = { url, ...result };\n writeFileSync(connectionPath(dir), JSON.stringify(connection, null, 2) + \"\\n\", { mode: 0o600 });\n return connection;\n}\n\n/** Wrap a receipt store so every stored receipt is enqueued to a durable outbox and\n * exported to Cloud. Returns the wrapped store and the exporter (flush + stop). */\nexport function attachExporter(\n outboxDbPath: string, connection: HookConnection, store: ReceiptStore, fetchImpl?: typeof fetch,\n): { store: ReceiptStore; exporter: CloudExporter; outbox: SqliteCloudOutbox } {\n const outbox = new SqliteCloudOutbox(outboxDbPath);\n const exporter = createCloudExporter({ url: connection.url, credential: connection.credential, outbox, fetch: fetchImpl });\n return { store: withCloudExporter(store, exporter), exporter, outbox };\n}\n\n/** Attempt delivery with a bounded timeout so a per-invocation hook never hangs the\n * agent; undelivered receipts stay in the durable outbox and flush next time. */\nexport async function flushBounded(exporter: CloudExporter, timeoutMs = 3000): Promise<void> {\n await Promise.race([\n exporter.flush().catch(() => {}),\n new Promise<void>((resolve) => setTimeout(resolve, Math.max(0, timeoutMs)).unref?.()),\n ]);\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch-cli.d.ts","sourceRoot":"","sources":["../src/dispatch-cli.ts"],"names":[],"mappings":"AAsBA,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,GAAG,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CA4EvH"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// `scopebond budget` and `scopebond delegation`: manage the dispatch boundary's local settings.
|
|
2
|
+
//
|
|
3
|
+
// These change what an agent may do, so they belong to a person at a terminal. The caller
|
|
4
|
+
// refuses them without a TTY or `--yes`, the same as `init` and `trust`.
|
|
5
|
+
//
|
|
6
|
+
// budget init [--actor kid] [--ops a,b] write the 100 per 60 seconds monitor-only template
|
|
7
|
+
// budget status each policy, its state and the current count
|
|
8
|
+
// budget ack <budget-id> accept a policy exactly as written
|
|
9
|
+
// delegation add <file.json> register a delegation (a root, or a child of one)
|
|
10
|
+
// delegation list every delegation and whether it is revoked
|
|
11
|
+
// delegation revoke <id> revoke one and, by chain, everything below it
|
|
12
|
+
// delegation import <file.json> add revoked ids exported from the workspace
|
|
13
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
import { DispatchStore, DISPATCH_DB, DISPATCH_FILE, readDispatchFile } from "@scopebond/gateway/node";
|
|
16
|
+
import { budgetAcknowledged, budgetDigest, defaultBudgetTemplate, scopeDigest } from "@scopebond/gateway";
|
|
17
|
+
function writeSettings(dir, next) {
|
|
18
|
+
writeFileSync(join(dir, DISPATCH_FILE), `${JSON.stringify(next, null, 2)}\n`, { mode: 0o600 });
|
|
19
|
+
}
|
|
20
|
+
export function runDispatchCommand(kind, args, dir, agentKid) {
|
|
21
|
+
const [sub, ...rest] = args;
|
|
22
|
+
const flag = (name) => { const i = rest.indexOf(name); return i >= 0 ? rest[i + 1] : undefined; };
|
|
23
|
+
if (kind === "budget") {
|
|
24
|
+
const current = readDispatchFile(dir) ?? {};
|
|
25
|
+
if (sub === "init") {
|
|
26
|
+
const actor = flag("--actor") ?? agentKid;
|
|
27
|
+
const ops = (flag("--ops") ?? "shell.exec,file.write,git.push,mcp.tool.call,net.fetch").split(",").filter(Boolean);
|
|
28
|
+
const template = defaultBudgetTemplate(actor, ops);
|
|
29
|
+
if ((current.budgets ?? []).some((b) => b.budget_id === template.budget_id)) {
|
|
30
|
+
console.log(`A budget for ${actor} over these operations already exists.`);
|
|
31
|
+
return 0;
|
|
32
|
+
}
|
|
33
|
+
writeSettings(dir, { ...current, budgets: [...(current.budgets ?? []), template] });
|
|
34
|
+
console.log(`Wrote a monitor-only budget: ${template.max} dispatches in ${template.window_seconds}s for ${actor}.`);
|
|
35
|
+
console.log(`Nothing is limited. To enforce it, edit "mode" to "enforce" in ${join(dir, DISPATCH_FILE)}, then run \`budget ack ${template.budget_id}\`.`);
|
|
36
|
+
return 0;
|
|
37
|
+
}
|
|
38
|
+
if (sub === "ack") {
|
|
39
|
+
const id = rest[0];
|
|
40
|
+
const budgets = current.budgets ?? [];
|
|
41
|
+
const policy = budgets.find((b) => b.budget_id === id);
|
|
42
|
+
if (!policy) {
|
|
43
|
+
console.error(`no budget ${id ?? ""}`);
|
|
44
|
+
return 1;
|
|
45
|
+
}
|
|
46
|
+
const acknowledged = { ...policy, acknowledgement: { digest: budgetDigest(policy), acknowledged_at: new Date().toISOString() } };
|
|
47
|
+
writeSettings(dir, { ...current, budgets: budgets.map((b) => (b.budget_id === id ? acknowledged : b)) });
|
|
48
|
+
console.log(`Acknowledged ${id} at digest ${budgetDigest(policy).slice(0, 12)} (${policy.mode}). Any later edit to it needs a new acknowledgement.`);
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
if (sub === "status") {
|
|
52
|
+
const budgets = current.budgets ?? [];
|
|
53
|
+
if (budgets.length === 0) {
|
|
54
|
+
console.log("No action budgets are configured.");
|
|
55
|
+
return 0;
|
|
56
|
+
}
|
|
57
|
+
const db = existsSync(join(dir, DISPATCH_DB)) ? new DispatchStore(join(dir, DISPATCH_DB)) : null;
|
|
58
|
+
try {
|
|
59
|
+
for (const b of budgets) {
|
|
60
|
+
const used = db ? db.budgetCount(b.budget_id, b.window_seconds).count : 0;
|
|
61
|
+
const state = b.revoked ? "withdrawn" : Date.parse(b.expires_at) <= Date.now() ? "expired" : budgetAcknowledged(b) ? "acknowledged" : "not acknowledged";
|
|
62
|
+
const scope = b.authority_scope === "shared_gateway" ? "shared gateway (an independent hook cannot enforce this)" : "this installation only";
|
|
63
|
+
console.log(`${b.budget_id} ${b.mode} ${used}/${b.max} in ${b.window_seconds}s ${state} ${scope}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
db?.close();
|
|
68
|
+
}
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
71
|
+
console.error("usage: budget init|ack <id>|status");
|
|
72
|
+
return 1;
|
|
73
|
+
}
|
|
74
|
+
const store = new DispatchStore(join(dir, DISPATCH_DB));
|
|
75
|
+
try {
|
|
76
|
+
if (sub === "list") {
|
|
77
|
+
const all = store.listDelegations();
|
|
78
|
+
if (all.length === 0)
|
|
79
|
+
console.log("No delegations are registered.");
|
|
80
|
+
for (const d of all)
|
|
81
|
+
console.log(`${d.delegation_id} actor ${d.actor} parent ${d.parent_id ?? "(root)"} until ${d.expires_at}${d.revoked ? " REVOKED" : ""}`);
|
|
82
|
+
return 0;
|
|
83
|
+
}
|
|
84
|
+
if (sub === "revoke") {
|
|
85
|
+
if (!rest[0]) {
|
|
86
|
+
console.error("usage: delegation revoke <id>");
|
|
87
|
+
return 1;
|
|
88
|
+
}
|
|
89
|
+
store.revoke(rest[0]);
|
|
90
|
+
console.log(`Revoked ${rest[0]}; every session below it is refused from the next action.`);
|
|
91
|
+
return 0;
|
|
92
|
+
}
|
|
93
|
+
if (sub === "import") {
|
|
94
|
+
if (!rest[0]) {
|
|
95
|
+
console.error("usage: delegation import <revocations.json>");
|
|
96
|
+
return 1;
|
|
97
|
+
}
|
|
98
|
+
const raw = JSON.parse(readFileSync(rest[0], "utf8"));
|
|
99
|
+
const ids = Array.isArray(raw) ? raw : raw?.revoked;
|
|
100
|
+
if (!Array.isArray(ids)) {
|
|
101
|
+
console.error("the file must be a list of ids or { \"revoked\": [ids] }");
|
|
102
|
+
return 1;
|
|
103
|
+
}
|
|
104
|
+
console.log(`Imported ${store.importRevocations(ids)} new revocation(s).`);
|
|
105
|
+
return 0;
|
|
106
|
+
}
|
|
107
|
+
if (sub === "add") {
|
|
108
|
+
if (!rest[0]) {
|
|
109
|
+
console.error("usage: delegation add <delegation.json> ({ delegation_id, parent_id, actor, scope, expires_at })");
|
|
110
|
+
return 1;
|
|
111
|
+
}
|
|
112
|
+
const input = JSON.parse(readFileSync(rest[0], "utf8"));
|
|
113
|
+
const result = store.addDelegation({ ...input, scope_digest: scopeDigest(input.scope), issued_at: input.issued_at ?? new Date().toISOString() });
|
|
114
|
+
if (!result.ok) {
|
|
115
|
+
console.error(`refused: ${result.problem}`);
|
|
116
|
+
return 1;
|
|
117
|
+
}
|
|
118
|
+
console.log("Registered.");
|
|
119
|
+
return 0;
|
|
120
|
+
}
|
|
121
|
+
console.error("usage: delegation add <file>|list|revoke <id>|import <file>");
|
|
122
|
+
return 1;
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
store.close();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=dispatch-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch-cli.js","sourceRoot":"","sources":["../src/dispatch-cli.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,EAAE;AACF,0FAA0F;AAC1F,yEAAyE;AACzE,EAAE;AACF,+FAA+F;AAC/F,yFAAyF;AACzF,+EAA+E;AAC/E,8FAA8F;AAC9F,uFAAuF;AACvF,0FAA0F;AAC1F,wFAAwF;AAExF,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACtG,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,qBAAqB,EAAE,WAAW,EAAgD,MAAM,oBAAoB,CAAC;AAExJ,SAAS,aAAa,CAAC,GAAW,EAAE,IAA6B;IAC/D,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACjG,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAA6B,EAAE,IAAc,EAAE,GAAW,EAAE,QAAgB;IAC7G,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAC5B,MAAM,IAAI,GAAG,CAAC,IAAY,EAAsB,EAAE,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC9H,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;YACnB,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,QAAQ,CAAC;YAC1C,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,wDAAwD,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACnH,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACnD,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,wCAAwC,CAAC,CAAC;gBAAC,OAAO,CAAC,CAAC;YAAC,CAAC;YACtK,aAAa,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;YACpF,OAAO,CAAC,GAAG,CAAC,gCAAgC,QAAQ,CAAC,GAAG,kBAAkB,QAAQ,CAAC,cAAc,SAAS,KAAK,GAAG,CAAC,CAAC;YACpH,OAAO,CAAC,GAAG,CAAC,kEAAkE,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,2BAA2B,QAAQ,CAAC,SAAS,KAAK,CAAC,CAAC;YAC1J,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;YAClB,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACnB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC;YACvD,IAAI,CAAC,MAAM,EAAE,CAAC;gBAAC,OAAO,CAAC,KAAK,CAAC,aAAa,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;gBAAC,OAAO,CAAC,CAAC;YAAC,CAAC;YAClE,MAAM,YAAY,GAAuB,EAAE,GAAG,MAAM,EAAE,eAAe,EAAE,EAAE,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,EAAE,eAAe,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC;YACrJ,aAAa,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACzG,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,cAAc,YAAY,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM,CAAC,IAAI,sDAAsD,CAAC,CAAC;YACrJ,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YACrB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;YACtC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAAC,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;gBAAC,OAAO,CAAC,CAAC;YAAC,CAAC;YACzF,MAAM,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACjG,IAAI,CAAC;gBACH,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;oBACxB,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC1E,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,kBAAkB,CAAC;oBACzJ,MAAM,KAAK,GAAG,CAAC,CAAC,eAAe,KAAK,gBAAgB,CAAC,CAAC,CAAC,0DAA0D,CAAC,CAAC,CAAC,wBAAwB,CAAC;oBAC7I,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,cAAc,MAAM,KAAK,KAAK,KAAK,EAAE,CAAC,CAAC;gBACzG,CAAC;YACH,CAAC;oBAAS,CAAC;gBAAC,EAAE,EAAE,KAAK,EAAE,CAAC;YAAC,CAAC;YAC1B,OAAO,CAAC,CAAC;QACX,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACpD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;IACxD,IAAI,CAAC;QACH,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;YACnB,MAAM,GAAG,GAAG,KAAK,CAAC,eAAe,EAAE,CAAC;YACpC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;YACpE,KAAK,MAAM,CAAC,IAAI,GAAG;gBAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,aAAa,WAAW,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC,SAAS,IAAI,QAAQ,WAAW,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAClK,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBAAC,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;gBAAC,OAAO,CAAC,CAAC;YAAC,CAAC;YAC3E,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,2DAA2D,CAAC,CAAC;YAC3F,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBAAC,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;gBAAC,OAAO,CAAC,CAAC;YAAC,CAAC;YACzF,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAY,CAAC;YACjE,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAE,GAA6B,EAAE,OAAO,CAAC;YAC/E,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAC,OAAO,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;gBAAC,OAAO,CAAC,CAAC;YAAC,CAAC;YACjH,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,iBAAiB,CAAC,GAAe,CAAC,qBAAqB,CAAC,CAAC;YACvF,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;YAClB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBAAC,OAAO,CAAC,KAAK,CAAC,mGAAmG,CAAC,CAAC;gBAAC,OAAO,CAAC,CAAC;YAAC,CAAC;YAC/I,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAwE,CAAC;YAC/H,MAAM,MAAM,GAAG,KAAK,CAAC,aAAa,CAAC,EAAE,GAAG,KAAK,EAAE,YAAY,EAAE,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YACjJ,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;gBAAC,OAAO,CAAC,KAAK,CAAC,YAAY,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;gBAAC,OAAO,CAAC,CAAC;YAAC,CAAC;YAC1E,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YAC3B,OAAO,CAAC,CAAC;QACX,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,6DAA6D,CAAC,CAAC;QAC7E,OAAO,CAAC,CAAC;IACX,CAAC;YAAS,CAAC;QAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IAAC,CAAC;AAC9B,CAAC","sourcesContent":["// `scopebond budget` and `scopebond delegation`: manage the dispatch boundary's local settings.\n//\n// These change what an agent may do, so they belong to a person at a terminal. The caller\n// refuses them without a TTY or `--yes`, the same as `init` and `trust`.\n//\n// budget init [--actor kid] [--ops a,b] write the 100 per 60 seconds monitor-only template\n// budget status each policy, its state and the current count\n// budget ack <budget-id> accept a policy exactly as written\n// delegation add <file.json> register a delegation (a root, or a child of one)\n// delegation list every delegation and whether it is revoked\n// delegation revoke <id> revoke one and, by chain, everything below it\n// delegation import <file.json> add revoked ids exported from the workspace\n\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { DispatchStore, DISPATCH_DB, DISPATCH_FILE, readDispatchFile } from \"@scopebond/gateway/node\";\nimport { budgetAcknowledged, budgetDigest, defaultBudgetTemplate, scopeDigest, type ActionBudgetPolicy, type DelegatedScope } from \"@scopebond/gateway\";\n\nfunction writeSettings(dir: string, next: Record<string, unknown>): void {\n writeFileSync(join(dir, DISPATCH_FILE), `${JSON.stringify(next, null, 2)}\\n`, { mode: 0o600 });\n}\n\nexport function runDispatchCommand(kind: \"budget\" | \"delegation\", args: string[], dir: string, agentKid: string): number {\n const [sub, ...rest] = args;\n const flag = (name: string): string | undefined => { const i = rest.indexOf(name); return i >= 0 ? rest[i + 1] : undefined; };\n if (kind === \"budget\") {\n const current = readDispatchFile(dir) ?? {};\n if (sub === \"init\") {\n const actor = flag(\"--actor\") ?? agentKid;\n const ops = (flag(\"--ops\") ?? \"shell.exec,file.write,git.push,mcp.tool.call,net.fetch\").split(\",\").filter(Boolean);\n const template = defaultBudgetTemplate(actor, ops);\n if ((current.budgets ?? []).some((b) => b.budget_id === template.budget_id)) { console.log(`A budget for ${actor} over these operations already exists.`); return 0; }\n writeSettings(dir, { ...current, budgets: [...(current.budgets ?? []), template] });\n console.log(`Wrote a monitor-only budget: ${template.max} dispatches in ${template.window_seconds}s for ${actor}.`);\n console.log(`Nothing is limited. To enforce it, edit \"mode\" to \"enforce\" in ${join(dir, DISPATCH_FILE)}, then run \\`budget ack ${template.budget_id}\\`.`);\n return 0;\n }\n if (sub === \"ack\") {\n const id = rest[0];\n const budgets = current.budgets ?? [];\n const policy = budgets.find((b) => b.budget_id === id);\n if (!policy) { console.error(`no budget ${id ?? \"\"}`); return 1; }\n const acknowledged: ActionBudgetPolicy = { ...policy, acknowledgement: { digest: budgetDigest(policy), acknowledged_at: new Date().toISOString() } };\n writeSettings(dir, { ...current, budgets: budgets.map((b) => (b.budget_id === id ? acknowledged : b)) });\n console.log(`Acknowledged ${id} at digest ${budgetDigest(policy).slice(0, 12)} (${policy.mode}). Any later edit to it needs a new acknowledgement.`);\n return 0;\n }\n if (sub === \"status\") {\n const budgets = current.budgets ?? [];\n if (budgets.length === 0) { console.log(\"No action budgets are configured.\"); return 0; }\n const db = existsSync(join(dir, DISPATCH_DB)) ? new DispatchStore(join(dir, DISPATCH_DB)) : null;\n try {\n for (const b of budgets) {\n const used = db ? db.budgetCount(b.budget_id, b.window_seconds).count : 0;\n const state = b.revoked ? \"withdrawn\" : Date.parse(b.expires_at) <= Date.now() ? \"expired\" : budgetAcknowledged(b) ? \"acknowledged\" : \"not acknowledged\";\n const scope = b.authority_scope === \"shared_gateway\" ? \"shared gateway (an independent hook cannot enforce this)\" : \"this installation only\";\n console.log(`${b.budget_id} ${b.mode} ${used}/${b.max} in ${b.window_seconds}s ${state} ${scope}`);\n }\n } finally { db?.close(); }\n return 0;\n }\n console.error(\"usage: budget init|ack <id>|status\");\n return 1;\n }\n\n const store = new DispatchStore(join(dir, DISPATCH_DB));\n try {\n if (sub === \"list\") {\n const all = store.listDelegations();\n if (all.length === 0) console.log(\"No delegations are registered.\");\n for (const d of all) console.log(`${d.delegation_id} actor ${d.actor} parent ${d.parent_id ?? \"(root)\"} until ${d.expires_at}${d.revoked ? \" REVOKED\" : \"\"}`);\n return 0;\n }\n if (sub === \"revoke\") {\n if (!rest[0]) { console.error(\"usage: delegation revoke <id>\"); return 1; }\n store.revoke(rest[0]);\n console.log(`Revoked ${rest[0]}; every session below it is refused from the next action.`);\n return 0;\n }\n if (sub === \"import\") {\n if (!rest[0]) { console.error(\"usage: delegation import <revocations.json>\"); return 1; }\n const raw = JSON.parse(readFileSync(rest[0], \"utf8\")) as unknown;\n const ids = Array.isArray(raw) ? raw : (raw as { revoked?: unknown })?.revoked;\n if (!Array.isArray(ids)) { console.error(\"the file must be a list of ids or { \\\"revoked\\\": [ids] }\"); return 1; }\n console.log(`Imported ${store.importRevocations(ids as string[])} new revocation(s).`);\n return 0;\n }\n if (sub === \"add\") {\n if (!rest[0]) { console.error(\"usage: delegation add <delegation.json> ({ delegation_id, parent_id, actor, scope, expires_at })\"); return 1; }\n const input = JSON.parse(readFileSync(rest[0], \"utf8\")) as { scope: DelegatedScope; issued_at?: string; [k: string]: unknown };\n const result = store.addDelegation({ ...input, scope_digest: scopeDigest(input.scope), issued_at: input.issued_at ?? new Date().toISOString() });\n if (!result.ok) { console.error(`refused: ${result.problem}`); return 1; }\n console.log(\"Registered.\");\n return 0;\n }\n console.error(\"usage: delegation add <file>|list|revoke <id>|import <file>\");\n return 1;\n } finally { store.close(); }\n}\n"]}
|
package/dist/explain.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explain.d.ts","sourceRoot":"","sources":["../src/explain.ts"],"names":[],"mappings":"AAcA,2DAA2D;AAC3D,MAAM,WAAW,aAAa;IAC5B,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qDAAqD;AACrD,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAQD;gFACgF;AAChF,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"explain.d.ts","sourceRoot":"","sources":["../src/explain.ts"],"names":[],"mappings":"AAcA,2DAA2D;AAC3D,MAAM,WAAW,aAAa;IAC5B,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qDAAqD;AACrD,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAQD;gFACgF;AAChF,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,GAAG,MAAM,CAUxE;AAWD,oEAAoE;AACpE,wBAAgB,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,aAAa,GAAG,IAAI,CAQvH;AAED,MAAM,WAAW,gBAAgB;IAC/B,8DAA8D;IAC9D,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;8CAE0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;qFACiF;IACjF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;kFAGkF;AAClF,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAoB3D"}
|
package/dist/explain.js
CHANGED
|
@@ -24,7 +24,8 @@ export function describeAction(intent) {
|
|
|
24
24
|
: type === "git.push" ? `${str(p.remote)} ${str(p.ref)}`.trim()
|
|
25
25
|
: type === "file.write" || type === "file.read" ? str(p.path)
|
|
26
26
|
: type === "mcp.tool.call" ? `${str(p.server)}/${str(p.tool)}`
|
|
27
|
-
: type === "net.fetch" ? str(p.host)
|
|
27
|
+
: type === "net.fetch" ? str(p.host)
|
|
28
|
+
: type === "db.exec" ? `${str(p.scope)} ${str(p.provider)} ${str(p.verb)}`.trim() : "";
|
|
28
29
|
return `${type || "?"}${bits ? ` ${bits}` : ""}`;
|
|
29
30
|
}
|
|
30
31
|
/** Trim a description to one readable fragment, cut on a word boundary. */
|
package/dist/explain.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explain.js","sourceRoot":"","sources":["../src/explain.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,8BAA8B;AAC9B,EAAE;AACF,iFAAiF;AACjF,+EAA+E;AAC/E,kFAAkF;AAClF,iFAAiF;AACjF,+EAA+E;AAC/E,oDAAoD;AACpD,EAAE;AACF,2DAA2D;AAC3D,gFAAgF;AAChF,6EAA6E;AAmB7E;0EAC0E;AAC1E,MAAM,OAAO,GAAG,GAAG,CAAC;AAEpB,MAAM,GAAG,GAAG,CAAC,CAAU,EAAU,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAErE;gFACgF;AAChF,MAAM,UAAU,cAAc,CAAC,MAAiC;IAC9D,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACtC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,CAA4B,CAAC;IAC5D,MAAM,IAAI,GAAG,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;QACjD,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE;YAC/D,CAAC,CAAC,IAAI,KAAK,YAAY,IAAI,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;gBAC7D,CAAC,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;oBAC9D,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"explain.js","sourceRoot":"","sources":["../src/explain.ts"],"names":[],"mappings":"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","sourcesContent":["// The sentence a person — and the coding agent they are supervising — sees when\n// Scopebond blocks an action.\n//\n// The engine's own reason is precise and unreadable (\"param ref fails pattern\"):\n// it names the mechanism, not the rule. The policy clause that decided already\n// carries a written `description`, and the verdict names that clause, so both are\n// available here. The composed message says what was blocked, which rule blocked\n// it, why that rule exists, and where to change it — and it keeps the engine's\n// detail so a surprising decision stays debuggable.\n//\n// This string is also fed back to the agent (Claude Code's\n// `permissionDecisionReason`, Cursor's `agentMessage`), so a clear one lets the\n// agent pick a different approach instead of retrying the same blocked call.\n\n/** A policy clause, as much of it as the message needs. */\nexport interface ExplainClause {\n id?: unknown;\n mode?: unknown;\n description?: unknown;\n}\n\nexport interface ExplainPolicy {\n clauses?: unknown;\n}\n\n/** An intent, as much of it as the message needs. */\nexport interface ExplainIntent {\n action_type?: unknown;\n params?: unknown;\n}\n\n/** How long a clause description may run before it is cut. Long enough for the\n * starter policy's first clause, short enough not to bury a terminal. */\nconst MAX_WHY = 300;\n\nconst str = (v: unknown): string => (typeof v === \"string\" ? v : \"\");\n\n/** One line naming the action: `git.push origin main`, `shell.exec rm`,\n * `file.read .env`. Shared with `log` so a decision reads the same in both. */\nexport function describeAction(intent: ExplainIntent | undefined): string {\n const type = str(intent?.action_type);\n const p = (intent?.params ?? {}) as Record<string, unknown>;\n const bits = type === \"shell.exec\" ? str(p.program)\n : type === \"git.push\" ? `${str(p.remote)} ${str(p.ref)}`.trim()\n : type === \"file.write\" || type === \"file.read\" ? str(p.path)\n : type === \"mcp.tool.call\" ? `${str(p.server)}/${str(p.tool)}`\n : type === \"net.fetch\" ? str(p.host)\n : type === \"db.exec\" ? `${str(p.scope)} ${str(p.provider)} ${str(p.verb)}`.trim() : \"\";\n return `${type || \"?\"}${bits ? ` ${bits}` : \"\"}`;\n}\n\n/** Trim a description to one readable fragment, cut on a word boundary. */\nfunction shorten(text: string, max = MAX_WHY): string {\n const clean = text.replace(/\\s+/g, \" \").trim();\n if (clean.length <= max) return clean;\n const cut = clean.slice(0, max);\n const lastSpace = cut.lastIndexOf(\" \");\n return `${(lastSpace > max * 0.6 ? cut.slice(0, lastSpace) : cut).replace(/[,;:—-]$/, \"\")}…`;\n}\n\n/** Find the clause that decided, by the id the verdict reported. */\nexport function findClause(policy: ExplainPolicy | undefined, clauseId: string | null | undefined): ExplainClause | null {\n if (!clauseId || !Array.isArray(policy?.clauses)) return null;\n for (const clause of policy.clauses) {\n if (clause && typeof clause === \"object\" && str((clause as ExplainClause).id) === clauseId) {\n return clause as ExplainClause;\n }\n }\n return null;\n}\n\nexport interface ExplainDenyInput {\n /** The loaded policy, for the deciding clause's own words. */\n policy?: ExplainPolicy;\n /** The clause id the verdict reported, when it reported one. */\n clauseId?: string | null;\n /** The engine's reason — kept verbatim as the technical detail. */\n detail: string;\n /** The action that was blocked. */\n intent?: ExplainIntent;\n /** Where the rule lives, so the next step is a real path. */\n policyPath?: string;\n /** How to change it, when there is something better to say than \"edit this file\" — the\n * compiled policy is generated, so pointing a reader at it invites them to hand-edit\n * something that will be overwritten. */\n remedy?: string;\n /** The harness reported this action only after it happened, so the decision records\n * and flags it but did not prevent it. The wording must not claim otherwise. */\n postHoc?: boolean;\n}\n\n/** Compose the block message. Degrades in order: with a clause and a description\n * it explains the rule; with a clause but no description it still names it; with\n * no clause at all (an undetermined verdict, a kill switch) it reports the\n * engine's reason unchanged rather than inventing a rule that did not decide. */\nexport function explainDeny(input: ExplainDenyInput): string {\n const detail = input.detail.trim() || \"denied\";\n const action = describeAction(input.intent);\n const clause = findClause(input.policy, input.clauseId);\n const clauseId = str(clause?.id) || str(input.clauseId);\n // \"blocked\" is a claim about prevention, so it is only used where the action really\n // was stopped in flight.\n const verb = input.postHoc ? \"recorded an out-of-policy\" : \"blocked\";\n if (!clauseId) {\n return action ? `Scopebond ${verb} ${action}: ${detail}` : `Scopebond ${verb} action: ${detail}`;\n }\n const mode = str(clause?.mode) || \"enforce\";\n const why = shorten(str(clause?.description));\n const lines = [\n `Scopebond ${verb} ${action || \"action\"} — rule \"${clauseId}\" (${mode}).`,\n ...(why ? [`Why: ${why}`] : []),\n ...(detail && detail !== \"denied\" ? [`Detail: ${detail}`] : []),\n `Change the rule: ${input.remedy ?? `edit clause \"${clauseId}\" in ${input.policyPath || \"your Scopebond policy\"}`}`,\n ];\n return lines.join(\"\\n\");\n}\n"]}
|
package/dist/group.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Mapped } from "./map.js";
|
|
2
|
+
export declare const ACTION_GROUP_PARAM = "action_group";
|
|
3
|
+
export declare const ACTION_GROUP_SIZE_PARAM = "action_group_size";
|
|
4
|
+
export declare const ACTION_GROUP_SEQ_PARAM = "action_group_seq";
|
|
5
|
+
/** A new group id. With a harness call id the result is stable for that id. */
|
|
6
|
+
export declare function actionGroupId(key?: string): string;
|
|
7
|
+
/** Stamp every intent of one call with the shared group id, its position and the count. */
|
|
8
|
+
export declare function withActionGroup(mapped: Mapped[], groupId: string): Mapped[];
|
|
9
|
+
/** The physical targets of a group, each counted once, for consumers that total actions
|
|
10
|
+
* by physical target (a target reached by two spellings or two intents counts once). */
|
|
11
|
+
export declare function distinctTargets(mapped: Mapped[]): string[];
|
|
12
|
+
//# sourceMappingURL=group.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../src/group.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,eAAO,MAAM,kBAAkB,iBAAiB,CAAC;AACjD,eAAO,MAAM,uBAAuB,sBAAsB,CAAC;AAC3D,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AAEzD,+EAA+E;AAC/E,wBAAgB,aAAa,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAKlD;AAED,2FAA2F;AAC3F,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAa3E;AAED;yFACyF;AACzF,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAO1D"}
|
package/dist/group.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Canonical action groups.
|
|
2
|
+
//
|
|
3
|
+
// One tool call can map to several intents: a shell command, the files it reads and
|
|
4
|
+
// writes, every destination of a multi-ref push, each spelling of an ambiguous Windows
|
|
5
|
+
// short path. Each intent is its own signed receipt; without a shared parent id a
|
|
6
|
+
// consumer can only count them as unrelated actions or guess that they belong together.
|
|
7
|
+
//
|
|
8
|
+
// The group id rides inside the intent's `params` (`action_group`, `action_group_size`,
|
|
9
|
+
// `action_group_seq`). `params` is the extensible, signed part of an intent — the
|
|
10
|
+
// receipt schema allows undeclared adapter parameters there — so this adds no
|
|
11
|
+
// top-level receipt key and changes no receipt that already exists. Because the group
|
|
12
|
+
// is part of the signed intent, the machine key that authenticates the action
|
|
13
|
+
// authenticates its linkage too; nothing links receipts heuristically.
|
|
14
|
+
//
|
|
15
|
+
// The id is derived from the harness's own tool-call id when it supplies one (so a
|
|
16
|
+
// retried call keeps its group) and is random otherwise. Distinct calls never share an
|
|
17
|
+
// id: the derivation is a one-way hash of the key, never a shared prefix.
|
|
18
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
19
|
+
export const ACTION_GROUP_PARAM = "action_group";
|
|
20
|
+
export const ACTION_GROUP_SIZE_PARAM = "action_group_size";
|
|
21
|
+
export const ACTION_GROUP_SEQ_PARAM = "action_group_seq";
|
|
22
|
+
/** A new group id. With a harness call id the result is stable for that id. */
|
|
23
|
+
export function actionGroupId(key) {
|
|
24
|
+
if (key !== undefined && key !== "") {
|
|
25
|
+
return `sbg_${createHash("sha256").update(`scopebond:action-group:v1\0${key}`).digest("hex").slice(0, 32)}`;
|
|
26
|
+
}
|
|
27
|
+
return `sbg_${randomBytes(16).toString("hex")}`;
|
|
28
|
+
}
|
|
29
|
+
/** Stamp every intent of one call with the shared group id, its position and the count. */
|
|
30
|
+
export function withActionGroup(mapped, groupId) {
|
|
31
|
+
return mapped.map((m, index) => ({
|
|
32
|
+
...m,
|
|
33
|
+
intent: {
|
|
34
|
+
...m.intent,
|
|
35
|
+
params: {
|
|
36
|
+
...m.intent.params,
|
|
37
|
+
[ACTION_GROUP_PARAM]: groupId,
|
|
38
|
+
[ACTION_GROUP_SIZE_PARAM]: mapped.length,
|
|
39
|
+
[ACTION_GROUP_SEQ_PARAM]: index,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
/** The physical targets of a group, each counted once, for consumers that total actions
|
|
45
|
+
* by physical target (a target reached by two spellings or two intents counts once). */
|
|
46
|
+
export function distinctTargets(mapped) {
|
|
47
|
+
const seen = new Set();
|
|
48
|
+
for (const m of mapped) {
|
|
49
|
+
const path = m.intent.params.path;
|
|
50
|
+
if (typeof path === "string" && path !== "")
|
|
51
|
+
seen.add(`${m.intent.action_type.startsWith("file.") ? "file" : m.intent.action_type}:${path.toLowerCase()}`);
|
|
52
|
+
}
|
|
53
|
+
return [...seen];
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"group.js","sourceRoot":"","sources":["../src/group.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,EAAE;AACF,oFAAoF;AACpF,uFAAuF;AACvF,kFAAkF;AAClF,wFAAwF;AACxF,EAAE;AACF,wFAAwF;AACxF,kFAAkF;AAClF,8EAA8E;AAC9E,sFAAsF;AACtF,8EAA8E;AAC9E,uEAAuE;AACvE,EAAE;AACF,mFAAmF;AACnF,uFAAuF;AACvF,0EAA0E;AAE1E,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGtD,MAAM,CAAC,MAAM,kBAAkB,GAAG,cAAc,CAAC;AACjD,MAAM,CAAC,MAAM,uBAAuB,GAAG,mBAAmB,CAAC;AAC3D,MAAM,CAAC,MAAM,sBAAsB,GAAG,kBAAkB,CAAC;AAEzD,+EAA+E;AAC/E,MAAM,UAAU,aAAa,CAAC,GAAY;IACxC,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;QACpC,OAAO,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,8BAA8B,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;IAC9G,CAAC;IACD,OAAO,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;AAClD,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,eAAe,CAAC,MAAgB,EAAE,OAAe;IAC/D,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAC/B,GAAG,CAAC;QACJ,MAAM,EAAE;YACN,GAAG,CAAC,CAAC,MAAM;YACX,MAAM,EAAE;gBACN,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM;gBAClB,CAAC,kBAAkB,CAAC,EAAE,OAAO;gBAC7B,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC,MAAM;gBACxC,CAAC,sBAAsB,CAAC,EAAE,KAAK;aAChC;SACF;KACF,CAAC,CAAC,CAAC;AACN,CAAC;AAED;yFACyF;AACzF,MAAM,UAAU,eAAe,CAAC,MAAgB;IAC9C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;QAClC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,EAAE;YAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC7J,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AACnB,CAAC","sourcesContent":["// Canonical action groups.\n//\n// One tool call can map to several intents: a shell command, the files it reads and\n// writes, every destination of a multi-ref push, each spelling of an ambiguous Windows\n// short path. Each intent is its own signed receipt; without a shared parent id a\n// consumer can only count them as unrelated actions or guess that they belong together.\n//\n// The group id rides inside the intent's `params` (`action_group`, `action_group_size`,\n// `action_group_seq`). `params` is the extensible, signed part of an intent — the\n// receipt schema allows undeclared adapter parameters there — so this adds no\n// top-level receipt key and changes no receipt that already exists. Because the group\n// is part of the signed intent, the machine key that authenticates the action\n// authenticates its linkage too; nothing links receipts heuristically.\n//\n// The id is derived from the harness's own tool-call id when it supplies one (so a\n// retried call keeps its group) and is random otherwise. Distinct calls never share an\n// id: the derivation is a one-way hash of the key, never a shared prefix.\n\nimport { createHash, randomBytes } from \"node:crypto\";\nimport type { Mapped } from \"./map.js\";\n\nexport const ACTION_GROUP_PARAM = \"action_group\";\nexport const ACTION_GROUP_SIZE_PARAM = \"action_group_size\";\nexport const ACTION_GROUP_SEQ_PARAM = \"action_group_seq\";\n\n/** A new group id. With a harness call id the result is stable for that id. */\nexport function actionGroupId(key?: string): string {\n if (key !== undefined && key !== \"\") {\n return `sbg_${createHash(\"sha256\").update(`scopebond:action-group:v1\\0${key}`).digest(\"hex\").slice(0, 32)}`;\n }\n return `sbg_${randomBytes(16).toString(\"hex\")}`;\n}\n\n/** Stamp every intent of one call with the shared group id, its position and the count. */\nexport function withActionGroup(mapped: Mapped[], groupId: string): Mapped[] {\n return mapped.map((m, index) => ({\n ...m,\n intent: {\n ...m.intent,\n params: {\n ...m.intent.params,\n [ACTION_GROUP_PARAM]: groupId,\n [ACTION_GROUP_SIZE_PARAM]: mapped.length,\n [ACTION_GROUP_SEQ_PARAM]: index,\n },\n },\n }));\n}\n\n/** The physical targets of a group, each counted once, for consumers that total actions\n * by physical target (a target reached by two spellings or two intents counts once). */\nexport function distinctTargets(mapped: Mapped[]): string[] {\n const seen = new Set<string>();\n for (const m of mapped) {\n const path = m.intent.params.path;\n if (typeof path === \"string\" && path !== \"\") seen.add(`${m.intent.action_type.startsWith(\"file.\") ? \"file\" : m.intent.action_type}:${path.toLowerCase()}`);\n }\n return [...seen];\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,23 @@ export { createHookRuntime, starterPolicy, upgradeStarterPolicy } from "./runtim
|
|
|
4
4
|
export type { RuntimeConfig, Decision } from "./runtime.js";
|
|
5
5
|
export { compile, defaultRules, describeRules, loadRules, saveRules, rulesPath, pathRuleFor, RULES_FILE, } from "./rules.js";
|
|
6
6
|
export type { RuleSet, PathRule } from "./rules.js";
|
|
7
|
+
export { pathRuleMatches, isDestructiveProgram, isProtectedBranch } from "./rules.js";
|
|
8
|
+
export { classifyIntent, classificationBlocks, BLOCKING } from "./classify.js";
|
|
9
|
+
export type { CatalogId, Classification } from "./classify.js";
|
|
10
|
+
export { classifyRoot, applyRootScope } from "./paths.js";
|
|
11
|
+
export type { RootScope, RootOptions } from "./paths.js";
|
|
12
|
+
export { actionGroupId, withActionGroup, distinctTargets, ACTION_GROUP_PARAM, ACTION_GROUP_SIZE_PARAM, ACTION_GROUP_SEQ_PARAM } from "./group.js";
|
|
13
|
+
export { computeManifest, renderManifest, cellState, cellKey, vectorsForCell, vectorDigest } from "./capabilities.js";
|
|
14
|
+
export type { Manifest, CapabilityCell, CapabilityState, ProofRecord, HostVariant, EventPhase, ManifestInput } from "./capabilities.js";
|
|
15
|
+
export { runProofFixtures, deliverProofReceipts, loadProofs, saveProofs, PROOF_FILE } from "./proof.js";
|
|
16
|
+
export { inspectBudgetExport, loadBudgetExport, localBudgetOf, BUDGET_EXPORT_TYPE } from "./budget-load.js";
|
|
17
|
+
export { inspectExport, loadPolicyExport, policyScopeDigest, policyBuilds, POLICY_SCOPE_DOMAIN, LOADED_POLICY_FILE } from "./policy-load.js";
|
|
18
|
+
export { inspectManaged, compileManaged, installManaged, restoreLocal, isManaged, readMeta, digestRules, MANAGED_RULE_IDS, MANAGED_DOC_FILE, MANAGED_META_FILE, } from "./managed.js";
|
|
19
|
+
export type { ManagedDocument, ManagedRule, ManagedMeta, RefusalReason } from "./managed.js";
|
|
20
|
+
export { syncPolicy, syncIfDue, SYNC_INTERVAL_MS, INLINE_BUDGET_MS } from "./policy-sync.js";
|
|
21
|
+
export type { SyncOutcome, SyncOptions } from "./policy-sync.js";
|
|
22
|
+
export { VECTORS, mapVector } from "./vectors.js";
|
|
23
|
+
export type { Vector, VectorAgent, Dialect } from "./vectors.js";
|
|
7
24
|
export { scaffold, harnessSnippet, installHarness, placeHook } from "./init.js";
|
|
8
25
|
export type { HookPlacement } from "./init.js";
|
|
9
26
|
export { userHome, userHarnessFile, projectHarnessFile, resolveConfigDir, writeHarnessConfig, removeHarnessConfig, cursorDetected, codexDetected, absoluteHookCommand, isHarnessConfigured, purgeHome, readHarnessConfig, trustProjectPolicy, isTrustedProject, untrustedProjectPolicy, trustedProjectsFile, harnessScopes, harnessScopeLabel, configuredHookCommands, hookCommandResolves, isScopebondHookCommand, harnessEntryMatches, localHarnessFile, isMachineSpecificCommand, gitShareState, excludeFromGit, pruneHarnessEntries, } from "./install.js";
|
|
@@ -15,4 +32,16 @@ export type { PinResult } from "./runtime-install.js";
|
|
|
15
32
|
export { connectCloud, loadConnection, attachExporter, flushBounded, connectionPath } from "./cloud.js";
|
|
16
33
|
export type { HookConnection } from "./cloud.js";
|
|
17
34
|
export { scrubSecrets, scrubParam, redactCommand, digest, sha256, keyedDigest, useDigestKey, loadOrCreateDigestKey } from "./minimize.js";
|
|
35
|
+
export { AGENT_KINDS, assertAgentKind, observationSigner, signObservation, observationHash, sourceReceiptHash, signingBytes, buildPayload, buildOperation, operationsForCall, bindingKeyFromHex, loadOrCreateBindingKey, digestPolicy, REQUEST_BINDING_DOMAIN, MAX_OBSERVATION_BYTES, MAX_BATCH_ITEMS, MAX_BATCH_BODY_BYTES, } from "./observation.js";
|
|
36
|
+
export type { ObservationPayload, SignedObservation, ObservationSigner, BindingKey, AgentKind } from "./observation.js";
|
|
37
|
+
export { ObservationStore, OBSERVATION_DB } from "./obs-store.js";
|
|
38
|
+
export { uploadPending, parseRetryAfter, OBSERVATIONS_PATH } from "./obs-upload.js";
|
|
39
|
+
export { openObservations, observationStatus, describeObservations, ObservationEmitter, OBSERVATIONS_SCOPE } from "./obs-emitter.js";
|
|
40
|
+
export { wireLifecycleHooks, unwireLifecycleHooks } from "./install.js";
|
|
41
|
+
export { deriveTypedOperations, keyedIdFor, callRequestOf, TYPED_ACTION_TYPES, fixtureProbe, gitPushOperation, githubOperation, packageOperation, parseGh, parseGithubMcp, normalizeRemote, systemGit, UNBOUND, } from "./typed-ops.js";
|
|
42
|
+
export type { CallRequest, GitProbe, TypedContext, GithubRepo, GithubRequest, DeriveInput } from "./typed-ops.js";
|
|
43
|
+
export { deriveInfraOperation, databaseFacts, databaseGuardActions, parseDestination, fetchOperation, systemFiles, fixtureFiles } from "./typed-infra.js";
|
|
44
|
+
export type { FileProbe, InfraContext, ReadContext, DatabaseFacts, DatabaseGuardAction } from "./typed-infra.js";
|
|
45
|
+
export { classifySql } from "./sql-classify.js";
|
|
46
|
+
export type { SqlClass, SqlVerb } from "./sql-classify.js";
|
|
18
47
|
//# sourceMappingURL=index.d.ts.map
|
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,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACtF,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EACL,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,GAC/F,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAChF,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EACL,QAAQ,EAAE,eAAe,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,mBAAmB,EACxG,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,SAAS,EAClF,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,mBAAmB,EACpG,aAAa,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,mBAAmB,EAC7E,sBAAsB,EAAE,mBAAmB,EAC3C,gBAAgB,EAAE,wBAAwB,EAAE,aAAa,EAAE,cAAc,EAAE,mBAAmB,GAC/F,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACvE,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClG,OAAO,EACL,oBAAoB,EAAE,eAAe,EAAE,iBAAiB,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,GACpG,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,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,WAAW,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -4,10 +4,29 @@
|
|
|
4
4
|
export { mapClaudeToolUse, mapCodexToolUse, mapCursorEvent, fillPushBranch } from "./map.js";
|
|
5
5
|
export { createHookRuntime, starterPolicy, upgradeStarterPolicy } from "./runtime.js";
|
|
6
6
|
export { compile, defaultRules, describeRules, loadRules, saveRules, rulesPath, pathRuleFor, RULES_FILE, } from "./rules.js";
|
|
7
|
+
export { pathRuleMatches, isDestructiveProgram, isProtectedBranch } from "./rules.js";
|
|
8
|
+
export { classifyIntent, classificationBlocks, BLOCKING } from "./classify.js";
|
|
9
|
+
export { classifyRoot, applyRootScope } from "./paths.js";
|
|
10
|
+
export { actionGroupId, withActionGroup, distinctTargets, ACTION_GROUP_PARAM, ACTION_GROUP_SIZE_PARAM, ACTION_GROUP_SEQ_PARAM } from "./group.js";
|
|
11
|
+
export { computeManifest, renderManifest, cellState, cellKey, vectorsForCell, vectorDigest } from "./capabilities.js";
|
|
12
|
+
export { runProofFixtures, deliverProofReceipts, loadProofs, saveProofs, PROOF_FILE } from "./proof.js";
|
|
13
|
+
export { inspectBudgetExport, loadBudgetExport, localBudgetOf, BUDGET_EXPORT_TYPE } from "./budget-load.js";
|
|
14
|
+
export { inspectExport, loadPolicyExport, policyScopeDigest, policyBuilds, POLICY_SCOPE_DOMAIN, LOADED_POLICY_FILE } from "./policy-load.js";
|
|
15
|
+
export { inspectManaged, compileManaged, installManaged, restoreLocal, isManaged, readMeta, digestRules, MANAGED_RULE_IDS, MANAGED_DOC_FILE, MANAGED_META_FILE, } from "./managed.js";
|
|
16
|
+
export { syncPolicy, syncIfDue, SYNC_INTERVAL_MS, INLINE_BUDGET_MS } from "./policy-sync.js";
|
|
17
|
+
export { VECTORS, mapVector } from "./vectors.js";
|
|
7
18
|
export { scaffold, harnessSnippet, installHarness, placeHook } from "./init.js";
|
|
8
19
|
export { userHome, userHarnessFile, projectHarnessFile, resolveConfigDir, writeHarnessConfig, removeHarnessConfig, cursorDetected, codexDetected, absoluteHookCommand, isHarnessConfigured, purgeHome, readHarnessConfig, trustProjectPolicy, isTrustedProject, untrustedProjectPolicy, trustedProjectsFile, harnessScopes, harnessScopeLabel, configuredHookCommands, hookCommandResolves, isScopebondHookCommand, harnessEntryMatches, localHarnessFile, isMachineSpecificCommand, gitShareState, excludeFromGit, pruneHarnessEntries, } from "./install.js";
|
|
9
20
|
export { explainDeny, describeAction, findClause } from "./explain.js";
|
|
10
21
|
export { ensureDurableRuntime, isEphemeralPath, nodeModulesRootOf, runtimeRoot, runtimeDirFor, pinnedCliPath, } from "./runtime-install.js";
|
|
11
22
|
export { connectCloud, loadConnection, attachExporter, flushBounded, connectionPath } from "./cloud.js";
|
|
12
23
|
export { scrubSecrets, scrubParam, redactCommand, digest, sha256, keyedDigest, useDigestKey, loadOrCreateDigestKey } from "./minimize.js";
|
|
24
|
+
export { AGENT_KINDS, assertAgentKind, observationSigner, signObservation, observationHash, sourceReceiptHash, signingBytes, buildPayload, buildOperation, operationsForCall, bindingKeyFromHex, loadOrCreateBindingKey, digestPolicy, REQUEST_BINDING_DOMAIN, MAX_OBSERVATION_BYTES, MAX_BATCH_ITEMS, MAX_BATCH_BODY_BYTES, } from "./observation.js";
|
|
25
|
+
export { ObservationStore, OBSERVATION_DB } from "./obs-store.js";
|
|
26
|
+
export { uploadPending, parseRetryAfter, OBSERVATIONS_PATH } from "./obs-upload.js";
|
|
27
|
+
export { openObservations, observationStatus, describeObservations, ObservationEmitter, OBSERVATIONS_SCOPE } from "./obs-emitter.js";
|
|
28
|
+
export { wireLifecycleHooks, unwireLifecycleHooks } from "./install.js";
|
|
29
|
+
export { deriveTypedOperations, keyedIdFor, callRequestOf, TYPED_ACTION_TYPES, fixtureProbe, gitPushOperation, githubOperation, packageOperation, parseGh, parseGithubMcp, normalizeRemote, systemGit, UNBOUND, } from "./typed-ops.js";
|
|
30
|
+
export { deriveInfraOperation, databaseFacts, databaseGuardActions, parseDestination, fetchOperation, systemFiles, fixtureFiles } from "./typed-infra.js";
|
|
31
|
+
export { classifySql } from "./sql-classify.js";
|
|
13
32
|
//# 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,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEtF,OAAO,EACL,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,GAC/F,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEhF,OAAO,EACL,QAAQ,EAAE,eAAe,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,mBAAmB,EACxG,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,SAAS,EAClF,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,mBAAmB,EACpG,aAAa,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,mBAAmB,EAC7E,sBAAsB,EAAE,mBAAmB,EAC3C,gBAAgB,EAAE,wBAAwB,EAAE,aAAa,EAAE,cAAc,EAAE,mBAAmB,GAC/F,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEvE,OAAO,EACL,oBAAoB,EAAE,eAAe,EAAE,iBAAiB,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,GACpG,MAAM,sBAAsB,CAAC;AAE9B,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,WAAW,EAAE,YAAY,EAAE,qBAAqB,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 {\n compile, defaultRules, describeRules, loadRules, saveRules, rulesPath, pathRuleFor, RULES_FILE,\n} from \"./rules.js\";\nexport type { RuleSet, PathRule } from \"./rules.js\";\nexport { scaffold, harnessSnippet, installHarness, placeHook } from \"./init.js\";\nexport type { HookPlacement } from \"./init.js\";\nexport {\n userHome, userHarnessFile, projectHarnessFile, resolveConfigDir, writeHarnessConfig, removeHarnessConfig,\n cursorDetected, codexDetected, absoluteHookCommand, isHarnessConfigured, purgeHome,\n readHarnessConfig, trustProjectPolicy, isTrustedProject, untrustedProjectPolicy, trustedProjectsFile,\n harnessScopes, harnessScopeLabel, configuredHookCommands, hookCommandResolves,\n isScopebondHookCommand, harnessEntryMatches,\n localHarnessFile, isMachineSpecificCommand, gitShareState, excludeFromGit, pruneHarnessEntries,\n} from \"./install.js\";\nexport type { Harness, HarnessScopes, GitShare } from \"./install.js\";\nexport { explainDeny, describeAction, findClause } from \"./explain.js\";\nexport type { ExplainDenyInput, ExplainIntent, ExplainPolicy, ExplainClause } from \"./explain.js\";\nexport {\n ensureDurableRuntime, isEphemeralPath, nodeModulesRootOf, runtimeRoot, runtimeDirFor, pinnedCliPath,\n} from \"./runtime-install.js\";\nexport type { PinResult } from \"./runtime-install.js\";\nexport { connectCloud, loadConnection, attachExporter, flushBounded, connectionPath } from \"./cloud.js\";\nexport type { HookConnection } from \"./cloud.js\";\nexport { scrubSecrets, scrubParam, redactCommand, digest, sha256, keyedDigest, useDigestKey, loadOrCreateDigestKey } from \"./minimize.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","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 {\n compile, defaultRules, describeRules, loadRules, saveRules, rulesPath, pathRuleFor, RULES_FILE,\n} from \"./rules.js\";\nexport type { RuleSet, PathRule } from \"./rules.js\";\nexport { pathRuleMatches, isDestructiveProgram, isProtectedBranch } from \"./rules.js\";\nexport { classifyIntent, classificationBlocks, BLOCKING } from \"./classify.js\";\nexport type { CatalogId, Classification } from \"./classify.js\";\nexport { classifyRoot, applyRootScope } from \"./paths.js\";\nexport type { RootScope, RootOptions } from \"./paths.js\";\nexport { actionGroupId, withActionGroup, distinctTargets, ACTION_GROUP_PARAM, ACTION_GROUP_SIZE_PARAM, ACTION_GROUP_SEQ_PARAM } from \"./group.js\";\nexport { computeManifest, renderManifest, cellState, cellKey, vectorsForCell, vectorDigest } from \"./capabilities.js\";\nexport type { Manifest, CapabilityCell, CapabilityState, ProofRecord, HostVariant, EventPhase, ManifestInput } from \"./capabilities.js\";\nexport { runProofFixtures, deliverProofReceipts, loadProofs, saveProofs, PROOF_FILE } from \"./proof.js\";\nexport { inspectBudgetExport, loadBudgetExport, localBudgetOf, BUDGET_EXPORT_TYPE } from \"./budget-load.js\";\nexport { inspectExport, loadPolicyExport, policyScopeDigest, policyBuilds, POLICY_SCOPE_DOMAIN, LOADED_POLICY_FILE } from \"./policy-load.js\";\nexport {\n inspectManaged, compileManaged, installManaged, restoreLocal, isManaged, readMeta, digestRules,\n MANAGED_RULE_IDS, MANAGED_DOC_FILE, MANAGED_META_FILE,\n} from \"./managed.js\";\nexport type { ManagedDocument, ManagedRule, ManagedMeta, RefusalReason } from \"./managed.js\";\nexport { syncPolicy, syncIfDue, SYNC_INTERVAL_MS, INLINE_BUDGET_MS } from \"./policy-sync.js\";\nexport type { SyncOutcome, SyncOptions } from \"./policy-sync.js\";\nexport { VECTORS, mapVector } from \"./vectors.js\";\nexport type { Vector, VectorAgent, Dialect } from \"./vectors.js\";\nexport { scaffold, harnessSnippet, installHarness, placeHook } from \"./init.js\";\nexport type { HookPlacement } from \"./init.js\";\nexport {\n userHome, userHarnessFile, projectHarnessFile, resolveConfigDir, writeHarnessConfig, removeHarnessConfig,\n cursorDetected, codexDetected, absoluteHookCommand, isHarnessConfigured, purgeHome,\n readHarnessConfig, trustProjectPolicy, isTrustedProject, untrustedProjectPolicy, trustedProjectsFile,\n harnessScopes, harnessScopeLabel, configuredHookCommands, hookCommandResolves,\n isScopebondHookCommand, harnessEntryMatches,\n localHarnessFile, isMachineSpecificCommand, gitShareState, excludeFromGit, pruneHarnessEntries,\n} from \"./install.js\";\nexport type { Harness, HarnessScopes, GitShare } from \"./install.js\";\nexport { explainDeny, describeAction, findClause } from \"./explain.js\";\nexport type { ExplainDenyInput, ExplainIntent, ExplainPolicy, ExplainClause } from \"./explain.js\";\nexport {\n ensureDurableRuntime, isEphemeralPath, nodeModulesRootOf, runtimeRoot, runtimeDirFor, pinnedCliPath,\n} from \"./runtime-install.js\";\nexport type { PinResult } from \"./runtime-install.js\";\nexport { connectCloud, loadConnection, attachExporter, flushBounded, connectionPath } from \"./cloud.js\";\nexport type { HookConnection } from \"./cloud.js\";\nexport { scrubSecrets, scrubParam, redactCommand, digest, sha256, keyedDigest, useDigestKey, loadOrCreateDigestKey } from \"./minimize.js\";\nexport {\n AGENT_KINDS, assertAgentKind, observationSigner, signObservation, observationHash, sourceReceiptHash, signingBytes,\n buildPayload, buildOperation, operationsForCall, bindingKeyFromHex, loadOrCreateBindingKey, digestPolicy,\n REQUEST_BINDING_DOMAIN, MAX_OBSERVATION_BYTES, MAX_BATCH_ITEMS, MAX_BATCH_BODY_BYTES,\n} from \"./observation.js\";\nexport type { ObservationPayload, SignedObservation, ObservationSigner, BindingKey, AgentKind } from \"./observation.js\";\nexport { ObservationStore, OBSERVATION_DB } from \"./obs-store.js\";\nexport { uploadPending, parseRetryAfter, OBSERVATIONS_PATH } from \"./obs-upload.js\";\nexport { openObservations, observationStatus, describeObservations, ObservationEmitter, OBSERVATIONS_SCOPE } from \"./obs-emitter.js\";\nexport { wireLifecycleHooks, unwireLifecycleHooks } from \"./install.js\";\nexport {\n deriveTypedOperations, keyedIdFor, callRequestOf, TYPED_ACTION_TYPES, fixtureProbe, gitPushOperation, githubOperation, packageOperation, parseGh, parseGithubMcp, normalizeRemote, systemGit, UNBOUND,\n} from \"./typed-ops.js\";\nexport type { CallRequest, GitProbe, TypedContext, GithubRepo, GithubRequest, DeriveInput } from \"./typed-ops.js\";\nexport { deriveInfraOperation, databaseFacts, databaseGuardActions, parseDestination, fetchOperation, systemFiles, fixtureFiles } from \"./typed-infra.js\";\nexport type { FileProbe, InfraContext, ReadContext, DatabaseFacts, DatabaseGuardAction } from \"./typed-infra.js\";\nexport { classifySql } from \"./sql-classify.js\";\nexport type { SqlClass, SqlVerb } from \"./sql-classify.js\";\n"]}
|
package/dist/install.d.ts
CHANGED
|
@@ -110,4 +110,14 @@ export declare function configuredHookCommands(file: string): string[];
|
|
|
110
110
|
export declare function hookCommandResolves(command: string): boolean;
|
|
111
111
|
/** Remove the user-level home (keys, policy, receipts). */
|
|
112
112
|
export declare function purgeHome(): void;
|
|
113
|
+
/** The Claude Code events the observation emitters listen to, beyond PreToolUse. */
|
|
114
|
+
export declare const LIFECYCLE_EVENTS: readonly ["SessionStart", "SessionEnd", "PostToolUse", "PostToolUseFailure"];
|
|
115
|
+
/** Add (idempotently) the session lifecycle and after-action hook entries to a Claude Code
|
|
116
|
+
* config file, running the same Scopebond command that already handles PreToolUse: the
|
|
117
|
+
* command tells the events apart. Only Claude Code is wired: its lifecycle events are the
|
|
118
|
+
* ones the hook's tested mapping covers. Nothing else in the file changes. */
|
|
119
|
+
export declare function wireLifecycleHooks(file: string, command: string): string;
|
|
120
|
+
/** Remove only the lifecycle entries `wireLifecycleHooks` added, leaving PreToolUse and every
|
|
121
|
+
* other setting alone. Returns the number removed. */
|
|
122
|
+
export declare function unwireLifecycleHooks(file: string): number;
|
|
113
123
|
//# sourceMappingURL=install.d.ts.map
|
package/dist/install.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEpD,gFAAgF;AAChF,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED;qEACqE;AACrE,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAIxD;AAED;gEACgE;AAChE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,GAAE,MAAsB,GAAG,MAAM,CAIxF;AAED;;;mDAGmD;AACnD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAE7F;AAED;;;;2EAI2E;AAC3E,MAAM,WAAW,aAAa;IAAG,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE;AAEpG,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,GAAE,MAAsB,GAAG,aAAa,CAS1F;AAED,gEAAgE;AAChE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAW/D;AAED;iFACiF;AACjF,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAIjE;AAED;;;;;mDAKmD;AACnD,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,CAAC;AAEpE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAepD;AAED;;0BAE0B;AAC1B,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAkBpD;AAED;4DAC4D;AAC5D,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM,CAqB9F;AAED;;sCAEsC;AACtC,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAYD;uFACuF;AACvF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQtD;AAED,wEAAwE;AACxE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGrD;AAED;;;;;iFAKiF;AACjF,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAavE;AAED,0FAA0F;AAC1F,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAIpF;AAyBD,eAAO,MAAM,sBAAsB,GAAI,KAAK,OAAO,KAAG,OAgBrD,CAAC;AAGF;kDACkD;AAClD,eAAO,MAAM,mBAAmB,GAAI,GAAG,OAAO,KAAG,OACkF,CAAC;AAGpI;;iFAEiF;AACjF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUvE;AAED;;;;;;;4EAO4E;AAC5E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK/D;AAED;4FAC4F;AAC5F,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAyB1F;AAED;gDACgD;AAChD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAUzD;AAED,4DAA4D;AAC5D,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED,2DAA2D;AAC3D,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED;;;;;;;;iEAQiE;AACjE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAG7E;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOzD;AAED;;sEAEsE;AACtE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAc7D;AAED;;;sFAGsF;AACtF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAa5D;AAED,2DAA2D;AAC3D,wBAAgB,SAAS,IAAI,IAAI,CAEhC"}
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
|
package/dist/install.js
CHANGED
|
@@ -458,4 +458,60 @@ export function hookCommandResolves(command) {
|
|
|
458
458
|
export function purgeHome() {
|
|
459
459
|
rmSync(userHome(), { recursive: true, force: true });
|
|
460
460
|
}
|
|
461
|
+
/** The Claude Code events the observation emitters listen to, beyond PreToolUse. */
|
|
462
|
+
export const LIFECYCLE_EVENTS = ["SessionStart", "SessionEnd", "PostToolUse", "PostToolUseFailure"];
|
|
463
|
+
/** Add (idempotently) the session lifecycle and after-action hook entries to a Claude Code
|
|
464
|
+
* config file, running the same Scopebond command that already handles PreToolUse: the
|
|
465
|
+
* command tells the events apart. Only Claude Code is wired: its lifecycle events are the
|
|
466
|
+
* ones the hook's tested mapping covers. Nothing else in the file changes. */
|
|
467
|
+
export function wireLifecycleHooks(file, command) {
|
|
468
|
+
const config = readHarnessConfig(file);
|
|
469
|
+
backupHarnessConfig(file);
|
|
470
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
471
|
+
const hooks = isRecord(config.hooks) ? config.hooks : (config.hooks = {});
|
|
472
|
+
for (const event of LIFECYCLE_EVENTS) {
|
|
473
|
+
const list = Array.isArray(hooks[event]) ? hooks[event] : (hooks[event] = []);
|
|
474
|
+
const at = list.findIndex(entryMatches);
|
|
475
|
+
const entry = event.startsWith("Session")
|
|
476
|
+
? { hooks: [{ type: "command", command }] }
|
|
477
|
+
: { matcher: "*", hooks: [{ type: "command", command }] };
|
|
478
|
+
if (at >= 0)
|
|
479
|
+
list[at] = entry;
|
|
480
|
+
else
|
|
481
|
+
list.push(entry);
|
|
482
|
+
}
|
|
483
|
+
writeFileSync(file, JSON.stringify(config, null, 2) + "\n");
|
|
484
|
+
return file;
|
|
485
|
+
}
|
|
486
|
+
/** Remove only the lifecycle entries `wireLifecycleHooks` added, leaving PreToolUse and every
|
|
487
|
+
* other setting alone. Returns the number removed. */
|
|
488
|
+
export function unwireLifecycleHooks(file) {
|
|
489
|
+
if (!existsSync(file))
|
|
490
|
+
return 0;
|
|
491
|
+
let config;
|
|
492
|
+
try {
|
|
493
|
+
config = readHarnessConfig(file);
|
|
494
|
+
}
|
|
495
|
+
catch {
|
|
496
|
+
return 0;
|
|
497
|
+
}
|
|
498
|
+
const hooks = isRecord(config.hooks) ? config.hooks : null;
|
|
499
|
+
if (!hooks)
|
|
500
|
+
return 0;
|
|
501
|
+
let removed = 0;
|
|
502
|
+
for (const event of LIFECYCLE_EVENTS) {
|
|
503
|
+
const value = hooks[event];
|
|
504
|
+
if (!Array.isArray(value))
|
|
505
|
+
continue;
|
|
506
|
+
const kept = value.filter((e) => !entryMatches(e));
|
|
507
|
+
removed += value.length - kept.length;
|
|
508
|
+
if (kept.length)
|
|
509
|
+
hooks[event] = kept;
|
|
510
|
+
else
|
|
511
|
+
delete hooks[event];
|
|
512
|
+
}
|
|
513
|
+
if (removed > 0)
|
|
514
|
+
writeFileSync(file, JSON.stringify(config, null, 2) + "\n");
|
|
515
|
+
return removed;
|
|
516
|
+
}
|
|
461
517
|
//# sourceMappingURL=install.js.map
|