@guilz-dev/belay 0.3.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 +7 -1
- package/dist/adapters/cursor/runtime-entry.js +1 -0
- package/dist/adapters/layouts/scope.js +3 -2
- package/dist/adapters/shared/gate-runtime.d.ts +12 -16
- package/dist/adapters/shared/gate-runtime.js +499 -43
- package/dist/bundle/claude-runtime.mjs +8004 -2676
- package/dist/bundle/codex-runtime.mjs +8021 -2683
- package/dist/bundle/cursor-runtime.mjs +7993 -2667
- package/dist/cli.js +180 -6
- package/dist/commands/approve.d.ts +1 -0
- package/dist/commands/approve.js +45 -26
- package/dist/commands/classify-for-report.js +1 -1
- package/dist/commands/config.d.ts +8 -0
- package/dist/commands/config.js +264 -58
- package/dist/commands/doctor.js +47 -2
- package/dist/commands/explain.js +17 -2
- package/dist/commands/harvest.d.ts +29 -0
- package/dist/commands/harvest.js +72 -0
- package/dist/commands/judge.d.ts +11 -1
- package/dist/commands/judge.js +24 -4
- package/dist/commands/metrics.js +34 -2
- package/dist/commands/quality.d.ts +38 -0
- package/dist/commands/quality.js +105 -0
- package/dist/commands/session.d.ts +20 -0
- package/dist/commands/session.js +51 -0
- package/dist/commands/simulate.d.ts +1 -0
- package/dist/commands/simulate.js +7 -2
- package/dist/commands/standing-allow.d.ts +10 -0
- package/dist/commands/standing-allow.js +26 -0
- package/dist/commands/tui.d.ts +48 -0
- package/dist/commands/tui.js +150 -0
- package/dist/config-io.js +59 -17
- package/dist/conformance/guarantee-posture.d.ts +21 -0
- package/dist/conformance/guarantee-posture.js +46 -0
- package/dist/conformance/guarantee-table.d.ts +1 -0
- package/dist/conformance/guarantee-table.js +14 -9
- package/dist/core/approval-replay-cli.d.ts +7 -0
- package/dist/core/approval-replay-cli.js +36 -0
- package/dist/core/approval-replay.d.ts +45 -0
- package/dist/core/approval-replay.js +141 -0
- package/dist/core/approval-service.d.ts +15 -0
- package/dist/core/approval-service.js +53 -4
- package/dist/core/approval.d.ts +26 -3
- package/dist/core/approval.js +61 -7
- package/dist/core/audit-analysis.d.ts +7 -1
- package/dist/core/audit-analysis.js +111 -0
- package/dist/core/audit-metrics.d.ts +7 -0
- package/dist/core/audit-metrics.js +24 -4
- package/dist/core/audit-query.d.ts +1 -0
- package/dist/core/audit-query.js +3 -0
- package/dist/core/audit-replay-context.d.ts +35 -0
- package/dist/core/audit-replay-context.js +88 -0
- package/dist/core/audit-types.d.ts +24 -1
- package/dist/core/audit-types.js +1 -1
- package/dist/core/capability/approval-state-mutation.d.ts +13 -0
- package/dist/core/capability/approval-state-mutation.js +92 -0
- package/dist/core/capability/approval-v3.d.ts +15 -0
- package/dist/core/capability/approval-v3.js +74 -0
- package/dist/core/capability/attestation.d.ts +13 -0
- package/dist/core/capability/attestation.js +55 -0
- package/dist/core/capability/boundary-attestation-sign.d.ts +21 -0
- package/dist/core/capability/boundary-attestation-sign.js +84 -0
- package/dist/core/capability/boundary-driver-container.d.ts +7 -0
- package/dist/core/capability/boundary-driver-container.js +122 -0
- package/dist/core/capability/boundary-driver.d.ts +29 -0
- package/dist/core/capability/boundary-driver.js +43 -0
- package/dist/core/capability/boundary-egress.d.ts +21 -0
- package/dist/core/capability/boundary-egress.js +109 -0
- package/dist/core/capability/boundary-grant-materialize.d.ts +13 -0
- package/dist/core/capability/boundary-grant-materialize.js +78 -0
- package/dist/core/capability/boundary-profile.d.ts +15 -0
- package/dist/core/capability/boundary-profile.js +25 -0
- package/dist/core/capability/boundary-run.d.ts +23 -0
- package/dist/core/capability/boundary-run.js +23 -0
- package/dist/core/capability/boundary-session.d.ts +57 -0
- package/dist/core/capability/boundary-session.js +129 -0
- package/dist/core/capability/capability-request-hash.d.ts +2 -0
- package/dist/core/capability/capability-request-hash.js +8 -0
- package/dist/core/capability/gate-latency-ratchet.d.ts +7 -0
- package/dist/core/capability/gate-latency-ratchet.js +18 -0
- package/dist/core/capability/gate-policy-shadow.d.ts +25 -0
- package/dist/core/capability/gate-policy-shadow.js +108 -0
- package/dist/core/capability/gate-shadow-audit.d.ts +1 -0
- package/dist/core/capability/gate-shadow-audit.js +1 -0
- package/dist/core/capability/gate-shadow-ratchet.d.ts +14 -0
- package/dist/core/capability/gate-shadow-ratchet.js +81 -0
- package/dist/core/capability/grant-lease.d.ts +9 -0
- package/dist/core/capability/grant-lease.js +46 -0
- package/dist/core/capability/grant-loader.d.ts +12 -0
- package/dist/core/capability/grant-loader.js +23 -0
- package/dist/core/capability/grant-match.d.ts +6 -0
- package/dist/core/capability/grant-match.js +93 -0
- package/dist/core/capability/grant.d.ts +16 -0
- package/dist/core/capability/grant.js +16 -0
- package/dist/core/capability/index.d.ts +10 -1
- package/dist/core/capability/index.js +8 -0
- package/dist/core/capability/limits.d.ts +7 -0
- package/dist/core/capability/limits.js +55 -0
- package/dist/core/capability/paths.d.ts +2 -2
- package/dist/core/capability/paths.js +9 -9
- package/dist/core/capability/policy-bridge.d.ts +18 -0
- package/dist/core/capability/policy-bridge.js +51 -0
- package/dist/core/capability/policy-engine.d.ts +70 -0
- package/dist/core/capability/policy-engine.js +476 -0
- package/dist/core/capability/policy-types.d.ts +20 -0
- package/dist/core/capability/policy-types.js +1 -0
- package/dist/core/capability/request.d.ts +45 -0
- package/dist/core/capability/request.js +1 -0
- package/dist/core/capability/resolver.d.ts +4 -0
- package/dist/core/capability/resolver.js +4 -0
- package/dist/core/capability/trusted-workspace-roots.d.ts +25 -0
- package/dist/core/capability/trusted-workspace-roots.js +149 -0
- package/dist/core/capability/types.d.ts +11 -1
- package/dist/core/capability-approval.d.ts +2 -1
- package/dist/core/capability-approval.js +100 -2
- package/dist/core/classify-subagent.d.ts +2 -1
- package/dist/core/classify-subagent.js +40 -22
- package/dist/core/classify-tool.js +157 -64
- package/dist/core/config.d.ts +32 -3
- package/dist/core/config.js +105 -3
- package/dist/core/gate-contract.d.ts +3 -0
- package/dist/core/gate-contract.js +3 -0
- package/dist/core/gate-engine.js +12 -7
- package/dist/core/harvest.d.ts +53 -0
- package/dist/core/harvest.js +276 -0
- package/dist/core/index.d.ts +9 -3
- package/dist/core/index.js +6 -2
- package/dist/core/judge-doctor.d.ts +3 -0
- package/dist/core/judge-doctor.js +90 -11
- package/dist/core/judge-fallback-hints.d.ts +13 -0
- package/dist/core/judge-fallback-hints.js +108 -0
- package/dist/core/path-utils.d.ts +12 -0
- package/dist/core/path-utils.js +60 -7
- package/dist/core/reclassify.d.ts +3 -0
- package/dist/core/reclassify.js +44 -14
- package/dist/core/recovery/capability.d.ts +3 -0
- package/dist/core/recovery/capability.js +22 -0
- package/dist/core/recovery/fail-closed.d.ts +6 -0
- package/dist/core/recovery/fail-closed.js +25 -0
- package/dist/core/recovery/index.d.ts +3 -0
- package/dist/core/recovery/index.js +2 -0
- package/dist/core/recovery/types.d.ts +20 -0
- package/dist/core/recovery/types.js +1 -0
- package/dist/core/replay-scrub.d.ts +9 -0
- package/dist/core/replay-scrub.js +43 -0
- package/dist/core/shell-tokenizer.d.ts +2 -0
- package/dist/core/shell-tokenizer.js +82 -23
- package/dist/core/standing-allow.d.ts +50 -0
- package/dist/core/standing-allow.js +178 -0
- package/dist/core/transactional/diff-evaluator.js +4 -1
- package/dist/core/transactional/eligibility.js +4 -0
- package/dist/core/transactional/git-worktree.d.ts +10 -3
- package/dist/core/transactional/git-worktree.js +81 -11
- package/dist/core/transactional/reasons.d.ts +1 -0
- package/dist/core/transactional/reasons.js +4 -0
- package/dist/core/transactional/runner.js +22 -6
- package/dist/core/transactional/types.d.ts +4 -0
- package/dist/core/types.d.ts +36 -3
- package/dist/core/verdict/adapter.d.ts +3 -4
- package/dist/core/verdict/adapter.js +19 -6
- package/dist/core/verdict/containment.d.ts +4 -3
- package/dist/core/verdict/containment.js +17 -12
- package/dist/core/verdict/cursor-acp-client.d.ts +67 -0
- package/dist/core/verdict/cursor-acp-client.js +345 -0
- package/dist/core/verdict/egress-classify.d.ts +2 -2
- package/dist/core/verdict/egress-classify.js +2 -2
- package/dist/core/verdict/git-classifier.d.ts +26 -0
- package/dist/core/verdict/git-classifier.js +533 -0
- package/dist/core/verdict/judge-audit.d.ts +1 -0
- package/dist/core/verdict/judge-audit.js +33 -1
- package/dist/core/verdict/judge-baseline.d.ts +20 -0
- package/dist/core/verdict/judge-baseline.js +49 -0
- package/dist/core/verdict/judge-broker-service.d.ts +42 -0
- package/dist/core/verdict/judge-broker-service.js +291 -0
- package/dist/core/verdict/judge-catalog.js +1 -0
- package/dist/core/verdict/judge-cli-fingerprint.d.ts +6 -0
- package/dist/core/verdict/judge-cli-fingerprint.js +67 -0
- package/dist/core/verdict/judge-cli.d.ts +23 -0
- package/dist/core/verdict/judge-cli.js +139 -16
- package/dist/core/verdict/judge-factory.js +13 -4
- package/dist/core/verdict/judge-provider-matrix.d.ts +20 -0
- package/dist/core/verdict/judge-provider-matrix.js +66 -0
- package/dist/core/verdict/judge-runtime-config.d.ts +44 -0
- package/dist/core/verdict/judge-runtime-config.js +96 -0
- package/dist/core/verdict/judge-session-broker.d.ts +48 -0
- package/dist/core/verdict/judge-session-broker.js +200 -0
- package/dist/core/verdict/judge-session-guard.d.ts +27 -0
- package/dist/core/verdict/judge-session-guard.js +91 -0
- package/dist/core/verdict/judge-session-kill-switch.d.ts +11 -0
- package/dist/core/verdict/judge-session-kill-switch.js +43 -0
- package/dist/core/verdict/judge-session-mutex.d.ts +9 -0
- package/dist/core/verdict/judge-session-mutex.js +23 -0
- package/dist/core/verdict/judge-shadow.d.ts +24 -0
- package/dist/core/verdict/judge-shadow.js +116 -0
- package/dist/core/verdict/judge-transport.d.ts +44 -0
- package/dist/core/verdict/judge-transport.js +268 -0
- package/dist/core/verdict/judge.d.ts +14 -14
- package/dist/core/verdict/judge.js +5 -67
- package/dist/core/verdict/launcher-resolve.d.ts +2 -0
- package/dist/core/verdict/launcher-resolve.js +16 -0
- package/dist/core/verdict/parser.js +6 -1
- package/dist/core/verdict/prescan.d.ts +15 -0
- package/dist/core/verdict/prescan.js +68 -0
- package/dist/core/verdict/shell-policy.d.ts +25 -0
- package/dist/core/verdict/shell-policy.js +40 -0
- package/dist/core/verdict/shell-semantics.d.ts +24 -0
- package/dist/core/verdict/shell-semantics.js +225 -0
- package/dist/core/verdict/types.d.ts +26 -1
- package/dist/core/verdict/verdict.js +300 -179
- package/dist/corpus/adversarial-probe.d.ts +86 -0
- package/dist/corpus/adversarial-probe.js +220 -0
- package/dist/corpus/evaluate.d.ts +45 -12
- package/dist/corpus/evaluate.js +61 -8
- package/dist/corpus/gate-latency-budget.d.ts +39 -0
- package/dist/corpus/gate-latency-budget.js +33 -0
- package/dist/corpus/gates.d.ts +35 -0
- package/dist/corpus/gates.js +81 -0
- package/dist/corpus/judge-accuracy.d.ts +8 -0
- package/dist/corpus/judge-accuracy.js +39 -0
- package/dist/corpus/must-allow-commands.d.ts +5 -0
- package/dist/corpus/must-allow-commands.js +13 -0
- package/dist/corpus/mutators.d.ts +28 -0
- package/dist/corpus/mutators.js +162 -0
- package/dist/corpus/ratchet.d.ts +42 -0
- package/dist/corpus/ratchet.js +116 -0
- package/dist/corpus/runtime-match.d.ts +19 -0
- package/dist/corpus/runtime-match.js +43 -0
- package/dist/corpus/standing-allow-catalog.generated.d.ts +13 -0
- package/dist/corpus/standing-allow-catalog.generated.js +99 -0
- package/dist/corpus/types.d.ts +47 -0
- package/dist/corpus/types.js +157 -0
- package/dist/installer.js +4 -1
- package/dist/judge-broker-daemon.d.ts +1 -0
- package/dist/judge-broker-daemon.js +137 -0
- package/dist/services/sandbox-service.d.ts +5 -0
- package/dist/services/sandbox-service.js +30 -2
- package/dist/types.d.ts +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +7 -3
- package/skills/belay/SKILL.md +7 -1
- package/skills/belay/belay-approve.md +17 -0
package/dist/cli.js
CHANGED
|
@@ -6,11 +6,15 @@ import { auditProject, formatAuditReport } from './commands/audit.js';
|
|
|
6
6
|
import { doctorProject, formatDoctorReport } from './commands/doctor.js';
|
|
7
7
|
import { dogfoodProject, formatDogfoodResult } from './commands/dogfood.js';
|
|
8
8
|
import { explainCommand, formatExplainReport } from './commands/explain.js';
|
|
9
|
+
import { formatHarvestReport, harvestApplyProject, harvestListProject } from './commands/harvest.js';
|
|
9
10
|
import { formatMetricsReport, metricsProject } from './commands/metrics.js';
|
|
11
|
+
import { formatQualityReport, qualityCheck } from './commands/quality.js';
|
|
10
12
|
import { formatRecoverReport, recoverProject } from './commands/recover.js';
|
|
11
13
|
import { formatReport, reportProject } from './commands/report.js';
|
|
12
14
|
import { revokeApproval } from './commands/revoke.js';
|
|
15
|
+
import { formatSessionStatusReport, sessionStartProject, sessionStatusProject, } from './commands/session.js';
|
|
13
16
|
import { formatSimulateReport, simulateProject } from './commands/simulate.js';
|
|
17
|
+
import { revokeStandingAllow } from './commands/standing-allow.js';
|
|
14
18
|
import { formatStatusReport, statusProject } from './commands/status.js';
|
|
15
19
|
import { loadConfigFile } from './config-io.js';
|
|
16
20
|
import { rejectDeprecatedJudgeModelAuto } from './core/judge-model-policy.js';
|
|
@@ -154,6 +158,13 @@ function parseArgs(argv) {
|
|
|
154
158
|
index += 1;
|
|
155
159
|
continue;
|
|
156
160
|
}
|
|
161
|
+
if (token === '--live-probe') {
|
|
162
|
+
if (command !== 'judge') {
|
|
163
|
+
throw new Error('--live-probe is only valid for judge test.');
|
|
164
|
+
}
|
|
165
|
+
options.judgeLiveProbe = true;
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
157
168
|
if (token === '--json') {
|
|
158
169
|
options.json = true;
|
|
159
170
|
continue;
|
|
@@ -178,6 +189,24 @@ function parseArgs(argv) {
|
|
|
178
189
|
index += 1;
|
|
179
190
|
continue;
|
|
180
191
|
}
|
|
192
|
+
if (token === '--outcome') {
|
|
193
|
+
const next = rest[index + 1];
|
|
194
|
+
if (!next || !['provably-benign', 'accepted-benign', 'reject'].includes(next)) {
|
|
195
|
+
throw new Error('--outcome requires provably-benign, accepted-benign, or reject.');
|
|
196
|
+
}
|
|
197
|
+
options.harvestOutcome = next;
|
|
198
|
+
index += 1;
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
if (token === '--corpus') {
|
|
202
|
+
const next = rest[index + 1];
|
|
203
|
+
if (!next) {
|
|
204
|
+
throw new Error('--corpus requires a path.');
|
|
205
|
+
}
|
|
206
|
+
options.corpusPath = next;
|
|
207
|
+
index += 1;
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
181
210
|
if (token === '--kind') {
|
|
182
211
|
const next = rest[index + 1];
|
|
183
212
|
if (!next) {
|
|
@@ -252,11 +281,18 @@ function parseArgs(argv) {
|
|
|
252
281
|
index += 1;
|
|
253
282
|
continue;
|
|
254
283
|
}
|
|
284
|
+
if (token === '--replay') {
|
|
285
|
+
if (command !== 'approve') {
|
|
286
|
+
throw new Error('--replay is only valid for approve.');
|
|
287
|
+
}
|
|
288
|
+
options.approveReplay = true;
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
255
291
|
if (token === '--scope') {
|
|
256
292
|
const next = rest[index + 1];
|
|
257
293
|
if (command === 'approve') {
|
|
258
|
-
if (!next || !['once', 'domain', 'path'].includes(next)) {
|
|
259
|
-
throw new Error('--scope requires once, domain, or
|
|
294
|
+
if (!next || !['once', 'domain', 'path', 'workspace-root'].includes(next)) {
|
|
295
|
+
throw new Error('--scope requires once, domain, path, or workspace-root.');
|
|
260
296
|
}
|
|
261
297
|
options.approveScope = next;
|
|
262
298
|
}
|
|
@@ -315,6 +351,9 @@ function parseArgs(argv) {
|
|
|
315
351
|
if (command === 'recover') {
|
|
316
352
|
options.recoverCommand = next;
|
|
317
353
|
}
|
|
354
|
+
else if (command === 'harvest') {
|
|
355
|
+
options.harvestCommand = next;
|
|
356
|
+
}
|
|
318
357
|
else {
|
|
319
358
|
options.explainCommand = next;
|
|
320
359
|
}
|
|
@@ -343,7 +382,13 @@ function parseArgs(argv) {
|
|
|
343
382
|
return { command: 'help', options };
|
|
344
383
|
}
|
|
345
384
|
if (token === '--') {
|
|
346
|
-
|
|
385
|
+
const remainder = rest.slice(index + 1).join(' ');
|
|
386
|
+
if (command === 'session' && options.sessionSubcommand === 'start') {
|
|
387
|
+
options.sessionAgentCommand = remainder;
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
options.explainCommand = remainder;
|
|
391
|
+
}
|
|
347
392
|
break;
|
|
348
393
|
}
|
|
349
394
|
if (command === 'audit' && !options.auditSubcommand) {
|
|
@@ -367,16 +412,38 @@ function parseArgs(argv) {
|
|
|
367
412
|
}
|
|
368
413
|
throw new Error('sandbox requires subcommand: status');
|
|
369
414
|
}
|
|
415
|
+
if (command === 'session' && !options.sessionSubcommand) {
|
|
416
|
+
if (token === 'start' || token === 'status') {
|
|
417
|
+
options.sessionSubcommand = token;
|
|
418
|
+
continue;
|
|
419
|
+
}
|
|
420
|
+
throw new Error('session requires subcommand: start or status');
|
|
421
|
+
}
|
|
422
|
+
if (command === 'standing-allow' && !options.standingAllowSubcommand) {
|
|
423
|
+
if (token === 'revoke') {
|
|
424
|
+
options.standingAllowSubcommand = token;
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
427
|
+
throw new Error('standing-allow requires subcommand: revoke');
|
|
428
|
+
}
|
|
429
|
+
if (command === 'harvest' && !options.harvestSubcommand) {
|
|
430
|
+
if (token === 'list' || token === 'apply') {
|
|
431
|
+
options.harvestSubcommand = token;
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
throw new Error('harvest requires subcommand: list or apply');
|
|
435
|
+
}
|
|
370
436
|
if (command === 'judge' && !options.judgeSubcommand) {
|
|
371
437
|
if (token === 'status' ||
|
|
372
438
|
token === 'list' ||
|
|
373
439
|
token === 'use' ||
|
|
374
440
|
token === 'test' ||
|
|
441
|
+
token === 'bench' ||
|
|
375
442
|
token === 'consent') {
|
|
376
443
|
options.judgeSubcommand = token;
|
|
377
444
|
continue;
|
|
378
445
|
}
|
|
379
|
-
throw new Error('judge requires subcommand: status, list, use, test, or consent');
|
|
446
|
+
throw new Error('judge requires subcommand: status, list, use, test, bench, or consent');
|
|
380
447
|
}
|
|
381
448
|
if (command === 'config' && !options.configSubcommand) {
|
|
382
449
|
if (token === 'list' ||
|
|
@@ -458,6 +525,7 @@ Usage:
|
|
|
458
525
|
${c} dogfood [--target <dir>] [--adapter cursor|claude|codex] [--enforce] [--force]
|
|
459
526
|
${c} doctor [--target <dir>] [--adapter cursor|claude|codex] [--json] [--fix] [--dry-run]
|
|
460
527
|
${c} metrics [--target <dir>] [--json]
|
|
528
|
+
${c} quality [--target <dir>] [--corpus <path>] [--json]
|
|
461
529
|
${c} report [--target <dir>] [--since <iso>] [--until <iso>] [--limit <n>] [--json]
|
|
462
530
|
${c} recover [--target <dir>] [--since <iso>] [--fingerprint <fp>] [--command "<text>"] [--limit <n>] [--json]
|
|
463
531
|
(--limit picks the Nth recover candidate after priority ranking: local_mutation first, then recency; 1 = highest priority, default 1)
|
|
@@ -467,11 +535,17 @@ Usage:
|
|
|
467
535
|
${c} explain [--target <dir>] [--cwd <dir>] [--kind shell|tool|subagent] [--tool <name>] [--payload-json <json>] [--command <text>] [--json] [-- <command>]
|
|
468
536
|
${c} egress <start|stop|status|env> [--target <dir>] [--json]
|
|
469
537
|
${c} sandbox status [--target <dir>] [--json]
|
|
470
|
-
${c}
|
|
538
|
+
${c} session <start|status> [--target <dir>] [--json]
|
|
539
|
+
${c} session start [--target <dir>] [-- <agent command>]
|
|
540
|
+
${c} judge <status|list|use|test|bench|consent> [--target <dir>] [--json]
|
|
541
|
+
${c} judge test [--target <dir>] [--json] [--live-probe]
|
|
471
542
|
${c} judge use <ollama|codex|claude|cursor> [--model <id>] [--endpoint <url>] [--timeout <ms>] [--accept-cloud] [--cloud-consent-approval-id <id>] [--credential project|apiKey] [--key-stdin] [--key-env <NAME>]
|
|
472
543
|
${c} judge consent <ollama|codex|claude|cursor> [--endpoint <url>]
|
|
473
|
-
${c} approve <approval-id> [--scope once|domain|path] [--path <path>] [--token <signed-token>] [--target <dir>]
|
|
544
|
+
${c} approve <approval-id> [--replay] [--scope once|domain|path|workspace-root] [--path <path>] [--token <signed-token>] [--target <dir>]
|
|
474
545
|
${c} revoke <approval-id> [--target <dir>]
|
|
546
|
+
${c} standing-allow revoke --fingerprint <fp> [--kind shell|tool|subagent] [--target <dir>]
|
|
547
|
+
${c} harvest list [--target <dir>] [--since <iso>] [--until <iso>] [--json]
|
|
548
|
+
${c} harvest apply --command "<text>" --outcome provably-benign|accepted-benign|reject [--reason <r>] [--corpus <path>] [--target <dir>]
|
|
475
549
|
`);
|
|
476
550
|
}
|
|
477
551
|
async function main() {
|
|
@@ -545,6 +619,9 @@ async function main() {
|
|
|
545
619
|
if (!options.judgeSubcommand) {
|
|
546
620
|
throw new Error('judge requires subcommand: status, list, use, or test');
|
|
547
621
|
}
|
|
622
|
+
if (options.judgeLiveProbe && options.judgeSubcommand !== 'test') {
|
|
623
|
+
throw new Error('--live-probe is only valid for judge test.');
|
|
624
|
+
}
|
|
548
625
|
const result = await runJudgeCommand({
|
|
549
626
|
targetDir: options.targetDir,
|
|
550
627
|
json: options.json,
|
|
@@ -558,6 +635,7 @@ async function main() {
|
|
|
558
635
|
credentialMode: options.credentialMode,
|
|
559
636
|
keyStdin: options.keyStdin,
|
|
560
637
|
keyEnv: options.keyEnv,
|
|
638
|
+
liveProbe: options.judgeLiveProbe,
|
|
561
639
|
});
|
|
562
640
|
if (options.json && typeof result === 'object') {
|
|
563
641
|
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
@@ -679,6 +757,21 @@ async function main() {
|
|
|
679
757
|
}
|
|
680
758
|
return;
|
|
681
759
|
}
|
|
760
|
+
if (command === 'quality') {
|
|
761
|
+
const report = await qualityCheck({
|
|
762
|
+
targetDir: options.targetDir,
|
|
763
|
+
corpusDir: options.corpusPath,
|
|
764
|
+
json: options.json,
|
|
765
|
+
});
|
|
766
|
+
if (options.json) {
|
|
767
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
768
|
+
}
|
|
769
|
+
else {
|
|
770
|
+
process.stdout.write(`${formatQualityReport(report)}\n`);
|
|
771
|
+
}
|
|
772
|
+
process.exitCode = report.ok ? 0 : 1;
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
682
775
|
if (command === 'report') {
|
|
683
776
|
const report = await reportProject({
|
|
684
777
|
targetDir: options.targetDir,
|
|
@@ -695,6 +788,42 @@ async function main() {
|
|
|
695
788
|
}
|
|
696
789
|
return;
|
|
697
790
|
}
|
|
791
|
+
if (command === 'harvest') {
|
|
792
|
+
if (options.harvestSubcommand === 'list') {
|
|
793
|
+
const report = await harvestListProject({
|
|
794
|
+
targetDir: options.targetDir,
|
|
795
|
+
since: options.since,
|
|
796
|
+
until: options.until,
|
|
797
|
+
json: options.json,
|
|
798
|
+
});
|
|
799
|
+
if (options.json) {
|
|
800
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
801
|
+
}
|
|
802
|
+
else {
|
|
803
|
+
process.stdout.write(`${formatHarvestReport(report)}\n`);
|
|
804
|
+
}
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
if (options.harvestSubcommand === 'apply') {
|
|
808
|
+
if (!options.harvestCommand) {
|
|
809
|
+
throw new Error('harvest apply requires --command.');
|
|
810
|
+
}
|
|
811
|
+
if (!options.harvestOutcome) {
|
|
812
|
+
throw new Error('harvest apply requires --outcome.');
|
|
813
|
+
}
|
|
814
|
+
const result = await harvestApplyProject({
|
|
815
|
+
targetDir: options.targetDir,
|
|
816
|
+
command: options.harvestCommand,
|
|
817
|
+
outcome: options.harvestOutcome,
|
|
818
|
+
reason: options.reason,
|
|
819
|
+
corpusPath: options.corpusPath,
|
|
820
|
+
});
|
|
821
|
+
process.stdout.write(`${result.message}\n`);
|
|
822
|
+
process.exitCode = result.ok ? 0 : 1;
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
throw new Error('harvest requires subcommand: list or apply');
|
|
826
|
+
}
|
|
698
827
|
if (command === 'recover') {
|
|
699
828
|
const report = await recoverProject({
|
|
700
829
|
targetDir: options.targetDir,
|
|
@@ -794,6 +923,32 @@ async function main() {
|
|
|
794
923
|
process.exitCode = report.issues.length > 0 && report.sandboxEnabled ? 1 : 0;
|
|
795
924
|
return;
|
|
796
925
|
}
|
|
926
|
+
if (command === 'session') {
|
|
927
|
+
if (!options.sessionSubcommand) {
|
|
928
|
+
throw new Error('session requires subcommand: start or status');
|
|
929
|
+
}
|
|
930
|
+
if (options.sessionSubcommand === 'start') {
|
|
931
|
+
const result = await sessionStartProject({
|
|
932
|
+
targetDir: options.targetDir,
|
|
933
|
+
agentCommand: options.sessionAgentCommand,
|
|
934
|
+
});
|
|
935
|
+
process.stdout.write(`${result.message}\n`);
|
|
936
|
+
process.exitCode = result.ok ? 0 : 1;
|
|
937
|
+
return;
|
|
938
|
+
}
|
|
939
|
+
const report = await sessionStatusProject({
|
|
940
|
+
targetDir: options.targetDir,
|
|
941
|
+
json: options.json,
|
|
942
|
+
});
|
|
943
|
+
if (options.json) {
|
|
944
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
945
|
+
}
|
|
946
|
+
else {
|
|
947
|
+
process.stdout.write(`${formatSessionStatusReport(report)}\n`);
|
|
948
|
+
}
|
|
949
|
+
process.exitCode = report.ok ? 0 : 1;
|
|
950
|
+
return;
|
|
951
|
+
}
|
|
797
952
|
if (command === 'approve') {
|
|
798
953
|
if (!options.approvalId) {
|
|
799
954
|
throw new Error('approve requires an approval ID.');
|
|
@@ -804,6 +959,7 @@ async function main() {
|
|
|
804
959
|
token: options.approvalToken,
|
|
805
960
|
scope: options.approveScope,
|
|
806
961
|
scopePath: options.approvePath,
|
|
962
|
+
replay: options.approveReplay,
|
|
807
963
|
});
|
|
808
964
|
process.stdout.write(`${result.message}\n`);
|
|
809
965
|
process.exitCode = result.ok ? 0 : 1;
|
|
@@ -821,6 +977,24 @@ async function main() {
|
|
|
821
977
|
process.exitCode = result.ok ? 0 : 1;
|
|
822
978
|
return;
|
|
823
979
|
}
|
|
980
|
+
if (command === 'standing-allow') {
|
|
981
|
+
if (options.standingAllowSubcommand === 'revoke') {
|
|
982
|
+
if (!options.fingerprint) {
|
|
983
|
+
throw new Error('standing-allow revoke requires --fingerprint.');
|
|
984
|
+
}
|
|
985
|
+
const result = await revokeStandingAllow({
|
|
986
|
+
targetDir: options.targetDir,
|
|
987
|
+
fingerprint: options.fingerprint,
|
|
988
|
+
kind: options.kind === 'tool' || options.kind === 'subagent' || options.kind === 'shell'
|
|
989
|
+
? options.kind
|
|
990
|
+
: undefined,
|
|
991
|
+
});
|
|
992
|
+
process.stdout.write(`${result.message}\n`);
|
|
993
|
+
process.exitCode = result.ok ? 0 : 1;
|
|
994
|
+
return;
|
|
995
|
+
}
|
|
996
|
+
throw new Error('standing-allow requires subcommand: revoke');
|
|
997
|
+
}
|
|
824
998
|
throw new Error(`Unknown command: ${command}`);
|
|
825
999
|
}
|
|
826
1000
|
catch (error) {
|
package/dist/commands/approve.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { loadApprovalState, loadConfigFile } from '../config-io.js';
|
|
3
|
+
import { canAutoReplay, getExecutionLeaseMs, replayShellCommand } from '../core/approval-replay.js';
|
|
4
|
+
import { consumeApprovedAfterCliReplay, createGateApprovalStore, recordApproval, } from '../core/approval-service.js';
|
|
4
5
|
import { JUDGE_CLOUD_CONSENT_REASON } from '../core/capability/reasons.js';
|
|
5
6
|
import { recordCapabilityApproval } from '../core/capability-approval.js';
|
|
6
7
|
import { recordEgressApproval } from '../core/egress-approval.js';
|
|
@@ -32,11 +33,11 @@ export async function approvePending(options) {
|
|
|
32
33
|
});
|
|
33
34
|
return { ok: result.ok, message: result.message };
|
|
34
35
|
}
|
|
35
|
-
if (options.scope === 'path') {
|
|
36
|
+
if (options.scope === 'path' || options.scope === 'workspace-root') {
|
|
36
37
|
const result = await recordCapabilityApproval({
|
|
37
38
|
approvalId: options.approvalId,
|
|
38
39
|
config,
|
|
39
|
-
scope:
|
|
40
|
+
scope: options.scope,
|
|
40
41
|
scopePath: options.scopePath,
|
|
41
42
|
token: options.token,
|
|
42
43
|
requireSignedToken: config.approvalSigning.required,
|
|
@@ -44,33 +45,51 @@ export async function approvePending(options) {
|
|
|
44
45
|
});
|
|
45
46
|
return { ok: result.ok, message: result.message };
|
|
46
47
|
}
|
|
48
|
+
const approvalStore = createGateApprovalStore(repoRoot, config);
|
|
47
49
|
const result = await recordApproval({
|
|
48
50
|
approvalId: options.approvalId,
|
|
49
51
|
config,
|
|
50
52
|
token: options.token,
|
|
51
53
|
requireSignedToken: config.approvalSigning.required,
|
|
52
|
-
store:
|
|
53
|
-
async loadPending() {
|
|
54
|
-
const filePath = pendingApprovalsPath(repoRoot, config);
|
|
55
|
-
return {
|
|
56
|
-
filePath,
|
|
57
|
-
state: await loadApprovalState(repoRoot, 'pending-approvals.json', config),
|
|
58
|
-
};
|
|
59
|
-
},
|
|
60
|
-
async loadApproved() {
|
|
61
|
-
const filePath = approvedApprovalsPath(repoRoot, config);
|
|
62
|
-
return {
|
|
63
|
-
filePath,
|
|
64
|
-
state: await loadApprovalState(repoRoot, 'approved-approvals.json', config),
|
|
65
|
-
};
|
|
66
|
-
},
|
|
67
|
-
async writePending(_filePath, state) {
|
|
68
|
-
await saveApprovalState(repoRoot, 'pending-approvals.json', state, config);
|
|
69
|
-
},
|
|
70
|
-
async writeApproved(_filePath, state) {
|
|
71
|
-
await saveApprovalState(repoRoot, 'approved-approvals.json', state, config);
|
|
72
|
-
},
|
|
73
|
-
},
|
|
54
|
+
store: approvalStore,
|
|
74
55
|
});
|
|
56
|
+
if (!result.ok) {
|
|
57
|
+
return { ok: result.ok, message: result.message };
|
|
58
|
+
}
|
|
59
|
+
if (options.replay) {
|
|
60
|
+
const approval = result.approval;
|
|
61
|
+
if (!approval) {
|
|
62
|
+
return { ok: false, message: 'Approval recorded but replay envelope is missing.' };
|
|
63
|
+
}
|
|
64
|
+
if (!canAutoReplay(config, approval.kind)) {
|
|
65
|
+
return {
|
|
66
|
+
ok: false,
|
|
67
|
+
message: 'Replay is not enabled for this approval kind. Retry the original action manually or enable approval.autoReplayScopes.',
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (approval.kind !== 'shell' || !approval.input) {
|
|
71
|
+
return {
|
|
72
|
+
ok: false,
|
|
73
|
+
message: 'CLI replay is only supported for shell approvals. Retry the original tool or subagent action manually.',
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const replayResult = await replayShellCommand(approval.input, approval.cwd ?? repoRoot, getExecutionLeaseMs(config));
|
|
77
|
+
const output = [replayResult.stdout, replayResult.stderr].filter(Boolean).join('\n').trim();
|
|
78
|
+
if (replayResult.exitCode === 0) {
|
|
79
|
+
await consumeApprovedAfterCliReplay({
|
|
80
|
+
approvalId: options.approvalId,
|
|
81
|
+
store: approvalStore,
|
|
82
|
+
});
|
|
83
|
+
return {
|
|
84
|
+
ok: true,
|
|
85
|
+
message: `Belay replay succeeded for ${options.approvalId}. Do not retry via hooks; the one-shot grant was consumed.${output ? `\n${output}` : ''}`,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
const timeoutNote = replayResult.timedOut ? ' Replay timed out.' : '';
|
|
89
|
+
return {
|
|
90
|
+
ok: false,
|
|
91
|
+
message: `Belay replay failed for ${options.approvalId} (exit ${replayResult.exitCode}).${timeoutNote} Approval remains active for one hook retry.${output ? `\n${output}` : ''}`,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
75
94
|
return { ok: result.ok, message: result.message };
|
|
76
95
|
}
|
|
@@ -36,7 +36,7 @@ export async function classifyForReport(params) {
|
|
|
36
36
|
if (!params.command && !params.payload) {
|
|
37
37
|
throw new Error('classify-for-report requires command or payload for subagent classification.');
|
|
38
38
|
}
|
|
39
|
-
result = classifySubagent(payload, repoRoot, classifierOptions);
|
|
39
|
+
result = classifySubagent(payload, repoRoot, classifierOptions, config);
|
|
40
40
|
input = params.command ?? JSON.stringify(payload);
|
|
41
41
|
}
|
|
42
42
|
else if (kind === 'tool') {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type JudgeProviderId } from '../core/verdict/judge-catalog.js';
|
|
2
2
|
import type { AdapterName, InitOptions } from '../types.js';
|
|
3
|
+
import { type SelectOptions } from './tui.js';
|
|
3
4
|
export declare const BELAY_CONFIG_SUBCOMMANDS: readonly ["list", "get", "set", "unset", "credential", "judge"];
|
|
4
5
|
export type BelayConfigSubcommand = (typeof BELAY_CONFIG_SUBCOMMANDS)[number];
|
|
5
6
|
export interface BelayConfigOptions {
|
|
@@ -39,6 +40,13 @@ export interface BelayConfigInteractiveOptions {
|
|
|
39
40
|
/** Suppress the interactive header when nested under runBelayConfigInteractive */
|
|
40
41
|
skipBanner?: boolean;
|
|
41
42
|
}
|
|
43
|
+
export declare const JUDGE_CREDENTIAL_MODE_PROMPT = "Judge API key source";
|
|
44
|
+
export declare const JUDGE_CREDENTIAL_STORE_KEY_PROMPT = "Paste API key to store locally (visible input; prefer belay config credential set --key-stdin): ";
|
|
45
|
+
export declare const JUDGE_TRANSPORT_MODE_PROMPT = "How should Belay reach the judge?";
|
|
46
|
+
export declare const JUDGE_HTTP_ENDPOINT_PROMPT = "Judge HTTP API URL:";
|
|
47
|
+
export type JudgeTransportWizardMode = 'cli' | 'http';
|
|
48
|
+
export declare function buildJudgeTransportSelectOptions(judgeProviderId: JudgeProviderId): SelectOptions<JudgeTransportWizardMode>;
|
|
49
|
+
export declare function buildJudgeCredentialModeSelectOptions(judgeProviderId: JudgeProviderId): SelectOptions<'project' | 'apiKey'>;
|
|
42
50
|
export declare function resolveBelayConfigInteractiveMode(repoRoot: string): Promise<'full' | 'judge-only'>;
|
|
43
51
|
export declare function runBelayConfigFullInteractive(options?: BelayConfigInteractiveOptions): Promise<{
|
|
44
52
|
repoRoot: string;
|